Recenter for the calendar (bug#78205)

* lisp/calendar/cal-move.el (calendar-recenter-last-op): New
variable to track last recenter operation.
(calendar-recenter): New command to recenter the calendar.
* lisp/calendar/calendar.el (calendar-mode-map): Keybinding for
this command.
* doc/emacs/calendar.texi (Scroll Calendar): Document this
command.
* etc/NEWS: Announce this command.
This commit is contained in:
Manuel Giraud 2025-05-01 17:06:07 +02:00 committed by Eli Zaretskii
parent c9c6abfa81
commit 0469f41ac2
4 changed files with 51 additions and 0 deletions

View file

@ -258,6 +258,8 @@ Scroll forward by three months (@code{calendar-scroll-left-three-months}).
@itemx @key{PageUp}
@itemx @key{prior}
Scroll backward by three months (@code{calendar-scroll-right-three-months}).
@item C-l
Recenter the date at point.
@end table
@kindex > @r{(Calendar mode)}
@ -293,6 +295,15 @@ calendar backward by a year.
(or @key{prior}) are equivalent to @kbd{C-v} and @kbd{M-v}, just as
they are in other modes.
@kindex C-l @r{(Calendar mode)}
@findex calendar-recenter
The command @kbd{C-l} (@code{calendar-recenter}) scrolls the calendar
on display so that the month of the date at point is centered
horizontally. Next invocation of this command puts that month on the
leftmost position, and another invocation puts it on the rightmost
position. Subsequent invocations reuse the same order in a cyclical
manner.
@node Counting Days
@section Counting Days

View file

@ -2040,6 +2040,12 @@ DISABLE-URI non-nil.
When starting these debuggers (e.g., 'M-x pdb') while visiting a file,
pressing 'M-n' in the command prompt suggests a command line including
the file name, using the minibuffer's "future history".
** Calendar
+++
*** New command 'calendar-recenter'.
This command recenters the month of the date at point. By default, it
is bound to 'C-l' in the calendar buffer.
* New Modes and Packages in Emacs 31.1

View file

@ -217,6 +217,39 @@ EVENT is an event like `last-nonmenu-event'."
last-nonmenu-event))
(calendar-scroll-left (* -3 arg) event))
(defvar calendar-recenter-last-op nil
"Last calendar recenter operation performed.")
;;;###cal-autoload
(defun calendar-recenter ()
"Scroll the calendar so that the month of the date at point is centered.
Next invocation puts this month on the leftmost position, and another
invocation puts this month on the rightmost position. Subsequent
invocations reuse the same order in a cyclical manner."
(interactive)
(let ((positions '(center first last))
(cursor-month (calendar-extract-month
(calendar-cursor-to-nearest-date))))
;; Update global last position upon repeat.
(setq calendar-recenter-last-op
(if (eq this-command last-command)
(car (or (cdr (memq calendar-recenter-last-op positions))
positions))
(car positions)))
;; Like most functions in calendar, a span of three displayed months
;; is implied here.
(cond ((eq calendar-recenter-last-op 'center)
(cond ((= cursor-month (1- displayed-month))
(calendar-scroll-right))
((= cursor-month (1+ displayed-month))
(calendar-scroll-left))))
;; Other sub-cases should not happen as we should be centered
;; from here.
((eq calendar-recenter-last-op 'first)
(calendar-scroll-left))
((eq calendar-recenter-last-op 'last)
(calendar-scroll-right 2)))))
;;;###cal-autoload
(defun calendar-forward-day (arg)
"Move the cursor forward ARG days.

View file

@ -1593,6 +1593,7 @@ Otherwise, use the selected window of EVENT's frame."
(define-key map "\C-x>" 'calendar-scroll-left)
(define-key map [next] 'calendar-scroll-left-three-months)
(define-key map "\C-v" 'calendar-scroll-left-three-months)
(define-key map "\C-l" 'calendar-recenter)
(define-key map "\C-b" 'calendar-backward-day)
(define-key map "\C-p" 'calendar-backward-week)
(define-key map "\e{" 'calendar-backward-month)