Commit
Author: Kevin Schoon [kevinschoon@gmail.com]
Hash: 21aab957a2872d0ee71d9bb246e88fdd2d793f89
Timestamp: Tue, 18 Aug 2020 00:48:11 +0000 (4 years ago)

+89 -177 +/-6 browse
progress
1diff --git a/.gitignore b/.gitignore
2index 69fa449..7bcace9 100644
3--- a/.gitignore
4+++ b/.gitignore
5 @@ -1 +1,2 @@
6+ .merlin
7 _build/
8 diff --git a/.merlin b/.merlin
9deleted file mode 100644
10index a469268..0000000
11--- a/.merlin
12+++ /dev/null
13 @@ -1,138 +0,0 @@
14- EXCLUDE_QUERY_DIR
15- B /home/kevin/.opam/default/lib/base
16- B /home/kevin/.opam/default/lib/base/base_internalhash_types
17- B /home/kevin/.opam/default/lib/base/caml
18- B /home/kevin/.opam/default/lib/base/md5
19- B /home/kevin/.opam/default/lib/base/shadow_stdlib
20- B /home/kevin/.opam/default/lib/base_bigstring
21- B /home/kevin/.opam/default/lib/base_quickcheck
22- B /home/kevin/.opam/default/lib/bigarray-compat
23- B /home/kevin/.opam/default/lib/bin_prot
24- B /home/kevin/.opam/default/lib/bin_prot/shape
25- B /home/kevin/.opam/default/lib/bytes
26- B /home/kevin/.opam/default/lib/core
27- B /home/kevin/.opam/default/lib/core/error_checking_mutex
28- B /home/kevin/.opam/default/lib/core_kernel
29- B /home/kevin/.opam/default/lib/core_kernel/base_for_tests
30- B /home/kevin/.opam/default/lib/core_kernel/caml_unix
31- B /home/kevin/.opam/default/lib/core_kernel/flags
32- B /home/kevin/.opam/default/lib/core_kernel/version_util
33- B /home/kevin/.opam/default/lib/cstruct
34- B /home/kevin/.opam/default/lib/ctypes
35- B /home/kevin/.opam/default/lib/ezjsonm
36- B /home/kevin/.opam/default/lib/fieldslib
37- B /home/kevin/.opam/default/lib/fmt
38- B /home/kevin/.opam/default/lib/hex
39- B /home/kevin/.opam/default/lib/integers
40- B /home/kevin/.opam/default/lib/jane-street-headers
41- B /home/kevin/.opam/default/lib/jsonm
42- B /home/kevin/.opam/default/lib/logs
43- B /home/kevin/.opam/default/lib/parsexp
44- B /home/kevin/.opam/default/lib/ppx_assert/runtime-lib
45- B /home/kevin/.opam/default/lib/ppx_bench/runtime-lib
46- B /home/kevin/.opam/default/lib/ppx_compare/runtime-lib
47- B /home/kevin/.opam/default/lib/ppx_enumerate/runtime-lib
48- B /home/kevin/.opam/default/lib/ppx_expect/collector
49- B /home/kevin/.opam/default/lib/ppx_expect/common
50- B /home/kevin/.opam/default/lib/ppx_expect/config
51- B /home/kevin/.opam/default/lib/ppx_expect/config_types
52- B /home/kevin/.opam/default/lib/ppx_hash/runtime-lib
53- B /home/kevin/.opam/default/lib/ppx_here/runtime-lib
54- B /home/kevin/.opam/default/lib/ppx_inline_test/config
55- B /home/kevin/.opam/default/lib/ppx_inline_test/runtime-lib
56- B /home/kevin/.opam/default/lib/ppx_module_timer/runtime
57- B /home/kevin/.opam/default/lib/ppx_sexp_conv/runtime-lib
58- B /home/kevin/.opam/default/lib/result
59- B /home/kevin/.opam/default/lib/rresult
60- B /home/kevin/.opam/default/lib/seq
61- B /home/kevin/.opam/default/lib/sexplib
62- B /home/kevin/.opam/default/lib/sexplib/unix
63- B /home/kevin/.opam/default/lib/sexplib0
64- B /home/kevin/.opam/default/lib/spawn
65- B /home/kevin/.opam/default/lib/splittable_random
66- B /home/kevin/.opam/default/lib/stdio
67- B /home/kevin/.opam/default/lib/stdlib-shims
68- B /home/kevin/.opam/default/lib/time_now
69- B /home/kevin/.opam/default/lib/timezone
70- B /home/kevin/.opam/default/lib/typerep
71- B /home/kevin/.opam/default/lib/uchar
72- B /home/kevin/.opam/default/lib/uutf
73- B /home/kevin/.opam/default/lib/variantslib
74- B /home/kevin/.opam/default/lib/yaml
75- B /home/kevin/.opam/default/lib/yaml/bindings
76- B /home/kevin/.opam/default/lib/yaml/bindings/types
77- B /home/kevin/.opam/default/lib/yaml/c
78- B /home/kevin/.opam/default/lib/yaml/ffi
79- B /home/kevin/.opam/default/lib/yaml/types
80- B /usr/lib/ocaml
81- B /usr/lib/ocaml/threads
82- B _build/default/.main.eobjs/byte
83- S /home/kevin/.opam/default/lib/base
84- S /home/kevin/.opam/default/lib/base/base_internalhash_types
85- S /home/kevin/.opam/default/lib/base/caml
86- S /home/kevin/.opam/default/lib/base/md5
87- S /home/kevin/.opam/default/lib/base/shadow_stdlib
88- S /home/kevin/.opam/default/lib/base_bigstring
89- S /home/kevin/.opam/default/lib/base_quickcheck
90- S /home/kevin/.opam/default/lib/bigarray-compat
91- S /home/kevin/.opam/default/lib/bin_prot
92- S /home/kevin/.opam/default/lib/bin_prot/shape
93- S /home/kevin/.opam/default/lib/bytes
94- S /home/kevin/.opam/default/lib/core
95- S /home/kevin/.opam/default/lib/core/error_checking_mutex
96- S /home/kevin/.opam/default/lib/core_kernel
97- S /home/kevin/.opam/default/lib/core_kernel/base_for_tests
98- S /home/kevin/.opam/default/lib/core_kernel/caml_unix
99- S /home/kevin/.opam/default/lib/core_kernel/flags
100- S /home/kevin/.opam/default/lib/core_kernel/version_util
101- S /home/kevin/.opam/default/lib/cstruct
102- S /home/kevin/.opam/default/lib/ctypes
103- S /home/kevin/.opam/default/lib/ezjsonm
104- S /home/kevin/.opam/default/lib/fieldslib
105- S /home/kevin/.opam/default/lib/fmt
106- S /home/kevin/.opam/default/lib/hex
107- S /home/kevin/.opam/default/lib/integers
108- S /home/kevin/.opam/default/lib/jane-street-headers
109- S /home/kevin/.opam/default/lib/jsonm
110- S /home/kevin/.opam/default/lib/logs
111- S /home/kevin/.opam/default/lib/parsexp
112- S /home/kevin/.opam/default/lib/ppx_assert/runtime-lib
113- S /home/kevin/.opam/default/lib/ppx_bench/runtime-lib
114- S /home/kevin/.opam/default/lib/ppx_compare/runtime-lib
115- S /home/kevin/.opam/default/lib/ppx_enumerate/runtime-lib
116- S /home/kevin/.opam/default/lib/ppx_expect/collector
117- S /home/kevin/.opam/default/lib/ppx_expect/common
118- S /home/kevin/.opam/default/lib/ppx_expect/config
119- S /home/kevin/.opam/default/lib/ppx_expect/config_types
120- S /home/kevin/.opam/default/lib/ppx_hash/runtime-lib
121- S /home/kevin/.opam/default/lib/ppx_here/runtime-lib
122- S /home/kevin/.opam/default/lib/ppx_inline_test/config
123- S /home/kevin/.opam/default/lib/ppx_inline_test/runtime-lib
124- S /home/kevin/.opam/default/lib/ppx_module_timer/runtime
125- S /home/kevin/.opam/default/lib/ppx_sexp_conv/runtime-lib
126- S /home/kevin/.opam/default/lib/result
127- S /home/kevin/.opam/default/lib/rresult
128- S /home/kevin/.opam/default/lib/seq
129- S /home/kevin/.opam/default/lib/sexplib
130- S /home/kevin/.opam/default/lib/sexplib/unix
131- S /home/kevin/.opam/default/lib/sexplib0
132- S /home/kevin/.opam/default/lib/spawn
133- S /home/kevin/.opam/default/lib/splittable_random
134- S /home/kevin/.opam/default/lib/stdio
135- S /home/kevin/.opam/default/lib/stdlib-shims
136- S /home/kevin/.opam/default/lib/time_now
137- S /home/kevin/.opam/default/lib/timezone
138- S /home/kevin/.opam/default/lib/typerep
139- S /home/kevin/.opam/default/lib/uchar
140- S /home/kevin/.opam/default/lib/uutf
141- S /home/kevin/.opam/default/lib/variantslib
142- S /home/kevin/.opam/default/lib/yaml
143- S /home/kevin/.opam/default/lib/yaml/bindings
144- S /home/kevin/.opam/default/lib/yaml/bindings/types
145- S /home/kevin/.opam/default/lib/yaml/c
146- S /home/kevin/.opam/default/lib/yaml/ffi
147- S /home/kevin/.opam/default/lib/yaml/types
148- S /usr/lib/ocaml
149- S /usr/lib/ocaml/threads
150- S .
151- FLG -open Dune__exe -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -w -32 -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -w -27
152 diff --git a/README.md b/README.md
153index fbb9dd5..b21a5c0 100644
154--- a/README.md
155+++ b/README.md
156 @@ -17,7 +17,7 @@ tags: ["misc", "note taking"]
157
158 # Hello World!
159
160- Today will be a nice day.
161+ Today will be a nice day 🐪.
162 ```
163
164 ## Configuration
165 diff --git a/dune b/dune
166index 948c326..c27e3c9 100644
167--- a/dune
168+++ b/dune
169 @@ -1,6 +1,7 @@
170 (executable
171 (name main)
172- (libraries base core ezjsonm stdio yaml))
173+ (libraries base core ezjsonm stdio yaml)
174+ (preprocess (pps ppx_jane)))
175 (env
176 (dev
177 (flags (:standard -w -32)(:standard -w -27))))
178 diff --git a/main.ml b/main.ml
179index 9698179..5f25066 100644
180--- a/main.ml
181+++ b/main.ml
182 @@ -1,25 +1,20 @@
183 open Core
184
185 let list_notes =
186- Command.basic ~summary:"List Notes"
187- Command.Param.(
188- map (anon (maybe ("filter" %: string))) ~f:(
189- fun filter_str () ->
190- let notes = Note.read_tasks "db" in
191- List.iter ~f: (fun x -> Note.display_task x) notes;
192- )
193- )
194-
195-
196- let edit_note =
197- Command.basic ~summary: "Create a New Note or Edit An Existing Note"
198- Command.Param.(
199- map (anon (maybe ("name" %: string))) ~f:(
200- fun name () ->
201- print_endline "creating a new note" ;
202- )
203- )
204-
205+ Command.basic ~summary: "list existing notes"
206+ ~readme: (fun () -> "
207+ The list subcommand will list one or more notes stored
208+ in the state directory, you can apply one or more filters
209+ to reduce the number of results that are returned
210+ ")
211+ Command.Let_syntax.(
212+ let%map_open
213+ filters = anon ( sequence ("filter" %: string) )
214+ in
215+ fun () ->
216+ let notes = Note.read_notes_filtered "db" filters in
217+ (List.iter ~f: (fun x -> Note.display_note_fancy x) notes) ;
218+ )
219
220 let delete_note =
221 Command.basic ~summary: "Create a New Note"
222 @@ -30,7 +25,10 @@ let delete_note =
223 )
224 )
225
226- let command = Command.group ~summary:"list" [ ("list", list_notes) ]
227+ let command = Command.group ~summary:"list" [
228+ ("list", list_notes) ;
229+ ("delete", delete_note)
230+ ]
231
232 let () =
233 Command.run command
234 diff --git a/note.ml b/note.ml
235index e7f2610..2a04d20 100644
236--- a/note.ml
237+++ b/note.ml
238 @@ -1,7 +1,12 @@
239 open Core
240 open Stdio
241
242- type task = { title : string; tags : string list }
243+ type t = {
244+ title : string;
245+ content : string;
246+ tags : string list;
247+ created : Time.t;
248+ }
249
250 let get_title dict =
251 let title = List.find ~f:(fun (key, _) -> equal_string key "title") dict in
252 @@ -11,33 +16,78 @@ let get_tags dict =
253 let title = List.find ~f:(fun (key, _) -> equal_string key "tags") dict in
254 match title with Some (_, v) -> Ezjsonm.get_strings v | None -> []
255
256- let get_front_matter task_str =
257+ (* TODO *)
258+ let get_created dict = Time.parse "20010102" ~fmt:"%Y%m%d" ~zone:Time.Zone.utc
259+
260+ let get_content note_str =
261+ let indexes =
262+ String.substr_index_all ~may_overlap:true ~pattern:"---" note_str
263+ in
264+ if List.length indexes >= 2 then
265+ String.slice note_str (List.nth_exn indexes 1 + 3) (String.length note_str)
266+ else ""
267+
268+ let of_string note_str =
269 let indexes =
270- String.substr_index_all ~may_overlap:true ~pattern:"---" task_str
271+ String.substr_index_all ~may_overlap:true ~pattern:"---" note_str
272 in
273 if List.length indexes >= 2 then
274 let meta_str =
275- String.slice task_str
276+ String.slice note_str
277 (List.nth_exn indexes 0 + 3)
278 (List.nth_exn indexes 1)
279 in
280 let value = Yaml.of_string_exn meta_str in
281 let dict = Ezjsonm.get_dict value in
282- Some { title = get_title dict; tags = get_tags dict }
283+ Some
284+ {
285+ title = get_title dict;
286+ content = get_content note_str;
287+ tags = get_tags dict;
288+ created = get_created dict;
289+ }
290 else None
291
292- let read_task path =
293- let task_str = In_channel.read_all path in
294- get_front_matter task_str
295+ let read_note path =
296+ let note_str = In_channel.read_all path in
297+ of_string note_str
298
299- let read_tasks path =
300+ let read_notes path =
301 let files = Sys.ls_dir path in
302 let paths = List.map ~f:(fun p -> sprintf "%s/%s" path p) files in
303- List.map ~f:read_task paths
304-
305- let display_task task =
306- match task with
307- | Some t ->
308- print_endline t.title;
309- print_endline (String.concat ~sep:" | " t.tags)
310- | None -> print_endline "bad task :("
311+ List.filter_map ~f:read_note paths
312+
313+ (* TODO: some how core List.mem does not work?!?!?! *)
314+ let filter_note_by_tags note tags =
315+ match
316+ List.find
317+ ~f:(fun tag -> List.count ~f:(fun x -> equal_string x tag) note.tags > 0)
318+ tags
319+ with
320+ | Some x -> true
321+ | None -> false
322+
323+ let read_notes_filtered path filters =
324+ let notes = read_notes path in
325+ if List.length filters > 0 then
326+ (* first look by name *)
327+ let by_name =
328+ List.find
329+ ~f:(fun n -> equal_string n.title (List.nth_exn filters 0))
330+ notes
331+ in
332+ match by_name with
333+ | Some note -> [ note ]
334+ | None ->
335+ (* now we filter by tags *)
336+ List.filter ~f:(fun note -> filter_note_by_tags note filters) notes
337+ else notes
338+
339+ let display_note_fancy note =
340+ let created = Time.to_string note.created in
341+ let tag_string = String.concat ~sep:"|" note.tags in
342+ let formatted = Printf.sprintf "(%s) %s [%s]" created note.title tag_string in
343+ print_endline formatted;
344+ print_endline note.content
345+
346+ let display_note note = print_endline note.title