From: Thierry Volpiatto <thievol@posteo.net>
To: Eli Zaretskii <eliz@gnu.org>
Cc: michael_heerdegen@web.de, 66394@debbugs.gnu.org,
monnier@iro.umontreal.ca, stefankangas@gmail.com
Subject: bug#66394: 29.1; Make register-read-with-preview more useful
Date: Sat, 25 Nov 2023 21:14:31 +0000 [thread overview]
Message-ID: <87zfz1cz7s.fsf@posteo.net> (raw)
In-Reply-To: <83il5pbnmh.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 25 Nov 2023 22:10:14 +0200 (53 minutes, 35 seconds ago)")
[-- Attachment #1.1: Type: text/plain, Size: 496 bytes --]
Eli Zaretskii <eliz@gnu.org> writes:
> How would "make clean" help? I did remove register.elc, it didn't
> help.
Not only register is involved here but indirectly cl-generic.
> OK, so I guess I shouldn't have tried to install it.
Here a patch with the change suggested by Stefan applied, slighly
modified though because it fails if I put the call to
cl--generic-prefill-dispatchers at the recommended place.
I recompiled Emacs with this patch with no errors.
--
Thierry
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 0001-Improve-register-preview-Fix-bug-66394.patch --]
[-- Type: text/x-diff, Size: 17350 bytes --]
From ccecd34b8307c7168e89289f933e63590ce6fc9c Mon Sep 17 00:00:00 2001
From: Thierry Volpiatto <thievol@posteo.net>
Date: Sun, 19 Nov 2023 20:42:56 +0100
Subject: [PATCH] Improve register-preview (Fix bug#66394)
A minibuffer is used now instead of read-key.
Registers in preview buffer are now filtered according to type of
registers the current command requires.
Navigation with C-n/p or up/down is now provided and update
minibuffer.
Current register is highlighted in preview buffer.
* cl-generic.el: Add a call to `cl--generic-prefill-dispatchers` to
fix build error.
* register.el:
* (register-preview-default-keys): new user var.
* (register-use-preview): Same.
* (register-preview-info): New structure to store various info for
preview.
* (register-command-info): New generic.
* (register-preview-forward-line): New, provide navigation in preview
buffer.
* (register-preview-next, register-preview-previous): New, navigation.
* (register-type): New, returns register type.
* (register--type): Generic fn, new, returns register type according
to value.
* (register-of-type-alist): New, filter register-alist according to
type.
* (register-preview): Signature changed, use TYPES now.
* (register-preview-get-defaults): New generic, compute defauts
according to action.
* (register-read-with-preview): Now use read-from-minibuffer and
minibuffer-setup-hook.
---
lisp/emacs-lisp/cl-generic.el | 1 +
lisp/register.el | 295 +++++++++++++++++++++++++++++-----
2 files changed, 259 insertions(+), 37 deletions(-)
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 56eb83e6f75..0ef0d1e192a 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -1379,6 +1379,7 @@ See the full list and their hierarchy in `cl--typeof-types'."
(cl--generic-prefill-dispatchers 0 integer)
(cl--generic-prefill-dispatchers 1 integer)
(cl--generic-prefill-dispatchers 0 cl--generic-generalizer integer)
+(cl--generic-prefill-dispatchers 0 (eql 'x) integer)
;;; Dispatch on major mode.
diff --git a/lisp/register.el b/lisp/register.el
index ca6de450993..61bef503f91 100644
--- a/lisp/register.el
+++ b/lisp/register.el
@@ -35,6 +35,8 @@
;; FIXME: Clean up namespace usage!
+(declare-function frameset-register-p "frameset")
+
(cl-defstruct
(registerv (:constructor nil)
(:constructor registerv--make (&optional data print-func
@@ -91,6 +93,7 @@ of the marked text."
:type '(choice (const :tag "None" nil)
(character :tag "Use register" :value ?+)))
+;; FIXME: This is no more needed, remove it.
(defcustom register-preview-delay 1
"If non-nil, time to wait in seconds before popping up register preview window.
If nil, do not show register previews, unless `help-char' (or a member of
@@ -99,6 +102,14 @@ If nil, do not show register previews, unless `help-char' (or a member of
:type '(choice number (const :tag "No preview unless requested" nil))
:group 'register)
+(defcustom register-preview-default-keys (mapcar #'string (number-sequence ?a ?z))
+ "Default keys for setting a new register."
+ :type '(repeat string))
+
+(defcustom register-use-preview t
+ "Always show register preview when non nil."
+ :type 'boolean)
+
(defun get-register (register)
"Return contents of Emacs register named REGISTER, or nil if none."
(alist-get register register-alist))
@@ -128,53 +139,263 @@ See the documentation of the variable `register-alist' for possible VALUEs."
Called with one argument, a cons (NAME . CONTENTS) as found in `register-alist'.
The function should return a string, the description of the argument.")
-(defun register-preview (buffer &optional show-empty)
+(cl-defstruct register-preview-info
+ "Store data for a specific register command.
+TYPES are the types of register supported.
+MSG is the minibuffer message to send when a register is selected.
+ACT is the type of action the command is doing on register.
+SMATCH accept a boolean value to say if command accept non matching register."
+ types msg act smatch)
+
+(cl-defgeneric register-command-info (command)
+ "Returns a `register-preview-info' object storing data for COMMAND."
+ (ignore command))
+(cl-defmethod register-command-info ((_command (eql insert-register)))
+ (make-register-preview-info
+ :types '(string number)
+ :msg "Insert register `%s'"
+ :act 'insert
+ :smatch t))
+(cl-defmethod register-command-info ((_command (eql jump-to-register)))
+ (make-register-preview-info
+ :types '(window frame marker kmacro
+ file buffer file-query)
+ :msg "Jump to register `%s'"
+ :act 'jump
+ :smatch t))
+(cl-defmethod register-command-info ((_command (eql view-register)))
+ (make-register-preview-info
+ :types '(all)
+ :msg "View register `%s'"
+ :act 'view
+ :smatch t))
+(cl-defmethod register-command-info ((_command (eql append-to-register)))
+ (make-register-preview-info
+ :types '(string number)
+ :msg "Append to register `%s'"
+ :act 'modify
+ :smatch t))
+(cl-defmethod register-command-info ((_command (eql prepend-to-register)))
+ (make-register-preview-info
+ :types '(string number)
+ :msg "Prepend to register `%s'"
+ :act 'modify
+ :smatch t))
+(cl-defmethod register-command-info ((_command (eql increment-register)))
+ (make-register-preview-info
+ :types '(string number)
+ :msg "Increment register `%s'"
+ :act 'modify
+ :smatch t))
+
+(defun register-preview-forward-line (arg)
+ "Move to next or previous line in register preview buffer.
+If ARG is positive goto next line, if negative to previous.
+Do nothing when defining or executing kmacros."
+ ;; Ensure user enter manually key in minibuffer when recording a macro.
+ (unless (or defining-kbd-macro executing-kbd-macro
+ (not (get-buffer-window "*Register Preview*" 'visible)))
+ (let ((fn (if (> arg 0) #'eobp #'bobp))
+ (posfn (if (> arg 0)
+ #'point-min
+ (lambda () (1- (point-max)))))
+ str)
+ (with-current-buffer "*Register Preview*"
+ (let ((ovs (overlays-in (point-min) (point-max)))
+ pos)
+ (goto-char (if ovs
+ (overlay-start (car ovs))
+ (point-min)))
+ (setq pos (point))
+ (and ovs (forward-line arg))
+ (when (and (funcall fn)
+ (or (> arg 0) (eql pos (point))))
+ (goto-char (funcall posfn)))
+ (setq str (buffer-substring-no-properties
+ (pos-bol) (1+ (pos-bol))))
+ (remove-overlays)
+ (with-selected-window (minibuffer-window)
+ (delete-minibuffer-contents)
+ (insert str)))))))
+
+(defun register-preview-next ()
+ "Goto next line in register preview buffer."
+ (interactive)
+ (register-preview-forward-line 1))
+
+(defun register-preview-previous ()
+ "Goto previous line in register preview buffer."
+ (interactive)
+ (register-preview-forward-line -1))
+
+(defun register-type (register)
+ "Return REGISTER type.
+Current register types actually returned are one of:
+- string
+- number
+- marker
+- buffer
+- file
+- file-query
+- window
+- frame
+- kmacro
+
+One can add new types to a specific command by defining a new `cl-defmethod'
+matching this command. Predicate for type in new `cl-defmethod' should
+satisfy `cl-typep' otherwise the new type should be defined with
+`cl-deftype'."
+ ;; Call register--type against the register value.
+ (register--type (if (consp (cdr register))
+ (cadr register)
+ (cdr register))))
+
+(cl-defgeneric register--type (regval)
+ "Returns type of register value REGVAL."
+ (ignore regval))
+
+(cl-defmethod register--type ((_regval string)) 'string)
+(cl-defmethod register--type ((_regval number)) 'number)
+(cl-defmethod register--type ((_regval marker)) 'marker)
+(cl-defmethod register--type ((_regval (eql 'buffer))) 'buffer)
+(cl-defmethod register--type ((_regval (eql 'file))) 'file)
+(cl-defmethod register--type ((_regval (eql 'file-query))) 'file-query)
+(cl-defmethod register--type ((_regval window-configuration)) 'window)
+(cl-deftype frame-register () '(satisfies frameset-register-p))
+(cl-defmethod register--type :extra "frame-register" (_regval) 'frame)
+(cl-deftype kmacro-register () '(satisfies kmacro-register-p))
+(cl-defmethod register--type :extra "kmacro-register" (_regval) 'kmacro)
+
+(defun register-of-type-alist (types)
+ "Filter `register-alist' according to TYPES."
+ (if (memq 'all types)
+ register-alist
+ (cl-loop for register in register-alist
+ when (memq (register-type register) types)
+ collect register)))
+
+(defun register-preview (buffer &optional show-empty types)
"Pop up a window showing the registers preview in BUFFER.
If SHOW-EMPTY is non-nil, show the window even if no registers.
+Argument TYPES (a list) specify the types of register to show, when nil show all
+registers, see `register-type' for suitable types.
Format of each entry is controlled by the variable `register-preview-function'."
- (when (or show-empty (consp register-alist))
- (with-current-buffer-window
- buffer
- (cons 'display-buffer-below-selected
- '((window-height . fit-window-to-buffer)
- (preserve-size . (nil . t))))
- nil
- (with-current-buffer standard-output
- (setq cursor-in-non-selected-windows nil)
- (mapc (lambda (elem)
- (when (get-register (car elem))
- (insert (funcall register-preview-function elem))))
- register-alist)))))
+ (let ((registers (register-of-type-alist (or types '(all)))))
+ (when (or show-empty (consp registers))
+ (with-current-buffer-window
+ buffer
+ (cons 'display-buffer-below-selected
+ '((window-height . fit-window-to-buffer)
+ (preserve-size . (nil . t))))
+ nil
+ (with-current-buffer standard-output
+ (setq cursor-in-non-selected-windows nil)
+ (mapc (lambda (elem)
+ (when (get-register (car elem))
+ (insert (funcall register-preview-function elem))))
+ registers))))))
+
+(cl-defgeneric register-preview-get-defaults (action)
+ "Returns default registers according to ACTION."
+ (ignore action))
+(cl-defmethod register-preview-get-defaults ((_action (eql set)))
+ (cl-loop for s in register-preview-default-keys
+ unless (assoc (string-to-char s) register-alist)
+ collect s))
(defun register-read-with-preview (prompt)
"Read and return a register name, possibly showing existing registers.
-Prompt with the string PROMPT. If `register-alist' and
-`register-preview-delay' are both non-nil, display a window
-listing existing registers after `register-preview-delay' seconds.
+Prompt with the string PROMPT.
If `help-char' (or a member of `help-event-list') is pressed,
display such a window regardless."
(let* ((buffer "*Register Preview*")
- (timer (when (numberp register-preview-delay)
- (run-with-timer register-preview-delay nil
- (lambda ()
- (unless (get-buffer-window buffer)
- (register-preview buffer))))))
- (help-chars (cl-loop for c in (cons help-char help-event-list)
- when (not (get-register c))
- collect c)))
+ (pat "")
+ (map (let ((m (make-sparse-keymap)))
+ (set-keymap-parent m minibuffer-local-map)
+ m))
+ (data (register-command-info this-command))
+ types msg result timer act win strs smatch)
+ (if data
+ (setq types (register-preview-info-types data)
+ msg (register-preview-info-msg data)
+ act (register-preview-info-act data)
+ smatch (register-preview-info-smatch data))
+ (setq types '(all)
+ msg "Overwrite register `%s'"
+ act 'set))
+ (setq strs (mapcar (lambda (x)
+ (string (car x)))
+ (register-of-type-alist types)))
+ (when (and (memq act '(insert jump view)) (null strs))
+ (error "No register suitable for `%s'" act))
+ (dolist (k (cons help-char help-event-list))
+ (define-key map
+ (vector k) (lambda ()
+ (interactive)
+ (unless (get-buffer-window buffer)
+ (with-selected-window (minibuffer-selected-window)
+ (register-preview buffer 'show-empty types))))))
+ (define-key map (kbd "<down>") 'register-preview-next)
+ (define-key map (kbd "<up>") 'register-preview-previous)
+ (define-key map (kbd "C-n") 'register-preview-next)
+ (define-key map (kbd "C-p") 'register-preview-previous)
+ (unless (or executing-kbd-macro (null register-use-preview))
+ (register-preview buffer nil types))
(unwind-protect
- (progn
- (while (memq (read-key (propertize prompt 'face 'minibuffer-prompt))
- help-chars)
- (unless (get-buffer-window buffer)
- (register-preview buffer 'show-empty)))
- (when (or (eq ?\C-g last-input-event)
- (eq 'escape last-input-event)
- (eq ?\C-\[ last-input-event))
- (keyboard-quit))
- (if (characterp last-input-event) last-input-event
- (error "Non-character input-event")))
- (and (timerp timer) (cancel-timer timer))
+ (progn
+ (minibuffer-with-setup-hook
+ (lambda ()
+ (setq timer
+ (run-with-idle-timer
+ 0.01 'repeat
+ (lambda ()
+ (with-selected-window (minibuffer-window)
+ (let ((input (minibuffer-contents)))
+ (when (> (length input) 1)
+ (let ((new (substring input 1))
+ (old (substring input 0 1)))
+ (setq input (if (or (null smatch)
+ (member new strs))
+ new old))
+ (delete-minibuffer-contents)
+ (insert input)))
+ (when (and smatch (not (string= input ""))
+ (not (member input strs)))
+ (setq input "")
+ (delete-minibuffer-contents)
+ (minibuffer-message "Not matching"))
+ (when (not (string= input pat))
+ (setq pat input))))
+ (if (setq win (get-buffer-window buffer))
+ (with-selected-window win
+ (let ((ov (make-overlay (point-min) (point-min))))
+ (goto-char (point-min))
+ (remove-overlays)
+ (unless (string= pat "")
+ (if (re-search-forward (concat "^" pat) nil t)
+ (progn (move-overlay
+ ov
+ (match-beginning 0) (pos-eol))
+ (overlay-put ov 'face 'match)
+ (when msg
+ (with-selected-window (minibuffer-window)
+ (minibuffer-message msg pat))))
+ (with-selected-window (minibuffer-window)
+ (minibuffer-message
+ "Register `%s' is empty" pat))))))
+ (unless (string= pat "")
+ (if (member pat strs)
+ (with-selected-window (minibuffer-window)
+ (minibuffer-message msg pat))
+ (with-selected-window (minibuffer-window)
+ (minibuffer-message
+ "Register `%s' is empty" pat)))))))))
+ (setq result (read-from-minibuffer
+ prompt nil map nil nil (register-preview-get-defaults act))))
+ (cl-assert (and result (not (string= result "")))
+ nil "No register specified")
+ (string-to-char result))
+ (when timer (cancel-timer timer))
(let ((w (get-buffer-window buffer)))
(and (window-live-p w) (delete-window w)))
(and (get-buffer buffer) (kill-buffer buffer)))))
--
2.34.1
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 686 bytes --]
next prev parent reply other threads:[~2023-11-25 21:14 UTC|newest]
Thread overview: 121+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-07 19:03 bug#66394: 29.1; Make register-read-with-preview more useful Thierry Volpiatto
2023-10-08 6:45 ` bug#66394: [RE] " Thierry Volpiatto
2023-10-12 6:43 ` Thierry Volpiatto
2023-10-14 2:04 ` Richard Stallman
2023-10-14 5:59 ` Thierry Volpiatto
2023-10-16 2:04 ` Richard Stallman
2023-10-15 7:56 ` Thierry Volpiatto
2023-10-15 8:18 ` Stefan Kangas
2023-10-15 10:05 ` Thierry Volpiatto
2023-10-15 12:55 ` Stefan Kangas
2023-11-18 18:39 ` Thierry Volpiatto
2023-10-19 2:42 ` bug#66394: 29.1; " Michael Heerdegen
2023-10-19 6:16 ` Thierry Volpiatto
2023-10-20 5:00 ` Michael Heerdegen
2023-10-20 5:49 ` Thierry Volpiatto
2023-10-21 1:09 ` Michael Heerdegen
2023-10-21 3:34 ` Thierry Volpiatto
2023-10-23 4:09 ` Michael Heerdegen
2023-10-23 5:14 ` Thierry Volpiatto
2023-10-24 3:42 ` Michael Heerdegen
2023-10-24 3:54 ` Michael Heerdegen
2023-10-24 5:30 ` Thierry Volpiatto
2023-10-25 3:54 ` Michael Heerdegen
2023-10-24 7:19 ` Thierry Volpiatto
2023-10-25 4:10 ` Michael Heerdegen
2023-10-25 6:38 ` Thierry Volpiatto
2023-10-26 4:18 ` Michael Heerdegen
2023-10-26 6:17 ` Thierry Volpiatto
2023-10-27 1:27 ` Michael Heerdegen
2023-10-27 4:24 ` Thierry Volpiatto
2023-11-03 4:58 ` Michael Heerdegen
2023-11-19 19:37 ` Thierry Volpiatto
2023-11-20 6:00 ` Thierry Volpiatto
2023-11-20 17:33 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-11-20 18:51 ` Thierry Volpiatto
2023-11-25 10:23 ` Eli Zaretskii
2023-11-25 19:59 ` Thierry Volpiatto
2023-11-25 20:10 ` Eli Zaretskii
2023-11-25 21:14 ` Thierry Volpiatto [this message]
2023-11-26 10:38 ` Eli Zaretskii
2023-11-26 16:46 ` Thierry Volpiatto
2023-11-29 14:04 ` Eli Zaretskii
2023-11-29 18:18 ` Thierry Volpiatto
2023-11-30 6:00 ` Eli Zaretskii
2023-11-30 10:21 ` Thierry Volpiatto
2023-12-02 5:51 ` Thierry Volpiatto
2023-12-02 7:50 ` Eli Zaretskii
2023-12-02 8:08 ` Thierry Volpiatto
2023-12-03 14:35 ` Thierry Volpiatto
2023-12-03 15:05 ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-03 16:48 ` Thierry Volpiatto
2023-12-03 18:29 ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-03 18:39 ` Eli Zaretskii
2023-12-03 21:23 ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-04 7:30 ` Thierry Volpiatto
2023-12-04 7:57 ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-11 6:55 ` Thierry Volpiatto
2023-12-11 9:30 ` Thierry Volpiatto
2023-12-11 9:58 ` Thierry Volpiatto
2023-12-11 12:30 ` Eli Zaretskii
2023-12-11 13:10 ` Thierry Volpiatto
2023-12-11 17:32 ` Thierry Volpiatto
2023-12-11 23:36 ` Dmitry Gutov
2023-12-12 6:29 ` Thierry Volpiatto
2023-12-12 9:31 ` Thierry Volpiatto
2023-12-12 10:16 ` Thierry Volpiatto
2023-12-12 16:44 ` Thierry Volpiatto
2023-12-14 1:46 ` Dmitry Gutov
2023-12-14 5:34 ` Thierry Volpiatto
2023-12-14 7:38 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-14 8:24 ` Eli Zaretskii
2023-12-14 7:44 ` Eli Zaretskii
2023-12-14 15:50 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-14 17:58 ` Thierry Volpiatto
2023-12-14 19:19 ` Andreas Schwab
2023-12-14 20:29 ` Stefan Kangas
2023-12-15 14:45 ` Thierry Volpiatto
2023-12-15 15:18 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-15 18:36 ` Thierry Volpiatto
2023-12-15 23:30 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-16 13:18 ` Thierry Volpiatto
2023-12-16 15:31 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-16 20:39 ` Thierry Volpiatto
2023-12-17 23:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-18 5:15 ` Thierry Volpiatto
2023-12-18 13:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-18 18:11 ` Thierry Volpiatto
2023-12-18 18:22 ` Dmitry Gutov
2023-12-18 6:18 ` Thierry Volpiatto
2023-12-19 17:40 ` Thierry Volpiatto
2023-12-19 17:47 ` Thierry Volpiatto
2023-12-20 12:05 ` Eli Zaretskii
2023-12-20 17:23 ` Thierry Volpiatto
2023-12-21 11:47 ` Eli Zaretskii
2023-12-21 18:04 ` Thierry Volpiatto
2023-12-23 10:49 ` Eli Zaretskii
2023-12-16 15:07 ` Dmitry Gutov
2023-12-16 20:20 ` Thierry Volpiatto
2023-12-16 23:28 ` Dmitry Gutov
2023-12-14 2:10 ` Dmitry Gutov
2023-12-14 5:30 ` Thierry Volpiatto
2023-12-14 19:39 ` Stefan Kangas
2023-12-12 6:06 ` Alfred M. Szmidt
2023-12-12 9:37 ` Steve Perry via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-12 12:15 ` Eli Zaretskii
2023-12-12 17:58 ` Steve Perry via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-11-25 21:38 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-02 9:24 ` Bastien
2023-12-02 9:52 ` Thierry Volpiatto
2023-12-02 10:37 ` Bastien Guerry
2023-12-02 10:54 ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-02 11:55 ` Thierry Volpiatto
2023-12-02 12:43 ` Thierry Volpiatto
2023-12-02 13:02 ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-02 13:50 ` Bastien Guerry
2023-12-02 15:01 ` Thierry Volpiatto
2023-12-05 7:34 ` Tino Calancha
2023-12-05 7:38 ` Tino Calancha
2023-12-05 7:43 ` Tino Calancha
2023-12-12 5:46 ` Pedro Andres Aranda Gutierrez
2023-12-12 12:01 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87zfz1cz7s.fsf@posteo.net \
--to=thievol@posteo.net \
--cc=66394@debbugs.gnu.org \
--cc=eliz@gnu.org \
--cc=michael_heerdegen@web.de \
--cc=monnier@iro.umontreal.ca \
--cc=stefankangas@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).