Skip to content

Commit

Permalink
Cross platform compat
Browse files Browse the repository at this point in the history
  • Loading branch information
darrenldl committed Jun 30, 2024
1 parent ce81e4b commit ebe260d
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 121 deletions.
9 changes: 9 additions & 0 deletions bin/params.ml
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,12 @@ let blink_on_duration : Mtime.span = Mtime.Span.(140 * ms)
let cwd = Sys.getcwd ()

let cwd_with_trailing_sep = cwd ^ Filename.dir_sep

let os_typ : [ `Darwin | `Linux | `Windows ] =
if Sys.win32 then (
`Windows
) else (
match String.lowercase_ascii (CCUnix.call_stdout "uname") with
| "darwin" -> `Darwin
| _ -> `Linux
)
205 changes: 109 additions & 96 deletions bin/path_open.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,111 +8,124 @@ let pandoc_supported_format ~path =
let cmd = xdg_open_cmd ~path in
Proc_utils.run_in_background cmd |> ignore

let compute_most_unique_word_and_residing_page_num index found_phrase =
let page_nums = found_phrase
|> List.map (fun word ->
word.Search_result.found_word_pos
|> (fun pos -> Index.loc_of_pos pos index)
|> Index.Loc.line_loc
|> Index.Line_loc.page_num
)
|> List.sort_uniq Int.compare
in
let frequency_of_word_of_page_ci : int String_map.t Int_map.t =
List.fold_left (fun acc page_num ->
let m = Misc_utils.frequencies_of_words_ci
(Index.words_of_page_num page_num index)
in
Int_map.add page_num m acc
)
Int_map.empty
page_nums
in
found_phrase
|> List.map (fun word ->
let page_num =
Index.loc_of_pos word.Search_result.found_word_pos index
|> Index.Loc.line_loc
|> Index.Line_loc.page_num
in
let m = Int_map.find page_num frequency_of_word_of_page_ci in
let freq =
String_map.fold (fun word_on_page_ci freq acc_freq ->
if
CCString.find ~sub:word.Search_result.found_word_ci word_on_page_ci >= 0
then (
acc_freq + freq
) else (
acc_freq
)
)
m
0
in
(word, page_num, freq)
)
|> List.fold_left (fun best x ->
let (_x_word, _x_page_num, x_freq) = x in
match best with
| None -> Some x
| Some (_best_word, _best_page_num, best_freq) -> (
if x_freq < best_freq then
Some x
else
best
)
)
None
|> Option.get
|> (fun (word, page_num, _freq) ->
(word.found_word, page_num))

let pdf index ~path ~search_result =
let path = Filename.quote path in
let fallback = xdg_open_cmd ~path in
let fallback =
match Params.os_typ with
| `Linux -> xdg_open_cmd ~path
| `Darwin -> Fmt.str "open %s" path
| `Windows -> Fmt.str {|start "" %s|} path
in
let cmd =
match search_result with
| None -> fallback
| Some search_result -> (
let found_phrase = Search_result.found_phrase search_result in
let page_nums = found_phrase
|> List.map (fun word ->
word.Search_result.found_word_pos
|> (fun pos -> Index.loc_of_pos pos index)
|> Index.Loc.line_loc
|> Index.Line_loc.page_num
)
|> List.sort_uniq Int.compare
in
let frequency_of_word_of_page_ci : int String_map.t Int_map.t =
List.fold_left (fun acc page_num ->
let m = Misc_utils.frequencies_of_words_ci
(Index.words_of_page_num page_num index)
in
Int_map.add page_num m acc
)
Int_map.empty
page_nums
in
let (most_unique_word, most_unique_word_page_num) =
found_phrase
|> List.map (fun word ->
let page_num =
Index.loc_of_pos word.Search_result.found_word_pos index
|> Index.Loc.line_loc
|> Index.Line_loc.page_num
in
let m = Int_map.find page_num frequency_of_word_of_page_ci in
let freq =
String_map.fold (fun word_on_page_ci freq acc_freq ->
if
CCString.find ~sub:word.Search_result.found_word_ci word_on_page_ci >= 0
then (
acc_freq + freq
) else (
acc_freq
)
)
m
0
in
(word, page_num, freq)
)
|> List.fold_left (fun best x ->
let (_x_word, _x_page_num, x_freq) = x in
match best with
| None -> Some x
| Some (_best_word, _best_page_num, best_freq) -> (
if x_freq < best_freq then
Some x
match Params.os_typ with
| `Linux -> (
match Xdg_utils.default_desktop_file_path `PDF with
| None -> fallback
| Some viewer_desktop_file_path -> (
let (most_unique_word, most_unique_word_page_num) =
compute_most_unique_word_and_residing_page_num index found_phrase
in
let flatpak_package_name =
let s = Filename.basename viewer_desktop_file_path in
Option.value ~default:s
(CCString.chop_suffix ~suf:".desktop" s)
in
let viewer_desktop_file_path_lowercase_ascii =
String.lowercase_ascii viewer_desktop_file_path
in
let contains sub =
CCString.find ~sub viewer_desktop_file_path_lowercase_ascii >= 0
in
let make_command name args =
if contains "flatpak" then
Fmt.str "flatpak run %s %s" flatpak_package_name args
else
best
)
)
None
|> Option.get
|> (fun (word, page_num, _freq) ->
(word.found_word, page_num))
in
match Xdg_utils.default_desktop_file_path `PDF with
| None -> fallback
| Some viewer_desktop_file_path -> (
let flatpak_package_name =
let s = Filename.basename viewer_desktop_file_path in
Option.value ~default:s
(CCString.chop_suffix ~suf:".desktop" s)
in
let viewer_desktop_file_path_lowercase_ascii =
String.lowercase_ascii viewer_desktop_file_path
in
let contains sub =
CCString.find ~sub viewer_desktop_file_path_lowercase_ascii >= 0
in
let make_command name args =
if contains "flatpak" then
Fmt.str "flatpak run %s %s" flatpak_package_name args
else
Fmt.str "%s %s" name args
in
let page_num = most_unique_word_page_num + 1 in
if contains "okular" then
make_command "okular"
(Fmt.str "--page %d --find %s %s" page_num most_unique_word path)
else if contains "evince" then
make_command "evince"
(Fmt.str "--page-index %d --find %s %s" page_num most_unique_word path)
else if contains "xreader" then
make_command "xreader"
(Fmt.str "--page-index %d --find %s %s" page_num most_unique_word path)
else if contains "atril" then
make_command "atril"
(Fmt.str "--page-index %d --find %s %s" page_num most_unique_word path)
else if contains "mupdf" then
make_command "mupdf" (Fmt.str "%s %d" path page_num)
else
fallback
Fmt.str "%s %s" name args
in
let page_num = most_unique_word_page_num + 1 in
if contains "okular" then
make_command "okular"
(Fmt.str "--page %d --find %s %s" page_num most_unique_word path)
else if contains "evince" then
make_command "evince"
(Fmt.str "--page-index %d --find %s %s" page_num most_unique_word path)
else if contains "xreader" then
make_command "xreader"
(Fmt.str "--page-index %d --find %s %s" page_num most_unique_word path)
else if contains "atril" then
make_command "atril"
(Fmt.str "--page-index %d --find %s %s" page_num most_unique_word path)
else if contains "mupdf" then
make_command "mupdf" (Fmt.str "%s %d" path page_num)
else
fallback
)
)
| `Darwin -> fallback
| `Windows -> fallback
)
in
Proc_utils.run_in_background cmd |> ignore
Expand Down
52 changes: 27 additions & 25 deletions bin/xdg_utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,32 @@ let default_desktop_file_path (typ : [ `PDF ]) =
)

let cache_home =
if Sys.win32 then (
let local_app_data = "LOCALAPPDATA" in
match Sys.getenv_opt local_app_data with
| None -> (
Misc_utils.exit_with_error_msg
(Fmt.str "environment variable %%%s%% is not set" local_app_data);
)
| Some x -> x
) else (
let home_dir =
match Sys.getenv_opt "HOME" with
match Params.os_typ with
| `Windows -> (
let local_app_data = "LOCALAPPDATA" in
match Sys.getenv_opt local_app_data with
| None -> (
Misc_utils.exit_with_error_msg "environment variable HOME is not set";
Misc_utils.exit_with_error_msg
(Fmt.str "environment variable %%%s%% is not set" local_app_data);
)
| Some home -> home
in
match String.lowercase_ascii (CCUnix.call_stdout "uname") with
| "darwin" -> (
Filename.concat home_dir
(Filename.concat "Library" "Application Support")
)
| _ -> (
match Sys.getenv_opt "XDG_CACHE_HOME" with
| None -> Filename.concat home_dir ".cache"
| Some x -> x
)
)
| Some x -> x
)
| `Linux | `Darwin as x -> (
let home_dir =
match Sys.getenv_opt "HOME" with
| None -> (
Misc_utils.exit_with_error_msg "environment variable HOME is not set";
)
| Some home -> home
in
match (x :> [ `Linux | `Darwin ]) with
| `Linux -> (
match Sys.getenv_opt "XDG_CACHE_HOME" with
| None -> Filename.concat home_dir ".cache"
| Some x -> x
)
| `Darwin -> (
Filename.concat home_dir
(Filename.concat "Library" "Application Support")
)
)

0 comments on commit ebe260d

Please sign in to comment.