[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/tmr 2fc61f9595 1/2: WIP: Create tabulated-list view + u
From: |
ELPA Syncer |
Subject: |
[elpa] externals/tmr 2fc61f9595 1/2: WIP: Create tabulated-list view + use a struct for tmr--timers |
Date: |
Sun, 8 May 2022 04:57:53 -0400 (EDT) |
branch: externals/tmr
commit 2fc61f95950b564cb3ceefe57f1fec339adc2969
Author: Damien Cassou <damien@cassou.me>
Commit: Protesilaos Stavrou <info@protesilaos.com>
WIP: Create tabulated-list view + use a struct for tmr--timers
---
tmr-tabulated.el | 69 ++++++++++++++++++++++++++++++++++++++++
tmr.el | 96 ++++++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 141 insertions(+), 24 deletions(-)
diff --git a/tmr-tabulated.el b/tmr-tabulated.el
new file mode 100644
index 0000000000..c81f3c63cb
--- /dev/null
+++ b/tmr-tabulated.el
@@ -0,0 +1,69 @@
+;;; tmr-tabulated.el --- Display timers in a tabulated list -*-
lexical-binding: t -*-
+
+;; Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+;; Author: Damien Cassou <damien@cassou.me>,
+;; Protesilaos Stavrou <info@protesilaos.com>
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; TODO
+
+;;; Code:
+
+(require 'tmr)
+
+;;;###autoload
+(defun tmr-tabulated-view ()
+ "Open a tabulated list buffer listing tmr timers."
+ (interactive)
+ (switch-to-buffer (get-buffer-create "*tmr-tabulated-view*"))
+ (tmr-tabulated--set-entries)
+ (tmr-tabulated-mode)
+ (tabulated-list-print))
+
+(defun tmr-tabulated--set-entries ()
+ "Set the value of `tabulated-list-entries' with timers."
+ (setq-local tabulated-list-entries
+ (mapcar #'tmr-tabulated--timer-to-entry tmr--timers)))
+
+(defun tmr-tabulated--timer-to-entry (timer)
+ "Convert TIMER into an entry suitable for `tabulated-list-entries'."
+ (list (tmr--timer-creation-date timer)
+ (vector (tmr--format-creation-date timer)
+ (tmr--format-end-date timer)
+ (if (tmr--timer-donep timer) "✔" "")
+ (or (tmr--timer-description timer) ""))))
+
+(defvar tmr-tabulated-mode-map
+ (let ((map (make-sparse-keymap)))
+ map)
+ "Keybindings for `tmr-tabulated-mode-map'.")
+
+(define-derived-mode tmr-tabulated-mode tabulated-list-mode "TMR"
+ "Major mode to display tmr timers."
+ (setq-local tabulated-list-format
+ [("Start" 10 t)
+ ("End" 10 t)
+ ("Finished?" 10 t)
+ ("Description" 0 t)])
+ (add-hook 'tabulated-list-revert-hook #'tmr-tabulated--set-entries)
+ (tabulated-list-init-header))
+
+(provide 'tmr-tabulated)
+;;; tmr-tabulated.el ends here
diff --git a/tmr.el b/tmr.el
index 0defce9458..357183ae84 100644
--- a/tmr.el
+++ b/tmr.el
@@ -115,6 +115,52 @@ It should take two string arguments: the title and the
message."
:type 'function
:group 'tmr)
+(cl-defstruct (tmr-timer
+ (:constructor tmr--timer-create)
+ (:conc-name tmr--timer-))
+ (creation-date
+ nil
+ :read-only t
+ :documentation "Time at which the timer was created.")
+ (duration
+ nil
+ :read-only t
+ :documentation "Number of seconds after `start' indicating when the timer
finishes.")
+ (donep
+ nil
+ :read-only nil
+ :documentation "Non-nil if the timer is finished.")
+ (timer-object
+ nil
+ :read-only nil
+ :documentation "The object returned by `run-with-timer'.")
+ (description
+ nil
+ :read-only t
+ :documentation "Optional string describing the purpose of the timer, e.g.,
\"Stop the oven\"."))
+
+(defun tmr--long-description (timer)
+ "Return a human-readable description for TIMER."
+ (let ((start (tmr--format-creation-date timer))
+ (duration (tmr--timer-duration timer))
+ (description (tmr--timer-description timer)))
+ (if description
+ (format "Started at %s with input '%s' and description '%s'" start
duration description)
+ (format "Started at %s with input '%s'" start duration))))
+
+(defun tmr--format-creation-date (timer)
+ "Return a string representing when TIMER was created."
+ (tmr--format-time (tmr--timer-creation-date timer)))
+
+(defun tmr--format-end-date (timer)
+ "Return a string representing when TIMER should finish."
+ (format-time-string "%T" (time-add (tmr--timer-creation-date timer)
+ (tmr--timer-duration timer))))
+
+(defun tmr--format-time (time)
+ "Return a human-readable string representing TIME."
+ (format-time-string "%T" time))
+
(defun tmr--unit (time)
"Determine common time unit for TIME."
(cond
@@ -185,19 +231,21 @@ Read: (info \"(elisp) Desktop Notifications\") for
details."
"Send notification with TITLE and MESSAGE using `tmr-notify-function'."
(funcall tmr-notify-function title message))
-(defun tmr--notify (start &optional description)
- "Send notification for timer with START time.
-Optionally include DESCRIPTION."
- (let ((end (format-time-string "%T"))
- (desc-plain "")
- (desc-propertized ""))
- (when description
- (setq desc-plain (concat "\n" description)
- desc-propertized (concat " [" (propertize description 'face 'bold)
"]")))
+(defun tmr--notify (timer)
+ "Send notification for TIMER."
+ (let* ((description (tmr--timer-description timer))
+ (desc-plain (if description
+ (concat "\n" description)
+ ""))
+ (desc-propertized (if description
+ (concat " [" (propertize description 'face
'bold) "]")
+ ""))
+ (start (tmr--format-creation-date timer))
+ (end (tmr--format-end-date timer)))
+ (setf (tmr--timer-donep timer) t)
(tmr--notify-send-notification
"TMR May Ring (Emacs tmr package)"
- (format "Time is up!\nStarted: %s\nEnded: %s%s"
- start end desc-plain))
+ (format "Time is up!\nStarted: %s\nEnded: %s%s" start end desc-plain))
(message
"TMR %s %s ; %s %s%s"
(propertize "Start:" 'face 'success) start
@@ -239,7 +287,7 @@ multiple timers, prompt for one with completion."
Optionally include DESCRIPTION."
(let* ((specifier (substring time -1))
(amount (substring time 0 -1))
- (start (format-time-string "%T"))
+ (start (tmr--format-time (current-time)))
(unit (pcase specifier
("s" (format "%ss (s == second)" amount))
("h" (format "%sh (h == hour)" amount))
@@ -302,19 +350,19 @@ command `tmr-with-description' instead of this one."
(list
(tmr--read-duration)
(when current-prefix-arg (tmr--description-prompt))))
- (let* ((start (format-time-string "%T"))
- (unit (tmr--unit time))
- (object-desc (if description
- (format "Started at %s with input '%s' and
description '%s'" start time description)
- (format "Started at %s with input '%s'" start time))))
+ (let* ((creation-date (current-time))
+ (duration (tmr--unit time))
+ (timer (tmr--timer-create
+ :description description
+ :creation-date creation-date
+ :duration duration))
+ (timer-object (run-with-timer
+ duration nil
+ #'tmr--notify timer)))
+ (setf (tmr--timer-timer-object timer) timer-object)
(tmr--echo-area time description)
- (push (cons
- object-desc
- (run-with-timer
- unit nil
- 'tmr--notify start description))
- tmr--timers)
- (tmr--log-in-buffer object-desc)))
+ (push timer tmr--timers)
+ (tmr--log-in-buffer (tmr--long-description timer))))
;;;###autoload
(defun tmr-with-description (time description)