branch: elpa/casual
commit 59bd92d024eeb77be4b985611b6675ad5b8f0efe
Merge: 65e9a61038 77c3d73f9e
Author: Charles Choi <[email protected]>
Commit: GitHub <[email protected]>
Merge pull request #307 from
kickingvegas/merge-development-to-main-20251006_140334
Merge development to main 20251006_140334
---
docs/casual.info | Bin 132097 -> 132785 bytes
docs/casual.org | 6 +-
docs/casual.texi | 29 ++++---
docs/images/casual-timezone-planner-screenshot.png | Bin 190433 -> 197780 bytes
docs/timezone.org | 21 +++--
lisp/casual-timezone-utils.el | 88 ++++++++++++++-------
lisp/casual.el | 2 +-
tests/test-casual-timezone-utils.el | 16 +++-
8 files changed, 108 insertions(+), 54 deletions(-)
diff --git a/docs/casual.info b/docs/casual.info
index 0a396eadfa..751861b6d7 100644
Binary files a/docs/casual.info and b/docs/casual.info differ
diff --git a/docs/casual.org b/docs/casual.org
index aadd126484..778a29c2e3 100644
--- a/docs/casual.org
+++ b/docs/casual.org
@@ -5,7 +5,7 @@
#+EMAIL: [email protected]
#+OPTIONS: ':t toc:t author:t email:t H:4 f:t
#+LANGUAGE: en
-#+MACRO: version 2.9.0
+#+MACRO: version 2.9.1
#+MACRO: kbd (eval (org-texinfo-kbd-macro $1))
#+TEXINFO_FILENAME: casual.info
#+TEXINFO_CLASS: casual
@@ -55,7 +55,7 @@ Copyright © 2024-2025 Charles Y. Choi
** Motivations
#+CINDEX: Motivations
-#+TEXINFO: @majorheading Goals
+#+TEXINFO: @subheading Goals
- To provide a keyboard-driven menu UI toolkit for common Emacs commands.
@@ -64,7 +64,7 @@ Copyright © 2024-2025 Charles Y. Choi
- To be a frequently used interface for modes supported by Casual.
-#+TEXINFO: @majorheading Non-Goals
+#+TEXINFO: @subheading Non-Goals
- Full coverage of all Emacs commands.
diff --git a/docs/casual.texi b/docs/casual.texi
index ab469193bf..678806b0cb 100644
--- a/docs/casual.texi
+++ b/docs/casual.texi
@@ -20,7 +20,7 @@ Copyright © 2024-2025 Charles Y@. Choi
@finalout
@titlepage
@title Casual User Guide
-@subtitle for version 2.9.0
+@subtitle for version 2.9.1
@author Charles Y@. Choi (@email{kickingvegas@@gmail.com})
@page
@vskip 0pt plus 1filll
@@ -33,7 +33,7 @@ Copyright © 2024-2025 Charles Y@. Choi
@node Top
@top Casual User Guide
-Version: 2.9.0
+Version: 2.9.1
Casual is a project to re-imagine the primary user interface for Emacs using
keyboard-driven menus.
@@ -300,7 +300,7 @@ Timezone Usage
@cindex Motivations
-@majorheading Goals
+@subheading Goals
@itemize
@item
@@ -314,7 +314,7 @@ To be a frequently used interface for modes supported by
Casual.
@end itemize
-@majorheading Non-Goals
+@subheading Non-Goals
@itemize
@item
@@ -3076,6 +3076,8 @@ Casual Timezone is a library of commands to work with
different time zones. Answ
Casual Timezone only supports systems that have a
@uref{https://en.wikipedia.org/wiki/Tz_database, tz database}.
+Casual Timezone supports viewing multiple time zones in a tabular view with
the command @code{casual-timezone-planner} as shown below:
+
@image{images/casual-timezone-planner-screenshot,,,,png}
@menu
@@ -3090,16 +3092,16 @@ Casual Timezone only supports systems that have a
@uref{https://en.wikipedia.org
Casual Timezone is configured as part of Casual EditKit in the Tools menu
(@code{casual-editkit-tools-tmenu}). Refer to the @ref{EditKit Install} section
for instructions on how to install it.
-The main menu for Casual Timezone is @code{casual-timezone-tmenu} for users
who wish to access it directly.
+The main menu for Casual Timezone can be invoked directly using @code{M-x}
@code{casual-timezone-tmenu}.
@node Timezone Usage
@subsection Timezone Usage
@cindex Timezone Usage
-@image{images/casual-timezone-planner-screenshot,,,,png}
+@image{images/casual-timezone-tmenu-screenshot,,,,png}
-Casual Timezone offers the following commands:
+The main menu for Casual Timezone (@code{casual-timezone-tmenu}) offers the
following commands:
@itemize
@item
@@ -3109,12 +3111,19 @@ Casual Timezone offers the following commands:
@code{casual-timezone-remote-time-to-local} (menu binding: @code{r}) will
convert a date in a remote time zone to its local equivalent.
@item
-@code{casual-timezone-planner} (menu binding: @code{z}) will generate a table
comparing hours between the local and a remote timezone on a certain date.
+@code{casual-timezone-planner} (menu binding: @code{z}) will generate a table
comparing hours between the local and a remote time zone on a certain date.
Multiple remote time zones can be specified.
@end itemize
-These commands are offered in the menu @code{casual-timezone-tmenu} shown
below.
-@image{images/casual-timezone-tmenu-screenshot,,,,png}
+@subheading Timezone Planner
+
+@image{images/casual-timezone-planner-screenshot,,,,png}
+
+The command @code{casual-timezone-planner} will prompt the user for one or
more time zones and a date to compare in tabular form the local time with the
zones selected. Multiple time zones are comma-separated.
+
+In this table, the point can be navigated using the @kbd{p}, @kbd{n},
@kbd{@key{TAB}}, and @kbd{S-@key{TAB}} bindings.
+
+Use the @kbd{T} binding to copy the timestamp under the current point to the
@code{kill-ring}. The @kbd{t} binding will copy all timestamps on the current
line to the @code{kill-ring}.
@menu
* Timezone Formatting::
diff --git a/docs/images/casual-timezone-planner-screenshot.png
b/docs/images/casual-timezone-planner-screenshot.png
index d9d6ac8f2b..7f3ac817c5 100644
Binary files a/docs/images/casual-timezone-planner-screenshot.png and
b/docs/images/casual-timezone-planner-screenshot.png differ
diff --git a/docs/timezone.org b/docs/timezone.org
index 15b8a0018d..d4a8eb0dcd 100644
--- a/docs/timezone.org
+++ b/docs/timezone.org
@@ -6,6 +6,8 @@ Casual Timezone is a library of commands to work with different
time zones. Answ
Casual Timezone only supports systems that have a
[[https://en.wikipedia.org/wiki/Tz_database][tz database]].
+Casual Timezone supports viewing multiple time zones in a tabular view with
the command ~casual-timezone-planner~ as shown below:
+
[[file:images/casual-timezone-planner-screenshot.png]]
** Timezone Install
@@ -16,24 +18,31 @@ Casual Timezone only supports systems that have a
[[https://en.wikipedia.org/wik
Casual Timezone is configured as part of Casual EditKit in the Tools menu
(~casual-editkit-tools-tmenu~). Refer to the [[#editkit-install][EditKit
Install]] section for instructions on how to install it.
-The main menu for Casual Timezone is ~casual-timezone-tmenu~ for users who
wish to access it directly.
+The main menu for Casual Timezone can be invoked directly using ~M-x~
~casual-timezone-tmenu~.
** Timezone Usage
#+CINDEX: Timezone Usage
-[[file:images/casual-timezone-planner-screenshot.png]]
+[[file:images/casual-timezone-tmenu-screenshot.png]]
-Casual Timezone offers the following commands:
+The main menu for Casual Timezone (~casual-timezone-tmenu~) offers the
following commands:
- ~casual-timezone-local-time-to-remote~ (menu binding: ~l~) will convert a
local date to its equivalent in remote time zone.
- ~casual-timezone-remote-time-to-local~ (menu binding: ~r~) will convert a
date in a remote time zone to its local equivalent.
-- ~casual-timezone-planner~ (menu binding: ~z~) will generate a table
comparing hours between the local and a remote timezone on a certain date.
+- ~casual-timezone-planner~ (menu binding: ~z~) will generate a table
comparing hours between the local and a remote time zone on a certain date.
Multiple remote time zones can be specified.
-These commands are offered in the menu ~casual-timezone-tmenu~ shown below.
-[[file:images/casual-timezone-tmenu-screenshot.png]]
+#+TEXINFO: @subheading Timezone Planner
+
+[[file:images/casual-timezone-planner-screenshot.png]]
+
+The command ~casual-timezone-planner~ will prompt the user for one or more
time zones and a date to compare in tabular form the local time with the zones
selected. Multiple time zones are comma-separated.
+
+In this table, the point can be navigated using the {{{kbd(p)}}},
{{{kbd(n)}}}, {{{kbd(TAB)}}}, and {{{kbd(S-TAB)}}} bindings.
+
+Use the {{{kbd(T)}}} binding to copy the timestamp under the current point to
the ~kill-ring~. The {{{kbd(t)}}} binding will copy all timestamps on the
current line to the ~kill-ring~.
*** Timezone Formatting
diff --git a/lisp/casual-timezone-utils.el b/lisp/casual-timezone-utils.el
index 801b765ac4..0eda4308a5 100644
--- a/lisp/casual-timezone-utils.el
+++ b/lisp/casual-timezone-utils.el
@@ -33,6 +33,8 @@
(:next . '("↓" "Next"))
(:forward . '("→" "Forward"))
(:backward . '("←" "Backward"))
+ (:right . '("→" "Right"))
+ (:left . '("←" "Left"))
(:current . '("⨀" "Current Hour")))
"Unicode symbol DB to use for Timezone Transient menus.")
@@ -69,7 +71,7 @@ The specification of this variable conforms to the format
string used by
"Datestamp format used by `casual-timezone-planner'.
This customizable variable determines the reporting format used
-by the command `casual-timezone-planner'. The specification of this
+by the command `casual-timezone-planner'. The specification of this
variable conforms to the format string used by
`format-time-string' as described in Info node `(elisp) Time
Parsing'.
@@ -260,6 +262,7 @@ The format of the timestamp is defined in the variable
"k" #'previous-line
"w" #'world-clock
"z" #'casual-timezone-planner
+ "T" #'casual-timezone-planner-current-point
"c" #'calendar)
(define-derived-mode casual-timezone-planner-mode
@@ -267,10 +270,16 @@ The format of the timestamp is defined in the variable
"Major mode for Timezone Planner."
(hl-line-mode t))
-(defun casual-timezone-planner ()
- "Generate table comparing hours between local and a remote timezone.
+(defun casual-timezone-planner (remote-timezones datestamp)
+ "Generate hours table between local and REMOTE-TIMEZONES on DATESTAMP.
-This command will prompt the user twice:
+REMOTE-TIMEZONES is a list of timezones to compare local time with. It
+can be either be a `list' of strings or a comma or space separated
+`string' type.
+
+DATESTAMP is a string in YYYY-MM-DD format.
+
+When called interactively, this command will prompt the user twice:
1. to specify a remote timezone
2. to specify a calendar day
@@ -280,18 +289,19 @@ updated) comparing the hours between the two timezones.
The report datestamp format can be customized via the variable
`casual-timezone-datestamp-format'.
-Working hours are annotated with a ☼. The range of working hours can be
+Working hours are annotated with a ☼. The range of working hours can be
customized via the variable `casual-timezone-working-hours-range'."
- (interactive)
+ (interactive (list
+ (completing-read-multiple "Remote Timezone(s): "
(casual-timezone-zone-info))
+ (org-read-date)))
+ (when (stringp remote-timezones) (setq remote-timezones (split-string
remote-timezones "[, ]+")))
(unless (not (eq system-type 'windows-nt))
(error "Not available on Windows"))
- (let* ((remote-tz (completing-read-default "Remote Timezone: "
(casual-timezone-zone-info)))
- ;; (tzcode (casual-timezone-offset-8601 (nth 0 (current-time-zone nil
remote-tz))))
- (datestamp (org-read-date))
+ (let* (;; (tzcode (casual-timezone-offset-8601 (nth 0 (current-time-zone nil
remote-tz))))
(local-tz (nth 1 (current-time-zone)))
(start-time (date-to-time (concat datestamp " " "05:00")))
- (increments (seq-map (lambda (x) (seconds-to-time (* x
3600)))(number-sequence 0 25)))
+ (increments (seq-map (lambda (x) (seconds-to-time (* x 3600)))
(number-sequence 0 25)))
(tztimes (seq-map (lambda (x) (time-add start-time x)) increments))
(local-times
(seq-map
@@ -299,13 +309,16 @@ customized via the variable
`casual-timezone-working-hours-range'."
tztimes))
(remote-times
(seq-map
- (lambda (x) (time-to-seconds (date-to-time (format-time-string
- "%Y-%m-%dT%H:%M:%S"
- (date-to-time (format-time-string
(concat x " " local-tz)))
- remote-tz))))
- local-times))
- (tz-data (seq-mapn #'list tztimes remote-times))
- (tz-buffer-name (format "*%s - %s*" local-tz remote-tz)))
+ (lambda (remote-tz)
+ (seq-map
+ (lambda (x) (time-to-seconds (date-to-time (format-time-string
+ "%Y-%m-%dT%H:%M:%S"
+ (date-to-time
(format-time-string (concat x " " local-tz)))
+ remote-tz))))
+ local-times))
+ remote-timezones))
+ (tz-data (apply #'seq-mapn #'list tztimes remote-times))
+ (tz-buffer-name (format "*%s - %s*" local-tz (string-join
remote-timezones " - "))))
(get-buffer-create tz-buffer-name)
(switch-to-buffer (set-buffer tz-buffer-name))
@@ -314,15 +327,16 @@ customized via the variable
`casual-timezone-working-hours-range'."
(let ((inhibit-read-only t))
(erase-buffer)
(make-vtable
- :columns `((:name ,local-tz :width 30 :align left) ;; !!! For some
reason I can't pass in local-tz
- (:name ,remote-tz :width 30 :align left))
+ :columns (append
+ `((:name ,local-tz :width 30 :align left)) ;; !!! For some
reason I can't pass in local-tz
+ (seq-map (lambda (remote-tz)
+ `(:name ,remote-tz :width 30 :align left))
+ remote-timezones))
:objects tz-data
:getter `(lambda (issue column table)
- (pcase (vtable-column table column)
- (,local-tz (nth 0 issue))
- (,remote-tz (nth 1 issue))))
+ (nth column issue))
:formatter `(lambda (value column table)
(casual-timezone--date-formatter value))
@@ -342,13 +356,14 @@ The format of the timestamp is defined in the variable
(kill-new result)
(message result)))
-(defun casual-timezone-planner-current-remote ()
- "Copy remote time on current line to `kill-ring'.
+(defun casual-timezone-planner-current-point ()
+ "Copy time at current point to `kill-ring'.
The format of the timestamp is defined in the variable
`casual-timezone-datestamp-format'."
(interactive)
- (let ((result (casual-timezone-planner--format-current-index 1)))
+ (let ((result (casual-timezone-planner--format-current-index
+ (vtable-current-column))))
(kill-new result)
(message result)))
@@ -358,9 +373,13 @@ The format of the timestamp is defined in the variable
The format of the timestamp is defined in the variable
`casual-timezone-datestamp-format'."
(interactive)
- (let* ((local (casual-timezone-planner--format-current-index 0))
- (remote (casual-timezone-planner--format-current-index 1))
- (result (format "%s, %s" local remote)))
+ (let* ((result
+ (string-join
+ (seq-map-indexed
+ (lambda (_ i)
+ (casual-timezone-planner--format-current-index i))
+ (vtable-current-object))
+ "; ")))
(kill-new result)
(message result)))
@@ -471,6 +490,7 @@ window width has changed."
["Casual Timezone"
["Navigation"
+ :pad-keys t
("." "Current Hour" casual-timezone-jump-to-relative-now
:description (lambda () (casual-timezone-unicode-get :current))
:transient t)
@@ -479,6 +499,12 @@ window width has changed."
:transient t)
("n" "Next" next-line
:description (lambda () (casual-timezone-unicode-get :next))
+ :transient t)
+ ("TAB" "Right" vtable-next-column
+ :description (lambda () (casual-timezone-unicode-get :right))
+ :transient t)
+ ("S-TAB" "Left" vtable-previous-column
+ :description (lambda () (casual-timezone-unicode-get :left))
:transient t)]
["Day"
@@ -492,11 +518,13 @@ window width has changed."
["Copy Time"
("t" "Times" casual-timezone-planner-current-time)
("l" "Local" casual-timezone-planner-current-local)
- ("r" "Remote" casual-timezone-planner-current-remote)]
+ ;; ("r" "Remote" casual-timezone-planner-current-remote)
+ ("T" "Point" casual-timezone-planner-current-point)]
["Misc"
("z" "Planner…" casual-timezone-planner)
- ("w" "World Clock" world-clock)]]
+ ("w" "World Clock" world-clock)
+ ("c" "Calendar" calendar)]]
[:class transient-row
(casual-lib-quit-one)
diff --git a/lisp/casual.el b/lisp/casual.el
index dee336866f..b07d5c0364 100644
--- a/lisp/casual.el
+++ b/lisp/casual.el
@@ -5,7 +5,7 @@
;; Author: Charles Choi <[email protected]>
;; URL: https://github.com/kickingvegas/casual
;; Keywords: tools, wp
-;; Version: 2.9.0
+;; Version: 2.9.1-rc.1
;; Package-Requires: ((emacs "29.1") (transient "0.9.0"))
;; This program is free software; you can redistribute it and/or modify
diff --git a/tests/test-casual-timezone-utils.el
b/tests/test-casual-timezone-utils.el
index 1fea140fd9..ee06be4998 100644
--- a/tests/test-casual-timezone-utils.el
+++ b/tests/test-casual-timezone-utils.el
@@ -31,6 +31,8 @@
(let ((casual-lib-use-unicode nil))
(should (string-equal (casual-timezone-unicode-get :forward) "Forward"))
(should (string-equal (casual-timezone-unicode-get :backward) "Backward"))
+ (should (string-equal (casual-timezone-unicode-get :right) "Right"))
+ (should (string-equal (casual-timezone-unicode-get :left) "Left"))
(should (string-equal (casual-timezone-unicode-get :current) "Current
Hour"))
(should (string-equal (casual-timezone-unicode-get :previous) "Previous"))
(should (string-equal (casual-timezone-unicode-get :next) "Next")))
@@ -38,6 +40,8 @@
(let ((casual-lib-use-unicode t))
(should (string-equal (casual-timezone-unicode-get :forward) "→"))
(should (string-equal (casual-timezone-unicode-get :backward) "←"))
+ (should (string-equal (casual-timezone-unicode-get :right) "→"))
+ (should (string-equal (casual-timezone-unicode-get :left) "←"))
(should (string-equal (casual-timezone-unicode-get :current) "⨀"))
(should (string-equal (casual-timezone-unicode-get :previous) "↑"))
(should (string-equal (casual-timezone-unicode-get :next) "↓"))))
@@ -52,20 +56,24 @@
(casualt-mock #'casual-timezone-planner-backward-day)
(casualt-mock #'casual-timezone-planner-current-time)
(casualt-mock #'casual-timezone-planner-current-local)
- (casualt-mock #'casual-timezone-planner-current-remote)
+ (casualt-mock #'casual-timezone-planner-current-point)
+ (casualt-mock #'vtable-next-column)
+ (casualt-mock #'vtable-previous-column)
(casualt-mock #'casual-timezone-planner)
(casualt-mock #'world-clock)
(casualt-mock #'quit-window))
(let ((test-vectors
'((:binding "." :command casual-timezone-jump-to-relative-now)
- (:binding "p" :command previous-line)
(:binding "n" :command next-line)
+ (:binding "p" :command previous-line)
(:binding "f" :command casual-timezone-planner-forward-day)
(:binding "b" :command casual-timezone-planner-backward-day)
(:binding "t" :command casual-timezone-planner-current-time)
(:binding "l" :command casual-timezone-planner-current-local)
- (:binding "r" :command casual-timezone-planner-current-remote)
+ (:binding "TAB" :command vtable-next-column)
+ (:binding "S-TAB" :command vtable-previous-column)
+ (:binding "T" :command casual-timezone-planner-current-point)
(:binding "z" :command casual-timezone-planner)
(:binding "w" :command world-clock)
(:binding "q" :command quit-window))))
@@ -112,7 +120,7 @@
(should (eq (keymap-lookup test-map ".")
#'casual-timezone-jump-to-relative-now))
(should (eq (keymap-lookup test-map "t")
#'casual-timezone-planner-current-time))
(should (eq (keymap-lookup test-map "l")
#'casual-timezone-planner-current-local))
- (should (eq (keymap-lookup test-map "r")
#'casual-timezone-planner-current-remote))
+ (should (eq (keymap-lookup test-map "T")
#'casual-timezone-planner-current-point))
(should (eq (keymap-lookup test-map "p") #'previous-line))
(should (eq (keymap-lookup test-map "n") #'next-line))
(should (eq (keymap-lookup test-map "q") #'quit-window))