From 5020d89104dfc25601ca595bca9124a27ea8b1cb Mon Sep 17 00:00:00 2001 From: Amin Bandali Date: Sun, 4 Jan 2026 23:50:51 -0500 Subject: [PATCH] New minor mode center-line-mode * lisp/textmodes/text-mode.el (center-line-mode--track-changes): New local variable for storing the id of the change tracker registered for the current buffer. (center-line-mode--track-changes-signal): New function to be called by the track-changes library whenever there is a change in the current buffer. (center-line-mode--track-changes-function): New function called from the above signal function, iterates over the lines of the modified region, calling 'center-line' for each non-empty line. (center-line-mode): New minor mode. * etc/NEWS: Document the new minor mode. --- etc/NEWS | 5 ++++ lisp/textmodes/text-mode.el | 50 +++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index 0b4fcadb620..b3b9a84680e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -949,6 +949,11 @@ These commands did not previously accept a prefix argument. Now a numeric prefix argument specifies a repeat count, just like it already did for 'undo'. +** New minor mode 'center-line-mode'. +This mode keeps modified lines centered horizontally according to the +value of 'fill-column', by calling 'center-line' on each non-empty line +of the modified region. + * Changes in Specialized Modes and Packages in Emacs 31.1 diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el index 5c9449a2238..b5b496a30dc 100644 --- a/lisp/textmodes/text-mode.el +++ b/lisp/textmodes/text-mode.el @@ -269,6 +269,56 @@ The argument NLINES says how many lines to center." (setq nlines (1+ nlines)) (forward-line -1))))) +;; Actually defined in track-changes.el. +(defvar track-changes-undo-only) +(declare-function track-changes-register "track-changes" + ( signal &optional &key nobefore disjoint immediate)) +(declare-function track-changes-unregister "track-changes" (id)) +(declare-function track-changes-fetch "track-changes" (id func)) + +(defvar-local center-line-mode--track-changes nil) + +(defun center-line-mode--track-changes-signal (tracker) + (track-changes-fetch + tracker + #'center-line-mode--track-changes-function)) + +(defun center-line-mode--track-changes-function (beg end _before) + (unless track-changes-undo-only + (save-excursion + (let ((beg-line (line-number-at-pos beg)) + (end-line (line-number-at-pos end)) + (should-center-last-line-p + (progn + (goto-char end) + (null + (or (bolp) + (and (eolp) + (looking-back "[\r\n\t ]" (1- (point))))))))) + (goto-char beg) + (dotimes (_ (- end-line beg-line)) ; all but last line + (unless (and (bolp) (eolp)) + (center-line)) + (forward-line 1)) + (when should-center-last-line-p + (center-line))))) + ;; Disregard our own changes. + (track-changes-fetch center-line-mode--track-changes #'ignore)) + +(define-minor-mode center-line-mode + "Minor mode for keeping modified lines centered horizontally. +Calls `center-line' on each line of the modified region to center the +text within the width specified by `fill-column'." + :lighter " Center-Line" + (require 'track-changes) + (if center-line-mode + (setq center-line-mode--track-changes + (track-changes-register + #'center-line-mode--track-changes-signal + :nobefore t)) + (when center-line-mode--track-changes + (track-changes-unregister center-line-mode--track-changes)))) + (define-obsolete-function-alias 'indented-text-mode #'text-mode "29.1")