From: Tianxiang Xiong <tianxiang.xiong@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: "Clément Pit--Claudel" <clement.pit@gmail.com>,
monnier@iro.umontreal.ca, emacs-devel@gnu.org
Subject: Re: Proposal: font lock for `describe-variable`
Date: Tue, 27 Sep 2016 20:45:08 -0700 [thread overview]
Message-ID: <CACMkxiwR94LZaiLZoPw6VXXGHJMchuSBv7j1q_kVBZ5dGvac7Q@mail.gmail.com> (raw)
In-Reply-To: <83ponpb5rv.fsf@gnu.org>
[-- Attachment #1.1: Type: text/plain, Size: 774 bytes --]
@Eli I don't know what you mean, then. The diffs in the 0002 version are
definitely not due to whitespace changes; I explicitly removed the
whitespace-only changes from 0001.
There *is* a good amount of refactoring, simply because the previous code
was very hard to follow. The new code is ~40 lines shorter and, if I do say
so myself, much clearer.
I've attached the 0002 version again in case there's something wrong with
the previous one.
2016-09-27 10:40 GMT-07:00 Eli Zaretskii <eliz@gnu.org>:
> > From: Tianxiang Xiong <tianxiang.xiong@gmail.com>
> > Date: Tue, 27 Sep 2016 09:30:18 -0700
> > Cc: emacs-devel@gnu.org, monnier@iro.umontreal.ca,
> > Clément Pit--Claudel <clement.pit@gmail.com>
> >
> > Even the 0002 version?
>
> Yes.
>
[-- Attachment #1.2: Type: text/html, Size: 1347 bytes --]
[-- Attachment #2: 0002-Use-font-lock-for-describe-variable.patch --]
[-- Type: text/x-patch, Size: 27486 bytes --]
From 8dfffc1c7661c27c27ec01782b91b51410f313fa Mon Sep 17 00:00:00 2001
From: Tianxiang Xiong <tianxiang.xiong@gmail.com>
Date: Sat, 24 Sep 2016 19:57:21 -0700
Subject: [PATCH] Use font-lock for `describe-variable`
As a side effect, clean up code.
---
lisp/help-fns.el | 570 +++++++++++++++++++++++++------------------------------
1 file changed, 263 insertions(+), 307 deletions(-)
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index e4e2333..768a288 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -35,6 +35,7 @@
(require 'cl-lib)
(require 'help-mode)
(require 'radix-tree)
+(require 'subr-x)
(defvar help-fns-describe-function-functions nil
"List of functions to run in help buffer in `describe-function'.
@@ -733,334 +734,289 @@ describe-variable-custom-version-info
(cpv (get variable 'custom-package-version))
(output nil))
(if custom-version
- (setq output
- (format "This variable was introduced, or its default value was changed, in\nversion %s of Emacs.\n"
- custom-version))
+ (setq output
+ (format "This variable was introduced, or its default value was changed, in version %s of Emacs.\n"
+ custom-version))
(when cpv
- (let* ((package (car-safe cpv))
- (version (if (listp (cdr-safe cpv))
- (car (cdr-safe cpv))
- (cdr-safe cpv)))
- (pkg-versions (assq package customize-package-emacs-version-alist))
- (emacsv (cdr (assoc version pkg-versions))))
- (if (and package version)
- (setq output
- (format (concat "This variable was introduced, or its default value was changed, in\nversion %s of the %s package"
- (if emacsv
- (format " that is part of Emacs %s" emacsv))
- ".\n")
- version package))))))
+ (let* ((package (car-safe cpv))
+ (version (if (listp (cdr-safe cpv))
+ (car (cdr-safe cpv))
+ (cdr-safe cpv)))
+ (pkg-versions (assq package customize-package-emacs-version-alist))
+ (emacsv (cdr (assoc version pkg-versions))))
+ (if (and package version)
+ (setq output
+ (format (concat "This variable was introduced, or its default value was changed, in version %s of the %s package"
+ (if emacsv
+ (format " that is part of Emacs %s" emacsv))
+ ".\n")
+ version package))))))
output))
;;;###autoload
(defun describe-variable (variable &optional buffer frame)
"Display the full documentation of VARIABLE (a symbol).
-Returns the documentation as a string, also.
-If VARIABLE has a buffer-local value in BUFFER or FRAME
-\(default to the current buffer and current frame),
-it is displayed along with the global value."
+
+Returns the documentation as a string.
+
+If VARIABLE has a buffer-local value in BUFFER or FRAME (default
+to the current buffer and frame), it is displayed along
+with the global value."
(interactive
- (let ((v (variable-at-point))
- (enable-recursive-minibuffers t)
- (orig-buffer (current-buffer))
- val)
- (setq val (completing-read
+ (let* ((v (variable-at-point))
+ (enable-recursive-minibuffers t)
+ (orig-buffer (current-buffer))
+ (val (completing-read
(if (symbolp v)
(format
"Describe variable (default %s): " v)
"Describe variable: ")
#'help--symbol-completion-table
(lambda (vv)
- ;; In case the variable only exists in the buffer
- ;; the command we switch back to that buffer before
- ;; we examine the variable.
(with-current-buffer orig-buffer
(or (get vv 'variable-documentation)
(and (boundp vv) (not (keywordp vv))))))
- t nil nil
- (if (symbolp v) (symbol-name v))))
- (list (if (equal val "")
- v (intern val)))))
- (let (file-name)
- (unless (buffer-live-p buffer) (setq buffer (current-buffer)))
- (unless (frame-live-p frame) (setq frame (selected-frame)))
- (if (not (symbolp variable))
- (message "You did not specify a variable")
- (save-excursion
- (let ((valvoid (not (with-current-buffer buffer (boundp variable))))
- (permanent-local (get variable 'permanent-local))
- val val-start-pos locus)
- ;; Extract the value before setting up the output buffer,
- ;; in case `buffer' *is* the output buffer.
- (unless valvoid
- (with-selected-frame frame
- (with-current-buffer buffer
- (setq val (symbol-value variable)
- locus (variable-binding-locus variable)))))
- (help-setup-xref (list #'describe-variable variable buffer)
- (called-interactively-p 'interactive))
- (with-help-window (help-buffer)
- (with-current-buffer buffer
- (prin1 variable)
- (setq file-name (find-lisp-object-file-name variable 'defvar))
-
- (if file-name
- (progn
- (princ (format-message
- " is a variable defined in `%s'.\n"
- (if (eq file-name 'C-source)
- "C source code"
- (file-name-nondirectory file-name))))
- (with-current-buffer standard-output
- (save-excursion
- (re-search-backward (substitute-command-keys
- "`\\([^`']+\\)'")
- nil t)
- (help-xref-button 1 'help-variable-def
- variable file-name)))
- (if valvoid
- (princ "It is void as a variable.")
- (princ "Its ")))
- (if valvoid
- (princ " is void as a variable.")
- (princ (substitute-command-keys "'s ")))))
- (unless valvoid
- (with-current-buffer standard-output
- (setq val-start-pos (point))
- (princ "value is")
- (let ((line-beg (line-beginning-position))
- (print-rep
- (let ((rep
- (let ((print-quoted t))
- (prin1-to-string val))))
- (if (and (symbolp val) (not (booleanp val)))
- (format-message "`%s'" rep)
- rep))))
- (if (< (+ (length print-rep) (point) (- line-beg)) 68)
- (insert " " print-rep)
- (terpri)
- (pp val)
- ;; Remove trailing newline.
- (delete-char -1))
- (let* ((sv (get variable 'standard-value))
- (origval (and (consp sv)
- (condition-case nil
- (eval (car sv))
- (error :help-eval-error))))
- from)
- (when (and (consp sv)
- (not (equal origval val))
- (not (equal origval :help-eval-error)))
- (princ "\nOriginal value was \n")
- (setq from (point))
- (pp origval)
- (if (< (point) (+ from 20))
- (delete-region (1- from) from)))))))
- (terpri)
- (when locus
- (cond
+ t
+ nil
+ nil
+ (when (symbolp v) (symbol-name v)))))
+ (list (if (equal val "") v (intern val)))))
+ (unless (buffer-live-p buffer) (setq buffer (current-buffer)))
+ (unless (frame-live-p frame) (setq frame (selected-frame)))
+
+ ;; Error if no variable is specified
+ (if (not (symbolp variable))
+ (user-error "%s" "You did not specify a variable"))
+
+ (save-excursion
+ (let* ((void (not (with-current-buffer buffer (boundp variable))))
+ (val (if void nil (symbol-value variable)))
+ (locus (variable-binding-locus variable)))
+ (cl-flet ((value-pretty (lambda (val)
+ (with-temp-buffer
+ (let ((large (and (sequencep val)
+ (> (length val) 500))))
+ (if large
+ (princ val)
+ (pp val (current-buffer))
+ (when (and (not (null val))
+ (not (stringp val))
+ (sequencep val))
+ (kill-backward-chars 1))
+ (emacs-lisp-mode)
+ (turn-on-font-lock)
+ (font-lock-ensure))
+ (buffer-string))))))
+ ;; Setup xrefs
+ (help-setup-xref (list #'describe-variable variable buffer)
+ (called-interactively-p 'interactive))
+
+ (with-help-window (help-buffer)
+ (with-current-buffer standard-output
+ ;; Variable name
+ (insert (propertize (symbol-name variable)
+ 'face font-lock-variable-name-face))
+
+ ;; Definition file
+ (if-let ((file-name (find-lisp-object-file-name variable 'defvar)))
+ (progn
+ (insert " is a variable defined in ")
+ (if (eq file-name 'C-source)
+ (insert "C source code.")
+ (help-insert-xref-button (file-name-nondirectory file-name)
+ 'help-variable-def variable file-name)
+ (insert "."))))
+ (insert "\n\n")
+
+ ;; Value
+ (if void
+ (insert "It is void as a variable.")
+ (if (and (or (null val)
+ (stringp val)
+ (not (sequencep val)))
+ (< (length (prin1-to-string val))
+ (- fill-column 13)))
+ (insert (format-message "Its value is %s.\n" (value-pretty val)))
+ (insert (format-message "Its value is:\n\n%s\n" (value-pretty val))))
+
+ ;; Original value
+ (let* ((sv (get variable 'standard-value))
+ (origval (and (consp sv)
+ (condition-case nil
+ (eval (car sv))
+ (error :help-eval-error)))))
+ (when (and (consp sv)
+ (not (equal origval val))
+ (not (equal origval :help-eval-error)))
+ (if (< (length (prin1-to-string origval))
+ (- fill-column 19))
+ (insert (format "Original value was %s.\n" (value-pretty origval)))
+ (insert (format "Original value was: \n\n%s" (value-pretty origval)))))))
+ (insert "\n")
+
+ ;; Locus (where variable's binding comes from)
+ (when locus
+ (cond
((bufferp locus)
- (princ (format "Local in buffer %s; "
- (buffer-name buffer))))
+ (insert (format "It is local to buffer %s; "
+ (buffer-name locus))))
((framep locus)
- (princ (format "It is a frame-local variable; ")))
+ (insert (format "It is local to frame %s; "
+ (print1-to-string locus))))
((terminal-live-p locus)
- (princ (format "It is a terminal-local variable; ")))
+ (insert (format "It is local to terminal %s; "
+ (prin1-to-string locus))))
(t
- (princ (format "It is local to %S" locus))))
- (if (not (default-boundp variable))
- (princ "globally void")
- (let ((global-val (default-value variable)))
- (with-current-buffer standard-output
- (princ "global value is ")
- (if (eq val global-val)
- (princ "the same.")
- (terpri)
- ;; Fixme: pp can take an age if you happen to
- ;; ask for a very large expression. We should
- ;; probably print it raw once and check it's a
- ;; sensible size before prettyprinting. -- fx
- (let ((from (point)))
- (pp global-val)
- ;; See previous comment for this function.
- ;; (help-xref-on-pp from (point))
- (if (< (point) (+ from 20))
- (delete-region (1- from) from)))))))
- (terpri))
-
- ;; If the value is large, move it to the end.
- (with-current-buffer standard-output
- (when (> (count-lines (point-min) (point-max)) 10)
- ;; Note that setting the syntax table like below
- ;; makes forward-sexp move over a `'s' at the end
- ;; of a symbol.
- (set-syntax-table emacs-lisp-mode-syntax-table)
- (goto-char val-start-pos)
- ;; The line below previously read as
- ;; (delete-region (point) (progn (end-of-line) (point)))
- ;; which suppressed display of the buffer local value for
- ;; large values.
- (when (looking-at "value is") (replace-match ""))
- (save-excursion
- (insert "\n\nValue:")
- (set (make-local-variable 'help-button-cache)
- (point-marker)))
- (insert "value is shown ")
- (insert-button "below"
- 'action help-button-cache
- 'follow-link t
- 'help-echo "mouse-2, RET: show value")
- (insert ".\n")))
- (terpri)
-
- (let* ((alias (condition-case nil
- (indirect-variable variable)
- (error variable)))
- (obsolete (get variable 'byte-obsolete-variable))
- (use (car obsolete))
- (safe-var (get variable 'safe-local-variable))
- (doc (or (documentation-property
- variable 'variable-documentation)
- (documentation-property
- alias 'variable-documentation)))
- (extra-line nil))
-
- ;; Mention if it's a local variable.
- (cond
- ((and (local-variable-if-set-p variable)
- (or (not (local-variable-p variable))
- (with-temp-buffer
- (local-variable-if-set-p variable))))
- (setq extra-line t)
- (princ " Automatically becomes ")
- (if permanent-local
- (princ "permanently "))
- (princ "buffer-local when set.\n"))
- ((not permanent-local))
- ((bufferp locus)
- (setq extra-line t)
- (princ
- (substitute-command-keys
- " This variable's buffer-local value is permanent.\n")))
- (t
- (setq extra-line t)
- (princ (substitute-command-keys
- " This variable's value is permanent \
-if it is given a local binding.\n"))))
-
- ;; Mention if it's an alias.
+ (insert (format "It is local to %s" locus))))
+ (if (not (default-boundp variable))
+ (insert "globally void")
+ (let ((global-val (default-value variable)))
+ (with-current-buffer standard-output
+ (insert "global value is ")
+ (if (eq val global-val)
+ (insert "the same.")
+ (insert "\n")
+ ;; Fixme: pp can take an age if you happen to
+ ;; ask for a very large expression. We should
+ ;; probably print it raw once and check it's a
+ ;; sensible size before prettyprinting. -- fx
+ (let ((from (point)))
+ (pp global-val)
+ ;; See previous comment for this function.
+ ;; (help-xref-on-pp from (point))
+ (if (< (point) (+ from 20))
+ (delete-region (1- from) from))))))))
+
+ ;; Buffer local
+ (cond
+ ((and (local-variable-if-set-p variable)
+ (or (not (local-variable-p variable))
+ (with-temp-buffer
+ (local-variable-if-set-p variable))))
+ (insert "Automatically becomes ")
+ (if (get variable 'permanent-local)
+ (insert "permanently "))
+ (insert "buffer-local when set.\n\n"))
+ ((not (get variable 'permanent-local)))
+ ((bufferp locus)
+ (insert
+ (substitute-command-keys
+ "This variable's buffer-local value is permanent.\n\n")))
+ (t
+ (insert "This variable's value is permanent if it is given a local binding.\n\n")))
+
+ ;; Alias
+ (let ((alias (condition-case nil
+ (indirect-variable variable)
+ (error variable))))
(unless (eq alias variable)
- (setq extra-line t)
- (princ (format-message
- " This variable is an alias for `%s'.\n"
- alias)))
-
- (when obsolete
- (setq extra-line t)
- (princ " This variable is obsolete")
- (if (nth 2 obsolete)
- (princ (format " since %s" (nth 2 obsolete))))
- (princ (cond ((stringp use) (concat ";\n " use))
- (use (format-message ";\n use `%s' instead."
- (car obsolete)))
- (t ".")))
- (terpri))
-
- (when (member (cons variable val)
- (with-current-buffer buffer
- file-local-variables-alist))
- (setq extra-line t)
- (if (member (cons variable val)
- (with-current-buffer buffer
- dir-local-variables-alist))
- (let ((file (and (buffer-file-name buffer)
- (not (file-remote-p
- (buffer-file-name buffer)))
- (dir-locals-find-file
- (buffer-file-name buffer))))
- (is-directory nil))
- (princ (substitute-command-keys
- " This variable's value is directory-local"))
- (when (consp file) ; result from cache
- ;; If the cache element has an mtime, we
- ;; assume it came from a file.
- (if (nth 2 file)
- ;; (car file) is a directory.
- (setq file (dir-locals--all-files (car file)))
- ;; Otherwise, assume it was set directly.
- (setq file (car file)
- is-directory t)))
- (if (null file)
- (princ ".\n")
- (princ ", set ")
- (princ (substitute-command-keys
- (cond
- (is-directory "for the directory\n `")
- ;; Many files matched.
- ((and (consp file) (cdr file))
- (setq file (file-name-directory (car file)))
- (format "by one of the\n %s files in the directory\n `"
- dir-locals-file))
- (t (setq file (car file))
- "by the file\n `"))))
- (with-current-buffer standard-output
- (insert-text-button
- file 'type 'help-dir-local-var-def
- 'help-args (list variable file)))
- (princ (substitute-command-keys "'.\n"))))
- (princ (substitute-command-keys
- " This variable's value is file-local.\n"))))
-
- (when (memq variable ignored-local-variables)
- (setq extra-line t)
- (princ " This variable is ignored as a file-local \
-variable.\n"))
-
- ;; Can be both risky and safe, eg auto-fill-function.
- (when (risky-local-variable-p variable)
- (setq extra-line t)
- (princ " This variable may be risky if used as a \
-file-local variable.\n")
- (when (assq variable safe-local-variable-values)
- (princ (substitute-command-keys
- " However, you have added it to \
-`safe-local-variable-values'.\n"))))
-
- (when safe-var
- (setq extra-line t)
- (princ " This variable is safe as a file local variable ")
- (princ "if its value\n satisfies the predicate ")
- (princ (if (byte-code-function-p safe-var)
- "which is a byte-compiled expression.\n"
- (format-message "`%s'.\n" safe-var))))
-
- (if extra-line (terpri))
- (princ "Documentation:\n")
- (with-current-buffer standard-output
- (insert (or doc "Not documented as a variable."))))
-
- ;; Make a link to customize if this variable can be customized.
- (when (custom-variable-p variable)
- (let ((customize-label "customize"))
- (terpri)
- (terpri)
- (princ (concat "You can " customize-label " this variable."))
- (with-current-buffer standard-output
- (save-excursion
- (re-search-backward
- (concat "\\(" customize-label "\\)") nil t)
- (help-xref-button 1 'help-customize-variable variable))))
- ;; Note variable's version or package version.
- (let ((output (describe-variable-custom-version-info variable)))
- (when output
- (terpri)
- (terpri)
- (princ output))))
-
- (with-current-buffer standard-output
- ;; Return the text we displayed.
- (buffer-string))))))))
-
+ (insert (format-message
+ "This variable is an alias for `%s'.\n\n" alias))))
+
+ ;; Obsolete
+ (let* ((obsolete (get variable 'byte-obsolete-variable))
+ (obsolete-since (nth 2 obsolete))
+ (use (car obsolete)))
+ (when obsolete-since
+ (insert (propertize (format-message "This variable is obsolete since %s" obsolete-since)
+ 'face 'error))
+ (insert (propertize (cond ((stringp use) (concat "; " use "\n"))
+ (use (format-message "; use `%s' instead.\n"
+ (car obsolete)))
+ (t ".\n"))
+ 'face 'error))
+ (insert "\n")))
+
+ ;; File or directory local
+ (when (member (cons variable val)
+ (with-current-buffer buffer
+ file-local-variables-alist))
+ (setq extra-line t)
+ (if (member (cons variable val)
+ (with-current-buffer buffer
+ dir-local-variables-alist))
+ (let ((file (and (buffer-file-name buffer)
+ (not (file-remote-p
+ (buffer-file-name buffer)))
+ (dir-locals-find-file
+ (buffer-file-name buffer))))
+ (is-directory nil))
+ (insert "This variable's value is directory-local")
+ (when (consp file) ; result from cache
+ ;; If the cache element has an mtime, we
+ ;; assume it came from a file.
+ (if (nth 2 file)
+ ;; (car file) is a directory.
+ (setq file (dir-locals--all-files (car file)))
+ ;; Otherwise, assume it was set directly.
+ (setq file (car file)
+ is-directory t)))
+ (if (null file)
+ (insert ".\n")
+ (insert ", set ")
+ (insert (substitute-command-keys
+ (cond
+ (is-directory "for the directory\n `")
+ ;; Many files matched.
+ ((and (consp file) (cdr file))
+ (setq file (file-name-directory (car file)))
+ (format "by one of the\n %s files in the directory\n `"
+ dir-locals-file))
+ (t (setq file (car file))
+ "by the file\n `"))))
+ (help-insert-xref-button file 'help-dir-local-var-def
+ variable file)
+ (insert (substitute-command-keys "'.\n"))))
+ (insert "This variable's value is file-local.\n")))
+
+ ;; Ignored local
+ (when (memq variable ignored-local-variables)
+ (insert "This variable is ignored as a file-local variable.\n\n"))
+
+ ;; Risky local
+ (when (risky-local-variable-p variable)
+ (insert (propertize "This variable may be risky if used as a file-local variable"
+ 'face font-lock-warning-face))
+ (if (assq variable safe-local-variable-values)
+ (insert "; however, you have added it to `safe-local-variable-values'.\n"))
+ (insert ".\n\n"))
+
+ ;; Safe local
+ (when-let ((safe-var (get variable 'safe-local-variable)))
+ (insert "This variable is safe as a file local variable")
+ (insert "if its value satisfies the predicate ")
+ (insert (if (byte-code-function-p safe-var)
+ "which is a byte-compiled expression.\n\n"
+ (format-message "`%s'.\n\n" safe-var))))
+
+ ;; Documentation
+ (unless void
+ (let* ((alias (condition-case nil
+ (indirect-variable variable)
+ (error variable)))
+ (doc (or (documentation-property variable
+ 'variable-documentation)
+ (documentation-property alias
+ 'variable-documentation)
+ "Not documented as a variable.")))
+ (insert "Documentation:\n\n")
+ (insert (propertize doc 'face font-lock-doc-face))
+ (insert "\n\n")))
+
+ ;; Make a link to customize if this variable can be
+ ;; customized.
+ (when (custom-variable-p variable)
+ (insert "You can ")
+ (help-insert-xref-button "customize" 'help-customize-variable
+ variable)
+ (insert " this variable.")
+ ;; Note variable's version or package version.
+ (when-let ((output (describe-variable-custom-version-info variable)))
+ (insert "\n\n")
+ (insert output)))
+
+ ;; Return the Help buffer string
+ (buffer-string)))))))
(defvar help-xref-stack-item)
--
2.7.4
next prev parent reply other threads:[~2016-09-28 3:45 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-27 4:09 Proposal: font lock for `describe-variable` Tianxiang Xiong
2016-09-27 15:49 ` Eli Zaretskii
2016-09-27 16:30 ` Tianxiang Xiong
2016-09-27 17:40 ` Eli Zaretskii
2016-09-28 3:45 ` Tianxiang Xiong [this message]
2016-09-28 4:21 ` Clément Pit--Claudel
2016-09-30 7:34 ` Tianxiang Xiong
2016-09-30 13:20 ` Stefan Monnier
2016-09-30 14:41 ` Stefan Monnier
2016-10-03 13:57 ` Tino Calancha
2016-10-08 21:51 ` Tianxiang Xiong
2016-10-09 15:48 ` Tino Calancha
2016-10-11 4:11 ` Tianxiang Xiong
2016-10-11 5:40 ` Tino Calancha
2016-10-11 5:51 ` Clément Pit--Claudel
2016-10-11 5:59 ` Tino Calancha
2016-10-11 13:31 ` Clément Pit--Claudel
2016-10-11 13:57 ` Tino Calancha
-- strict thread matches above, loose matches on Subject: below --
2016-09-25 18:25 Tianxiang Xiong
2016-09-25 3:36 Tianxiang Xiong
2016-09-25 14:47 ` Clément Pit--Claudel
2016-09-25 19:02 ` Stefan Monnier
2016-09-25 19:46 ` Clément Pit--Claudel
2016-09-25 21:12 ` Stefan Monnier
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=CACMkxiwR94LZaiLZoPw6VXXGHJMchuSBv7j1q_kVBZ5dGvac7Q@mail.gmail.com \
--to=tianxiang.xiong@gmail.com \
--cc=clement.pit@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
/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).