master 79c1f363a36 1/4: Merge from origin/emacs-31
Eli Zaretskii <[email protected]> Sat, 1 Aug 2026 07:38:42 -0400 (EDT)
| Newsgroups | gmane.emacs.diffs |
|---|---|
| Message-ID | <[email protected]> |
branch: master commit 79c1f363a36c0b94a1f08ea1b02ed0e2db9ca841 Merge: a8539b7919e ad60eb855d2 Author: Eli Zaretskii <[email protected]> Commit: Eli Zaretskii <[email protected]> Merge from origin/emacs-31 ad60eb855d2 ; Improve documentation of "shadow cursor" c6d60333609 Fix attendee lookup in gnus-icalendar 5b5cc17832c vc-working-revision: Don't bind default-directory to a re... ab88a0be86d Fix Dired problem with nonexistent directory (bug#81509) 158a0391359 ; * admin/MAINTAINERS: Mark F. Jason Park as co-maintaini... 1da79a162dd ; * src/treesit.c (treesit_cursor_helper_1): Further expl... 037076824f1 ; * src/treesit.c (treesit_cursor_helper_1): Fix last cha... 5e3f68c669c Fix emacs-eglot test on emba 97e24e12d5b Fix C-x v w a/A on the repository root b65f8ef93d0 (sh-font-lock-paren): Fix bug#81192 # Conflicts: # etc/NEWS --- admin/MAINTAINERS | 5 ++++ doc/emacs/files.texi | 22 ++++++++++++----- etc/NEWS.31 | 8 +++++++ lisp/dired.el | 28 +++++++++++++++------- lisp/gnus/gnus-icalendar.el | 21 +++++++++++----- lisp/progmodes/sh-script.el | 2 +- lisp/vc/diff-mode.el | 5 +++- lisp/vc/vc-hooks.el | 13 +++++----- lisp/vc/vc.el | 25 +++++++++---------- src/treesit.c | 10 ++++---- test/infra/Dockerfile.emba | 2 +- .../progmodes/sh-script-resources/sh-indents.erts | 13 ++++++++++ test/lisp/vc/vc-tests/vc-tests.el | 14 +++++------ 13 files changed, 115 insertions(+), 53 deletions(-) diff --git a/admin/MAINTAINERS b/admin/MAINTAINERS index a2e80bf2dc8..0a5f923fd56 100644 --- a/admin/MAINTAINERS +++ b/admin/MAINTAINERS @@ -262,6 +262,11 @@ Stephane Marks Elías Gabriel Pérez lisp/progmodes/hideshow.el +F. Jason Park + ERC + lisp/erc/* + doc/misc/erc.texi + ============================================================================== 2. Areas that someone is willing to maintain, although he would not necessarily mind if someone else was the official maintainer. diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index b223540b97d..c271da15a1a 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -1808,11 +1808,20 @@ Move to the next hunk-start (@code{diff-hunk-next}). With prefix argument @var{n}, move forward to the @var{n}th next hunk. @vindex diff-refine -By default, Diff mode @dfn{refines} hunks as Emacs displays them, -highlighting their changes with better granularity. Alternatively, if -you set @code{diff-refine} to the symbol @code{navigation}, Diff mode -only refines the hunk you move to with this command or with -@code{diff-hunk-prev}. +By default, Diff mode automatically @dfn{refines} hunks as Emacs +displays them, highlighting their changes with better granularity. +Alternatively, if you set @code{diff-refine} to the symbol +@code{navigation}, Diff mode only refines the hunk you move to with this +command or with @code{diff-hunk-prev}. Finally, you can set +@code{diff-refine} to @code{nil} and manually refine hunks using +@kbd{C-c C-b} (@code{diff-refine-hunk}), described below. + +@cindex shadow cursor (Diff mode) +@vindex smerge-refine-shadow-cursor +By default, refining a hunk in any way displays a @dfn{shadow cursor} at +one of the two edges of the refined region, to better show where the +refined region starts or ends. This can be controlled by customizing +the variable @code{smerge-refine-shadow-cursor}. @findex diff-hunk-prev @item M-p @@ -1895,7 +1904,8 @@ parts of the buffer where the hunks' file names are specified. @item C-c C-b Highlight the changes of the hunk at point with a finer granularity (@code{diff-refine-hunk}). This allows you to see exactly which parts -of each changed line were actually changed. +of each changed line were actually changed. Refining a hunk by default +shows a ``shadow cursor'' at one of the two edges of the refined region. @vindex diff-refine By default, Diff mode refines hunks as Emacs displays them, so you may diff --git a/etc/NEWS.31 b/etc/NEWS.31 index 1270b95e622..d71204b6be0 100644 --- a/etc/NEWS.31 +++ b/etc/NEWS.31 @@ -2566,6 +2566,14 @@ started inside Emacs. *** 'diff-mode' now refrains from automatically refining big hunks. What is big is defined by the new 'diff-refine-threshold' user option. ++++ +*** Refining a hunk shows a "shadow cursor" at the beginning/end of region. +By default, the shadow cursor looks like an empty rectangle the size of +a character cell. It is displayed at the beginning or the end of the +refined region, to better show where the refined region starts or ends. +This can be controlled by the new user option +'smerge-refine-shadow-cursor', which also affects SMerge mode, see below. + --- *** New command 'diff-kill-ring-save'. This command copies to the 'kill-ring' a region of text modified diff --git a/lisp/dired.el b/lisp/dired.el index a4bfd81b5b9..c559b7be6e2 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1238,8 +1238,11 @@ Type \\[describe-mode] after entering Dired for more info. If DIRNAME is already in a Dired buffer, that buffer is used without refresh." ;; Cannot use (interactive "D") because of wildcards. (interactive (dired-read-dir-and-switches "")) - (prog1 (pop-to-buffer-same-window (dired-noselect dirname switches)) - (dired--display-ls-error))) + (let ((buf (dired-noselect dirname switches))) + (prog1 (if buf + (pop-to-buffer-same-window buf) + (current-buffer)) + (dired--display-ls-error)))) ;; This lets clicks on the menu bar invoke Dired even if some feature ;; remaps the Dired command to another command that does not handle this @@ -1258,24 +1261,33 @@ If this command needs to split the current window, it by default obeys the user options `split-height-threshold' and `split-width-threshold', when it decides whether to split the window horizontally or vertically." (interactive (dired-read-dir-and-switches "in other window ")) - (prog1 (switch-to-buffer-other-window (dired-noselect dirname switches)) - (dired--display-ls-error))) + (let ((buf (dired-noselect dirname switches))) + (prog1 (if buf + (switch-to-buffer-other-window buf) + (current-buffer)) + (dired--display-ls-error)))) ;;;###autoload (keymap-set ctl-x-5-map "d" #'dired-other-frame) ;;;###autoload (defun dired-other-frame (dirname &optional switches) "\"Edit\" directory DIRNAME. Like `dired' but make a new frame." (interactive (dired-read-dir-and-switches "in other frame ")) - (prog1 (switch-to-buffer-other-frame (dired-noselect dirname switches)) - (dired--display-ls-error))) + (let ((buf (dired-noselect dirname switches))) + (prog1 (if buf + (switch-to-buffer-other-frame buf) + (current-buffer)) + (dired--display-ls-error)))) ;;;###autoload (keymap-set tab-prefix-map "d" #'dired-other-tab) ;;;###autoload (defun dired-other-tab (dirname &optional switches) "\"Edit\" directory DIRNAME. Like `dired' but make a new tab." (interactive (dired-read-dir-and-switches "in other tab ")) - (prog1 (switch-to-buffer-other-tab (dired-noselect dirname switches)) - (dired--display-ls-error))) + (let ((buf (dired-noselect dirname switches))) + (prog1 (if buf + (switch-to-buffer-other-tab buf) + (current-buffer)) + (dired--display-ls-error)))) ;;;###autoload (defun dired-noselect (dir-or-list &optional switches) diff --git a/lisp/gnus/gnus-icalendar.el b/lisp/gnus/gnus-icalendar.el index 54f105f6fda..d29eb545572 100644 --- a/lisp/gnus/gnus-icalendar.el +++ b/lisp/gnus/gnus-icalendar.el @@ -149,16 +149,25 @@ (defun gnus-icalendar-event--find-attendee (attendees ids) "Return the first `icalendar-attendee' in ATTENDEES matching IDS. -IDS should be a list of strings. The first attendee is returned whose -name (as `icalendar-cnparam') or email address (without \"mailto:\") -is a member of IDS." +IDS should be a list whose values are strings or functions. The first +attendee is returned whose name (as `icalendar-cnparam') or email +address (without \"mailto:\") matches a member of IDS." (catch 'found (dolist (attendee attendees) (ical:with-property attendee ((ical:cnparam :value name)) (let ((email (ical:strip-mailto value))) - (when (or (member name ids) - (member email ids)) - (throw 'found attendee))))))) + (dolist (matcher ids) + ;; Each MATCHER can be either a string or a function. + ;; The previous implementation returned an attendee if: + ;; - its NAME was `equal' to MATCHER as a string + ;; - its EMAIL matched MATCHER as a regexp + ;; - its EMAIL matched MATCHER if it was a predicate + ;; See also bug#81408. + (when (or (and (functionp matcher) (funcall matcher email)) + (and (stringp matcher) + (or (equal matcher name) + (string-match-p matcher email)))) + (throw 'found attendee)))))))) (defun gnus-icalendar-event--attendees-by-type (attendees) "Return lists of required and optional participants in ATTENDEES. diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 79180da8718..dce24949b5f 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -1037,7 +1037,7 @@ subshells can nest." ;; Skip through one pattern (while (or (/= 0 (skip-syntax-backward "w_")) - (/= 0 (skip-chars-backward "-$=?[]*@/\\\\")) + (/= 0 (skip-chars-backward "-$=?[]*@/\\\\!%:.^~,")) (and (sh-is-quoted-p (1- (point))) (goto-char (- (point) 2))) (when (memq (char-before) '(?\" ?\' ?\})) diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 735c36f9d97..b9ecab7af61 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -107,7 +107,10 @@ The value `font-lock' means to refine during font-lock. The value `navigation' means to refine each hunk as you visit it with `diff-hunk-next' or `diff-hunk-prev'. -You can always manually refine a hunk with `diff-refine-hunk'." +You can always manually refine a hunk with `diff-refine-hunk'. + +By default, refining a hunk in any way displays the \"shadow cursor\" +at one end of the refined region. See `smerge-refine-shadow-cursor'." :version "27.1" :type '(choice (const :tag "Don't refine hunks" nil) (const :tag "Refine hunks during font-lock" font-lock) diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el index 7267c37851d..06f954ce9fc 100644 --- a/lisp/vc/vc-hooks.el +++ b/lisp/vc/vc-hooks.el @@ -587,12 +587,13 @@ If FILE is not registered, this function always returns nil. This function does not return nil without first confirming with the underlying VCS that FILE is unregistered; this is in contrast to `vc-symbolic-working-revision'." - (or (vc-file-getprop file 'vc-working-revision) - (let ((default-directory (file-name-directory file))) - (and (setq backend (or backend (vc-backend file))) - (vc-file-setprop file 'vc-working-revision - (vc-call-backend backend 'working-revision - file)))))) + (let ((abs (expand-file-name file))) + (or (vc-file-getprop abs 'vc-working-revision) + (let ((default-directory (file-name-directory abs))) + (and (setq backend (or backend (vc-backend file))) + (vc-file-setprop abs 'vc-working-revision + (vc-call-backend backend 'working-revision + file))))))) (defun vc-symbolic-working-revision (file &optional backend) "Return BACKEND's symbolic name for FILE's working revision. diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index c0d160d182c..e2588fc3765 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -5731,9 +5731,9 @@ yourself with a function like `vc-file-tree-walk'." ;; having to load `vc-dir' just to get access to this simple wrapper. (let ((morep t) results) (with-temp-buffer - (setq default-directory directory) + (setq default-directory (expand-file-name directory)) (vc-call-backend (or backend (vc-responsible-backend directory)) - 'dir-status-files directory files + 'dir-status-files default-directory files (lambda (entries &optional more-to-come) (let (entry) (while (setq entry (pop entries)) @@ -6067,16 +6067,17 @@ non-ignored, non-up-to-date files within those directories." (remaining (cadr fileset)) ret-val) (while remaining - (cond* ((bind* (next (pop remaining)))) - ((atom next) - (push next (alist-get (vc-state next backend) ret-val))) - ((bind* (file (car next)))) - ((file-directory-p file) - (setq remaining - (nconc (vc-dir-status-files file nil backend) - remaining))) - (t - (push file (alist-get (cadr next) ret-val))))) + (let* ((next (pop remaining)) + (file (if (consp next) (car next) next))) + (if (file-directory-p file) + (setq remaining + (nconc (vc-dir-status-files file nil backend) + remaining)) + (push file + (alist-get (if (consp next) + (cadr next) + (vc-state next backend)) + ret-val))))) ret-val)) (declare-function diff-kill-creations-deletions "diff-mode") diff --git a/src/treesit.c b/src/treesit.c index 09a9006b876..edf728e04fa 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -4315,12 +4315,12 @@ treesit_cursor_helper_1 (TSTreeCursor *cursor, TSNode *target, /* ts_tree_cursor_goto_first_child_for_byte is significantly faster, so despite it having problems (see bug#60127), we try it first. Also, ts_tree_cursor_goto_first_child_for_byte can't find - zero-width nodes (which exists and are legit, e.g., markdown's + zero-width nodes (which exist and are legit, e.g., markdown's block_continuation), because a zero-width node can't contain a pos - (end > pos). */ - if (start_pos != end_pos - && ts_tree_cursor_goto_first_child_for_byte (cursor, start_pos) == -1 - && !ts_tree_cursor_goto_first_child (cursor)) + (end > pos); instead, it'll falsely return the next child. */ + if (!((start_pos != end_pos + && ts_tree_cursor_goto_first_child_for_byte (cursor, start_pos) != -1) + || ts_tree_cursor_goto_first_child (cursor))) return false; /* Go through each sibling that could contain TARGET. Because of diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba index ad880212e4a..c56eec00f3a 100644 --- a/test/infra/Dockerfile.emba +++ b/test/infra/Dockerfile.emba @@ -74,7 +74,7 @@ RUN apt-get update && \ clangd npm node-typescript rust-analyzer cargo \ && rm -rf /var/lib/apt/lists/* -RUN npm install -g typescript-language-server typescript +RUN npm install -g typescript-language-server RUN npm install -g vscode-json-languageserver # eclipse-jdt-ls is planned as Java language server. diff --git a/test/lisp/progmodes/sh-script-resources/sh-indents.erts b/test/lisp/progmodes/sh-script-resources/sh-indents.erts index 5a72df0e7ef..2bd09a9e9dd 100644 --- a/test/lisp/progmodes/sh-script-resources/sh-indents.erts +++ b/test/lisp/progmodes/sh-script-resources/sh-indents.erts @@ -49,3 +49,16 @@ Name: sh-indents5 for i do echo 1; done for i; do echo 1; done =-=-= + +Name: sh-indents-case-pattern-bug#81192 + +=-= +case "$1" in + a:b) + echo "a b" + ;; + *,*) + echo "other" + ;; +esac +=-=-= diff --git a/test/lisp/vc/vc-tests/vc-tests.el b/test/lisp/vc/vc-tests/vc-tests.el index f190db103d5..3201434ab78 100644 --- a/test/lisp/vc/vc-tests/vc-tests.el +++ b/test/lisp/vc/vc-tests/vc-tests.el @@ -1010,13 +1010,13 @@ This checks also `vc-backend' and `vc-responsible-backend'." (should (eq (vc-state "qux" backend) 'added)) (should (eq (vc-state "quux" backend) 'unregistered))) - (cl-flet ((go () - (let ((default-directory first) - (vc-no-confirm-moving-changes t)) - (vc--apply-to-other-working-tree - second second `(,backend - ("foo" "bar" "baz" "qux" "quux")) - nil t)))) + (cl-flet + ((go () + (let ((default-directory first) + (vc-no-confirm-moving-changes t)) + (vc--apply-to-other-working-tree second second + `(,backend (,first)) + nil t)))) (let ((default-directory second)) ;; Set up a series of incompatibilities, one-by-one, and ;; try to move. In each case the problem should block the