Compare commits
3 Commits
dev
...
month-grap
Author | SHA1 | Date |
---|---|---|
contrapunctus | 3819b2e0de | |
contrapunctus | 2480d26f91 | |
contrapunctus | 8f664fd4e2 |
23
TODO.org
23
TODO.org
|
@ -413,7 +413,7 @@ Some options and ideas -
|
||||||
- untouched project with target defined - red
|
- untouched project with target defined - red
|
||||||
- target ±5 minutes - green
|
- target ±5 minutes - green
|
||||||
- target*2 and above - red
|
- target*2 and above - red
|
||||||
* documentation discoverability :doc:
|
* documentation discoverability :doc:
|
||||||
Ensure that the user manual is easily discoverable.
|
Ensure that the user manual is easily discoverable.
|
||||||
|
|
||||||
#+BEGIN_QUOTE
|
#+BEGIN_QUOTE
|
||||||
|
@ -427,9 +427,8 @@ Ensure that the user manual is easily discoverable.
|
||||||
[2021-06-02 13:53:37] rnkn: although you will probably need a function link instead to find the org file \\
|
[2021-06-02 13:53:37] rnkn: although you will probably need a function link instead to find the org file \\
|
||||||
[2021-06-02 13:54:30] contrapunctus: Although I guess the manual.org does not really need those fancy features...info export could work for it. \\
|
[2021-06-02 13:54:30] contrapunctus: Although I guess the manual.org does not really need those fancy features...info export could work for it. \\
|
||||||
#+END_QUOTE
|
#+END_QUOTE
|
||||||
* macro for extensions :code:extension:
|
* macro for extensions :code:extension:
|
||||||
<2021-06-07T16:33:54+0530>
|
<2021-06-07T16:33:54+0530>
|
||||||
|
|
||||||
A macro to create new columns for Chronometrist.
|
A macro to create new columns for Chronometrist.
|
||||||
|
|
||||||
Extension writer specifies
|
Extension writer specifies
|
||||||
|
@ -452,7 +451,11 @@ Benefits -
|
||||||
+ easier creation of such extensions
|
+ easier creation of such extensions
|
||||||
+ users can easily replace the function used to generate the cells, without having to deal with how the string is inserted into the row specifier.
|
+ users can easily replace the function used to generate the cells, without having to deal with how the string is inserted into the row specifier.
|
||||||
|
|
||||||
* unified format-duration function :code:customization:
|
Current uses -
|
||||||
|
1. =chronometrist-goal=
|
||||||
|
2. =chronometrist-spark=
|
||||||
|
|
||||||
|
* unified format-duration function :code:customization:
|
||||||
<2021-06-08T11:17:54+0530>
|
<2021-06-08T11:17:54+0530>
|
||||||
|
|
||||||
Currently we have at least three ways of displaying durations - ="HH:MM:SS"= , ="XhYm"= , and =X hour(s), Y minutes(s)"= . Make a single function similar to =format-time-string=, but for durations. =ts-human-format-duration= from =ts.el= is not nearly as flexible as I'd like. When completed, we can have a single custom variable accepting a format string, which can be used to customize display of durations for the entire application at once.
|
Currently we have at least three ways of displaying durations - ="HH:MM:SS"= , ="XhYm"= , and =X hour(s), Y minutes(s)"= . Make a single function similar to =format-time-string=, but for durations. =ts-human-format-duration= from =ts.el= is not nearly as flexible as I'd like. When completed, we can have a single custom variable accepting a format string, which can be used to customize display of durations for the entire application at once.
|
||||||
|
@ -490,7 +493,7 @@ Alternative syntax
|
||||||
+ to display only values, use ="%<code>"=
|
+ to display only values, use ="%<code>"=
|
||||||
+ to display long units, use ="~[<separator>]<code>"=
|
+ to display long units, use ="~[<separator>]<code>"=
|
||||||
|
|
||||||
* DONE error - =min= called with nil :spark:bug:
|
* DONE error - =min= called with nil :spark:bug:
|
||||||
<2021-06-11T03:44:17+0530>
|
<2021-06-11T03:44:17+0530>
|
||||||
1. clock in
|
1. clock in
|
||||||
2. change =:start= of active interval to another time on the same date
|
2. change =:start= of active interval to another time on the same date
|
||||||
|
@ -544,7 +547,7 @@ Debugger entered--Lisp error: (wrong-number-of-arguments #<subr min> 0)
|
||||||
command-execute(file-notify-handle-event nil [(file-notify ((1 . 1) (modify) "chronometrist.sexp" 0) file-notify--callback-inotify)] t)
|
command-execute(file-notify-handle-event nil [(file-notify ((1 . 1) (modify) "chronometrist.sexp" 0) file-notify--callback-inotify)] t)
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
* STARTED discoverability and mouse-accessibility of commands [33%] :ux:
|
* STARTED discoverability and mouse-accessibility of commands [33%] :ux:
|
||||||
<2021-06-15T16:18:49+0530>
|
<2021-06-15T16:18:49+0530>
|
||||||
Goals
|
Goals
|
||||||
1. discoverability of commands
|
1. discoverability of commands
|
||||||
|
@ -560,7 +563,7 @@ Strategies
|
||||||
* Perhaps I needn't worry too much. =menu-bar-mode= is enabled by default, and it makes #1 and #2 easy. I think a significant amount of the userbase disables =menu-bar-mode=, but they also have things like =counsel-M-x=, =describe-=.
|
* Perhaps I needn't worry too much. =menu-bar-mode= is enabled by default, and it makes #1 and #2 easy. I think a significant amount of the userbase disables =menu-bar-mode=, but they also have things like =counsel-M-x=, =describe-=.
|
||||||
+ The menu does not make the behavior of the numeric argument discoverable. Doesn't make sense to put it there, either.
|
+ The menu does not make the behavior of the numeric argument discoverable. Doesn't make sense to put it there, either.
|
||||||
|
|
||||||
* query-editing the file buffer :feature:
|
* query-editing the file buffer :feature:
|
||||||
<2021-06-16T07:50:21+0530>
|
<2021-06-16T07:50:21+0530>
|
||||||
|
|
||||||
=chronometrist-loop-file= can be used to run queries against user data. It would be cool to be able to edit the file directly from the query results.
|
=chronometrist-loop-file= can be used to run queries against user data. It would be cool to be able to edit the file directly from the query results.
|
||||||
|
@ -569,7 +572,7 @@ Strategies
|
||||||
2. The result data may be something which corresponds to the input data, in which case we could jump to the corresponding plist.
|
2. The result data may be something which corresponds to the input data, in which case we could jump to the corresponding plist.
|
||||||
3. The result data may be impossible to trace back to the input data (e.g. a sum of intervals from many plists), in which case we cannot provide direct editing.
|
3. The result data may be impossible to trace back to the input data (e.g. a sum of intervals from many plists), in which case we cannot provide direct editing.
|
||||||
|
|
||||||
* error in change type detection :core:bug:
|
* error in change type detection :core:bug:
|
||||||
<2021-06-16T18:40:18+0530>
|
<2021-06-16T18:40:18+0530>
|
||||||
Steps
|
Steps
|
||||||
1. Clock in
|
1. Clock in
|
||||||
|
@ -577,14 +580,14 @@ Steps
|
||||||
3. Clock in to different task. Error.
|
3. Clock in to different task. Error.
|
||||||
|
|
||||||
Might have to do with there being 2 empty lines between the last-but-one plist and the new last plist.
|
Might have to do with there being 2 empty lines between the last-but-one plist and the new last plist.
|
||||||
* spark monthly view :spark:feature:
|
* spark monthly view :spark:feature:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:feature: frontend
|
:feature: frontend
|
||||||
:END:
|
:END:
|
||||||
<2021-06-17T00:08:08+0530>
|
<2021-06-17T00:08:08+0530>
|
||||||
Frontend to show one or more months for a specific task, calendar-style, with each day being a single sparkline block.
|
Frontend to show one or more months for a specific task, calendar-style, with each day being a single sparkline block.
|
||||||
|
|
||||||
* Task-specific detailed view :feature:
|
* Task-specific detailed view :feature:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:feature: frontend
|
:feature: frontend
|
||||||
:END:
|
:END:
|
||||||
|
|
|
@ -102,5 +102,89 @@ SCHEMA should be a vector as specified by `tabulated-list-format'."
|
||||||
;; when being enabled/disabled, `chronometrist-spark-minor-mode' will already be t/nil here
|
;; when being enabled/disabled, `chronometrist-spark-minor-mode' will already be t/nil here
|
||||||
(if chronometrist-spark-minor-mode (chronometrist-spark-setup) (chronometrist-spark-teardown)))
|
(if chronometrist-spark-minor-mode (chronometrist-spark-setup) (chronometrist-spark-teardown)))
|
||||||
|
|
||||||
|
(defun chronometrist-task-durations-month (task iso-year-month)
|
||||||
|
(let* ((start-ts (chronometrist-iso-date-to-ts (concat iso-year-month "-01")))
|
||||||
|
;; last date of month
|
||||||
|
(stop-ts (ts-adjust 'month 1 'day -1 start-ts)))
|
||||||
|
(cl-loop with current = start-ts
|
||||||
|
while (not (ts> current stop-ts))
|
||||||
|
collect (chronometrist-task-time-one-day task current)
|
||||||
|
do (setq current (ts-adjust 'day 1 current)))))
|
||||||
|
|
||||||
|
(defgroup chronometrist-task-graph nil
|
||||||
|
"Task-specific monthly/weekly graph for the `chronometrist' time tracker."
|
||||||
|
:group 'chronometrist)
|
||||||
|
|
||||||
|
(defcustom chronometrist-task-graph-buffer-name "*chronometrist-task-graph*"
|
||||||
|
"Name of buffer created by `chronometrist-task-graph'."
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom chronometrist-task-graph-default-unit :month
|
||||||
|
"Default unit for `chronometrist-task-graph'.
|
||||||
|
Values may be either `:month' or `:week'."
|
||||||
|
:type '(radio (const :tag "Month" :month) (const :tag "Week" :week)))
|
||||||
|
|
||||||
|
(defcustom chronometrist-task-graph-schema
|
||||||
|
[("#" 3 (lambda (row-1 row-2) (< (car row-1) (car row-2))))
|
||||||
|
("Month" 20 t)
|
||||||
|
("Graph" 31 t)]
|
||||||
|
"Vector specifying format of `chronometrist-task-graph' buffer.
|
||||||
|
See `tabulated-list-format'."
|
||||||
|
:type '(vector))
|
||||||
|
|
||||||
|
(defvar chronometrist-task-graph-schema-transformers nil
|
||||||
|
"List of functions to transform `chronometrist-task-graph-schema' (which see).
|
||||||
|
This is passed to `chronometrist-run-transformers', which see.
|
||||||
|
|
||||||
|
Extensions adding to this list to increase the number of columns
|
||||||
|
will also need to modify the value of `tabulated-list-entries' by
|
||||||
|
using `chronometrist-task-graph-row-transformers'.")
|
||||||
|
|
||||||
|
(defvar chronometrist-task-graph-row-transformers nil
|
||||||
|
"List of functions to transform each row of `chronometrist-task-graph-rows'.
|
||||||
|
This is passed to `chronometrist-run-transformers', which see.
|
||||||
|
|
||||||
|
Extensions adding to this list to increase the number of columns
|
||||||
|
will also need to modify the value of `tabulated-list-format' by
|
||||||
|
using `chronometrist-task-graph-schema-transformers'.")
|
||||||
|
|
||||||
|
(defun chronometrist-task-graph-rows ()
|
||||||
|
"Return rows to be displayed in the `chronometrist-task-graph' buffer.
|
||||||
|
Return value is a list as specified by `tabulated-list-entries'."
|
||||||
|
(cl-loop with index = 1
|
||||||
|
for plist in (gethash (chronometrist-events-last-date) chronometrist-events) collect
|
||||||
|
(-let* (((&plist :name name :tags tags :start start :stop stop) plist)
|
||||||
|
)
|
||||||
|
(--> (vconcat (vector index-string name)
|
||||||
|
(when chronometrist-task-graph-display-tags (vector tags))
|
||||||
|
(when chronometrist-task-graph-display-key-values (vector key-values))
|
||||||
|
(vector duration timespan))
|
||||||
|
(list index it)
|
||||||
|
(chronometrist-run-transformers chronometrist-task-graph-row-transformers it)))
|
||||||
|
do (cl-incf index)))
|
||||||
|
|
||||||
|
(define-derived-mode chronometrist-task-graph-mode tabulated-list-mode "Task Graph"
|
||||||
|
"Major mode for `chronometrist-task-graph'."
|
||||||
|
(make-local-variable 'tabulated-list-format)
|
||||||
|
(--> (chronometrist-run-transformers chronometrist-task-graph-schema-transformers
|
||||||
|
chronometrist-task-graph-schema)
|
||||||
|
(setq tabulated-list-format it))
|
||||||
|
(make-local-variable 'tabulated-list-entries)
|
||||||
|
(setq tabulated-list-entries #'chronometrist-task-graph-rows)
|
||||||
|
(make-local-variable 'tabulated-list-sort-key)
|
||||||
|
(tabulated-list-init-header)
|
||||||
|
(run-hooks 'chronometrist-task-graph-mode-hook))
|
||||||
|
|
||||||
|
(defun chronometrist-task-graph ()
|
||||||
|
(interactive)
|
||||||
|
(let ((buffer (get-buffer-create chronometrist-task-graph-buffer-name))
|
||||||
|
(window (save-excursion
|
||||||
|
(get-buffer-window chronometrist-task-graph-buffer-name t))))
|
||||||
|
(cond (window (kill-buffer chronometrist-task-graph-buffer-name))
|
||||||
|
(t (with-current-buffer buffer
|
||||||
|
(switch-to-buffer buffer)
|
||||||
|
(chronometrist-task-graph-mode)
|
||||||
|
(tabulated-list-print))))))
|
||||||
|
|
||||||
(provide 'chronometrist-spark)
|
(provide 'chronometrist-spark)
|
||||||
;;; chronometrist-spark.el ends here
|
;;; chronometrist-spark.el ends here
|
||||||
|
|
|
@ -38,28 +38,28 @@
|
||||||
(require 'spark)
|
(require 'spark)
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
* Code
|
* Code
|
||||||
** custom group :custom:group:
|
** custom group :custom:group:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defgroup chronometrist-spark nil
|
(defgroup chronometrist-spark nil
|
||||||
"Show sparklines in `chronometrist'."
|
"Show sparklines in `chronometrist'."
|
||||||
:group 'applications)
|
:group 'applications)
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** length :custom:variable:
|
** length :custom:variable:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defcustom chronometrist-spark-length 7
|
(defcustom chronometrist-spark-length 7
|
||||||
"Length of each sparkline in number of days."
|
"Length of each sparkline in number of days."
|
||||||
:type 'integer)
|
:type 'integer)
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** show-range :custom:variable:
|
** show-range :custom:variable:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defcustom chronometrist-spark-show-range t
|
(defcustom chronometrist-spark-show-range t
|
||||||
"If non-nil, display range of each sparkline."
|
"If non-nil, display range of each sparkline."
|
||||||
:type 'boolean)
|
:type 'boolean)
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** range :function:
|
** range :function:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defun chronometrist-spark-range (durations)
|
(defun chronometrist-spark-range (durations)
|
||||||
"Return range for DURATIONS as a string.
|
"Return range for DURATIONS as a string.
|
||||||
|
@ -86,7 +86,7 @@ DURATIONS must be a list of integer seconds."
|
||||||
(should (equal (chronometrist-spark-range '(60 0 0)) "(1m)"))
|
(should (equal (chronometrist-spark-range '(60 0 0)) "(1m)"))
|
||||||
(should (equal (chronometrist-spark-range '(60 0 120)) "(1m~2m)")))
|
(should (equal (chronometrist-spark-range '(60 0 120)) "(1m~2m)")))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
** TODO row-transformer :function:
|
** TODO row-transformer :function:
|
||||||
if larger than 7
|
if larger than 7
|
||||||
add space after (% length 7)th element
|
add space after (% length 7)th element
|
||||||
then add space after every 7 elements
|
then add space after every 7 elements
|
||||||
|
@ -121,7 +121,7 @@ ROW must be a valid element of the list specified by
|
||||||
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** TODO schema-transformer :function:
|
** TODO schema-transformer :function:
|
||||||
calculate length while accounting for space
|
calculate length while accounting for space
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
@ -136,7 +136,7 @@ SCHEMA should be a vector as specified by `tabulated-list-format'."
|
||||||
t)]))
|
t)]))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** setup :writer:
|
** setup :writer:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defun chronometrist-spark-setup ()
|
(defun chronometrist-spark-setup ()
|
||||||
"Add `chronometrist-sparkline' functions to `chronometrist' hooks."
|
"Add `chronometrist-sparkline' functions to `chronometrist' hooks."
|
||||||
|
@ -144,7 +144,7 @@ SCHEMA should be a vector as specified by `tabulated-list-format'."
|
||||||
(add-to-list 'chronometrist-schema-transformers #'chronometrist-spark-schema-transformer))
|
(add-to-list 'chronometrist-schema-transformers #'chronometrist-spark-schema-transformer))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** teardown :writer:
|
** teardown :writer:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defun chronometrist-spark-teardown ()
|
(defun chronometrist-spark-teardown ()
|
||||||
"Remove `chronometrist-sparkline' functions from `chronometrist' hooks."
|
"Remove `chronometrist-sparkline' functions from `chronometrist' hooks."
|
||||||
|
@ -154,7 +154,7 @@ SCHEMA should be a vector as specified by `tabulated-list-format'."
|
||||||
(remove #'chronometrist-spark-schema-transformer chronometrist-schema-transformers)))
|
(remove #'chronometrist-spark-schema-transformer chronometrist-schema-transformers)))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** minor-mode :minor:mode:
|
** minor-mode :minor:mode:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(define-minor-mode chronometrist-spark-minor-mode
|
(define-minor-mode chronometrist-spark-minor-mode
|
||||||
nil nil nil nil
|
nil nil nil nil
|
||||||
|
@ -162,6 +162,136 @@ SCHEMA should be a vector as specified by `tabulated-list-format'."
|
||||||
(if chronometrist-spark-minor-mode (chronometrist-spark-setup) (chronometrist-spark-teardown)))
|
(if chronometrist-spark-minor-mode (chronometrist-spark-setup) (chronometrist-spark-teardown)))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
** task graph view
|
||||||
|
*** prompt
|
||||||
|
*** task-durations-month
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defun chronometrist-task-durations-month (task iso-year-month)
|
||||||
|
(let* ((start-ts (chronometrist-iso-date-to-ts (concat iso-year-month "-01")))
|
||||||
|
;; last date of month
|
||||||
|
(stop-ts (ts-adjust 'month 1 'day -1 start-ts)))
|
||||||
|
(cl-loop with current = start-ts
|
||||||
|
while (not (ts> current stop-ts))
|
||||||
|
collect (chronometrist-task-time-one-day task current)
|
||||||
|
do (setq current (ts-adjust 'day 1 current)))))
|
||||||
|
#+END_SRC
|
||||||
|
**** tests
|
||||||
|
#+BEGIN_SRC emacs-lisp :tangle chronometrist-spark-tests.el :load test
|
||||||
|
(ert-deftest chronometrist-task-durations-month ()
|
||||||
|
(should
|
||||||
|
(--every-p #'integerp (chronometrist-task-durations-month "Anything" "2021-01"))))
|
||||||
|
#+END_SRC
|
||||||
|
*** task-graph :custom:group:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defgroup chronometrist-task-graph nil
|
||||||
|
"Task-specific monthly/weekly graph for the `chronometrist' time tracker."
|
||||||
|
:group 'chronometrist)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** buffer-name :custom:variable:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defcustom chronometrist-task-graph-buffer-name "*chronometrist-task-graph*"
|
||||||
|
"Name of buffer created by `chronometrist-task-graph'."
|
||||||
|
:type 'string)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** default-unit :custom:variable:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defcustom chronometrist-task-graph-default-unit :month
|
||||||
|
"Default unit for `chronometrist-task-graph'.
|
||||||
|
Values may be either `:month' or `:week'."
|
||||||
|
:type '(radio (const :tag "Month" :month) (const :tag "Week" :week)))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** schema :custom:variable:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defcustom chronometrist-task-graph-schema
|
||||||
|
[("#" 3 (lambda (row-1 row-2) (< (car row-1) (car row-2))))
|
||||||
|
("Month" 20 t)
|
||||||
|
("Graph" 31 t)]
|
||||||
|
"Vector specifying format of `chronometrist-task-graph' buffer.
|
||||||
|
See `tabulated-list-format'."
|
||||||
|
:type '(vector))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** schema-transformers :extension:variable:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defvar chronometrist-task-graph-schema-transformers nil
|
||||||
|
"List of functions to transform `chronometrist-task-graph-schema' (which see).
|
||||||
|
This is passed to `chronometrist-run-transformers', which see.
|
||||||
|
|
||||||
|
Extensions adding to this list to increase the number of columns
|
||||||
|
will also need to modify the value of `tabulated-list-entries' by
|
||||||
|
using `chronometrist-task-graph-row-transformers'.")
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** row-transformers :extension:variable:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defvar chronometrist-task-graph-row-transformers nil
|
||||||
|
"List of functions to transform each row of `chronometrist-task-graph-rows'.
|
||||||
|
This is passed to `chronometrist-run-transformers', which see.
|
||||||
|
|
||||||
|
Extensions adding to this list to increase the number of columns
|
||||||
|
will also need to modify the value of `tabulated-list-format' by
|
||||||
|
using `chronometrist-task-graph-schema-transformers'.")
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** months :variable:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defvar chronometrist-task-graph-months
|
||||||
|
'("January" "February" "March" "April" "May" "June"
|
||||||
|
"July" "August" "September" "October" "November" "December"))
|
||||||
|
#+END_SRC
|
||||||
|
*** rows :function:
|
||||||
|
1. check default unit
|
||||||
|
2.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defun chronometrist-task-graph-rows ()
|
||||||
|
"Return rows to be displayed in the `chronometrist-task-graph' buffer.
|
||||||
|
Return value is a list as specified by `tabulated-list-entries'."
|
||||||
|
(cl-loop with index = 1
|
||||||
|
for month in chronometrist-task-graph-months collect
|
||||||
|
(-let* (((&plist :name name :tags tags :start start :stop stop) plist)
|
||||||
|
)
|
||||||
|
(--> (vconcat (vector index-string name)
|
||||||
|
(when chronometrist-task-graph-display-tags (vector tags))
|
||||||
|
(when chronometrist-task-graph-display-key-values (vector key-values))
|
||||||
|
(vector duration timespan))
|
||||||
|
(list index it)
|
||||||
|
(chronometrist-run-transformers chronometrist-task-graph-row-transformers it)))
|
||||||
|
do (cl-incf index)))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** chronometrist-task-graph-mode :major:mode:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(define-derived-mode chronometrist-task-graph-mode tabulated-list-mode "Task Graph"
|
||||||
|
"Major mode for `chronometrist-task-graph'."
|
||||||
|
(make-local-variable 'tabulated-list-format)
|
||||||
|
(--> (chronometrist-run-transformers chronometrist-task-graph-schema-transformers
|
||||||
|
chronometrist-task-graph-schema)
|
||||||
|
(setq tabulated-list-format it))
|
||||||
|
(make-local-variable 'tabulated-list-entries)
|
||||||
|
(setq tabulated-list-entries #'chronometrist-task-graph-rows)
|
||||||
|
(make-local-variable 'tabulated-list-sort-key)
|
||||||
|
(tabulated-list-init-header)
|
||||||
|
(run-hooks 'chronometrist-task-graph-mode-hook))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** chronometrist-task-graph :command:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defun chronometrist-task-graph ()
|
||||||
|
(interactive)
|
||||||
|
(let ((buffer (get-buffer-create chronometrist-task-graph-buffer-name))
|
||||||
|
(window (save-excursion
|
||||||
|
(get-buffer-window chronometrist-task-graph-buffer-name t))))
|
||||||
|
(cond (window (kill-buffer chronometrist-task-graph-buffer-name))
|
||||||
|
(t (with-current-buffer buffer
|
||||||
|
(switch-to-buffer buffer)
|
||||||
|
(chronometrist-task-graph-mode)
|
||||||
|
(tabulated-list-print))))))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
* Provide
|
* Provide
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(provide 'chronometrist-spark)
|
(provide 'chronometrist-spark)
|
||||||
|
|
|
@ -2087,7 +2087,7 @@ Return value is a list as specified by `tabulated-list-entries'."
|
||||||
(setq tabulated-list-entries #'chronometrist-details-rows)
|
(setq tabulated-list-entries #'chronometrist-details-rows)
|
||||||
(make-local-variable 'tabulated-list-sort-key)
|
(make-local-variable 'tabulated-list-sort-key)
|
||||||
(tabulated-list-init-header)
|
(tabulated-list-init-header)
|
||||||
(run-hooks 'chronometrist-mode-hook))
|
(run-hooks 'chronometrist-details-mode-hook))
|
||||||
|
|
||||||
(defun chronometrist-details ()
|
(defun chronometrist-details ()
|
||||||
(interactive)
|
(interactive)
|
||||||
|
|
|
@ -976,7 +976,7 @@ Boilerplate for updating state between file operations in tests.
|
||||||
(list :last (chronometrist-file-hash :before-last nil)
|
(list :last (chronometrist-file-hash :before-last nil)
|
||||||
:rest (chronometrist-file-hash nil :before-last t)))))
|
:rest (chronometrist-file-hash nil :before-last t)))))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
*** chronometrist-file :custom:variable:
|
*** chronometrist-file :custom:variable:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defcustom chronometrist-file
|
(defcustom chronometrist-file
|
||||||
(locate-user-emacs-file "chronometrist.sexp")
|
(locate-user-emacs-file "chronometrist.sexp")
|
||||||
|
@ -1510,7 +1510,7 @@ The data from =chronometrist-events= is used by most (all?) interval-consuming f
|
||||||
(setq chronometrist--file-state nil)
|
(setq chronometrist--file-state nil)
|
||||||
(chronometrist-refresh))
|
(chronometrist-refresh))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
*** chronometrist-events :variable:
|
*** chronometrist-events :variable:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:VALUE: hash table
|
:VALUE: hash table
|
||||||
:END:
|
:END:
|
||||||
|
@ -2099,7 +2099,7 @@ Return the value returned by Fₙ."
|
||||||
See `tabulated-list-format'."
|
See `tabulated-list-format'."
|
||||||
:type '(vector))
|
:type '(vector))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
**** chronometrist-mode-hook :hook:normal:
|
**** chronometrist-mode-hook :hook:normal:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defvar chronometrist-mode-hook nil
|
(defvar chronometrist-mode-hook nil
|
||||||
"Normal hook run at the very end of `chronometrist-mode'.")
|
"Normal hook run at the very end of `chronometrist-mode'.")
|
||||||
|
@ -2314,7 +2314,7 @@ refresh the `chronometrist' buffer."
|
||||||
(chronometrist-out))
|
(chronometrist-out))
|
||||||
t))
|
t))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
**** chronometrist-in :command:
|
**** chronometrist-in :command:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defun chronometrist-in (task &optional _prefix)
|
(defun chronometrist-in (task &optional _prefix)
|
||||||
"Clock in to TASK; record current time in `chronometrist-file'.
|
"Clock in to TASK; record current time in `chronometrist-file'.
|
||||||
|
@ -2324,7 +2324,7 @@ TASK is the name of the task, a string. PREFIX is ignored."
|
||||||
(chronometrist-sexp-new plist)
|
(chronometrist-sexp-new plist)
|
||||||
(chronometrist-refresh)))
|
(chronometrist-refresh)))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
**** chronometrist-out :command:
|
**** chronometrist-out :command:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defun chronometrist-out (&optional _prefix)
|
(defun chronometrist-out (&optional _prefix)
|
||||||
"Record current moment as stop time to last s-exp in `chronometrist-file'.
|
"Record current moment as stop time to last s-exp in `chronometrist-file'.
|
||||||
|
@ -2778,7 +2778,7 @@ Argument _FS-EVENT is ignored."
|
||||||
'(change)
|
'(change)
|
||||||
#'chronometrist-refresh-file))))
|
#'chronometrist-refresh-file))))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
**** chronometrist-report :command:
|
**** chronometrist-report :command:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun chronometrist-report (&optional keep-date)
|
(defun chronometrist-report (&optional keep-date)
|
||||||
|
@ -3307,7 +3307,7 @@ Return value is a list as specified by `tabulated-list-entries'."
|
||||||
(setq tabulated-list-entries #'chronometrist-details-rows)
|
(setq tabulated-list-entries #'chronometrist-details-rows)
|
||||||
(make-local-variable 'tabulated-list-sort-key)
|
(make-local-variable 'tabulated-list-sort-key)
|
||||||
(tabulated-list-init-header)
|
(tabulated-list-init-header)
|
||||||
(run-hooks 'chronometrist-mode-hook))
|
(run-hooks 'chronometrist-details-mode-hook))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
**** chronometrist-details :command:
|
**** chronometrist-details :command:
|
||||||
|
|
Reference in New Issue