summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ansi-color.el353
-rw-r--r--lisp/bookmark.el7
-rw-r--r--lisp/calc/calc-prog.el9
-rw-r--r--lisp/calc/calc-store.el2
-rw-r--r--lisp/calc/calc-units.el39
-rw-r--r--lisp/cedet/semantic/complete.el9
-rw-r--r--lisp/cus-edit.el4
-rw-r--r--lisp/cus-start.el2
-rw-r--r--lisp/cus-theme.el34
-rw-r--r--lisp/custom.el7
-rw-r--r--lisp/dired-aux.el8
-rw-r--r--lisp/dired-x.el2
-rw-r--r--lisp/emacs-lisp/cl-generic.el21
-rw-r--r--lisp/emacs-lisp/debug.el6
-rw-r--r--lisp/emacs-lisp/edebug.el6
-rw-r--r--lisp/emacs-lisp/ert.el129
-rw-r--r--lisp/emacs-lisp/lisp-mode.el82
-rw-r--r--lisp/emacs-lisp/memory-report.el3
-rw-r--r--lisp/emacs-lisp/subr-x.el42
-rw-r--r--lisp/epa.el6
-rw-r--r--lisp/faces.el16
-rw-r--r--lisp/files.el1
-rw-r--r--lisp/format.el4
-rw-r--r--lisp/gnus/gnus-agent.el82
-rw-r--r--lisp/gnus/gnus-art.el162
-rw-r--r--lisp/gnus/gnus-bookmark.el49
-rw-r--r--lisp/gnus/gnus-dired.el10
-rw-r--r--lisp/gnus/gnus-draft.el15
-rw-r--r--lisp/gnus/gnus-eform.el11
-rw-r--r--lisp/gnus/gnus-group.el406
-rw-r--r--lisp/gnus/gnus-html.el26
-rw-r--r--lisp/gnus/gnus-icalendar.el59
-rw-r--r--lisp/gnus/gnus-kill.el21
-rw-r--r--lisp/gnus/gnus-ml.el17
-rw-r--r--lisp/gnus/gnus-msg.el66
-rw-r--r--lisp/gnus/gnus-registry.el8
-rw-r--r--lisp/gnus/gnus-salt.el48
-rw-r--r--lisp/gnus/gnus-score.el27
-rw-r--r--lisp/gnus/gnus-srvr.el135
-rw-r--r--lisp/gnus/gnus-start.el3
-rw-r--r--lisp/gnus/gnus-sum.el953
-rw-r--r--lisp/gnus/gnus-topic.el105
-rw-r--r--lisp/gnus/gnus-undo.el15
-rw-r--r--lisp/gnus/gnus-util.el10
-rw-r--r--lisp/gnus/gnus.el37
-rw-r--r--lisp/gnus/message.el142
-rw-r--r--lisp/gnus/spam.el14
-rw-r--r--lisp/help-mode.el4
-rw-r--r--lisp/image-dired.el9
-rw-r--r--lisp/info-look.el43
-rw-r--r--lisp/info.el9
-rw-r--r--lisp/international/mule-diag.el4
-rw-r--r--lisp/international/quail.el2
-rw-r--r--lisp/language/cyril-util.el2
-rw-r--r--lisp/ldefs-boot.el18
-rw-r--r--lisp/mail/rmailkwd.el9
-rw-r--r--lisp/mail/rmailmm.el2
-rw-r--r--lisp/mail/rmailout.el5
-rw-r--r--lisp/man.el4
-rw-r--r--lisp/menu-bar.el5
-rw-r--r--lisp/mh-e/mh-acros.el13
-rw-r--r--lisp/mh-e/mh-comp.el15
-rw-r--r--lisp/mh-e/mh-compat.el15
-rw-r--r--lisp/mh-e/mh-e.el43
-rw-r--r--lisp/mh-e/mh-folder.el28
-rw-r--r--lisp/mh-e/mh-gnus.el3
-rw-r--r--lisp/mh-e/mh-identity.el7
-rw-r--r--lisp/mh-e/mh-letter.el8
-rw-r--r--lisp/mh-e/mh-mime.el34
-rw-r--r--lisp/mh-e/mh-search.el5
-rw-r--r--lisp/mh-e/mh-seq.el2
-rw-r--r--lisp/mh-e/mh-show.el9
-rw-r--r--lisp/mh-e/mh-tool-bar.el73
-rw-r--r--lisp/mh-e/mh-utils.el18
-rw-r--r--lisp/mh-e/mh-xface.el49
-rw-r--r--lisp/mouse.el141
-rw-r--r--lisp/net/ange-ftp.el5
-rw-r--r--lisp/net/eww.el297
-rw-r--r--lisp/net/shr.el32
-rw-r--r--lisp/net/tramp-archive.el2
-rw-r--r--lisp/org/org-capture.el11
-rw-r--r--lisp/org/org-refile.el12
-rw-r--r--lisp/proced.el70
-rw-r--r--lisp/progmodes/cpp.el7
-rw-r--r--lisp/progmodes/ebrowse.el6
-rw-r--r--lisp/progmodes/erts-mode.el201
-rw-r--r--lisp/progmodes/etags.el4
-rw-r--r--lisp/progmodes/grep.el8
-rw-r--r--lisp/progmodes/hideif.el2
-rw-r--r--lisp/progmodes/js.el1138
-rw-r--r--lisp/progmodes/pascal.el4
-rw-r--r--lisp/progmodes/prolog.el7
-rw-r--r--lisp/progmodes/python.el17
-rw-r--r--lisp/progmodes/sql.el17
-rw-r--r--lisp/progmodes/verilog-mode.el23
-rw-r--r--lisp/progmodes/xref.el17
-rw-r--r--lisp/ses.el4
-rw-r--r--lisp/simple.el36
-rw-r--r--lisp/subr.el107
-rw-r--r--lisp/term.el338
-rw-r--r--lisp/textmodes/artist.el5
-rw-r--r--lisp/textmodes/bibtex.el7
-rw-r--r--lisp/textmodes/reftex-parse.el12
-rw-r--r--lisp/textmodes/sgml-mode.el12
-rw-r--r--lisp/textmodes/tex-mode.el2
-rw-r--r--lisp/vc/diff.el8
-rw-r--r--lisp/vc/ediff-ptch.el14
-rw-r--r--lisp/vc/ediff-util.el6
-rw-r--r--lisp/vc/pcvs.el3
-rw-r--r--lisp/vc/vc.el15
-rw-r--r--lisp/wid-edit.el2
111 files changed, 2811 insertions, 3432 deletions
diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el
index b1c9cdaeca4..2e51264ec39 100644
--- a/lisp/ansi-color.el
+++ b/lisp/ansi-color.el
@@ -458,11 +458,18 @@ variable, and is meant to be used in `compilation-filter-hook'."
;; Working with strings
(defvar-local ansi-color-context nil
"Context saved between two calls to `ansi-color-apply'.
-This is a list of the form (CODES FRAGMENT) or nil. CODES
+This is a list of the form (FACE-VEC FRAGMENT) or nil. FACE-VEC
represents the state the last call to `ansi-color-apply' ended
-with, currently a list of ansi codes, and FRAGMENT is a string
-starting with an escape sequence, possibly the start of a new
-escape sequence.")
+with, currently a list of the form:
+
+ (BASIC-FACES FG BG)
+
+BASIC-FACES is a bool-vector that specifies which basic faces
+from `ansi-color-basic-faces-vector' to apply. FG and BG are
+ANSI color codes for the foreground and background color.
+
+FRAGMENT is a string starting with an escape sequence, possibly
+the start of a new escape sequence.")
(defun ansi-color-filter-apply (string)
"Filter out all ANSI control sequences from STRING.
@@ -473,17 +480,17 @@ will be used for the next call to `ansi-color-apply'. Set
`ansi-color-context' to nil if you don't want this.
This function can be added to `comint-preoutput-filter-functions'."
- (let ((start 0) end result)
+ (let ((context (ansi-color--ensure-context 'ansi-color-context nil))
+ (start 0) end result)
;; if context was saved and is a string, prepend it
- (if (cadr ansi-color-context)
- (setq string (concat (cadr ansi-color-context) string)
- ansi-color-context nil))
+ (setq string (concat (cadr context) string))
+ (setcar (cdr context) "")
;; find the next escape sequence
(while (setq end (string-match ansi-color-control-seq-regexp string start))
(push (substring string start end) result)
(setq start (match-end 0)))
;; save context, add the remainder of the string to the result
- (let (fragment)
+ (let ((fragment ""))
(push (substring string start
(if (string-match "\033" string start)
(let ((pos (match-beginning 0)))
@@ -491,25 +498,9 @@ This function can be added to `comint-preoutput-filter-functions'."
pos)
nil))
result)
- (setq ansi-color-context (if fragment (list nil fragment))))
+ (setcar (cdr context) fragment))
(apply #'concat (nreverse result))))
-(defun ansi-color--find-face (codes)
- "Return the face corresponding to CODES."
- ;; Sort the codes in ascending order to guarantee that "bold" comes before
- ;; any of the colors. This ensures that `ansi-color-bold-is-bright' is
- ;; applied correctly.
- (let (faces bright (codes (sort (copy-sequence codes) #'<)))
- (while codes
- (when-let ((face (ansi-color-get-face-1 (pop codes) bright)))
- (when (and ansi-color-bold-is-bright (eq face 'ansi-color-bold))
- (setq bright t))
- (push face faces)))
- ;; Avoid some long-lived conses in the common case.
- (if (cdr faces)
- (nreverse faces)
- (car faces))))
-
(defun ansi-color-apply (string)
"Translates SGR control sequences into text properties.
Delete all other control sequences without processing them.
@@ -524,49 +515,157 @@ This information will be used for the next call to `ansi-color-apply'.
Set `ansi-color-context' to nil if you don't want this.
This function can be added to `comint-preoutput-filter-functions'."
- (let ((codes (car ansi-color-context))
- (start 0) end result)
+ (let* ((context
+ (ansi-color--ensure-context 'ansi-color-context nil))
+ (face-vec (car context))
+ (start 0)
+ end result)
;; If context was saved and is a string, prepend it.
- (if (cadr ansi-color-context)
- (setq string (concat (cadr ansi-color-context) string)
- ansi-color-context nil))
+ (setq string (concat (cadr context) string))
+ (setcar (cdr context) "")
;; Find the next escape sequence.
(while (setq end (string-match ansi-color-control-seq-regexp string start))
(let ((esc-end (match-end 0)))
;; Colorize the old block from start to end using old face.
- (when codes
+ (when-let ((face (ansi-color--face-vec-face face-vec)))
(put-text-property start end 'font-lock-face
- (ansi-color--find-face codes) string))
+ face string))
(push (substring string start end) result)
(setq start (match-end 0))
;; If this is a color escape sequence,
(when (eq (aref string (1- esc-end)) ?m)
;; create a new face from it.
- (setq codes (ansi-color-apply-sequence
- (substring string end esc-end) codes)))))
+ (let ((cur-pos end))
+ (ansi-color--update-face-vec
+ face-vec
+ (lambda ()
+ (when (string-match ansi-color-parameter-regexp
+ string cur-pos)
+ (setq cur-pos (match-end 0))
+ (when (<= cur-pos esc-end)
+ (string-to-number (match-string 1 string))))))))))
;; if the rest of the string should have a face, put it there
- (when codes
+ (when-let ((face (ansi-color--face-vec-face face-vec)))
(put-text-property start (length string)
- 'font-lock-face (ansi-color--find-face codes) string))
+ 'font-lock-face face string))
;; save context, add the remainder of the string to the result
- (let (fragment)
- (if (string-match "\033" string start)
- (let ((pos (match-beginning 0)))
- (setq fragment (substring string pos))
- (push (substring string start pos) result))
- (push (substring string start) result))
- (setq ansi-color-context (if (or codes fragment) (list codes fragment))))
+ (if (string-match "\033" string start)
+ (let ((pos (match-beginning 0)))
+ (setcar (cdr context) (substring string pos))
+ (push (substring string start pos) result))
+ (push (substring string start) result))
(apply 'concat (nreverse result))))
+(defun ansi-color--ensure-context (context-sym position)
+ "Return CONTEXT-SYM's value as a valid context.
+If it is nil, set CONTEXT-SYM's value to a new context and return
+it. Context is a list of the form as described in
+`ansi-color-context' if POSITION is nil, or
+`ansi-color-context-region' if POSITION is non-nil.
+
+If CONTEXT-SYM's value is already non-nil, return it. If its
+marker doesn't point anywhere yet, position it before character
+number POSITION, if non-nil."
+ (let ((context (symbol-value context-sym)))
+ (if context
+ (if position
+ (let ((marker (cadr context)))
+ (unless (marker-position marker)
+ (set-marker marker position))
+ context)
+ context)
+ (set context-sym
+ (list (list (make-bool-vector 8 nil)
+ nil nil)
+ (if position
+ (copy-marker position)
+ ""))))))
+
+(defun ansi-color--face-vec-face (face-vec)
+ "Return the face corresponding to FACE-VEC.
+FACE-VEC is a list containing information about the ANSI sequence
+code. It is usually stored as the car of the variable
+`ansi-color-context-region'."
+ (let* ((basic-faces (car face-vec))
+ (colors (cdr face-vec))
+ (bright (and ansi-color-bold-is-bright (aref basic-faces 1)))
+ (faces nil))
+
+ (when-let ((fg (car colors)))
+ (push
+ `(:foreground
+ ,(or (ansi-color--code-as-hex fg)
+ (face-foreground
+ (aref (if (or bright (>= fg 8))
+ ansi-color-bright-colors-vector
+ ansi-color-normal-colors-vector)
+ (mod fg 8))
+ nil 'default)))
+ faces))
+ (when-let ((bg (cadr colors)))
+ (push
+ `(:background
+ ,(or (ansi-color--code-as-hex bg)
+ (face-background
+ (aref (if (or bright (>= bg 8))
+ ansi-color-bright-colors-vector
+ ansi-color-normal-colors-vector)
+ (mod bg 8))
+ nil 'default)))
+ faces))
+
+ (let ((i 8))
+ (while (> i 0)
+ (setq i (1- i))
+ (when (aref basic-faces i)
+ (push (aref ansi-color-basic-faces-vector i) faces))))
+ ;; Avoid some long-lived conses in the common case.
+ (if (cdr faces)
+ faces
+ (car faces))))
+
+(defun ansi-color--code-as-hex (color)
+ "Convert COLOR to hexadecimal string representation.
+COLOR is an ANSI color code. If it is between 16 and 255
+inclusive, it corresponds to a color from an 8-bit color cube.
+If it is greater or equal than 256, it is subtracted by 256 to
+directly specify a 24-bit color.
+
+Return a hexadecimal string, specifying the color, or nil, if
+COLOR is less than 16."
+ (cond
+ ((< color 16) nil)
+ ((>= color 256) (format "#%06X" (- color 256)))
+ ((>= color 232) ;; Grayscale
+ (format "#%06X" (* #x010101 (+ 8 (* 10 (- color 232))))))
+ (t ;; 6x6x6 color cube
+ (setq color (- color 16))
+ (let ((res 0)
+ (frac (* 6 6)))
+ (while (<= 1 frac) ; Repeat 3 times
+ (setq res (* res #x000100))
+ (let ((color-num (mod (/ color frac) 6)))
+ (unless (zerop color-num)
+ (setq res (+ res #x37 (* #x28 color-num)))))
+ (setq frac (/ frac 6)))
+ (format "#%06X" res)))))
+
;; Working with regions
(defvar-local ansi-color-context-region nil
"Context saved between two calls to `ansi-color-apply-on-region'.
-This is a list of the form (CODES MARKER) or nil. CODES
+This is a list of the form (FACE-VEC MARKER) or nil. FACE-VEC
represents the state the last call to `ansi-color-apply-on-region'
-ended with, currently a list of ansi codes, and MARKER is a
-buffer position within an escape sequence or the last position
-processed.")
+ended with, currently a list of the form:
+
+ (BASIC-FACES FG BG).
+
+BASIC-FACES is a bool-vector that specifies which basic faces
+from `ansi-color-basic-faces-vector' to apply. FG and BG are
+ANSI color codes for the foreground and background color.
+
+MARKER is a buffer position within an escape sequence or the last
+position processed.")
(defun ansi-color-filter-region (begin end)
"Filter out all ANSI control sequences from region BEGIN to END.
@@ -576,8 +675,10 @@ Every call to this function will set and use the buffer-local variable
used for the next call to `ansi-color-apply-on-region'. Specifically,
it will override BEGIN, the start of the region. Set
`ansi-color-context-region' to nil if you don't want this."
- (let ((end-marker (copy-marker end))
- (start (or (cadr ansi-color-context-region) begin)))
+ (let* ((end-marker (copy-marker end))
+ (context (ansi-color--ensure-context
+ 'ansi-color-context-region begin))
+ (start (cadr context)))
(save-excursion
(goto-char start)
;; Delete escape sequences.
@@ -585,8 +686,8 @@ it will override BEGIN, the start of the region. Set
(delete-region (match-beginning 0) (match-end 0)))
;; save context, add the remainder of the string to the result
(if (re-search-forward "\033" end-marker t)
- (setq ansi-color-context-region (list nil (match-beginning 0)))
- (setq ansi-color-context-region nil)))))
+ (set-marker start (match-beginning 0))
+ (set-marker start nil)))))
(defun ansi-color-apply-on-region (begin end &optional preserve-sequences)
"Translates SGR control sequences into overlays or extents.
@@ -608,58 +709,58 @@ this.
If PRESERVE-SEQUENCES is t, the sequences are hidden instead of
being deleted."
- (let ((codes (car ansi-color-context-region))
- (start-marker (or (cadr ansi-color-context-region)
- (copy-marker begin)))
- (end-marker (copy-marker end)))
+ (let* ((context (ansi-color--ensure-context
+ 'ansi-color-context-region begin))
+ (face-vec (car context))
+ (start-marker (cadr context))
+ (end-marker (copy-marker end)))
(save-excursion
(goto-char start-marker)
;; Find the next escape sequence.
(while (re-search-forward ansi-color-control-seq-regexp end-marker t)
;; Extract escape sequence.
- (let ((esc-seq (buffer-substring
- (match-beginning 0) (point))))
- (if preserve-sequences
- ;; Make the escape sequence transparent.
- (overlay-put (make-overlay (match-beginning 0) (point))
- 'invisible t)
- ;; Otherwise, strip.
- (delete-region (match-beginning 0) (point)))
-
+ (let ((esc-beg (match-beginning 0))
+ (esc-end (point)))
;; Colorize the old block from start to end using old face.
(funcall ansi-color-apply-face-function
(prog1 (marker-position start-marker)
;; Store new start position.
- (set-marker start-marker (point)))
- (match-beginning 0) (ansi-color--find-face codes))
+ (set-marker start-marker esc-end))
+ esc-beg (ansi-color--face-vec-face face-vec))
;; If this is a color sequence,
- (when (eq (aref esc-seq (1- (length esc-seq))) ?m)
- ;; update the list of ansi codes.
- (setq codes (ansi-color-apply-sequence esc-seq codes)))))
+ (when (eq (char-before esc-end) ?m)
+ (goto-char esc-beg)
+ (ansi-color--update-face-vec
+ face-vec (lambda ()
+ (when (re-search-forward ansi-color-parameter-regexp
+ esc-end t)
+ (string-to-number (match-string 1))))))
+
+ (if preserve-sequences
+ ;; Make the escape sequence transparent.
+ (overlay-put (make-overlay esc-beg esc-end) 'invisible t)
+ ;; Otherwise, strip.
+ (delete-region esc-beg esc-end))))
;; search for the possible start of a new escape sequence
(if (re-search-forward "\033" end-marker t)
- (progn
- ;; if the rest of the region should have a face, put it there
- (funcall ansi-color-apply-face-function
- start-marker (point) (ansi-color--find-face codes))
- ;; save codes and point
- (setq ansi-color-context-region
- (list codes (copy-marker (match-beginning 0)))))
- ;; if the rest of the region should have a face, put it there
- (funcall ansi-color-apply-face-function
- start-marker end-marker (ansi-color--find-face codes))
- ;; Save a restart position when there are codes active. It's
- ;; convenient for man.el's process filter to pass `begin'
- ;; positions that overlap regions previously colored; these
- ;; `codes' should not be applied to that overlap, so we need
- ;; to know where they should really start.
- (setq ansi-color-context-region
- (if codes (list codes (copy-marker (point)))))))
- ;; Clean up our temporary markers.
- (unless (eq start-marker (cadr ansi-color-context-region))
- (set-marker start-marker nil))
- (unless (eq end-marker (cadr ansi-color-context-region))
- (set-marker end-marker nil))))
+ (progn
+ (while (re-search-forward "\033" end-marker t))
+ (backward-char)
+ (funcall ansi-color-apply-face-function
+ start-marker (point)
+ (ansi-color--face-vec-face face-vec))
+ (set-marker start-marker (point)))
+ (let ((faces (ansi-color--face-vec-face face-vec)))
+ (funcall ansi-color-apply-face-function
+ start-marker end-marker faces)
+ ;; Save a restart position when there are codes active. It's
+ ;; convenient for man.el's process filter to pass `begin'
+ ;; positions that overlap regions previously colored; these
+ ;; `codes' should not be applied to that overlap, so we need
+ ;; to know where they should really start.
+ (set-marker start-marker (when faces end-marker)))))
+ ;; Clean up our temporary marker.
+ (set-marker end-marker nil)))
(defun ansi-color-apply-overlay-face (beg end face)
"Make an overlay from BEG to END, and apply face FACE.
@@ -767,6 +868,7 @@ the foreground color code is replaced or added resp. deleted; if it
is 40-47 (or 100-107) resp. 49, the background color code is replaced
or added resp. deleted; any other code is discarded together with the
old codes. Finally, the so changed list of codes is returned."
+ (declare (obsolete ansi-color--update-face-vec "29.1"))
(let ((new-codes (ansi-color-parse-sequence escape-sequence)))
(while new-codes
(let* ((new (pop new-codes))
@@ -795,6 +897,72 @@ old codes. Finally, the so changed list of codes is returned."
(_ nil)))))
codes))
+(defun ansi-color--update-face-vec (face-vec iterator)
+ "Apply escape sequences to FACE-VEC.
+
+Destructively modify FACE-VEC, which should be a list containing
+face information. It is described in
+`ansi-color-context-region'. ITERATOR is a function which is
+called repeatedly with zero arguments and should return either
+the next ANSI code in the current sequence as a number or nil if
+there are no more ANSI codes left.
+
+For each new code, the following happens: if it is 1-7, set the
+corresponding properties; if it is 21-25 or 27, unset appropriate
+properties; if it is 30-37 (or 90-97) or resp. 39, set the
+foreground color or resp. unset it; if it is 40-47 (or 100-107)
+resp. 49, set the background color or resp. unset it; if it is 38
+or 48, the following codes are used to set the foreground or
+background color and the correct color mode; any other code will
+unset all properties and colors."
+ (let ((basic-faces (car face-vec))
+ (colors (cdr face-vec))
+ new q do-clear)
+ (while (setq new (funcall iterator))
+ (setq q (/ new 10))
+ (pcase q
+ (0 (if (memq new '(0 8 9))
+ (setq do-clear t)
+ (aset basic-faces new t)))
+ (2 (if (memq new '(20 26 28 29))
+ (setq do-clear t)
+ ;; The standard says `21 doubly underlined' while
+ ;; https://en.wikipedia.org/wiki/ANSI_escape_code claims
+ ;; `21 Bright/Bold: off or Underline: Double'.
+ (aset basic-faces (- new 20) nil)
+ (aset basic-faces (pcase new (22 1) (25 6) (_ 0)) nil)))
+ ((or 3 4 9 10)
+ (let ((r (mod new 10))
+ (cell (if (memq q '(3 9)) colors (cdr colors))))
+ (pcase r
+ (8
+ (pcase (funcall iterator)
+ (5 (setq new (setcar cell (funcall iterator)))
+ (setq do-clear (or (null new) (>= new 256))))
+ (2
+ (let ((red (funcall iterator))
+ (green (funcall iterator))
+ (blue (funcall iterator)))
+ (if (and red green blue
+ (progn
+ (setq new (+ (* #x010000 red)
+ (* #x000100 green)
+ (* #x000001 blue)))
+ (<= new #xFFFFFF)))
+ (setcar cell (+ 256 new))
+ (setq do-clear t))))
+ (_ (setq do-clear t))))
+ (9 (setcar cell nil))
+ (_ (setcar cell (+ (if (memq q '(3 4)) 0 8) r))))))
+ (_ (setq do-clear t)))
+
+ (when do-clear
+ (setq do-clear nil)
+ ;; Zero out our bool vector without any allocation.
+ (bool-vector-intersection basic-faces #&8"\0" basic-faces)
+ (setcar colors nil)
+ (setcar (cdr colors) nil)))))
+
(defun ansi-color-make-color-map ()
"Create a vector of face definitions and return it.
@@ -859,6 +1027,7 @@ This function is obsolete, and no longer needed to use ansi-color."
"Get face definition for ANSI-CODE.
BRIGHT, if non-nil, requests \"bright\" ANSI colors, even if ANSI-CODE
is a normal-intensity color."
+ (declare (obsolete ansi-color--face-vec-face "29.1"))
(when (and bright (<= 30 ansi-code 49))
(setq ansi-code (+ ansi-code 60)))
(cond ((<= 0 ansi-code 7)
diff --git a/lisp/bookmark.el b/lisp/bookmark.el
index d64966df5af..5c4a9803b39 100644
--- a/lisp/bookmark.el
+++ b/lisp/bookmark.el
@@ -498,11 +498,8 @@ If DEFAULT is nil then return empty string for empty input."
'string-lessp)
(bookmark-all-names)))
(let* ((completion-ignore-case bookmark-completion-ignore-case)
- (default (unless (equal "" default) default))
- (prompt (concat prompt (if default
- (format " (%s): " default)
- ": "))))
- (completing-read prompt
+ (default (unless (equal "" default) default)))
+ (completing-read (format-prompt prompt default)
(lambda (string pred action)
(if (eq action 'metadata)
'(metadata (category . bookmark))
diff --git a/lisp/calc/calc-prog.el b/lisp/calc/calc-prog.el
index 3492b6d831b..b381f8afcf9 100644
--- a/lisp/calc/calc-prog.el
+++ b/lisp/calc/calc-prog.el
@@ -205,9 +205,8 @@
(progn
(setq cmd-base-default (concat "User-" keyname))
(setq cmd (completing-read
- (concat "Define M-x command name (default calc-"
- cmd-base-default
- "): ")
+ (format-prompt "Define M-x command name"
+ (concat "calc-" cmd-base-default))
obarray 'commandp nil
(if (and odef (symbolp (cdr odef)))
(symbol-name (cdr odef))
@@ -241,8 +240,8 @@
(setq func
(concat "calcFunc-"
(completing-read
- (concat "Define algebraic function name (default "
- cmd-base-default "): ")
+ (format-prompt "Define algebraic function name"
+ cmd-base-default)
(mapcar (lambda (x) (substring x 9))
(all-completions "calcFunc-"
obarray))
diff --git a/lisp/calc/calc-store.el b/lisp/calc/calc-store.el
index ee29c440fe4..b3968555b62 100644
--- a/lisp/calc/calc-store.el
+++ b/lisp/calc/calc-store.el
@@ -586,7 +586,7 @@
(defun calc-permanent-variable (&optional var)
(interactive)
(calc-wrapper
- (or var (setq var (calc-read-var-name "Save variable (default all): ")))
+ (or var (setq var (calc-read-var-name (format-prompt "Save variable" "all"))))
(let (calc-pv-pos)
(and var (or (and (boundp var) (symbol-value var))
(error "No such variable")))
diff --git a/lisp/calc/calc-units.el b/lisp/calc/calc-units.el
index fd6f3a7b67b..f6d749db117 100644
--- a/lisp/calc/calc-units.el
+++ b/lisp/calc/calc-units.el
@@ -486,18 +486,13 @@ If COMP or STD is non-nil, put that in the units table instead."
(setq defunits (math-get-default-units expr))
(unless new-units
(setq new-units
- (read-string (concat
+ (read-string (format-prompt
(if (and uoldname (not nouold))
(concat "Old units: "
uoldname
", new units")
"New units")
- (if defunits
- (concat
- " (default "
- defunits
- "): ")
- ": "))))
+ defunits)))
(if (and
(string= new-units "")
defunits)
@@ -533,14 +528,7 @@ If COMP or STD is non-nil, put that in the units table instead."
(let* ((old-units (math-extract-units expr))
(defunits (math-get-default-units expr))
units
- (new-units
- (read-string (concat "New units"
- (if defunits
- (concat
- " (default "
- defunits
- "): ")
- ": ")))))
+ (new-units (read-string (format-prompt "New units" defunits))))
(if (and
(string= new-units "")
defunits)
@@ -596,19 +584,14 @@ If COMP or STD is non-nil, put that in the units table instead."
(setq expr (math-mul expr uold)))
(setq defunits (math-get-default-units expr))
(setq unew (or new-units
- (completing-read
- (concat
- (if uoldname
- (concat "Old temperature units: "
- uoldname
- ", new units")
- "New temperature units")
- (if defunits
- (concat " (default "
- defunits
- "): ")
- ": "))
- tempunits)))
+ (completing-read (format-prompt
+ (if uoldname
+ (concat "Old temperature units: "
+ uoldname
+ ", new units")
+ "New temperature units")
+ defunits)
+ tempunits)))
(setq unew (math-read-expr (if (string= unew "") defunits unew)))
(when (eq (car-safe unew) 'error)
(error "Bad format in units expression: %s" (nth 2 unew)))
diff --git a/lisp/cedet/semantic/complete.el b/lisp/cedet/semantic/complete.el
index 6cfbdd5f03f..375b97a7a5d 100644
--- a/lisp/cedet/semantic/complete.el
+++ b/lisp/cedet/semantic/complete.el
@@ -224,11 +224,10 @@ HISTORY is a symbol representing a variable to story the history in."
;; @todo - move from () to into the editable area
(if (string-match ":" prompt)
- (setq prompt (concat
- (substring prompt 0 (match-beginning 0))
- " (default " default-as-string ")"
- (substring prompt (match-beginning 0))))
- (setq prompt (concat prompt " (" default-as-string "): "))))
+ (setq prompt (format-prompt
+ (substring prompt 0 (match-beginning 0))
+ default-as-string))
+ (setq prompt (format-prompt prompt default-as-string))))
;;
;; Perform the Completion
;;
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index a0bde396735..34a6db508d5 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -1133,7 +1133,7 @@ for the MODE to customize."
(defun customize-read-group ()
(let ((completion-ignore-case t))
- (completing-read "Customize group (default emacs): "
+ (completing-read (format-prompt "Customize group" "emacs")
obarray
(lambda (symbol)
(or (and (get symbol 'custom-loads)
@@ -1205,7 +1205,7 @@ Show the buffer in another window, but don't select it."
(unless (eq symbol basevar)
(message "`%s' is an alias for `%s'" symbol basevar))))
-(defvar customize-changed-options-previous-release "27.2"
+(defvar customize-changed-options-previous-release "28.1"
"Version for `customize-changed' to refer back to by default.")
;; Packages will update this variable, so make it available.
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 1a3e5682bba..a46107a6784 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -386,7 +386,7 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
(const :tag "When sent SIGUSR1" sigusr1)
(const :tag "When sent SIGUSR2" sigusr2))
"24.1")
-
+ (translate-upper-case-key-bindings keyboard boolean "29.1")
;; This is not good news because it will use the wrong
;; version-specific directories when you upgrade. We need
;; customization of the front of the list, maintaining the
diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el
index 07881e9b74e..f618e3341cb 100644
--- a/lisp/cus-theme.el
+++ b/lisp/cus-theme.el
@@ -627,22 +627,24 @@ Theme files are named *-theme.el in `"))
(let ((help-echo "mouse-2: Enable this theme for this session")
widget)
(dolist (theme (custom-available-themes))
- (setq widget (widget-create 'checkbox
- :value (custom-theme-enabled-p theme)
- :theme-name theme
- :help-echo help-echo
- :action #'custom-theme-checkbox-toggle))
- (push (cons theme widget) custom--listed-themes)
- (widget-create-child-and-convert widget 'push-button
- :button-face-get 'ignore
- :mouse-face-get 'ignore
- :value (format " %s" theme)
- :action #'widget-parent-action
- :help-echo help-echo)
- (widget-insert " -- "
- (propertize (custom-theme-summary theme)
- 'face 'shadow)
- ?\n)))
+ ;; Don't list obsolete themes.
+ (unless (get theme 'byte-obsolete-info)
+ (setq widget (widget-create 'checkbox
+ :value (custom-theme-enabled-p theme)
+ :theme-name theme
+ :help-echo help-echo
+ :action #'custom-theme-checkbox-toggle))
+ (push (cons theme widget) custom--listed-themes)
+ (widget-create-child-and-convert widget 'push-button
+ :button-face-get 'ignore
+ :mouse-face-get 'ignore
+ :value (format " %s" theme)
+ :action #'widget-parent-action
+ :help-echo help-echo)
+ (widget-insert " -- "
+ (propertize (custom-theme-summary theme)
+ 'face 'shadow)
+ ?\n))))
(goto-char (point-min))
(widget-setup))
diff --git a/lisp/custom.el b/lisp/custom.el
index 858b158051c..0cd4318e63d 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -1331,6 +1331,13 @@ Return t if THEME was successfully loaded, nil otherwise."
t))))
(t
(error "Unable to load theme `%s'" theme))))
+ (when-let ((obs (get theme 'byte-obsolete-info)))
+ (display-warning 'initialization
+ (format "The `%s' theme is obsolete%s"
+ theme
+ (if (nth 2 obs)
+ (format " since Emacs %s" (nth 2 obs))
+ ""))))
;; Optimization: if the theme changes the `default' face, put that
;; entry first. This avoids some `frame-set-background-mode' rigmarole
;; by assigning the new background immediately.
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 32375ac5253..ef299b21fd6 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -444,10 +444,10 @@ List has a form of (file-name full-file-name (attribute-list))."
((eq op-symbol 'chgrp)
(file-attribute-group-id
(file-attributes default-file 'string))))))
- (prompt (concat "Change " attribute-name " of %s to"
- (if (eq op-symbol 'touch)
- " (default now): "
- ": ")))
+ (prompt (format-prompt "Change %s of %%s to"
+ (when (eq op-symbol 'touch)
+ "now")
+ attribute-name))
(new-attribute (dired-mark-read-string prompt nil op-symbol
arg files default
(cond ((eq op-symbol 'chown)
diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 7c6f49f2ae4..7f889a2bfd6 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -554,7 +554,7 @@ If the region is active in Transient Mark mode, operate only on
files in the active region if `dired-mark-region' is non-nil."
(interactive
(list (read-regexp
- "Mark unmarked files matching regexp (default all): "
+ (format-prompt "Mark unmarked files matching regexp" "all")
nil 'dired-regexp-history)
nil current-prefix-arg nil))
(let ((dired-marker-char (if unflag-p ?\s dired-marker-char)))
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 4834fb13c6a..2c292415cfe 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -100,6 +100,7 @@
(eval-when-compile (require 'cl-lib))
(eval-when-compile (require 'cl-macs)) ;For cl--find-class.
(eval-when-compile (require 'pcase))
+(eval-when-compile (require 'subr-x))
(cl-defstruct (cl--generic-generalizer
(:constructor nil)
@@ -589,19 +590,10 @@ The set of acceptable TYPEs (also called \"specializers\") is defined
;; e.g. for tracing/debug-on-entry.
(defalias sym gfun)))))
-(defmacro cl--generic-with-memoization (place &rest code)
- (declare (indent 1) (debug t))
- (gv-letplace (getter setter) place
- `(or ,getter
- ,(macroexp-let2 nil val (macroexp-progn code)
- `(progn
- ,(funcall setter val)
- ,val)))))
-
(defvar cl--generic-dispatchers (make-hash-table :test #'equal))
(defun cl--generic-get-dispatcher (dispatch)
- (cl--generic-with-memoization
+ (with-memoization
(gethash dispatch cl--generic-dispatchers)
;; (message "cl--generic-get-dispatcher (%S)" dispatch)
(let* ((dispatch-arg (car dispatch))
@@ -644,10 +636,13 @@ The set of acceptable TYPEs (also called \"specializers\") is defined
;; overkill: better just use a `cl-typep' test.
(byte-compile
`(lambda (generic dispatches-left methods)
+ ;; FIXME: We should find a way to expand `with-memoize' once
+ ;; and forall so we don't need `subr-x' when we get here.
+ (eval-when-compile (require 'subr-x))
(let ((method-cache (make-hash-table :test #'eql)))
(lambda (,@fixedargs &rest args)
(let ,bindings
- (apply (cl--generic-with-memoization
+ (apply (with-memoization
(gethash ,tag-exp method-cache)
(cl--generic-cache-miss
generic ',dispatch-arg dispatches-left methods
@@ -691,7 +686,7 @@ for all those different tags in the method-cache.")
;; Special case needed to fix a circularity during bootstrap.
(cl--generic-standard-method-combination generic methods)
(let ((f
- (cl--generic-with-memoization
+ (with-memoization
;; FIXME: Since the fields of `generic' are modified, this
;; hash-table won't work right, because the hashes will change!
;; It's not terribly serious, but reduces the effectiveness of
@@ -1143,7 +1138,7 @@ These match if the argument is a cons cell whose car is `eql' to VAL."
;; since we can't use the `head' specializer to implement itself.
(if (not (eq (car-safe specializer) 'head))
(cl-call-next-method)
- (cl--generic-with-memoization
+ (with-memoization
(gethash (cadr specializer) cl--generic-head-used)
specializer)
(list cl--generic-head-generalizer)))
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el
index 0592db85df4..163528acf6f 100644
--- a/lisp/emacs-lisp/debug.el
+++ b/lisp/emacs-lisp/debug.el
@@ -701,7 +701,8 @@ To specify a nil argument interactively, exit with an empty minibuffer."
(interactive
(list (let ((name
(completing-read
- "Cancel debug on entry to function (default all functions): "
+ (format-prompt "Cancel debug on entry to function"
+ "all functions")
(mapcar #'symbol-name (debug--function-list)) nil t)))
(when name
(unless (string= name "")
@@ -804,7 +805,8 @@ To specify a nil argument interactively, exit with an empty minibuffer."
(interactive
(list (let ((name
(completing-read
- "Cancel debug on set for variable (default all variables): "
+ (format-prompt "Cancel debug on set for variable"
+ "all variables")
(mapcar #'symbol-name (debug--variable-list)) nil t)))
(when name
(unless (string= name "")
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 4f3c05baa98..a38c8bd5ca9 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -3519,7 +3519,8 @@ The removes the effect of `edebug-on-entry'. If FUNCTION is
nil, remove `edebug-on-entry' on all functions."
(interactive
(list (let ((name (completing-read
- "Cancel edebug on entry to (default all functions): "
+ (format-prompt "Cancel edebug on entry to"
+ "all functions")
(let ((functions (edebug--edebug-on-entry-functions)))
(unless functions
(user-error "No functions have `edebug-on-entry'"))
@@ -4548,7 +4549,8 @@ instrumentation for, defaulting to all functions."
(user-error "Found no functions to remove instrumentation from"))
(let ((name
(completing-read
- "Remove instrumentation from (default all functions): "
+ (format-prompt "Remove instrumentation from"
+ "all functions")
functions)))
(if (and name
(not (equal name "")))
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el
index 98cb1fd1cf6..21b3fbf98b3 100644
--- a/lisp/emacs-lisp/ert.el
+++ b/lisp/emacs-lisp/ert.el
@@ -63,6 +63,7 @@
(require 'ewoc)
(require 'find-func)
(require 'pp)
+(require 'map)
;;; UI customization options.
@@ -218,11 +219,7 @@ it has to be wrapped in `(eval (quote ...))'.
`(:expected-result-type ,expected-result))
,@(when tags-supplied-p
`(:tags ,tags))
- :body (lambda ()
- ;; Use the value of `lexical-binding' in
- ;; the source file when evaluating the body.
- (let ((lexical-binding ,lexical-binding))
- ,@body))))
+ :body (lambda () ,@body)))
',name))))
(defvar ert--find-test-regexp
@@ -779,7 +776,8 @@ This mainly sets up debugger-related bindings."
;; handle ert errors. Once that's done, remove
;; `ert--should-signal-hook'. See Bug#24402 and Bug#11218 for
;; details.
- (let ((debugger (lambda (&rest args)
+ (let ((lexical-binding t)
+ (debugger (lambda (&rest args)
(ert--run-test-debugger test-execution-info
args)))
(debug-on-error t)
@@ -2661,6 +2659,125 @@ To be used in the ERT results buffer."
'ert--activate-font-lock-keywords)
nil)
+(defun ert-test-erts-file (file &optional transform)
+ "Parse FILE as a file containing before/after parts.
+TRANSFORM will be called to get from before to after."
+ (with-temp-buffer
+ (insert-file-contents file)
+ (let ((gen-specs (list (cons 'dummy t)
+ (cons 'code transform))))
+ ;; The start of the "before" part starts with a form feed and then
+ ;; the name of the test.
+ (while (re-search-forward "^=-=\n" nil t)
+ (setq gen-specs (ert-test--erts-test gen-specs file))))))
+
+(defun ert-test--erts-test (gen-specs file)
+ (let* ((file-buffer (current-buffer))
+ (specs (ert--erts-specifications (match-beginning 0)))
+ (name (cdr (assq 'name specs)))
+ (start-before (point))
+ (end-after (if (re-search-forward "^=-=-=\n" nil t)
+ (match-beginning 0)
+ (point-max)))
+ (skip (cdr (assq 'skip specs)))
+ end-before start-after
+ after after-point)
+ (unless name
+ (error "No name for test case"))
+ (if (and skip
+ (eval (car (read-from-string skip))))
+ ;; Skipping this test.
+ ()
+ ;; Do the test.
+ (goto-char end-after)
+ ;; We have a separate after section.
+ (if (re-search-backward "^=-=\n" start-before t)
+ (setq end-before (match-beginning 0)
+ start-after (match-end 0))
+ (setq end-before end-after
+ start-after start-before))
+ ;; Update persistent specs.
+ (when-let ((point-char (assq 'point-char specs)))
+ (setq gen-specs
+ (map-insert gen-specs 'point-char (cdr point-char))))
+ (when-let ((code (cdr (assq 'code specs))))
+ (setq gen-specs
+ (map-insert gen-specs 'code (car (read-from-string code)))))
+ ;; Get the "after" strings.
+ (with-temp-buffer
+ (insert-buffer-substring file-buffer start-after end-after)
+ (ert--erts-unquote)
+ ;; Remove the newline at the end of the buffer.
+ (when-let ((no-newline (cdr (assq 'no-after-newline specs))))
+ (goto-char (point-min))
+ (when (re-search-forward "\n\\'" nil t)
+ (delete-region (match-beginning 0) (match-end 0))))
+ ;; Get the expected "after" point.
+ (when-let ((point-char (cdr (assq 'point-char gen-specs))))
+ (goto-char (point-min))
+ (when (search-forward point-char nil t)
+ (delete-region (match-beginning 0) (match-end 0))
+ (setq after-point (point))))
+ (setq after (buffer-string)))
+ ;; Do the test.
+ (with-temp-buffer
+ (insert-buffer-substring file-buffer start-before end-before)
+ (ert--erts-unquote)
+ ;; Remove the newline at the end of the buffer.
+ (when-let ((no-newline (cdr (assq 'no-before-newline specs))))
+ (goto-char (point-min))
+ (when (re-search-forward "\n\\'" nil t)
+ (delete-region (match-beginning 0) (match-end 0))))
+ (goto-char (point-min))
+ ;; Place point in the specified place.
+ (when-let ((point-char (cdr (assq 'point-char gen-specs))))
+ (when (search-forward point-char nil t)
+ (delete-region (match-beginning 0) (match-end 0))))
+ (let ((code (cdr (assq 'code gen-specs))))
+ (unless code
+ (error "No code to run the transform"))
+ (funcall code))
+ (unless (equal (buffer-string) after)
+ (ert-fail (list (format "Mismatch in test \"%s\", file %s"
+ name file)
+ (buffer-string)
+ after)))
+ (when (and after-point
+ (not (= after-point (point))))
+ (ert-fail (list (format "Point wrong in test \"%s\", expected point %d, actual %d, file %s"
+ name
+ after-point (point)
+ file)
+ (buffer-string)))))))
+ ;; Return the new value of the general specifications.
+ gen-specs)
+
+(defun ert--erts-unquote ()
+ (goto-char (point-min))
+ (while (re-search-forward "^\\=-=\\(-=\\)$" nil t)
+ (delete-region (match-beginning 0) (1+ (match-beginning 0)))))
+
+(defun ert--erts-specifications (end)
+ "Find specifications before point (back to the previous test)."
+ (save-excursion
+ (goto-char end)
+ (goto-char
+ (if (re-search-backward "^=-=-=\n" nil t)
+ (match-end 0)
+ (point-min)))
+ (let ((specs nil))
+ (while (< (point) end)
+ (if (looking-at "\\([^ \n\t:]+\\):\\([ \t]+\\)?\\(.*\\)")
+ (let ((name (intern (downcase (match-string 1))))
+ (value (match-string 3)))
+ (forward-line 1)
+ (while (looking-at "[ \t]+\\(.*\\)")
+ (setq value (concat value (match-string 1)))
+ (forward-line 1))
+ (push (cons name value) specs))
+ (forward-line 1)))
+ (nreverse specs))))
+
(defvar ert-unload-hook ())
(add-hook 'ert-unload-hook #'ert--unload-function)
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index fc7a7362cd7..b7b8f3a90c4 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -29,6 +29,7 @@
;;; Code:
(eval-when-compile (require 'cl-lib))
+(eval-when-compile (require 'subr-x))
(defvar font-lock-comment-face)
(defvar font-lock-doc-face)
@@ -1105,6 +1106,62 @@ is the buffer position of the start of the containing expression."
(t
normal-indent))))))
+(defun lisp--local-defform-body-p (state)
+ "Return non-nil when at local definition body according to STATE.
+STATE is the `parse-partial-sexp' state for current position."
+ (when-let ((start-of-innermost-containing-list (nth 1 state)))
+ (let* ((parents (nth 9 state))
+ (second-cons-after (cddr parents))
+ second-order-parent)
+ (while second-cons-after
+ (when (= start-of-innermost-containing-list
+ (car second-cons-after))
+ (setq second-order-parent (car parents)
+ ;; Leave the loop.
+ second-cons-after nil))
+ (pop second-cons-after)
+ (pop parents))
+ (when second-order-parent
+ (save-excursion
+ (goto-char (1+ second-order-parent))
+ (and (when-let ((head (ignore-errors
+ ;; FIXME: This does not distinguish
+ ;; between reading nil and a read error.
+ ;; We don't care but still, better fix this.
+ (read (current-buffer)))))
+ (memq head '( cl-flet cl-labels cl-macrolet cl-flet*
+ cl-symbol-macrolet)))
+ ;; Now we must check that we are
+ ;; in the second element of the flet-like form.
+ ;; It would be easier if `parse-partial-sexp' also recorded
+ ;; relative positions of subsexps in supersexps
+ ;; but it doesn't so we check manually.
+ ;;
+ ;; First, we must be looking at list now.
+ (ignore-errors (when (= (scan-lists (point) 1 0)
+ (scan-sexps (point) 1))
+ ;; Looking at list; descend into it:
+ (down-list 1)
+ t))
+ ;; In Wishful Lisp, the following form would be
+ ;; (cl-member start-of-innermost-containing-list
+ ;; (points-at-beginning-of-lists-at-this-level)
+ ;; :test #'=)
+ (cl-loop
+ with pos = (ignore-errors
+ ;; The first local definition may be indented
+ ;; with whitespace following open paren.
+ (goto-char (scan-lists (point) 1 0))
+ (goto-char (scan-lists (point) -1 0))
+ (point))
+ while pos
+ do (if (= start-of-innermost-containing-list pos)
+ (cl-return t)
+ (setq pos (ignore-errors
+ (goto-char (scan-lists (point) 2 0))
+ (goto-char (scan-lists (point) -1 0))
+ (point)))))))))))
+
(defun lisp-indent-function (indent-point state)
"This function is the normal value of the variable `lisp-indent-function'.
The function `calculate-lisp-indent' calls this to determine
@@ -1138,16 +1195,19 @@ Lisp function does not specify a special indentation."
(if (and (elt state 2)
(not (looking-at "\\sw\\|\\s_")))
;; car of form doesn't seem to be a symbol
- (progn
+ (if (lisp--local-defform-body-p state)
+ ;; We nevertheless check whether we are in flet-like form
+ ;; as we presume local function names could be non-symbols.
+ (lisp-indent-defform state indent-point)
(if (not (> (save-excursion (forward-line 1) (point))
calculate-lisp-indent-last-sexp))
- (progn (goto-char calculate-lisp-indent-last-sexp)
- (beginning-of-line)
- (parse-partial-sexp (point)
- calculate-lisp-indent-last-sexp 0 t)))
- ;; Indent under the list or under the first sexp on the same
- ;; line as calculate-lisp-indent-last-sexp. Note that first
- ;; thing on that line has to be complete sexp since we are
+ (progn (goto-char calculate-lisp-indent-last-sexp)
+ (beginning-of-line)
+ (parse-partial-sexp (point)
+ calculate-lisp-indent-last-sexp 0 t)))
+ ;; Indent under the list or under the first sexp on the same
+ ;; line as calculate-lisp-indent-last-sexp. Note that first
+ ;; thing on that line has to be complete sexp since we are
;; inside the innermost containing sexp.
(backward-prefix-chars)
(current-column))
@@ -1160,13 +1220,15 @@ Lisp function does not specify a special indentation."
(cond ((or (eq method 'defun)
(and (null method)
(> (length function) 3)
- (string-match "\\`def" function)))
+ (string-match "\\`def" function))
+ ;; Check whether we are in flet-like form.
+ (lisp--local-defform-body-p state))
(lisp-indent-defform state indent-point))
((integerp method)
(lisp-indent-specform method state
indent-point normal-indent))
(method
- (funcall method indent-point state)))))))
+ (funcall method indent-point state)))))))
(defcustom lisp-body-indent 2
"Number of columns to indent the second line of a `(def...)' form."
diff --git a/lisp/emacs-lisp/memory-report.el b/lisp/emacs-lisp/memory-report.el
index 3166d33e029..cda2dee6cbc 100644
--- a/lisp/emacs-lisp/memory-report.el
+++ b/lisp/emacs-lisp/memory-report.el
@@ -31,7 +31,7 @@
(require 'subr-x)
(require 'cl-lib)
-(defvar memory-report--type-size (make-hash-table))
+(defvar memory-report--type-size nil)
;;;###autoload
(defun memory-report ()
@@ -84,6 +84,7 @@ by counted more than once."
(gethash 'object memory-report--type-size)))
(defun memory-report--set-size (elems)
+ (setq memory-report--type-size (make-hash-table))
(setf (gethash 'string memory-report--type-size)
(cadr (assq 'strings elems)))
(setf (gethash 'cons memory-report--type-size)
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 3de666682fa..8d6bb19fd49 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -208,7 +208,9 @@ The variable list SPEC is the same as in `if-let'."
(string= string ""))
(defsubst string-join (strings &optional separator)
- "Join all STRINGS using SEPARATOR."
+ "Join all STRINGS using SEPARATOR.
+Optional argument SEPARATOR must be a string, a vector, or a list of
+characters; nil stands for the empty string."
(mapconcat #'identity strings separator))
(define-obsolete-function-alias 'string-reverse 'reverse "25.1")
@@ -400,6 +402,44 @@ as the new values of the bound variables in the recursive invocation."
(cl-labels ((,name ,fargs . ,body)) #',name)
. ,aargs)))
+(defmacro with-memoization (place &rest code)
+ "Return the value of CODE and stash it in PLACE.
+If PLACE's value is non-nil, then don't bother evaluating CODE
+and return the value found in PLACE instead."
+ (declare (indent 1) (debug (gv-place body)))
+ (gv-letplace (getter setter) place
+ `(or ,getter
+ ,(macroexp-let2 nil val (macroexp-progn code)
+ `(progn
+ ,(funcall setter val)
+ ,val)))))
+
+;;;###autoload
+(defun ensure-empty-lines (&optional lines)
+ "Ensure that there's LINES number of empty lines before point.
+If LINES is nil or missing, a this ensures that there's a single
+empty line before point.
+
+Interactively, this command uses the numerical prefix for LINES.
+
+If there's already more empty lines before point than LINES, the
+number of blank lines will be reduced.
+
+If point is not at the beginning of a line, a newline character
+is inserted before adjusting the number of empty lines."
+ (interactive "p")
+ (unless (bolp)
+ (insert "\n"))
+ (let ((lines (or lines 1))
+ (start (save-excursion
+ (if (re-search-backward "[^\n]" nil t)
+ (+ (point) 2)
+ (point-min)))))
+ (cond
+ ((> (- (point) start) lines)
+ (delete-region (point) (- (point) (- (point) start lines))))
+ ((< (- (point) start) lines)
+ (insert (make-string (- lines (- (point) start)) ?\n))))))
(provide 'subr-x)
diff --git a/lisp/epa.el b/lisp/epa.el
index 57d355cb3e0..e4b89e984d2 100644
--- a/lisp/epa.el
+++ b/lisp/epa.el
@@ -648,7 +648,7 @@ If SECRET is non-nil, list secret keys instead of public keys."
(setq input (file-name-sans-extension (expand-file-name input)))
(expand-file-name
(read-file-name
- (concat "To file (default " (file-name-nondirectory input) ") ")
+ (format-prompt "To file" (file-name-nondirectory input))
(file-name-directory input)
input)))
@@ -1236,9 +1236,7 @@ If no one is selected, symmetric encryption will be performed. ")
(list keys
(expand-file-name
(read-file-name
- (concat "To file (default "
- (file-name-nondirectory default-name)
- ") ")
+ (format-prompt "To file" (file-name-nondirectory default-name))
(file-name-directory default-name)
default-name)))))
(let ((context (epg-make-context epa-protocol)))
diff --git a/lisp/faces.el b/lisp/faces.el
index 7b96d938c56..089cb889090 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -861,8 +861,8 @@ is specified, `:italic' is ignored."
(defun make-face-bold (face &optional frame _noerror)
"Make the font of FACE be bold, if possible.
FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility.
Use `set-face-attribute' for finer control of the font weight."
+ (declare (advertised-calling-convention (face &optional frame) "29.1"))
(interactive (list (read-face-name "Make which face bold"
(face-at-point t))))
(set-face-attribute face frame :weight 'bold))
@@ -870,8 +870,8 @@ Use `set-face-attribute' for finer control of the font weight."
(defun make-face-unbold (face &optional frame _noerror)
"Make the font of FACE be non-bold, if possible.
-FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility."
+FRAME nil or not specified means change face on all frames."
+ (declare (advertised-calling-convention (face &optional frame) "29.1"))
(interactive (list (read-face-name "Make which face non-bold"
(face-at-point t))))
(set-face-attribute face frame :weight 'normal))
@@ -880,8 +880,8 @@ Argument NOERROR is ignored and retained for compatibility."
(defun make-face-italic (face &optional frame _noerror)
"Make the font of FACE be italic, if possible.
FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility.
Use `set-face-attribute' for finer control of the font slant."
+ (declare (advertised-calling-convention (face &optional frame) "29.1"))
(interactive (list (read-face-name "Make which face italic"
(face-at-point t))))
(set-face-attribute face frame :slant 'italic))
@@ -889,8 +889,8 @@ Use `set-face-attribute' for finer control of the font slant."
(defun make-face-unitalic (face &optional frame _noerror)
"Make the font of FACE be non-italic, if possible.
-FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility."
+FRAME nil or not specified means change face on all frames."
+ (declare (advertised-calling-convention (face &optional frame) "29.1"))
(interactive (list (read-face-name "Make which face non-italic"
(face-at-point t))))
(set-face-attribute face frame :slant 'normal))
@@ -899,8 +899,8 @@ Argument NOERROR is ignored and retained for compatibility."
(defun make-face-bold-italic (face &optional frame _noerror)
"Make the font of FACE be bold and italic, if possible.
FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility.
Use `set-face-attribute' for finer control of font weight and slant."
+ (declare (advertised-calling-convention (face &optional frame) "29.1"))
(interactive (list (read-face-name "Make which face bold-italic"
(face-at-point t))))
(set-face-attribute face frame :weight 'bold :slant 'italic))
@@ -1100,7 +1100,7 @@ returned. Otherwise, DEFAULT is returned verbatim."
;; prompt. If so, remove it.
(setq prompt (replace-regexp-in-string ": ?\\'" "" prompt))
(let ((prompt (if default
- (format-message "%s (default `%s'): " prompt default)
+ (format-prompt prompt default)
(format "%s: " prompt)))
aliasfaces nonaliasfaces faces)
;; Build up the completion tables.
diff --git a/lisp/files.el b/lisp/files.el
index 64c69e685c8..feec62799fa 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -2883,6 +2883,7 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|CBR\\|7Z\\|SQUASHFS\\)\\'" .
("\\.[ds]?va?h?\\'" . verilog-mode)
("\\.by\\'" . bovine-grammar-mode)
("\\.wy\\'" . wisent-grammar-mode)
+ ("\\.erts\\'" . erts-mode)
;; .emacs or .gnus or .viper following a directory delimiter in
;; Unix or MS-DOS syntax.
("[:/\\]\\..*\\(emacs\\|gnus\\|viper\\)\\'" . emacs-lisp-mode)
diff --git a/lisp/format.el b/lisp/format.el
index 6c0ba11641e..8ae51f19ebc 100644
--- a/lisp/format.el
+++ b/lisp/format.el
@@ -320,7 +320,7 @@ If the format is not specified, attempt a regexp-based guess.
Set `buffer-file-format' to the format used, and call any
format-specific mode functions."
(interactive
- (list (format-read "Translate buffer from format (default guess): ")))
+ (list (format-read (format-prompt "Translate buffer from format" "guess"))))
(save-excursion
(goto-char (point-min))
(format-decode format (buffer-size) t)))
@@ -331,7 +331,7 @@ Arg FORMAT is optional; if omitted the format will be determined by looking
for identifying regular expressions at the beginning of the region."
(interactive
(list (region-beginning) (region-end)
- (format-read "Translate region from format (default guess): ")))
+ (format-read (format-prompt "Translate region from format" "guess"))))
(save-excursion
(goto-char from)
(format-decode format (- to from) nil)))
diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el
index 6426d825465..20da295aca9 100644
--- a/lisp/gnus/gnus-agent.el
+++ b/lisp/gnus/gnus-agent.el
@@ -475,17 +475,16 @@ manipulated as follows:
(gnus-run-hooks 'gnus-agent-mode-hook
(intern (format "gnus-agent-%s-mode-hook" buffer)))))
-(defvar gnus-agent-group-mode-map (make-sparse-keymap))
-(gnus-define-keys gnus-agent-group-mode-map
- "Ju" gnus-agent-fetch-groups
- "Jc" gnus-enter-category-buffer
- "Jj" gnus-agent-toggle-plugged
- "Js" gnus-agent-fetch-session
- "JY" gnus-agent-synchronize-flags
- "JS" gnus-group-send-queue
- "Ja" gnus-agent-add-group
- "Jr" gnus-agent-remove-group
- "Jo" gnus-agent-toggle-group-plugged)
+(defvar-keymap gnus-agent-group-mode-map
+ "Ju" #'gnus-agent-fetch-groups
+ "Jc" #'gnus-enter-category-buffer
+ "Jj" #'gnus-agent-toggle-plugged
+ "Js" #'gnus-agent-fetch-session
+ "JY" #'gnus-agent-synchronize-flags
+ "JS" #'gnus-group-send-queue
+ "Ja" #'gnus-agent-add-group
+ "Jr" #'gnus-agent-remove-group
+ "Jo" #'gnus-agent-toggle-group-plugged)
(defun gnus-agent-group-make-menu-bar ()
(unless (boundp 'gnus-agent-group-menu)
@@ -504,16 +503,15 @@ manipulated as follows:
["Synchronize flags" gnus-agent-synchronize-flags t]
))))
-(defvar gnus-agent-summary-mode-map (make-sparse-keymap))
-(gnus-define-keys gnus-agent-summary-mode-map
- "Jj" gnus-agent-toggle-plugged
- "Ju" gnus-agent-summary-fetch-group
- "JS" gnus-agent-fetch-group
- "Js" gnus-agent-summary-fetch-series
- "J#" gnus-agent-mark-article
- "J\M-#" gnus-agent-unmark-article
- "@" gnus-agent-toggle-mark
- "Jc" gnus-agent-catchup)
+(defvar-keymap gnus-agent-summary-mode-map
+ "Jj" #'gnus-agent-toggle-plugged
+ "Ju" #'gnus-agent-summary-fetch-group
+ "JS" #'gnus-agent-fetch-group
+ "Js" #'gnus-agent-summary-fetch-series
+ "J#" #'gnus-agent-mark-article
+ "J\M-#" #'gnus-agent-unmark-article
+ "@" #'gnus-agent-toggle-mark
+ "Jc" #'gnus-agent-catchup)
(defun gnus-agent-summary-make-menu-bar ()
(unless (boundp 'gnus-agent-summary-menu)
@@ -527,11 +525,10 @@ manipulated as follows:
["Fetch downloadable" gnus-agent-summary-fetch-group t]
["Catchup undownloaded" gnus-agent-catchup t]))))
-(defvar gnus-agent-server-mode-map (make-sparse-keymap))
-(gnus-define-keys gnus-agent-server-mode-map
- "Jj" gnus-agent-toggle-plugged
- "Ja" gnus-agent-add-server
- "Jr" gnus-agent-remove-server)
+(defvar-keymap gnus-agent-server-mode-map
+ "Jj" #'gnus-agent-toggle-plugged
+ "Ja" #'gnus-agent-add-server
+ "Jr" #'gnus-agent-remove-server)
(defun gnus-agent-server-make-menu-bar ()
(unless (boundp 'gnus-agent-server-menu)
@@ -2597,25 +2594,20 @@ General format specifiers can also be used. See Info node
(defvar gnus-category-line-format-spec nil)
(defvar gnus-category-mode-line-format-spec nil)
-(defvar gnus-category-mode-map nil)
-
-(unless gnus-category-mode-map
- (setq gnus-category-mode-map (make-sparse-keymap))
- (suppress-keymap gnus-category-mode-map)
-
- (gnus-define-keys gnus-category-mode-map
- "q" gnus-category-exit
- "k" gnus-category-kill
- "c" gnus-category-copy
- "a" gnus-category-add
- "e" gnus-agent-customize-category
- "p" gnus-category-edit-predicate
- "g" gnus-category-edit-groups
- "s" gnus-category-edit-score
- "l" gnus-category-list
-
- "\C-c\C-i" gnus-info-find-node
- "\C-c\C-b" gnus-bug))
+(defvar-keymap gnus-category-mode-map
+ :suppress t
+ "q" #'gnus-category-exit
+ "k" #'gnus-category-kill
+ "c" #'gnus-category-copy
+ "a" #'gnus-category-add
+ "e" #'gnus-agent-customize-category
+ "p" #'gnus-category-edit-predicate
+ "g" #'gnus-category-edit-groups
+ "s" #'gnus-category-edit-score
+ "l" #'gnus-category-list
+
+ "\C-c\C-i" #'gnus-info-find-node
+ "\C-c\C-b" #'gnus-bug)
(defcustom gnus-category-menu-hook nil
"Hook run after the creation of the menu."
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el
index 7b6e15d6f87..bb466b9400a 100644
--- a/lisp/gnus/gnus-art.el
+++ b/lisp/gnus/gnus-art.el
@@ -3933,8 +3933,8 @@ This format is defined by the `gnus-article-time-format' variable."
;; No split name was found.
((null split-name)
(read-file-name
- (concat prompt " (default "
- (file-name-nondirectory default-name) "): ")
+ (format-prompt prompt
+ (file-name-nondirectory default-name))
(file-name-directory default-name)
default-name))
;; A single group name is returned.
@@ -3943,8 +3943,8 @@ This format is defined by the `gnus-article-time-format' variable."
(funcall function split-name headers
(symbol-value variable)))
(read-file-name
- (concat prompt " (default "
- (file-name-nondirectory default-name) "): ")
+ (format-prompt prompt
+ (file-name-nondirectory default-name))
(file-name-directory default-name)
default-name))
;; A single split name was found
@@ -3956,9 +3956,8 @@ This format is defined by the `gnus-article-time-format' variable."
(file-name-as-directory name))
((file-exists-p name) name)
(t gnus-article-save-directory))))
- (read-file-name
- (concat prompt " (default " name "): ")
- dir name)))
+ (read-file-name (format-prompt prompt name)
+ dir name)))
;; A list of splits was found.
(t
(setq split-name (nreverse split-name))
@@ -4387,44 +4386,44 @@ If variable `gnus-use-long-file-name' is non-nil, it is
;;; Gnus article mode
;;;
-(set-keymap-parent gnus-article-mode-map button-buffer-map)
-
-(gnus-define-keys gnus-article-mode-map
- " " gnus-article-goto-next-page
- [?\S-\ ] gnus-article-goto-prev-page
- "\177" gnus-article-goto-prev-page
- [delete] gnus-article-goto-prev-page
- "\C-c^" gnus-article-refer-article
- "h" gnus-article-show-summary
- "s" gnus-article-show-summary
- "\C-c\C-m" gnus-article-mail
- "?" gnus-article-describe-briefly
- "<" beginning-of-buffer
- ">" end-of-buffer
- "\C-c\C-i" gnus-info-find-node
- "\C-c\C-b" gnus-bug
- "R" gnus-article-reply-with-original
- "F" gnus-article-followup-with-original
- "\C-hk" gnus-article-describe-key
- "\C-hc" gnus-article-describe-key-briefly
- "\C-hb" gnus-article-describe-bindings
-
- "e" gnus-article-read-summary-keys
- "\C-d" gnus-article-read-summary-keys
- "\C-c\C-f" gnus-summary-mail-forward
- "\M-*" gnus-article-read-summary-keys
- "\M-#" gnus-article-read-summary-keys
- "\M-^" gnus-article-read-summary-keys
- "\M-g" gnus-article-read-summary-keys)
+(defvar gnus-article-send-map nil)
+
+(define-keymap :keymap gnus-article-mode-map :suppress t
+ :parent button-buffer-map
+ " " #'gnus-article-goto-next-page
+ [?\S-\ ] #'gnus-article-goto-prev-page
+ "\177" #'gnus-article-goto-prev-page
+ [delete] #'gnus-article-goto-prev-page
+ "\C-c^" #'gnus-article-refer-article
+ "h" #'gnus-article-show-summary
+ "s" #'gnus-article-show-summary
+ "\C-c\C-m" #'gnus-article-mail
+ "?" #'gnus-article-describe-briefly
+ "<" #'beginning-of-buffer
+ ">" #'end-of-buffer
+ "\C-c\C-i" #'gnus-info-find-node
+ "\C-c\C-b" #'gnus-bug
+ "R" #'gnus-article-reply-with-original
+ "F" #'gnus-article-followup-with-original
+ "\C-hk" #'gnus-article-describe-key
+ "\C-hc" #'gnus-article-describe-key-briefly
+ "\C-hb" #'gnus-article-describe-bindings
+
+ "e" #'gnus-article-read-summary-keys
+ "\C-d" #'gnus-article-read-summary-keys
+ "\C-c\C-f" #'gnus-summary-mail-forward
+ "\M-*" #'gnus-article-read-summary-keys
+ "\M-#" #'gnus-article-read-summary-keys
+ "\M-^" #'gnus-article-read-summary-keys
+ "\M-g" #'gnus-article-read-summary-keys
+
+ "S" (define-keymap :prefix 'gnus-article-send-map
+ "W" #'gnus-article-wide-reply-with-original
+ [t] #'gnus-article-read-summary-send-keys))
(substitute-key-definition
#'undefined #'gnus-article-read-summary-keys gnus-article-mode-map)
-(defvar gnus-article-send-map)
-(gnus-define-keys (gnus-article-send-map "S" gnus-article-mode-map)
- "W" gnus-article-wide-reply-with-original
- [t] gnus-article-read-summary-send-keys)
-
(defun gnus-article-make-menu-bar ()
(unless (boundp 'gnus-article-commands-menu)
(gnus-summary-make-menu-bar))
@@ -7217,50 +7216,43 @@ other groups."
(defvar gnus-article-edit-done-function nil)
-(defvar gnus-article-edit-mode-map nil)
-
-;; Should we be using derived.el for this?
-(unless gnus-article-edit-mode-map
- (setq gnus-article-edit-mode-map (make-keymap))
- (set-keymap-parent gnus-article-edit-mode-map text-mode-map)
-
- (gnus-define-keys gnus-article-edit-mode-map
- "\C-c?" describe-mode
- "\C-c\C-c" gnus-article-edit-done
- "\C-c\C-k" gnus-article-edit-exit
- "\C-c\C-f\C-t" message-goto-to
- "\C-c\C-f\C-o" message-goto-from
- "\C-c\C-f\C-b" message-goto-bcc
- ;;"\C-c\C-f\C-w" message-goto-fcc
- "\C-c\C-f\C-c" message-goto-cc
- "\C-c\C-f\C-s" message-goto-subject
- "\C-c\C-f\C-r" message-goto-reply-to
- "\C-c\C-f\C-n" message-goto-newsgroups
- "\C-c\C-f\C-d" message-goto-distribution
- "\C-c\C-f\C-f" message-goto-followup-to
- "\C-c\C-f\C-m" message-goto-mail-followup-to
- "\C-c\C-f\C-k" message-goto-keywords
- "\C-c\C-f\C-u" message-goto-summary
- "\C-c\C-f\C-i" message-insert-or-toggle-importance
- "\C-c\C-f\C-a" message-generate-unsubscribed-mail-followup-to
- "\C-c\C-b" message-goto-body
- "\C-c\C-i" message-goto-signature
-
- "\C-c\C-t" message-insert-to
- "\C-c\C-n" message-insert-newsgroups
- "\C-c\C-o" message-sort-headers
- "\C-c\C-e" message-elide-region
- "\C-c\C-v" message-delete-not-region
- "\C-c\C-z" message-kill-to-signature
- "\M-\r" message-newline-and-reformat
- "\C-c\C-a" mml-attach-file
- "\C-a" message-beginning-of-line
- "\t" message-tab
- "\M-;" comment-region)
-
- (gnus-define-keys (gnus-article-edit-wash-map
- "\C-c\C-w" gnus-article-edit-mode-map)
- "f" gnus-article-edit-full-stops))
+(defvar-keymap gnus-article-edit-mode-map
+ :full t :parent text-mode-map
+ "\C-c?" #'describe-mode
+ "\C-c\C-c" #'gnus-article-edit-done
+ "\C-c\C-k" #'gnus-article-edit-exit
+ "\C-c\C-f\C-t" #'message-goto-to
+ "\C-c\C-f\C-o" #'message-goto-from
+ "\C-c\C-f\C-b" #'message-goto-bcc
+ ;;"\C-c\C-f\C-w" message-goto-fcc
+ "\C-c\C-f\C-c" #'message-goto-cc
+ "\C-c\C-f\C-s" #'message-goto-subject
+ "\C-c\C-f\C-r" #'message-goto-reply-to
+ "\C-c\C-f\C-n" #'message-goto-newsgroups
+ "\C-c\C-f\C-d" #'message-goto-distribution
+ "\C-c\C-f\C-f" #'message-goto-followup-to
+ "\C-c\C-f\C-m" #'message-goto-mail-followup-to
+ "\C-c\C-f\C-k" #'message-goto-keywords
+ "\C-c\C-f\C-u" #'message-goto-summary
+ "\C-c\C-f\C-i" #'message-insert-or-toggle-importance
+ "\C-c\C-f\C-a" #'message-generate-unsubscribed-mail-followup-to
+ "\C-c\C-b" #'message-goto-body
+ "\C-c\C-i" #'message-goto-signature
+
+ "\C-c\C-t" #'message-insert-to
+ "\C-c\C-n" #'message-insert-newsgroups
+ "\C-c\C-o" #'message-sort-headers
+ "\C-c\C-e" #'message-elide-region
+ "\C-c\C-v" #'message-delete-not-region
+ "\C-c\C-z" #'message-kill-to-signature
+ "\M-\r" #'message-newline-and-reformat
+ "\C-c\C-a" #'mml-attach-file
+ "\C-a" #'message-beginning-of-line
+ "\t" #'message-tab
+ "\M-;" #'comment-region
+
+ "\C-c\C-w" (define-keymap :prefix 'gnus-article-edit-wash-map
+ "f" #'gnus-article-edit-full-stops))
(easy-menu-define
gnus-article-edit-mode-field-menu gnus-article-edit-mode-map ""
diff --git a/lisp/gnus/gnus-bookmark.el b/lisp/gnus/gnus-bookmark.el
index 83e482f14c1..171da9d17a0 100644
--- a/lisp/gnus/gnus-bookmark.el
+++ b/lisp/gnus/gnus-bookmark.el
@@ -418,32 +418,29 @@ That is, all information but the name."
(defvar gnus-bookmark-bmenu-bookmark-column nil)
(defvar gnus-bookmark-bmenu-hidden-bookmarks ())
-(defvar gnus-bookmark-bmenu-mode-map nil)
-
-(if gnus-bookmark-bmenu-mode-map
- nil
- (setq gnus-bookmark-bmenu-mode-map (make-keymap))
- (suppress-keymap gnus-bookmark-bmenu-mode-map t)
- (define-key gnus-bookmark-bmenu-mode-map "q" 'quit-window)
- (define-key gnus-bookmark-bmenu-mode-map "\C-m" 'gnus-bookmark-bmenu-select)
- (define-key gnus-bookmark-bmenu-mode-map "v" 'gnus-bookmark-bmenu-select)
- (define-key gnus-bookmark-bmenu-mode-map "d" 'gnus-bookmark-bmenu-delete)
- (define-key gnus-bookmark-bmenu-mode-map "k" 'gnus-bookmark-bmenu-delete)
- (define-key gnus-bookmark-bmenu-mode-map "\C-d" 'gnus-bookmark-bmenu-delete-backwards)
- (define-key gnus-bookmark-bmenu-mode-map "x" 'gnus-bookmark-bmenu-execute-deletions)
- (define-key gnus-bookmark-bmenu-mode-map " " 'next-line)
- (define-key gnus-bookmark-bmenu-mode-map "n" 'next-line)
- (define-key gnus-bookmark-bmenu-mode-map "p" 'previous-line)
- (define-key gnus-bookmark-bmenu-mode-map "\177" 'gnus-bookmark-bmenu-backup-unmark)
- (define-key gnus-bookmark-bmenu-mode-map "?" 'describe-mode)
- (define-key gnus-bookmark-bmenu-mode-map "u" 'gnus-bookmark-bmenu-unmark)
- (define-key gnus-bookmark-bmenu-mode-map "m" 'gnus-bookmark-bmenu-mark)
- (define-key gnus-bookmark-bmenu-mode-map "l" 'gnus-bookmark-bmenu-load)
- (define-key gnus-bookmark-bmenu-mode-map "s" 'gnus-bookmark-bmenu-save)
- (define-key gnus-bookmark-bmenu-mode-map "t" 'gnus-bookmark-bmenu-toggle-infos)
- (define-key gnus-bookmark-bmenu-mode-map "a" 'gnus-bookmark-bmenu-show-details)
- (define-key gnus-bookmark-bmenu-mode-map [mouse-2]
- 'gnus-bookmark-bmenu-select-by-mouse))
+
+(defvar-keymap gnus-bookmark-bmenu-mode-map
+ :full t
+ :suppress 'nodigits
+ "q" #'quit-window
+ "\C-m" #'gnus-bookmark-bmenu-select
+ "v" #'gnus-bookmark-bmenu-select
+ "d" #'gnus-bookmark-bmenu-delete
+ "k" #'gnus-bookmark-bmenu-delete
+ "\C-d" #'gnus-bookmark-bmenu-delete-backwards
+ "x" #'gnus-bookmark-bmenu-execute-deletions
+ " " #'next-line
+ "n" #'next-line
+ "p" #'previous-line
+ "\177" #'gnus-bookmark-bmenu-backup-unmark
+ "?" #'describe-mode
+ "u" #'gnus-bookmark-bmenu-unmark
+ "m" #'gnus-bookmark-bmenu-mark
+ "l" #'gnus-bookmark-bmenu-load
+ "s" #'gnus-bookmark-bmenu-save
+ "t" #'gnus-bookmark-bmenu-toggle-infos
+ "a" #'gnus-bookmark-bmenu-show-details
+ [mouse-2] #'gnus-bookmark-bmenu-select-by-mouse)
;; Bookmark Buffer Menu mode is suitable only for specially formatted
;; data.
diff --git a/lisp/gnus/gnus-dired.el b/lisp/gnus/gnus-dired.el
index e9eddae942f..be46d3a341d 100644
--- a/lisp/gnus/gnus-dired.el
+++ b/lisp/gnus/gnus-dired.el
@@ -53,12 +53,10 @@
(autoload 'message-buffers "message")
(autoload 'gnus-print-buffer "gnus-sum")
-(defvar gnus-dired-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-c\C-m\C-a" 'gnus-dired-attach)
- (define-key map "\C-c\C-m\C-l" 'gnus-dired-find-file-mailcap)
- (define-key map "\C-c\C-m\C-p" 'gnus-dired-print)
- map))
+(defvar-keymap gnus-dired-mode-map
+ "\C-c\C-m\C-a" #'gnus-dired-attach
+ "\C-c\C-m\C-l" #'gnus-dired-find-file-mailcap
+ "\C-c\C-m\C-p" #'gnus-dired-print)
;; FIXME: Make it customizable, change the default to `mail-user-agent' when
;; this file is renamed (e.g. to `dired-mime.el').
diff --git a/lisp/gnus/gnus-draft.el b/lisp/gnus/gnus-draft.el
index 9a0f21359f8..756e6d2d362 100644
--- a/lisp/gnus/gnus-draft.el
+++ b/lisp/gnus/gnus-draft.el
@@ -33,15 +33,12 @@
;;; Draft minor mode
-(defvar gnus-draft-mode-map
- (let ((map (make-sparse-keymap)))
- (gnus-define-keys map
- "Dt" gnus-draft-toggle-sending
- "e" gnus-draft-edit-message ;; Use `B w' for `gnus-summary-edit-article'
- "De" gnus-draft-edit-message
- "Ds" gnus-draft-send-message
- "DS" gnus-draft-send-all-messages)
- map))
+(defvar-keymap gnus-draft-mode-map
+ "Dt" #'gnus-draft-toggle-sending
+ "e" #' gnus-draft-edit-message ;; Use `B w' for `gnus-summary-edit-article'
+ "De" #'gnus-draft-edit-message
+ "Ds" #'gnus-draft-send-message
+ "DS" #'gnus-draft-send-all-messages)
(defun gnus-draft-make-menu-bar ()
(unless (boundp 'gnus-draft-menu)
diff --git a/lisp/gnus/gnus-eform.el b/lisp/gnus/gnus-eform.el
index 3fd8bf51de4..b0aa58f0f28 100644
--- a/lisp/gnus/gnus-eform.el
+++ b/lisp/gnus/gnus-eform.el
@@ -48,13 +48,10 @@
(defvar gnus-edit-form-buffer "*Gnus edit form*")
(defvar gnus-edit-form-done-function nil)
-(defvar gnus-edit-form-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map emacs-lisp-mode-map)
- (gnus-define-keys map
- "\C-c\C-c" gnus-edit-form-done
- "\C-c\C-k" gnus-edit-form-exit)
- map))
+(defvar-keymap gnus-edit-form-mode-map
+ :parent emacs-lisp-mode-map
+ "\C-c\C-c" #'gnus-edit-form-done
+ "\C-c\C-k" #'gnus-edit-form-exit)
(defun gnus-edit-form-make-menu-bar ()
(unless (boundp 'gnus-edit-form-menu)
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index b1e486b0627..2a4c84c94b0 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -573,209 +573,209 @@ simple manner."
;;; Gnus group mode
;;;
-(gnus-define-keys gnus-group-mode-map
- " " gnus-group-read-group
- "=" gnus-group-select-group
- "\r" gnus-group-select-group
- "\M-\r" gnus-group-quick-select-group
- "\M- " gnus-group-visible-select-group
- [(meta control return)] gnus-group-select-group-ephemerally
- "j" gnus-group-jump-to-group
- "n" gnus-group-next-unread-group
- "p" gnus-group-prev-unread-group
- "\177" gnus-group-prev-unread-group
- [delete] gnus-group-prev-unread-group
- "N" gnus-group-next-group
- "P" gnus-group-prev-group
- "\M-n" gnus-group-next-unread-group-same-level
- "\M-p" gnus-group-prev-unread-group-same-level
- "," gnus-group-best-unread-group
- "." gnus-group-first-unread-group
- "u" gnus-group-toggle-subscription-at-point
- "U" gnus-group-toggle-subscription
- "c" gnus-group-catchup-current
- "C" gnus-group-catchup-current-all
- "\M-c" gnus-group-clear-data
- "l" gnus-group-list-groups
- "L" gnus-group-list-all-groups
- "m" gnus-group-mail
- "i" gnus-group-news
- "g" gnus-group-get-new-news
- "\M-g" gnus-group-get-new-news-this-group
- "R" gnus-group-restart
- "r" gnus-group-read-init-file
- "B" gnus-group-browse-foreign-server
- "b" gnus-group-check-bogus-groups
- "F" gnus-group-find-new-groups
- "\C-c\C-d" gnus-group-describe-group
- "\M-d" gnus-group-describe-all-groups
- "\C-c\C-a" gnus-group-apropos
- "\C-c\M-\C-a" gnus-group-description-apropos
- "a" gnus-group-post-news
- "\ek" gnus-group-edit-local-kill
- "\eK" gnus-group-edit-global-kill
- "\C-k" gnus-group-kill-group
- "\C-y" gnus-group-yank-group
- "\C-w" gnus-group-kill-region
- "\C-x\C-t" gnus-group-transpose-groups
- "\C-c\C-l" gnus-group-list-killed
- "\C-c\C-x" gnus-group-expire-articles
- "\C-c\M-\C-x" gnus-group-expire-all-groups
- "V" gnus-version
- "s" gnus-group-save-newsrc
- "z" gnus-group-suspend
- "q" gnus-group-exit
- "Q" gnus-group-quit
- "?" gnus-group-describe-briefly
- "\C-c\C-i" gnus-info-find-node
- "\M-e" gnus-group-edit-group-method
- "^" gnus-group-enter-server-mode
- [mouse-2] gnus-mouse-pick-group
- [follow-link] mouse-face
- "<" beginning-of-buffer
- ">" end-of-buffer
- "\C-c\C-b" gnus-bug
- "\C-c\C-s" gnus-group-sort-groups
- "t" gnus-topic-mode
- "\C-c\M-g" gnus-activate-all-groups
- "\M-&" gnus-group-universal-argument
- "#" gnus-group-mark-group
- "\M-#" gnus-group-unmark-group)
-
-(gnus-define-keys (gnus-group-cloud-map "~" gnus-group-mode-map)
- "u" gnus-cloud-upload-all-data
- "~" gnus-cloud-upload-all-data
- "d" gnus-cloud-download-all-data
- "\r" gnus-cloud-download-all-data)
-
-(gnus-define-keys (gnus-group-mark-map "M" gnus-group-mode-map)
- "m" gnus-group-mark-group
- "u" gnus-group-unmark-group
- "w" gnus-group-mark-region
- "b" gnus-group-mark-buffer
- "r" gnus-group-mark-regexp
- "U" gnus-group-unmark-all-groups)
-
-(gnus-define-keys (gnus-group-sieve-map "D" gnus-group-mode-map)
- "u" gnus-sieve-update
- "g" gnus-sieve-generate)
-
-(gnus-define-keys (gnus-group-group-map "G" gnus-group-mode-map)
- "d" gnus-group-make-directory-group
- "h" gnus-group-make-help-group
- "u" gnus-group-make-useful-group
- "l" gnus-group-nnimap-edit-acl
- "m" gnus-group-make-group
- "E" gnus-group-edit-group
- "e" gnus-group-edit-group-method
- "p" gnus-group-edit-group-parameters
- "v" gnus-group-add-to-virtual
- "V" gnus-group-make-empty-virtual
- "D" gnus-group-enter-directory
- "f" gnus-group-make-doc-group
- "w" gnus-group-make-web-group
- "G" gnus-group-read-ephemeral-search-group
- "g" gnus-group-make-search-group
- "M" gnus-group-read-ephemeral-group
- "r" gnus-group-rename-group
- "R" gnus-group-make-rss-group
- "c" gnus-group-customize
- "z" gnus-group-compact-group
- "x" gnus-group-expunge-group
- "\177" gnus-group-delete-group
- [delete] gnus-group-delete-group)
-
-(gnus-define-keys (gnus-group-sort-map "S" gnus-group-group-map)
- "s" gnus-group-sort-groups
- "a" gnus-group-sort-groups-by-alphabet
- "u" gnus-group-sort-groups-by-unread
- "l" gnus-group-sort-groups-by-level
- "v" gnus-group-sort-groups-by-score
- "r" gnus-group-sort-groups-by-rank
- "m" gnus-group-sort-groups-by-method
- "n" gnus-group-sort-groups-by-real-name)
-
-(gnus-define-keys (gnus-group-sort-selected-map "P" gnus-group-group-map)
- "s" gnus-group-sort-selected-groups
- "a" gnus-group-sort-selected-groups-by-alphabet
- "u" gnus-group-sort-selected-groups-by-unread
- "l" gnus-group-sort-selected-groups-by-level
- "v" gnus-group-sort-selected-groups-by-score
- "r" gnus-group-sort-selected-groups-by-rank
- "m" gnus-group-sort-selected-groups-by-method
- "n" gnus-group-sort-selected-groups-by-real-name)
-
-(gnus-define-keys (gnus-group-list-map "A" gnus-group-mode-map)
- "k" gnus-group-list-killed
- "z" gnus-group-list-zombies
- "s" gnus-group-list-groups
- "u" gnus-group-list-all-groups
- "A" gnus-group-list-active
- "a" gnus-group-apropos
- "d" gnus-group-description-apropos
- "m" gnus-group-list-matching
- "M" gnus-group-list-all-matching
- "l" gnus-group-list-level
- "c" gnus-group-list-cached
- "?" gnus-group-list-dormant
- "!" gnus-group-list-ticked)
-
-(gnus-define-keys (gnus-group-list-limit-map "/" gnus-group-list-map)
- "k" gnus-group-list-limit
- "z" gnus-group-list-limit
- "s" gnus-group-list-limit
- "u" gnus-group-list-limit
- "A" gnus-group-list-limit
- "m" gnus-group-list-limit
- "M" gnus-group-list-limit
- "l" gnus-group-list-limit
- "c" gnus-group-list-limit
- "?" gnus-group-list-limit
- "!" gnus-group-list-limit)
-
-(gnus-define-keys (gnus-group-list-flush-map "f" gnus-group-list-map)
- "k" gnus-group-list-flush
- "z" gnus-group-list-flush
- "s" gnus-group-list-flush
- "u" gnus-group-list-flush
- "A" gnus-group-list-flush
- "m" gnus-group-list-flush
- "M" gnus-group-list-flush
- "l" gnus-group-list-flush
- "c" gnus-group-list-flush
- "?" gnus-group-list-flush
- "!" gnus-group-list-flush)
-
-(gnus-define-keys (gnus-group-list-plus-map "p" gnus-group-list-map)
- "k" gnus-group-list-plus
- "z" gnus-group-list-plus
- "s" gnus-group-list-plus
- "u" gnus-group-list-plus
- "A" gnus-group-list-plus
- "m" gnus-group-list-plus
- "M" gnus-group-list-plus
- "l" gnus-group-list-plus
- "c" gnus-group-list-plus
- "?" gnus-group-list-plus
- "!" gnus-group-list-plus)
-
-(gnus-define-keys (gnus-group-score-map "W" gnus-group-mode-map)
- "f" gnus-score-flush-cache
- "e" gnus-score-edit-all-score)
-
-(gnus-define-keys (gnus-group-help-map "H" gnus-group-mode-map)
- "d" gnus-group-describe-group
- "v" gnus-version)
-
-(gnus-define-keys (gnus-group-sub-map "S" gnus-group-mode-map)
- "l" gnus-group-set-current-level
- "t" gnus-group-toggle-subscription-at-point
- "s" gnus-group-toggle-subscription
- "k" gnus-group-kill-group
- "y" gnus-group-yank-group
- "w" gnus-group-kill-region
- "\C-k" gnus-group-kill-level
- "z" gnus-group-kill-all-zombies)
+(define-keymap :keymap gnus-group-mode-map
+ " " #'gnus-group-read-group
+ "=" #'gnus-group-select-group
+ "\r" #'gnus-group-select-group
+ "\M-\r" #'gnus-group-quick-select-group
+ "\M- " #'gnus-group-visible-select-group
+ [(meta control return)] #'gnus-group-select-group-ephemerally
+ "j" #'gnus-group-jump-to-group
+ "n" #'gnus-group-next-unread-group
+ "p" #'gnus-group-prev-unread-group
+ "\177" #'gnus-group-prev-unread-group
+ [delete] #'gnus-group-prev-unread-group
+ "N" #'gnus-group-next-group
+ "P" #'gnus-group-prev-group
+ "\M-n" #'gnus-group-next-unread-group-same-level
+ "\M-p" #'gnus-group-prev-unread-group-same-level
+ "," #'gnus-group-best-unread-group
+ "." #'gnus-group-first-unread-group
+ "u" #'gnus-group-toggle-subscription-at-point
+ "U" #'gnus-group-toggle-subscription
+ "c" #'gnus-group-catchup-current
+ "C" #'gnus-group-catchup-current-all
+ "\M-c" #'gnus-group-clear-data
+ "l" #'gnus-group-list-groups
+ "L" #'gnus-group-list-all-groups
+ "m" #'gnus-group-mail
+ "i" #'gnus-group-news
+ "g" #'gnus-group-get-new-news
+ "\M-g" #'gnus-group-get-new-news-this-group
+ "R" #'gnus-group-restart
+ "r" #'gnus-group-read-init-file
+ "B" #'gnus-group-browse-foreign-server
+ "b" #'gnus-group-check-bogus-groups
+ "F" #'gnus-group-find-new-groups
+ "\C-c\C-d" #'gnus-group-describe-group
+ "\M-d" #'gnus-group-describe-all-groups
+ "\C-c\C-a" #'gnus-group-apropos
+ "\C-c\M-\C-a" #'gnus-group-description-apropos
+ "a" #'gnus-group-post-news
+ "\ek" #'gnus-group-edit-local-kill
+ "\eK" #'gnus-group-edit-global-kill
+ "\C-k" #'gnus-group-kill-group
+ "\C-y" #'gnus-group-yank-group
+ "\C-w" #'gnus-group-kill-region
+ "\C-x\C-t" #'gnus-group-transpose-groups
+ "\C-c\C-l" #'gnus-group-list-killed
+ "\C-c\C-x" #'gnus-group-expire-articles
+ "\C-c\M-\C-x" #'gnus-group-expire-all-groups
+ "V" #'gnus-version
+ "s" #'gnus-group-save-newsrc
+ "z" #'gnus-group-suspend
+ "q" #'gnus-group-exit
+ "Q" #'gnus-group-quit
+ "?" #'gnus-group-describe-briefly
+ "\C-c\C-i" #'gnus-info-find-node
+ "\M-e" #'gnus-group-edit-group-method
+ "^" #'gnus-group-enter-server-mode
+ [mouse-2] #'gnus-mouse-pick-group
+ [follow-link] 'mouse-face
+ "<" #'beginning-of-buffer
+ ">" #'end-of-buffer
+ "\C-c\C-b" #'gnus-bug
+ "\C-c\C-s" #'gnus-group-sort-groups
+ "t" #'gnus-topic-mode
+ "\C-c\M-g" #'gnus-activate-all-groups
+ "\M-&" #'gnus-group-universal-argument
+ "#" #'gnus-group-mark-group
+ "\M-#" #'gnus-group-unmark-group
+
+ "~" (define-keymap :prefix 'gnus-group-cloud-map
+ "u" #'gnus-cloud-upload-all-data
+ "~" #'gnus-cloud-upload-all-data
+ "d" #'gnus-cloud-download-all-data
+ "\r" #'gnus-cloud-download-all-data)
+
+ "M" (define-keymap :prefix 'gnus-group-mark-map
+ "m" #'gnus-group-mark-group
+ "u" #'gnus-group-unmark-group
+ "w" #'gnus-group-mark-region
+ "b" #'gnus-group-mark-buffer
+ "r" #'gnus-group-mark-regexp
+ "U" #'gnus-group-unmark-all-groups)
+
+ "D" (define-keymap :prefix 'gnus-group-sieve-map
+ "u" #'gnus-sieve-update
+ "g" #'gnus-sieve-generate)
+
+ "G" (define-keymap :prefix 'gnus-group-group-map
+ "d" #'gnus-group-make-directory-group
+ "h" #'gnus-group-make-help-group
+ "u" #'gnus-group-make-useful-group
+ "l" #'gnus-group-nnimap-edit-acl
+ "m" #'gnus-group-make-group
+ "E" #'gnus-group-edit-group
+ "e" #'gnus-group-edit-group-method
+ "p" #'gnus-group-edit-group-parameters
+ "v" #'gnus-group-add-to-virtual
+ "V" #'gnus-group-make-empty-virtual
+ "D" #'gnus-group-enter-directory
+ "f" #'gnus-group-make-doc-group
+ "w" #'gnus-group-make-web-group
+ "G" #'gnus-group-read-ephemeral-search-group
+ "g" #'gnus-group-make-search-group
+ "M" #'gnus-group-read-ephemeral-group
+ "r" #'gnus-group-rename-group
+ "R" #'gnus-group-make-rss-group
+ "c" #'gnus-group-customize
+ "z" #'gnus-group-compact-group
+ "x" #'gnus-group-expunge-group
+ "\177" #'gnus-group-delete-group
+ [delete] #'gnus-group-delete-group)
+
+ "S" (define-keymap :prefix 'gnus-group-sort-map
+ "s" #'gnus-group-sort-groups
+ "a" #'gnus-group-sort-groups-by-alphabet
+ "u" #'gnus-group-sort-groups-by-unread
+ "l" #'gnus-group-sort-groups-by-level
+ "v" #'gnus-group-sort-groups-by-score
+ "r" #'gnus-group-sort-groups-by-rank
+ "m" #'gnus-group-sort-groups-by-method
+ "n" #'gnus-group-sort-groups-by-real-name)
+
+ "P" (define-keymap :prefix 'gnus-group-sort-selected-map
+ "s" #'gnus-group-sort-selected-groups
+ "a" #'gnus-group-sort-selected-groups-by-alphabet
+ "u" #'gnus-group-sort-selected-groups-by-unread
+ "l" #'gnus-group-sort-selected-groups-by-level
+ "v" #'gnus-group-sort-selected-groups-by-score
+ "r" #'gnus-group-sort-selected-groups-by-rank
+ "m" #'gnus-group-sort-selected-groups-by-method
+ "n" #'gnus-group-sort-selected-groups-by-real-name)
+
+ "A" (define-keymap :prefix 'gnus-group-list-map
+ "k" #'gnus-group-list-killed
+ "z" #'gnus-group-list-zombies
+ "s" #'gnus-group-list-groups
+ "u" #'gnus-group-list-all-groups
+ "A" #'gnus-group-list-active
+ "a" #'gnus-group-apropos
+ "d" #'gnus-group-description-apropos
+ "m" #'gnus-group-list-matching
+ "M" #'gnus-group-list-all-matching
+ "l" #'gnus-group-list-level
+ "c" #'gnus-group-list-cached
+ "?" #'gnus-group-list-dormant
+ "!" #'gnus-group-list-ticked
+
+ "/" (define-keymap :prefix 'gnus-group-list-limit-map
+ "k" #'gnus-group-list-limit
+ "z" #'gnus-group-list-limit
+ "s" #'gnus-group-list-limit
+ "u" #'gnus-group-list-limit
+ "A" #'gnus-group-list-limit
+ "m" #'gnus-group-list-limit
+ "M" #'gnus-group-list-limit
+ "l" #'gnus-group-list-limit
+ "c" #'gnus-group-list-limit
+ "?" #'gnus-group-list-limit
+ "!" #'gnus-group-list-limit)
+
+ "f" (define-keymap :prefix 'gnus-group-list-flush-map
+ "k" #'gnus-group-list-flush
+ "z" #'gnus-group-list-flush
+ "s" #'gnus-group-list-flush
+ "u" #'gnus-group-list-flush
+ "A" #'gnus-group-list-flush
+ "m" #'gnus-group-list-flush
+ "M" #'gnus-group-list-flush
+ "l" #'gnus-group-list-flush
+ "c" #'gnus-group-list-flush
+ "?" #'gnus-group-list-flush
+ "!" #'gnus-group-list-flush)
+
+ "p" (define-keymap :prefix 'gnus-group-list-plus-map
+ "k" #'gnus-group-list-plus
+ "z" #'gnus-group-list-plus
+ "s" #'gnus-group-list-plus
+ "u" #'gnus-group-list-plus
+ "A" #'gnus-group-list-plus
+ "m" #'gnus-group-list-plus
+ "M" #'gnus-group-list-plus
+ "l" #'gnus-group-list-plus
+ "c" #'gnus-group-list-plus
+ "?" #'gnus-group-list-plus
+ "!" #'gnus-group-list-plus))
+
+ "W" (define-keymap :prefix 'gnus-group-score-map
+ "f" #'gnus-score-flush-cache
+ "e" #'gnus-score-edit-all-score)
+
+ "H" (define-keymap :prefix 'gnus-group-help-map
+ "d" #'gnus-group-describe-group
+ "v" #'gnus-version)
+
+ "S" (define-keymap :prefix 'gnus-group-sub-map
+ "l" #'gnus-group-set-current-level
+ "t" #'gnus-group-toggle-subscription-at-point
+ "s" #'gnus-group-toggle-subscription
+ "k" #'gnus-group-kill-group
+ "y" #'gnus-group-yank-group
+ "w" #'gnus-group-kill-region
+ "\C-k" #'gnus-group-kill-level
+ "z" #'gnus-group-kill-all-zombies))
(defun gnus-topic-mode-p ()
"Return non-nil in `gnus-topic-mode'."
diff --git a/lisp/gnus/gnus-html.el b/lisp/gnus/gnus-html.el
index be62bfd81f5..c1815d3486c 100644
--- a/lisp/gnus/gnus-html.el
+++ b/lisp/gnus/gnus-html.el
@@ -71,21 +71,17 @@ fit these criteria."
:group 'gnus-art
:type 'float)
-(defvar gnus-html-image-map
- (let ((map (make-sparse-keymap)))
- (define-key map "u" 'gnus-article-copy-string)
- (define-key map "i" 'gnus-html-insert-image)
- (define-key map "v" 'gnus-html-browse-url)
- map))
-
-(defvar gnus-html-displayed-image-map
- (let ((map (make-sparse-keymap)))
- (define-key map "a" 'gnus-html-show-alt-text)
- (define-key map "i" 'gnus-html-browse-image)
- (define-key map "\r" 'gnus-html-browse-url)
- (define-key map "u" 'gnus-article-copy-string)
- (define-key map [tab] 'button-forward)
- map))
+(defvar-keymap gnus-html-image-map
+ "u" #'gnus-article-copy-string
+ "i" #'gnus-html-insert-image
+ "v" #'gnus-html-browse-url)
+
+(defvar-keymap gnus-html-displayed-image-map
+ "a" #'gnus-html-show-alt-text
+ "i" #'gnus-html-browse-image
+ "\r" #'gnus-html-browse-url
+ "u" #'gnus-article-copy-string
+ [tab] #'forward-button)
(defun gnus-html-encode-url (url)
"Encode URL."
diff --git a/lisp/gnus/gnus-icalendar.el b/lisp/gnus/gnus-icalendar.el
index b6e5e7f786a..81e46d7a51e 100644
--- a/lisp/gnus/gnus-icalendar.el
+++ b/lisp/gnus/gnus-icalendar.el
@@ -194,7 +194,11 @@
(caddr event))))
(cl-labels
- ((attendee-role (prop) (plist-get (cadr prop) 'ROLE))
+ ((attendee-role (prop)
+ ;; RFC5546: default ROLE is REQ-PARTICIPANT
+ (and prop
+ (or (plist-get (cadr prop) 'ROLE)
+ "REQ-PARTICIPANT")))
(attendee-name
(prop)
(or (plist-get (cadr prop) 'CN)
@@ -225,7 +229,10 @@
(gnus-icalendar-event--find-attendee
ical attendee-name-or-email)))
(attendee-names (gnus-icalendar-event--get-attendee-names ical))
- (role (plist-get (cadr attendee) 'ROLE))
+ ;; RFC5546: default ROLE is REQ-PARTICIPANT
+ (role (and attendee
+ (or (plist-get (cadr attendee) 'ROLE)
+ "REQ-PARTICIPANT")))
(participation-type (pcase role
("REQ-PARTICIPANT" 'required)
("OPT-PARTICIPANT" 'optional)
@@ -345,10 +352,16 @@ status will be retrieved from the first matching attendee record."
(mapc #'process-event-line (split-string ical-request "\n"))
+ ;; RFC5546 refers to uninvited attendees as "party crashers".
+ ;; This situation is common if the invitation is sent to a group
+ ;; of people via a mailing list.
(unless (gnus-icalendar-find-if (lambda (x) (string-match "^ATTENDEE" x))
reply-event-lines)
(lwarn 'gnus-icalendar :warning
- "Could not find an event attendee matching given identity"))
+ "Could not find an event attendee matching given identity")
+ (push (format "ATTENDEE;RSVP=TRUE;PARTSTAT=%s;CN=%s:MAILTO:%s"
+ attendee-status user-full-name user-mail-address)
+ reply-event-lines))
(mapconcat #'identity `("BEGIN:VEVENT"
,@(nreverse reply-event-lines)
@@ -847,10 +860,14 @@ These will be used to retrieve the RSVP information from ical events."
button t
gnus-data ,data))))
-(defun gnus-icalendar-send-buffer-by-mail (buffer-name subject)
+(defun gnus-icalendar-send-buffer-by-mail (buffer-name subject organizer)
(let ((message-signature nil))
(with-current-buffer gnus-summary-buffer
(gnus-summary-reply)
+ ;; Reply to the organizer, not to whoever sent the invitation. person
+ ;; Some calendar systems use specific email address as organizer to
+ ;; receive these responses.
+ (message-replace-header "To" organizer)
(message-goto-body)
(mml-insert-multipart "alternative")
(mml-insert-empty-tag 'part 'type "text/plain")
@@ -866,7 +883,8 @@ These will be used to retrieve the RSVP information from ical events."
(event (caddr data))
(reply (gnus-icalendar-with-decoded-handle handle
(gnus-icalendar-event-reply-from-buffer
- (current-buffer) status (gnus-icalendar-identities)))))
+ (current-buffer) status (gnus-icalendar-identities))))
+ (organizer (gnus-icalendar-event:organizer event)))
(when reply
(cl-labels
@@ -883,7 +901,7 @@ These will be used to retrieve the RSVP information from ical events."
(delete-region (point-min) (point-max))
(insert reply)
(fold-icalendar-buffer)
- (gnus-icalendar-send-buffer-by-mail (buffer-name) subject))
+ (gnus-icalendar-send-buffer-by-mail (buffer-name) subject organizer))
;; Back in article buffer
(setq-local gnus-icalendar-reply-status status)
@@ -897,10 +915,16 @@ These will be used to retrieve the RSVP information from ical events."
(gnus-icalendar-event:sync-to-org event gnus-icalendar-reply-status))
(cl-defmethod gnus-icalendar-event:inline-reply-buttons ((event gnus-icalendar-event) handle)
- (when (gnus-icalendar-event:rsvp event)
- `(("Accept" gnus-icalendar-reply (,handle accepted ,event))
- ("Tentative" gnus-icalendar-reply (,handle tentative ,event))
- ("Decline" gnus-icalendar-reply (,handle declined ,event)))))
+ (let ((accept-btn "Accept")
+ (tentative-btn "Tentative")
+ (decline-btn "Decline"))
+ (unless (gnus-icalendar-event:rsvp event)
+ (setq accept-btn "Uninvited Accept"
+ tentative-btn "Uninvited Tentative"
+ decline-btn "Uninvited Decline"))
+ `((,accept-btn gnus-icalendar-reply (,handle accepted ,event))
+ (,tentative-btn gnus-icalendar-reply (,handle tentative ,event))
+ (,decline-btn gnus-icalendar-reply (,handle declined ,event)))))
(cl-defmethod gnus-icalendar-event:inline-reply-buttons ((_event gnus-icalendar-event-reply) _handle)
"No buttons for REPLY events."
@@ -1038,13 +1062,14 @@ These will be used to retrieve the RSVP information from ical events."
(add-to-list 'mm-automatic-display "text/calendar")
(add-to-list 'mm-inline-media-tests '("text/calendar" gnus-icalendar-mm-inline identity))
- (gnus-define-keys (gnus-summary-calendar-map "i" gnus-summary-mode-map)
- "a" gnus-icalendar-reply-accept
- "t" gnus-icalendar-reply-tentative
- "d" gnus-icalendar-reply-decline
- "c" gnus-icalendar-event-check-agenda
- "e" gnus-icalendar-event-export
- "s" gnus-icalendar-event-show)
+ (define-key gnus-summary-mode-map "i"
+ (define-keymap :prefix 'gnus-summary-calendar-map
+ "a" #'gnus-icalendar-reply-accept
+ "t" #'gnus-icalendar-reply-tentative
+ "d" #'gnus-icalendar-reply-decline
+ "c" #'gnus-icalendar-event-check-agenda
+ "e" #'gnus-icalendar-event-export
+ "s" #'gnus-icalendar-event-show))
(require 'gnus-art)
(add-to-list 'gnus-mime-action-alist
diff --git a/lisp/gnus/gnus-kill.el b/lisp/gnus/gnus-kill.el
index 525823e72ce..7e589c54e97 100644
--- a/lisp/gnus/gnus-kill.el
+++ b/lisp/gnus/gnus-kill.el
@@ -66,18 +66,15 @@ of time."
;;; Gnus Kill File Mode
;;;
-(defvar gnus-kill-file-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map emacs-lisp-mode-map)
- (gnus-define-keymap map
- "\C-c\C-k\C-s" gnus-kill-file-kill-by-subject
- "\C-c\C-k\C-a" gnus-kill-file-kill-by-author
- "\C-c\C-k\C-t" gnus-kill-file-kill-by-thread
- "\C-c\C-k\C-x" gnus-kill-file-kill-by-xref
- "\C-c\C-a" gnus-kill-file-apply-buffer
- "\C-c\C-e" gnus-kill-file-apply-last-sexp
- "\C-c\C-c" gnus-kill-file-exit)
- map))
+(defvar-keymap gnus-kill-file-mode-map
+ :parent emacs-lisp-mode-map
+ "\C-c\C-k\C-s" #'gnus-kill-file-kill-by-subject
+ "\C-c\C-k\C-a" #'gnus-kill-file-kill-by-author
+ "\C-c\C-k\C-t" #'gnus-kill-file-kill-by-thread
+ "\C-c\C-k\C-x" #'gnus-kill-file-kill-by-xref
+ "\C-c\C-a" #'gnus-kill-file-apply-buffer
+ "\C-c\C-e" #'gnus-kill-file-apply-last-sexp
+ "\C-c\C-c" #'gnus-kill-file-exit)
(define-derived-mode gnus-kill-file-mode emacs-lisp-mode "Kill"
"Major mode for editing kill files.
diff --git a/lisp/gnus/gnus-ml.el b/lisp/gnus/gnus-ml.el
index ee3abf2f7be..bf33194cf75 100644
--- a/lisp/gnus/gnus-ml.el
+++ b/lisp/gnus/gnus-ml.el
@@ -31,16 +31,13 @@
;;; Mailing list minor mode
-(defvar gnus-mailing-list-mode-map
- (let ((map (make-sparse-keymap)))
- (gnus-define-keys map
- "\C-c\C-nh" gnus-mailing-list-help
- "\C-c\C-ns" gnus-mailing-list-subscribe
- "\C-c\C-nu" gnus-mailing-list-unsubscribe
- "\C-c\C-np" gnus-mailing-list-post
- "\C-c\C-no" gnus-mailing-list-owner
- "\C-c\C-na" gnus-mailing-list-archive)
- map))
+(defvar-keymap gnus-mailing-list-mode-map
+ "\C-c\C-nh" #'gnus-mailing-list-help
+ "\C-c\C-ns" #'gnus-mailing-list-subscribe
+ "\C-c\C-nu" #'gnus-mailing-list-unsubscribe
+ "\C-c\C-np" #'gnus-mailing-list-post
+ "\C-c\C-no" #'gnus-mailing-list-owner
+ "\C-c\C-na" #'gnus-mailing-list-archive)
(defvar gnus-mailing-list-menu)
diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el
index 8a3272042f3..e88aa8f7d09 100644
--- a/lisp/gnus/gnus-msg.el
+++ b/lisp/gnus/gnus-msg.el
@@ -349,39 +349,39 @@ only affect the Gcc copy, but not the original message."
;;; Gnus Posting Functions
;;;
-(gnus-define-keys (gnus-summary-send-map "S" gnus-summary-mode-map)
- "p" gnus-summary-post-news
- "i" gnus-summary-news-other-window
- "f" gnus-summary-followup
- "F" gnus-summary-followup-with-original
- "c" gnus-summary-cancel-article
- "s" gnus-summary-supersede-article
- "r" gnus-summary-reply
- "y" gnus-summary-yank-message
- "R" gnus-summary-reply-with-original
- "L" gnus-summary-reply-to-list-with-original
- "w" gnus-summary-wide-reply
- "W" gnus-summary-wide-reply-with-original
- "v" gnus-summary-very-wide-reply
- "V" gnus-summary-very-wide-reply-with-original
- "n" gnus-summary-followup-to-mail
- "N" gnus-summary-followup-to-mail-with-original
- "m" gnus-summary-mail-other-window
- "u" gnus-uu-post-news
- "A" gnus-summary-attach-article
- "\M-c" gnus-summary-mail-crosspost-complaint
- "Br" gnus-summary-reply-broken-reply-to
- "BR" gnus-summary-reply-broken-reply-to-with-original
- "om" gnus-summary-mail-forward
- "op" gnus-summary-post-forward
- "Om" gnus-uu-digest-mail-forward
- "Op" gnus-uu-digest-post-forward)
-
-(gnus-define-keys (gnus-send-bounce-map "D" gnus-summary-send-map)
- "b" gnus-summary-resend-bounced-mail
- ;; "c" gnus-summary-send-draft
- "r" gnus-summary-resend-message
- "e" gnus-summary-resend-message-edit)
+(define-keymap :prefix 'gnus-summary-send-map
+ "p" #'gnus-summary-post-news
+ "i" #'gnus-summary-news-other-window
+ "f" #'gnus-summary-followup
+ "F" #'gnus-summary-followup-with-original
+ "c" #'gnus-summary-cancel-article
+ "s" #'gnus-summary-supersede-article
+ "r" #'gnus-summary-reply
+ "y" #'gnus-summary-yank-message
+ "R" #'gnus-summary-reply-with-original
+ "L" #'gnus-summary-reply-to-list-with-original
+ "w" #'gnus-summary-wide-reply
+ "W" #'gnus-summary-wide-reply-with-original
+ "v" #'gnus-summary-very-wide-reply
+ "V" #'gnus-summary-very-wide-reply-with-original
+ "n" #'gnus-summary-followup-to-mail
+ "N" #'gnus-summary-followup-to-mail-with-original
+ "m" #'gnus-summary-mail-other-window
+ "u" #'gnus-uu-post-news
+ "A" #'gnus-summary-attach-article
+ "\M-c" #'gnus-summary-mail-crosspost-complaint
+ "Br" #'gnus-summary-reply-broken-reply-to
+ "BR" #'gnus-summary-reply-broken-reply-to-with-original
+ "om" #'gnus-summary-mail-forward
+ "op" #'gnus-summary-post-forward
+ "Om" #'gnus-uu-digest-mail-forward
+ "Op" #'gnus-uu-digest-post-forward
+
+ "D" (define-keymap :prefix 'gnus-send-bounce-map
+ "b" #'gnus-summary-resend-bounced-mail
+ ;; "c" gnus-summary-send-draft
+ "r" #'gnus-summary-resend-message
+ "e" #'gnus-summary-resend-message-edit))
;;; Internal functions.
diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el
index 9b76f983227..8ce88dc81e4 100644
--- a/lisp/gnus/gnus-registry.el
+++ b/lisp/gnus/gnus-registry.el
@@ -990,9 +990,9 @@ Uses `gnus-registry-marks' to find what shortcuts to install."
gnus-registry-misc-menus)
(gnus-message 9 "Defined mark handling function %s"
function-name))))))
- (gnus-define-keys-1
- '(gnus-registry-mark-map "M" gnus-summary-mark-map)
- keys-plist)
+ (define-key gnus-summary-mark-map "M"
+ (apply #'define-keymap :prefix 'gnus-summary-mark-map
+ keys-plist))
(add-hook 'gnus-summary-menu-hook
(lambda ()
(easy-menu-add-item
@@ -1142,7 +1142,7 @@ non-nil."
entry)
(while (car-safe old)
(cl-incf count)
- ;; don't use progress reporters for backwards compatibility
+ ;; todo: use progress reporters.
(when (and (< 0 expected)
(= 0 (mod count 100)))
(message "importing: %d of %d (%.2f%%)"
diff --git a/lisp/gnus/gnus-salt.el b/lisp/gnus/gnus-salt.el
index dc81dfc5f6c..8ffe4a4c573 100644
--- a/lisp/gnus/gnus-salt.el
+++ b/lisp/gnus/gnus-salt.el
@@ -64,15 +64,12 @@ It accepts the same format specs that `gnus-summary-line-format' does."
;;; Internal variables.
-(defvar gnus-pick-mode-map
- (let ((map (make-sparse-keymap)))
- (gnus-define-keys map
- " " gnus-pick-next-page
- "u" gnus-pick-unmark-article-or-thread
- "." gnus-pick-article-or-thread
- [down-mouse-2] gnus-pick-mouse-pick-region
- "\r" gnus-pick-start-reading)
- map))
+(defvar-keymap gnus-pick-mode-map
+ " " #'gnus-pick-next-page
+ "u" #'gnus-pick-unmark-article-or-thread
+ "." #'gnus-pick-article-or-thread
+ [down-mouse-2] #'gnus-pick-mouse-pick-region
+ "\r" #'gnus-pick-start-reading)
(defun gnus-pick-make-menu-bar ()
(unless (boundp 'gnus-pick-menu)
@@ -315,11 +312,8 @@ This must be bound to a button-down mouse event."
(defvar gnus-binary-mode-hook nil
"Hook run in summary binary mode buffers.")
-(defvar gnus-binary-mode-map
- (let ((map (make-sparse-keymap)))
- (gnus-define-keys map
- "g" gnus-binary-show-article)
- map))
+(defvar-keymap gnus-binary-mode-map
+ "g" #'gnus-binary-show-article)
(defun gnus-binary-make-menu-bar ()
(unless (boundp 'gnus-binary-menu)
@@ -424,21 +418,17 @@ Two predefined functions are available:
(defvar gnus-tree-displayed-thread nil)
(defvar gnus-tree-inhibit nil)
-(defvar gnus-tree-mode-map
- (let ((map (make-keymap)))
- (suppress-keymap map)
- (gnus-define-keys
- map
- "\r" gnus-tree-select-article
- [mouse-2] gnus-tree-pick-article
- "\C-?" gnus-tree-read-summary-keys
- "h" gnus-tree-show-summary
-
- "\C-c\C-i" gnus-info-find-node)
-
- (substitute-key-definition
- 'undefined 'gnus-tree-read-summary-keys map)
- map))
+(defvar-keymap gnus-tree-mode-map
+ :full t :suppress t
+ "\r" #'gnus-tree-select-article
+ [mouse-2] #'gnus-tree-pick-article
+ "\C-?" #'gnus-tree-read-summary-keys
+ "h" #'gnus-tree-show-summary
+
+ "\C-c\C-i" #'gnus-info-find-node)
+
+(substitute-key-definition 'undefined #'gnus-tree-read-summary-keys
+ gnus-tree-mode-map)
(defun gnus-tree-make-menu-bar ()
(unless (boundp 'gnus-tree-menu)
diff --git a/lisp/gnus/gnus-score.el b/lisp/gnus/gnus-score.el
index e0ad9f698d3..2ca25802957 100644
--- a/lisp/gnus/gnus-score.el
+++ b/lisp/gnus/gnus-score.el
@@ -502,19 +502,20 @@ of the last successful match.")
;;; Summary mode score maps.
-(gnus-define-keys (gnus-summary-score-map "V" gnus-summary-mode-map)
- "s" gnus-summary-set-score
- "S" gnus-summary-current-score
- "c" gnus-score-change-score-file
- "C" gnus-score-customize
- "m" gnus-score-set-mark-below
- "x" gnus-score-set-expunge-below
- "R" gnus-summary-rescore
- "e" gnus-score-edit-current-scores
- "f" gnus-score-edit-file
- "F" gnus-score-flush-cache
- "t" gnus-score-find-trace
- "w" gnus-score-find-favorite-words)
+(define-key gnus-summary-mode-map "V"
+ (define-keymap :prefix 'gnus-summary-score-map
+ "s" #'gnus-summary-set-score
+ "S" #'gnus-summary-current-score
+ "c" #'gnus-score-change-score-file
+ "C" #'gnus-score-customize
+ "m" #'gnus-score-set-mark-below
+ "x" #'gnus-score-set-expunge-below
+ "R" #'gnus-summary-rescore
+ "e" #'gnus-score-edit-current-scores
+ "f" #'gnus-score-edit-file
+ "F" #'gnus-score-flush-cache
+ "t" #'gnus-score-find-trace
+ "w" #'gnus-score-find-favorite-words))
;; Summary score file commands
diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el
index 5f2fc463330..f2ffb067b8e 100644
--- a/lisp/gnus/gnus-srvr.el
+++ b/lisp/gnus/gnus-srvr.el
@@ -103,7 +103,43 @@ If nil, a faster, but more primitive, buffer is used instead."
(defvar gnus-server-mode-line-format-spec nil)
(defvar gnus-server-killed-servers nil)
-(defvar gnus-server-mode-map nil)
+(defvar-keymap gnus-server-mode-map
+ :full t :suppress t
+ " " #'gnus-server-read-server-in-server-buffer
+ "\r" #'gnus-server-read-server
+ [mouse-2] #'gnus-server-pick-server
+ "q" #'gnus-server-exit
+ "l" #'gnus-server-list-servers
+ "k" #'gnus-server-kill-server
+ "y" #'gnus-server-yank-server
+ "c" #'gnus-server-copy-server
+ "a" #'gnus-server-add-server
+ "e" #'gnus-server-edit-server
+ "S" #'gnus-server-show-server
+ "s" #'gnus-server-scan-server
+
+ "O" #'gnus-server-open-server
+ "\M-o" #'gnus-server-open-all-servers
+ "C" #'gnus-server-close-server
+ "\M-c" #'gnus-server-close-all-servers
+ "D" #'gnus-server-deny-server
+ "L" #'gnus-server-offline-server
+ "R" #'gnus-server-remove-denials
+
+ "n" #'next-line
+ "p" #'previous-line
+
+ "g" #'gnus-server-regenerate-server
+
+ "G" #'gnus-group-read-ephemeral-search-group
+
+ "z" #'gnus-server-compact-server
+
+ "i" #'gnus-server-toggle-cloud-server
+ "I" #'gnus-server-set-cloud-method-server
+
+ "\C-c\C-i" #'gnus-info-find-node
+ "\C-c\C-b" #'gnus-bug)
(defcustom gnus-server-menu-hook nil
"Hook run after the creation of the server mode menu."
@@ -145,47 +181,6 @@ If nil, a faster, but more primitive, buffer is used instead."
(gnus-run-hooks 'gnus-server-menu-hook)))
-(unless gnus-server-mode-map
- (setq gnus-server-mode-map (make-keymap))
- (suppress-keymap gnus-server-mode-map)
-
- (gnus-define-keys gnus-server-mode-map
- " " gnus-server-read-server-in-server-buffer
- "\r" gnus-server-read-server
- [mouse-2] gnus-server-pick-server
- "q" gnus-server-exit
- "l" gnus-server-list-servers
- "k" gnus-server-kill-server
- "y" gnus-server-yank-server
- "c" gnus-server-copy-server
- "a" gnus-server-add-server
- "e" gnus-server-edit-server
- "S" gnus-server-show-server
- "s" gnus-server-scan-server
-
- "O" gnus-server-open-server
- "\M-o" gnus-server-open-all-servers
- "C" gnus-server-close-server
- "\M-c" gnus-server-close-all-servers
- "D" gnus-server-deny-server
- "L" gnus-server-offline-server
- "R" gnus-server-remove-denials
-
- "n" next-line
- "p" previous-line
-
- "g" gnus-server-regenerate-server
-
- "G" gnus-group-read-ephemeral-search-group
-
- "z" gnus-server-compact-server
-
- "i" gnus-server-toggle-cloud-server
- "I" gnus-server-set-cloud-method-server
-
- "\C-c\C-i" gnus-info-find-node
- "\C-c\C-b" gnus-bug))
-
(defface gnus-server-agent
'((((class color) (background light)) (:foreground "PaleTurquoise" :bold t))
(((class color) (background dark)) (:foreground "PaleTurquoise" :bold t))
@@ -697,37 +692,31 @@ claim them."
function
(repeat function)))
-(defvar gnus-browse-mode-map nil)
-
-(unless gnus-browse-mode-map
- (setq gnus-browse-mode-map (make-keymap))
- (suppress-keymap gnus-browse-mode-map)
-
- (gnus-define-keys
- gnus-browse-mode-map
- " " gnus-browse-read-group
- "=" gnus-browse-select-group
- "n" gnus-browse-next-group
- "p" gnus-browse-prev-group
- "\177" gnus-browse-prev-group
- [delete] gnus-browse-prev-group
- "N" gnus-browse-next-group
- "P" gnus-browse-prev-group
- "\M-n" gnus-browse-next-group
- "\M-p" gnus-browse-prev-group
- "\r" gnus-browse-select-group
- "u" gnus-browse-toggle-subscription-at-point
- "l" gnus-browse-exit
- "L" gnus-browse-exit
- "q" gnus-browse-exit
- "Q" gnus-browse-exit
- "d" gnus-browse-describe-group
- [delete] gnus-browse-delete-group
- "\C-c\C-c" gnus-browse-exit
- "?" gnus-browse-describe-briefly
-
- "\C-c\C-i" gnus-info-find-node
- "\C-c\C-b" gnus-bug))
+(defvar-keymap gnus-browse-mode-map
+ :full t :suppress t
+ " " #'gnus-browse-read-group
+ "=" #'gnus-browse-select-group
+ "n" #'gnus-browse-next-group
+ "p" #'gnus-browse-prev-group
+ "\177" #'gnus-browse-prev-group
+ [delete] #'gnus-browse-prev-group
+ "N" #'gnus-browse-next-group
+ "P" #'gnus-browse-prev-group
+ "\M-n" #'gnus-browse-next-group
+ "\M-p" #'gnus-browse-prev-group
+ "\r" #'gnus-browse-select-group
+ "u" #'gnus-browse-toggle-subscription-at-point
+ "l" #'gnus-browse-exit
+ "L" #'gnus-browse-exit
+ "q" #'gnus-browse-exit
+ "Q" #'gnus-browse-exit
+ "d" #'gnus-browse-describe-group
+ [delete] #'gnus-browse-delete-group
+ "\C-c\C-c" #'gnus-browse-exit
+ "?" #'gnus-browse-describe-briefly
+
+ "\C-c\C-i" #'gnus-info-find-node
+ "\C-c\C-b" #'gnus-bug)
(defun gnus-browse-make-menu-bar ()
(gnus-turn-off-edit-menu 'browse)
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index c7be958edd1..606bd3a39a4 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -663,6 +663,7 @@ the first newsgroup."
(defvar mail-sources)
(defvar nnmail-scan-directory-mail-source-once)
(defvar nnmail-split-history)
+(defvar gnus-save-newsrc-file-last-timestamp nil)
(defun gnus-close-all-servers ()
"Close all servers."
@@ -707,6 +708,7 @@ the first newsgroup."
gnus-current-select-method nil
nnmail-split-history nil
gnus-extended-servers nil
+ gnus-save-newsrc-file-last-timestamp nil
gnus-ephemeral-servers nil)
(gnus-shutdown 'gnus)
;; Kill the startup file.
@@ -2731,7 +2733,6 @@ The form should return either t or nil."
'msdos-long-file-names
(lambda () t))))
-(defvar gnus-save-newsrc-file-last-timestamp nil)
(defun gnus-save-newsrc-file (&optional force)
"Save .newsrc file.
Use the group string names in `gnus-group-list' to pull info
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index d790655aa90..ab8c578c9cd 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -1907,485 +1907,482 @@ increase the score of each group you read."
;; Non-orthogonal keys
-(gnus-define-keys gnus-summary-mode-map
- " " gnus-summary-next-page
- [?\S-\ ] gnus-summary-prev-page
- "\177" gnus-summary-prev-page
- [delete] gnus-summary-prev-page
- "\r" gnus-summary-scroll-up
- "\M-\r" gnus-summary-scroll-down
- "n" gnus-summary-next-unread-article
- "p" gnus-summary-prev-unread-article
- "N" gnus-summary-next-article
- "P" gnus-summary-prev-article
- "\M-\C-n" gnus-summary-next-same-subject
- "\M-\C-p" gnus-summary-prev-same-subject
- "\M-n" gnus-summary-next-unread-subject
- "\M-p" gnus-summary-prev-unread-subject
- "." gnus-summary-first-unread-article
- "," gnus-summary-best-unread-article
- "[" gnus-summary-prev-unseen-article
- "]" gnus-summary-next-unseen-article
- "\M-s\M-s" gnus-summary-search-article-forward
- "\M-s\M-r" gnus-summary-search-article-backward
- "\M-r" gnus-summary-search-article-backward
- "\M-S" gnus-summary-repeat-search-article-forward
- "\M-R" gnus-summary-repeat-search-article-backward
- "<" gnus-summary-beginning-of-article
- ">" gnus-summary-end-of-article
- "j" gnus-summary-goto-article
- "^" gnus-summary-refer-parent-article
- "\M-^" gnus-summary-refer-article
- "u" gnus-summary-tick-article-forward
- "!" gnus-summary-tick-article-forward
- "U" gnus-summary-tick-article-backward
- "d" gnus-summary-mark-as-read-forward
- "D" gnus-summary-mark-as-read-backward
- "E" gnus-summary-mark-as-expirable
- "\M-u" gnus-summary-clear-mark-forward
- "\M-U" gnus-summary-clear-mark-backward
- "k" gnus-summary-kill-same-subject-and-select
- "\C-k" gnus-summary-kill-same-subject
- "\M-\C-k" gnus-summary-kill-thread
- "\M-\C-l" gnus-summary-lower-thread
- "e" gnus-summary-edit-article
- "#" gnus-summary-mark-as-processable
- "\M-#" gnus-summary-unmark-as-processable
- "\M-\C-t" gnus-summary-toggle-threads
- "\M-\C-s" gnus-summary-show-thread
- "\M-\C-h" gnus-summary-hide-thread
- "\M-\C-f" gnus-summary-next-thread
- "\M-\C-b" gnus-summary-prev-thread
- [(meta down)] gnus-summary-next-thread
- [(meta up)] gnus-summary-prev-thread
- "\M-\C-u" gnus-summary-up-thread
- "\M-\C-d" gnus-summary-down-thread
- "&" gnus-summary-execute-command
- "c" gnus-summary-catchup-and-exit
- "\C-w" gnus-summary-mark-region-as-read
- "\C-t" toggle-truncate-lines
- "?" gnus-summary-mark-as-dormant
- "\C-c\M-\C-s" gnus-summary-limit-include-expunged
- "\C-c\C-s\C-n" gnus-summary-sort-by-number
- "\C-c\C-s\C-m\C-n" gnus-summary-sort-by-most-recent-number
- "\C-c\C-s\C-l" gnus-summary-sort-by-lines
- "\C-c\C-s\C-c" gnus-summary-sort-by-chars
- "\C-c\C-s\C-m\C-m" gnus-summary-sort-by-marks
- "\C-c\C-s\C-a" gnus-summary-sort-by-author
- "\C-c\C-s\C-t" gnus-summary-sort-by-recipient
- "\C-c\C-s\C-s" gnus-summary-sort-by-subject
- "\C-c\C-s\C-d" gnus-summary-sort-by-date
- "\C-c\C-s\C-m\C-d" gnus-summary-sort-by-most-recent-date
- "\C-c\C-s\C-i" gnus-summary-sort-by-score
- "\C-c\C-s\C-o" gnus-summary-sort-by-original
- "\C-c\C-s\C-r" gnus-summary-sort-by-random
- "\C-c\C-s\C-u" gnus-summary-sort-by-newsgroups
- "\C-c\C-s\C-x" gnus-summary-sort-by-extra
- "=" gnus-summary-expand-window
- "\C-x\C-s" gnus-summary-reselect-current-group
- "\M-g" gnus-summary-rescan-group
- "\C-c\C-r" gnus-summary-caesar-message
- "f" gnus-summary-followup
- "F" gnus-summary-followup-with-original
- "C" gnus-summary-cancel-article
- "r" gnus-summary-reply
- "R" gnus-summary-reply-with-original
- "\C-c\C-f" gnus-summary-mail-forward
- "o" gnus-summary-save-article
- "\C-o" gnus-summary-save-article-mail
- "|" gnus-summary-pipe-output
- "\M-k" gnus-summary-edit-local-kill
- "\M-K" gnus-summary-edit-global-kill
+(define-keymap :keymap gnus-summary-mode-map
+ " " #'gnus-summary-next-page
+ [?\S-\ ] #'gnus-summary-prev-page
+ "\177" #'gnus-summary-prev-page
+ [delete] #'gnus-summary-prev-page
+ "\r" #'gnus-summary-scroll-up
+ "\M-\r" #'gnus-summary-scroll-down
+ "n" #'gnus-summary-next-unread-article
+ "p" #'gnus-summary-prev-unread-article
+ "N" #'gnus-summary-next-article
+ "P" #'gnus-summary-prev-article
+ "\M-\C-n" #'gnus-summary-next-same-subject
+ "\M-\C-p" #'gnus-summary-prev-same-subject
+ "\M-n" #'gnus-summary-next-unread-subject
+ "\M-p" #'gnus-summary-prev-unread-subject
+ "." #'gnus-summary-first-unread-article
+ "," #'gnus-summary-best-unread-article
+ "[" #'gnus-summary-prev-unseen-article
+ "]" #'gnus-summary-next-unseen-article
+ "\M-s\M-s" #'gnus-summary-search-article-forward
+ "\M-s\M-r" #'gnus-summary-search-article-backward
+ "\M-r" #'gnus-summary-search-article-backward
+ "\M-S" #'gnus-summary-repeat-search-article-forward
+ "\M-R" #'gnus-summary-repeat-search-article-backward
+ "<" #'gnus-summary-beginning-of-article
+ ">" #'gnus-summary-end-of-article
+ "j" #'gnus-summary-goto-article
+ "^" #'gnus-summary-refer-parent-article
+ "\M-^" #'gnus-summary-refer-article
+ "u" #'gnus-summary-tick-article-forward
+ "!" #'gnus-summary-tick-article-forward
+ "U" #'gnus-summary-tick-article-backward
+ "d" #'gnus-summary-mark-as-read-forward
+ "D" #'gnus-summary-mark-as-read-backward
+ "E" #'gnus-summary-mark-as-expirable
+ "\M-u" #'gnus-summary-clear-mark-forward
+ "\M-U" #'gnus-summary-clear-mark-backward
+ "k" #'gnus-summary-kill-same-subject-and-select
+ "\C-k" #'gnus-summary-kill-same-subject
+ "\M-\C-k" #'gnus-summary-kill-thread
+ "\M-\C-l" #'gnus-summary-lower-thread
+ "e" #'gnus-summary-edit-article
+ "#" #'gnus-summary-mark-as-processable
+ "\M-#" #'gnus-summary-unmark-as-processable
+ "\M-\C-t" #'gnus-summary-toggle-threads
+ "\M-\C-s" #'gnus-summary-show-thread
+ "\M-\C-h" #'gnus-summary-hide-thread
+ "\M-\C-f" #'gnus-summary-next-thread
+ "\M-\C-b" #'gnus-summary-prev-thread
+ [(meta down)] #'gnus-summary-next-thread
+ [(meta up)] #'gnus-summary-prev-thread
+ "\M-\C-u" #'gnus-summary-up-thread
+ "\M-\C-d" #'gnus-summary-down-thread
+ "&" #'gnus-summary-execute-command
+ "c" #'gnus-summary-catchup-and-exit
+ "\C-w" #'gnus-summary-mark-region-as-read
+ "\C-t" #'toggle-truncate-lines
+ "?" #'gnus-summary-mark-as-dormant
+ "\C-c\M-\C-s" #'gnus-summary-limit-include-expunged
+ "\C-c\C-s\C-n" #'gnus-summary-sort-by-number
+ "\C-c\C-s\C-m\C-n" #'gnus-summary-sort-by-most-recent-number
+ "\C-c\C-s\C-l" #'gnus-summary-sort-by-lines
+ "\C-c\C-s\C-c" #'gnus-summary-sort-by-chars
+ "\C-c\C-s\C-m\C-m" #'gnus-summary-sort-by-marks
+ "\C-c\C-s\C-a" #'gnus-summary-sort-by-author
+ "\C-c\C-s\C-t" #'gnus-summary-sort-by-recipient
+ "\C-c\C-s\C-s" #'gnus-summary-sort-by-subject
+ "\C-c\C-s\C-d" #'gnus-summary-sort-by-date
+ "\C-c\C-s\C-m\C-d" #'gnus-summary-sort-by-most-recent-date
+ "\C-c\C-s\C-i" #'gnus-summary-sort-by-score
+ "\C-c\C-s\C-o" #'gnus-summary-sort-by-original
+ "\C-c\C-s\C-r" #'gnus-summary-sort-by-random
+ "\C-c\C-s\C-u" #'gnus-summary-sort-by-newsgroups
+ "\C-c\C-s\C-x" #'gnus-summary-sort-by-extra
+ "=" #'gnus-summary-expand-window
+ "\C-x\C-s" #'gnus-summary-reselect-current-group
+ "\M-g" #'gnus-summary-rescan-group
+ "\C-c\C-r" #'gnus-summary-caesar-message
+ "f" #'gnus-summary-followup
+ "F" #'gnus-summary-followup-with-original
+ "C" #'gnus-summary-cancel-article
+ "r" #'gnus-summary-reply
+ "R" #'gnus-summary-reply-with-original
+ "\C-c\C-f" #'gnus-summary-mail-forward
+ "o" #'gnus-summary-save-article
+ "\C-o" #'gnus-summary-save-article-mail
+ "|" #'gnus-summary-pipe-output
+ "\M-k" #'gnus-summary-edit-local-kill
+ "\M-K" #'gnus-summary-edit-global-kill
;; "V" gnus-version
- "\C-c\C-d" gnus-summary-describe-group
- "\C-c\C-p" gnus-summary-make-group-from-search
- "q" gnus-summary-exit
- "Q" gnus-summary-exit-no-update
- "\C-c\C-i" gnus-info-find-node
- [mouse-2] gnus-mouse-pick-article
- [follow-link] mouse-face
- "m" gnus-summary-mail-other-window
- "a" gnus-summary-post-news
- "x" gnus-summary-limit-to-unread
- "s" gnus-summary-isearch-article
- "\t" gnus-summary-button-forward
- [backtab] gnus-summary-button-backward
- "w" gnus-summary-browse-url
- "t" gnus-summary-toggle-header
- "g" gnus-summary-show-article
- "l" gnus-summary-goto-last-article
- "\C-c\C-v\C-v" gnus-uu-decode-uu-view
- "\C-d" gnus-summary-enter-digest-group
- "\M-\C-d" gnus-summary-read-document
- "\M-\C-e" gnus-summary-edit-parameters
- "\M-\C-a" gnus-summary-customize-parameters
- "\C-c\C-b" gnus-bug
- "*" gnus-cache-enter-article
- "\M-*" gnus-cache-remove-article
- "\M-&" gnus-summary-universal-argument
- "\C-l" gnus-recenter
- "I" gnus-summary-increase-score
- "L" gnus-summary-lower-score
- "\M-i" gnus-symbolic-argument
- "h" gnus-summary-select-article-buffer
-
- "b" gnus-article-view-part
- "\M-t" gnus-summary-toggle-display-buttonized
-
- "V" gnus-summary-score-map
- "X" gnus-uu-extract-map
- "S" gnus-summary-send-map)
-
-;; Sort of orthogonal keymap
-(gnus-define-keys (gnus-summary-mark-map "M" gnus-summary-mode-map)
- "t" gnus-summary-tick-article-forward
- "!" gnus-summary-tick-article-forward
- "d" gnus-summary-mark-as-read-forward
- "r" gnus-summary-mark-as-read-forward
- "c" gnus-summary-clear-mark-forward
- " " gnus-summary-clear-mark-forward
- "e" gnus-summary-mark-as-expirable
- "x" gnus-summary-mark-as-expirable
- "?" gnus-summary-mark-as-dormant
- "b" gnus-summary-set-bookmark
- "B" gnus-summary-remove-bookmark
- "#" gnus-summary-mark-as-processable
- "\M-#" gnus-summary-unmark-as-processable
- "S" gnus-summary-limit-include-expunged
- "C" gnus-summary-catchup
- "H" gnus-summary-catchup-to-here
- "h" gnus-summary-catchup-from-here
- "\C-c" gnus-summary-catchup-all
- "k" gnus-summary-kill-same-subject-and-select
- "K" gnus-summary-kill-same-subject
- "P" gnus-uu-mark-map)
-
-(gnus-define-keys (gnus-summary-mscore-map "V" gnus-summary-mark-map)
- "c" gnus-summary-clear-above
- "u" gnus-summary-tick-above
- "m" gnus-summary-mark-above
- "k" gnus-summary-kill-below)
-
-(gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map)
- "/" gnus-summary-limit-to-subject
- "n" gnus-summary-limit-to-articles
- "b" gnus-summary-limit-to-bodies
- "h" gnus-summary-limit-to-headers
- "w" gnus-summary-pop-limit
- "s" gnus-summary-limit-to-subject
- "a" gnus-summary-limit-to-author
- "u" gnus-summary-limit-to-unread
- "m" gnus-summary-limit-to-marks
- "M" gnus-summary-limit-exclude-marks
- "v" gnus-summary-limit-to-score
- "*" gnus-summary-limit-include-cached
- "D" gnus-summary-limit-include-dormant
- "T" gnus-summary-limit-include-thread
- "d" gnus-summary-limit-exclude-dormant
- "t" gnus-summary-limit-to-age
- "." gnus-summary-limit-to-unseen
- "x" gnus-summary-limit-to-extra
- "p" gnus-summary-limit-to-display-predicate
- "E" gnus-summary-limit-include-expunged
- "c" gnus-summary-limit-exclude-childless-dormant
- "C" gnus-summary-limit-mark-excluded-as-read
- "o" gnus-summary-insert-old-articles
- "N" gnus-summary-insert-new-articles
- "S" gnus-summary-limit-to-singletons
- "r" gnus-summary-limit-to-replied
- "R" gnus-summary-limit-to-recipient
- "A" gnus-summary-limit-to-address)
-
-(gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map)
- "n" gnus-summary-next-unread-article
- "p" gnus-summary-prev-unread-article
- "N" gnus-summary-next-article
- "P" gnus-summary-prev-article
- "\C-n" gnus-summary-next-same-subject
- "\C-p" gnus-summary-prev-same-subject
- "\M-n" gnus-summary-next-unread-subject
- "\M-p" gnus-summary-prev-unread-subject
- "f" gnus-summary-first-unread-article
- "b" gnus-summary-best-unread-article
- "u" gnus-summary-next-unseen-article
- "U" gnus-summary-prev-unseen-article
- "j" gnus-summary-goto-article
- "g" gnus-summary-goto-subject
- "l" gnus-summary-goto-last-article
- "o" gnus-summary-pop-article)
-
-(gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map)
- "k" gnus-summary-kill-thread
- "E" gnus-summary-expire-thread
- "l" gnus-summary-lower-thread
- "i" gnus-summary-raise-thread
- "T" gnus-summary-toggle-threads
- "t" gnus-summary-rethread-current
- "^" gnus-summary-reparent-thread
- "\M-^" gnus-summary-reparent-children
- "s" gnus-summary-show-thread
- "S" gnus-summary-show-all-threads
- "h" gnus-summary-hide-thread
- "H" gnus-summary-hide-all-threads
- "n" gnus-summary-next-thread
- "p" gnus-summary-prev-thread
- "u" gnus-summary-up-thread
- "o" gnus-summary-top-thread
- "d" gnus-summary-down-thread
- "#" gnus-uu-mark-thread
- "\M-#" gnus-uu-unmark-thread)
-
-(gnus-define-keys (gnus-summary-buffer-map "Y" gnus-summary-mode-map)
- "g" gnus-summary-prepare
- "c" gnus-summary-insert-cached-articles
- "d" gnus-summary-insert-dormant-articles
- "t" gnus-summary-insert-ticked-articles)
-
-(gnus-define-keys (gnus-summary-exit-map "Z" gnus-summary-mode-map)
- "c" gnus-summary-catchup-and-exit
- "C" gnus-summary-catchup-all-and-exit
- "E" gnus-summary-exit-no-update
- "Q" gnus-summary-exit
- "Z" gnus-summary-exit
- "n" gnus-summary-catchup-and-goto-next-group
- "p" gnus-summary-catchup-and-goto-prev-group
- "R" gnus-summary-reselect-current-group
- "G" gnus-summary-rescan-group
- "N" gnus-summary-next-group
- "s" gnus-summary-save-newsrc
- "P" gnus-summary-prev-group)
-
-(gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map)
- " " gnus-summary-next-page
- "n" gnus-summary-next-page
- [?\S-\ ] gnus-summary-prev-page
- "\177" gnus-summary-prev-page
- [delete] gnus-summary-prev-page
- "p" gnus-summary-prev-page
- "\r" gnus-summary-scroll-up
- "\M-\r" gnus-summary-scroll-down
- "<" gnus-summary-beginning-of-article
- ">" gnus-summary-end-of-article
- "b" gnus-summary-beginning-of-article
- "e" gnus-summary-end-of-article
- "^" gnus-summary-refer-parent-article
- "r" gnus-summary-refer-parent-article
- "C" gnus-summary-show-complete-article
- "D" gnus-summary-enter-digest-group
- "R" gnus-summary-refer-references
- "T" gnus-summary-refer-thread
- "W" gnus-warp-to-article
- "g" gnus-summary-show-article
- "s" gnus-summary-isearch-article
- "\t" gnus-summary-button-forward
- [backtab] gnus-summary-button-backward
- "w" gnus-summary-browse-url
- "P" gnus-summary-print-article
- "S" gnus-sticky-article
- "M" gnus-mailing-list-insinuate
- "t" gnus-article-babel)
-
-(gnus-define-keys (gnus-summary-wash-map "W" gnus-summary-mode-map)
- "b" gnus-article-add-buttons
- "B" gnus-article-add-buttons-to-head
- "o" gnus-article-treat-overstrike
- "e" gnus-article-emphasize
- "w" gnus-article-fill-cited-article
- "Q" gnus-article-fill-long-lines
- "L" gnus-article-toggle-truncate-lines
- "C" gnus-article-capitalize-sentences
- "c" gnus-article-remove-cr
- "q" gnus-article-de-quoted-unreadable
- "6" gnus-article-de-base64-unreadable
- "Z" gnus-article-decode-HZ
- "A" gnus-article-treat-ansi-sequences
- "h" gnus-article-wash-html
- "u" gnus-article-unsplit-urls
- "s" gnus-summary-force-verify-and-decrypt
- "f" gnus-article-display-x-face
- "l" gnus-summary-stop-page-breaking
- "r" gnus-summary-caesar-message
- "m" gnus-summary-morse-message
- "t" gnus-summary-toggle-header
- "g" gnus-treat-smiley
- "v" gnus-summary-verbose-headers
- "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
- "p" gnus-article-verify-x-pgp-sig
- "d" gnus-article-treat-smartquotes
- "U" gnus-article-treat-non-ascii
- "i" gnus-summary-idna-message)
-
-(gnus-define-keys (gnus-summary-wash-deuglify-map "Y" gnus-summary-wash-map)
- ;; mnemonic: deuglif*Y*
- "u" gnus-article-outlook-unwrap-lines
- "a" gnus-article-outlook-repair-attribution
- "c" gnus-article-outlook-rearrange-citation
- "f" gnus-article-outlook-deuglify-article) ;; mnemonic: full deuglify
-
-(gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
- "a" gnus-article-hide
- "h" gnus-article-hide-headers
- "b" gnus-article-hide-boring-headers
- "s" gnus-article-hide-signature
- "c" gnus-article-hide-citation
- "C" gnus-article-hide-citation-in-followups
- "l" gnus-article-hide-list-identifiers
- "B" gnus-article-strip-banner
- "P" gnus-article-hide-pem
- "\C-c" gnus-article-hide-citation-maybe)
-
-(gnus-define-keys (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map)
- "a" gnus-article-highlight
- "h" gnus-article-highlight-headers
- "c" gnus-article-highlight-citation
- "s" gnus-article-highlight-signature)
-
-(gnus-define-keys (gnus-summary-wash-header-map "G" gnus-summary-wash-map)
- "f" gnus-article-treat-fold-headers
- "u" gnus-article-treat-unfold-headers
- "n" gnus-article-treat-fold-newsgroups)
-
-(gnus-define-keys (gnus-summary-wash-display-map "D" gnus-summary-wash-map)
- "x" gnus-article-display-x-face
- "d" gnus-article-display-face
- "s" gnus-treat-smiley
- "D" gnus-article-remove-images
- "W" gnus-article-show-images
- "F" gnus-article-toggle-fonts
- "f" gnus-treat-from-picon
- "m" gnus-treat-mail-picon
- "n" gnus-treat-newsgroups-picon
- "g" gnus-treat-from-gravatar
- "h" gnus-treat-mail-gravatar)
-
-(gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
- "w" gnus-article-decode-mime-words
- "c" gnus-article-decode-charset
- "h" gnus-mime-buttonize-attachments-in-header
- "v" gnus-mime-view-all-parts
- "b" gnus-article-view-part)
-
-(gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
- "z" gnus-article-date-ut
- "u" gnus-article-date-ut
- "l" gnus-article-date-local
- "p" gnus-article-date-english
- "e" gnus-article-date-lapsed
- "o" gnus-article-date-original
- "i" gnus-article-date-iso8601
- "s" gnus-article-date-user)
-
-(gnus-define-keys (gnus-summary-wash-empty-map "E" gnus-summary-wash-map)
- "t" gnus-article-remove-trailing-blank-lines
- "l" gnus-article-strip-leading-blank-lines
- "m" gnus-article-strip-multiple-blank-lines
- "a" gnus-article-strip-blank-lines
- "A" gnus-article-strip-all-blank-lines
- "s" gnus-article-strip-leading-space
- "e" gnus-article-strip-trailing-space
- "w" gnus-article-remove-leading-whitespace)
-
-(gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
- "v" gnus-version
- "d" gnus-summary-describe-group
- "h" gnus-summary-describe-briefly
- "i" gnus-info-find-node)
-
-(gnus-define-keys (gnus-summary-backend-map "B" gnus-summary-mode-map)
- "e" gnus-summary-expire-articles
- "\M-\C-e" gnus-summary-expire-articles-now
- "\177" gnus-summary-delete-article
- [delete] gnus-summary-delete-article
- [backspace] gnus-summary-delete-article
- "m" gnus-summary-move-article
- "r" gnus-summary-respool-article
- "w" gnus-summary-edit-article
- "c" gnus-summary-copy-article
- "B" gnus-summary-crosspost-article
- "q" gnus-summary-respool-query
- "t" gnus-summary-respool-trace
- "i" gnus-summary-import-article
- "I" gnus-summary-create-article
- "p" gnus-summary-article-posted-p)
-
-(gnus-define-keys (gnus-summary-save-map "O" gnus-summary-mode-map)
- "o" gnus-summary-save-article
- "m" gnus-summary-save-article-mail
- "F" gnus-summary-write-article-file
- "r" gnus-summary-save-article-rmail
- "f" gnus-summary-save-article-file
- "b" gnus-summary-save-article-body-file
- "B" gnus-summary-write-article-body-file
- "h" gnus-summary-save-article-folder
- "v" gnus-summary-save-article-vm
- "p" gnus-summary-pipe-output
- "P" gnus-summary-muttprint)
-
-(gnus-define-keys (gnus-summary-mime-map "K" gnus-summary-mode-map)
- "b" gnus-summary-display-buttonized
- "m" gnus-summary-repair-multipart
- "v" gnus-article-view-part
- "o" gnus-article-save-part
- "O" gnus-article-save-part-and-strip
- "r" gnus-article-replace-part
- "d" gnus-article-delete-part
- "t" gnus-article-view-part-as-type
- "j" gnus-article-jump-to-part
- "c" gnus-article-copy-part
- "C" gnus-article-view-part-as-charset
- "e" gnus-article-view-part-externally
- "H" gnus-article-browse-html-article
- "E" gnus-article-encrypt-body
- "i" gnus-article-inline-part
- "|" gnus-article-pipe-part)
-
-(gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map)
- "p" gnus-summary-mark-as-processable
- "u" gnus-summary-unmark-as-processable
- "U" gnus-summary-unmark-all-processable
- "v" gnus-uu-mark-over
- "s" gnus-uu-mark-series
- "r" gnus-uu-mark-region
- "g" gnus-uu-unmark-region
- "R" gnus-uu-mark-by-regexp
- "G" gnus-uu-unmark-by-regexp
- "t" gnus-uu-mark-thread
- "T" gnus-uu-unmark-thread
- "a" gnus-uu-mark-all
- "b" gnus-uu-mark-buffer
- "S" gnus-uu-mark-sparse
- "k" gnus-summary-kill-process-mark
- "y" gnus-summary-yank-process-mark
- "w" gnus-summary-save-process-mark
- "i" gnus-uu-invert-processable)
-
-(gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map)
- ;;"x" gnus-uu-extract-any
- "m" gnus-summary-save-parts
- "u" gnus-uu-decode-uu
- "U" gnus-uu-decode-uu-and-save
- "s" gnus-uu-decode-unshar
- "S" gnus-uu-decode-unshar-and-save
- "o" gnus-uu-decode-save
- "O" gnus-uu-decode-save
- "b" gnus-uu-decode-binhex
- "B" gnus-uu-decode-binhex
- "Y" gnus-uu-decode-yenc
- "p" gnus-uu-decode-postscript
- "P" gnus-uu-decode-postscript-and-save)
-
-(gnus-define-keys
- (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
- "u" gnus-uu-decode-uu-view
- "U" gnus-uu-decode-uu-and-save-view
- "s" gnus-uu-decode-unshar-view
- "S" gnus-uu-decode-unshar-and-save-view
- "o" gnus-uu-decode-save-view
- "O" gnus-uu-decode-save-view
- "b" gnus-uu-decode-binhex-view
- "B" gnus-uu-decode-binhex-view
- "p" gnus-uu-decode-postscript-view
- "P" gnus-uu-decode-postscript-and-save-view)
+ "\C-c\C-d" #'gnus-summary-describe-group
+ "\C-c\C-p" #'gnus-summary-make-group-from-search
+ "q" #'gnus-summary-exit
+ "Q" #'gnus-summary-exit-no-update
+ "\C-c\C-i" #'gnus-info-find-node
+ [mouse-2] #'gnus-mouse-pick-article
+ [follow-link] 'mouse-face
+ "m" #'gnus-summary-mail-other-window
+ "a" #'gnus-summary-post-news
+ "x" #'gnus-summary-limit-to-unread
+ "s" #'gnus-summary-isearch-article
+ "\t" #'gnus-summary-button-forward
+ [backtab] #'gnus-summary-button-backward
+ "w" #'gnus-summary-browse-url
+ "t" #'gnus-summary-toggle-header
+ "g" #'gnus-summary-show-article
+ "l" #'gnus-summary-goto-last-article
+ "\C-c\C-v\C-v" #'gnus-uu-decode-uu-view
+ "\C-d" #'gnus-summary-enter-digest-group
+ "\M-\C-d" #'gnus-summary-read-document
+ "\M-\C-e" #'gnus-summary-edit-parameters
+ "\M-\C-a" #'gnus-summary-customize-parameters
+ "\C-c\C-b" #'gnus-bug
+ "*" #'gnus-cache-enter-article
+ "\M-*" #'gnus-cache-remove-article
+ "\M-&" #'gnus-summary-universal-argument
+ "\C-l" #'gnus-recenter
+ "I" #'gnus-summary-increase-score
+ "L" #'gnus-summary-lower-score
+ "\M-i" #'gnus-symbolic-argument
+ "h" #'gnus-summary-select-article-buffer
+
+ "b" #'gnus-article-view-part
+ "\M-t" #'gnus-summary-toggle-display-buttonized
+
+ "S" #'gnus-summary-send-map
+
+ ;; Sort of orthogonal keymaps.
+ "M" (define-keymap :prefix 'gnus-summary-mark-map
+ "t" #'gnus-summary-tick-article-forward
+ "!" #'gnus-summary-tick-article-forward
+ "d" #'gnus-summary-mark-as-read-forward
+ "r" #'gnus-summary-mark-as-read-forward
+ "c" #'gnus-summary-clear-mark-forward
+ " " #'gnus-summary-clear-mark-forward
+ "e" #'gnus-summary-mark-as-expirable
+ "x" #'gnus-summary-mark-as-expirable
+ "?" #'gnus-summary-mark-as-dormant
+ "b" #'gnus-summary-set-bookmark
+ "B" #'gnus-summary-remove-bookmark
+ "#" #'gnus-summary-mark-as-processable
+ "\M-#" #'gnus-summary-unmark-as-processable
+ "S" #'gnus-summary-limit-include-expunged
+ "C" #'gnus-summary-catchup
+ "H" #'gnus-summary-catchup-to-here
+ "h" #'gnus-summary-catchup-from-here
+ "\C-c" #'gnus-summary-catchup-all
+ "k" #'gnus-summary-kill-same-subject-and-select
+ "K" #'gnus-summary-kill-same-subject
+
+ "P" (define-keymap :prefix 'gnus-uu-mark-map
+ "p" #'gnus-summary-mark-as-processable
+ "u" #'gnus-summary-unmark-as-processable
+ "U" #'gnus-summary-unmark-all-processable
+ "v" #'gnus-uu-mark-over
+ "s" #'gnus-uu-mark-series
+ "r" #'gnus-uu-mark-region
+ "g" #'gnus-uu-unmark-region
+ "R" #'gnus-uu-mark-by-regexp
+ "G" #'gnus-uu-unmark-by-regexp
+ "t" #'gnus-uu-mark-thread
+ "T" #'gnus-uu-unmark-thread
+ "a" #'gnus-uu-mark-all
+ "b" #'gnus-uu-mark-buffer
+ "S" #'gnus-uu-mark-sparse
+ "k" #'gnus-summary-kill-process-mark
+ "y" #'gnus-summary-yank-process-mark
+ "w" #'gnus-summary-save-process-mark
+ "i" #'gnus-uu-invert-processable)
+
+ "V" (define-keymap :prefix 'gnus-summary-mscore-map
+ "c" #'gnus-summary-clear-above
+ "u" #'gnus-summary-tick-above
+ "m" #'gnus-summary-mark-above
+ "k" #'gnus-summary-kill-below))
+
+ "/" (define-keymap :prefix 'gnus-summary-limit-map
+ "/" #'gnus-summary-limit-to-subject
+ "n" #'gnus-summary-limit-to-articles
+ "b" #'gnus-summary-limit-to-bodies
+ "h" #'gnus-summary-limit-to-headers
+ "w" #'gnus-summary-pop-limit
+ "s" #'gnus-summary-limit-to-subject
+ "a" #'gnus-summary-limit-to-author
+ "u" #'gnus-summary-limit-to-unread
+ "m" #'gnus-summary-limit-to-marks
+ "M" #'gnus-summary-limit-exclude-marks
+ "v" #'gnus-summary-limit-to-score
+ "*" #'gnus-summary-limit-include-cached
+ "D" #'gnus-summary-limit-include-dormant
+ "T" #'gnus-summary-limit-include-thread
+ "d" #'gnus-summary-limit-exclude-dormant
+ "t" #'gnus-summary-limit-to-age
+ "." #'gnus-summary-limit-to-unseen
+ "x" #'gnus-summary-limit-to-extra
+ "p" #'gnus-summary-limit-to-display-predicate
+ "E" #'gnus-summary-limit-include-expunged
+ "c" #'gnus-summary-limit-exclude-childless-dormant
+ "C" #'gnus-summary-limit-mark-excluded-as-read
+ "o" #'gnus-summary-insert-old-articles
+ "N" #'gnus-summary-insert-new-articles
+ "S" #'gnus-summary-limit-to-singletons
+ "r" #'gnus-summary-limit-to-replied
+ "R" #'gnus-summary-limit-to-recipient
+ "A" #'gnus-summary-limit-to-address)
+
+ "G" (define-keymap :prefix 'gnus-summary-goto-map
+ "n" #'gnus-summary-next-unread-article
+ "p" #'gnus-summary-prev-unread-article
+ "N" #'gnus-summary-next-article
+ "P" #'gnus-summary-prev-article
+ "\C-n" #'gnus-summary-next-same-subject
+ "\C-p" #'gnus-summary-prev-same-subject
+ "\M-n" #'gnus-summary-next-unread-subject
+ "\M-p" #'gnus-summary-prev-unread-subject
+ "f" #'gnus-summary-first-unread-article
+ "b" #'gnus-summary-best-unread-article
+ "u" #'gnus-summary-next-unseen-article
+ "U" #'gnus-summary-prev-unseen-article
+ "j" #'gnus-summary-goto-article
+ "g" #'gnus-summary-goto-subject
+ "l" #'gnus-summary-goto-last-article
+ "o" #'gnus-summary-pop-article)
+
+ "T" (define-keymap :prefix 'gnus-summary-thread-map
+ "k" #'gnus-summary-kill-thread
+ "E" #'gnus-summary-expire-thread
+ "l" #'gnus-summary-lower-thread
+ "i" #'gnus-summary-raise-thread
+ "T" #'gnus-summary-toggle-threads
+ "t" #'gnus-summary-rethread-current
+ "^" #'gnus-summary-reparent-thread
+ "\M-^" #'gnus-summary-reparent-children
+ "s" #'gnus-summary-show-thread
+ "S" #'gnus-summary-show-all-threads
+ "h" #'gnus-summary-hide-thread
+ "H" #'gnus-summary-hide-all-threads
+ "n" #'gnus-summary-next-thread
+ "p" #'gnus-summary-prev-thread
+ "u" #'gnus-summary-up-thread
+ "o" #'gnus-summary-top-thread
+ "d" #'gnus-summary-down-thread
+ "#" #'gnus-uu-mark-thread
+ "\M-#" #'gnus-uu-unmark-thread)
+
+ "Y" (define-keymap :prefix 'gnus-summary-buffer-map
+ "g" #'gnus-summary-prepare
+ "c" #'gnus-summary-insert-cached-articles
+ "d" #'gnus-summary-insert-dormant-articles
+ "t" #'gnus-summary-insert-ticked-articles)
+
+ "Z" (define-keymap :prefix 'gnus-summary-exit-map
+ "c" #'gnus-summary-catchup-and-exit
+ "C" #'gnus-summary-catchup-all-and-exit
+ "E" #'gnus-summary-exit-no-update
+ "Q" #'gnus-summary-exit
+ "Z" #'gnus-summary-exit
+ "n" #'gnus-summary-catchup-and-goto-next-group
+ "p" #'gnus-summary-catchup-and-goto-prev-group
+ "R" #'gnus-summary-reselect-current-group
+ "G" #'gnus-summary-rescan-group
+ "N" #'gnus-summary-next-group
+ "s" #'gnus-summary-save-newsrc
+ "P" #'gnus-summary-prev-group)
+
+ "A" (define-keymap :prefix 'gnus-summary-article-map
+ " " #'gnus-summary-next-page
+ "n" #'gnus-summary-next-page
+ [?\S-\ ] #'gnus-summary-prev-page
+ "\177" #'gnus-summary-prev-page
+ [delete] #'gnus-summary-prev-page
+ "p" #'gnus-summary-prev-page
+ "\r" #'gnus-summary-scroll-up
+ "\M-\r" #'gnus-summary-scroll-down
+ "<" #'gnus-summary-beginning-of-article
+ ">" #'gnus-summary-end-of-article
+ "b" #'gnus-summary-beginning-of-article
+ "e" #'gnus-summary-end-of-article
+ "^" #'gnus-summary-refer-parent-article
+ "r" #'gnus-summary-refer-parent-article
+ "C" #'gnus-summary-show-complete-article
+ "D" #'gnus-summary-enter-digest-group
+ "R" #'gnus-summary-refer-references
+ "T" #'gnus-summary-refer-thread
+ "W" #'gnus-warp-to-article
+ "g" #'gnus-summary-show-article
+ "s" #'gnus-summary-isearch-article
+ "\t" #'gnus-summary-button-forward
+ [backtab] #'gnus-summary-button-backward
+ "w" #'gnus-summary-browse-url
+ "P" #'gnus-summary-print-article
+ "S" #'gnus-sticky-article
+ "M" #'gnus-mailing-list-insinuate
+ "t" #'gnus-article-babel)
+
+ "W" (define-keymap :prefix 'gnus-summary-wash-map
+ "b" #'gnus-article-add-buttons
+ "B" #'gnus-article-add-buttons-to-head
+ "o" #'gnus-article-treat-overstrike
+ "e" #'gnus-article-emphasize
+ "w" #'gnus-article-fill-cited-article
+ "Q" #'gnus-article-fill-long-lines
+ "L" #'gnus-article-toggle-truncate-lines
+ "C" #'gnus-article-capitalize-sentences
+ "c" #'gnus-article-remove-cr
+ "q" #'gnus-article-de-quoted-unreadable
+ "6" #'gnus-article-de-base64-unreadable
+ "Z" #'gnus-article-decode-HZ
+ "A" #'gnus-article-treat-ansi-sequences
+ "h" #'gnus-article-wash-html
+ "u" #'gnus-article-unsplit-urls
+ "s" #'gnus-summary-force-verify-and-decrypt
+ "f" #'gnus-article-display-x-face
+ "l" #'gnus-summary-stop-page-breaking
+ "r" #'gnus-summary-caesar-message
+ "m" #'gnus-summary-morse-message
+ "t" #'gnus-summary-toggle-header
+ "g" #'gnus-treat-smiley
+ "v" #'gnus-summary-verbose-headers
+ "a" #'gnus-article-strip-headers-in-body ;; mnemonic: wash archive
+ "p" #'gnus-article-verify-x-pgp-sig
+ "d" #'gnus-article-treat-smartquotes
+ "U" #'gnus-article-treat-non-ascii
+ "i" #'gnus-summary-idna-message
+
+ "Y" (define-keymap :prefix 'gnus-summary-wash-deuglify-map
+ ;; mnemonic: deuglif*Y*
+ "u" #'gnus-article-outlook-unwrap-lines
+ "a" #'gnus-article-outlook-repair-attribution
+ "c" #'gnus-article-outlook-rearrange-citation
+ ;; mnemonic: full deuglify
+ "f" #'gnus-article-outlook-deuglify-article)
+
+ "W" (define-keymap :prefix 'gnus-summary-wash-hide-map
+ "a" #'gnus-article-hide
+ "h" #'gnus-article-hide-headers
+ "b" #'gnus-article-hide-boring-headers
+ "s" #'gnus-article-hide-signature
+ "c" #'gnus-article-hide-citation
+ "C" #'gnus-article-hide-citation-in-followups
+ "l" #'gnus-article-hide-list-identifiers
+ "B" #'gnus-article-strip-banner
+ "P" #'gnus-article-hide-pem
+ "\C-c" #'gnus-article-hide-citation-maybe)
+
+ "H" (define-keymap :prefix 'gnus-summary-wash-highlight-map
+ "a" #'gnus-article-highlight
+ "h" #'gnus-article-highlight-headers
+ "c" #'gnus-article-highlight-citation
+ "s" #'gnus-article-highlight-signature)
+
+ "G" (define-keymap :prefix 'gnus-summary-wash-header-map
+ "f" #'gnus-article-treat-fold-headers
+ "u" #'gnus-article-treat-unfold-headers
+ "n" #'gnus-article-treat-fold-newsgroups)
+
+ "D" (define-keymap :prefix 'gnus-summary-wash-display-map
+ "x" #'gnus-article-display-x-face
+ "d" #'gnus-article-display-face
+ "s" #'gnus-treat-smiley
+ "D" #'gnus-article-remove-images
+ "W" #'gnus-article-show-images
+ "F" #'gnus-article-toggle-fonts
+ "f" #'gnus-treat-from-picon
+ "m" #'gnus-treat-mail-picon
+ "n" #'gnus-treat-newsgroups-picon
+ "g" #'gnus-treat-from-gravatar
+ "h" #'gnus-treat-mail-gravatar)
+
+ "M" (define-keymap :prefix 'gnus-summary-wash-mime-map
+ "w" #'gnus-article-decode-mime-words
+ "c" #'gnus-article-decode-charset
+ "h" #'gnus-mime-buttonize-attachments-in-header
+ "v" #'gnus-mime-view-all-parts
+ "b" #'gnus-article-view-part)
+
+ "T" (define-keymap :prefix 'gnus-summary-wash-time-map
+ "z" #'gnus-article-date-ut
+ "u" #'gnus-article-date-ut
+ "l" #'gnus-article-date-local
+ "p" #'gnus-article-date-english
+ "e" #'gnus-article-date-lapsed
+ "o" #'gnus-article-date-original
+ "i" #'gnus-article-date-iso8601
+ "s" #'gnus-article-date-user)
+
+ "E" (define-keymap :prefix 'gnus-summary-wash-empty-map
+ "t" #'gnus-article-remove-trailing-blank-lines
+ "l" #'gnus-article-strip-leading-blank-lines
+ "m" #'gnus-article-strip-multiple-blank-lines
+ "a" #'gnus-article-strip-blank-lines
+ "A" #'gnus-article-strip-all-blank-lines
+ "s" #'gnus-article-strip-leading-space
+ "e" #'gnus-article-strip-trailing-space
+ "w" #'gnus-article-remove-leading-whitespace))
+
+ "H" (define-keymap :prefix 'gnus-summary-help-map
+ "v" #'gnus-version
+ "d" #'gnus-summary-describe-group
+ "h" #'gnus-summary-describe-briefly
+ "i" #'gnus-info-find-node)
+
+ "B" (define-keymap :prefix 'gnus-summary-backend-map
+ "e" #'gnus-summary-expire-articles
+ "\M-\C-e" #'gnus-summary-expire-articles-now
+ "\177" #'gnus-summary-delete-article
+ [delete] #'gnus-summary-delete-article
+ [backspace] #'gnus-summary-delete-article
+ "m" #'gnus-summary-move-article
+ "r" #'gnus-summary-respool-article
+ "w" #'gnus-summary-edit-article
+ "c" #'gnus-summary-copy-article
+ "B" #'gnus-summary-crosspost-article
+ "q" #'gnus-summary-respool-query
+ "t" #'gnus-summary-respool-trace
+ "i" #'gnus-summary-import-article
+ "I" #'gnus-summary-create-article
+ "p" #'gnus-summary-article-posted-p)
+
+ "O" (define-keymap :prefix 'gnus-summary-save-map
+ "o" #'gnus-summary-save-article
+ "m" #'gnus-summary-save-article-mail
+ "F" #'gnus-summary-write-article-file
+ "r" #'gnus-summary-save-article-rmail
+ "f" #'gnus-summary-save-article-file
+ "b" #'gnus-summary-save-article-body-file
+ "B" #'gnus-summary-write-article-body-file
+ "h" #'gnus-summary-save-article-folder
+ "v" #'gnus-summary-save-article-vm
+ "p" #'gnus-summary-pipe-output
+ "P" #'gnus-summary-muttprint)
+
+ "K" (define-keymap :prefix 'gnus-summary-mime-map
+ "b" #'gnus-summary-display-buttonized
+ "m" #'gnus-summary-repair-multipart
+ "v" #'gnus-article-view-part
+ "o" #'gnus-article-save-part
+ "O" #'gnus-article-save-part-and-strip
+ "r" #'gnus-article-replace-part
+ "d" #'gnus-article-delete-part
+ "t" #'gnus-article-view-part-as-type
+ "j" #'gnus-article-jump-to-part
+ "c" #'gnus-article-copy-part
+ "C" #'gnus-article-view-part-as-charset
+ "e" #'gnus-article-view-part-externally
+ "H" #'gnus-article-browse-html-article
+ "E" #'gnus-article-encrypt-body
+ "i" #'gnus-article-inline-part
+ "|" #'gnus-article-pipe-part)
+
+ "X" (define-keymap :prefix 'gnus-uu-extract-map
+ ;;"x" gnus-uu-extract-any
+ "m" #'gnus-summary-save-parts
+ "u" #'gnus-uu-decode-uu
+ "U" #'gnus-uu-decode-uu-and-save
+ "s" #'gnus-uu-decode-unshar
+ "S" #'gnus-uu-decode-unshar-and-save
+ "o" #'gnus-uu-decode-save
+ "O" #'gnus-uu-decode-save
+ "b" #'gnus-uu-decode-binhex
+ "B" #'gnus-uu-decode-binhex
+ "Y" #'gnus-uu-decode-yenc
+ "p" #'gnus-uu-decode-postscript
+ "P" #'gnus-uu-decode-postscript-and-save
+
+ "v" (define-keymap :prefix 'gnus-uu-extract-view-map
+ "u" #'gnus-uu-decode-uu-view
+ "U" #'gnus-uu-decode-uu-and-save-view
+ "s" #'gnus-uu-decode-unshar-view
+ "S" #'gnus-uu-decode-unshar-and-save-view
+ "o" #'gnus-uu-decode-save-view
+ "O" #'gnus-uu-decode-save-view
+ "b" #'gnus-uu-decode-binhex-view
+ "B" #'gnus-uu-decode-binhex-view
+ "p" #'gnus-uu-decode-postscript-view
+ "P" #'gnus-uu-decode-postscript-and-save-view)))
(defvar gnus-article-post-menu nil)
diff --git a/lisp/gnus/gnus-topic.el b/lisp/gnus/gnus-topic.el
index c8bcccdfdde..e78dd1542c8 100644
--- a/lisp/gnus/gnus-topic.el
+++ b/lisp/gnus/gnus-topic.el
@@ -1056,63 +1056,56 @@ articles in the topic and its subtopics."
;;; Topic mode, commands and keymap.
-(defvar gnus-topic-mode-map nil)
-(defvar gnus-group-topic-map nil)
-
-(unless gnus-topic-mode-map
- (setq gnus-topic-mode-map (make-sparse-keymap))
-
+(defvar-keymap gnus-topic-mode-map
;; Override certain group mode keys.
- (gnus-define-keys gnus-topic-mode-map
- "=" gnus-topic-select-group
- "\r" gnus-topic-select-group
- " " gnus-topic-read-group
- "\C-c\C-x" gnus-topic-expire-articles
- "c" gnus-topic-catchup-articles
- "\C-k" gnus-topic-kill-group
- "\C-y" gnus-topic-yank-group
- "\M-g" gnus-topic-get-new-news-this-topic
- "AT" gnus-topic-list-active
- "Gp" gnus-topic-edit-parameters
- "#" gnus-topic-mark-topic
- "\M-#" gnus-topic-unmark-topic
- [tab] gnus-topic-indent
- [(meta tab)] gnus-topic-unindent
- "\C-i" gnus-topic-indent
- "\M-\C-i" gnus-topic-unindent
- [mouse-2] gnus-mouse-pick-topic)
-
- ;; Define a new submap.
- (gnus-define-keys (gnus-group-topic-map "T" gnus-group-mode-map)
- "#" gnus-topic-mark-topic
- "\M-#" gnus-topic-unmark-topic
- "n" gnus-topic-create-topic
- "m" gnus-topic-move-group
- "D" gnus-topic-remove-group
- "c" gnus-topic-copy-group
- "h" gnus-topic-hide-topic
- "s" gnus-topic-show-topic
- "j" gnus-topic-jump-to-topic
- "M" gnus-topic-move-matching
- "C" gnus-topic-copy-matching
- "\M-p" gnus-topic-goto-previous-topic
- "\M-n" gnus-topic-goto-next-topic
- "\C-i" gnus-topic-indent
- [tab] gnus-topic-indent
- "r" gnus-topic-rename
- "\177" gnus-topic-delete
- [delete] gnus-topic-delete
- "H" gnus-topic-toggle-display-empty-topics)
-
- (gnus-define-keys (gnus-topic-sort-map "S" gnus-group-topic-map)
- "s" gnus-topic-sort-groups
- "a" gnus-topic-sort-groups-by-alphabet
- "u" gnus-topic-sort-groups-by-unread
- "l" gnus-topic-sort-groups-by-level
- "e" gnus-topic-sort-groups-by-server
- "v" gnus-topic-sort-groups-by-score
- "r" gnus-topic-sort-groups-by-rank
- "m" gnus-topic-sort-groups-by-method))
+ "=" #'gnus-topic-select-group
+ "\r" #'gnus-topic-select-group
+ " " #'gnus-topic-read-group
+ "\C-c\C-x" #'gnus-topic-expire-articles
+ "c" #'gnus-topic-catchup-articles
+ "\C-k" #'gnus-topic-kill-group
+ "\C-y" #'gnus-topic-yank-group
+ "\M-g" #'gnus-topic-get-new-news-this-topic
+ "AT" #'gnus-topic-list-active
+ "Gp" #'gnus-topic-edit-parameters
+ "#" #'gnus-topic-mark-topic
+ "\M-#" #'gnus-topic-unmark-topic
+ [tab] #'gnus-topic-indent
+ [(meta tab)] #'gnus-topic-unindent
+ "\C-i" #'gnus-topic-indent
+ "\M-\C-i" #'gnus-topic-unindent
+ [mouse-2] #'gnus-mouse-pick-topic
+
+ "T" (define-keymap :prefix 'gnus-group-topic-map
+ "#" #'gnus-topic-mark-topic
+ "\M-#" #'gnus-topic-unmark-topic
+ "n" #'gnus-topic-create-topic
+ "m" #'gnus-topic-move-group
+ "D" #'gnus-topic-remove-group
+ "c" #'gnus-topic-copy-group
+ "h" #'gnus-topic-hide-topic
+ "s" #'gnus-topic-show-topic
+ "j" #'gnus-topic-jump-to-topic
+ "M" #'gnus-topic-move-matching
+ "C" #'gnus-topic-copy-matching
+ "\M-p" #'gnus-topic-goto-previous-topic
+ "\M-n" #'gnus-topic-goto-next-topic
+ "\C-i" #'gnus-topic-indent
+ [tab] #'gnus-topic-indent
+ "r" #'gnus-topic-rename
+ "\177" #'gnus-topic-delete
+ [delete] #'gnus-topic-delete
+ "H" #'gnus-topic-toggle-display-empty-topics
+
+ "S" (define-keymap :prefix 'gnus-topic-sort-map
+ "s" #'gnus-topic-sort-groups
+ "a" #'gnus-topic-sort-groups-by-alphabet
+ "u" #'gnus-topic-sort-groups-by-unread
+ "l" #'gnus-topic-sort-groups-by-level
+ "e" #'gnus-topic-sort-groups-by-server
+ "v" #'gnus-topic-sort-groups-by-score
+ "r" #'gnus-topic-sort-groups-by-rank
+ "m" #'gnus-topic-sort-groups-by-method)))
(defun gnus-topic-make-menu-bar ()
(unless (boundp 'gnus-topic-menu)
diff --git a/lisp/gnus/gnus-undo.el b/lisp/gnus/gnus-undo.el
index 64ed2bbad6b..182c8743e09 100644
--- a/lisp/gnus/gnus-undo.el
+++ b/lisp/gnus/gnus-undo.el
@@ -75,15 +75,12 @@
;;; Minor mode definition.
-(defvar gnus-undo-mode-map
- (let ((map (make-sparse-keymap)))
- (gnus-define-keys map
- "\M-\C-_" gnus-undo
- "\C-_" gnus-undo
- "\C-xu" gnus-undo
- ;; many people are used to type `C-/' on X terminals and get `C-_'.
- [(control /)] gnus-undo)
- map))
+(defvar-keymap gnus-undo-mode-map
+ "\M-\C-_" #'gnus-undo
+ "\C-_" #'gnus-undo
+ "\C-xu" #'gnus-undo
+ ;; many people are used to type `C-/' on X terminals and get `C-_'.
+ [(control /)] #'gnus-undo)
(defun gnus-undo-make-menu-bar ()
;; This is disabled for the time being.
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index fb285962d6f..0163abad4b1 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -300,7 +300,7 @@ Symbols are also allowed; their print names are used instead."
(defmacro gnus-local-set-keys (&rest plist)
"Set the keys in PLIST in the current keymap."
- (declare (indent 1))
+ (declare (obsolete define-keymap "29.1") (indent 1))
`(gnus-define-keys-1 (current-local-map) ',plist))
(defmacro gnus-define-keys (keymap &rest plist)
@@ -310,12 +310,12 @@ Symbols are also allowed; their print names are used instead."
(defmacro gnus-define-keys-safe (keymap &rest plist)
"Define all keys in PLIST in KEYMAP without overwriting previous definitions."
- (declare (indent 1))
+ (declare (obsolete define-keymap "29.1") (indent 1))
`(gnus-define-keys-1 (quote ,keymap) (quote ,plist) t))
(defmacro gnus-define-keymap (keymap &rest plist)
"Define all keys in PLIST in KEYMAP."
- (declare (indent 1))
+ (declare (obsolete define-keymap "29.1") (indent 1))
`(gnus-define-keys-1 ,keymap (quote ,plist)))
(defun gnus-define-keys-1 (keymap plist &optional safe)
@@ -1310,9 +1310,7 @@ SPEC is a predicate specifier that contains stuff like `or', `and',
initial-input history def)
"Call `gnus-completing-read-function'."
(funcall gnus-completing-read-function
- (concat prompt (when def
- (concat " (default " def ")"))
- ": ")
+ (format-prompt prompt def)
collection require-match initial-input history def))
(defun gnus-emacs-completing-read (prompt collection &optional require-match
diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el
index f558360361d..6644cc4d814 100644
--- a/lisp/gnus/gnus.el
+++ b/lisp/gnus/gnus.el
@@ -2537,7 +2537,7 @@ are always t.")
;; Only used in gnus-util, which has an autoload.
("rmailsum" rmail-update-summary)
("gnus-xmas" gnus-xmas-splash)
- ("score-mode" :interactive t gnus-score-mode)
+ ("score-mode" :interactive t gnus-score-mode gnus-score-edit-all-score)
("gnus-mh" gnus-summary-save-article-folder
gnus-Folder-save-name gnus-folder-save-name)
("gnus-mh" :interactive (gnus-summary-mode) gnus-summary-save-in-folder)
@@ -2609,7 +2609,11 @@ are always t.")
gnus-uu-decode-uu-and-save-view gnus-uu-decode-unshar-view
gnus-uu-decode-unshar-and-save-view gnus-uu-decode-save-view
gnus-uu-decode-binhex-view gnus-uu-unmark-thread
- gnus-uu-mark-over gnus-uu-post-news gnus-uu-invert-processable)
+ gnus-uu-mark-over gnus-uu-post-news gnus-uu-invert-processable
+ gnus-uu-decode-postscript-and-save-view
+ gnus-uu-decode-postscript-view gnus-uu-decode-postscript-and-save
+ gnus-uu-decode-yenc gnus-uu-unmark-by-regexp gnus-uu-unmark-region
+ gnus-uu-decode-postscript)
("gnus-uu" gnus-uu-delete-work-dir gnus-uu-unmark-thread)
("gnus-msg" (gnus-summary-send-map keymap)
gnus-article-mail gnus-copy-article-buffer gnus-extended-version)
@@ -2667,7 +2671,34 @@ are always t.")
gnus-article-edit-mode gnus-article-edit-article
gnus-article-edit-done gnus-article-decode-encoded-words
gnus-start-date-timer gnus-stop-date-timer
- gnus-mime-view-all-parts)
+ gnus-mime-view-all-parts gnus-article-pipe-part
+ gnus-article-inline-part gnus-article-encrypt-body
+ gnus-article-browse-html-article gnus-article-view-part-externally
+ gnus-article-view-part-as-charset gnus-article-copy-part
+ gnus-article-jump-to-part gnus-article-view-part-as-type
+ gnus-article-delete-part gnus-article-replace-part
+ gnus-article-save-part-and-strip gnus-article-save-part
+ gnus-article-remove-leading-whitespace gnus-article-strip-trailing-space
+ gnus-article-strip-leading-space gnus-article-strip-all-blank-lines
+ gnus-article-strip-blank-lines gnus-article-strip-multiple-blank-lines
+ gnus-article-date-user gnus-article-date-iso8601
+ gnus-article-date-english gnus-article-date-ut
+ gnus-article-decode-charset gnus-article-decode-mime-words
+ gnus-article-toggle-fonts gnus-article-show-images
+ gnus-article-remove-images gnus-article-display-face
+ gnus-article-treat-fold-newsgroups gnus-article-treat-unfold-headers
+ gnus-article-treat-fold-headers gnus-article-highlight-signature
+ gnus-article-highlight-headers gnus-article-highlight
+ gnus-article-strip-banner gnus-article-hide-list-identifiers
+ gnus-article-hide gnus-article-outlook-rearrange-citation
+ gnus-article-treat-non-ascii gnus-article-treat-smartquotes
+ gnus-article-verify-x-pgp-sig gnus-article-strip-headers-in-body
+ gnus-treat-smiley gnus-article-treat-ansi-sequences
+ gnus-article-capitalize-sentences gnus-article-toggle-truncate-lines
+ gnus-article-fill-long-lines gnus-article-emphasize
+ gnus-article-add-buttons-to-head gnus-article-add-button
+ gnus-article-babel gnus-sticky-article gnus-article-view-part
+ gnus-article-add-buttons)
("gnus-int" gnus-request-type)
("gnus-start" gnus-newsrc-parse-options gnus-1 gnus-no-server-1
gnus-dribble-enter gnus-read-init-file gnus-dribble-touch
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index d460f9bd922..e165a0429fd 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -2868,84 +2868,78 @@ Consider adding this function to `message-header-setup-hook'"
;;; Set up keymap.
-(defvar message-mode-map nil)
-
-(unless message-mode-map
- (setq message-mode-map (make-keymap))
- (set-keymap-parent message-mode-map text-mode-map)
- (define-key message-mode-map "\C-c?" #'describe-mode)
-
- (define-key message-mode-map "\C-c\C-f\C-t" #'message-goto-to)
- (define-key message-mode-map "\C-c\C-f\C-o" #'message-goto-from)
- (define-key message-mode-map "\C-c\C-f\C-b" #'message-goto-bcc)
- (define-key message-mode-map "\C-c\C-f\C-w" #'message-goto-fcc)
- (define-key message-mode-map "\C-c\C-f\C-c" #'message-goto-cc)
- (define-key message-mode-map "\C-c\C-f\C-s" #'message-goto-subject)
- (define-key message-mode-map "\C-c\C-f\C-r" #'message-goto-reply-to)
- (define-key message-mode-map "\C-c\C-f\C-n" #'message-goto-newsgroups)
- (define-key message-mode-map "\C-c\C-f\C-d" #'message-goto-distribution)
- (define-key message-mode-map "\C-c\C-f\C-f" #'message-goto-followup-to)
- (define-key message-mode-map "\C-c\C-f\C-m" #'message-goto-mail-followup-to)
- (define-key message-mode-map "\C-c\C-f\C-k" #'message-goto-keywords)
- (define-key message-mode-map "\C-c\C-f\C-u" #'message-goto-summary)
- (define-key message-mode-map "\C-c\C-f\C-i"
- #'message-insert-or-toggle-importance)
- (define-key message-mode-map "\C-c\C-f\C-a"
- #'message-generate-unsubscribed-mail-followup-to)
+(defvar-keymap message-mode-map
+ :full t :parent text-mode-map
+ :doc "Message Mode keymap."
+ "\C-c?" #'describe-mode
+
+ "\C-c\C-f\C-t" #'message-goto-to
+ "\C-c\C-f\C-o" #'message-goto-from
+ "\C-c\C-f\C-b" #'message-goto-bcc
+ "\C-c\C-f\C-w" #'message-goto-fcc
+ "\C-c\C-f\C-c" #'message-goto-cc
+ "\C-c\C-f\C-s" #'message-goto-subject
+ "\C-c\C-f\C-r" #'message-goto-reply-to
+ "\C-c\C-f\C-n" #'message-goto-newsgroups
+ "\C-c\C-f\C-d" #'message-goto-distribution
+ "\C-c\C-f\C-f" #'message-goto-followup-to
+ "\C-c\C-f\C-m" #'message-goto-mail-followup-to
+ "\C-c\C-f\C-k" #'message-goto-keywords
+ "\C-c\C-f\C-u" #'message-goto-summary
+ "\C-c\C-f\C-i" #'message-insert-or-toggle-importance
+ "\C-c\C-f\C-a" #'message-generate-unsubscribed-mail-followup-to
;; modify headers (and insert notes in body)
- (define-key message-mode-map "\C-c\C-fs" #'message-change-subject)
+ "\C-c\C-fs" #'message-change-subject
;;
- (define-key message-mode-map "\C-c\C-fx" #'message-cross-post-followup-to)
+ "\C-c\C-fx" #'message-cross-post-followup-to
;; prefix+message-cross-post-followup-to = same w/o cross-post
- (define-key message-mode-map "\C-c\C-ft" #'message-reduce-to-to-cc)
- (define-key message-mode-map "\C-c\C-fa" #'message-add-archive-header)
+ "\C-c\C-ft" #'message-reduce-to-to-cc
+ "\C-c\C-fa" #'message-add-archive-header
;; mark inserted text
- (define-key message-mode-map "\C-c\M-m" #'message-mark-inserted-region)
- (define-key message-mode-map "\C-c\M-f" #'message-mark-insert-file)
-
- (define-key message-mode-map "\C-c\C-b" #'message-goto-body)
- (define-key message-mode-map "\C-c\C-i" #'message-goto-signature)
-
- (define-key message-mode-map "\C-c\C-t" #'message-insert-to)
- (define-key message-mode-map "\C-c\C-fw" #'message-insert-wide-reply)
- (define-key message-mode-map "\C-c\C-n" #'message-insert-newsgroups)
- (define-key message-mode-map "\C-c\C-l" #'message-to-list-only)
- (define-key message-mode-map "\C-c\C-f\C-e" #'message-insert-expires)
-
- (define-key message-mode-map "\C-c\C-u" #'message-insert-or-toggle-importance)
- (define-key message-mode-map "\C-c\M-n"
- #'message-insert-disposition-notification-to)
-
- (define-key message-mode-map "\C-c\C-y" #'message-yank-original)
- (define-key message-mode-map "\C-c\M-\C-y" #'message-yank-buffer)
- (define-key message-mode-map "\C-c\C-q" #'message-fill-yanked-message)
- (define-key message-mode-map "\C-c\C-w" #'message-insert-signature)
- (define-key message-mode-map "\C-c\M-h" #'message-insert-headers)
- (define-key message-mode-map "\C-c\C-r" #'message-caesar-buffer-body)
- (define-key message-mode-map "\C-c\C-o" #'message-sort-headers)
- (define-key message-mode-map "\C-c\M-r" #'message-rename-buffer)
-
- (define-key message-mode-map "\C-c\C-c" #'message-send-and-exit)
- (define-key message-mode-map "\C-c\C-s" #'message-send)
- (define-key message-mode-map "\C-c\C-k" #'message-kill-buffer)
- (define-key message-mode-map "\C-c\C-d" #'message-dont-send)
- (define-key message-mode-map "\C-c\n" #'gnus-delay-article)
-
- (define-key message-mode-map "\C-c\M-k" #'message-kill-address)
- (define-key message-mode-map "\C-c\C-e" #'message-elide-region)
- (define-key message-mode-map "\C-c\C-v" #'message-delete-not-region)
- (define-key message-mode-map "\C-c\C-z" #'message-kill-to-signature)
- (define-key message-mode-map "\M-\r" #'message-newline-and-reformat)
- (define-key message-mode-map [remap split-line] #'message-split-line)
-
- (define-key message-mode-map "\C-c\C-a" #'mml-attach-file)
- (define-key message-mode-map "\C-c\C-p" #'message-insert-screenshot)
-
- (define-key message-mode-map "\C-a" #'message-beginning-of-line)
- (define-key message-mode-map "\t" #'message-tab)
-
- (define-key message-mode-map "\M-n" #'message-display-abbrev))
+ "\C-c\M-m" #'message-mark-inserted-region
+ "\C-c\M-f" #'message-mark-insert-file
+
+ "\C-c\C-b" #'message-goto-body
+ "\C-c\C-i" #'message-goto-signature
+
+ "\C-c\C-t" #'message-insert-to
+ "\C-c\C-fw" #'message-insert-wide-reply
+ "\C-c\C-n" #'message-insert-newsgroups
+ "\C-c\C-l" #'message-to-list-only
+ "\C-c\C-f\C-e" #'message-insert-expires
+ "\C-c\C-u" #'message-insert-or-toggle-importance
+ "\C-c\M-n" #'message-insert-disposition-notification-to
+
+ "\C-c\C-y" #'message-yank-original
+ "\C-c\M-\C-y" #'message-yank-buffer
+ "\C-c\C-q" #'message-fill-yanked-message
+ "\C-c\C-w" #'message-insert-signature
+ "\C-c\M-h" #'message-insert-headers
+ "\C-c\C-r" #'message-caesar-buffer-body
+ "\C-c\C-o" #'message-sort-headers
+ "\C-c\M-r" #'message-rename-buffer
+
+ "\C-c\C-c" #'message-send-and-exit
+ "\C-c\C-s" #'message-send
+ "\C-c\C-k" #'message-kill-buffer
+ "\C-c\C-d" #'message-dont-send
+ "\C-c\n" #'gnus-delay-article
+
+ "\C-c\M-k" #'message-kill-address
+ "\C-c\C-e" #'message-elide-region
+ "\C-c\C-v" #'message-delete-not-region
+ "\C-c\C-z" #'message-kill-to-signature
+ "\M-\r" #'message-newline-and-reformat
+ [remap split-line] #'message-split-line
+
+ "\C-c\C-a" #'mml-attach-file
+ "\C-c\C-p" #'message-insert-screenshot
+
+ "\C-a" #'message-beginning-of-line
+ "\t" #'message-tab
+
+ "\M-n" #'message-display-abbrev)
(easy-menu-define
message-mode-menu message-mode-map "Message Menu."
@@ -5356,7 +5350,7 @@ Otherwise, generate and save a value for `canlock-password' first."
(zerop
(length
(setq to (completing-read
- "Followups to (default no Followup-To header): "
+ (format-prompt "Followups to" "no Followup-To header")
(mapcar #'list
(cons "poster"
(message-tokenize-header
diff --git a/lisp/gnus/spam.el b/lisp/gnus/spam.el
index d00f0a60b66..cfef69f1031 100644
--- a/lisp/gnus/spam.el
+++ b/lisp/gnus/spam.el
@@ -663,13 +663,13 @@ order for SpamAssassin to recognize the new registered spam."
;;; Key bindings for spam control.
-(gnus-define-keys gnus-summary-mode-map
- "St" spam-generic-score
- "Sx" gnus-summary-mark-as-spam
- "Mst" spam-generic-score
- "Msx" gnus-summary-mark-as-spam
- "\M-d" gnus-summary-mark-as-spam
- "$" gnus-summary-mark-as-spam)
+(define-keymap :keymap gnus-summary-mode-map
+ "St" #'spam-generic-score
+ "Sx" #'gnus-summary-mark-as-spam
+ "Mst" #'spam-generic-score
+ "Msx" #'gnus-summary-mark-as-spam
+ "\M-d" #'gnus-summary-mark-as-spam
+ "$" #'gnus-summary-mark-as-spam)
(defvar spam-cache-lookups t
"Whether spam.el will try to cache lookups using `spam-caches'.")
diff --git a/lisp/help-mode.el b/lisp/help-mode.el
index 0b404fe89f1..d61b1bdc624 100644
--- a/lisp/help-mode.el
+++ b/lisp/help-mode.el
@@ -273,6 +273,10 @@ The format is (FUNCTION ARGS...).")
(when (or (< position (point-min))
(> position (point-max)))
(widen))
+ ;; Save mark for the old location, unless the point is not
+ ;; actually going to move.
+ (unless (= (point) position)
+ (push-mark nil t))
(goto-char position))
(message "Unable to find location in file")))))
diff --git a/lisp/image-dired.el b/lisp/image-dired.el
index 3ca47300a99..ec3f988bfbb 100644
--- a/lisp/image-dired.el
+++ b/lisp/image-dired.el
@@ -1433,6 +1433,14 @@ dired."
(interactive)
(image-dired-modify-mark-on-thumb-original-file 'toggle))
+(defun image-dired-unmark-all-marks ()
+ "Remove all marks from all files.
+Do this in the Dired buffer and update this thumbnail buffer."
+ (interactive)
+ (with-current-buffer (image-dired-associated-dired-buffer)
+ (dired-unmark-all-marks))
+ (image-dired-thumb-update-marks))
+
(defun image-dired-jump-original-dired-buffer ()
"Jump to the dired buffer associated with the current image file.
You probably want to use this together with
@@ -1536,6 +1544,7 @@ You probably want to use this together with
["Quit" quit-window]
["Delete thumbnail from buffer" image-dired-delete-char]
["Delete marked images" image-dired-delete-marked]
+ ["Unmark all marks" image-dired-unmark-all-marks]
["Remove tag from current or marked thumbnails"
image-dired-tag-thumbnail-remove]
["Tag current or marked thumbnails" image-dired-tag-thumbnail]
diff --git a/lisp/info-look.el b/lisp/info-look.el
index cc6a806f56f..309f2e8d631 100644
--- a/lisp/info-look.el
+++ b/lisp/info-look.el
@@ -43,6 +43,7 @@
(require 'info)
(eval-when-compile (require 'subr-x))
+(eval-when-compile (require 'cl-lib))
(defgroup info-lookup nil
"Major mode sensitive help agent."
@@ -123,6 +124,14 @@ OTHER-MODES is a list of cross references to other help modes.")
(defsubst info-lookup->mode-value (topic mode)
(assoc mode (info-lookup->topic-value topic)))
+(defun info-lookup--expand-info (info)
+ ;; We have a dynamic doc-spec function.
+ (when (and (null (nth 3 info))
+ (nth 6 info))
+ (setf (nth 3 info) (funcall (nth 6 info))
+ (nth 6 info) nil))
+ info)
+
(defsubst info-lookup->regexp (topic mode)
(nth 1 (info-lookup->mode-value topic mode)))
@@ -145,7 +154,11 @@ Function arguments are specified as keyword/argument pairs:
(KEYWORD . ARGUMENT)
KEYWORD is either `:topic', `:mode', `:regexp', `:ignore-case',
- `:doc-spec', `:parse-rule', or `:other-modes'.
+ `:doc-spec', `:parse-rule', `:other-modes' or `:doc-spec-function'.
+ `:doc-spec-function' is used to compute a `:doc-spec', but instead of
+ doing so at load time, this is done when the user asks for info on
+ the mode in question.
+
ARGUMENT has a value as explained in the documentation of the
variable `info-lookup-alist'.
@@ -161,7 +174,8 @@ for more details."
(defun info-lookup-add-help* (maybe &rest arg)
(let (topic mode regexp ignore-case doc-spec
- parse-rule other-modes keyword value)
+ parse-rule other-modes keyword value
+ doc-spec-function)
(setq topic 'symbol
mode major-mode
regexp "\\w+")
@@ -184,6 +198,8 @@ for more details."
(setq ignore-case value))
((eq keyword :doc-spec)
(setq doc-spec value))
+ ((eq keyword :doc-spec-function)
+ (setq doc-spec-function value))
((eq keyword :parse-rule)
(setq parse-rule value))
((eq keyword :other-modes)
@@ -191,7 +207,8 @@ for more details."
(t
(error "Unknown keyword \"%S\"" keyword))))
(or (and maybe (info-lookup->mode-value topic mode))
- (let* ((data (list regexp ignore-case doc-spec parse-rule other-modes))
+ (let* ((data (list regexp ignore-case doc-spec parse-rule other-modes
+ doc-spec-function))
(topic-cell (or (assoc topic info-lookup-alist)
(car (setq info-lookup-alist
(cons (cons topic nil)
@@ -344,8 +361,9 @@ If optional argument QUERY is non-nil, query for the help mode."
(defun info-lookup (topic item mode)
"Display the documentation of a help item."
(or mode (setq mode (info-lookup-select-mode)))
- (or (info-lookup->mode-value topic mode)
- (error "No %s help available for `%s'" topic mode))
+ (if-let ((info (info-lookup->mode-value topic mode)))
+ (info-lookup--expand-info info)
+ (error "No %s help available for `%s'" topic mode))
(let* ((completions (info-lookup->completions topic mode))
(ignore-case (info-lookup->ignore-case topic mode))
(entry (or (assoc (if ignore-case (downcase item) item) completions)
@@ -724,6 +742,8 @@ Return nil if there is nothing appropriate in the buffer near point."
(defun info-complete (topic mode)
"Try to complete a help item."
(barf-if-buffer-read-only)
+ (when-let ((info (info-lookup->mode-value topic mode)))
+ (info-lookup--expand-info info))
(let ((data (info-lookup-completions-at-point topic mode)))
(if (null data)
(error "No %s completion available for `%s' at point" topic mode)
@@ -904,9 +924,16 @@ Return nil if there is nothing appropriate in the buffer near point."
(info-lookup-maybe-add-help
:mode 'python-mode
- :doc-spec `((,(if (Info-find-file "python3.9" t)
- "(python3.9)Index"
- "(python)Index"))))
+ ;; Debian includes Python info files, but they're version-named
+ ;; instead of having a symlink.
+ :doc-spec-function (lambda ()
+ (list
+ (list
+ (cl-loop for version from 20 downto 7
+ for name = (format "python3.%d" version)
+ if (Info-find-file name t)
+ return (format "(%s)Index" name)
+ finally return "(python)Index")))))
(info-lookup-maybe-add-help
:mode 'cperl-mode
diff --git a/lisp/info.el b/lisp/info.el
index 8c08eaec3c8..41889d6de17 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -2604,12 +2604,9 @@ new buffer."
(if (eq (length completions) 1)
(setq default (car completions)))
(if completions
- (let ((input (completing-read (if default
- (concat
- "Follow reference named (default "
- default "): ")
- "Follow reference named: ")
- completions nil t)))
+ (let ((input (completing-read (format-prompt "Follow reference named"
+ default)
+ completions nil t)))
(list (if (equal input "")
default input)
current-prefix-arg))
diff --git a/lisp/international/mule-diag.el b/lisp/international/mule-diag.el
index 862c577bd5d..5cc73e43671 100644
--- a/lisp/international/mule-diag.el
+++ b/lisp/international/mule-diag.el
@@ -833,7 +833,7 @@ The IGNORED argument is ignored."
"Display information about a font whose name is FONTNAME."
(interactive
(list (completing-read
- "Font name (default current choice for ASCII chars): "
+ (format-prompt "Font name" "current choice for ASCII chars")
(and window-system
;; Implied by `window-system'.
(fboundp 'x-list-fonts)
@@ -1004,7 +1004,7 @@ This shows which font is used for which character(s)."
(mapcar 'cdr fontset-alias-alist)))
(completion-ignore-case t))
(list (completing-read
- "Fontset (default used by the current frame): "
+ (format-prompt "Fontset" "used by the current frame")
fontset-list nil t)))))
(if (= (length fontset) 0)
(setq fontset (face-attribute 'default :fontset))
diff --git a/lisp/international/quail.el b/lisp/international/quail.el
index 50ff307b73a..89ab450aeee 100644
--- a/lisp/international/quail.el
+++ b/lisp/international/quail.el
@@ -917,7 +917,7 @@ The format of KBD-LAYOUT is the same as `quail-keyboard-layout'."
The variable `quail-keyboard-layout-type' holds the currently selected
keyboard type."
(interactive
- (list (completing-read "Keyboard type (default current choice): "
+ (list (completing-read (format-prompt "Keyboard type" "current choice")
quail-keyboard-layout-alist
nil t)))
(or (and keyboard-type (> (length keyboard-type) 0))
diff --git a/lisp/language/cyril-util.el b/lisp/language/cyril-util.el
index 04e681d743d..e404288ddca 100644
--- a/lisp/language/cyril-util.el
+++ b/lisp/language/cyril-util.el
@@ -60,7 +60,7 @@ If the argument is nil, we return the display table to its standard state."
(list
(let* ((completion-ignore-case t))
(completing-read
- "Cyrillic language (default nil): "
+ (format-prompt "Cyrillic language" "nil")
cyrillic-language-alist nil t nil nil nil))))
(or standard-display-table
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index c452825e6d3..47d251f3b56 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -11134,6 +11134,22 @@ Kill all test buffers that are still live." t nil)
;;;***
+;;;### (autoloads nil "erts-mode" "progmodes/erts-mode.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from progmodes/erts-mode.el
+
+(autoload 'erts-mode "erts-mode" "\
+Major mode for editing erts (Emacs testing) files.
+This mode mainly provides some font locking.
+
+\\{erts-mode-map}
+
+\(fn)" t nil)
+
+(register-definition-prefixes "erts-mode" '("erts-"))
+
+;;;***
+
;;;### (autoloads nil "esh-arg" "eshell/esh-arg.el" (0 0 0 0))
;;; Generated autoloads from eshell/esh-arg.el
@@ -11559,7 +11575,7 @@ for \\[find-tag] (which see)." t nil)
(autoload 'etags--xref-backend "etags" nil nil nil)
-(register-definition-prefixes "etags" '("default-tags-table-function" "etags-" "file-of-tag" "find-tag-" "goto-tag-location-function" "initialize-new-tags-table" "last-tag" "list-tags-function" "select-tags-table-" "snarf-tag-function" "tag" "verify-tags-table-function"))
+(register-definition-prefixes "etags" '("default-tags-table-function" "etags-" "file-of-tag" "find-tag-" "goto-tag-location-function" "initialize-new-tags-table" "last-tag" "list-tags-function" "select-tags-table-" "snarf-tag-function" "tag" "verify-tags-table-function" "xref-"))
;;;***
diff --git a/lisp/mail/rmailkwd.el b/lisp/mail/rmailkwd.el
index 58a8eb7a370..d8fcc1c0a99 100644
--- a/lisp/mail/rmailkwd.el
+++ b/lisp/mail/rmailkwd.el
@@ -74,12 +74,9 @@ according to the choice made, and returns a symbol."
(rmail-summary-exists)
(and (setq old (rmail-get-keywords))
(mapc #'rmail-make-label (split-string old ", "))))
- (completing-read (concat prompt
- (if rmail-last-label
- (concat " (default "
- (symbol-name rmail-last-label)
- "): ")
- ": "))
+ (completing-read (format-prompt prompt
+ (and rmail-last-label
+ (symbol-name rmail-last-label)))
rmail-label-obarray
nil
nil))))
diff --git a/lisp/mail/rmailmm.el b/lisp/mail/rmailmm.el
index 99bff66657b..66a1e9a4dbd 100644
--- a/lisp/mail/rmailmm.el
+++ b/lisp/mail/rmailmm.el
@@ -254,7 +254,7 @@ TRUNCATED is non-nil if the text of this entity was truncated."))
(unless (y-or-n-p "This entity is truncated; save anyway? ")
(error "Aborted")))
(setq filename (expand-file-name
- (read-file-name (format "Save as (default: %s): " filename)
+ (read-file-name (format-prompt "Save as" filename)
directory
(expand-file-name filename directory))
directory))
diff --git a/lisp/mail/rmailout.el b/lisp/mail/rmailout.el
index 91f86a234d4..1f5bb2d9f1b 100644
--- a/lisp/mail/rmailout.el
+++ b/lisp/mail/rmailout.el
@@ -107,9 +107,8 @@ error: %S\n"
(read-file
(expand-file-name
(read-file-name
- (concat "Output message to mail file (default "
- (file-name-nondirectory default-file)
- "): ")
+ (format-prompt "Output message to mail file"
+ (file-name-nondirectory default-file))
(file-name-directory default-file)
(abbreviate-file-name default-file))
(file-name-directory default-file))))
diff --git a/lisp/man.el b/lisp/man.el
index 4ef2deac4f3..2bde1fc7fb2 100644
--- a/lisp/man.el
+++ b/lisp/man.el
@@ -1786,7 +1786,7 @@ Returns t if section is found, nil otherwise."
Man--last-section
(car Man--sections)))
(completion-ignore-case t)
- (prompt (concat "Go to section (default " default "): "))
+ (prompt (format-prompt "Go to section" default))
(chosen (completing-read prompt Man--sections
nil nil nil nil default)))
(list chosen))
@@ -1850,7 +1850,7 @@ Specify which REFERENCE to use; default is based on word at point."
(defaults
(mapcar 'substring-no-properties
(cons default Man--refpages)))
- (prompt (concat "Refer to (default " default "): "))
+ (prompt (format-prompt "Refer to" default))
(chosen (completing-read prompt Man--refpages
nil nil nil nil defaults)))
chosen)))
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index b2577c085fc..40a1730637d 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -1918,10 +1918,7 @@ key, a click, or a menu-item"))
(let* ((default (thing-at-point 'sexp))
(topic
(read-from-minibuffer
- (format "Subject to look up%s: "
- (if default
- (format " (default \"%s\")" default)
- ""))
+ (format-prompt "Subject to look up" default)
nil nil nil nil default)))
(list (if (zerop (length topic))
default
diff --git a/lisp/mh-e/mh-acros.el b/lisp/mh-e/mh-acros.el
index 8fdcf3c62b4..5ea7bca6f9f 100644
--- a/lisp/mh-e/mh-acros.el
+++ b/lisp/mh-e/mh-acros.el
@@ -53,7 +53,7 @@
;;;###mh-autoload
(defmacro mh-do-in-xemacs (&rest body)
"Execute BODY if in XEmacs."
- (declare (debug t) (indent defun))
+ (declare (obsolete nil "29.1") (debug t) (indent defun))
(when (featurep 'xemacs) `(progn ,@body)))
;;;###mh-autoload
@@ -105,14 +105,11 @@ XEmacs and versions of GNU Emacs before 21.1 require
;;;###mh-autoload
(defmacro mh-mark-active-p (check-transient-mark-mode-flag)
- "A macro that expands into appropriate code in XEmacs and nil in GNU Emacs.
-In GNU Emacs if CHECK-TRANSIENT-MARK-MODE-FLAG is non-nil then
-check if variable `transient-mark-mode' is active."
- (cond ((featurep 'xemacs) ;XEmacs
- '(and (boundp 'zmacs-regions) zmacs-regions (region-active-p)))
- ((not check-transient-mark-mode-flag) ;GNU Emacs
+ "If CHECK-TRANSIENT-MARK-MODE-FLAG is non-nil then check if
+variable `transient-mark-mode' is active."
+ (cond ((not check-transient-mark-mode-flag)
'(and (boundp 'mark-active) mark-active))
- (t ;GNU Emacs
+ (t
'(and (boundp 'transient-mark-mode) transient-mark-mode
(boundp 'mark-active) mark-active))))
diff --git a/lisp/mh-e/mh-comp.el b/lisp/mh-e/mh-comp.el
index 404b6b3ce75..1eacc505898 100644
--- a/lisp/mh-e/mh-comp.el
+++ b/lisp/mh-e/mh-comp.el
@@ -1077,7 +1077,6 @@ letter."
;; Insert identity.
(mh-insert-identity mh-identity-default t)
(mh-identity-make-menu)
- (mh-identity-add-menu)
;; Cleanup possibly RFC2047 encoded subject header
(mh-decode-message-subject)
@@ -1107,18 +1106,8 @@ The versions of MH-E, Emacs, and MH are shown."
;; Lazily initialize mh-x-mailer-string.
(when (and mh-insert-x-mailer-flag (null mh-x-mailer-string))
(setq mh-x-mailer-string
- (format "MH-E %s; %s; %sEmacs %s"
- mh-version mh-variant-in-use
- (if (featurep 'xemacs) "X" "GNU ")
- (cond ((not (featurep 'xemacs))
- (string-match "[0-9]+\\.[0-9]+\\(\\.[0-9]+\\)?"
- emacs-version)
- (match-string 0 emacs-version))
- ((string-match "[0-9.]*\\( +([ a-z]+[0-9]+)\\)?"
- emacs-version)
- (match-string 0 emacs-version))
- (t (format "%s.%s" emacs-major-version
- emacs-minor-version))))))
+ (format "MH-E %s; %s; Emacs %s"
+ mh-version mh-variant-in-use emacs-version)))
;; Insert X-Mailer, but only if it doesn't already exist.
(save-excursion
(when (and mh-insert-x-mailer-flag
diff --git a/lisp/mh-e/mh-compat.el b/lisp/mh-e/mh-compat.el
index ade80e8b95e..26e5576fe64 100644
--- a/lisp/mh-e/mh-compat.el
+++ b/lisp/mh-e/mh-compat.el
@@ -42,21 +42,6 @@
(mh-do-in-gnu-emacs
(defalias 'mh-require #'require))
-(mh-do-in-xemacs
- (defun mh-require (feature &optional filename noerror)
- "If feature FEATURE is not loaded, load it from FILENAME.
-If FEATURE is not a member of the list `features', then the feature
-is not loaded; so load the file FILENAME.
-If FILENAME is omitted, the printname of FEATURE is used as the file name.
-If the optional third argument NOERROR is non-nil,
-then return nil if the file is not found instead of signaling an error.
-
-Simulate NOERROR argument in XEmacs which lacks it."
- (if (not (featurep feature))
- (if filename
- (load filename noerror t)
- (load (format "%s" feature) noerror t)))))
-
(defun-mh mh-assoc-string assoc-string (key list case-fold)
"Like `assoc' but specifically for strings.
Case is ignored if CASE-FOLD is non-nil.
diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el
index 9cbc8cfb737..d929a329c93 100644
--- a/lisp/mh-e/mh-e.el
+++ b/lisp/mh-e/mh-e.el
@@ -88,9 +88,6 @@
(require 'mh-buffers)
(require 'mh-compat)
-(mh-do-in-xemacs
- (require 'mh-xemacs))
-
(mh-font-lock-add-keywords
'emacs-lisp-mode
(eval-when-compile
@@ -619,10 +616,6 @@ Output is expected to be shown to user, not parsed by MH-E."
;; The bug wasn't seen in emacs21 but still occurred in XEmacs21.4.
(mh-exchange-point-and-mark-preserving-active-mark))
-;; Shush compiler.
-(mh-do-in-xemacs
- (defvar mark-active))
-
(defun mh-exchange-point-and-mark-preserving-active-mark ()
"Put the mark where point is now, and point where the mark is now.
This command works even when the mark is not active, and
@@ -3117,42 +3110,6 @@ of your own choosing."
:group 'mh-tool-bar
:package-version '(MH-E . "7.0"))
-;; XEmacs has a couple of extra customizations...
-(mh-do-in-xemacs
- (defcustom-mh mh-xemacs-use-tool-bar-flag mh-xemacs-has-tool-bar-flag
- "If non-nil, use tool bar.
-
-This option controls whether to show the MH-E icons at all. By
-default, this option is turned on if the window system supports
-tool bars. If your system doesn't support tool bars, then you
-won't be able to turn on this option."
- :type 'boolean
- :group 'mh-tool-bar
- :set (lambda (symbol value)
- (if (and (eq value t)
- (not mh-xemacs-has-tool-bar-flag))
- (error "Tool bar not supported"))
- (set-default symbol value))
- :package-version '(MH-E . "7.3"))
-
- (defcustom-mh mh-xemacs-tool-bar-position nil
- "Tool bar location.
-
-This option controls the placement of the tool bar along the four
-edges of the frame. You can choose from one of \"Same As Default
-Tool Bar\", \"Top\", \"Bottom\", \"Left\", or \"Right\". If this
-variable is set to anything other than \"Same As Default Tool
-Bar\" and the default tool bar is in a different location, then
-two tool bars will be displayed: the MH-E tool bar and the
-default tool bar."
- :type '(radio (const :tag "Same As Default Tool Bar" :value nil)
- (const :tag "Top" :value top)
- (const :tag "Bottom" :value bottom)
- (const :tag "Left" :value left)
- (const :tag "Right" :value right))
- :group 'mh-tool-bar
- :package-version '(MH-E . "7.3")))
-
;;; Hooks (:group 'mh-hooks + group where hook described)
diff --git a/lisp/mh-e/mh-folder.el b/lisp/mh-e/mh-folder.el
index 35277ae46a1..5fbaf12ef97 100644
--- a/lisp/mh-e/mh-folder.el
+++ b/lisp/mh-e/mh-folder.el
@@ -343,11 +343,7 @@ annotation.")
[backtab] mh-prev-button
"\M-\t" mh-prev-button)
-(cond
- ((featurep 'xemacs)
- (define-key mh-folder-mode-map [button2] 'mh-show-mouse))
- (t
- (define-key mh-folder-mode-map [mouse-2] 'mh-show-mouse)))
+(define-key mh-folder-mode-map [mouse-2] 'mh-show-mouse)
;; "C-c /" prefix is used in mh-folder-mode by pgp.el and mailcrypt
@@ -512,12 +508,8 @@ font-lock is done highlighting.")
;;; MH-Folder Mode
(defmacro mh-remove-xemacs-horizontal-scrollbar ()
- "Get rid of the horizontal scrollbar that XEmacs insists on putting in."
- (when (featurep 'xemacs)
- '(if (and (featurep 'scrollbar)
- (fboundp 'set-specifier))
- (set-specifier horizontal-scrollbar-visible-p nil
- (cons (current-buffer) nil)))))
+ (declare (obsolete nil "29.1"))
+ nil)
;; Register mh-folder-mode as supporting which-function-mode...
(eval-and-compile (mh-require 'which-func nil t))
@@ -527,8 +519,6 @@ font-lock is done highlighting.")
;; Shush compiler.
(defvar desktop-save-buffer)
(defvar font-lock-auto-fontify)
-(mh-do-in-xemacs
- (defvar font-lock-defaults))
;; Ensure new buffers won't get this mode if default major-mode is nil.
(put 'mh-folder-mode 'mode-class 'special)
@@ -595,8 +585,6 @@ perform the operation on all messages in that region.
(mh-tool-bar-folder-buttons-init))
(if (boundp 'tool-bar-map)
(set (make-local-variable 'tool-bar-map) mh-folder-tool-bar-map)))
- (mh-do-in-xemacs
- (mh-tool-bar-init :folder))
(make-local-variable 'font-lock-defaults)
(setq font-lock-defaults '(mh-folder-font-lock-keywords t))
(make-local-variable 'desktop-save-buffer)
@@ -644,7 +632,6 @@ perform the operation on all messages in that region.
'imenu-create-index-function 'mh-index-create-imenu-index
; Setup imenu support
'mh-previous-window-config nil) ; Previous window configuration
- (mh-remove-xemacs-horizontal-scrollbar)
(setq truncate-lines t)
(auto-save-mode -1)
(setq buffer-offer-save t)
@@ -655,15 +642,8 @@ perform the operation on all messages in that region.
(mh-funcall-if-exists hl-line-mode 1)
(setq revert-buffer-function #'mh-undo-folder)
(add-to-list 'minor-mode-alist '(mh-showing-mode " Show"))
- (mh-do-in-xemacs
- (easy-menu-add mh-folder-sequence-menu)
- (easy-menu-add mh-folder-message-menu)
- (easy-menu-add mh-folder-folder-menu))
(mh-inc-spool-make)
- (mh-set-help mh-folder-mode-help-messages)
- (if (and (featurep 'xemacs)
- font-lock-auto-fontify)
- (turn-on-font-lock))) ; Force font-lock in XEmacs.
+ (mh-set-help mh-folder-mode-help-messages))
diff --git a/lisp/mh-e/mh-gnus.el b/lisp/mh-e/mh-gnus.el
index cc60f7b6640..a3ba8593881 100644
--- a/lisp/mh-e/mh-gnus.el
+++ b/lisp/mh-e/mh-gnus.el
@@ -39,8 +39,7 @@
;; TODO This is not in Gnus 5.11.
(defun-mh mh-gnus-local-map-property gnus-local-map-property (map)
"Return a list suitable for a text property list specifying keymap MAP."
- (cond ((featurep 'xemacs) (list 'keymap map))
- ((>= emacs-major-version 21) (list 'keymap map))
+ (cond ((>= emacs-major-version 21) (list 'keymap map))
(t (list 'local-map map))))
;; Copy of function from mm-decode.el.
diff --git a/lisp/mh-e/mh-identity.el b/lisp/mh-e/mh-identity.el
index ceede0d07cb..cd7f089dc14 100644
--- a/lisp/mh-e/mh-identity.el
+++ b/lisp/mh-e/mh-identity.el
@@ -54,8 +54,7 @@ This is normally set as part of an Identity in
(defun mh-identity-make-menu ()
"Build the Identity menu.
This should be called any time `mh-identity-list' or
-`mh-auto-fields-list' change.
-See `mh-identity-add-menu'."
+`mh-auto-fields-list' change."
(easy-menu-define mh-identity-menu mh-letter-mode-map
"MH-E identity menu"
(append
@@ -88,8 +87,8 @@ See `mh-identity-add-menu'."
(defun mh-identity-add-menu ()
"Add the current Identity menu.
See `mh-identity-make-menu'."
- (if mh-identity-menu
- (mh-do-in-xemacs (easy-menu-add mh-identity-menu))))
+ (declare (obsolete nil "29.1"))
+ nil)
(defvar mh-identity-local nil
"Buffer-local variable that holds the identity currently in use.")
diff --git a/lisp/mh-e/mh-letter.el b/lisp/mh-e/mh-letter.el
index ae5b80d5807..493749577b9 100644
--- a/lisp/mh-e/mh-letter.el
+++ b/lisp/mh-e/mh-letter.el
@@ -260,10 +260,6 @@ searching for `mh-mail-header-separator' in the buffer."
;;; MH-Letter Mode
-;; Shush compiler.
-(mh-do-in-xemacs
- (defvar font-lock-defaults))
-
;; Ensure new buffers won't get this mode if default major-mode is nil.
(put 'mh-letter-mode 'mode-class 'special)
@@ -300,8 +296,6 @@ order).
(mh-tool-bar-letter-buttons-init))
(if (boundp 'tool-bar-map)
(set (make-local-variable 'tool-bar-map) mh-letter-tool-bar-map)))
- (mh-do-in-xemacs
- (mh-tool-bar-init :letter))
;; Set the local value of mh-mail-header-separator according to what is
;; present in the buffer...
(set (make-local-variable 'mh-mail-header-separator)
@@ -328,12 +322,10 @@ order).
(t
;; ...or the header only
(setq font-lock-defaults '((mh-show-font-lock-keywords) t))))
- (mh-do-in-xemacs (easy-menu-add mh-letter-menu))
;; Maybe we want to use the existing Mail menu from mail-mode in
;; 9.0; in the mean time, let's remove it since the redundancy will
;; only produce confusion.
(define-key mh-letter-mode-map [menu-bar mail] #'undefined)
- (mh-do-in-xemacs (easy-menu-remove mail-menubar-menu))
(setq fill-column mh-letter-fill-column)
(add-hook 'completion-at-point-functions
#'mh-letter-completion-at-point nil 'local)
diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el
index ad594aef906..dfd984118b1 100644
--- a/lisp/mh-e/mh-mime.el
+++ b/lisp/mh-e/mh-mime.el
@@ -189,8 +189,6 @@ Set from last use.")
(set-keymap-parent map mh-show-mode-map))
(mh-do-in-gnu-emacs
(define-key map [mouse-2] #'mh-push-button))
- (mh-do-in-xemacs
- (define-key map '(button2) #'mh-push-button))
(dolist (c mh-mime-button-commands)
(define-key map (cadr c) (car c)))
map))
@@ -215,8 +213,6 @@ Set from last use.")
(define-key map "\r" #'mh-press-button)
(mh-do-in-gnu-emacs
(define-key map [mouse-2] #'mh-push-button))
- (mh-do-in-xemacs
- (define-key map '(button2) #'mh-push-button))
map))
@@ -777,20 +773,13 @@ This is only useful if a Content-Disposition header is not present."
; this only tells us if the image is
; something that emacs can display
(let ((image (mm-get-image handle)))
- (or (mh-do-in-xemacs
- (and (mh-funcall-if-exists glyphp image)
- (< (glyph-width image)
- (or mh-max-inline-image-width (window-pixel-width)))
- (< (glyph-height image)
- (or mh-max-inline-image-height
- (window-pixel-height)))))
- (mh-do-in-gnu-emacs
- (let ((size (and (fboundp 'image-size) (image-size image))))
- (and size
- (< (cdr size) (or mh-max-inline-image-height
- (1- (window-height))))
- (< (car size) (or mh-max-inline-image-width
- (window-width)))))))))))
+ (mh-do-in-gnu-emacs
+ (let ((size (and (fboundp 'image-size) (image-size image))))
+ (and size
+ (< (cdr size) (or mh-max-inline-image-height
+ (1- (window-height))))
+ (< (car size) (or mh-max-inline-image-width
+ (window-width))))))))))
(defun mh-inline-vcard-p (handle)
"Decide if HANDLE is a vcard that must be displayed inline."
@@ -821,19 +810,12 @@ being used to highlight the signature in a MIME part."
(mh-do-in-gnu-emacs
(let ((ov (make-overlay (point) (point-max))))
(overlay-put ov 'face 'mh-show-signature)
- (overlay-put ov 'evaporate t)))
- (mh-do-in-xemacs
- (set-extent-property (make-extent (point) (point-max))
- 'face 'mh-show-signature))))))
+ (overlay-put ov 'evaporate t)))))))
;;; Button Display
-;; Shush compiler.
-(mh-do-in-xemacs
- (defvar ov))
-
(defun mh-insert-mime-button (handle index displayed)
"Insert MIME button for HANDLE.
INDEX is the part number that will be DISPLAYED. It is also used
diff --git a/lisp/mh-e/mh-search.el b/lisp/mh-e/mh-search.el
index e03c9dc83f7..d84af791f9a 100644
--- a/lisp/mh-e/mh-search.el
+++ b/lisp/mh-e/mh-search.el
@@ -318,10 +318,6 @@ folder containing the index search results."
(cl-loop for msg-hash being the hash-values of mh-index-data
count (> (hash-table-count msg-hash) 0)))))))
-;; Shush compiler.
-(mh-do-in-xemacs
- (defvar pick-folder)) ;FIXME: Why?
-
(defun mh-search-folder (folder window-config)
"Search FOLDER for messages matching a pattern.
@@ -616,7 +612,6 @@ The hook `mh-search-mode-hook' is called upon entry to this mode.
\\{mh-search-mode-map}"
- (mh-do-in-xemacs (easy-menu-add mh-pick-menu))
(mh-set-help mh-search-mode-help-messages))
diff --git a/lisp/mh-e/mh-seq.el b/lisp/mh-e/mh-seq.el
index a50319a455d..69f9224ebee 100644
--- a/lisp/mh-e/mh-seq.el
+++ b/lisp/mh-e/mh-seq.el
@@ -194,8 +194,6 @@ MESSAGE appears."
" "))))
;; Shush compiler.
-(mh-do-in-xemacs
- (defvar tool-bar-mode))
(defvar tool-bar-map)
;;;###mh-autoload
diff --git a/lisp/mh-e/mh-show.el b/lisp/mh-e/mh-show.el
index 803f07e02b2..9dfce215e47 100644
--- a/lisp/mh-e/mh-show.el
+++ b/lisp/mh-e/mh-show.el
@@ -839,8 +839,6 @@ See also `mh-folder-mode'.
(mh-do-in-gnu-emacs
(if (boundp 'tool-bar-map)
(set (make-local-variable 'tool-bar-map) mh-show-tool-bar-map)))
- (mh-do-in-xemacs
- (mh-tool-bar-init :show))
(set (make-local-variable 'mail-header-separator) mh-mail-header-separator)
(setq paragraph-start (default-value 'paragraph-start))
(setq buffer-invisibility-spec '((vanish . t) t))
@@ -858,16 +856,9 @@ See also `mh-folder-mode'.
(mh-gnus-article-highlight-citation))
(t
(setq font-lock-defaults '(mh-show-font-lock-keywords t))))
- (if (and (featurep 'xemacs)
- font-lock-auto-fontify)
- (turn-on-font-lock))
(when mh-decode-mime-flag
(mh-make-local-hook 'kill-buffer-hook)
(add-hook 'kill-buffer-hook #'mh-mime-cleanup nil t))
- (mh-do-in-xemacs
- (easy-menu-add mh-show-sequence-menu)
- (easy-menu-add mh-show-message-menu)
- (easy-menu-add mh-show-folder-menu))
(make-local-variable 'mh-show-folder-buffer)
(buffer-disable-undo)
(use-local-map mh-show-mode-map))
diff --git a/lisp/mh-e/mh-tool-bar.el b/lisp/mh-e/mh-tool-bar.el
index 94aa8dd4a92..4e795d96000 100644
--- a/lisp/mh-e/mh-tool-bar.el
+++ b/lisp/mh-e/mh-tool-bar.el
@@ -29,8 +29,6 @@
(require 'mh-e)
(mh-do-in-gnu-emacs
(require 'tool-bar))
-(mh-do-in-xemacs
- (require 'toolbar))
;;; Tool Bar Commands
@@ -145,8 +143,6 @@ where,
(let* ((name (nth 0 button))
(name-str (symbol-name name))
(icon (nth 2 button))
- (xemacs-icon (mh-do-in-xemacs
- `(cdr (assoc (quote ,(intern icon)) mh-xemacs-icon-map))))
(full-doc (nth 3 button))
(doc (if (string-match "\\(.*\\)\n" full-doc)
(match-string 1 full-doc)
@@ -186,7 +182,7 @@ where,
(t 'folder-buttons)))
(docs (cond ((eq mbuttons 'letter-buttons) 'letter-docs)
((eq mbuttons 'folder-buttons) 'folder-docs))))
- (add-to-list vector-list `(vector ,xemacs-icon ',function t ,full-doc))
+ (add-to-list vector-list `(vector nil ',function t ,full-doc))
(add-to-list
setter `(when (member ',name ,list)
(mh-funcall-if-exists
@@ -282,72 +278,6 @@ Use SEQUENCE-MAP if display is limited; DEFAULT-MAP otherwise."
(mh-tool-bar-letter-buttons-init)
(mh-tool-bar-update 'mh-letter-mode mh-letter-tool-bar-map
mh-letter-tool-bar-map)))
- ;; XEmacs specific code
- (mh-do-in-xemacs
- (defvar mh-tool-bar-folder-vector-map
- (list ,@(cl-loop for button in folder-buttons
- for vector in folder-vectors
- collect `(cons ',button ,vector))))
- (defvar mh-tool-bar-show-vector-map
- (list ,@(cl-loop for button in show-buttons
- for vector in show-vectors
- collect `(cons ',button ,vector))))
- (defvar mh-tool-bar-letter-vector-map
- (list ,@(cl-loop for button in letter-buttons
- for vector in letter-vectors
- collect `(cons ',button ,vector))))
- (defvar mh-tool-bar-folder-buttons)
- (defvar mh-tool-bar-show-buttons)
- (defvar mh-tool-bar-letter-buttons)
- ;; Custom setter functions
- (defun mh-tool-bar-letter-buttons-set (symbol value)
- (set-default symbol value)
- (when mh-xemacs-has-tool-bar-flag
- (setq mh-tool-bar-letter-buttons
- (cl-loop
- for b in value
- collect (cdr (assoc b mh-tool-bar-letter-vector-map))))))
- (defun mh-tool-bar-folder-buttons-set (symbol value)
- (set-default symbol value)
- (when mh-xemacs-has-tool-bar-flag
- (setq mh-tool-bar-folder-buttons
- (cl-loop
- for b in value
- collect (cdr (assoc b mh-tool-bar-folder-vector-map))))
- (setq mh-tool-bar-show-buttons
- (cl-loop
- for b in value
- collect (cdr (assoc b mh-tool-bar-show-vector-map))))))
- (defun mh-tool-bar-init (mode)
- "Install tool bar in MODE."
- (when mh-xemacs-use-tool-bar-flag
- (let ((tool-bar (cond ((eq mode :folder)
- mh-tool-bar-folder-buttons)
- ((eq mode :letter)
- mh-tool-bar-letter-buttons)
- ((eq mode :show)
- mh-tool-bar-show-buttons)))
- (height 37)
- (width 40)
- (buffer (current-buffer)))
- (cond
- ((eq mh-xemacs-tool-bar-position 'top)
- (set-specifier top-toolbar tool-bar buffer)
- (set-specifier top-toolbar-visible-p t)
- (set-specifier top-toolbar-height height))
- ((eq mh-xemacs-tool-bar-position 'bottom)
- (set-specifier bottom-toolbar tool-bar buffer)
- (set-specifier bottom-toolbar-visible-p t)
- (set-specifier bottom-toolbar-height height))
- ((eq mh-xemacs-tool-bar-position 'left)
- (set-specifier left-toolbar tool-bar buffer)
- (set-specifier left-toolbar-visible-p t)
- (set-specifier left-toolbar-width width))
- ((eq mh-xemacs-tool-bar-position 'right)
- (set-specifier right-toolbar tool-bar buffer)
- (set-specifier right-toolbar-visible-p t)
- (set-specifier right-toolbar-width width))
- (t (set-specifier default-toolbar tool-bar buffer)))))))
;; Declare customizable tool bars
(custom-declare-variable
'mh-tool-bar-folder-buttons
@@ -372,7 +302,6 @@ Use SEQUENCE-MAP if display is limited; DEFAULT-MAP otherwise."
;;:package-version '(MH-E "7.1")
))))
-;; The icon names are duplicated in the Makefile and mh-xemacs.el.
(mh-tool-bar-define
((:folder mh-inc-folder mh-mime-save-parts
mh-previous-undeleted-msg mh-page-msg
diff --git a/lisp/mh-e/mh-utils.el b/lisp/mh-e/mh-utils.el
index bbce17013b1..49302e16879 100644
--- a/lisp/mh-e/mh-utils.el
+++ b/lisp/mh-e/mh-utils.el
@@ -61,9 +61,9 @@ used in lieu of `search' in the CL package."
;;;###mh-autoload
(defun mh-colors-available-p ()
"Check if colors are available in the Emacs being used."
- (or (featurep 'xemacs)
- (let ((color-cells (mh-display-color-cells)))
- (and (numberp color-cells) (>= color-cells 8)))))
+ ;; FIXME: Can this be replaced with `display-color-p'?
+ (let ((color-cells (mh-display-color-cells)))
+ (and (numberp color-cells) (>= color-cells 8))))
;;;###mh-autoload
(defun mh-colors-in-use-p ()
@@ -139,14 +139,7 @@ Ignores case when searching for OLD."
(mh-funcall-if-exists
find-image '((:type xpm :ascent center
:file "mh-logo.xpm"))))))
- (car mode-line-buffer-identification))))
- (mh-do-in-xemacs
- (setq modeline-buffer-identification
- (list
- (if mh-modeline-glyph
- (cons modeline-buffer-id-left-extent mh-modeline-glyph)
- (cons modeline-buffer-id-left-extent "XEmacs%N:"))
- (cons modeline-buffer-id-right-extent " %17b")))))
+ (car mode-line-buffer-identification)))))
@@ -922,9 +915,6 @@ Handle RFC 822 (or later) continuation lines."
(let ((map (make-sparse-keymap)))
(mh-do-in-gnu-emacs
(define-key map [mouse-2] #'mh-letter-toggle-header-field-display-button))
- (mh-do-in-xemacs
- (define-key map '(button2)
- #'mh-letter-toggle-header-field-display-button))
map))
;;;###mh-autoload
diff --git a/lisp/mh-e/mh-xface.el b/lisp/mh-e/mh-xface.el
index 58177c1794e..9d3f0f4a624 100644
--- a/lisp/mh-e/mh-xface.el
+++ b/lisp/mh-e/mh-xface.el
@@ -31,10 +31,7 @@
(autoload 'message-fetch-field "message")
(defvar mh-show-xface-function
- (cond ((and (featurep 'xemacs) (locate-library "x-face") (not (featurep 'xface)))
- (load "x-face" t t)
- #'mh-face-display-function)
- ((>= emacs-major-version 21)
+ (cond ((>= emacs-major-version 21)
#'mh-face-display-function)
(t #'ignore))
"Determine at run time what function should be called to display X-Face.")
@@ -88,36 +85,7 @@ in this order is used."
(mh-face-foreground 'mh-show-xface nil t)
:background
(mh-face-background 'mh-show-xface nil t))
- " ")))
- ;; XEmacs
- (mh-do-in-xemacs
- (cond
- ((eq type 'url)
- (mh-x-image-url-display url))
- ((eq type 'png)
- (when (featurep 'png)
- (set-extent-begin-glyph
- (make-extent (point) (point))
- (make-glyph (vector 'png ':data (mh-face-to-png face))))))
- ;; Try internal xface support if available...
- ((and (eq type 'pbm) (featurep 'xface))
- (set-glyph-face
- (set-extent-begin-glyph
- (make-extent (point) (point))
- (make-glyph (vector 'xface ':data (concat "X-Face: " x-face))))
- 'mh-show-xface))
- ;; Otherwise try external support with x-face...
- ((and (eq type 'pbm)
- (fboundp 'x-face-xmas-wl-display-x-face)
- (fboundp 'executable-find) (executable-find "uncompface"))
- (mh-funcall-if-exists x-face-xmas-wl-display-x-face))
- ;; Picon display
- ((and raw (member type '(xpm xbm gif)))
- (when (featurep type)
- (set-extent-begin-glyph
- (make-extent (point) (point))
- (make-glyph (vector type ':data raw))))))
- (when raw (insert " "))))))))
+ " "))))))))
(defun mh-face-to-png (data)
"Convert base64 encoded DATA to png image."
@@ -178,8 +146,7 @@ The directories are searched for in the order they appear in the list.")
(cl-loop for type in '(xpm xbm gif)
when (or (mh-do-in-gnu-emacs
(ignore-errors
- (mh-funcall-if-exists image-type-available-p type)))
- (mh-do-in-xemacs (featurep type)))
+ (mh-funcall-if-exists image-type-available-p type))))
collect type))
(autoload 'message-tokenize-header "sendmail")
@@ -405,15 +372,7 @@ filenames. In addition, replaces * with %2a. See URL
(eq marker mh-x-image-marker))
(goto-char marker)
(mh-do-in-gnu-emacs
- (mh-funcall-if-exists insert-image (create-image image 'png)))
- (mh-do-in-xemacs
- (when (featurep 'png)
- (set-extent-begin-glyph
- (make-extent (point) (point))
- (make-glyph
- (vector 'png ':data (with-temp-buffer
- (insert-file-contents-literally image)
- (buffer-string))))))))
+ (mh-funcall-if-exists insert-image (create-image image 'png))))
(set-buffer-modified-p buffer-modified-flag)))))
(defun mh-x-image-url-fetch-image (url cache-file marker sentinel)
diff --git a/lisp/mouse.el b/lisp/mouse.el
index bb47d04a3a8..1cbdaaf8129 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -1568,8 +1568,7 @@ The region will be defined with mark and point."
(mouse-minibuffer-check start-event)
(setq mouse-selection-click-count-buffer (current-buffer))
(deactivate-mark)
- (let* ((scroll-margin 0) ; Avoid margin scrolling (Bug#9541).
- (start-posn (event-start start-event))
+ (let* ((start-posn (event-start start-event))
(start-point (posn-point start-posn))
(start-window (posn-window start-posn))
(_ (with-current-buffer (window-buffer start-window)
@@ -1591,72 +1590,84 @@ The region will be defined with mark and point."
;; Don't count the mode line.
(1- (nth 3 bounds))))
(click-count (1- (event-click-count start-event)))
- ;; Suppress automatic hscrolling, because that is a nuisance
- ;; when setting point near the right fringe (but see below).
+ ;; Save original automatic scrolling behavior (see below).
(auto-hscroll-mode-saved auto-hscroll-mode)
- (old-track-mouse track-mouse))
+ (scroll-margin-saved scroll-margin)
+ (old-track-mouse track-mouse)
+ (cleanup (lambda ()
+ (setq track-mouse old-track-mouse)
+ (setq auto-hscroll-mode auto-hscroll-mode-saved)
+ (setq scroll-margin scroll-margin-saved))))
+ (condition-case err
+ (progn
+ (setq mouse-selection-click-count click-count)
+
+ ;; Suppress automatic scrolling near the edges while tracking
+ ;; movement, as it interferes with the natural dragging behavior
+ ;; (point will unexpectedly be moved beneath the pointer, making
+ ;; selections in auto-scrolling margins impossible).
+ (setq auto-hscroll-mode nil)
+ (setq scroll-margin 0)
+
+ ;; In case the down click is in the middle of some intangible text,
+ ;; use the end of that text, and put it in START-POINT.
+ (if (< (point) start-point)
+ (goto-char start-point))
+ (setq start-point (point))
+
+ ;; Activate the region, using `mouse-start-end' to determine where
+ ;; to put point and mark (e.g., double-click will select a word).
+ (setq-local transient-mark-mode
+ (if (eq transient-mark-mode 'lambda)
+ '(only)
+ (cons 'only transient-mark-mode)))
+ (let ((range (mouse-start-end start-point start-point click-count)))
+ (push-mark (nth 0 range) t t)
+ (goto-char (nth 1 range)))
- (setq mouse-selection-click-count click-count)
- ;; In case the down click is in the middle of some intangible text,
- ;; use the end of that text, and put it in START-POINT.
- (if (< (point) start-point)
- (goto-char start-point))
- (setq start-point (point))
+ (setf (terminal-parameter nil 'mouse-drag-start) start-event)
+ (setq track-mouse t)
- ;; Activate the region, using `mouse-start-end' to determine where
- ;; to put point and mark (e.g., double-click will select a word).
- (setq-local transient-mark-mode
- (if (eq transient-mark-mode 'lambda)
- '(only)
- (cons 'only transient-mark-mode)))
- (let ((range (mouse-start-end start-point start-point click-count)))
- (push-mark (nth 0 range) t t)
- (goto-char (nth 1 range)))
-
- (setf (terminal-parameter nil 'mouse-drag-start) start-event)
- (setq track-mouse t)
- (setq auto-hscroll-mode nil)
-
- (set-transient-map
- (let ((map (make-sparse-keymap)))
- (define-key map [switch-frame] #'ignore)
- (define-key map [select-window] #'ignore)
- (define-key map [mouse-movement]
- (lambda (event) (interactive "e")
- (let* ((end (event-end event))
- (end-point (posn-point end)))
- (unless (eq end-point start-point)
- ;; As soon as the user moves, we can re-enable auto-hscroll.
- (setq auto-hscroll-mode auto-hscroll-mode-saved)
- ;; And remember that we have moved, so mouse-set-region can know
- ;; its event is really a drag event.
- (setcar start-event 'mouse-movement))
- (if (and (eq (posn-window end) start-window)
- (integer-or-marker-p end-point))
- (mouse--drag-set-mark-and-point start-point
- end-point click-count)
- (let ((mouse-row (cdr (cdr (mouse-position)))))
- (cond
- ((null mouse-row))
- ((< mouse-row top)
- (mouse-scroll-subr start-window (- mouse-row top)
- nil start-point))
- ((>= mouse-row bottom)
- (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
- nil start-point))))))))
- map)
- t (lambda ()
- (setq track-mouse old-track-mouse)
- (setq auto-hscroll-mode auto-hscroll-mode-saved)
- ;; Don't deactivate the mark when the context menu was invoked
- ;; by down-mouse-3 immediately after down-mouse-1 and without
- ;; releasing the mouse button with mouse-1. This allows to use
- ;; region-related context menu to operate on the selected region.
- (unless (and context-menu-mode
- (eq (car-safe (aref (this-command-keys-vector) 0))
- 'down-mouse-3))
- (deactivate-mark)
- (pop-mark))))))
+ (set-transient-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [switch-frame] #'ignore)
+ (define-key map [select-window] #'ignore)
+ (define-key map [mouse-movement]
+ (lambda (event) (interactive "e")
+ (let* ((end (event-end event))
+ (end-point (posn-point end)))
+ (unless (eq end-point start-point)
+ ;; And remember that we have moved, so mouse-set-region can know
+ ;; its event is really a drag event.
+ (setcar start-event 'mouse-movement))
+ (if (and (eq (posn-window end) start-window)
+ (integer-or-marker-p end-point))
+ (mouse--drag-set-mark-and-point start-point
+ end-point click-count)
+ (let ((mouse-row (cdr (cdr (mouse-position)))))
+ (cond
+ ((null mouse-row))
+ ((< mouse-row top)
+ (mouse-scroll-subr start-window (- mouse-row top)
+ nil start-point))
+ ((>= mouse-row bottom)
+ (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
+ nil start-point))))))))
+ map)
+ t (lambda ()
+ (funcall cleanup)
+ ;; Don't deactivate the mark when the context menu was invoked
+ ;; by down-mouse-3 immediately after down-mouse-1 and without
+ ;; releasing the mouse button with mouse-1. This allows to use
+ ;; region-related context menu to operate on the selected region.
+ (unless (and context-menu-mode
+ (eq (car-safe (aref (this-command-keys-vector) 0))
+ 'down-mouse-3))
+ (deactivate-mark)
+ (pop-mark)))))
+ ;; Cleanup on errors
+ (error (funcall cleanup)
+ (signal (car err) (cdr err))))))
(defun mouse--drag-set-mark-and-point (start click click-count)
(let* ((range (mouse-start-end start click click-count))
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el
index 2585833e1d4..a6c256eeba8 100644
--- a/lisp/net/ange-ftp.el
+++ b/lisp/net/ange-ftp.el
@@ -1230,8 +1230,9 @@ only return the directory part of FILE."
;; found another machine with the same user.
;; Try that account.
(read-passwd
- (format "passwd for %s@%s (default same as %s@%s): "
- user host user other)
+ (format-prompt "passwd for %s@%s"
+ (format "same as %s@%s" user other)
+ user host)
nil
(ange-ftp-lookup-passwd other user))
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index bb6583c2a9a..24c63352105 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -271,15 +271,13 @@ See also `eww-form-checkbox-selected-symbol'."
"text/html, text/plain, text/sgml, text/css, application/xhtml+xml, */*;q=0.01"
"Value used for the HTTP 'Accept' header.")
-(defvar eww-link-keymap
- (let ((map (copy-keymap shr-map)))
- (define-key map "\r" 'eww-follow-link)
- map))
+(defvar-keymap eww-link-keymap
+ :parent shr-map
+ "\r" #'eww-follow-link)
-(defvar eww-image-link-keymap
- (let ((map (copy-keymap shr-image-map)))
- (define-key map "\r" 'eww-follow-link)
- map))
+(defvar-keymap eww-image-link-keymap
+ :parent shr-map
+ "\r" #'eww-follow-link)
(defun eww-suggested-uris nil
"Return the list of URIs to suggest at the `eww' prompt.
@@ -973,67 +971,64 @@ the like."
(setq result highest))))
result))
-(defvar eww-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "g" 'eww-reload) ;FIXME: revert-buffer-function instead!
- (define-key map "G" 'eww)
- (define-key map [?\M-\r] 'eww-open-in-new-buffer)
- (define-key map [?\t] 'shr-next-link)
- (define-key map [?\M-\t] 'shr-previous-link)
- (define-key map [backtab] 'shr-previous-link)
- (define-key map [delete] 'scroll-down-command)
- (define-key map "l" 'eww-back-url)
- (define-key map "r" 'eww-forward-url)
- (define-key map "n" 'eww-next-url)
- (define-key map "p" 'eww-previous-url)
- (define-key map "u" 'eww-up-url)
- (define-key map "t" 'eww-top-url)
- (define-key map "&" 'eww-browse-with-external-browser)
- (define-key map "d" 'eww-download)
- (define-key map "w" 'eww-copy-page-url)
- (define-key map "C" 'url-cookie-list)
- (define-key map "v" 'eww-view-source)
- (define-key map "R" 'eww-readable)
- (define-key map "H" 'eww-list-histories)
- (define-key map "E" 'eww-set-character-encoding)
- (define-key map "s" 'eww-switch-to-buffer)
- (define-key map "S" 'eww-list-buffers)
- (define-key map "F" 'eww-toggle-fonts)
- (define-key map "D" 'eww-toggle-paragraph-direction)
- (define-key map [(meta C)] 'eww-toggle-colors)
- (define-key map [(meta I)] 'eww-toggle-images)
-
- (define-key map "b" 'eww-add-bookmark)
- (define-key map "B" 'eww-list-bookmarks)
- (define-key map [(meta n)] 'eww-next-bookmark)
- (define-key map [(meta p)] 'eww-previous-bookmark)
-
- (easy-menu-define nil map ""
- '("Eww"
- ["Exit" quit-window t]
- ["Close browser" quit-window t]
- ["Reload" eww-reload t]
- ["Follow URL in new buffer" eww-open-in-new-buffer]
- ["Back to previous page" eww-back-url
- :active (not (zerop (length eww-history)))]
- ["Forward to next page" eww-forward-url
- :active (not (zerop eww-history-position))]
- ["Browse with external browser" eww-browse-with-external-browser t]
- ["Download" eww-download t]
- ["View page source" eww-view-source]
- ["Copy page URL" eww-copy-page-url t]
- ["List histories" eww-list-histories t]
- ["Switch to buffer" eww-switch-to-buffer t]
- ["List buffers" eww-list-buffers t]
- ["Add bookmark" eww-add-bookmark t]
- ["List bookmarks" eww-list-bookmarks t]
- ["List cookies" url-cookie-list t]
- ["Toggle fonts" eww-toggle-fonts t]
- ["Toggle colors" eww-toggle-colors t]
- ["Toggle images" eww-toggle-images t]
- ["Character Encoding" eww-set-character-encoding]
- ["Toggle Paragraph Direction" eww-toggle-paragraph-direction]))
- map))
+(defvar-keymap eww-mode-map
+ "g" #'eww-reload ;FIXME: revert-buffer-function instead!
+ "G" #'eww
+ [?\M-\r] #'eww-open-in-new-buffer
+ [?\t] #'shr-next-link
+ [?\M-\t] #'shr-previous-link
+ [backtab] #'shr-previous-link
+ [delete] #'scroll-down-command
+ "l" #'eww-back-url
+ "r" #'eww-forward-url
+ "n" #'eww-next-url
+ "p" #'eww-previous-url
+ "u" #'eww-up-url
+ "t" #'eww-top-url
+ "&" #'eww-browse-with-external-browser
+ "d" #'eww-download
+ "w" #'eww-copy-page-url
+ "C" #'url-cookie-list
+ "v" #'eww-view-source
+ "R" #'eww-readable
+ "H" #'eww-list-histories
+ "E" #'eww-set-character-encoding
+ "s" #'eww-switch-to-buffer
+ "S" #'eww-list-buffers
+ "F" #'eww-toggle-fonts
+ "D" #'eww-toggle-paragraph-direction
+ [(meta C)] #'eww-toggle-colors
+ [(meta I)] #'eww-toggle-images
+
+ "b" #'eww-add-bookmark
+ "B" #'eww-list-bookmarks
+ [(meta n)] #'eww-next-bookmark
+ [(meta p)] #'eww-previous-bookmark
+
+ :menu '("Eww"
+ ["Exit" quit-window t]
+ ["Close browser" quit-window t]
+ ["Reload" eww-reload t]
+ ["Follow URL in new buffer" eww-open-in-new-buffer]
+ ["Back to previous page" eww-back-url
+ :active (not (zerop (length eww-history)))]
+ ["Forward to next page" eww-forward-url
+ :active (not (zerop eww-history-position))]
+ ["Browse with external browser" eww-browse-with-external-browser t]
+ ["Download" eww-download t]
+ ["View page source" eww-view-source]
+ ["Copy page URL" eww-copy-page-url t]
+ ["List histories" eww-list-histories t]
+ ["Switch to buffer" eww-switch-to-buffer t]
+ ["List buffers" eww-list-buffers t]
+ ["Add bookmark" eww-add-bookmark t]
+ ["List bookmarks" eww-list-bookmarks t]
+ ["List cookies" url-cookie-list t]
+ ["Toggle fonts" eww-toggle-fonts t]
+ ["Toggle colors" eww-toggle-colors t]
+ ["Toggle images" eww-toggle-images t]
+ ["Character Encoding" eww-set-character-encoding]
+ ["Toggle Paragraph Direction" eww-toggle-paragraph-direction]))
(defun eww-context-menu (menu click)
"Populate MENU with eww commands at CLICK."
@@ -1230,54 +1225,43 @@ just re-display the HTML already fetched."
(defvar eww-form nil)
-(defvar eww-submit-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\r" 'eww-submit)
- (define-key map [(control c) (control c)] 'eww-submit)
- map))
-
-(defvar eww-submit-file
- (let ((map (make-sparse-keymap)))
- (define-key map "\r" 'eww-select-file)
- (define-key map [(control c) (control c)] 'eww-submit)
- map))
-
-(defvar eww-checkbox-map
- (let ((map (make-sparse-keymap)))
- (define-key map " " 'eww-toggle-checkbox)
- (define-key map "\r" 'eww-toggle-checkbox)
- (define-key map [(control c) (control c)] 'eww-submit)
- map))
-
-(defvar eww-text-map
- (let ((map (make-keymap)))
- (set-keymap-parent map text-mode-map)
- (define-key map "\r" 'eww-submit)
- (define-key map [(control a)] 'eww-beginning-of-text)
- (define-key map [(control c) (control c)] 'eww-submit)
- (define-key map [(control e)] 'eww-end-of-text)
- (define-key map [?\t] 'shr-next-link)
- (define-key map [?\M-\t] 'shr-previous-link)
- (define-key map [backtab] 'shr-previous-link)
- map))
-
-(defvar eww-textarea-map
- (let ((map (make-keymap)))
- (set-keymap-parent map text-mode-map)
- (define-key map "\r" 'forward-line)
- (define-key map [(control c) (control c)] 'eww-submit)
- (define-key map [?\t] 'shr-next-link)
- (define-key map [?\M-\t] 'shr-previous-link)
- (define-key map [backtab] 'shr-previous-link)
- map))
-
-(defvar eww-select-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\r" 'eww-change-select)
- (define-key map [follow-link] 'mouse-face)
- (define-key map [mouse-2] 'eww-change-select)
- (define-key map [(control c) (control c)] 'eww-submit)
- map))
+(defvar-keymap eww-submit-map
+ "\r" #'eww-submit
+ [(control c) (control c)] #'eww-submit)
+
+(defvar-keymap eww-submit-file
+ "\r" #'eww-select-file
+ [(control c) (control c)] #'eww-submit)
+
+(defvar-keymap eww-checkbox-map
+ " " #'eww-toggle-checkbox
+ "\r" #'eww-toggle-checkbox
+ [(control c) (control c)] #'eww-submit)
+
+(defvar-keymap eww-text-map
+ :full t :parent text-mode-map
+ "\r" #'eww-submit
+ [(control a)] #'eww-beginning-of-text
+ [(control c) (control c)] #'eww-submit
+ [(control e)] #'eww-end-of-text
+ [?\t] #'shr-next-link
+ [?\M-\t] #'shr-previous-link
+ [backtab] #'shr-previous-link)
+
+(defvar-keymap eww-textarea-map
+ :full t :parent text-mode-map
+ "\r" #'forward-line
+ [(control c) (control c)] #'eww-submit
+ [?\t] #'shr-next-link
+ [?\M-\t] #'shr-previous-link
+ [backtab] #'shr-previous-link)
+
+(defvar-keymap eww-select-map
+ :doc "Map for select buttons"
+ "\r" #'eww-change-select
+ [follow-link] 'mouse-face
+ [mouse-2] #'eww-change-select
+ [(control c) (control c)] #'eww-submit)
(defun eww-beginning-of-text ()
"Move to the start of the input field."
@@ -2100,23 +2084,18 @@ If ERROR-OUT, signal user-error if there are no bookmarks."
'eww-bookmark)))
(eww-browse-url (plist-get bookmark :url))))
-(defvar eww-bookmark-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [(control k)] 'eww-bookmark-kill)
- (define-key map [(control y)] 'eww-bookmark-yank)
- (define-key map "\r" 'eww-bookmark-browse)
-
- (easy-menu-define nil map
- "Menu for `eww-bookmark-mode-map'."
- '("Eww Bookmark"
- ["Exit" quit-window t]
- ["Browse" eww-bookmark-browse
- :active (get-text-property (line-beginning-position) 'eww-bookmark)]
- ["Kill" eww-bookmark-kill
- :active (get-text-property (line-beginning-position) 'eww-bookmark)]
- ["Yank" eww-bookmark-yank
- :active eww-bookmark-kill-ring]))
- map))
+(defvar-keymap eww-bookmark-mode-map
+ [(control k)] #'eww-bookmark-kill
+ [(control y)] #'eww-bookmark-yank
+ "\r" #'eww-bookmark-browse
+ :menu '("Eww Bookmark"
+ ["Exit" quit-window t]
+ ["Browse" eww-bookmark-browse
+ :active (get-text-property (line-beginning-position) 'eww-bookmark)]
+ ["Kill" eww-bookmark-kill
+ :active (get-text-property (line-beginning-position) 'eww-bookmark)]
+ ["Yank" eww-bookmark-yank
+ :active eww-bookmark-kill-ring]))
(define-derived-mode eww-bookmark-mode special-mode "eww bookmarks"
"Mode for listing bookmarks.
@@ -2181,19 +2160,15 @@ If ERROR-OUT, signal user-error if there are no bookmarks."
(pop-to-buffer-same-window buffer)))
(eww-restore-history history)))
-(defvar eww-history-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\r" 'eww-history-browse)
- (define-key map "n" 'next-line)
- (define-key map "p" 'previous-line)
-
- (easy-menu-define nil map
- "Menu for `eww-history-mode-map'."
- '("Eww History"
- ["Exit" quit-window t]
- ["Browse" eww-history-browse
- :active (get-text-property (line-beginning-position) 'eww-history)]))
- map))
+(defvar-keymap eww-history-mode-map
+ "\r" #'eww-history-browse
+ "n" #'next-line
+ "p" #'previous-line
+ :menu '("Eww History"
+ ["Exit" quit-window t]
+ ["Browse" eww-history-browse
+ :active (get-text-property (line-beginning-position)
+ 'eww-history)]))
(define-derived-mode eww-history-mode special-mode "eww history"
"Mode for listing eww-histories.
@@ -2304,22 +2279,18 @@ If ERROR-OUT, signal user-error if there are no bookmarks."
(forward-line -1))
(eww-buffer-show))
-(defvar eww-buffers-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [(control k)] 'eww-buffer-kill)
- (define-key map "\r" 'eww-buffer-select)
- (define-key map "n" 'eww-buffer-show-next)
- (define-key map "p" 'eww-buffer-show-previous)
-
- (easy-menu-define nil map
- "Menu for `eww-buffers-mode-map'."
- '("Eww Buffers"
- ["Exit" quit-window t]
- ["Select" eww-buffer-select
- :active (get-text-property (line-beginning-position) 'eww-buffer)]
- ["Kill" eww-buffer-kill
- :active (get-text-property (line-beginning-position) 'eww-buffer)]))
- map))
+(defvar-keymap eww-buffers-mode-map
+ [(control k)] #'eww-buffer-kill
+ "\r" #'eww-buffer-select
+ "n" #'eww-buffer-show-next
+ "p" #'eww-buffer-show-previous
+ :menu '("Eww Buffers"
+ ["Exit" quit-window t]
+ ["Select" eww-buffer-select
+ :active (get-text-property (line-beginning-position) 'eww-buffer)]
+ ["Kill" eww-buffer-kill
+ :active (get-text-property (line-beginning-position)
+ 'eww-buffer)]))
(define-derived-mode eww-buffers-mode special-mode "eww buffers"
"Mode for listing buffers.
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index a8e15c1e0ae..72d2ab78676 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -247,23 +247,21 @@ and other things:
(defvar shr-target-id nil
"Target fragment identifier anchor.")
-(defvar shr-map
- (let ((map (make-sparse-keymap)))
- (define-key map "a" #'shr-show-alt-text)
- (define-key map "i" #'shr-browse-image)
- (define-key map "z" #'shr-zoom-image)
- (define-key map [?\t] #'shr-next-link)
- (define-key map [?\M-\t] #'shr-previous-link)
- (define-key map [follow-link] 'mouse-face)
- (define-key map [mouse-2] #'shr-browse-url)
- (define-key map [C-down-mouse-1] #'shr-mouse-browse-url-new-window)
- (define-key map "I" #'shr-insert-image)
- (define-key map "w" #'shr-maybe-probe-and-copy-url)
- (define-key map "u" #'shr-maybe-probe-and-copy-url)
- (define-key map "v" #'shr-browse-url)
- (define-key map "O" #'shr-save-contents)
- (define-key map "\r" #'shr-browse-url)
- map))
+(defvar-keymap shr-map
+ "a" #'shr-show-alt-text
+ "i" #'shr-browse-image
+ "z" #'shr-zoom-image
+ [?\t] #'shr-next-link
+ [?\M-\t] #'shr-previous-link
+ [follow-link] 'mouse-face
+ [mouse-2] #'shr-browse-url
+ [C-down-mouse-1] #'shr-mouse-browse-url-new-window
+ "I" #'shr-insert-image
+ "w" #'shr-maybe-probe-and-copy-url
+ "u" #'shr-maybe-probe-and-copy-url
+ "v" #'shr-browse-url
+ "O" #'shr-save-contents
+ "\r" #'shr-browse-url)
(defvar shr-image-map
(let ((map (copy-keymap shr-map)))
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index b28235924de..8bf25151dfb 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -353,6 +353,7 @@ arguments to pass to the OPERATION."
;;;###autoload
(progn (defun tramp-archive-autoload-file-name-handler (operation &rest args)
"Load Tramp archive file name handler, and perform OPERATION."
+ (defvar tramp-archive-autoload)
(when tramp-archive-enabled
;; We cannot use `tramp-compat-temporary-file-directory' here due
;; to autoload. When installing Tramp's GNU ELPA package, there
@@ -360,7 +361,6 @@ arguments to pass to the OPERATION."
;; overload this.
(let ((default-directory temporary-file-directory)
(tramp-archive-autoload t))
- tramp-archive-autoload ; Silence byte compiler.
(apply #'tramp-autoload-file-name-handler operation args)))))
;;;###autoload
diff --git a/lisp/org/org-capture.el b/lisp/org/org-capture.el
index a9350c58d52..1756b34fc5b 100644
--- a/lisp/org/org-capture.el
+++ b/lisp/org/org-capture.el
@@ -1815,10 +1815,13 @@ by their respective `org-store-link-plist' properties if present."
;; Load history list for current prompt.
(setq org-capture--prompt-history
(gethash prompt org-capture--prompt-history-table))
- (push (org-completing-read
- (concat (or prompt "Enter string")
- (and default (format " [%s]" default))
- ": ")
+ (push (org-completing-read
+ ;; `format-prompt' is new in Emacs 28.1.
+ (if (fboundp 'format-prompt)
+ (format-prompt (or prompt "Enter string") default)
+ (concat (or prompt "Enter string")
+ (and default (format " [%s]" default))
+ ": "))
completions
nil nil nil 'org-capture--prompt-history default)
strings)
diff --git a/lisp/org/org-refile.el b/lisp/org/org-refile.el
index 678759e10db..73eaad6bf52 100644
--- a/lisp/org/org-refile.el
+++ b/lisp/org/org-refile.el
@@ -640,11 +640,13 @@ this function appends the default value from
org-refile-target-table))
(completion-ignore-case t)
cdef
- (prompt (concat prompt
- (or (and (car org-refile-history)
- (concat " (default " (car org-refile-history) ")"))
- (and (assoc cbnex tbl) (setq cdef cbnex)
- (concat " (default " cbnex ")"))) ": "))
+ (prompt (let ((default (or (car org-refile-history)
+ (and (assoc cbnex tbl) (setq cdef cbnex)
+ cbnex))))
+ ;; `format-prompt' is new in Emacs 28.1.
+ (if (fboundp 'format-prompt)
+ (format-prompt prompt default)
+ (concat prompt " (default " default ": "))))
pa answ parent-target child parent old-hist)
(setq old-hist org-refile-history)
(setq answ (funcall cfunc prompt tbl nil (not new-nodes)
diff --git a/lisp/proced.el b/lisp/proced.el
index fec2a29c847..e959e91c6e2 100644
--- a/lisp/proced.el
+++ b/lisp/proced.el
@@ -658,6 +658,7 @@ After displaying or updating a Proced buffer, Proced runs the normal hook
`proced-post-display-hook'.
\\{proced-mode-map}"
+ :interactive nil
(abbrev-mode 0)
(auto-fill-mode 0)
(setq buffer-read-only t
@@ -721,7 +722,7 @@ Proced buffers."
With prefix ARG, update this buffer automatically if ARG is positive,
otherwise do not update. Sets the variable `proced-auto-update-flag'.
The time interval for updates is specified via `proced-auto-update-interval'."
- (interactive (list (or current-prefix-arg 'toggle)))
+ (interactive (list (or current-prefix-arg 'toggle)) proced-mode)
(setq proced-auto-update-flag
(cond ((eq arg 'toggle) (not proced-auto-update-flag))
(arg (> (prefix-numeric-value arg) 0))
@@ -733,19 +734,19 @@ The time interval for updates is specified via `proced-auto-update-interval'."
(defun proced-mark (&optional count)
"Mark the current (or next COUNT) processes."
- (interactive "p")
+ (interactive "p" proced-mode)
(proced-do-mark t count))
(defun proced-unmark (&optional count)
"Unmark the current (or next COUNT) processes."
- (interactive "p")
+ (interactive "p" proced-mode)
(proced-do-mark nil count))
(defun proced-unmark-backward (&optional count)
"Unmark the previous (or COUNT previous) processes."
;; Analogous to `dired-unmark-backward',
;; but `ibuffer-unmark-backward' behaves different.
- (interactive "p")
+ (interactive "p" proced-mode)
(proced-do-mark nil (- (or count 1))))
(defun proced-do-mark (mark &optional count)
@@ -762,7 +763,7 @@ The time interval for updates is specified via `proced-auto-update-interval'."
(defun proced-toggle-marks ()
"Toggle marks: marked processes become unmarked, and vice versa."
- (interactive)
+ (interactive nil proced-mode)
(let ((mark-re (proced-marker-regexp))
buffer-read-only)
(save-excursion
@@ -788,14 +789,14 @@ Otherwise move one line forward after inserting the mark."
"Mark all processes.
If `transient-mark-mode' is turned on and the region is active,
mark the region."
- (interactive)
+ (interactive nil proced-mode)
(proced-do-mark-all t))
(defun proced-unmark-all ()
"Unmark all processes.
If `transient-mark-mode' is turned on and the region is active,
unmark the region."
- (interactive)
+ (interactive nil proced-mode)
(proced-do-mark-all nil))
(defun proced-do-mark-all (mark)
@@ -830,14 +831,14 @@ mark the region."
(defun proced-mark-children (ppid &optional omit-ppid)
"Mark child processes of process PPID.
Also mark process PPID unless prefix OMIT-PPID is non-nil."
- (interactive (list (proced-pid-at-point) current-prefix-arg))
+ (interactive (list (proced-pid-at-point) current-prefix-arg) proced-mode)
(proced-mark-process-alist
(proced-filter-children proced-process-alist ppid omit-ppid)))
(defun proced-mark-parents (cpid &optional omit-cpid)
"Mark parent processes of process CPID.
Also mark CPID unless prefix OMIT-CPID is non-nil."
- (interactive (list (proced-pid-at-point) current-prefix-arg))
+ (interactive (list (proced-pid-at-point) current-prefix-arg) proced-mode)
(proced-mark-process-alist
(proced-filter-parents proced-process-alist cpid omit-cpid)))
@@ -870,7 +871,7 @@ If `transient-mark-mode' is turned on and the region is active,
omit the processes in region.
If QUIET is non-nil suppress status message.
Returns count of omitted lines."
- (interactive "P")
+ (interactive "P" proced-mode)
(let ((mark-re (proced-marker-regexp))
(count 0)
buffer-read-only)
@@ -947,7 +948,8 @@ Set variable `proced-filter' to SCHEME. Revert listing."
(interactive
(let ((scheme (completing-read "Filter: "
proced-filter-alist nil t)))
- (list (if (string= "" scheme) nil (intern scheme)))))
+ (list (if (string= "" scheme) nil (intern scheme))))
+ proced-mode)
;; only update if necessary
(unless (eq proced-filter scheme)
(setq proced-filter scheme)
@@ -1057,7 +1059,7 @@ Each parent process is followed by its child processes.
The process tree inherits the chosen sorting order of the process listing,
that is, child processes of the same parent process are sorted using
the selected sorting order."
- (interactive (list (or current-prefix-arg 'toggle)))
+ (interactive (list (or current-prefix-arg 'toggle)) proced-mode)
(setq proced-tree-flag
(cond ((eq arg 'toggle) (not proced-tree-flag))
(arg (> (prefix-numeric-value arg) 0))
@@ -1140,7 +1142,7 @@ This command refines an already existing process listing generated initially
based on the value of the variable `proced-filter'. It does not change
this variable. It does not revert the listing. If you frequently need
a certain refinement, consider defining a new filter in `proced-filter-alist'."
- (interactive (list last-input-event))
+ (interactive (list last-input-event) proced-mode)
(if event (posn-set-point (event-end event)))
(let ((key (get-text-property (point) 'proced-key))
(pid (get-text-property (point) 'proced-pid)))
@@ -1269,7 +1271,8 @@ in the mode line, using \"+\" or \"-\" for ascending or descending order."
nil t)))
(list (if (string= "" scheme) nil (intern scheme))
;; like 'toggle in `define-derived-mode'
- (or current-prefix-arg 'no-arg))))
+ (or current-prefix-arg 'no-arg)))
+ proced-mode)
(setq proced-descend
;; If `proced-sort-interactive' is called repeatedly for the same
@@ -1290,37 +1293,37 @@ in the mode line, using \"+\" or \"-\" for ascending or descending order."
(defun proced-sort-pcpu (&optional arg)
"Sort Proced buffer by percentage CPU time (%CPU).
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'pcpu arg))
(defun proced-sort-pmem (&optional arg)
"Sort Proced buffer by percentage memory usage (%MEM).
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'pmem arg))
(defun proced-sort-pid (&optional arg)
"Sort Proced buffer by PID.
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'pid arg))
(defun proced-sort-start (&optional arg)
"Sort Proced buffer by time the command started (START).
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'start arg))
(defun proced-sort-time (&optional arg)
"Sort Proced buffer by CPU time (TIME).
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'time arg))
(defun proced-sort-user (&optional arg)
"Sort Proced buffer by USER.
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list (or current-prefix-arg 'no-arg)))
+ (interactive (list (or current-prefix-arg 'no-arg)) proced-mode)
(proced-sort-interactive 'user arg))
(defun proced-sort-header (event &optional arg)
@@ -1329,7 +1332,7 @@ EVENT is a mouse event with starting position in the header line.
It is converted to the corresponding attribute key.
This command updates the variable `proced-sort'.
Prefix ARG controls sort order, see `proced-sort-interactive'."
- (interactive (list last-input-event (or last-prefix-arg 'no-arg)))
+ (interactive (list last-input-event (or last-prefix-arg 'no-arg)) proced-mode)
(let ((start (event-start event))
col key)
(save-selected-window
@@ -1534,7 +1537,8 @@ With prefix REVERT non-nil revert listing."
(let ((scheme (completing-read "Format: "
proced-format-alist nil t)))
(list (if (string= "" scheme) nil (intern scheme))
- current-prefix-arg)))
+ current-prefix-arg))
+ proced-mode)
;; only update if necessary
(when (or (not (eq proced-format scheme)) revert)
(setq proced-format scheme)
@@ -1566,7 +1570,7 @@ Suppress status information if QUIET is nil.
After updating a displayed Proced buffer run the normal hook
`proced-post-display-hook'."
;; This is the main function that generates and updates the process listing.
- (interactive "P")
+ (interactive "P" proced-mode)
(setq revert (or revert (not proced-process-alist)))
(or quiet (message (if revert "Updating process information..."
"Updating process display...")))
@@ -1772,11 +1776,12 @@ supported but discouraged. It will be removed in a future version of Emacs."
`(:annotation-function
,(lambda (s) (cdr (assoc s proced-signal-list))))))
(proced-with-processes-buffer process-alist
- (list (completing-read (concat "Send signal [" pnum
- "] (default TERM): ")
+ (list (completing-read (format-prompt "Send signal [%s]"
+ "TERM" pnum)
proced-signal-list
nil nil nil nil "TERM")
- process-alist))))
+ process-alist)))
+ proced-mode)
(unless (and signal process-alist)
;; Discouraged usage (supported for backward compatibility):
@@ -1797,8 +1802,8 @@ supported but discouraged. It will be removed in a future version of Emacs."
`(:annotation-function
,(lambda (s) (cdr (assoc s proced-signal-list))))))
(proced-with-processes-buffer process-alist
- (setq signal (completing-read (concat "Send signal [" pnum
- "] (default TERM): ")
+ (setq signal (completing-read (format-prompt "Send signal [%s]"
+ "TERM" pnum)
proced-signal-list
nil nil nil nil "TERM"))))))
@@ -1861,7 +1866,8 @@ the normal hook `proced-after-send-signal-hook'."
(let ((process-alist (proced-marked-processes)))
(proced-with-processes-buffer process-alist
(list (read-number "New priority: ")
- process-alist))))
+ process-alist)))
+ proced-mode)
(if (numberp priority)
(setq priority (number-to-string priority)))
(let (failures)
@@ -1893,7 +1899,7 @@ the normal hook `proced-after-send-signal-hook'."
"Pop up a buffer with error log output from Proced.
A group of errors from a single command ends with a formfeed.
Thus, use \\[backward-page] to find the beginning of a group of errors."
- (interactive)
+ (interactive nil proced-mode)
(if (get-buffer proced-log-buffer)
(save-selected-window
;; move `proced-log-buffer' to the front of the buffer list
@@ -1945,7 +1951,7 @@ STRING is an overall summary of the failures."
(defun proced-help ()
"Provide help for the Proced user."
- (interactive)
+ (interactive nil proced-mode)
(proced-why)
(if (eq last-command 'proced-help)
(describe-mode)
@@ -1955,7 +1961,7 @@ STRING is an overall summary of the failures."
"Undo in a Proced buffer.
This doesn't recover killed processes, it just undoes changes in the Proced
buffer. You can use it to recover marks."
- (interactive)
+ (interactive nil proced-mode)
(let (buffer-read-only)
(undo))
(message "Change in Proced buffer undone.
diff --git a/lisp/progmodes/cpp.el b/lisp/progmodes/cpp.el
index d800365e66d..baee72b332d 100644
--- a/lisp/progmodes/cpp.el
+++ b/lisp/progmodes/cpp.el
@@ -702,11 +702,8 @@ BRANCH should be either nil (false branch), t (true branch) or `both'."
(x-popup-menu cpp-button-event
(list prompt (cons prompt cpp-face-default-list)))
(let ((name (car (rassq default cpp-face-default-list))))
- (cdr (assoc (completing-read (if name
- (concat prompt
- " (default " name "): ")
- (concat prompt ": "))
- cpp-face-default-list nil t)
+ (cdr (assoc (completing-read (format-prompt "%s" name prompt)
+ cpp-face-default-list nil t)
cpp-face-all-list))))
default))
diff --git a/lisp/progmodes/ebrowse.el b/lisp/progmodes/ebrowse.el
index ab0329d7eec..6e416d064a8 100644
--- a/lisp/progmodes/ebrowse.el
+++ b/lisp/progmodes/ebrowse.el
@@ -1330,9 +1330,9 @@ Pop to member buffer if no prefix ARG, to tree buffer otherwise."
"Set the indentation width of the tree display."
(interactive)
(let ((width (string-to-number (read-string
- (concat "Indentation (default "
- (int-to-string ebrowse--indentation)
- "): ")
+ (format-prompt
+ "Indentation"
+ (int-to-string ebrowse--indentation))
nil nil ebrowse--indentation))))
(when (cl-plusp width)
(setq-local ebrowse--indentation width)
diff --git a/lisp/progmodes/erts-mode.el b/lisp/progmodes/erts-mode.el
new file mode 100644
index 00000000000..9d51c1f8f08
--- /dev/null
+++ b/lisp/progmodes/erts-mode.el
@@ -0,0 +1,201 @@
+;;; erts-mode.el --- major mode to edit erts files -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Keywords: tools
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(eval-when-compile (require 'cl-lib))
+(require 'ert)
+
+(defgroup erts-mode nil
+ "Major mode for editing Emacs test files."
+ :group 'lisp)
+
+(defface erts-mode-specification-name
+ '((((class color)
+ (background dark))
+ :foreground "green")
+ (((class color)
+ (background light))
+ :foreground "cornflower blue")
+ (t
+ :bold t))
+ "Face used for displaying specification names."
+ :group 'erts-mode)
+
+(defface erts-mode-specification-value
+ '((((class color)
+ (background dark))
+ :foreground "DeepSkyBlue1")
+ (((class color)
+ (background light))
+ :foreground "blue")
+ (t
+ :bold t))
+ "Face used for displaying specificaton values."
+ :group 'erts-mode)
+
+(defface erts-mode-start-test
+ '((t :inherit font-lock-keyword-face))
+ "Face used for displaying specificaton test start markers."
+ :group 'erts-mode)
+
+(defface erts-mode-end-test
+ '((t :inherit font-lock-comment-face))
+ "Face used for displaying specificaton test start markers."
+ :group 'erts-mode)
+
+(defvar erts-mode-map
+ (let ((map (make-keymap)))
+ (set-keymap-parent map prog-mode-map)
+ (define-key map "\C-c\C-r" 'erts-tag-region)
+ (define-key map "\C-c\C-c" 'erts-run-test)
+ map))
+
+(defvar erts-mode-font-lock-keywords
+ ;; Specifications.
+ `((erts-mode--match-not-in-test
+ ("^\\([^ \t\n:]+:\\)[ \t]*\\(.*\\(\n[ \t].*\\)*\\)\n?"
+ (progn (goto-char (match-beginning 0)) (match-end 0)) nil
+ (1 'erts-mode-specification-name)
+ (2 'erts-mode-specification-value)))
+ ("^=-=$" 0 'erts-mode-start-test)
+ ("^=-=-=$" 0 'erts-mode-end-test)))
+
+(defun erts-mode--match-not-in-test (_limit)
+ (when (erts-mode--in-test-p (point))
+ (erts-mode--end-of-test))
+ (let ((start (point)))
+ (goto-char
+ (if (re-search-forward "^=-=$" nil t)
+ (match-beginning 0)
+ (point-max)))
+ (if (< (point) start)
+ nil
+ ;; Here we disregard LIMIT so that we may extend the area again.
+ (set-match-data (list start (point)))
+ (point))))
+
+(defun erts-mode--end-of-test ()
+ (search-forward "^=-=-=\n" nil t))
+
+(defun erts-mode--in-test-p (point)
+ "Say whether POINT is in a test."
+ (save-excursion
+ (goto-char point)
+ (beginning-of-line)
+ (if (looking-at "=-=\\(-=\\)?$")
+ t
+ (let ((test-start (save-excursion
+ (re-search-backward "^=-=\n" nil t))))
+ ;; Before the first test.
+ (and test-start
+ (let ((test-end (re-search-backward "^=-=-=\n" nil t)))
+ (or (null test-end)
+ ;; Between tests.
+ (> test-start test-end))))))))
+
+;;;###autoload
+(define-derived-mode erts-mode prog-mode "erts"
+ "Major mode for editing erts (Emacs testing) files.
+This mode mainly provides some font locking.
+
+\\{erts-mode-map}"
+ (setq-local font-lock-defaults '(erts-mode-font-lock-keywords t)))
+
+(defun erts-tag-region (start end name)
+ "Tag the region between START and END as a test.
+Interactively, this is the region.
+
+NAME should be a string appropriate for output by ert if the test fails.
+If NAME is nil or the empty string, a name will be auto-generated."
+ (interactive "r\nsTest name: " erts-mode)
+ ;; Automatically make a name.
+ (when (zerop (length name))
+ (save-excursion
+ (goto-char (point-min))
+ (let ((names nil))
+ (while (re-search-forward "^Name:[ \t]*\\(.*\\)" nil t)
+ (let ((name (match-string 1)))
+ (unless (erts-mode--in-test-p (point))
+ (push name names))))
+ (setq name
+ (cl-loop with base = (file-name-sans-extension (buffer-name))
+ for i from 1
+ for name = (format "%s%d" base i)
+ unless (member name names)
+ return name)))))
+ (save-excursion
+ (goto-char end)
+ (unless (bolp)
+ (insert "\n"))
+ (insert "=-=-=\n")
+ (goto-char start)
+ (insert "Name: " name "\n\n")
+ (insert "=-=\n")))
+
+(defun erts-run-test (test-function)
+ "Run the current test.
+If the current erts file doesn't define a test function, the user
+will be prompted for one."
+ (interactive
+ (list (save-excursion
+ ;; Find the preceding Code spec.
+ (while (and (re-search-backward "^Code:" nil t)
+ (erts-mode--in-test-p (point))))
+ (if (and (not (erts-mode--in-test-p (point)))
+ (re-search-forward "^=-=$" nil t))
+ (progn
+ (goto-char (match-beginning 0))
+ (cdr (assq 'code (ert--erts-specifications (point)))))
+ (read-string "Transformation function: "))))
+ erts-mode)
+ (save-excursion
+ (erts-mode--goto-start-of-test)
+ (condition-case arg
+ (ert-test--erts-test
+ (list (cons 'dummy t)
+ (cons 'code (car (read-from-string test-function))))
+ (buffer-file-name))
+ (:success (message "Test successful"))
+ (ert-test-failed (message "Test failure; result: \n%s"
+ (substring-no-properties (cadr (cadr arg))))))))
+
+(defun erts-mode--goto-start-of-test ()
+ (if (not (erts-mode--in-test-p (point)))
+ (re-search-forward "^=-=\n" nil t)
+ (re-search-backward "^=-=\n" nil t)
+ (let ((potential-start (match-end 0)))
+ ;; See if we're in a two-clause ("before" and "after") test or not.
+ (if-let ((start (and (save-excursion (re-search-backward "^=-=\n" nil t))
+ (match-end 0))))
+ (let ((end (save-excursion (re-search-backward "^=-=-=\n" nil t))))
+ (if (or (not end)
+ (> start end))
+ ;; We are, so go to the real start.
+ (goto-char start)
+ (goto-char potential-start)))
+ (goto-char potential-start)))))
+
+(provide 'erts-mode)
+
+;;; erts-mode.el ends here
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index f53b09d9e8c..d2ce813daae 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -292,7 +292,7 @@ file the tag was in."
(or (locate-dominating-file default-directory "TAGS")
default-directory)))
(list (read-file-name
- "Visit tags table (default TAGS): "
+ (format-prompt "Visit tags table" "TAGS")
;; default to TAGS from default-directory up to root.
default-tag-dir
(expand-file-name "TAGS" default-tag-dir)
@@ -625,7 +625,7 @@ Returns t if it visits a tags table, or nil if there are no more in the list."
(car list))
;; Finally, prompt the user for a file name.
(expand-file-name
- (read-file-name "Visit tags table (default TAGS): "
+ (read-file-name (format-prompt "Visit tags table" "TAGS")
default-directory
"TAGS"
t))))))
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index ec2850737c8..001989e39ad 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -1057,11 +1057,9 @@ REGEXP is used as a string in the prompt."
default-extension
(car grep-files-history)
(car (car grep-files-aliases))))
- (files (completing-read
- (concat "Search for \"" regexp
- "\" in files matching wildcard"
- (if default (concat " (default " default ")"))
- ": ")
+ (files (completing-read
+ (format-prompt "Search for \"%s\" in files matching wildcard"
+ default regexp)
#'read-file-name-internal
nil nil nil 'grep-files-history
(delete-dups
diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el
index a18a67249ae..87732c10489 100644
--- a/lisp/progmodes/hideif.el
+++ b/lisp/progmodes/hideif.el
@@ -2456,7 +2456,7 @@ This allows #ifdef VAR to be hidden."
(t
nil))))
(var (read-minibuffer "Define what? " default))
- (val (read-from-minibuffer (format "Set %s to? (default 1): " var)
+ (val (read-from-minibuffer (format-prompt "Set %s to?" "1" var)
nil nil t nil "1")))
(list var val)))
(hif-set-var var (or val 1))
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index 845ca8609d7..f6603f86d5f 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -33,7 +33,7 @@
;; The main features of this JavaScript mode are syntactic
;; highlighting (enabled with `font-lock-mode' or
;; `global-font-lock-mode'), automatic indentation and filling of
-;; comments, C preprocessor fontification, and MozRepl integration.
+;; comments, and C preprocessor fontification.
;;
;; General Remarks:
;;
@@ -51,7 +51,6 @@
(require 'cc-fonts))
(require 'newcomment)
(require 'imenu)
-(require 'moz nil t)
(require 'json)
(require 'prog-mode)
@@ -59,12 +58,9 @@
(require 'cl-lib)
(require 'ido))
-(defvar inferior-moz-buffer)
-(defvar moz-repl-name)
(defvar ido-cur-list)
(defvar electric-layout-rules)
(declare-function ido-mode "ido" (&optional arg))
-(declare-function inferior-moz-process "ext:mozrepl" ())
;;; Constants
@@ -485,25 +481,22 @@ seldom use, either globally or on a per-buffer basis."
(list 'const x))
js--available-frameworks)))
-(defcustom js-js-switch-tabs
- (and (memq system-type '(darwin)) t)
+(defvar js-js-switch-tabs (and (memq system-type '(darwin)) t)
"Whether `js-mode' should display tabs while selecting them.
This is useful only if the windowing system has a good mechanism
-for preventing Firefox from stealing the keyboard focus."
- :type 'boolean)
+for preventing Firefox from stealing the keyboard focus.")
+(make-obsolete-variable 'js-js-switch-tabs "MozRepl no longer exists" "28.1")
-(defcustom js-js-tmpdir
- (locate-user-emacs-file "js/js")
+(defvar js-js-tmpdir (locate-user-emacs-file "js/js")
"Temporary directory used by `js-mode' to communicate with Mozilla.
-This directory must be readable and writable by both Mozilla and Emacs."
- :type 'directory
- :version "28.1")
+This directory must be readable and writable by both Mozilla and Emacs.")
+(make-obsolete-variable 'js-js-tmpdir "MozRepl no longer exists" "28.1")
-(defcustom js-js-timeout 5
+(defvar js-js-timeout 5
"Reply timeout for executing commands in Mozilla via `js-mode'.
The value is given in seconds. Increase this value if you are
-getting timeout messages."
- :type 'integer)
+getting timeout messages.")
+(make-obsolete-variable 'js-js-timeout "MozRepl no longer exists" "28.1")
(defcustom js-indent-first-init nil
"Non-nil means specially indent the first variable declaration's initializer.
@@ -671,18 +664,7 @@ This variable is like `sgml-attribute-offset'."
(defvar js-mode-map
(let ((keymap (make-sparse-keymap)))
- (define-key keymap [(control ?c) (meta ?:)] #'js-eval)
- (define-key keymap [(control ?c) (control ?j)] #'js-set-js-context)
- (define-key keymap [(control meta ?x)] #'js-eval-defun)
(define-key keymap [(meta ?.)] #'js-find-symbol)
- (easy-menu-define nil keymap "JavaScript Menu"
- '("JavaScript"
- ["Select New Mozilla Context..." js-set-js-context
- (fboundp #'inferior-moz-process)]
- ["Evaluate Expression in Mozilla Context..." js-eval
- (fboundp #'inferior-moz-process)]
- ["Send Current Function to Mozilla..." js-eval-defun
- (fboundp #'inferior-moz-process)]))
keymap)
"Keymap for `js-mode'.")
@@ -3336,1106 +3318,6 @@ current buffer. Pushes a mark onto the tag ring just like
(push-mark)
(goto-char marker)))
-;;; MozRepl integration
-
-(define-error 'js-moz-bad-rpc "Mozilla RPC Error") ;; '(timeout error))
-(define-error 'js-js-error "JavaScript Error") ;; '(js-error error))
-
-(defun js--wait-for-matching-output
- (process regexp timeout &optional start)
- "Wait TIMEOUT seconds for PROCESS to output a match for REGEXP.
-On timeout, return nil. On success, return t with match data
-set. If START is non-nil, look for output starting from START.
-Otherwise, use the current value of `process-mark'."
- (with-current-buffer (process-buffer process)
- (cl-loop with start-pos = (or start
- (marker-position (process-mark process)))
- with end-time = (time-add nil timeout)
- for time-left = (float-time (time-subtract end-time nil))
- do (goto-char (point-max))
- if (looking-back regexp start-pos) return t
- while (> time-left 0)
- do (accept-process-output process time-left nil t)
- do (goto-char (process-mark process))
- finally do (signal
- 'js-moz-bad-rpc
- (list (format "Timed out waiting for output matching %S" regexp))))))
-
-(cl-defstruct js--js-handle
- ;; Integer, mirrors the value we see in JS
- (id nil :read-only t)
-
- ;; Process to which this thing belongs
- (process nil :read-only t))
-
-(defun js--js-handle-expired-p (x)
- (not (eq (js--js-handle-process x)
- (inferior-moz-process))))
-
-(defvar js--js-references nil
- "Maps Elisp JavaScript proxy objects to their JavaScript IDs.")
-
-(defvar js--js-process nil
- "The most recent MozRepl process object.")
-
-(defvar js--js-gc-idle-timer nil
- "Idle timer for cleaning up JS object references.")
-
-(defvar js--js-last-gcs-done nil)
-
-(defconst js--moz-interactor
- (replace-regexp-in-string
- "[ \n]+" " "
- ; */" Make Emacs happy
-"(function(repl) {
- repl.defineInteractor('js', {
- onStart: function onStart(repl) {
- if(!repl._jsObjects) {
- repl._jsObjects = {};
- repl._jsLastID = 0;
- repl._jsGC = this._jsGC;
- }
- this._input = '';
- },
-
- _jsGC: function _jsGC(ids_in_use) {
- var objects = this._jsObjects;
- var keys = [];
- var num_freed = 0;
-
- for(var pn in objects) {
- keys.push(Number(pn));
- }
-
- keys.sort(function(x, y) x - y);
- ids_in_use.sort(function(x, y) x - y);
- var i = 0;
- var j = 0;
-
- while(i < ids_in_use.length && j < keys.length) {
- var id = ids_in_use[i++];
- while(j < keys.length && keys[j] !== id) {
- var k_id = keys[j++];
- delete objects[k_id];
- ++num_freed;
- }
- ++j;
- }
-
- while(j < keys.length) {
- var k_id = keys[j++];
- delete objects[k_id];
- ++num_freed;
- }
-
- return num_freed;
- },
-
- _mkArray: function _mkArray() {
- var result = [];
- for(var i = 0; i < arguments.length; ++i) {
- result.push(arguments[i]);
- }
- return result;
- },
-
- _parsePropDescriptor: function _parsePropDescriptor(parts) {
- if(typeof parts === 'string') {
- parts = [ parts ];
- }
-
- var obj = parts[0];
- var start = 1;
-
- if(typeof obj === 'string') {
- obj = window;
- start = 0;
- } else if(parts.length < 2) {
- throw new Error('expected at least 2 arguments');
- }
-
- for(var i = start; i < parts.length - 1; ++i) {
- obj = obj[parts[i]];
- }
-
- return [obj, parts[parts.length - 1]];
- },
-
- _getProp: function _getProp(/*...*/) {
- if(arguments.length === 0) {
- throw new Error('no arguments supplied to getprop');
- }
-
- if(arguments.length === 1 &&
- (typeof arguments[0]) !== 'string')
- {
- return arguments[0];
- }
-
- var [obj, propname] = this._parsePropDescriptor(arguments);
- return obj[propname];
- },
-
- _putProp: function _putProp(properties, value) {
- var [obj, propname] = this._parsePropDescriptor(properties);
- obj[propname] = value;
- },
-
- _delProp: function _delProp(propname) {
- var [obj, propname] = this._parsePropDescriptor(arguments);
- delete obj[propname];
- },
-
- _typeOf: function _typeOf(thing) {
- return typeof thing;
- },
-
- _callNew: function(constructor) {
- if(typeof constructor === 'string')
- {
- constructor = window[constructor];
- } else if(constructor.length === 1 &&
- typeof constructor[0] !== 'string')
- {
- constructor = constructor[0];
- } else {
- var [obj,propname] = this._parsePropDescriptor(constructor);
- constructor = obj[propname];
- }
-
- /* Hacky, but should be robust */
- var s = 'new constructor(';
- for(var i = 1; i < arguments.length; ++i) {
- if(i != 1) {
- s += ',';
- }
-
- s += 'arguments[' + i + ']';
- }
-
- s += ')';
- return eval(s);
- },
-
- _callEval: function(thisobj, js) {
- return eval.call(thisobj, js);
- },
-
- getPrompt: function getPrompt(repl) {
- return 'EVAL>'
- },
-
- _lookupObject: function _lookupObject(repl, id) {
- if(typeof id === 'string') {
- switch(id) {
- case 'global':
- return window;
- case 'nil':
- return null;
- case 't':
- return true;
- case 'false':
- return false;
- case 'undefined':
- return undefined;
- case 'repl':
- return repl;
- case 'interactor':
- return this;
- case 'NaN':
- return NaN;
- case 'Infinity':
- return Infinity;
- case '-Infinity':
- return -Infinity;
- default:
- throw new Error('No object with special id:' + id);
- }
- }
-
- var ret = repl._jsObjects[id];
- if(ret === undefined) {
- throw new Error('No object with id:' + id + '(' + typeof id + ')');
- }
- return ret;
- },
-
- _findOrAllocateObject: function _findOrAllocateObject(repl, value) {
- if(typeof value !== 'object' && typeof value !== 'function') {
- throw new Error('_findOrAllocateObject called on non-object('
- + typeof(value) + '): '
- + value)
- }
-
- for(var id in repl._jsObjects) {
- id = Number(id);
- var obj = repl._jsObjects[id];
- if(obj === value) {
- return id;
- }
- }
-
- var id = ++repl._jsLastID;
- repl._jsObjects[id] = value;
- return id;
- },
-
- _fixupList: function _fixupList(repl, list) {
- for(var i = 0; i < list.length; ++i) {
- if(list[i] instanceof Array) {
- this._fixupList(repl, list[i]);
- } else if(typeof list[i] === 'object') {
- var obj = list[i];
- if(obj.funcall) {
- var parts = obj.funcall;
- this._fixupList(repl, parts);
- var [thisobj, func] = this._parseFunc(parts[0]);
- list[i] = func.apply(thisobj, parts.slice(1));
- } else if(obj.objid) {
- list[i] = this._lookupObject(repl, obj.objid);
- } else {
- throw new Error('Unknown object type: ' + obj.toSource());
- }
- }
- }
- },
-
- _parseFunc: function(func) {
- var thisobj = null;
-
- if(typeof func === 'string') {
- func = window[func];
- } else if(func instanceof Array) {
- if(func.length === 1 && typeof func[0] !== 'string') {
- func = func[0];
- } else {
- [thisobj, func] = this._parsePropDescriptor(func);
- func = thisobj[func];
- }
- }
-
- return [thisobj,func];
- },
-
- _encodeReturn: function(value, array_as_mv) {
- var ret;
-
- if(value === null) {
- ret = ['special', 'null'];
- } else if(value === true) {
- ret = ['special', 'true'];
- } else if(value === false) {
- ret = ['special', 'false'];
- } else if(value === undefined) {
- ret = ['special', 'undefined'];
- } else if(typeof value === 'number') {
- if(isNaN(value)) {
- ret = ['special', 'NaN'];
- } else if(value === Infinity) {
- ret = ['special', 'Infinity'];
- } else if(value === -Infinity) {
- ret = ['special', '-Infinity'];
- } else {
- ret = ['atom', value];
- }
- } else if(typeof value === 'string') {
- ret = ['atom', value];
- } else if(array_as_mv && value instanceof Array) {
- ret = ['array', value.map(this._encodeReturn, this)];
- } else {
- ret = ['objid', this._findOrAllocateObject(repl, value)];
- }
-
- return ret;
- },
-
- _handleInputLine: function _handleInputLine(repl, line) {
- var ret;
- var array_as_mv = false;
-
- try {
- if(line[0] === '*') {
- array_as_mv = true;
- line = line.substring(1);
- }
- var parts = eval(line);
- this._fixupList(repl, parts);
- var [thisobj, func] = this._parseFunc(parts[0]);
- ret = this._encodeReturn(
- func.apply(thisobj, parts.slice(1)),
- array_as_mv);
- } catch(x) {
- ret = ['error', x.toString() ];
- }
-
- var JSON = Components.classes['@mozilla.org/dom/json;1'].createInstance(Components.interfaces.nsIJSON);
- repl.print(JSON.encode(ret));
- repl._prompt();
- },
-
- handleInput: function handleInput(repl, chunk) {
- this._input += chunk;
- var match, line;
- while(match = this._input.match(/.*\\n/)) {
- line = match[0];
-
- if(line === 'EXIT\\n') {
- repl.popInteractor();
- repl._prompt();
- return;
- }
-
- this._input = this._input.substring(line.length);
- this._handleInputLine(repl, line);
- }
- }
- });
-})
-")
-
- "String to set MozRepl up into a simple-minded evaluation mode.")
-
-(defun js--js-encode-value (x)
- "Marshall the given value for JS.
-Strings and numbers are JSON-encoded. Lists (including nil) are
-made into JavaScript array literals and their contents encoded
-with `js--js-encode-value'."
- (cond ((or (stringp x) (numberp x)) (json-encode x))
- ((symbolp x) (format "{objid:%S}" (symbol-name x)))
- ((js--js-handle-p x)
-
- (when (js--js-handle-expired-p x)
- (error "Stale JS handle"))
-
- (format "{objid:%s}" (js--js-handle-id x)))
-
- ((sequencep x)
- (if (eq (car-safe x) 'js--funcall)
- (format "{funcall:[%s]}"
- (mapconcat #'js--js-encode-value (cdr x) ","))
- (concat
- "[" (mapconcat #'js--js-encode-value x ",") "]")))
- (t
- (error "Unrecognized item: %S" x))))
-
-(defconst js--js-prompt-regexp "\\(repl[0-9]*\\)> $")
-(defconst js--js-repl-prompt-regexp "^EVAL>$")
-(defvar js--js-repl-depth 0)
-
-(defun js--js-wait-for-eval-prompt ()
- (js--wait-for-matching-output
- (inferior-moz-process)
- js--js-repl-prompt-regexp js-js-timeout
-
- ;; start matching against the beginning of the line in
- ;; order to catch a prompt that's only partially arrived
- (save-excursion (forward-line 0) (point))))
-
-;; Presumably "inferior-moz-process" loads comint.
-(declare-function comint-send-string "comint" (process string))
-(declare-function comint-send-input "comint"
- (&optional no-newline artificial))
-
-(defun js--js-enter-repl ()
- (inferior-moz-process) ; called for side-effect
- (with-current-buffer inferior-moz-buffer
- (goto-char (point-max))
-
- ;; Do some initialization the first time we see a process
- (unless (eq (inferior-moz-process) js--js-process)
- (setq js--js-process (inferior-moz-process))
- (setq js--js-references (make-hash-table :test 'eq :weakness t))
- (setq js--js-repl-depth 0)
-
- ;; Send interactor definition
- (comint-send-string js--js-process js--moz-interactor)
- (comint-send-string js--js-process
- (concat "(" moz-repl-name ")\n"))
- (js--wait-for-matching-output
- (inferior-moz-process) js--js-prompt-regexp
- js-js-timeout))
-
- ;; Sanity check
- (when (looking-back js--js-prompt-regexp
- (save-excursion (forward-line 0) (point)))
- (setq js--js-repl-depth 0))
-
- (if (> js--js-repl-depth 0)
- ;; If js--js-repl-depth > 0, we *should* be seeing an
- ;; EVAL> prompt. If we don't, give Mozilla a chance to catch
- ;; up with us.
- (js--js-wait-for-eval-prompt)
-
- ;; Otherwise, tell Mozilla to enter the interactor mode
- (insert (match-string-no-properties 1)
- ".pushInteractor('js')")
- (comint-send-input nil t)
- (js--wait-for-matching-output
- (inferior-moz-process) js--js-repl-prompt-regexp
- js-js-timeout))
-
- (cl-incf js--js-repl-depth)))
-
-(defun js--js-leave-repl ()
- (cl-assert (> js--js-repl-depth 0))
- (when (= 0 (cl-decf js--js-repl-depth))
- (with-current-buffer inferior-moz-buffer
- (goto-char (point-max))
- (js--js-wait-for-eval-prompt)
- (insert "EXIT")
- (comint-send-input nil t)
- (js--wait-for-matching-output
- (inferior-moz-process) js--js-prompt-regexp
- js-js-timeout))))
-
-(defsubst js--js-not (value)
- (memq value '(nil null false undefined)))
-
-(defsubst js--js-true (value)
- (not (js--js-not value)))
-
-(eval-and-compile
- (defun js--optimize-arglist (arglist)
- "Convert immediate js< and js! references to deferred ones."
- (cl-loop for item in arglist
- if (eq (car-safe item) 'js<)
- collect (append (list 'list ''js--funcall
- '(list 'interactor "_getProp"))
- (js--optimize-arglist (cdr item)))
- else if (eq (car-safe item) 'js>)
- collect (append (list 'list ''js--funcall
- '(list 'interactor "_putProp"))
-
- (if (atom (cadr item))
- (list (cadr item))
- (list
- (append
- (list 'list ''js--funcall
- '(list 'interactor "_mkArray"))
- (js--optimize-arglist (cadr item)))))
- (js--optimize-arglist (cddr item)))
- else if (eq (car-safe item) 'js!)
- collect (pcase-let ((`(,_ ,function . ,body) item))
- (append (list 'list ''js--funcall
- (if (consp function)
- (cons 'list
- (js--optimize-arglist function))
- function))
- (js--optimize-arglist body)))
- else
- collect item)))
-
-(defmacro js--js-get-service (class-name interface-name)
- `(js! ("Components" "classes" ,class-name "getService")
- (js< "Components" "interfaces" ,interface-name)))
-
-(defmacro js--js-create-instance (class-name interface-name)
- `(js! ("Components" "classes" ,class-name "createInstance")
- (js< "Components" "interfaces" ,interface-name)))
-
-(defmacro js--js-qi (object interface-name)
- `(js! (,object "QueryInterface")
- (js< "Components" "interfaces" ,interface-name)))
-
-(defmacro with-js (&rest forms)
- "Run FORMS with the Mozilla repl set up for js commands.
-Inside the lexical scope of `with-js', `js?', `js!',
-`js-new', `js-eval', `js-list', `js<', `js>', `js-get-service',
-`js-create-instance', and `js-qi' are defined."
- (declare (indent 0) (debug t))
- `(progn
- (js--js-enter-repl)
- (unwind-protect
- (cl-macrolet ((js? (&rest body) `(js--js-true ,@body))
- (js! (function &rest body)
- `(js--js-funcall
- ,(if (consp function)
- (cons 'list
- (js--optimize-arglist function))
- function)
- ,@(js--optimize-arglist body)))
-
- (js-new (function &rest body)
- `(js--js-new
- ,(if (consp function)
- (cons 'list
- (js--optimize-arglist function))
- function)
- ,@body))
-
- (js-eval (thisobj js)
- `(js--js-eval
- ,@(js--optimize-arglist
- (list thisobj js))))
-
- (js-list (&rest args)
- `(js--js-list
- ,@(js--optimize-arglist args)))
-
- (js-get-service (&rest args)
- `(js--js-get-service
- ,@(js--optimize-arglist args)))
-
- (js-create-instance (&rest args)
- `(js--js-create-instance
- ,@(js--optimize-arglist args)))
-
- (js-qi (&rest args)
- `(js--js-qi
- ,@(js--optimize-arglist args)))
-
- (js< (&rest body) `(js--js-get
- ,@(js--optimize-arglist body)))
- (js> (props value)
- `(js--js-funcall
- '(interactor "_putProp")
- ,(if (consp props)
- (cons 'list
- (js--optimize-arglist props))
- props)
- ,@(js--optimize-arglist (list value))
- ))
- (js-handle? (arg) `(js--js-handle-p ,arg)))
- ,@forms)
- (js--js-leave-repl))))
-
-(defvar js--js-array-as-list nil
- "Whether to listify any Array returned by a Mozilla function.
-If nil, the whole Array is treated as a JS symbol.")
-
-(defun js--js-decode-retval (result)
- (pcase (intern (cl-first result))
- ('atom (cl-second result))
- ('special (intern (cl-second result)))
- ('array
- (mapcar #'js--js-decode-retval (cl-second result)))
- ('objid
- (or (gethash (cl-second result)
- js--js-references)
- (puthash (cl-second result)
- (make-js--js-handle
- :id (cl-second result)
- :process (inferior-moz-process))
- js--js-references)))
-
- ('error (signal 'js-js-error (list (cl-second result))))
- (x (error "Unmatched case in js--js-decode-retval: %S" x))))
-
-(defvar comint-last-input-end)
-
-(defun js--js-funcall (function &rest arguments)
- "Call the Mozilla function FUNCTION with arguments ARGUMENTS.
-If function is a string, look it up as a property on the global
-object and use the global object for `this'.
-If FUNCTION is a list with one element, use that element as the
-function with the global object for `this', except that if that
-single element is a string, look it up on the global object.
-If FUNCTION is a list with more than one argument, use the list
-up to the last value as a property descriptor and the last
-argument as a function."
-
- (with-js
- (let ((argstr (js--js-encode-value
- (cons function arguments))))
-
- (with-current-buffer inferior-moz-buffer
- ;; Actual funcall
- (when js--js-array-as-list
- (insert "*"))
- (insert argstr)
- (comint-send-input nil t)
- (js--wait-for-matching-output
- (inferior-moz-process) "EVAL>"
- js-js-timeout)
- (goto-char comint-last-input-end)
-
- ;; Read the result
- (let* ((json-array-type 'list)
- (result (prog1 (json-read)
- (goto-char (point-max)))))
- (js--js-decode-retval result))))))
-
-(defun js--js-new (constructor &rest arguments)
- "Call CONSTRUCTOR as a constructor, with arguments ARGUMENTS.
-CONSTRUCTOR is a JS handle, a string, or a list of these things."
- (apply #'js--js-funcall
- '(interactor "_callNew")
- constructor arguments))
-
-(defun js--js-eval (thisobj js)
- (js--js-funcall '(interactor "_callEval") thisobj js))
-
-(defun js--js-list (&rest arguments)
- "Return a Lisp array resulting from evaluating each of ARGUMENTS."
- (let ((js--js-array-as-list t))
- (apply #'js--js-funcall '(interactor "_mkArray")
- arguments)))
-
-(defun js--js-get (&rest props)
- (apply #'js--js-funcall '(interactor "_getProp") props))
-
-(defun js--js-put (props value)
- (js--js-funcall '(interactor "_putProp") props value))
-
-(defun js-gc (&optional force)
- "Tell the repl about any objects we don't reference anymore.
-With argument, run even if no intervening GC has happened."
- (interactive)
-
- (when force
- (setq js--js-last-gcs-done nil))
-
- (let ((this-gcs-done gcs-done) keys num)
- (when (and js--js-references
- (boundp 'inferior-moz-buffer)
- (buffer-live-p inferior-moz-buffer)
-
- ;; Don't bother running unless we've had an intervening
- ;; garbage collection; without a gc, nothing is deleted
- ;; from the weak hash table, so it's pointless telling
- ;; MozRepl about that references we still hold
- (not (eq js--js-last-gcs-done this-gcs-done))
-
- ;; Are we looking at a normal prompt? Make sure not to
- ;; interrupt the user if he's doing something
- (with-current-buffer inferior-moz-buffer
- (save-excursion
- (goto-char (point-max))
- (looking-back js--js-prompt-regexp
- (save-excursion (forward-line 0) (point))))))
-
- (setq keys (cl-loop for x being the hash-keys
- of js--js-references
- collect x))
- (setq num (js--js-funcall '(repl "_jsGC") (or keys [])))
-
- (setq js--js-last-gcs-done this-gcs-done)
- (when (called-interactively-p 'interactive)
- (message "Cleaned %s entries" num))
-
- num)))
-
-(run-with-idle-timer 30 t #'js-gc)
-
-(defun js-eval (js)
- "Evaluate the JavaScript in JS and return JSON-decoded result."
- (interactive "MJavaScript to evaluate: ")
- (with-js
- (let* ((content-window (js--js-content-window
- (js--get-js-context)))
- (result (js-eval content-window js)))
- (when (called-interactively-p 'interactive)
- (message "%s" (js! "String" result)))
- result)))
-
-(defun js--get-tabs ()
- "Enumerate all JavaScript contexts available.
-Each context is a list:
- (TITLE URL BROWSER TAB TABBROWSER) for content documents
- (TITLE URL WINDOW) for windows
-
-All tabs of a given window are grouped together. The most recent
-window is first. Within each window, the tabs are returned
-left-to-right."
- (with-js
- (let (windows)
-
- (cl-loop with window-mediator = (js! ("Components" "classes"
- "@mozilla.org/appshell/window-mediator;1"
- "getService")
- (js< "Components" "interfaces"
- "nsIWindowMediator"))
- with enumerator = (js! (window-mediator "getEnumerator") nil)
-
- while (js? (js! (enumerator "hasMoreElements")))
- for window = (js! (enumerator "getNext"))
- for window-info = (js-list window
- (js< window "document" "title")
- (js! (window "location" "toString"))
- (js< window "closed")
- (js< window "windowState"))
-
- unless (or (js? (cl-fourth window-info))
- (eq (cl-fifth window-info) 2))
- do (push window-info windows))
-
- (cl-loop for (window title location) in windows
- collect (list title location window)
-
- for gbrowser = (js< window "gBrowser")
- if (js-handle? gbrowser)
- nconc (cl-loop
- for x below (js< gbrowser "browsers" "length")
- collect (js-list (js< gbrowser
- "browsers"
- x
- "contentDocument"
- "title")
-
- (js! (gbrowser
- "browsers"
- x
- "contentWindow"
- "location"
- "toString"))
- (js< gbrowser
- "browsers"
- x)
-
- (js! (gbrowser
- "tabContainer"
- "childNodes"
- "item")
- x)
-
- gbrowser))))))
-
-(defvar js-read-tab-history nil)
-
-(declare-function ido-chop "ido" (items elem))
-
-(defun js--read-tab (prompt)
- "Read a Mozilla tab with prompt PROMPT.
-Return a cons of (TYPE . OBJECT). TYPE is either `window' or
-`tab', and OBJECT is a JavaScript handle to a ChromeWindow or a
-browser, respectively."
-
- ;; Prime IDO
- (unless ido-mode
- (ido-mode 1)
- (ido-mode -1))
-
- (with-js
- (let ((tabs (js--get-tabs)) selected-tab-cname
- selected-tab prev-hitab)
-
- ;; Disambiguate names
- (setq tabs
- (cl-loop with tab-names = (make-hash-table :test 'equal)
- for tab in tabs
- for cname = (format "%s (%s)"
- (cl-second tab) (cl-first tab))
- for num = (cl-incf (gethash cname tab-names -1))
- if (> num 0)
- do (setq cname (format "%s <%d>" cname num))
- collect (cons cname tab)))
-
- (cl-labels
- ((find-tab-by-cname
- (cname)
- (cl-loop for tab in tabs
- if (equal (car tab) cname)
- return (cdr tab)))
-
- (mogrify-highlighting
- (hitab unhitab)
-
- ;; Hack to reduce the number of
- ;; round-trips to mozilla
- (let (cmds)
- (cond
- ;; Highlighting tab
- ((cl-fourth hitab)
- (push '(js! ((cl-fourth hitab) "setAttribute")
- "style"
- "color: red; font-weight: bold")
- cmds)
-
- ;; Highlight window proper
- (push '(js! ((cl-third hitab)
- "setAttribute")
- "style"
- "border: 8px solid red")
- cmds)
-
- ;; Select tab, when appropriate
- (when js-js-switch-tabs
- (push
- '(js> ((cl-fifth hitab) "selectedTab") (cl-fourth hitab))
- cmds)))
-
- ;; Highlighting whole window
- ((cl-third hitab)
- (push '(js! ((cl-third hitab) "document"
- "documentElement" "setAttribute")
- "style"
- (concat "-moz-appearance: none;"
- "border: 8px solid red;"))
- cmds)))
-
- (cond
- ;; Unhighlighting tab
- ((cl-fourth unhitab)
- (push '(js! ((cl-fourth unhitab) "setAttribute") "style" "")
- cmds)
- (push '(js! ((cl-third unhitab) "setAttribute") "style" "")
- cmds))
-
- ;; Unhighlighting window
- ((cl-third unhitab)
- (push '(js! ((cl-third unhitab) "document"
- "documentElement" "setAttribute")
- "style" "")
- cmds)))
-
- (eval `(with-js
- (js-list ,@(nreverse cmds)))
- t)))
-
- (command-hook
- ()
- (let* ((tab (find-tab-by-cname (car ido-matches))))
- (mogrify-highlighting tab prev-hitab)
- (setq prev-hitab tab)))
-
- (setup-hook
- ()
- ;; Fiddle with the match list a bit: if our first match
- ;; is a tabbrowser window, rotate the match list until
- ;; the active tab comes up
- (let ((matched-tab (find-tab-by-cname (car ido-matches))))
- (when (and matched-tab
- (null (cl-fourth matched-tab))
- (equal "navigator:browser"
- (js! ((cl-third matched-tab)
- "document"
- "documentElement"
- "getAttribute")
- "windowtype")))
-
- (cl-loop with tab-to-match = (js< (cl-third matched-tab)
- "gBrowser"
- "selectedTab")
-
- for match in ido-matches
- for candidate-tab = (find-tab-by-cname match)
- if (eq (cl-fourth candidate-tab) tab-to-match)
- do (setq ido-cur-list
- (ido-chop ido-cur-list match))
- and return t)))
-
- (add-hook 'post-command-hook #'command-hook t t)))
-
-
- (unwind-protect
- ;; FIXME: Don't impose IDO on the user.
- (setq selected-tab-cname
- (let ((ido-minibuffer-setup-hook
- (cons #'setup-hook ido-minibuffer-setup-hook)))
- (ido-completing-read
- prompt
- (mapcar #'car tabs)
- nil t nil
- 'js-read-tab-history)))
-
- (when prev-hitab
- (mogrify-highlighting nil prev-hitab)
- (setq prev-hitab nil)))
-
- (add-to-history 'js-read-tab-history selected-tab-cname)
-
- (setq selected-tab (cl-loop for tab in tabs
- if (equal (car tab) selected-tab-cname)
- return (cdr tab)))
-
- (cons (if (cl-fourth selected-tab) 'browser 'window)
- (cl-third selected-tab))))))
-
-(defun js--guess-eval-defun-info (pstate)
- "Helper function for `js-eval-defun'.
-Return a list (NAME . CLASSPARTS), where CLASSPARTS is a list of
-strings making up the class name and NAME is the name of the
-function part."
- (cond ((and (= (length pstate) 3)
- (eq (js--pitem-type (cl-first pstate)) 'function)
- (= (length (js--pitem-name (cl-first pstate))) 1)
- (consp (js--pitem-type (cl-second pstate))))
-
- (append (js--pitem-name (cl-second pstate))
- (list (cl-first (js--pitem-name (cl-first pstate))))))
-
- ((and (= (length pstate) 2)
- (eq (js--pitem-type (cl-first pstate)) 'function))
-
- (append
- (butlast (js--pitem-name (cl-first pstate)))
- (list (car (last (js--pitem-name (cl-first pstate)))))))
-
- (t (error "Function not a toplevel defun or class member"))))
-
-(defvar js--js-context nil
- "The current JavaScript context.
-This is a cons like the one returned from `js--read-tab'.
-Change with `js-set-js-context'.")
-
-(defconst js--js-inserter
- "(function(func_info,func) {
- func_info.unshift('window');
- var obj = window;
- for(var i = 1; i < func_info.length - 1; ++i) {
- var next = obj[func_info[i]];
- if(typeof next !== 'object' && typeof next !== 'function') {
- next = obj.prototype && obj.prototype[func_info[i]];
- if(typeof next !== 'object' && typeof next !== 'function') {
- alert('Could not find ' + func_info.slice(0, i+1).join('.') +
- ' or ' + func_info.slice(0, i+1).join('.') + '.prototype');
- return;
- }
-
- func_info.splice(i+1, 0, 'prototype');
- ++i;
- }
- }
-
- obj[func_info[i]] = func;
- alert('Successfully updated '+func_info.join('.'));
- })")
-
-(defun js-set-js-context (context)
- "Set the JavaScript context to CONTEXT.
-When called interactively, prompt for CONTEXT."
- (interactive (list (js--read-tab "JavaScript Context: ")))
- (setq js--js-context context))
-
-(defun js--get-js-context ()
- "Return a valid JavaScript context.
-If one hasn't been set, or if it's stale, prompt for a new one."
- (with-js
- (when (or (null js--js-context)
- (js--js-handle-expired-p (cdr js--js-context))
- (pcase (car js--js-context)
- ('window (js? (js< (cdr js--js-context) "closed")))
- ('browser (not (js? (js< (cdr js--js-context)
- "contentDocument"))))
- (x (error "Unmatched case in js--get-js-context: %S" x))))
- (setq js--js-context (js--read-tab "JavaScript Context: ")))
- js--js-context))
-
-(defun js--js-content-window (context)
- (with-js
- (pcase (car context)
- ('window (cdr context))
- ('browser (js< (cdr context)
- "contentWindow" "wrappedJSObject"))
- (x (error "Unmatched case in js--js-content-window: %S" x)))))
-
-(defun js--make-nsilocalfile (path)
- (with-js
- (let ((file (js-create-instance "@mozilla.org/file/local;1"
- "nsILocalFile")))
- (js! (file "initWithPath") path)
- file)))
-
-(defun js--js-add-resource-alias (alias path)
- (with-js
- (let* ((io-service (js-get-service "@mozilla.org/network/io-service;1"
- "nsIIOService"))
- (res-prot (js! (io-service "getProtocolHandler") "resource"))
- (res-prot (js-qi res-prot "nsIResProtocolHandler"))
- (path-file (js--make-nsilocalfile path))
- (path-uri (js! (io-service "newFileURI") path-file)))
- (js! (res-prot "setSubstitution") alias path-uri))))
-
-(cl-defun js-eval-defun ()
- "Update a Mozilla tab using the JavaScript defun at point."
- (interactive)
-
- ;; This function works by generating a temporary file that contains
- ;; the function we'd like to insert. We then use the elisp-js bridge
- ;; to command mozilla to load this file by inserting a script tag
- ;; into the document we set. This way, debuggers and such will have
- ;; a way to find the source of the just-inserted function.
- ;;
- ;; We delete the temporary file if there's an error, but otherwise
- ;; we add an unload event listener on the Mozilla side to delete the
- ;; file.
-
- (save-excursion
- (let (begin end pstate defun-info temp-name defun-body)
- (js-end-of-defun)
- (setq end (point))
- (js--ensure-cache)
- (js-beginning-of-defun)
- (re-search-forward "\\_<function\\_>")
- (setq begin (match-beginning 0))
- (setq pstate (js--forward-pstate))
-
- (when (or (null pstate)
- (> (point) end))
- (error "Could not locate function definition"))
-
- (setq defun-info (js--guess-eval-defun-info pstate))
-
- (let ((overlay (make-overlay begin end)))
- (overlay-put overlay 'face 'highlight)
- (unwind-protect
- (unless (y-or-n-p (format "Send %s to Mozilla? "
- (mapconcat #'identity defun-info ".")))
- (message "") ; question message lingers until next command
- (cl-return-from js-eval-defun))
- (delete-overlay overlay)))
-
- (setq defun-body (buffer-substring-no-properties begin end))
-
- (make-directory js-js-tmpdir t)
-
- ;; (Re)register a Mozilla resource URL to point to the
- ;; temporary directory
- (js--js-add-resource-alias "js" js-js-tmpdir)
-
- (setq temp-name (make-temp-file (concat js-js-tmpdir
- "/js-")
- nil ".js"))
- (unwind-protect
- (with-js
- (with-temp-buffer
- (insert js--js-inserter)
- (insert "(")
- (let ((standard-output (current-buffer)))
- (json--print-list defun-info))
- (insert ",\n")
- (insert defun-body)
- (insert "\n)")
- (write-region (point-min) (point-max) temp-name
- nil 1))
-
- ;; Give Mozilla responsibility for deleting this file
- (let* ((content-window (js--js-content-window
- (js--get-js-context)))
- (content-document (js< content-window "document"))
- (head (if (js? (js< content-document "body"))
- ;; Regular content
- (js< (js! (content-document "getElementsByTagName")
- "head")
- 0)
- ;; Chrome
- (js< content-document "documentElement")))
- (elem (js! (content-document "createElementNS")
- "http://www.w3.org/1999/xhtml" "script")))
-
- (js! (elem "setAttribute") "type" "text/javascript")
- (js! (elem "setAttribute") "src"
- (format "resource://js/%s"
- (file-name-nondirectory temp-name)))
-
- (js! (head "appendChild") elem)
-
- (js! (content-window "addEventListener") "unload"
- (js! ((js-new
- "Function" "file"
- "return function() { file.remove(false) }"))
- (js--make-nsilocalfile temp-name))
- 'false)
- (setq temp-name nil)
-
-
-
- ))
-
- ;; temp-name is set to nil on success
- (when temp-name
- (delete-file temp-name))))))
-
;;; Syntax extensions
(defvar js-syntactic-mode-name t
diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el
index e6e6e40aa19..5938da542ac 100644
--- a/lisp/progmodes/pascal.el
+++ b/lisp/progmodes/pascal.el
@@ -1357,9 +1357,7 @@ The default is a name found in the buffer around point."
default ""))
(label
;; Do completion with default.
- (completing-read (if (not (string= default ""))
- (concat "Label (default " default "): ")
- "Label: ")
+ (completing-read (format-prompt "Label" default)
;; Complete with the defuns found in the
;; current-buffer.
(let ((buf (current-buffer)))
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index 59004e413eb..c36082bb6d0 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -2484,11 +2484,8 @@ Interaction supports completion."
(if (eq (try-completion default prolog-info-alist) nil)
(setq default nil))
;; Read the PredSpec from the user
- (completing-read
- (if (zerop (length default))
- "Help on predicate: "
- (concat "Help on predicate (default " default "): "))
- prolog-info-alist nil t nil nil default)))
+ (completing-read (format-prompt "Help on predicate" default)
+ prolog-info-alist nil t nil nil default)))
(defun prolog-build-info-alist (&optional verbose)
"Build an alist of all builtins and library predicates.
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index c58ac6f637d..b1f61c89a41 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -4671,7 +4671,10 @@ See `python-check-command' for the default."
target = obj
objtype = 'def'
if target:
- args = inspect.formatargspec(*argspec_function(target))
+ if hasattr(inspect, 'signature'):
+ args = str(inspect.signature(target))
+ else:
+ args = inspect.formatargspec(*argspec_function(target))
name = obj.__name__
doc = '{objtype} {name}{args}'.format(
objtype=objtype, name=name, args=args
@@ -4770,10 +4773,14 @@ Interactively, prompt for symbol."
(interactive
(let ((symbol (python-eldoc--get-symbol-at-point))
(enable-recursive-minibuffers t))
- (list (read-string (if symbol
- (format "Describe symbol (default %s): " symbol)
- "Describe symbol: ")
- nil nil symbol))))
+ (list (read-string
+ ;; `format-prompt' is new in Emacs 28.1.
+ (if (fboundp 'format-prompt)
+ (format-prompt "Describe symbol" symbol)
+ (if symbol
+ (format "Describe symbol (default %s): " symbol)
+ "Describe symbol: "))
+ nil nil symbol))))
(message (python-eldoc--get-doc-at-point symbol)))
(defun python-describe-at-point (symbol process)
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index 5dfbf87e452..454279ca17f 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -3219,14 +3219,7 @@ For both `:file' and `:completion', there can also be a
symbol
(let* ((default (plist-get plist :default))
(last-value (sql-default-value symbol))
- (prompt-def
- (if default
- (if (string-match "\\(\\):[ \t]*\\'" prompt)
- (replace-match (format " (default \"%s\")" default) t t prompt 1)
- (replace-regexp-in-string "[ \t]*\\'"
- (format " (default \"%s\") " default)
- prompt t t))
- prompt))
+ (prompt-def (format-prompt prompt default))
(use-dialog-box nil))
(cond
((plist-member plist :file)
@@ -3311,7 +3304,7 @@ function like this: (sql-get-login \\='user \\='password \\='database)."
(let ((plist (cdr-safe w)))
(pcase (or (car-safe w) w)
('user
- (sql-get-login-ext 'sql-user "User: " 'sql-user-history plist))
+ (sql-get-login-ext 'sql-user "User" 'sql-user-history plist))
('password
(setq-default sql-password
@@ -3330,14 +3323,14 @@ function like this: (sql-get-login \\='user \\='password \\='database)."
(read-passwd "Password: " nil (sql-default-value 'sql-password)))))
('server
- (sql-get-login-ext 'sql-server "Server: " 'sql-server-history plist))
+ (sql-get-login-ext 'sql-server "Server" 'sql-server-history plist))
('database
- (sql-get-login-ext 'sql-database "Database: "
+ (sql-get-login-ext 'sql-database "Database"
'sql-database-history plist))
('port
- (sql-get-login-ext 'sql-port "Port: "
+ (sql-get-login-ext 'sql-port "Port"
nil (append '(:number t) plist)))))))
(defun sql-find-sqli-buffer (&optional product connection)
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index 52c34d9fbc6..3dd9a5efc19 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -5478,8 +5478,11 @@ becomes:
(let* ((pop-up-windows t))
(let ((name (expand-file-name
(read-file-name
- (format "Find this error in: (default %s) "
- file)
+ ;; `format-prompt' is new in Emacs 28.1.
+ (if (fboundp 'format-prompt)
+ (format-prompt "Find this error in" file)
+ (format "Find this error in (default %s): "
+ file))
nil ;; dir
file t))))
(setq buffer
@@ -7863,14 +7866,14 @@ If search fails, other files are checked based on
(let* ((default (verilog-get-default-symbol))
;; The following variable is used in verilog-comp-function
(verilog-buffer-to-use (current-buffer))
- (label (if (not (string= default ""))
- ;; Do completion with default
- (completing-read (concat "Goto-Label: (default "
- default ") ")
- #'verilog-comp-defun nil nil "")
- ;; There is no default value. Complete without it
- (completing-read "Goto-Label: "
- #'verilog-comp-defun nil nil "")))
+ (label
+ (completing-read (cond ((fboundp 'format-prompt)
+ ;; `format-prompt' is new in Emacs 28.1.
+ (format-prompt "Goto-Label" default))
+ ((not (string= default ""))
+ (concat "Goto-Label (default " default "): "))
+ (t "Goto-Label: "))
+ #'verilog-comp-defun nil nil ""))
pt)
;; Make sure library paths are correct, in case need to resolve module
(verilog-auto-reeval-locals)
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 1feb6ef9153..f4716fe9a64 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1310,12 +1310,17 @@ definitions."
(xref--prompt-p this-command))
(let ((id
(completing-read
- (if def
- (format "%s (default %s): "
- (substring prompt 0 (string-match
- "[ :]+\\'" prompt))
- def)
- prompt)
+ ;; `format-prompt' is new in Emacs 28.1
+ (if (fboundp 'format-prompt)
+ (format-prompt (substring prompt 0 (string-match
+ "[ :]+\\'" prompt))
+ def)
+ (if def
+ (format "%s (default %s): "
+ (substring prompt 0 (string-match
+ "[ :]+\\'" prompt))
+ def)
+ prompt))
(xref-backend-identifier-completion-table backend)
nil nil nil
'xref--read-identifier-history def)))
diff --git a/lisp/ses.el b/lisp/ses.el
index ea966295b18..51843eab032 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -3774,7 +3774,9 @@ function is redefined."
(setq name (intern name))
(let* ((cur-printer (gethash name ses--local-printer-hashmap))
(default (and cur-printer (ses--locprn-def cur-printer))))
- (setq def (ses-read-printer (format "Enter definition of printer %S" name)
+ (setq def (ses-read-printer (format-prompt
+ "Enter definition of printer %S"
+ default name)
default)))
(list name def)))
diff --git a/lisp/simple.el b/lisp/simple.el
index bec4aa4738e..f7e62e06ce1 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -527,21 +527,31 @@ Other major modes are defined by comparison with this one."
(kill-all-local-variables)
(run-mode-hooks))
+(define-derived-mode clean-mode fundamental-mode "Clean"
+ "A mode that removes all overlays and text properties."
+ (kill-all-local-variables t)
+ (let ((inhibit-read-only t))
+ (dolist (overlay (overlays-in (point-min) (point-max)))
+ (delete-overlay overlay))
+ (set-text-properties (point-min) (point-max) nil)
+ (setq-local after-change-functions
+ (list
+ (lambda (begin end _length)
+ (set-text-properties begin end nil))))))
+
;; Special major modes to view specially formatted data rather than files.
-(defvar special-mode-map
- (let ((map (make-sparse-keymap)))
- (suppress-keymap map)
- (define-key map "q" 'quit-window)
- (define-key map " " 'scroll-up-command)
- (define-key map [?\S-\ ] 'scroll-down-command)
- (define-key map "\C-?" 'scroll-down-command)
- (define-key map "?" 'describe-mode)
- (define-key map "h" 'describe-mode)
- (define-key map ">" 'end-of-buffer)
- (define-key map "<" 'beginning-of-buffer)
- (define-key map "g" 'revert-buffer)
- map))
+(defvar-keymap special-mode-map
+ :suppress t
+ "q" #'quit-window
+ " " #'scroll-up-command
+ [?\S-\ ] #'scroll-down-command
+ "\C-?" #'scroll-down-command
+ "?" #'describe-mode
+ "h" #'describe-mode
+ ">" #'end-of-buffer
+ "<" #'beginning-of-buffer
+ "g" #'revert-buffer)
(put 'special-mode 'mode-class 'special)
(define-derived-mode special-mode nil "Special"
diff --git a/lisp/subr.el b/lisp/subr.el
index f8f446c6a92..9f0fe42f923 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -6460,4 +6460,111 @@ not a list, return a one-element list containing OBJECT."
object
(list object)))
+(defun define-keymap (&rest definitions)
+ "Create a new keymap and define KEY/DEFEFINITION pairs as key sequences.
+The new keymap is returned.
+
+Options can be given as keywords before the KEY/DEFEFINITION
+pairs. Available keywords are:
+
+:full If non-nil, create a chartable alist (see `make-keymap').
+ If nil (i.e., the default), create a sparse keymap (see
+ `make-sparse-keymap').
+
+:suppress If non-nil, the keymap will be suppressed (see `suppress-keymap').
+ If `nodigits', treat digits like other chars.
+
+:parent If non-nil, this should be a keymap to use as the parent
+ (see `set-keymap-parent').
+
+:keymap If non-nil, instead of creating a new keymap, the given keymap
+ will be destructively modified instead.
+
+:name If non-nil, this should be a string to use as the menu for
+ the keymap in case you use it as a menu with `x-popup-menu'.
+
+:prefix If non-nil, this should be a symbol to be used as a prefix
+ command (see `define-prefix-command'). If this is the case,
+ this symbol is returned instead of the map itself.
+
+KEY/DEFINITION pairs are as KEY and DEF in `define-key'. KEY can
+also be the special symbol `:menu', in which case DEFINITION
+should be a MENU form as accepted by `easy-menu-define'.
+
+\(fn &key FULL PARENT SUPPRESS NAME PREFIX KEYMAP &rest [KEY DEFINITION]...)"
+ (define-keymap--define definitions))
+
+(defun define-keymap--define (definitions)
+ (let (full suppress parent name prefix keymap)
+ ;; Handle keywords.
+ (while (and definitions
+ (keywordp (car definitions))
+ (not (eq (car definitions) :menu)))
+ (let ((keyword (pop definitions)))
+ (unless definitions
+ (error "Missing keyword value for %s" keyword))
+ (let ((value (pop definitions)))
+ (pcase keyword
+ (:full (setq full value))
+ (:keymap (setq keymap value))
+ (:parent (setq parent value))
+ (:suppress (setq suppress value))
+ (:name (setq name value))
+ (:prefix (setq prefix value))))))
+
+ (when (and prefix
+ (or full parent suppress keymap))
+ (error "A prefix keymap can't be defined with :full/:parent/:suppress/:keymap keywords"))
+
+ (when (and keymap full)
+ (error "Invalid combination: :keymap with :full"))
+
+ (let ((keymap (cond
+ (keymap keymap)
+ (prefix (define-prefix-command prefix nil name))
+ (full (make-keymap name))
+ (t (make-sparse-keymap name)))))
+ (when suppress
+ (suppress-keymap keymap (eq suppress 'nodigits)))
+ (when parent
+ (set-keymap-parent keymap parent))
+
+ ;; Do the bindings.
+ (while definitions
+ (let ((key (pop definitions)))
+ (unless definitions
+ (error "Uneven number of key/definition pairs"))
+ (let ((def (pop definitions)))
+ (if (eq key :menu)
+ (easy-menu-define nil keymap "" def)
+ (define-key keymap key def)))))
+ keymap)))
+
+(defmacro defvar-keymap (variable-name &rest defs)
+ "Define VARIABLE-NAME as a variable with a keymap definition.
+See `define-keymap' for an explanation of the keywords and KEY/DEFINITION.
+
+In addition to the keywords accepted by `define-keymap', this
+macro also accepts a `:doc' keyword, which (if present) is used
+as the variable documentation string.
+
+\(fn VARIABLE-NAME &key DOC FULL PARENT SUPPRESS NAME PREFIX KEYMAP &rest [KEY DEFINITION]...)"
+ (let ((opts nil)
+ doc)
+ (while (and defs
+ (keywordp (car defs))
+ (not (eq (car defs) :menu)))
+ (let ((keyword (pop defs)))
+ (unless defs
+ (error "Uneven number of keywords"))
+ (if (eq keyword :doc)
+ (setq doc (pop defs))
+ (push keyword opts)
+ (push (pop defs) opts))))
+ (unless (zerop (% (length defs) 2))
+ (error "Uneven number of key/definition pairs: %s" defs))
+ `(defvar ,variable-name
+ (define-keymap--define (list ,@(nreverse opts) ,@defs))
+ ,@(and doc (list doc)))))
+
;;; subr.el ends here
diff --git a/lisp/term.el b/lisp/term.el
index e76eb77647f..0e36e877e61 100644
--- a/lisp/term.el
+++ b/lisp/term.el
@@ -303,6 +303,7 @@
(require 'ange-ftp)
(require 'cl-lib))
(require 'comint) ; Password regexp.
+(require 'ansi-color)
(require 'ehelp)
(require 'ring)
(require 'shell)
@@ -710,13 +711,20 @@ Buffer local variable.")
(defvar term-ansi-at-save-pwd nil)
(defvar term-ansi-at-save-anon nil)
(defvar term-ansi-current-bold nil)
+(defvar term-ansi-current-faint nil)
+(defvar term-ansi-current-italic nil)
+(defvar term-ansi-current-underline nil)
+(defvar term-ansi-current-slow-blink nil)
+(defvar term-ansi-current-fast-blink nil)
(defvar term-ansi-current-color 0)
(defvar term-ansi-face-already-done nil)
(defvar term-ansi-current-bg-color 0)
-(defvar term-ansi-current-underline nil)
(defvar term-ansi-current-reverse nil)
(defvar term-ansi-current-invisible nil)
+(make-obsolete-variable 'term-ansi-face-already-done
+ "it doesn't have any effect." "29.1")
+
;;; Faces
(defvar ansi-term-color-vector
[term
@@ -765,12 +773,36 @@ Buffer local variable.")
:group 'term
:version "28.1")
+(defface term-faint
+ '((t :inherit ansi-color-faint))
+ "Default face to use for faint text."
+ :group 'term
+ :version "28.1")
+
+(defface term-italic
+ '((t :inherit ansi-color-italic))
+ "Default face to use for italic text."
+ :group 'term
+ :version "28.1")
+
(defface term-underline
'((t :inherit ansi-color-underline))
"Default face to use for underlined text."
:group 'term
:version "28.1")
+(defface term-slow-blink
+ '((t :inherit ansi-color-slow-blink))
+ "Default face to use for slowly blinking text."
+ :group 'term
+ :version "28.1")
+
+(defface term-fast-blink
+ '((t :inherit ansi-color-fast-blink))
+ "Default face to use for rapidly blinking text."
+ :group 'term
+ :version "28.1")
+
(defface term-color-black
'((t :inherit ansi-color-black))
"Face used to render black color code."
@@ -1034,15 +1066,15 @@ is buffer-local."
(defun term-ansi-reset ()
(setq term-current-face 'term)
- (setq term-ansi-current-underline nil)
(setq term-ansi-current-bold nil)
+ (setq term-ansi-current-faint nil)
+ (setq term-ansi-current-italic nil)
+ (setq term-ansi-current-underline nil)
+ (setq term-ansi-current-slow-blink nil)
+ (setq term-ansi-current-fast-blink nil)
(setq term-ansi-current-reverse nil)
(setq term-ansi-current-color 0)
(setq term-ansi-current-invisible nil)
- ;; Stefan thought this should be t, but could not remember why.
- ;; Setting it to t seems to cause bug#11785. Setting it to nil
- ;; again to see if there are other consequences...
- (setq term-ansi-face-already-done nil)
(setq term-ansi-current-bg-color 0))
(define-derived-mode term-mode fundamental-mode "Term"
@@ -1581,10 +1613,12 @@ Using \"emacs\" loses, because bash disables editing if $TERM == emacs.")
:nd=\\E[C:up=\\E[A:ce=\\E[K:ho=\\E[H:pt\
:al=\\E[L:dl=\\E[M:DL=\\E[%%dM:AL=\\E[%%dL:cs=\\E[%%i%%d;%%dr:sf=^J\
:dc=\\E[P:DC=\\E[%%dP:IC=\\E[%%d@:im=\\E[4h:ei=\\E[4l:mi:\
+:mb=\\E[5m:mh=\\E[2m:ZR=\\E[23m:ZH=\\E[3m\
:so=\\E[7m:se=\\E[m:us=\\E[4m:ue=\\E[m:md=\\E[1m:mr=\\E[7m:me=\\E[m\
:UP=\\E[%%dA:DO=\\E[%%dB:LE=\\E[%%dD:RI=\\E[%%dC\
:kl=\\EOD:kd=\\EOB:kr=\\EOC:ku=\\EOA:kN=\\E[6~:kP=\\E[5~:@7=\\E[4~:kh=\\E[1~\
-:mk=\\E[8m:cb=\\E[1K:op=\\E[39;49m:Co#8:pa#64:AB=\\E[4%%dm:AF=\\E[3%%dm:cr=^M\
+:mk=\\E[8m:cb=\\E[1K:op=\\E[39;49m:Co#256:pa#32767\
+:AB=\\E[48;5;%%dm:AF=\\E[38;5;%%dm:cr=^M\
:bl=^G:do=^J:le=^H:ta=^I:se=\\E[27m:ue=\\E[24m\
:kb=^?:kD=^[[3~:sc=\\E7:rc=\\E8:r1=\\Ec:"
;; : -undefine ic
@@ -3104,30 +3138,34 @@ See `term-prompt-regexp'."
(term-horizontal-column)
term-ansi-current-bg-color
term-ansi-current-bold
+ term-ansi-current-faint
+ term-ansi-current-italic
+ term-ansi-current-underline
+ term-ansi-current-slow-blink
+ term-ansi-current-fast-blink
term-ansi-current-color
term-ansi-current-invisible
term-ansi-current-reverse
- term-ansi-current-underline
term-current-face)))
(?8 ;; Restore cursor (terminfo: rc, [ctlseqs]
;; "DECRC").
(when term-saved-cursor
(term-goto (nth 0 term-saved-cursor)
(nth 1 term-saved-cursor))
- (setq term-ansi-current-bg-color
- (nth 2 term-saved-cursor)
- term-ansi-current-bold
- (nth 3 term-saved-cursor)
- term-ansi-current-color
- (nth 4 term-saved-cursor)
- term-ansi-current-invisible
- (nth 5 term-saved-cursor)
- term-ansi-current-reverse
- (nth 6 term-saved-cursor)
- term-ansi-current-underline
- (nth 7 term-saved-cursor)
- term-current-face
- (nth 8 term-saved-cursor))))
+ (pcase-setq
+ `( ,_ ,_
+ ,term-ansi-current-bg-color
+ ,term-ansi-current-bold
+ ,term-ansi-current-faint
+ ,term-ansi-current-italic
+ ,term-ansi-current-underline
+ ,term-ansi-current-slow-blink
+ ,term-ansi-current-fast-blink
+ ,term-ansi-current-color
+ ,term-ansi-current-invisible
+ ,term-ansi-current-reverse
+ ,term-current-face)
+ term-saved-cursor)))
(?c ;; \Ec - Reset (terminfo: rs1, [ctlseqs] "RIS").
;; This is used by the "clear" program.
(term-reset-terminal))
@@ -3285,133 +3323,141 @@ option is enabled. See `term-set-goto-process-mark'."
(setq term-current-row 0)
(setq term-current-column 1)
(term--reset-scroll-region)
- (setq term-insert-mode nil)
- ;; FIXME: No idea why this is here, it looks wrong. --Stef
- (setq term-ansi-face-already-done nil))
-
-(defun term--maybe-brighten-color (color bold)
- "Possibly convert COLOR to its bright variant.
-COLOR is an index into `ansi-term-color-vector'. If BOLD and
-`ansi-color-bold-is-bright' are non-nil and COLOR is a regular color,
-return the bright version of COLOR; otherwise, return COLOR."
- (if (and ansi-color-bold-is-bright bold (<= 1 color 8))
- (+ color 8)
- color))
+ (setq term-insert-mode nil))
+
+(defun term--color-as-hex (for-foreground)
+ "Return the current ANSI color as a hexadecimal color string.
+Use the current background color if FOR-FOREGROUND is nil,
+otherwise use the current foreground color."
+ (let ((color (if for-foreground term-ansi-current-color
+ term-ansi-current-bg-color)))
+ (or (ansi-color--code-as-hex (1- color))
+ (progn
+ (and ansi-color-bold-is-bright term-ansi-current-bold
+ (<= 1 color 8)
+ (setq color (+ color 8)))
+ (if for-foreground
+ (face-foreground (elt ansi-term-color-vector color)
+ nil 'default)
+ (face-background (elt ansi-term-color-vector color)
+ nil 'default))))))
;; New function to deal with ansi colorized output, as you can see you can
;; have any bold/underline/fg/bg/reverse combination. -mm
(defun term-handle-colors-array (parameter)
- (cond
-
- ;; Bold (terminfo: bold)
- ((eq parameter 1)
- (setq term-ansi-current-bold t))
-
- ;; Underline
- ((eq parameter 4)
- (setq term-ansi-current-underline t))
-
- ;; Blink (unsupported by Emacs), will be translated to bold.
- ;; This may change in the future though.
- ((eq parameter 5)
- (setq term-ansi-current-bold t))
-
- ;; Reverse (terminfo: smso)
- ((eq parameter 7)
- (setq term-ansi-current-reverse t))
-
- ;; Invisible
- ((eq parameter 8)
- (setq term-ansi-current-invisible t))
-
- ;; Reset underline (terminfo: rmul)
- ((eq parameter 24)
- (setq term-ansi-current-underline nil))
-
- ;; Reset reverse (terminfo: rmso)
- ((eq parameter 27)
- (setq term-ansi-current-reverse nil))
-
- ;; Foreground
- ((and (>= parameter 30) (<= parameter 37))
- (setq term-ansi-current-color (- parameter 29)))
-
- ;; Bright foreground
- ((and (>= parameter 90) (<= parameter 97))
- (setq term-ansi-current-color (- parameter 81)))
-
- ;; Reset foreground
- ((eq parameter 39)
- (setq term-ansi-current-color 0))
-
- ;; Background
- ((and (>= parameter 40) (<= parameter 47))
- (setq term-ansi-current-bg-color (- parameter 39)))
-
- ;; Bright foreground
- ((and (>= parameter 100) (<= parameter 107))
- (setq term-ansi-current-bg-color (- parameter 91)))
-
- ;; Reset background
- ((eq parameter 49)
- (setq term-ansi-current-bg-color 0))
-
- ;; 0 (Reset) or unknown (reset anyway)
- (t
- (term-ansi-reset)))
-
- ;; (message "Debug: U-%d R-%d B-%d I-%d D-%d F-%d B-%d"
- ;; term-ansi-current-underline
- ;; term-ansi-current-reverse
- ;; term-ansi-current-bold
- ;; term-ansi-current-invisible
- ;; term-ansi-face-already-done
- ;; term-ansi-current-color
- ;; term-ansi-current-bg-color)
-
- (unless term-ansi-face-already-done
- (let ((current-color (term--maybe-brighten-color
- term-ansi-current-color
- term-ansi-current-bold))
- (current-bg-color (term--maybe-brighten-color
- term-ansi-current-bg-color
- term-ansi-current-bold)))
- (if term-ansi-current-invisible
- (let ((color
- (if term-ansi-current-reverse
- (face-foreground
- (elt ansi-term-color-vector current-color)
- nil 'default)
- (face-background
- (elt ansi-term-color-vector current-bg-color)
- nil 'default))))
- (setq term-current-face
- (list :background color
- :foreground color))
- ) ;; No need to bother with anything else if it's invisible.
- (setq term-current-face
- (list :foreground
- (face-foreground
- (elt ansi-term-color-vector current-color)
- nil 'default)
- :background
- (face-background
- (elt ansi-term-color-vector current-bg-color)
- nil 'default)
- :inverse-video term-ansi-current-reverse))
-
- (when term-ansi-current-bold
- (setq term-current-face
- `(,term-current-face :inherit term-bold)))
-
- (when term-ansi-current-underline
- (setq term-current-face
- `(,term-current-face :inherit term-underline))))))
-
- ;; (message "Debug %S" term-current-face)
- ;; FIXME: shouldn't we set term-ansi-face-already-done to t here? --Stef
- (setq term-ansi-face-already-done nil))
+ (declare (obsolete term--handle-colors-list "29.1"))
+ (term--handle-colors-list (list parameter)))
+
+(defun term--handle-colors-list (parameters)
+ (while parameters
+ (pcase (pop parameters)
+ (1 (setq term-ansi-current-bold t)) ; (terminfo: bold)
+ (2 (setq term-ansi-current-faint t)) ; (terminfo: dim)
+ (3 (setq term-ansi-current-italic t)) ; (terminfo: sitm)
+ (4 (setq term-ansi-current-underline t)) ; (terminfo: smul)
+ (5 (setq term-ansi-current-slow-blink t)) ; (terminfo: blink)
+ (6 (setq term-ansi-current-fast-blink t))
+ (7 (setq term-ansi-current-reverse t)) ; (terminfo: smso, rev)
+ (8 (setq term-ansi-current-invisible t)) ; (terminfo: invis)
+ (21 (setq term-ansi-current-bold nil))
+ (22 (setq term-ansi-current-bold nil)
+ (setq term-ansi-current-faint nil))
+ (23 (setq term-ansi-current-italic nil)) ; (terminfo: ritm)
+ (24 (setq term-ansi-current-underline nil)) ; (terminfo: rmul)
+ (25 (setq term-ansi-current-slow-blink nil)
+ (setq term-ansi-current-fast-blink nil))
+ (27 (setq term-ansi-current-reverse nil)) ; (terminfo: rmso)
+
+ ;; Foreground (terminfo: setaf)
+ ((and param (guard (<= 30 param 37)))
+ (setq term-ansi-current-color (- param 29)))
+
+ ;; Bright foreground (terminfo: setaf)
+ ((and param (guard (<= 90 param 97)))
+ (setq term-ansi-current-color (- param 81)))
+
+ ;; Extended foreground (terminfo: setaf)
+ (38
+ (pcase (pop parameters)
+ ;; 256 color
+ (5 (if (setq term-ansi-current-color (pop parameters))
+ (cl-incf term-ansi-current-color)
+ (term-ansi-reset)))
+ ;; Full 24-bit color
+ (2 (cl-loop with color = (1+ 256) ; Base
+ for i from 16 downto 0 by 8
+ if (pop parameters)
+ do (setq color (+ color (ash it i)))
+ else return (term-ansi-reset)
+ finally
+ (if (> color (+ 1 256 #xFFFFFF))
+ (term-ansi-reset)
+ (setq term-ansi-current-color color))))
+ (_ (term-ansi-reset))))
+
+ ;; Reset foreground (terminfo: op)
+ (39 (setq term-ansi-current-color 0))
+
+ ;; Background (terminfo: setab)
+ ((and param (guard (<= 40 param 47)))
+ (setq term-ansi-current-bg-color (- param 39)))
+
+ ;; Bright background (terminfo: setab)
+ ((and param (guard (<= 100 param 107)))
+ (setq term-ansi-current-bg-color (- param 91)))
+
+ ;; Extended background (terminfo: setab)
+ (48
+ (pcase (pop parameters)
+ ;; 256 color
+ (5 (if (setq term-ansi-current-bg-color (pop parameters))
+ (cl-incf term-ansi-current-bg-color)
+ (term-ansi-reset)))
+ ;; Full 24-bit color
+ (2 (cl-loop with color = (1+ 256) ; Base
+ for i from 16 downto 0 by 8
+ if (pop parameters)
+ do (setq color (+ color (ash it i)))
+ else return (term-ansi-reset)
+ finally
+ (if (> color (+ 1 256 #xFFFFFF))
+ (term-ansi-reset)
+ (setq term-ansi-current-bg-color color))))
+ (_ (term-ansi-reset))))
+
+ ;; Reset background (terminfo: op)
+ (49 (setq term-ansi-current-bg-color 0))
+
+ ;; 0 (Reset) (terminfo: sgr0) or unknown (reset anyway)
+ (_ (term-ansi-reset))))
+
+ (let (fg bg)
+ (if term-ansi-current-invisible
+ (setq bg (term--color-as-hex term-ansi-current-reverse)
+ fg bg)
+ (setq fg (term--color-as-hex t)
+ bg (term--color-as-hex nil)))
+ (setq term-current-face
+ `( :foreground ,fg
+ :background ,bg
+ ,@(unless term-ansi-current-invisible
+ (list :inverse-video term-ansi-current-reverse)))))
+
+ (setq term-current-face
+ `(,term-current-face
+ ,@(when term-ansi-current-bold
+ '(term-bold))
+ ,@(when term-ansi-current-faint
+ '(term-faint))
+ ,@(when term-ansi-current-italic
+ '(term-italic))
+ ,@(when term-ansi-current-underline
+ '(term-underline))
+ ,@(when term-ansi-current-slow-blink
+ '(term-slow-blink))
+ ,@(when term-ansi-current-fast-blink
+ '(term-fast-blink)))))
;; Handle a character assuming (eq terminal-state 2) -
@@ -3497,9 +3543,9 @@ return the bright version of COLOR; otherwise, return COLOR."
;; Modified to allow ansi coloring -mm
;; \E[m - Set/reset modes, set bg/fg
- ;;(terminfo: smso,rmso,smul,rmul,rev,bold,sgr0,invis,op,setab,setaf)
+ ;;(terminfo: smso,rmso,smul,rmul,rev,bold,dim,sitm,ritm,blink,sgr0,invis,op,setab,setaf)
((eq char ?m)
- (mapc #'term-handle-colors-array params))
+ (term--handle-colors-list params))
;; \E[6n - Report cursor position (terminfo: u7)
((eq char ?n)
diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el
index c42286e5bc3..25f0c35aa5d 100644
--- a/lisp/textmodes/artist.el
+++ b/lisp/textmodes/artist.el
@@ -2840,9 +2840,8 @@ Returns a list of strings."
(if (memq system-type '(windows-nt ms-dos))
(artist-figlet-get-font-list-windows)
(artist-figlet-get-font-list)))
- (font (completing-read (concat "Select font (default "
- artist-figlet-default-font
- "): ")
+ (font (completing-read (format-prompt "Select font"
+ artist-figlet-default-font)
(mapcar
(lambda (font) (cons font font))
avail-fonts))))
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 237a1d99353..c06e8bfa1bb 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -4317,8 +4317,6 @@ for a crossref key, t otherwise."
(eqb (goto-char pos))
(t (set-buffer buffer) (goto-char pos)))
pos))
-;; backward compatibility
-(defalias 'bibtex-find-crossref 'bibtex-search-crossref)
(defun bibtex-dist (pos beg end)
"Return distance between POS and region delimited by BEG and END."
@@ -4381,8 +4379,6 @@ A prefix arg negates the value of `bibtex-search-entry-globally'."
(if display (bibtex-reposition-window)))
(display (message "Key `%s' not found" key)))
pnt)))
-;; backward compatibility
-(defalias 'bibtex-find-entry 'bibtex-search-entry)
(defun bibtex-prepare-new-entry (index)
"Prepare a new BibTeX entry with index INDEX.
@@ -5608,5 +5604,8 @@ If APPEND is non-nil, append ENTRIES to those already displayed."
(setq buffer-read-only t)
(goto-char (point-min)))
+(define-obsolete-function-alias 'bibtex-find-crossref #'bibtex-search-crossref "29.1")
+(define-obsolete-function-alias 'bibtex-find-entry #'bibtex-search-entry "29.1")
+
(provide 'bibtex)
;;; bibtex.el ends here
diff --git a/lisp/textmodes/reftex-parse.el b/lisp/textmodes/reftex-parse.el
index c521a07f192..b8c75cb21b6 100644
--- a/lisp/textmodes/reftex-parse.el
+++ b/lisp/textmodes/reftex-parse.el
@@ -345,7 +345,17 @@ of master file."
;; Find external document specifications
(goto-char 1)
- (while (re-search-forward "[\n\r][ \t]*\\\\externaldocument\\(\\[\\([^]]*\\)\\]\\)?{\\([^}]+\\)}" nil t)
+ (while (re-search-forward
+ (concat "[\n\r][ \t]*"
+ ;; Support \externalcitedocument macro
+ "\\\\external\\(?:cite\\)?document"
+ ;; The optional prefix
+ "\\(\\[\\([^]]*\\)\\]\\)?"
+ ;; The 2nd opt. arg can only be nocite
+ "\\(?:\\[nocite\\]\\)?"
+ ;; Mandatory file argument
+ "{\\([^}]+\\)}")
+ nil t)
(push (list 'xr-doc (reftex-match-string 2)
(reftex-match-string 3))
docstruct))
diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el
index 7ef8161ab5c..22a90ca9cfb 100644
--- a/lisp/textmodes/sgml-mode.el
+++ b/lisp/textmodes/sgml-mode.el
@@ -440,7 +440,8 @@ These have to be run via `sgml-syntax-propertize'"))
;; internal
(defvar sgml-face-tag-alist ()
- "Alist of face and tag name for facemenu.")
+ "Alist of face and tag name for facemenu.
+The tag name can be a string or a list of strings.")
(defvar sgml-tag-face-alist ()
"Tag names and face or list of faces to fontify with when invisible.
@@ -528,11 +529,13 @@ an optional alist of possible values."
(comment-indent-new-line soft)))
(defun sgml-mode-facemenu-add-face-function (face _end)
- (let ((tag-face (cdr (assq face sgml-face-tag-alist))))
+ "Add \"face\" tags with `facemenu-keymap' commands."
+ (let ((tag-face (ensure-list (cdr (assq face sgml-face-tag-alist)))))
(cond (tag-face
(setq tag-face (funcall skeleton-transformation-function tag-face))
- (setq facemenu-end-add-face (concat "</" tag-face ">"))
- (concat "<" tag-face ">"))
+ (setq facemenu-end-add-face
+ (mapconcat (lambda (f) (concat "</" f ">")) (reverse tag-face) ""))
+ (mapconcat (lambda (f) (concat "<" f ">")) tag-face ""))
((and (consp face)
(consp (car face))
(null (cdr face))
@@ -1868,6 +1871,7 @@ This takes effect when first loading the library.")
(defvar html-face-tag-alist
'((bold . "strong")
(italic . "em")
+ (bold-italic . ("strong" "em"))
(underline . "u")
(mode-line . "rev"))
"Value of `sgml-face-tag-alist' for HTML mode.")
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index 6fd66b2502f..5fba93c76eb 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -2457,7 +2457,7 @@ Only applies the FSPEC to the args part of FORMAT."
(default (tex-compile-default fspec)))
(list default-directory
(completing-read
- (format "Command [%s]: " (tex-summarize-command default))
+ (format-prompt "Command" (tex-summarize-command default))
(mapcar (lambda (x)
(list (tex-format-cmd (eval (car x) t) fspec)))
tex-compile-commands)
diff --git a/lisp/vc/diff.el b/lisp/vc/diff.el
index 352fa693ffb..4061fedd578 100644
--- a/lisp/vc/diff.el
+++ b/lisp/vc/diff.el
@@ -96,15 +96,15 @@ Non-interactively, OLD and NEW may each be a file or a buffer."
(interactive
(let* ((newf (if (and buffer-file-name (file-exists-p buffer-file-name))
(read-file-name
- (concat "Diff new file (default "
- (file-name-nondirectory buffer-file-name) "): ")
+ (format-prompt "Diff new file"
+ (file-name-nondirectory buffer-file-name))
nil buffer-file-name t)
(read-file-name "Diff new file: " nil nil t)))
(oldf (file-newest-backup newf)))
(setq oldf (if (and oldf (file-exists-p oldf))
(read-file-name
- (concat "Diff original file (default "
- (file-name-nondirectory oldf) "): ")
+ (format-prompt "Diff original file"
+ (file-name-nondirectory oldf))
(file-name-directory oldf) oldf t)
(read-file-name "Diff original file: "
(file-name-directory newf) nil t)))
diff --git a/lisp/vc/ediff-ptch.el b/lisp/vc/ediff-ptch.el
index 4135e8b4702..7622cf4c196 100644
--- a/lisp/vc/ediff-ptch.el
+++ b/lisp/vc/ediff-ptch.el
@@ -503,15 +503,11 @@ are two possible targets for this %spatch. However, these files do not exist."
patch-file-name)
(setq patch-file-name
(read-file-name
- (format "Patch is in file%s: "
- (cond ((and buffer-file-name
- (equal (expand-file-name dir)
- (file-name-directory buffer-file-name)))
- (concat
- " (default "
- (file-name-nondirectory buffer-file-name)
- ")"))
- (t "")))
+ (format-prompt "Patch is in file"
+ (and buffer-file-name
+ (equal (expand-file-name dir)
+ (file-name-directory buffer-file-name))
+ (file-name-nondirectory buffer-file-name)))
dir buffer-file-name 'must-match))
(if (file-directory-p patch-file-name)
(error "Patch file cannot be a directory: %s" patch-file-name)
diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el
index 7c36291eea1..d4660a179e6 100644
--- a/lisp/vc/ediff-util.el
+++ b/lisp/vc/ediff-util.el
@@ -3103,11 +3103,7 @@ Hit \\[ediff-recenter] to reset the windows afterward."
(lambda () (when defaults
(setq minibuffer-default defaults)))
(read-file-name
- (format "%s%s "
- prompt
- (cond (default-file
- (concat " (default " default-file "):"))
- (t (concat " (default " default-dir "):"))))
+ (format-prompt prompt (or default-file default-dir))
default-dir
(or default-file default-dir)
t ; must match, no-confirm
diff --git a/lisp/vc/pcvs.el b/lisp/vc/pcvs.el
index bbc81ef195d..8f662e84589 100644
--- a/lisp/vc/pcvs.el
+++ b/lisp/vc/pcvs.el
@@ -1284,8 +1284,7 @@ marked instead. A directory can never be marked."
(intern
(upcase
(completing-read
- (concat
- "Mark files in state" (if default (concat " [" default "]")) ": ")
+ (format-prompt "Mark files in state" default)
(mapcar (lambda (x)
(list (downcase (symbol-name (car x)))))
cvs-states)
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 5b259fcdb33..edc4169465a 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1863,13 +1863,10 @@ Return t if the buffer had changes, nil otherwise."
(vc-working-revision first))))
(when (string= rev1-default "") (setq rev1-default nil))))
;; construct argument list
- (let* ((rev1-prompt (if rev1-default
- (concat "Older revision (default "
- rev1-default "): ")
- "Older revision: "))
- (rev2-prompt (concat "Newer revision (default "
- ;; (or rev2-default
- "current source): "))
+ (let* ((rev1-prompt (format-prompt "Older revision" rev1-default))
+ (rev2-prompt (format-prompt "Newer revision"
+ ;; (or rev2-default
+ "current source"))
(rev1 (vc-read-revision rev1-prompt files backend rev1-default))
(rev2 (vc-read-revision rev2-prompt files backend nil))) ;; rev2-default
(when (string= rev1 "") (setq rev1 nil))
@@ -2082,7 +2079,7 @@ If `F.~REV~' already exists, use it instead of checking it out again."
(with-current-buffer (or (buffer-base-buffer) (current-buffer))
(vc-ensure-vc-buffer)
(list
- (vc-read-revision "Revision to visit (default is working revision): "
+ (vc-read-revision (format-prompt "Revision to visit" "working revision")
(list buffer-file-name)))))
(set-buffer (or (buffer-base-buffer) (current-buffer)))
(vc-ensure-vc-buffer)
@@ -2378,7 +2375,7 @@ This function runs the hook `vc-retrieve-tag-hook' when finished."
(read-directory-name "Directory: " default-directory nil t))))
(list
dir
- (vc-read-revision "Tag name to retrieve (default latest revisions): "
+ (vc-read-revision (format-prompt "Tag name to retrieve" "latest revisions")
(list dir)
(vc-responsible-backend dir)))))
(let* ((backend (vc-responsible-backend dir))
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index 05606fbfb4a..fb06a95f51c 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -3325,7 +3325,7 @@ It reads a file name from an editable text field."
;;; (file (file-name-nondirectory value))
;;; (menu-tag (widget-apply widget :menu-tag-get))
;;; (must-match (widget-get widget :must-match))
-;;; (answer (read-file-name (concat menu-tag " (default " value "): ")
+;;; (answer (read-file-name (format-prompt menu-tag value)
;;; dir nil must-match file)))
;;; (widget-value-set widget (abbreviate-file-name answer))
;;; (widget-setup)