commit bda866009b48b73053d479ffb88e7a7ffbcf7996 (HEAD, refs/remotes/origin/master) Author: Štěpán Němec Date: Sat Apr 24 21:19:48 2021 +0200 * doc/lispref/macros.texi (Eval During Expansion): Copy edit. diff --git a/doc/lispref/macros.texi b/doc/lispref/macros.texi index 7c090aebc8..b8df363614 100644 --- a/doc/lispref/macros.texi +++ b/doc/lispref/macros.texi @@ -480,15 +480,17 @@ in expressions ordinarily. Another problem can happen if the macro definition itself evaluates any of the macro argument expressions, such as by calling -@code{eval} (@pxref{Eval}). You have to take into account that the -context of the caller is not accessible at that time since the macro expansion -may take place long before the code is executed. Also if your macro definition -does not use @code{lexical-binding} its own variables may hide the -user's variables, if the user happens to use a -variable with the same name as one of the macro arguments. Inside the -macro body, the macro argument binding is the most local binding of this -variable, so any references inside the form being evaluated do refer to -it. Here is an example: +@code{eval} (@pxref{Eval}). You have to take into account that macro +expansion may take place long before the code is executed, when the +context of the caller (where the macro expansion will be evaluated) is +not yet accessible. + + Also, if your macro definition does not use @code{lexical-binding}, its +formal arguments may hide the user's variables of the same name. Inside +the macro body, the macro argument binding is the most local binding of +such variable, so any references inside the form being evaluated do refer +to it. Here is an example: + @example @group (defmacro foo (a) @@ -510,9 +512,9 @@ it. Here is an example: @code{x}, because @code{a} conflicts with the macro argument variable @code{a}. - Also the expansion of @code{(foo x)} above will return something -different or signal an error when the code is compiled since in that case -@code{(foo x)} is expanded during compilation whereas the execution of + Also, the expansion of @code{(foo x)} above will return something +different or signal an error when the code is compiled, since in that case +@code{(foo x)} is expanded during compilation, whereas the execution of @code{(setq x 'b)} will only take place later when the code is executed. To avoid these problems, @strong{don't evaluate an argument expression commit 86d1b4d88f2999d2b0f94619dc53092bddfa0ec0 Author: Daniel Mendler Date: Tue Apr 20 00:01:44 2021 +0200 (completion-all-sorted-completions): Fix history use with boundaries Preprocess the history (and the default) through the new function `minibuffer--sort-preprocess-history` to filter out the completion base for completion tables with boundaries (in particular the file completion table). * lisp/minibuffer.el (minibuffer--sort-preprocess-history_: New function. (completion-all-sorted-completions): Use it. * test/lisp/minibuffer-tests.el (completion-all-sorted-completions): Add tests for various combinations of with/without history/base/default. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 51e0519d48..98691c2ede 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1381,6 +1381,26 @@ KEYFUN takes an element of ELEMS and should return a numerical value." (and (= (length c1) (length c2)) (string< c1 c2)))))) +(defun minibuffer--sort-preprocess-history (base) + "Preprocess history. +Remove completion BASE prefix string from history elements." + (let* ((def (if (stringp minibuffer-default) + minibuffer-default + (car-safe minibuffer-default))) + (hist (and (not (eq minibuffer-history-variable t)) + (symbol-value minibuffer-history-variable))) + (base-size (length base))) + ;; Default comes first. + (setq hist (if def (cons def hist) hist)) + ;; Drop base string from the history elements. + (if (= base-size 0) + hist + (delq nil (mapcar + (lambda (c) + (when (string-prefix-p base c) + (substring c base-size))) + hist))))) + (defun completion-all-sorted-completions (&optional start end) (or completion-all-sorted-completions (let* ((start (or start (minibuffer-prompt-end))) @@ -1410,21 +1430,17 @@ KEYFUN takes an element of ELEMS and should return a numerical value." (setq all (delete-dups all)) (setq last (last all)) - (cond - (sort-fun - (setq all (funcall sort-fun all))) - (t + (if sort-fun + (setq all (funcall sort-fun all)) ;; Sort first by length and alphabetically. (setq all (minibuffer--sort-by-length-alpha all)) - ;; Sort by history position, put the default, if it ;; exists, on top. - (when (and (minibufferp) (not (eq minibuffer-history-variable t))) - (let ((def (car-safe minibuffer-default)) - (hist (symbol-value minibuffer-history-variable))) + (when (minibufferp) (setq all (minibuffer--sort-by-position - (if def (cons def hist) hist) - all)))))) + (minibuffer--sort-preprocess-history + (substring string 0 base-size)) + all)))) ;; Cache the result. This is not just for speed, but also so that ;; repeated calls to minibuffer-force-complete can cycle through diff --git a/test/lisp/minibuffer-tests.el b/test/lisp/minibuffer-tests.el index 027711c21e..6ab5f57eff 100644 --- a/test/lisp/minibuffer-tests.el +++ b/test/lisp/minibuffer-tests.el @@ -136,5 +136,57 @@ (should (equal (completion-pcm--optimize-pattern '(any "" any)) '(any)))) +(defun test-completion-all-sorted-completions (base def history-var history-list) + (with-temp-buffer + (insert base) + (cl-letf (((symbol-function #'minibufferp) (lambda (&rest _) t))) + (let ((completion-styles '(basic)) + (completion-category-defaults nil) + (completion-category-overrides nil) + (minibuffer-history-variable history-var) + (minibuffer-history history-list) + (minibuffer-default def) + (minibuffer-completion-table + (lambda (str pred action) + (pcase action + (`(boundaries . ,_) `(boundaries ,(length base) . 0)) + (_ (complete-with-action + action + '("epsilon" "alpha" "gamma" "beta" "delta") + (substring str (length base)) pred)))))) + (completion-all-sorted-completions))))) + +(ert-deftest completion-all-sorted-completions () + ;; No base, disabled history, no default + (should (equal (test-completion-all-sorted-completions + "" nil t nil) + `("beta" "alpha" "delta" "gamma" "epsilon" . 0))) + ;; No base, disabled history, default string + (should (equal (test-completion-all-sorted-completions + "" "gamma" t nil) + `("gamma" "beta" "alpha" "delta" "epsilon" . 0))) + ;; No base, empty history, default string + (should (equal (test-completion-all-sorted-completions + "" "gamma" 'minibuffer-history nil) + `("gamma" "beta" "alpha" "delta" "epsilon" . 0))) + ;; No base, empty history, default list + (should (equal (test-completion-all-sorted-completions + "" '("gamma" "zeta") 'minibuffer-history nil) + `("gamma" "beta" "alpha" "delta" "epsilon" . 0))) + ;; No base, history, default string + (should (equal (test-completion-all-sorted-completions + "" "gamma" 'minibuffer-history '("other" "epsilon" "delta")) + `("gamma" "epsilon" "delta" "beta" "alpha" . 0))) + ;; Base, history, default string + (should (equal (test-completion-all-sorted-completions + "base/" "base/gamma" 'minibuffer-history + '("some/alpha" "base/epsilon" "base/delta")) + `("gamma" "epsilon" "delta" "beta" "alpha" . 5))) + ;; Base, history, default string + (should (equal (test-completion-all-sorted-completions + "base/" "gamma" 'minibuffer-history + '("some/alpha" "base/epsilon" "base/delta")) + `("epsilon" "delta" "beta" "alpha" "gamma" . 5)))) + (provide 'minibuffer-tests) ;;; minibuffer-tests.el ends here commit bc026835df38cd6a4a695f18ea9ffe92ec625e65 Author: Juri Linkov Date: Sun Apr 25 00:54:01 2021 +0300 * lisp/progmodes/project.el: Use project-prefixed-buffer-name in more places. (project-shell, project-eshell): Use project-prefixed-buffer-name (bug#47975). (project-compilation-buffer-name-function): Add :version tag. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 5996a76488..914d7ce9e4 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -918,10 +918,7 @@ With \\[universal-argument] prefix arg, create a new inferior shell buffer even if one already exists." (interactive) (let* ((default-directory (project-root (project-current t))) - (default-project-shell-name - (concat "*" (file-name-nondirectory - (directory-file-name default-directory)) - "-shell*")) + (default-project-shell-name (project-prefixed-buffer-name "shell")) (shell-buffer (get-buffer default-project-shell-name))) (if (and shell-buffer (not current-prefix-arg)) (pop-to-buffer-same-window shell-buffer) @@ -937,10 +934,7 @@ if one already exists." (interactive) (defvar eshell-buffer-name) (let* ((default-directory (project-root (project-current t))) - (eshell-buffer-name - (concat "*" (file-name-nondirectory - (directory-file-name default-directory)) - "-eshell*")) + (eshell-buffer-name (project-prefixed-buffer-name "eshell")) (eshell-buffer (get-buffer eshell-buffer-name))) (if (and eshell-buffer (not current-prefix-arg)) (pop-to-buffer-same-window eshell-buffer) @@ -1004,6 +998,7 @@ loop using the command \\[fileloop-continue]." "Function to compute the name of a project compilation buffer. If non-nil, it overrides `compilation-buffer-name-function' for `project-compile'." + :version "28.1" :group 'project :type '(choice (const :tag "Default" nil) (const :tag "Prefixed with root directory name" commit 48b6cec61cf24c8693331a6b39876984bfdda328 Author: Stefan Monnier Date: Sat Apr 24 15:57:22 2021 -0400 * lisp/mpc.el: Avoid (implicit) `eval`; prefer #' to quote function names (mpc-format): Compose functions instead of constructing source-code expressions at run time. Rename `mpc-pred` property to `mpc--uptodate-p`. (mpc-status-buffer-refresh): Adjust to the new property name. diff --git a/lisp/mpc.el b/lisp/mpc.el index 315d8c0626..f730275038 100644 --- a/lisp/mpc.el +++ b/lisp/mpc.el @@ -183,7 +183,7 @@ numerically rather than lexicographically." (abs res)) res)))))))) -(define-obsolete-function-alias 'mpc-string-prefix-p 'string-prefix-p "24.3") +(define-obsolete-function-alias 'mpc-string-prefix-p #'string-prefix-p "24.3") ;; This can speed up mpc--song-search significantly. The table may grow ;; very large, tho. It's only bounded by the fact that it gets flushed @@ -291,11 +291,11 @@ defaults to 6600 and HOST defaults to localhost." (let ((plist (process-plist mpc-proc))) (while plist (process-put proc (pop plist) (pop plist))))) (mpc-proc-buffer proc 'mpd-commands (current-buffer)) - (process-put proc 'callback 'ignore) + (process-put proc 'callback #'ignore) (process-put proc 'ready nil) (clrhash mpc--find-memoize) - (set-process-filter proc 'mpc--proc-filter) - (set-process-sentinel proc 'ignore) + (set-process-filter proc #'mpc--proc-filter) + (set-process-sentinel proc #'ignore) (set-process-query-on-exit-flag proc nil) ;; This may be called within a process filter ;-( (with-local-quit (mpc-proc-sync proc)) @@ -376,7 +376,7 @@ which will be concatenated with proper quoting before passing them to MPD." (mpc--debug "Send \"%s\"" cmd) (process-send-string proc (concat (if (stringp cmd) cmd - (mapconcat 'mpc--proc-quote-string cmd " ")) + (mapconcat #'mpc--proc-quote-string cmd " ")) "\n"))) (if callback ;; (let ((buf (current-buffer))) @@ -388,7 +388,7 @@ which will be concatenated with proper quoting before passing them to MPD." ;; (set-buffer buf))))) ) ;; If `callback' is nil, we're executing synchronously. - (process-put proc 'callback 'ignore) + (process-put proc 'callback #'ignore) ;; This returns the process's buffer. (mpc-proc-sync proc))))) @@ -398,7 +398,7 @@ which will be concatenated with proper quoting before passing them to MPD." (concat "command_list_begin\n" (mapconcat (lambda (cmd) (if (stringp cmd) cmd - (mapconcat 'mpc--proc-quote-string cmd " "))) + (mapconcat #'mpc--proc-quote-string cmd " "))) cmds "\n") "\ncommand_list_end")) @@ -488,9 +488,9 @@ to call FUN for any change whatsoever.") (defvar mpc--status-timer nil) (defun mpc--status-timer-start () - (add-hook 'pre-command-hook 'mpc--status-timer-stop) + (add-hook 'pre-command-hook #'mpc--status-timer-stop) (unless mpc--status-timer - (setq mpc--status-timer (run-with-timer 1 1 'mpc--status-timer-run)))) + (setq mpc--status-timer (run-with-timer 1 1 #'mpc--status-timer-run)))) (defun mpc--status-timer-stop () (when mpc--status-timer (cancel-timer mpc--status-timer) @@ -510,7 +510,7 @@ to call FUN for any change whatsoever.") ;; Turn it off even if we'll start it again, in case it changes the delay. (cancel-timer mpc--status-idle-timer)) (setq mpc--status-idle-timer - (run-with-idle-timer 1 t 'mpc--status-idle-timer-run)) + (run-with-idle-timer 1 t #'mpc--status-idle-timer-run)) ;; Typically, the idle timer is started from the mpc--status-callback, ;; which is run asynchronously while we're already idle (we typically ;; just started idling), so the timer itself will only be run the next @@ -525,7 +525,7 @@ to call FUN for any change whatsoever.") (unless really ;; We don't completely stop the timer, so that if some other MPD ;; client starts playback, we may get a chance to notice it. - (run-with-idle-timer 10 t 'mpc--status-idle-timer-run)))) + (run-with-idle-timer 10 t #'mpc--status-idle-timer-run)))) (defun mpc--status-idle-timer-run () (mpc--status-timer-start) (mpc--status-timer-run)) @@ -596,7 +596,7 @@ Any call to `mpc-status-refresh' may cause it to be restarted." ;; (dotimes (i (string-to-number pos)) (mpc--queue-pop)) ;; (mpc-proc-cmd (mpc-proc-cmd-list ;; (make-list (string-to-number pos) "delete 0")) -;; 'ignore) +;; #'ignore) ;; (if (not (equal (cdr (assq 'file mpc-status)) ;; (mpc--queue-head))) ;; (message "MPC's queue is out of sync")))))) @@ -683,7 +683,7 @@ The songs are returned as alists." (let ((plsongs (mpc-cmd-find 'Playlist pl))) (if (not (mpc-cmd-special-tag-p other-tag)) (when (member (cons other-tag value) - (apply 'append plsongs)) + (apply #'append plsongs)) (push pl pls)) ;; Problem N°2: we compute the intersection whereas all ;; we care about is whether it's empty. So we could @@ -694,15 +694,15 @@ The songs are returned as alists." ;; good enough because this is only used with "search", which ;; doesn't pay attention to playlists and URLs anyway. (let* ((osongs (mpc-cmd-find other-tag value)) - (ofiles (mpc-assq-all 'file (apply 'append osongs))) - (plfiles (mpc-assq-all 'file (apply 'append plsongs)))) + (ofiles (mpc-assq-all 'file (apply #'append osongs))) + (plfiles (mpc-assq-all 'file (apply #'append plsongs)))) (when (seq-intersection plfiles ofiles) (push pl pls))))))) pls)) ((eq tag 'Directory) (if (null other-tag) - (apply 'nconc + (apply #'nconc (mpc-assq-all 'directory (mpc-proc-buf-to-alist (mpc-proc-cmd "lsinfo"))) @@ -725,7 +725,7 @@ The songs are returned as alists." ;; If there's an other-tag, then just extract the dir info from the ;; list of other-tag's songs. (let* ((other-songs (mpc-cmd-find other-tag value)) - (files (mpc-assq-all 'file (apply 'append other-songs))) + (files (mpc-assq-all 'file (apply #'append other-songs))) (dirs '())) (dolist (file files) (let ((dir (file-name-directory file))) @@ -759,7 +759,7 @@ The songs are returned as alists." ((null other-tag) (condition-case nil - (mapcar 'cdr (mpc-proc-cmd-to-alist (list "list" (symbol-name tag)))) + (mapcar #'cdr (mpc-proc-cmd-to-alist (list "list" (symbol-name tag)))) (mpc-proc-error ;; If `tag' is not one of the expected tags, MPD burps about not ;; having the relevant table. @@ -770,7 +770,7 @@ The songs are returned as alists." (condition-case nil (if (mpc-cmd-special-tag-p other-tag) (signal 'mpc-proc-error "Not implemented") - (mapcar 'cdr + (mapcar #'cdr (mpc-proc-cmd-to-alist (list "list" (symbol-name tag) (symbol-name other-tag) value)))) @@ -781,7 +781,7 @@ The songs are returned as alists." (mpc-assq-all tag ;; Don't use `nconc' now that mpc-cmd-find may ;; return a memoized result. - (apply 'append other-songs)))))))) + (apply #'append other-songs)))))))) (defun mpc-cmd-stop (&optional callback) (mpc-proc-cmd "stop" callback)) @@ -847,7 +847,7 @@ If PLAYLIST is t or nil or missing, use the main playlist." ;; Sort them from last to first, so the renumbering ;; caused by the earlier deletions don't affect ;; later ones. - (sort (copy-sequence song-poss) '>)))) + (sort (copy-sequence song-poss) #'>)))) (if (stringp playlist) (puthash (cons 'Playlist playlist) nil mpc--find-memoize))) @@ -871,7 +871,7 @@ If PLAYLIST is t or nil or missing, use the main playlist." ;; Sort them from last to first, so the renumbering ;; caused by the earlier deletions affect ;; later ones a bit less. - (sort (copy-sequence song-poss) '>)))) + (sort (copy-sequence song-poss) #'>)))) (if (stringp playlist) (puthash (cons 'Playlist playlist) nil mpc--find-memoize)))) @@ -882,7 +882,7 @@ If PLAYLIST is t or nil or missing, use the main playlist." (unless callback (mpc-proc-sync)))) (defun mpc-cmd-tagtypes () - (mapcar 'cdr (mpc-proc-cmd-to-alist "tagtypes"))) + (mapcar #'cdr (mpc-proc-cmd-to-alist "tagtypes"))) ;; This was never integrated into MPD. ;; (defun mpc-cmd-download (file) @@ -998,7 +998,7 @@ If PLAYLIST is t or nil or missing, use the main playlist." (cond ((>= col 0) (insert str)) (t (insert (substring str (min (length str) (- col)))))))) - (pred nil)) + (pred #'always)) (while (string-match "%\\(?:%\\|\\(-\\)?\\([0-9]+\\)?{\\([[:alpha:]][[:alnum:]]*\\)\\(?:-\\([^}]+\\)\\)?}\\)" format-spec pos) (let ((pre-text (substring format-spec pos (match-beginning 0)))) (funcall insert pre-text) @@ -1017,7 +1017,7 @@ If PLAYLIST is t or nil or missing, use the main playlist." (pcase tag ((or 'Time 'Duration) (let ((time (cdr (or (assq 'time info) (assq 'Time info))))) - (setq pred (list nil)) ;Just assume it's never eq. + (setq pred #'ignore) ;Just assume it's never eq. (when time (mpc-secs-to-time (if (and (eq tag 'Duration) (string-match ":" time)) @@ -1026,7 +1026,11 @@ If PLAYLIST is t or nil or missing, use the main playlist." ('Cover (let ((dir (file-name-directory (cdr (assq 'file info))))) ;; (debug) - (push `(equal ',dir (file-name-directory (cdr (assq 'file info)))) pred) + (setq pred + (lambda (info) + (and (funcall pred info) + (equal dir (file-name-directory + (cdr (assq 'file info))))))) (if-let* ((covers '(".folder.png" "cover.jpg" "folder.jpg")) (cover (cl-loop for file in (directory-files (mpc-file-local-copy dir)) if (member (downcase file) covers) @@ -1043,7 +1047,7 @@ If PLAYLIST is t or nil or missing, use the main playlist." (setq size nil) (propertize dir 'display image)) ;; Make sure we return something on which we can - ;; place the `mpc-pred' property, as + ;; place the `mpc--uptodate-p' property, as ;; a negative-cache. We could also use ;; a default cover. (progn (setq size nil) " ")))) @@ -1052,7 +1056,10 @@ If PLAYLIST is t or nil or missing, use the main playlist." ;; than the URL in `file'. Pretend it's in `Title'. (when (and (null val) (eq tag 'Title)) (setq val (cdr (assq 'file info)))) - (push `(equal ',val (cdr (assq ',tag info))) pred) + (setq pred + (lambda (info) + (and (funcall pred info) + (equal val (cdr (assq ',tag info)))))) (cond ((not (and (eq tag 'Date) (stringp val))) val) ;; For "date", only keep the year! @@ -1080,11 +1087,11 @@ If PLAYLIST is t or nil or missing, use the main playlist." 'follow-link t 'keymap `(keymap (mouse-2 - . (lambda () - (interactive) - (mpc-constraints-push 'noerror) - (mpc-constraints-restore - ',(list (list tag text))))))))) + . ,(lambda () + (interactive) + (mpc-constraints-push 'noerror) + (mpc-constraints-restore + ',(list (list tag text))))))))) (funcall insert (concat (when size (propertize " " 'display @@ -1097,35 +1104,34 @@ If PLAYLIST is t or nil or missing, use the main playlist." (if (null size) (setq col (+ col textwidth postwidth)) (insert space) (setq col (+ col size)))))) - (put-text-property start (point) 'mpc-pred - `(lambda (info) (and ,@(nreverse pred)))))) + (put-text-property start (point) 'mpc--uptodate-p pred))) ;;; The actual UI code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar mpc-mode-map (let ((map (make-sparse-keymap))) - ;; (define-key map "\e" 'mpc-stop) - (define-key map "q" 'mpc-quit) - (define-key map "\r" 'mpc-select) - (define-key map [(shift return)] 'mpc-select-toggle) - (define-key map [mouse-2] 'mpc-select) - (define-key map [S-mouse-2] 'mpc-select-extend) - (define-key map [C-mouse-2] 'mpc-select-toggle) - (define-key map [drag-mouse-2] 'mpc-drag-n-drop) + ;; (define-key map "\e" #'mpc-stop) + (define-key map "q" #'mpc-quit) + (define-key map "\r" #'mpc-select) + (define-key map [(shift return)] #'mpc-select-toggle) + (define-key map [mouse-2] #'mpc-select) + (define-key map [S-mouse-2] #'mpc-select-extend) + (define-key map [C-mouse-2] #'mpc-select-toggle) + (define-key map [drag-mouse-2] #'mpc-drag-n-drop) ;; We use `always' because a binding to t is like a binding to nil. (define-key map [follow-link] :always) ;; But follow-link doesn't apply blindly to header-line and ;; mode-line clicks. - (define-key map [header-line follow-link] 'ignore) - (define-key map [mode-line follow-link] 'ignore) + (define-key map [header-line follow-link] #'ignore) + (define-key map [mode-line follow-link] #'ignore) ;; Doesn't work because the first click changes the buffer, so the second ;; is applied elsewhere :-( - ;; (define-key map [(double mouse-2)] 'mpc-play-at-point) - (define-key map "p" 'mpc-pause) - (define-key map "s" 'mpc-toggle-play) - (define-key map ">" 'mpc-next) - (define-key map "<" 'mpc-prev) - (define-key map "g" 'mpc-seek-current) + ;; (define-key map [(double mouse-2)] #'mpc-play-at-point) + (define-key map "p" #'mpc-pause) + (define-key map "s" #'mpc-toggle-play) + (define-key map ">" #'mpc-next) + (define-key map "<" #'mpc-prev) + (define-key map "g" #'mpc-seek-current) map)) (easy-menu-define mpc-mode-menu mpc-mode-map @@ -1217,7 +1223,7 @@ If PLAYLIST is t or nil or missing, use the main playlist." (when (assq 'file mpc-status) (let ((inhibit-read-only t)) (dolist (spec mpc-status-buffer-format) - (let ((pred (get-text-property (point) 'mpc-pred))) + (let ((pred (get-text-property (point) 'mpc--uptodate-p))) (if (and pred (funcall pred mpc-status)) (forward-line) (delete-region (point) (line-beginning-position 2)) @@ -1277,7 +1283,7 @@ If PLAYLIST is t or nil or missing, use the main playlist." ;; Restore the selection. I.e. move the overlays back to their ;; corresponding location. Actually which overlay is used for what ;; doesn't matter. - (mapc 'delete-overlay mpc-select) + (mapc #'delete-overlay mpc-select) (setq mpc-select nil) (dolist (elem selection) ;; After an update, some elements may have disappeared. @@ -1302,7 +1308,7 @@ If PLAYLIST is t or nil or missing, use the main playlist." (interactive (list last-nonmenu-event)) (mpc-event-set-point event) (if (and (bolp) (eobp)) (forward-line -1)) - (mapc 'delete-overlay mpc-select) + (mapc #'delete-overlay mpc-select) (setq mpc-select nil) (if (mpc-tagbrowser-all-p) nil @@ -1662,7 +1668,7 @@ Return non-nil if a selection was deactivated." ;; (unless (equal constraints mpc-constraints) ;; (setq-local mpc-constraints constraints) (dolist (cst constraints) - (let ((vals (apply 'mpc-union + (let ((vals (apply #'mpc-union (mapcar (lambda (val) (mpc-cmd-list mpc-tag (car cst) val)) (cdr cst))))) @@ -1681,7 +1687,7 @@ Return non-nil if a selection was deactivated." (setq mpc--changed-selection t)) (unless nodeactivate (setq selection nil) - (mapc 'delete-overlay mpc-select) + (mapc #'delete-overlay mpc-select) (setq mpc-select nil) (mpc-tagbrowser-all-select)))) @@ -1726,7 +1732,7 @@ Return non-nil if a selection was deactivated." (defvar mpc-tagbrowser-dir-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map mpc-tagbrowser-mode-map) - (define-key map [?\M-\C-m] 'mpc-tagbrowser-dir-toggle) + (define-key map [?\M-\C-m] #'mpc-tagbrowser-dir-toggle) map)) ;; (defvar mpc-tagbrowser-dir-keywords @@ -1838,12 +1844,12 @@ A value of t means the main playlist.") (let ((map (make-sparse-keymap))) ;; Bind the up-events rather than the down-event, so the ;; `message' isn't canceled by the subsequent up-event binding. - (define-key map [down-mouse-1] 'ignore) - (define-key map [mouse-1] 'mpc-volume-mouse-set) - (define-key map [header-line mouse-1] 'mpc-volume-mouse-set) - (define-key map [header-line down-mouse-1] 'ignore) - (define-key map [mode-line mouse-1] 'mpc-volume-mouse-set) - (define-key map [mode-line down-mouse-1] 'ignore) + (define-key map [down-mouse-1] #'ignore) + (define-key map [mouse-1] #'mpc-volume-mouse-set) + (define-key map [header-line mouse-1] #'mpc-volume-mouse-set) + (define-key map [header-line down-mouse-1] #'ignore) + (define-key map [mode-line mouse-1] #'mpc-volume-mouse-set) + (define-key map [mode-line down-mouse-1] #'ignore) map)) (defvar mpc-volume nil) (put 'mpc-volume 'risky-local-variable t) @@ -1876,7 +1882,7 @@ A value of t means the main playlist.") (progn (message "MPD volume already at %s%%" newvol) (ding)) - (mpc-proc-cmd (list "setvol" newvol) 'mpc-status-refresh) + (mpc-proc-cmd (list "setvol" newvol) #'mpc-status-refresh) (message "Set MPD volume to %s%%" newvol)))) (defun mpc-volume-widget (vol &optional size) @@ -1913,7 +1919,7 @@ A value of t means the main playlist.") (defvar mpc-songs-mode-map (let ((map (make-sparse-keymap))) - (define-key map [remap mpc-select] 'mpc-songs-jump-to) + (define-key map [remap mpc-select] #'mpc-songs-jump-to) map)) (defvar mpc-songpointer-set-visible nil) @@ -1961,7 +1967,7 @@ This is used so that they can be compared with `eq', which is needed for (setq mpc-songs-playlist (cadr cst))) ;; We don't do anything really special here for playlists, ;; because it's unclear what's a correct "union" of playlists. - (let ((vals (apply 'mpc-union + (let ((vals (apply #'mpc-union (mapcar (lambda (val) (mpc-cmd-find (car cst) val)) (cdr cst))))) @@ -2335,7 +2341,7 @@ This is used so that they can be compared with `eq', which is needed for "Quit Music Player Daemon." (interactive) (let* ((proc mpc-proc) - (bufs (mapcar 'cdr (if proc (process-get proc 'buffers)))) + (bufs (mapcar #'cdr (if proc (process-get proc 'buffers)))) (wins (mapcar (lambda (buf) (get-buffer-window buf 0)) bufs)) (song-buf (mpc-songs-buf)) frames) @@ -2356,7 +2362,7 @@ This is used so that they can be compared with `eq', which is needed for (unless (memq (window-buffer win) bufs) (setq delete nil))) (if delete (ignore-errors (delete-frame frame)))))) ;; Then kill the buffers. - (mapc 'kill-buffer bufs) + (mapc #'kill-buffer bufs) (mpc-status-stop) (if proc (delete-process proc)))) @@ -2519,7 +2525,7 @@ If stopped, start playback." (setq mpc-last-seek-time (cons currenttime (setq time (+ time step)))) (mpc-proc-cmd (list "seekid" songid time) - 'mpc-status-refresh)))) + #'mpc-status-refresh)))) (let ((status (mpc-cmd-status))) (let* ((songid (cdr (assq 'songid status))) (time (if songid (string-to-number @@ -2529,7 +2535,7 @@ If stopped, start playback." (lambda () (mpc-proc-cmd (list "seekid" songid (setq time (+ time step))) - 'mpc-status-refresh))))) + #'mpc-status-refresh))))) (while (mouse-movement-p (event-basic-type (setq event (read-event))))) (cancel-timer timer))))))) @@ -2584,7 +2590,7 @@ If stopped, start playback." ((and (>= songtime songduration) mpc--faster-toggle-forward) ;; Skip to the beginning of the next song. (if (not (equal (cdr (assq 'state mpc-status)) "play")) - (mpc-proc-cmd "next" 'mpc-status-refresh) + (mpc-proc-cmd "next" #'mpc-status-refresh) ;; If we're playing, this is done automatically, so we ;; don't need to do anything, or rather we *shouldn't* ;; do anything otherwise there's a race condition where @@ -2616,7 +2622,7 @@ If stopped, start playback." (condition-case nil (mpc-proc-cmd (list "seekid" songid songtime) - 'mpc-status-refresh) + #'mpc-status-refresh) (mpc-proc-error (mpc-status-refresh))))))))))) (setq mpc--faster-toggle-forward (> step 0)) (funcall fun) ;Initialize values. @@ -2700,7 +2706,7 @@ If stopped, start playback." (error "Not a playlist") (buffer-substring (line-beginning-position) (line-end-position))))) - (mpc-cmd-add (mapcar 'car songs) playlist) + (mpc-cmd-add (mapcar #'car songs) playlist) (message "Added %d songs to %s" (length songs) playlist) (if (member playlist (cdr (assq 'Playlist (mpc-constraints-get-current)))) @@ -2712,7 +2718,7 @@ If stopped, start playback." ((eq start-buf end-buf) ;; Moving songs within the shown playlist. (let ((dest-pos (get-text-property (point) 'mpc-file-pos))) - (mpc-cmd-move (mapcar 'cdr songs) dest-pos mpc-songs-playlist) + (mpc-cmd-move (mapcar #'cdr songs) dest-pos mpc-songs-playlist) (message "Moved %d songs" (length songs)))) (t ;; Adding songs to the shown playlist. @@ -2723,10 +2729,10 @@ If stopped, start playback." ;; MPD's protocol does not let us add songs at a particular ;; position in a playlist, so we first have to add them to the ;; end, and then move them to their final destination. - (mpc-cmd-add (mapcar 'car songs) mpc-songs-playlist) + (mpc-cmd-add (mapcar #'car songs) mpc-songs-playlist) (mpc-cmd-move (let ((poss '())) (dotimes (i (length songs)) - (push (+ i (length pl)) poss)) + (push (+ i (length pl)) poss)) (nreverse poss)) dest-pos mpc-songs-playlist) (message "Added %d songs" (length songs))))) commit d398eca44e119d60f21494a34050e6ca5bc9df8b Author: Stefan Monnier Date: Sat Apr 24 14:07:12 2021 -0400 * lisp/svg.el: Fix typo in sample code; add minor optimization (svg--elliptical-arc-command, svg--moveto-command) (svg--lineto-command): Use `mapcan`. diff --git a/lisp/svg.el b/lisp/svg.el index 717c84788f..05accf4f13 100644 --- a/lisp/svg.el +++ b/lisp/svg.el @@ -41,7 +41,7 @@ ;; into the buffer: ;; ;; (setq svg (svg-create 800 800 :stroke "orange" :stroke-width 5)) -;; (svg-gradient svg "gradient" 'linear '(0 . "red") '(100 . "blue")) +;; (svg-gradient svg "gradient" 'linear '((0 . "red") (100 . "blue"))) ;; (save-excursion (goto-char (point-max)) (svg-insert-image svg)) ;; Then add various elements to the structure: @@ -81,7 +81,7 @@ STOPS is a list of percentage/color pairs." (svg--def svg (apply - 'dom-node + #'dom-node (if (eq type 'linear) 'linearGradient 'radialGradient) @@ -358,8 +358,7 @@ This is in contrast to merely setting it to 0." (plist-get command-args :default-relative)))) (intern (if relative (downcase char) (upcase char))))) -(defun svg--elliptical-arc-coordinates - (rx ry x y &rest args) +(defun svg--elliptical-arc-coordinates (rx ry x y &rest args) (list rx ry (or (plist-get args :x-axis-rotation) 0) @@ -370,21 +369,19 @@ This is in contrast to merely setting it to 0." (defun svg--elliptical-arc-command (coordinates-list &rest args) (cons (svg--path-command-symbol 'a args) - (apply 'append - (mapcar - (lambda (coordinates) - (apply 'svg--elliptical-arc-coordinates - coordinates)) - coordinates-list)))) + (mapcan + (lambda (coordinates) + (apply #'svg--elliptical-arc-coordinates + coordinates)) + coordinates-list))) (defun svg--moveto-command (coordinates-list &rest args) (cons (svg--path-command-symbol 'm args) - (apply 'append - (mapcar - (lambda (coordinates) - (list (car coordinates) (cdr coordinates))) - coordinates-list)))) + (mapcan + (lambda (coordinates) + (list (car coordinates) (cdr coordinates))) + coordinates-list))) (defun svg--closepath-command (&rest args) (list (svg--path-command-symbol 'z args))) @@ -392,11 +389,10 @@ This is in contrast to merely setting it to 0." (defun svg--lineto-command (coordinates-list &rest args) (cons (svg--path-command-symbol 'l args) - (apply 'append - (mapcar - (lambda (coordinates) - (list (car coordinates) (cdr coordinates))) - coordinates-list)))) + (mapcan + (lambda (coordinates) + (list (car coordinates) (cdr coordinates))) + coordinates-list))) (defun svg--horizontal-lineto-command (coordinate-list &rest args) (cons @@ -411,24 +407,24 @@ This is in contrast to merely setting it to 0." (defun svg--curveto-command (coordinates-list &rest args) (cons (svg--path-command-symbol 'c args) - (apply 'append coordinates-list))) + (apply #'append coordinates-list))) (defun svg--smooth-curveto-command (coordinates-list &rest args) (cons (svg--path-command-symbol 's args) - (apply 'append coordinates-list))) + (apply #'append coordinates-list))) (defun svg--quadratic-bezier-curveto-command (coordinates-list &rest args) (cons (svg--path-command-symbol 'q args) - (apply 'append coordinates-list))) + (apply #'append coordinates-list))) (defun svg--smooth-quadratic-bezier-curveto-command (coordinates-list &rest args) (cons (svg--path-command-symbol 't args) - (apply 'append coordinates-list))) + (apply #'append coordinates-list))) (defun svg--eval-path-command (command default-relative) (cl-letf @@ -450,7 +446,7 @@ This is in contrast to merely setting it to 0." #'svg--elliptical-arc-command) (extended-command (append command (list :default-relative default-relative)))) - (mapconcat 'prin1-to-string (apply extended-command) " "))) + (mapconcat #'prin1-to-string (apply extended-command) " "))) (defun svg-path (svg commands &rest args) "Add the outline of a shape to SVG according to COMMANDS. @@ -459,7 +455,7 @@ modifiers. If :relative is t, then coordinates are relative to the last position, or -- initially -- to the origin." (let* ((default-relative (plist-get args :relative)) (stripped-args (svg--plist-delete args :relative)) - (d (mapconcat 'identity + (d (mapconcat #'identity (mapcar (lambda (command) (svg--eval-path-command command commit dec8a4775d665168d03693ef1aea99981f13b30a Author: Stefan Monnier Date: Sat Apr 24 13:45:08 2021 -0400 * doc/lispref/macros.texi (Eval During Expansion): Fix fixme diff --git a/doc/lispref/macros.texi b/doc/lispref/macros.texi index 57b8d396e0..7c090aebc8 100644 --- a/doc/lispref/macros.texi +++ b/doc/lispref/macros.texi @@ -480,13 +480,15 @@ in expressions ordinarily. Another problem can happen if the macro definition itself evaluates any of the macro argument expressions, such as by calling -@code{eval} (@pxref{Eval}). If the argument is supposed to refer to the -user's variables, you may have trouble if the user happens to use a +@code{eval} (@pxref{Eval}). You have to take into account that the +context of the caller is not accessible at that time since the macro expansion +may take place long before the code is executed. Also if your macro definition +does not use @code{lexical-binding} its own variables may hide the +user's variables, if the user happens to use a variable with the same name as one of the macro arguments. Inside the macro body, the macro argument binding is the most local binding of this variable, so any references inside the form being evaluated do refer to it. Here is an example: -@c FIXME with lexical-binding t this example no longer applies @example @group (defmacro foo (a) @@ -508,12 +510,10 @@ it. Here is an example: @code{x}, because @code{a} conflicts with the macro argument variable @code{a}. - Another problem with calling @code{eval} in a macro definition is that -it probably won't do what you intend in a compiled program. The -byte compiler runs macro definitions while compiling the program, when -the program's own computations (which you might have wished to access -with @code{eval}) don't occur and its local variable bindings don't -exist. + Also the expansion of @code{(foo x)} above will return something +different or signal an error when the code is compiled since in that case +@code{(foo x)} is expanded during compilation whereas the execution of +@code{(setq x 'b)} will only take place later when the code is executed. To avoid these problems, @strong{don't evaluate an argument expression while computing the macro expansion}. Instead, substitute the commit 9b8dc629d37de32abba76ac9b4b6106491cd21a4 Author: Glenn Morris Date: Sat Apr 24 10:05:17 2021 -0700 Simlify top-level Makefile since admin is always included * Makefile.in (clean_dirs, distclean_dirs, maintainer_clean_dirs): Add admin directories. (clean, distclean, bootstrap-clean, maintainer-clean): Simplify. (maybeclean_dirs): Remove - this dates to when admin/ was not included in tar files. diff --git a/Makefile.in b/Makefile.in index 638548370c..f04ba0c5c9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -834,12 +834,11 @@ mostlyclean: $(mostlyclean_dirs:=_mostlyclean) ### with them. ### ### Delete '.dvi' files here if they are not part of the distribution. -clean_dirs = $(mostlyclean_dirs) nextstep +clean_dirs = $(mostlyclean_dirs) nextstep admin/charsets admin/unidata $(foreach dir,$(clean_dirs),$(eval $(call submake_template,$(dir),clean))) clean: $(clean_dirs:=_clean) - $(MAKE) -C admin/charsets $@ [ ! -d test ] || $(MAKE) -C test $@ -rm -f ./*.tmp etc/*.tmp* -rm -rf info-dir.* @@ -860,16 +859,11 @@ top_distclean=\ rm -f config.status config.log~ \ Makefile makefile lib/gnulib.mk ${SUBDIR_MAKEFILES} -distclean_dirs = $(clean_dirs) leim lisp +distclean_dirs = $(clean_dirs) leim lisp admin/grammars $(foreach dir,$(distclean_dirs),$(eval $(call submake_template,$(dir),distclean))) -maybeclean_dirs = test admin/grammars admin/unidata admin/charsets - distclean: $(distclean_dirs:=_distclean) - for dir in $(filter-out test,$(maybeclean_dirs)); do \ - $(MAKE) -C $$dir $@ || exit; \ - done [ ! -d test ] || $(MAKE) -C test $@ ${top_distclean} @@ -879,9 +873,6 @@ distclean: $(distclean_dirs:=_distclean) $(foreach dir,$(distclean_dirs),$(eval $(call submake_template,$(dir),bootstrap-clean))) bootstrap-clean: $(distclean_dirs:=_bootstrap-clean) - for dir in $(filter-out test,$(maybeclean_dirs)); do \ - $(MAKE) -C $$dir $@ || exit; \ - done [ ! -d test ] || $(MAKE) -C test $@ [ ! -f config.log ] || mv -f config.log config.log~ rm -rf ${srcdir}/info @@ -903,14 +894,12 @@ top_maintainer_clean=\ ${top_distclean}; \ rm -fr autom4te.cache -maintainer_clean_dirs = src leim lisp +maintainer_clean_dirs = src leim lisp admin/charsets admin/grammars \ + admin/unidata $(foreach dir,$(maintainer_clean_dirs),$(eval $(call submake_template,$(dir),maintainer-clean))) maintainer-clean: bootstrap-clean $(maintainer_clean_dirs:=_maintainer-clean) - for dir in $(filter-out test,$(maybeclean_dirs)); do \ - $(MAKE) -C $$dir $@ || exit; \ - done [ ! -d test ] || $(MAKE) -C test $@ ${top_maintainer_clean} commit 2c2dfbbbf052353d3d64109e9b7e3d9b247d1e3c Author: Štěpán Němec Date: Tue Apr 21 10:51:45 2020 +0200 ; Fix some typos in doc strings and manuals diff --git a/doc/lispref/macros.texi b/doc/lispref/macros.texi index e56a85c747..57b8d396e0 100644 --- a/doc/lispref/macros.texi +++ b/doc/lispref/macros.texi @@ -486,7 +486,7 @@ variable with the same name as one of the macro arguments. Inside the macro body, the macro argument binding is the most local binding of this variable, so any references inside the form being evaluated do refer to it. Here is an example: - +@c FIXME with lexical-binding t this example no longer applies @example @group (defmacro foo (a) diff --git a/doc/lispref/nonascii.texi b/doc/lispref/nonascii.texi index 84f5d2f081..c22930d624 100644 --- a/doc/lispref/nonascii.texi +++ b/doc/lispref/nonascii.texi @@ -301,7 +301,7 @@ character, and returns that character. If @var{char} is neither @end defun @defun unibyte-char-to-multibyte char -This convert the unibyte character @var{char} to a multibyte +This converts the unibyte character @var{char} to a multibyte character, assuming @var{char} is either @acronym{ASCII} or raw 8-bit byte. @end defun @@ -676,7 +676,7 @@ This function returns the value of @var{char}'s @var{propname} property. @end group @group (get-char-code-property ?\( 'paired-bracket) - @result{} 41 ;; closing parenthesis + @result{} 41 ; closing parenthesis @end group @group (get-char-code-property ?\) 'bracket-type) @@ -955,13 +955,13 @@ translating the result. @defvar standard-translation-table-for-decode This is the default translation table for decoding. If a coding -systems specifies its own translation tables, the table that is the +system specifies its own translation tables, the table that is the value of this variable, if non-@code{nil}, is applied after them. @end defvar @defvar standard-translation-table-for-encode This is the default translation table for encoding. If a coding -systems specifies its own translation tables, the table that is the +system specifies its own translation tables, the table that is the value of this variable, if non-@code{nil}, is applied after them. @end defvar @@ -1258,7 +1258,7 @@ name or @code{nil}. @defun check-coding-system coding-system This function checks the validity of @var{coding-system}. If that is valid, it returns @var{coding-system}. If @var{coding-system} is -@code{nil}, the function return @code{nil}. For any other values, it +@code{nil}, the function returns @code{nil}. For any other values, it signals an error whose @code{error-symbol} is @code{coding-system-error} (@pxref{Signaling Errors, signal}). @end defun diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index b6553c8a63..869bb27266 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -17966,7 +17966,7 @@ This creates a group including all flagged messages from all groups on two IMAP servers, "home" and "work". And one last example. Here is a function that runs a search query to -find all message that have been received recently from certain groups: +find all messages that have been received recently from certain groups: @lisp (defun my-recent-email (args) diff --git a/doc/misc/sem-user.texi b/doc/misc/sem-user.texi index c37291ac14..70a19484e8 100644 --- a/doc/misc/sem-user.texi +++ b/doc/misc/sem-user.texi @@ -142,7 +142,7 @@ Move point ``up'' one reference (@code{senator-go-to-up-reference}). The meaning of ``up'' is language-dependent; in C++, for instance, this means moving to the parent of the current tag. -@item C-c, @key{SPC} +@item C-c , @key{SPC} Display a list of possible completions for the symbol at point (@code{semantic-complete-analyze-inline}). This also activates a special set of keybindings for choosing a completion: @key{RET} diff --git a/etc/NEWS b/etc/NEWS index 0bfe692929..63de46aebd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1684,7 +1684,7 @@ to the 'project-root' of the current project, when available. *** The TAB key binding in *xref* buffers is obsolete. Use 'C-u RET' instead. The TAB binding in *xref* buffers is still supported, but we plan on removing it in a future version; at that -time, the command 'xref-quit-and-got-xref' will no longer have a key +time, the command 'xref-quit-and-goto-xref' will no longer have a key binding in 'xref--xref-buffer-mode-map'. ** json.el diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index f5b8c7b662..31aa0cb4f9 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -438,7 +438,7 @@ Presumes point is at the end of the `cl-defmethod' symbol." ;;;###autoload (defmacro cl-defmethod (name args &rest body) "Define a new method for generic function NAME. -This it defines an implementation of NAME to use for invocations +This defines an implementation of NAME to use for invocations of specific types of arguments. ARGS is a list of dispatch arguments (see `cl-defun'), but where diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index a02406a7b7..b4f068cf3a 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el @@ -63,7 +63,7 @@ If this variable is set to 0, no idle time is required." :type 'number) (defcustom eldoc-print-after-edit nil - "If non-nil eldoc info is only shown when editing. + "If non-nil, eldoc info is only shown when editing. Changing the value requires toggling `eldoc-mode'." :type 'boolean) @@ -391,12 +391,12 @@ name, inside its arg list, or on any object with some associated information. Each hook function is called with at least one argument CALLBACK, -a function, and decides whether to display a doc short string +a function, and decides whether to display a short doc string about the context around point. - If that decision can be taken quickly, the hook function may - call CALLBACK immediately following the protocol described - below. Alternatively it may ignore CALLBACK entirely and + call CALLBACK immediately, following the protocol described + below. Alternatively, it may ignore CALLBACK entirely and return either the doc string, or nil if there's no doc appropriate for the context. @@ -688,11 +688,11 @@ following values are allowed: - `eldoc-documentation-compose': calls all functions in the special hook and displays all of the resulting doc strings together. Wait for all strings to be ready, and preserve their - relative as specified by the order of functions in the hook; + relative order as specified by the order of functions in the hook; - `eldoc-documentation-compose-eagerly': calls all functions in - the special hook and display as many of the resulting doc - strings as possible, as soon as possible. Preserving the + the special hook and displays as many of the resulting doc + strings as possible, as soon as possible. Preserves the relative order of doc strings; - `eldoc-documentation-enthusiast': calls all functions in the @@ -793,7 +793,7 @@ function passes responsibility to the functions in Other third-party values of `eldoc-documentation-strategy' should not use `eldoc--make-callback'. They must find some alternate way to produce callbacks to feed to -`eldoc-documentation-function' and should endeavour to display +`eldoc-documentation-functions' and should endeavour to display the docstrings eventually produced, using `eldoc-display-functions'." (let* (;; How many callbacks have been created by the strategy diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index 56e588ee0d..1e3eb9c12b 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -1210,7 +1210,7 @@ unmatchable Never match anything at all. CHARCLASS Match a character from a character class. One of: alpha, alphabetic, letter Alphabetic characters (defined by Unicode). alnum, alphanumeric Alphabetic or decimal digit chars (Unicode). - digit numeric, num 0-9. + digit, numeric, num 0-9. xdigit, hex-digit, hex 0-9, A-F, a-f. cntrl, control ASCII codes 0-31. blank Horizontal whitespace (Unicode). diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index eeb5ac851a..aa4c753287 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -8089,7 +8089,7 @@ Return nil if there are no unseen articles." (defun gnus-summary-first-unseen-or-unread-subject () "Place the point on the subject line of the first unseen and unread article. -If all article have been seen, on the subject line of the first unread +If all articles have been seen, on the subject line of the first unread article." (interactive nil gnus-summary-mode) (prog1 diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el index 77cad77711..8514434e9a 100644 --- a/lisp/progmodes/cc-styles.el +++ b/lisp/progmodes/cc-styles.el @@ -374,7 +374,7 @@ in this way. If DONT-OVERRIDE is t, style variables that already have values (i.e., whose values are not the symbol `set-from-style') will not be overridden. CC Mode calls c-set-style internally in this way whilst initializing a buffer; if -cc-set-style is called like this from anywhere else, it will usually behave as +c-set-style is called like this from anywhere else, it will usually behave as a null operation." (interactive (list (let ((completion-ignore-case t) diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el index a48b3457aa..8d2715f611 100644 --- a/lisp/textmodes/flyspell.el +++ b/lisp/textmodes/flyspell.el @@ -77,7 +77,7 @@ Detection of repeated words is not implemented in "A list of exceptions for duplicated words. It should be a list of (LANGUAGE . EXCEPTION-LIST). -LANGUAGE is nil, which means the exceptions apply regardless of +LANGUAGE can be nil, which means the exceptions apply regardless of the current dictionary, or a regular expression matching the dictionary name (`ispell-local-dictionary' or `ispell-dictionary') for which the exceptions should apply. diff --git a/src/character.h b/src/character.h index d19e1e2604..75351cd1ed 100644 --- a/src/character.h +++ b/src/character.h @@ -42,7 +42,7 @@ INLINE_HEADER_BEGIN F9..FF 11111yyy In each bit pattern, 'x' and 'y' each represent a single bit of the - character code payload, and least one 'y' must be a 1 bit. + character code payload, and at least one 'y' must be a 1 bit. In the 5-byte sequence, the 22-bit payload cannot exceed 3FFF7F. */ commit af464e438004698865eafc1b871d4316cfcd8dad Author: Stefan Kangas Date: Sat Apr 24 18:05:15 2021 +0200 * lisp/help.el (help--for-help-make-sections): Fix typo. diff --git a/lisp/help.el b/lisp/help.el index e98f4f2b7e..4dcb2353ce 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -222,7 +222,7 @@ Do not call this in the scope of `with-help-window'." (let ((title (car section)) (commands (cdr section))) (concat "\n\n" - (propertize (car section) 'face 'help-for-help-header) + (propertize title 'face 'help-for-help-header) "\n\n" (help--for-help-make-commands commands)))) sections "")) commit 1fce52813219d325c7c6f758f082009879e2f234 Author: Stefan Kangas Date: Sat Apr 24 15:18:03 2021 +0200 Redesign and improve the help-for-help (C-h C-h) command * lisp/help.el (help-for-help): Redesign help screen; add sections, rearrange and reword. (help-for-help-header): New face. (help--for-help-make-commands, help--for-help-make-sections): New functions. (help-for-help-buffer-name): New variable. * lisp/help-macro.el (make-help-screen): New optional argument BUFFER-NAME. Fontify keys. This change was discussed in: https://lists.gnu.org/r/emacs-devel/2021-02/msg01695.html https://lists.gnu.org/r/emacs-devel/2021-03/msg00670.html https://lists.gnu.org/r/emacs-devel/2021-04/msg00292.html diff --git a/etc/NEWS b/etc/NEWS index e944364499..0bfe692929 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -988,6 +988,9 @@ skipped. ** Help +--- +*** The 'help-for-help' ('C-h C-h') screen has been redesigned. + --- *** Keybindings in 'help-mode' use the new 'help-key-binding' face. This face is added by 'substitute-command-keys' to any "\[command]" diff --git a/lisp/help-macro.el b/lisp/help-macro.el index 81d238305b..96edeaf466 100644 --- a/lisp/help-macro.el +++ b/lisp/help-macro.el @@ -83,7 +83,8 @@ gives the window that lists the options." :type 'boolean :group 'help) -(defmacro make-help-screen (fname help-line help-text helped-map) +(defmacro make-help-screen (fname help-line help-text helped-map + &optional buffer-name) "Construct help-menu function name FNAME. When invoked, FNAME shows HELP-LINE and reads a command using HELPED-MAP. If the command is the help character, FNAME displays HELP-TEXT @@ -132,7 +133,7 @@ and then returns." (when (or (eq char ??) (eq char help-char) (memq char help-event-list)) (setq config (current-window-configuration)) - (pop-to-buffer " *Metahelp*" nil t) + (pop-to-buffer (or ,buffer-name " *Metahelp*") nil t) (and (fboundp 'make-frame) (not (eq (window-frame) prev-frame)) @@ -166,7 +167,12 @@ and then returns." (format "Type one of the options listed%s: " (if (pos-visible-in-window-p (point-max)) - "" ", or SPACE or DEL to scroll"))) + "" + (concat ", or " + (help--key-description-fontified "\s") ; SPC + " or " + (help--key-description-fontified "\d") ; DEL + " to scroll")))) char (aref key 0))) ;; If this is a scroll bar command, just run it. diff --git a/lisp/help.el b/lisp/help.el index d4be9aa720..e98f4f2b7e 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -187,59 +187,120 @@ Do not call this in the scope of `with-help-window'." ;; So keyboard macro definitions are documented correctly (fset 'defining-kbd-macro (symbol-function 'start-kbd-macro)) + +;;; Help for help. (a.k.a. `C-h C-h') + +(defvar help-for-help-buffer-name " *Metahelp*" + "Name of the `help-for-help' buffer.") + +(defface help-for-help-header '((t :height 1.26)) + "Face used for headers in the `help-for-help' buffer." + :group 'help) + +(defun help--for-help-make-commands (commands) + "Create commands for `help-for-help' screen from COMMANDS." + (mapconcat + (lambda (cmd) + (if (listp cmd) + (let ((name (car cmd)) (desc (cadr cmd))) + (concat + " " + (if (string-match (rx string-start "C-" word string-end) name) + ;; `help--key-description-fontified' would convert "C-m" to + ;; "RET" so we can't use it here. + (propertize name 'face 'help-key-binding) + (concat "\\[" name "]")) + (propertize "\t" 'display '(space :align-to 8)) + desc)) + "")) + commands "\n")) + +(defun help--for-help-make-sections (sections) + "Create sections for `help-for-help' screen from SECTIONS." + (mapconcat + (lambda (section) + (let ((title (car section)) (commands (cdr section))) + (concat + "\n\n" + (propertize (car section) 'face 'help-for-help-header) + "\n\n" + (help--for-help-make-commands commands)))) + sections "")) + (defalias 'help 'help-for-help) (make-help-screen help-for-help (purecopy "Type a help option: [abcCdefFgiIkKlLmnprstvw.] C-[cdefmnoptw] or ?") - "You have typed %THIS-KEY%, the help character. Type a Help option: -\(Use SPC or DEL to scroll through this text. Type \\\\[help-quit] to exit the Help command.) - -\\[apropos-command] PATTERN Show commands whose name matches the PATTERN (a list of words - or a regexp). See also \\[apropos]. -\\[describe-bindings] Display all key bindings. -\\[describe-key-briefly] KEYS Display the command name run by the given key sequence. -\\[describe-coding-system] CODING Describe the given coding system, or RET for current ones. -\\[apropos-documentation] PATTERN Show a list of functions, variables, and other items whose - documentation matches the PATTERN (a list of words or a regexp). -\\[view-echo-area-messages] Go to the *Messages* buffer which logs echo-area messages. -\\[describe-function] FUNCTION Display documentation for the given function. -\\[Info-goto-emacs-command-node] COMMAND Show the Emacs manual's section that describes the command. -\\[describe-gnu-project] Display information about the GNU project. -\\[view-hello-file] Display the HELLO file which illustrates various scripts. -\\[info] Start the Info documentation reader: read included manuals. -\\[describe-input-method] METHOD Describe a specific input method, or RET for current. -\\[describe-key] KEYS Display the full documentation for the key sequence. -\\[Info-goto-emacs-key-command-node] KEYS Show the Emacs manual's section for the command bound to KEYS. -\\[view-lossage] Show last 300 input keystrokes (lossage). -\\[describe-language-environment] LANG-ENV Describe a specific language environment, or RET for current. -\\[describe-mode] Display documentation of current minor modes and current major mode, - including their special commands. -\\[view-emacs-news] Display news of recent Emacs changes. -\\[describe-symbol] SYMBOL Display the given function or variable's documentation and value. -\\[finder-by-keyword] TOPIC Find packages matching a given topic keyword. -\\[describe-package] PACKAGE Describe the given Emacs Lisp package. -\\[info-emacs-manual] Display the Emacs manual in Info mode. -\\[info-display-manual] Prompt for a manual and then display it in Info mode. -\\[describe-syntax] Display contents of current syntax table, plus explanations. -\\[info-lookup-symbol] SYMBOL Show the section for the given symbol in the Info manual - for the programming language used in this buffer. -\\[help-with-tutorial] Start the Emacs learn-by-doing tutorial. -\\[describe-variable] VARIABLE Display the given variable's documentation and value. -\\[where-is] COMMAND Display which keystrokes invoke the given command (where-is). -\\[display-local-help] Display any available local help at point in the echo area. - -\\[about-emacs] Information about Emacs. -\\[describe-copying] Emacs copying permission (GNU General Public License). -\\[view-emacs-debugging] Instructions for debugging GNU Emacs. -\\[view-external-packages] External packages and information about Emacs. -\\[view-emacs-FAQ] Emacs FAQ. -C-m How to order printed Emacs manuals. -C-n News of recent Emacs changes. -\\[describe-distribution] Emacs ordering and distribution information. -\\[view-emacs-problems] Info about known Emacs problems. -\\[search-forward-help-for-help] Search forward \"help window\". -\\[view-emacs-todo] Emacs TODO list. -\\[describe-no-warranty] Information on absence of warranty for GNU Emacs." - help-map) + (concat + "\(Type " + (help--key-description-fontified "\s") ; SPC + " or " + (help--key-description-fontified "\d") ; DEL + " to scroll, " + (help--key-description-fontified "\C-s") + " to search, or \\\\[help-quit] to exit.)" + (help--for-help-make-sections + '(("Commands, Keys and Functions" + ("describe-mode" + "Show help for current major and minor modes and their commands") + ("describe-bindings" "Show all key bindings") + ("describe-key" "Show help for key") + ("describe-key-briefly" "Show help for key briefly") + ("where-is" "Show which key runs a specific command") + "" + ("apropos-command" + "Search for commands (see also \\[apropos])") + ("apropos-documentation" + "Search documentation of functions, variables, and other items") + ("describe-function" "Show help for function") + ("describe-variable" "Show help for variable") + ("describe-symbol" "Show help for function or variable")) + ("Manuals" + ("info-emacs-manual" "Show Emacs manual") + ("Info-goto-emacs-command-node" + "Show Emacs manual section for command") + ("Info-goto-emacs-key-command-node" + "Show Emacs manual section for a key sequence") + ("info" "Show all installed manuals") + ("info-display-manual" "Show a specific manual") + ("info-lookup-symbol" "Show description of symbol in pertinent manual")) + ("Other Help Commands" + ("view-external-packages" + "Extending Emacs with external packages") + ("finder-by-keyword" + "Search for Emacs packages (see also \\[list-packages])") + ("describe-package" "Describe a specific Emacs package") + "" + ("help-with-tutorial" "Start the Emacs tutorial") + ("view-echo-area-messages" + "Show recent messages (from echo area)") + ("view-lossage" "Show last 300 input keystrokes (lossage)") + ("display-local-help" "Show local help at point")) + ("Miscellaneous" + ("about-emacs" "About Emacs") + ("view-emacs-FAQ" "Emacs FAQ") + ("C-n" "News of recent changes") + ("view-emacs-problems" "Known problems") + ("view-emacs-debugging" "Debugging Emacs") + "" + ("describe-gnu-project" "About the GNU project") + ("describe-copying" + "Emacs copying permission (GNU General Public License)") + ("describe-distribution" + "Emacs ordering and distribution information") + ("C-m" "Order printed manuals") + ("view-emacs-todo" "Emacs TODO") + ("describe-no-warranty" + "Information on absence of warranty")) + ("Internationalization and Coding Systems" + ("describe-input-method" "Describe input method") + ("describe-coding-system" "Describe coding system") + ("describe-language-environment" + "Describe language environment") + ("describe-syntax" "Show current syntax table") + ("view-hello-file" + "Display the HELLO file illustrating various scripts"))))) + help-map + help-for-help-buffer-name) @@ -885,7 +946,7 @@ current buffer." "Search forward \"help window\"." (interactive) ;; Move cursor to the "help window". - (pop-to-buffer " *Metahelp*") + (pop-to-buffer help-for-help-buffer-name) ;; Do incremental search forward. (isearch-forward nil t)) commit 21b3ceea3b0321559e9cbdcb034d9c66d3264d89 Author: Eli Zaretskii Date: Sat Apr 24 15:00:13 2021 +0300 ; * etc/NEWS: Fix last change. diff --git a/etc/NEWS b/etc/NEWS index a246be3086..e944364499 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1679,10 +1679,10 @@ to the 'project-root' of the current project, when available. +++ *** The TAB key binding in *xref* buffers is obsolete. -The TAB binding in *xref* buffers is still supported, but we plan on -removing it in a future version; at that time, the command -'xref-quit-and-got-xref' will no longer have a key binding in -'xref--xref-buffer-mode-map'. +Use 'C-u RET' instead. The TAB binding in *xref* buffers is still +supported, but we plan on removing it in a future version; at that +time, the command 'xref-quit-and-got-xref' will no longer have a key +binding in 'xref--xref-buffer-mode-map'. ** json.el commit d753b39096320b45ba3414272f4445587f4e6e7f Author: Eli Zaretskii Date: Sat Apr 24 12:54:44 2021 +0300 Obsolete the TAB binding in *xref* buffers * doc/emacs/maintaining.texi (Xref Commands): Remove the description of the TAB binding. Enhance the description of the RET binding. (Bug#44611) * etc/NEWS: Announce the obsolescence of TAB binding in XREF. * lisp/progmodes/xref.el (xref-goto-xref): Improve doc string. diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index dfe4eb0ea3..880829aa5a 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -2213,7 +2213,8 @@ the special XREF mode: @table @kbd @item @key{RET} @itemx mouse-2 -Display the reference on the current line. +Display the reference on the current line (@code{xref-goto-xref}). +With prefix argument, also bury the @file{*xref*} buffer. @item n @itemx . @@ -2242,11 +2243,6 @@ display it in the other window (@code{xref-prev-group}). Display the reference on the current line in the other window (@code{xref-show-location-at-point}). -@item @key{TAB} -@findex xref-quit-and-goto-xref -Display the reference on the current line and bury the @file{*xref*} -buffer (@code{xref-quit-and-goto-xref}). - @item r @var{pattern} @key{RET} @var{replacement} @key{RET} Perform interactive query-replace on references that match @var{pattern} (@code{xref-query-replace-in-results}), replacing diff --git a/etc/NEWS b/etc/NEWS index 7d600eb374..a246be3086 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1677,6 +1677,13 @@ choosing the exact definition to go to, and this should do TRT. If chosen, file names in "*xref*" buffers will be displayed relative to the 'project-root' of the current project, when available. ++++ +*** The TAB key binding in *xref* buffers is obsolete. +The TAB binding in *xref* buffers is still supported, but we plan on +removing it in a future version; at that time, the command +'xref-quit-and-got-xref' will no longer have a key binding in +'xref--xref-buffer-mode-map'. + ** json.el --- diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 63d25de50a..e80603f23e 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -652,8 +652,8 @@ SELECT is `quit', also quit the *xref* window." (defun xref-goto-xref (&optional quit) "Jump to the xref on the current line and select its window. -Non-interactively, non-nil QUIT, or interactively, with prefix argument -means to first quit the *xref* buffer." +If QUIT is non-nil (interactively, with prefix argument), also +quit the *xref* buffer." (interactive "P") (let* ((buffer (current-buffer)) (xref (or (xref--item-at-point) commit ae81b9503ac4af7d4e57ee81f3b953142d6fb015 Author: Stefan Kangas Date: Sat Apr 24 10:47:50 2021 +0200 * lisp/rot13.el: Improve documentation. (Bug#47970) diff --git a/lisp/rot13.el b/lisp/rot13.el index dfcf4adc17..4e4e60fea3 100644 --- a/lisp/rot13.el +++ b/lisp/rot13.el @@ -3,6 +3,7 @@ ;; Copyright (C) 1988, 2001-2021 Free Software Foundation, Inc. ;; Author: Howard Gayle +;; Simon Josefsson ;; Maintainer: emacs-devel@gnu.org ;; This file is part of GNU Emacs. @@ -22,18 +23,26 @@ ;;; Commentary: -;; The entry point, `rot13-other-window', performs a Caesar cipher -;; encrypt/decrypt on the current buffer and displays the result in another -;; window. ROT13 encryption is sometimes used on USENET as a read-at-your- -;; own-risk wrapper for material some might consider offensive, such as -;; ethnic humor. +;; "ROT13 ('rotate by 13 places') is a simple letter substitution +;; cipher that replaces a letter with the 13th letter after it in +;; the alphabet. ROT13 is a special case of the Caesar cipher +;; which was developed in ancient Rome. ;; -;; Written by Howard Gayle. -;; This hack is mainly to show off the char table stuff. +;; Because there are 26 letters (2×13) in the basic Latin +;; alphabet, ROT13 is its own inverse; that is, to undo ROT13, the +;; same algorithm is applied, so the same action can be used for +;; encoding and decoding. The algorithm provides virtually no +;; cryptographic security, and is often cited as a canonical +;; example of weak encryption. ;; -;; New entry points, `rot13', `rot13-string', and `rot13-region' that -;; performs Caesar cipher encrypt/decrypt on buffers and strings, was -;; added by Simon Josefsson. +;; ROT13 is used in online forums as a means of hiding spoilers, +;; punchlines, puzzle solutions, and offensive materials from the +;; casual glance." - Wikipedia article on ROT13 +;; +;; The entry points, `rot13', `rot13-string', and `rot13-region' performs ROT13 +;; encoding/decoding on buffers and strings. The entry point +;; `rot13-other-window' performs a ROT13 encoding/decoding on the current +;; buffer and displays the result in another window. ;;; Code: