feat(details): create new buffer for each range
This commit is contained in:
parent
224a7fec3f
commit
661369188e
|
@ -1954,10 +1954,15 @@ If ARG is a numeric argument, go forward that many times."
|
||||||
"Details buffer for the `chronometrist' time tracker."
|
"Details buffer for the `chronometrist' time tracker."
|
||||||
:group 'chronometrist)
|
:group 'chronometrist)
|
||||||
|
|
||||||
(defcustom chronometrist-details-buffer-name "*chronometrist-details*"
|
(defcustom chronometrist-details-buffer-name-base "chronometrist-details"
|
||||||
"Name of buffer created by `chronometrist-details'."
|
"Name of buffer created by `chronometrist-details'."
|
||||||
:type 'string)
|
:type 'string)
|
||||||
|
|
||||||
|
(defun chronometrist-details-buffer-name (&optional suffix)
|
||||||
|
(if suffix
|
||||||
|
(format "*%s_%s*" chronometrist-details-buffer-name-base suffix)
|
||||||
|
(format "*%s*" chronometrist-details-buffer-name-base)))
|
||||||
|
|
||||||
(defcustom chronometrist-details-display-tags "%s"
|
(defcustom chronometrist-details-display-tags "%s"
|
||||||
"How to display tags in `chronometrist-details' buffers.
|
"How to display tags in `chronometrist-details' buffers.
|
||||||
Value can be
|
Value can be
|
||||||
|
@ -2098,16 +2103,21 @@ Return value is a list as specified by `tabulated-list-entries'."
|
||||||
(tabulated-list-init-header)
|
(tabulated-list-init-header)
|
||||||
(run-hooks 'chronometrist-mode-hook))
|
(run-hooks 'chronometrist-mode-hook))
|
||||||
|
|
||||||
|
(defun chronometrist-details-setup-buffer (buffer-or-name)
|
||||||
|
"Enable `chronometrist-details-mode' in BUFFER-OR-NAME and switch to it.
|
||||||
|
BUFFER-OR-NAME must be an existing buffer."
|
||||||
|
(with-current-buffer buffer-or-name
|
||||||
|
(switch-to-buffer buffer-or-name)
|
||||||
|
(chronometrist-details-mode)
|
||||||
|
(tabulated-list-print)))
|
||||||
|
|
||||||
(defun chronometrist-details ()
|
(defun chronometrist-details ()
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((buffer (get-buffer-create chronometrist-details-buffer-name))
|
(let ((buffer (get-buffer-create (chronometrist-details-buffer-name)))
|
||||||
(window (save-excursion
|
(window (save-excursion
|
||||||
(get-buffer-window chronometrist-details-buffer-name t))))
|
(get-buffer-window buffer t))))
|
||||||
(cond (window (kill-buffer chronometrist-details-buffer-name))
|
(cond (window (kill-buffer buffer))
|
||||||
(t (with-current-buffer buffer
|
(t (chronometrist-details-setup-buffer buffer)))))
|
||||||
(switch-to-buffer buffer)
|
|
||||||
(chronometrist-details-mode)
|
|
||||||
(tabulated-list-print))))))
|
|
||||||
|
|
||||||
(defvar chronometrist-details-range nil
|
(defvar chronometrist-details-range nil
|
||||||
"Time range for intervals displayed by `chronometrist-details'.
|
"Time range for intervals displayed by `chronometrist-details'.
|
||||||
|
@ -2115,8 +2125,9 @@ Values can be one of -
|
||||||
nil - no range. Display all intervals for today.
|
nil - no range. Display all intervals for today.
|
||||||
An ISO date string - display intervals for this date.
|
An ISO date string - display intervals for this date.
|
||||||
A cons cell in the form (BEGIN . END), where BEGIN and END are
|
A cons cell in the form (BEGIN . END), where BEGIN and END are
|
||||||
ISO date or date-time strings - display intervals in this range.
|
ISO date strings (inclusive) or date-time strings (\"BEGIN\"
|
||||||
Dates are inclusive.")
|
inclusive, \"END\" exclusive) - display intervals in this
|
||||||
|
range.")
|
||||||
(make-variable-buffer-local 'chronometrist-details-range)
|
(make-variable-buffer-local 'chronometrist-details-range)
|
||||||
|
|
||||||
(defun chronometrist-iso-date-p (string)
|
(defun chronometrist-iso-date-p (string)
|
||||||
|
@ -2160,41 +2171,51 @@ TABLE must be a hash table similar to `chronometrist-events'."
|
||||||
;; (chronometrist-details-intervals-for-range '("2021-06-01" . "2021-06-03") chronometrist-events)
|
;; (chronometrist-details-intervals-for-range '("2021-06-01" . "2021-06-03") chronometrist-events)
|
||||||
;; (chronometrist-details-intervals-for-range '("2021-06-02T01:00+05:30" . "2021-06-02T03:00+05:30") chronometrist-events)
|
;; (chronometrist-details-intervals-for-range '("2021-06-02T01:00+05:30" . "2021-06-02T03:00+05:30") chronometrist-events)
|
||||||
|
|
||||||
|
(defun chronometrist-details-input-to-value (input)
|
||||||
|
(pcase input
|
||||||
|
('nil nil)
|
||||||
|
(`(,date) date)
|
||||||
|
(`(,begin ,end)
|
||||||
|
(let* ((date-p (seq-find #'chronometrist-iso-date-p input))
|
||||||
|
(begin-date (car (hash-table-keys chronometrist-events)))
|
||||||
|
(begin-iso-ts (ts-format
|
||||||
|
"%FT%T%z" (chronometrist-iso-to-ts begin-date)))
|
||||||
|
(end-date (car (last (hash-table-keys chronometrist-events))))
|
||||||
|
(end-iso-ts (chronometrist-format-time-iso8601))
|
||||||
|
(begin (if (equal begin "begin")
|
||||||
|
(if date-p begin-date begin-iso-ts)
|
||||||
|
begin))
|
||||||
|
(end (if (equal end "end")
|
||||||
|
(if date-p end-date end-iso-ts)
|
||||||
|
end)))
|
||||||
|
(cons begin end)))
|
||||||
|
(_ (error "Unsupported range."))))
|
||||||
|
|
||||||
(defun chronometrist-details-set-range ()
|
(defun chronometrist-details-set-range ()
|
||||||
"Prompt user for range for current `chronometrist-details' buffer."
|
"Prompt user for range for current `chronometrist-details' buffer."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((input (completing-read-multiple
|
(let* ((input (completing-read-multiple
|
||||||
(concat "Range (blank, ISO-8601 date, "
|
(concat "Range (blank, ISO-8601 date, "
|
||||||
"or two ISO-8601 dates/timestamps): ")
|
"or two ISO-8601 dates/timestamps): ")
|
||||||
(append '("begin" "end")
|
(append '("begin" "end")
|
||||||
(reverse (hash-table-keys chronometrist-events)))
|
(reverse (hash-table-keys chronometrist-events)))
|
||||||
nil nil (pcase chronometrist-details-range
|
nil nil (pcase chronometrist-details-range
|
||||||
('nil nil)
|
('nil nil)
|
||||||
((pred stringp)
|
((pred stringp)
|
||||||
(format "%s" chronometrist-details-range))
|
(format "%s" chronometrist-details-range))
|
||||||
(`(,begin . ,end)
|
(`(,begin . ,end)
|
||||||
(format "%s,%s" begin end)))
|
(format "%s,%s" begin end)))
|
||||||
'chronometrist-details-range-history)))
|
'chronometrist-details-range-history))
|
||||||
(pcase input
|
(new-value (chronometrist-details-input-to-value input))
|
||||||
('nil (setq-local chronometrist-details-range nil))
|
(buffer-name (pcase new-value
|
||||||
(`(,date)
|
('date
|
||||||
(setq-local chronometrist-details-range date))
|
(chronometrist-details-buffer-name date))
|
||||||
(`(,begin ,end)
|
(`(,begin . ,end)
|
||||||
(let* ((date-p (seq-find #'chronometrist-iso-date-p input))
|
(chronometrist-details-buffer-name (format "%s_%s" begin end))))))
|
||||||
(begin-date (car (hash-table-keys chronometrist-events)))
|
(chronometrist-details-setup-buffer (get-buffer-create buffer-name))
|
||||||
(begin-iso-ts (ts-format
|
(with-current-buffer buffer-name
|
||||||
"%FT%T%z" (chronometrist-iso-to-ts begin-date)))
|
(setq-local chronometrist-details-range new-value)
|
||||||
(end-date (car (last (hash-table-keys chronometrist-events))))
|
(tabulated-list-revert))))
|
||||||
(end-iso-ts (chronometrist-format-time-iso8601))
|
|
||||||
(begin (if (equal begin "begin")
|
|
||||||
(if date-p begin-date begin-iso-ts)
|
|
||||||
begin))
|
|
||||||
(end (if (equal end "end")
|
|
||||||
(if date-p end-date end-iso-ts)
|
|
||||||
end)))
|
|
||||||
(setq-local chronometrist-details-range (cons begin end))))
|
|
||||||
(_ (error "Unsupported range.")))
|
|
||||||
(tabulated-list-revert)))
|
|
||||||
|
|
||||||
(defvar chronometrist-details-filter nil
|
(defvar chronometrist-details-filter nil
|
||||||
"Parameters to filter intervals displayed by `chronometrist-details'.
|
"Parameters to filter intervals displayed by `chronometrist-details'.
|
||||||
|
|
|
@ -3128,14 +3128,22 @@ If ARG is a numeric argument, go forward that many times."
|
||||||
:group 'chronometrist)
|
:group 'chronometrist)
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
**** buffer-name :custom:variable:
|
**** buffer-name-base :custom:variable:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defcustom chronometrist-details-buffer-name "*chronometrist-details*"
|
(defcustom chronometrist-details-buffer-name-base "chronometrist-details"
|
||||||
"Name of buffer created by `chronometrist-details'."
|
"Name of buffer created by `chronometrist-details'."
|
||||||
:type 'string)
|
:type 'string)
|
||||||
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
**** buffer-name :reader:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defun chronometrist-details-buffer-name (&optional suffix)
|
||||||
|
(if suffix
|
||||||
|
(format "*%s_%s*" chronometrist-details-buffer-name-base suffix)
|
||||||
|
(format "*%s*" chronometrist-details-buffer-name-base)))
|
||||||
|
|
||||||
|
#+END_SRC
|
||||||
**** display-tags :custom:variable:
|
**** display-tags :custom:variable:
|
||||||
If the value of this variable is a function and the string it returns contains a newline, the results may be undesirable...but hardly unrecoverable, so try it and see, if you wish.
|
If the value of this variable is a function and the string it returns contains a newline, the results may be undesirable...but hardly unrecoverable, so try it and see, if you wish.
|
||||||
|
|
||||||
|
@ -3335,18 +3343,26 @@ Return value is a list as specified by `tabulated-list-entries'."
|
||||||
(run-hooks 'chronometrist-mode-hook))
|
(run-hooks 'chronometrist-mode-hook))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
**** details-setup-buffer :procedure:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defun chronometrist-details-setup-buffer (buffer-or-name)
|
||||||
|
"Enable `chronometrist-details-mode' in BUFFER-OR-NAME and switch to it.
|
||||||
|
BUFFER-OR-NAME must be an existing buffer."
|
||||||
|
(with-current-buffer buffer-or-name
|
||||||
|
(switch-to-buffer buffer-or-name)
|
||||||
|
(chronometrist-details-mode)
|
||||||
|
(tabulated-list-print)))
|
||||||
|
|
||||||
|
#+END_SRC
|
||||||
**** chronometrist-details :command:
|
**** chronometrist-details :command:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defun chronometrist-details ()
|
(defun chronometrist-details ()
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((buffer (get-buffer-create chronometrist-details-buffer-name))
|
(let ((buffer (get-buffer-create (chronometrist-details-buffer-name)))
|
||||||
(window (save-excursion
|
(window (save-excursion
|
||||||
(get-buffer-window chronometrist-details-buffer-name t))))
|
(get-buffer-window buffer t))))
|
||||||
(cond (window (kill-buffer chronometrist-details-buffer-name))
|
(cond (window (kill-buffer buffer))
|
||||||
(t (with-current-buffer buffer
|
(t (chronometrist-details-setup-buffer buffer)))))
|
||||||
(switch-to-buffer buffer)
|
|
||||||
(chronometrist-details-mode)
|
|
||||||
(tabulated-list-print))))))
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
**** range :variable:
|
**** range :variable:
|
||||||
|
@ -3357,8 +3373,9 @@ Values can be one of -
|
||||||
nil - no range. Display all intervals for today.
|
nil - no range. Display all intervals for today.
|
||||||
An ISO date string - display intervals for this date.
|
An ISO date string - display intervals for this date.
|
||||||
A cons cell in the form (BEGIN . END), where BEGIN and END are
|
A cons cell in the form (BEGIN . END), where BEGIN and END are
|
||||||
ISO date or date-time strings - display intervals in this range.
|
ISO date strings (inclusive) or date-time strings (\"BEGIN\"
|
||||||
Dates are inclusive.")
|
inclusive, \"END\" exclusive) - display intervals in this
|
||||||
|
range.")
|
||||||
(make-variable-buffer-local 'chronometrist-details-range)
|
(make-variable-buffer-local 'chronometrist-details-range)
|
||||||
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
@ -3410,44 +3427,57 @@ TABLE must be a hash table similar to `chronometrist-events'."
|
||||||
;; (chronometrist-details-intervals-for-range '("2021-06-01" . "2021-06-03") chronometrist-events)
|
;; (chronometrist-details-intervals-for-range '("2021-06-01" . "2021-06-03") chronometrist-events)
|
||||||
;; (chronometrist-details-intervals-for-range '("2021-06-02T01:00+05:30" . "2021-06-02T03:00+05:30") chronometrist-events)
|
;; (chronometrist-details-intervals-for-range '("2021-06-02T01:00+05:30" . "2021-06-02T03:00+05:30") chronometrist-events)
|
||||||
|
|
||||||
|
#+END_SRC
|
||||||
|
**** input-to-value :function:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defun chronometrist-details-input-to-value (input)
|
||||||
|
(pcase input
|
||||||
|
('nil nil)
|
||||||
|
(`(,date) date)
|
||||||
|
(`(,begin ,end)
|
||||||
|
(let* ((date-p (seq-find #'chronometrist-iso-date-p input))
|
||||||
|
(begin-date (car (hash-table-keys chronometrist-events)))
|
||||||
|
(begin-iso-ts (ts-format
|
||||||
|
"%FT%T%z" (chronometrist-iso-to-ts begin-date)))
|
||||||
|
(end-date (car (last (hash-table-keys chronometrist-events))))
|
||||||
|
(end-iso-ts (chronometrist-format-time-iso8601))
|
||||||
|
(begin (if (equal begin "begin")
|
||||||
|
(if date-p begin-date begin-iso-ts)
|
||||||
|
begin))
|
||||||
|
(end (if (equal end "end")
|
||||||
|
(if date-p end-date end-iso-ts)
|
||||||
|
end)))
|
||||||
|
(cons begin end)))
|
||||||
|
(_ (error "Unsupported range."))))
|
||||||
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
**** set-range :command:writer:
|
**** set-range :command:writer:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defun chronometrist-details-set-range ()
|
(defun chronometrist-details-set-range ()
|
||||||
"Prompt user for range for current `chronometrist-details' buffer."
|
"Prompt user for range for current `chronometrist-details' buffer."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((input (completing-read-multiple
|
(let* ((input (completing-read-multiple
|
||||||
(concat "Range (blank, ISO-8601 date, "
|
(concat "Range (blank, ISO-8601 date, "
|
||||||
"or two ISO-8601 dates/timestamps): ")
|
"or two ISO-8601 dates/timestamps): ")
|
||||||
(append '("begin" "end")
|
(append '("begin" "end")
|
||||||
(reverse (hash-table-keys chronometrist-events)))
|
(reverse (hash-table-keys chronometrist-events)))
|
||||||
nil nil (pcase chronometrist-details-range
|
nil nil (pcase chronometrist-details-range
|
||||||
('nil nil)
|
('nil nil)
|
||||||
((pred stringp)
|
((pred stringp)
|
||||||
(format "%s" chronometrist-details-range))
|
(format "%s" chronometrist-details-range))
|
||||||
(`(,begin . ,end)
|
(`(,begin . ,end)
|
||||||
(format "%s,%s" begin end)))
|
(format "%s,%s" begin end)))
|
||||||
'chronometrist-details-range-history)))
|
'chronometrist-details-range-history))
|
||||||
(pcase input
|
(new-value (chronometrist-details-input-to-value input))
|
||||||
('nil (setq-local chronometrist-details-range nil))
|
(buffer-name (pcase new-value
|
||||||
(`(,date)
|
('date
|
||||||
(setq-local chronometrist-details-range date))
|
(chronometrist-details-buffer-name date))
|
||||||
(`(,begin ,end)
|
(`(,begin . ,end)
|
||||||
(let* ((date-p (seq-find #'chronometrist-iso-date-p input))
|
(chronometrist-details-buffer-name (format "%s_%s" begin end))))))
|
||||||
(begin-date (car (hash-table-keys chronometrist-events)))
|
(chronometrist-details-setup-buffer (get-buffer-create buffer-name))
|
||||||
(begin-iso-ts (ts-format
|
(with-current-buffer buffer-name
|
||||||
"%FT%T%z" (chronometrist-iso-to-ts begin-date)))
|
(setq-local chronometrist-details-range new-value)
|
||||||
(end-date (car (last (hash-table-keys chronometrist-events))))
|
(tabulated-list-revert))))
|
||||||
(end-iso-ts (chronometrist-format-time-iso8601))
|
|
||||||
(begin (if (equal begin "begin")
|
|
||||||
(if date-p begin-date begin-iso-ts)
|
|
||||||
begin))
|
|
||||||
(end (if (equal end "end")
|
|
||||||
(if date-p end-date end-iso-ts)
|
|
||||||
end)))
|
|
||||||
(setq-local chronometrist-details-range (cons begin end))))
|
|
||||||
(_ (error "Unsupported range.")))
|
|
||||||
(tabulated-list-revert)))
|
|
||||||
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
**** filter :variable:
|
**** filter :variable:
|
||||||
|
|
Reference in New Issue