Commit
+88 -65 +/-4 browse
1 | diff --git a/contrib/note_commit.sh b/contrib/note_commit.sh |
2 | index 67ee32d..140ba30 100755 |
3 | --- a/contrib/note_commit.sh |
4 | +++ b/contrib/note_commit.sh |
5 | @@ -5,7 +5,7 @@ |
6 | # script assumes that your state_dir is also a git repository. |
7 | set -e |
8 | |
9 | - STATE_DIR="$(note config -get state_dir)" |
10 | + STATE_DIR="$(note config get state_dir)" |
11 | |
12 | pushd "$STATE_DIR" |
13 | git add --all |
14 | diff --git a/lib/cmd.ml b/lib/cmd.ml |
15 | index c2828de..ef32891 100644 |
16 | --- a/lib/cmd.ml |
17 | +++ b/lib/cmd.ml |
18 | @@ -21,6 +21,15 @@ let filter_arg = |
19 | notes) |
20 | (fun filter -> filter) |
21 | |
22 | + let key_arg = |
23 | + Command.Arg_type.create |
24 | + ~complete:(fun _ ~part -> |
25 | + let string_keys = List.map ~f:Key.to_string Key.all in |
26 | + List.filter |
27 | + ~f:(fun key -> String.is_substring ~substring:part key) |
28 | + string_keys) |
29 | + Key.of_string |
30 | + |
31 | (* |
32 | * commands |
33 | *) |
34 | @@ -49,7 +58,7 @@ note cat -encoding json |
35 | and encoding = |
36 | flag "encoding" |
37 | (optional_with_default |
38 | - (Encoding.of_string (value_as_string (get load Key.Encoding))) |
39 | + (Encoding.of_string (value_to_string (get load Key.Encoding))) |
40 | (Command.Arg_type.create Encoding.of_string)) |
41 | ~doc:"format [json | yaml | raw] (default: raw)" |
42 | in |
43 | @@ -68,33 +77,27 @@ note cat -encoding json |
44 | | Raw -> In_channel.read_all (Note.get_path note) )) |
45 | notes] |
46 | |
47 | - let show_config = |
48 | - let open Command.Let_syntax in |
49 | - Command.basic ~summary:"display the configuration" |
50 | - ~readme:(fun () -> |
51 | - {| |
52 | - Display the current configuration as inferred by Note. It is also possible to |
53 | - extract specific values by specifying a key value. |
54 | + let config_show = |
55 | + Command.basic ~summary:"show the current configuration" |
56 | + (Command.Param.return (fun () -> print_endline (to_string load))) |
57 | |
58 | - Examples |
59 | + let config_get = |
60 | + let open Command.Let_syntax in |
61 | + Command.basic ~summary:"get a config value" |
62 | + [%map_open |
63 | + let key = anon ("key" %: key_arg) in |
64 | + fun () -> print_endline (value_to_string (get load key))] |
65 | |
66 | - # display the current configuration |
67 | - note config |
68 | - # extract a specific value from the configuration |
69 | - note config -get state_dir |
70 | - |}) |
71 | + let config_set = |
72 | + let open Command.Let_syntax in |
73 | + Command.basic ~summary:"set a config value" |
74 | [%map_open |
75 | - let key = |
76 | - flag "get" |
77 | - (optional (Command.Arg_type.create Key.of_string)) |
78 | - ~doc:"get a config value" |
79 | - in |
80 | - fun () -> |
81 | - match key with |
82 | - | Some key -> |
83 | - let value = get load key in |
84 | - print_endline (value_as_string value) |
85 | - | None -> print_string (to_string load)] |
86 | + let key = anon ("key" %: key_arg) and value = anon ("value" %: string) in |
87 | + fun () -> |
88 | + let cfg = load in |
89 | + let cfg = set cfg key (value_of_string key value) in |
90 | + save cfg |
91 | + ] |
92 | |
93 | let create_note = |
94 | let open Command.Let_syntax in |
95 | @@ -227,7 +230,7 @@ note ls |
96 | and style = |
97 | flag "style" |
98 | (optional_with_default |
99 | - (ListStyle.of_string (value_as_string (get load Key.ListStyle))) |
100 | + (ListStyle.of_string (value_to_string (get load Key.ListStyle))) |
101 | (Arg_type.create ListStyle.of_string)) |
102 | ~doc:"list style [fixed | wide | simple]" |
103 | in |
104 | @@ -252,7 +255,10 @@ let run = |
105 | [ |
106 | ("cat", cat_note); |
107 | ("create", create_note); |
108 | - ("config", show_config); |
109 | + ( "config", |
110 | + Command.group ~summary:"config management" |
111 | + [ ("show", config_show); ("get", config_get); ("set", config_set) ] |
112 | + ); |
113 | ("delete", delete_note); |
114 | ("edit", edit_note); |
115 | ("ls", list_notes); |
116 | diff --git a/lib/config.ml b/lib/config.ml |
117 | index 7b0f7ca..ee2be07 100644 |
118 | --- a/lib/config.ml |
119 | +++ b/lib/config.ml |
120 | @@ -6,6 +6,11 @@ let base_xdg_config_path = Filename.concat home ".config" |
121 | |
122 | let base_xdg_share_path = Filename.concat home ".local/share" |
123 | |
124 | + let config_path = |
125 | + match Sys.getenv "NOTE_CONFIG" with |
126 | + | Some path -> path |
127 | + | None -> Filename.concat base_xdg_config_path "/note/config.yaml" |
128 | + |
129 | module ListStyle = struct |
130 | type t = Fixed | Wide | Simple |
131 | |
132 | @@ -33,13 +38,6 @@ module Encoding = struct |
133 | | key -> failwith (sprintf "unsupported encoding type: %s" key) |
134 | end |
135 | |
136 | - type t = Yaml.value |
137 | - |
138 | - type value = |
139 | - | String of string option |
140 | - | ListStyle of ListStyle.t option |
141 | - | Encoding of Encoding.t option |
142 | - |
143 | module Key = struct |
144 | type t = |
145 | | StateDir |
146 | @@ -49,6 +47,8 @@ module Key = struct |
147 | | ListStyle |
148 | | Encoding |
149 | |
150 | + let all = [ StateDir; LockFile; Editor; OnModification; ListStyle; Encoding ] |
151 | + |
152 | let of_string = function |
153 | | "state_dir" -> StateDir |
154 | | "lock_file" -> LockFile |
155 | @@ -56,7 +56,7 @@ module Key = struct |
156 | | "on_modification" -> OnModification |
157 | | "list_style" -> ListStyle |
158 | | "encoding" -> Encoding |
159 | - | key -> failwith (sprintf "bad configuration key %s" key) |
160 | + | key -> failwith (sprintf "bad configuration key %s" key) |
161 | |
162 | let to_string = function |
163 | | StateDir -> "state_dir" |
164 | @@ -65,8 +65,18 @@ module Key = struct |
165 | | OnModification -> "on_modification" |
166 | | ListStyle -> "list_style" |
167 | | Encoding -> "encoding" |
168 | + |
169 | end |
170 | |
171 | + type t = Yaml.value |
172 | + |
173 | + let to_string t = Yaml.to_string_exn t |
174 | + |
175 | + type value = |
176 | + | String of string option |
177 | + | ListStyle of ListStyle.t option |
178 | + | Encoding of Encoding.t option |
179 | + |
180 | let get_default = function |
181 | | Key.StateDir -> String (Some (Filename.concat base_xdg_share_path "/note")) |
182 | | Key.LockFile -> String (Some (Filename.concat base_xdg_share_path "/note")) |
183 | @@ -75,25 +85,16 @@ let get_default = function |
184 | | Key.ListStyle -> ListStyle (Some ListStyle.Fixed) |
185 | | Key.Encoding -> Encoding (Some Encoding.Raw) |
186 | |
187 | - let of_json key json = |
188 | + let value_of_string key s = |
189 | match key with |
190 | - | Key.StateDir -> String (Some (Ezjsonm.get_string json)) |
191 | - | Key.LockFile -> String (Some (Ezjsonm.get_string json)) |
192 | - | Key.Editor -> String (Some (Ezjsonm.get_string json)) |
193 | - | Key.OnModification -> String (Some (Ezjsonm.get_string json)) |
194 | - | Key.ListStyle -> |
195 | - ListStyle (Some (ListStyle.of_string (Ezjsonm.get_string json))) |
196 | - | Key.Encoding -> |
197 | - Encoding (Some (Encoding.of_string (Ezjsonm.get_string json))) |
198 | - |
199 | - let to_string t = Yaml.to_string_exn t |
200 | - |
201 | - let get t key = |
202 | - match Ezjsonm.find_opt t [ Key.to_string key ] with |
203 | - | Some json -> of_json key json |
204 | - | None -> get_default key |
205 | - |
206 | - let value_as_string value = |
207 | + | Key.StateDir -> String (Some s) |
208 | + | Key.LockFile -> String (Some s) |
209 | + | Key.Editor -> String (Some s) |
210 | + | Key.OnModification -> String (Some s) |
211 | + | Key.ListStyle -> ListStyle (Some (ListStyle.of_string s)) |
212 | + | Key.Encoding -> Encoding (Some (Encoding.of_string s)) |
213 | + |
214 | + let value_to_string value = |
215 | match value with |
216 | | String value -> ( match value with Some v -> v | None -> "" ) |
217 | | ListStyle value -> ( |
218 | @@ -101,6 +102,15 @@ let value_as_string value = |
219 | | Encoding value -> ( |
220 | match value with Some v -> Encoding.to_string v | None -> "" ) |
221 | |
222 | + let get t key = |
223 | + match Ezjsonm.find_opt t [ Key.to_string key ] with |
224 | + | Some json -> value_of_string key (Ezjsonm.get_string json) |
225 | + | None -> get_default key |
226 | + |
227 | + let set t key value = |
228 | + Ezjsonm.update t [ Key.to_string key ] |
229 | + (Some (Ezjsonm.string (value_to_string value))) |
230 | + |
231 | let get_string_opt t key = |
232 | match get t key with |
233 | | String value -> value |
234 | @@ -115,18 +125,14 @@ let get_string t key = |
235 | | None -> failwith (sprintf "%s not defined" (Key.to_string key)) |
236 | |
237 | let load = |
238 | - let path = |
239 | - match Sys.getenv "NOTE_CONFIG" with |
240 | - | Some path -> path |
241 | - | None -> Filename.concat base_xdg_config_path "/note/config.yaml" |
242 | - in |
243 | let cfg = |
244 | - match Sys.file_exists path with |
245 | - | `Yes -> Yaml.of_string_exn (In_channel.read_all path) |
246 | + match Sys.file_exists config_path with |
247 | + | `Yes -> Yaml.of_string_exn (In_channel.read_all config_path) |
248 | | `No | `Unknown -> |
249 | - Unix.mkdir_p (Filename.dirname path); |
250 | - Out_channel.write_all path ~data:(Ezjsonm.to_string (Ezjsonm.dict [])); |
251 | - Yaml.of_string_exn (In_channel.read_all path) |
252 | + Unix.mkdir_p (Filename.dirname config_path); |
253 | + Out_channel.write_all config_path |
254 | + ~data:(Ezjsonm.to_string (Ezjsonm.dict [])); |
255 | + Yaml.of_string_exn (In_channel.read_all config_path) |
256 | in |
257 | |
258 | let state_dir = get_string cfg Key.StateDir in |
259 | @@ -136,3 +142,4 @@ let load = |
260 | Unix.mkdir_p state_dir; |
261 | cfg |
262 | |
263 | + let save t = Out_channel.write_all ~data:(to_string t) config_path |
264 | diff --git a/lib/config.mli b/lib/config.mli |
265 | index 743cbec..dc4d3b2 100644 |
266 | --- a/lib/config.mli |
267 | +++ b/lib/config.mli |
268 | @@ -25,6 +25,8 @@ module Key : sig |
269 | | ListStyle |
270 | | Encoding |
271 | |
272 | + val all : t list |
273 | + |
274 | val of_string : string -> t |
275 | |
276 | val to_string : t -> string |
277 | @@ -42,12 +44,20 @@ val to_string : t -> string |
278 | val load : t |
279 | (** load the configuration from disk *) |
280 | |
281 | - val value_as_string : value -> string |
282 | + val save : t -> unit |
283 | + (** save the configuration to disk *) |
284 | + |
285 | + val value_to_string : value -> string |
286 | (** convert a value to string form *) |
287 | |
288 | + val value_of_string : Key.t -> string -> value |
289 | + |
290 | val get : t -> Key.t -> value |
291 | (** get a single value by key *) |
292 | |
293 | + val set : t -> Key.t -> value -> t |
294 | + (** set a configuration value *) |
295 | + |
296 | val get_string : t -> Key.t -> string |
297 | (** get a single value as a string by key *) |
298 |