Commit
+89 -177 +/-6 browse
1 | diff --git a/.gitignore b/.gitignore |
2 | index 69fa449..7bcace9 100644 |
3 | --- a/.gitignore |
4 | +++ b/.gitignore |
5 | @@ -1 +1,2 @@ |
6 | + .merlin |
7 | _build/ |
8 | diff --git a/.merlin b/.merlin |
9 | deleted file mode 100644 |
10 | index 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 |
153 | index 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 |
166 | index 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 |
179 | index 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 |
235 | index 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 |