Fill key history per-task, before prompt

This commit is contained in:
contrapunctus 2021-01-01 00:56:39 +05:30
parent 3d9debf989
commit 796626904e
5 changed files with 116 additions and 118 deletions

View File

@ -868,8 +868,12 @@ Function - chronometrist-append-to-last (tags plist)
@item
Variable - chronometrist-tags-history
@item
Function - chronometrist-map-file (file fn)
@item
Function - chronometrist-tags-history-populate (task history-table file)
@item
Function - chronometrist-key-history-populate (task history-table file)
@item
Function - chronometrist-tags-history-add (plist)
@item
Function - chronometrist-tags-history-replace-last (plist)
@ -890,8 +894,6 @@ Variable - chronometrist-value-history
@item
Function - chronometrist-ht-history-prep (table)
@item
Function - chronometrist-key-history-populate (events-table history-table)
@item
Function - chronometrist-value-history-populate (events-table history-table)
@item
Keymap - chronometrist-kv-read-mode-map

View File

@ -349,39 +349,40 @@ Each of these has a corresponding function to clear it and fill it with values -
16. Function - chronometrist-report-next-week (arg)
** chronometrist-key-values.el
1. Internal Variable - chronometrist--tag-suggestions
2. Internal Variable - chronometrist--value-suggestions
3. Function - chronometrist-plist-remove (plist &rest keys)
4. Function - chronometrist-maybe-string-to-symbol (list)
5. Function - chronometrist-maybe-symbol-to-string (list)
6. Function - chronometrist-append-to-last (tags plist)
7. Variable - chronometrist-tags-history
8. Function - chronometrist-tags-history-populate (task history-table file)
9. Function - chronometrist-tags-history-add (plist)
10. Function - chronometrist-tags-history-replace-last (plist)
11. Function - chronometrist-tags-history-combination-strings (task)
12. Function - chronometrist-tags-history-individual-strings (task)
13. Function - chronometrist-tags-prompt (task &optional initial-input)
14. Function - chronometrist-tags-add (&rest args)
15. Custom Variable - chronometrist-kv-buffer-name
16. Variable - chronometrist-key-history
17. Variable - chronometrist-value-history
18. Function - chronometrist-ht-history-prep (table)
19. Function - chronometrist-key-history-populate (events-table history-table)
20. Function - chronometrist-value-history-populate (events-table history-table)
21. Keymap - chronometrist-kv-read-mode-map
22. Major Mode - chronometrist-kv-read-mode
23. Function - chronometrist-kv-completion-quit-key ()
24. Function - chronometrist-string-has-whitespace-p (string)
25. Function - chronometrist-key-prompt (used-keys)
26. Function - chronometrist-value-prompt (key)
27. Function - chronometrist-value-insert (value)
28. Function - chronometrist-kv-add (&rest args)
29. Command - chronometrist-kv-accept ()
30. Command - chronometrist-kv-reject ()
31. Internal Variable - chronometrist--skip-detail-prompts
32. Function - chronometrist-skip-query-prompt (task)
33. Function - chronometrist-skip-query-reset (_task)
1. Internal Variable - chronometrist--tag-suggestions
2. Internal Variable - chronometrist--value-suggestions
3. Function - chronometrist-plist-remove (plist &rest keys)
4. Function - chronometrist-maybe-string-to-symbol (list)
5. Function - chronometrist-maybe-symbol-to-string (list)
6. Function - chronometrist-append-to-last (tags plist)
7. Variable - chronometrist-tags-history
8. Function - chronometrist-map-file (file fn)
9. Function - chronometrist-tags-history-populate (task history-table file)
10. Function - chronometrist-key-history-populate (task history-table file)
11. Function - chronometrist-tags-history-add (plist)
12. Function - chronometrist-tags-history-replace-last (plist)
13. Function - chronometrist-tags-history-combination-strings (task)
14. Function - chronometrist-tags-history-individual-strings (task)
15. Function - chronometrist-tags-prompt (task &optional initial-input)
16. Function - chronometrist-tags-add (&rest args)
17. Custom Variable - chronometrist-kv-buffer-name
18. Variable - chronometrist-key-history
19. Variable - chronometrist-value-history
20. Function - chronometrist-ht-history-prep (table)
21. Function - chronometrist-value-history-populate (events-table history-table)
22. Keymap - chronometrist-kv-read-mode-map
23. Major Mode - chronometrist-kv-read-mode
24. Function - chronometrist-kv-completion-quit-key ()
25. Function - chronometrist-string-has-whitespace-p (string)
26. Function - chronometrist-key-prompt (used-keys)
27. Function - chronometrist-value-prompt (key)
28. Function - chronometrist-value-insert (value)
29. Function - chronometrist-kv-add (&rest args)
30. Command - chronometrist-kv-accept ()
31. Command - chronometrist-kv-reject ()
32. Internal Variable - chronometrist--skip-detail-prompts
33. Function - chronometrist-skip-query-prompt (task)
34. Function - chronometrist-skip-query-reset (_task)
** chronometrist-statistics-custom.el
1. Custom variable - chronometrist-statistics-buffer-name

View File

@ -105,16 +105,25 @@ Each value is a list of tag combinations, in reverse
chronological order. Each combination is a list containing tags
as symbol and/or strings.")
(defun chronometrist-map-file (file fn)
"Run FN for each s-expression in FILE.
FN must be a function accepting one argument."
(declare (indent defun) (debug t))
(chronometrist-sexp-in-file file
(goto-char (point-min))
(cl-loop with var
while (->> (current-buffer)
(read )
(ignore-errors )
(setq var ))
do (funcall fn var))))
(defun chronometrist-tags-history-populate (task history-table file)
"Store tag history for TASK in HISTORY-TABLE from FILE.
HISTORY-TABLE must be a hash table. (see `chronometrist-tags-history')"
(chronometrist-sexp-in-file file
(goto-char (point-min))
(cl-loop with plist
while (setq plist
(ignore-errors
(read (current-buffer)))) do
(let ((new-tag-list (plist-get plist :tags))
(chronometrist-map-file file
(lambda (plist)
(let ((new-tag-list (plist-get plist :tags))
(old-tag-lists (gethash task history-table)))
(and (equal task (plist-get plist :name))
new-tag-list
@ -130,6 +139,31 @@ HISTORY-TABLE must be a hash table. (see `chronometrist-tags-history')"
(cl-remove-duplicates it :test #'equal :from-end t)
(puthash task it history-table)))
(defun chronometrist-key-history-populate (task history-table file)
"Store key history for TASK in HISTORY-TABLE from FILE.
Return the new value of HISTORY-TABLE.
HISTORY-TABLE must be a hash table (see `chronometrist-key-history')."
(chronometrist-map-file file
(lambda (plist)
(catch 'quit
(let* ((name (plist-get plist :name))
(check (unless (equal name task) (throw 'quit nil)))
(keys (--> (chronometrist-plist-remove plist :name :start :stop :tags)
(seq-filter #'keywordp it)
(cl-loop for key in it collect
(s-chop-prefix ":" (symbol-name key)))))
(check (unless keys (throw 'quit nil)))
(old-keys (gethash name history-table)))
(puthash name
(if old-keys
(append keys old-keys)
keys)
history-table)))))
(--> (gethash task history-table)
(cl-remove-duplicates it :test #'equal :from-end t)
(puthash task it history-table)))
(defun chronometrist-tags-history-add (plist)
"Add tags from PLIST to `chronometrist-tags-history'."
(let* ((table chronometrist-tags-history)
@ -198,17 +232,16 @@ INITIAL-INPUT is as used in `completing-read'."
_ARGS are ignored. This function always returns t, so it can be
used in `chronometrist-before-out-functions'."
(unless chronometrist--skip-detail-prompts
(let* ((last-expr (chronometrist-last))
(last-name (plist-get last-expr :name))
(_update-history (chronometrist-tags-history-populate last-name chronometrist-tags-history
chronometrist-file))
(last-tags (plist-get last-expr :tags))
(input (->> last-tags
(chronometrist-maybe-symbol-to-string)
(-interpose ",")
(apply #'concat)
(chronometrist-tags-prompt last-name)
(chronometrist-maybe-string-to-symbol))))
(let* ((last-expr (chronometrist-last))
(last-name (plist-get last-expr :name))
(_history (chronometrist-tags-history-populate last-name chronometrist-tags-history chronometrist-file))
(last-tags (plist-get last-expr :tags))
(input (->> last-tags
(chronometrist-maybe-symbol-to-string)
(-interpose ",")
(apply #'concat)
(chronometrist-tags-prompt last-name)
(chronometrist-maybe-string-to-symbol))))
(when input
(--> (append last-tags input)
(reverse it)
@ -256,35 +289,6 @@ reversed and will have duplicate elements removed."
table)
finally return table))
(defun chronometrist-key-history-populate (events-table history-table)
"Clear HISTORY-TABLE and store key history in it, using EVENTS-TABLE.
Return the new value of HISTORY-TABLE.
EVENTS-TABLE and HISTORY-TABLE must be hash tables (see `chronometrist-events' and `chronometrist-key-history')."
(clrhash history-table)
;; add each task as a key
(mapc (lambda (task)
(puthash task nil history-table))
;; ;; Not necessary, if the only place this is called is `chronometrist-refresh-file'
;; (setq chronometrist--task-list (chronometrist-tasks-from-table))
chronometrist-task-list)
(cl-loop for events being the hash-values of events-table do
(cl-loop for event in events do
(let ((name (plist-get event :name))
(keys (->> (chronometrist-plist-remove event :name :start :stop :tags)
(seq-filter #'keywordp))))
(cl-loop for key in keys do
(when key
(let ((old-keys (gethash name history-table))
(new-key (->> (symbol-name key)
(s-chop-prefix ":")
(list))))
(--> (if old-keys
(append old-keys new-key)
new-key)
(puthash name it history-table))))))))
(chronometrist-ht-history-prep history-table))
(defun chronometrist-value-history-populate (events-table history-table)
"Clear HISTORY-TABLE and store value history in it, using EVENTS-TABLE.
Return the new value of HISTORY-TABLE.
@ -391,10 +395,13 @@ used in `chronometrist-before-out-functions'."
(unless chronometrist--skip-detail-prompts
(let* ((buffer (get-buffer-create chronometrist-kv-buffer-name))
(first-key-p t)
(last-kvs (chronometrist-plist-remove (chronometrist-last) :name :tags :start :stop))
(last-sexp (chronometrist-last))
(last-name (plist-get last-sexp :name))
(last-kvs (chronometrist-plist-remove last-sexp :name :tags :start :stop))
(used-keys (->> (seq-filter #'keywordp last-kvs)
(mapcar #'symbol-name)
(--map (s-chop-prefix ":" it)))))
(chronometrist-key-history-populate last-name chronometrist-key-history chronometrist-file)
(switch-to-buffer buffer)
(with-current-buffer buffer
(chronometrist-common-clear-buffer buffer)

View File

@ -261,7 +261,6 @@ Argument _FS-EVENT is ignored."
(setq chronometrist--inhibit-read-p nil)
(chronometrist-events-populate)
(setq chronometrist-task-list (chronometrist-tasks-from-table)))
(chronometrist-key-history-populate chronometrist-events chronometrist-key-history)
(chronometrist-value-history-populate chronometrist-events chronometrist-value-history)
(chronometrist-refresh))

View File

@ -30,42 +30,31 @@
'(:b 2 :c 3))))
(ert-deftest chronometrist-tags-history ()
(let ((_update (progn
(clrhash chronometrist-tags-history)
(cl-loop for task in '("Guitar" "Programming") do
(chronometrist-tags-history-populate task chronometrist-tags-history "test.sexp")))))
(should
(= (hash-table-count chronometrist-tags-history) 2))
(should
(cl-loop for task being the hash-keys of chronometrist-tags-history
always (stringp task)))
(should
(equal (gethash "Guitar" chronometrist-tags-history)
'((classical solo)
(classical warm-up))))
(should
(equal (gethash "Programming" chronometrist-tags-history)
'((reading) (bug-hunting))))))
(progn
(clrhash chronometrist-tags-history)
(cl-loop for task in '("Guitar" "Programming") do
(chronometrist-tags-history-populate task chronometrist-tags-history "test.sexp")))
(should
(= (hash-table-count chronometrist-tags-history) 2))
(should
(cl-loop for task being the hash-keys of chronometrist-tags-history
always (stringp task)))
(should
(equal (gethash "Guitar" chronometrist-tags-history)
'((classical solo)
(classical warm-up))))
(should
(equal (gethash "Programming" chronometrist-tags-history)
'((reading) (bug-hunting)))))
(ert-deftest chronometrist-key-history ()
(before-all
(setq chronometrist-file "tests/test.sexp")
(chronometrist-events-populate)
(setq chronometrist-task-list (chronometrist-tasks-from-table))
(chronometrist-key-history-populate chronometrist-events chronometrist-key-history))
(it "should
have 6 hash keys"
(should
(hash-table-count chronometrist-key-history)
:to-be 6))
(it "should
store multiple values"
(should
(length (gethash "Programming" chronometrist-key-history))
:to-be 3)
(should
(length (gethash "Arrangement/new edition" chronometrist-key-history))
:to-be 2)))
(progn
(clrhash chronometrist-key-history)
(cl-loop for task in '("Programming" "Arrangement/new edition") do
(chronometrist-key-history-populate task chronometrist-key-history "test.sexp")))
(should (= (hash-table-count chronometrist-key-history) 2))
(should (= (length (gethash "Programming" chronometrist-key-history)) 3))
(should (= (length (gethash "Arrangement/new edition" chronometrist-key-history)) 2)))
(ert-deftest chronometrist-value-history ()
(before-all