open Core.Std
(* Auxiliary sources *)
let list_episodes show_name =
let ic = Unix.open_process_in ("series " ^ show_name) in
let episodes =
In_channel.fold_lines ic ~init:[] ~f:(fun acc episode ->
let (id, name) = String.lsplit2_exn episode ~on:'\t' in
(name, id, id) :: acc
)
in
ignore (Unix.close_process_in ic) ;
Sources.from_list_rev episodes
let list_shows =
lazy (
let ic = Unix.open_process_in "series" in
let shows =
In_channel.fold_lines ic ~init:[] ~f:(fun acc show ->
let show_name, nb_eps = String.lsplit2_exn show ~on:' ' in
(show_name, show_name, String.lstrip nb_eps) :: acc
)
in
ignore (Unix.close_process_in ic) ;
Sources.from_list_rev shows
)
let papers =
let filter absolute_path =
match Sys.is_file absolute_path with
| `Yes ->
begin match snd @@ Filename.split_extension absolute_path with
| None -> false
| Some ext -> List.mem ["pdf" ; "ps" ; "djvu" ] ext
end
| _ -> false
in [
lazy Sources.(paths ~coupled_with:(files ~filter "/tmp")) ;
lazy Sources.(paths ~coupled_with:(files ~filter "/home/rks/Papiers")) ;
]
(* Completion engines *)
let series = Completion.({
ex_sources = [ list_shows ] ;
transition = fun show -> singleton (lazy (list_episodes show#display))
})
let engine =
let open Completion in
sum Sources.binaries (fun o ->
let cmd = o#display in
match cmd with
| "chromium" -> iterate [ Extra_sources.chromium_bookmarks ]
| "evince" -> iterate papers
| "series" -> series
| _ ->
sum (Sources.paths ~coupled_with:(Extra_sources.from_file cmd)) (
fun arg ->
match cmd, arg#display with
| "mpc", "load" -> iterate [ Extra_sources.Mpc.playlists ]
| "mpc", "play" -> singleton Extra_sources.Mpc.current_playlist
| _ -> Extra_sources.stm_from_file (cmd ^ arg#display)
)
)
(* Main function *)
let run =
let open Dmlenu in
let source_transition_hook state conf =
let open Matching in
let (match_fun, lines) =
match List.map state.Completion.entries ~f:(fun (_, _, s) -> s) with
| "mpc" :: "play" :: _ -> (subset ~case:false, 20)
| "mpc" :: _ -> (fuzzy_match ~case:false, 0)
| "chromium" :: _ | "evince" :: _ -> (fuzzy_match ~case:false, 20)
| "series" :: l when List.length l < 2 -> (fuzzy_match ~case:false, 20)
| _ -> (match_prefix ~case:false, 0)
in
set_match_query_fun match_fun ;
{ conf with lines }
in
let app_state = { prompt = "" ; compl = Completion.make_state engine } in
let conf = { default_conf with window_background = "#222222" } in
match run_list ~source_transition_hook app_state conf with
| [] -> ()
| prog :: _ as args ->
never_returns @@ Unix.exec ~prog ~args ()