aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMarc Coquand <marc@mccd.space>2024-05-13 11:00:47 -0500
committerMarc Coquand <marc@mccd.space>2024-05-13 11:00:47 -0500
commit121a6a376209de3f5a9474bf03721e2032a73e01 (patch)
tree6f02ffa1695510aa9227a9290abac11811b25373 /lib
downloadstitch-121a6a376209de3f5a9474bf03721e2032a73e01.tar.gz
stitch-121a6a376209de3f5a9474bf03721e2032a73e01.tar.bz2
stitch-121a6a376209de3f5a9474bf03721e2032a73e01.zip
initial commit
Diffstat (limited to '')
-rw-r--r--lib/dune7
-rw-r--r--lib/stitch.ml69
-rw-r--r--lib/zipper.ml22
3 files changed, 98 insertions, 0 deletions
diff --git a/lib/dune b/lib/dune
new file mode 100644
index 0000000..0ddfdce
--- /dev/null
+++ b/lib/dune
@@ -0,0 +1,7 @@
+(library
+ (name stitch)
+ (libraries
+ str
+ shexp.process
+ cmdliner
+ lambda-term))
diff --git a/lib/stitch.ml b/lib/stitch.ml
new file mode 100644
index 0000000..a6ba300
--- /dev/null
+++ b/lib/stitch.ml
@@ -0,0 +1,69 @@
+let execution_directory =
+ Sys.getenv_opt "STICH_DIRECTORY" |> Option.value ~default:"/home/mccd/notes-example"
+
+
+let grep_cmd = Sys.getenv_opt "STICH_GREP_CMD" |> Option.value ~default:"ugrep"
+
+let run_print ~dir args =
+ let open Shexp_process in
+ let open Shexp_process.Infix in
+ eval (chdir dir (call args |- read_all))
+
+
+let get_headlines () =
+ run_print
+ ~dir:execution_directory
+ [ grep_cmd; "^\\*"; "-H"; "-r"; "-n"; "--separator=|" ]
+
+
+exception Not_A_Tuple of string * string
+
+(** Returns a tuple of file name and Content *)
+let parse_headlines s =
+ String.split_on_char '\n' s
+ (* Testing in utop it seems like there is maybe a bug with bounded_split, 1 doesn't work for ':'. Therefore using a slower implementation. *)
+ |> List.filter_map (fun message ->
+ if String.equal message ""
+ then None
+ else (
+ let split = Str.bounded_split (Str.regexp "|") message 3 in
+ match split with
+ (* file, line, content *)
+ | [ file_name; _; content ] -> Some (file_name, content)
+ | _ -> raise (Not_A_Tuple (String.concat " SPLIT " split, message))))
+ |> Array.of_list
+
+
+(** Used for pretty printing *)
+let get_padding list =
+ Array.fold_left (fun n (file_name, _) -> Int.max n (String.length file_name)) 0 list
+
+
+let pad str n =
+ let padding = n - String.length str in
+ String.concat "" [ str; String.make padding ' ' ]
+
+
+(** Turns "2024-03-05.org:* Hello world" into "2024-03-05 | * Hello world" *)
+let pretty_format parsed_headlines =
+ let padding = get_padding parsed_headlines in
+ Array.map
+ (fun (file_name, content) -> String.concat " | " [ pad file_name padding; content ])
+ parsed_headlines
+
+
+(** Full body parsing *)
+
+let get_full_content () =
+ run_print
+ ~dir:execution_directory
+ [ grep_cmd; "^\\*"; "-h"; "-r"; "-n"; "-C"; "9999"; "--separator='|'" ]
+
+(* let parse_file_headline collection full = *)
+(* match full with *)
+(* | s :: r -> *)
+(* let split = Str.bounded_split (Str.regexp ":1:") s 1 in *)
+(* (match split with *)
+(* (\* file, line, content *\) *)
+(* | [ file_name; content ] -> file_name, content *)
+(* | rest -> *)
diff --git a/lib/zipper.ml b/lib/zipper.ml
new file mode 100644
index 0000000..37e14de
--- /dev/null
+++ b/lib/zipper.ml
@@ -0,0 +1,22 @@
+type zipper =
+ { above : string list
+ ; selected : string
+ ; below : string list
+ }
+
+let up (zipper : zipper) =
+ match zipper.above with
+ | [] -> zipper
+ | a :: rest -> { above = rest; selected = a; below = zipper.selected :: zipper.below }
+
+
+let down (zipper : zipper) =
+ match zipper.below with
+ | [] -> zipper
+ | a :: rest -> { below = rest; selected = a; above = zipper.selected :: zipper.above }
+
+
+let selected zipper = zipper.selected
+
+let to_array zipper =
+ List.concat [ zipper.above; [ zipper.selected ]; zipper.below ] |> Array.of_list