commit 323ac96236cac34a4c63b4b9be8a7369650069a7 (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Thu Jun 12 10:04:51 2025 +0300 ; Fix last change. diff --git a/lisp/term.el b/lisp/term.el index e46c2a965c3..98c136ce8a4 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -3069,6 +3069,9 @@ See `term-prompt-regexp'." (defconst term-control-seq-prefix-regexp "[\032\e]") +(defconst term--osc-max-bytes (* 32 1024 1024) + "Limit the length of OSC sequences to keep in memory.") + (defun term-emulate-terminal (proc str) (when (buffer-live-p (process-buffer proc)) (with-current-buffer (process-buffer proc) commit 6c13da2caf629b14853e9aa57e59aeeeec14e68f Author: Stephane Zermatten Date: Wed Jun 4 21:00:42 2025 +0300 Handle OSC sequences in term (bug#78263) Handlers can be registered to term-osc-handler, which by defaults, supports OSC 0, 2, 7 and 8, using handlers defined in ansi-osc. Unknown OSC sequences are ignored. * lisp/term.el (term-emulate-terminal): Handle OSC sequences. (term-osc-handler): New configuration variable. (term-control-seq-regexp): Extended regexp. (term--osc-max-bytes): New private constant. * lisp/ansi-osc.el (ansi-osc-handler): Handle OSC 0 like OSC 2. * test/lisp/term-tests.el (term-ignore-osc, term-handle-osc) (term-call-ansi-osc-handlers): New tests. diff --git a/lisp/ansi-osc.el b/lisp/ansi-osc.el index 06359779823..83fcd0d184a 100644 --- a/lisp/ansi-osc.el +++ b/lisp/ansi-osc.el @@ -62,7 +62,8 @@ pointed by `ansi-osc--marker'." (delete-region pos0 (point)) (setq ansi-osc--marker (copy-marker pos0)))))))) -(defvar-local ansi-osc-handlers '(("2" . ansi-osc-window-title-handler) +(defvar-local ansi-osc-handlers '(("0" . ansi-osc-window-title-handler) + ("2" . ansi-osc-window-title-handler) ("7" . ansi-osc-directory-tracker) ("8" . ansi-osc-hyperlink-handler)) "Alist of handlers for OSC escape sequences. diff --git a/lisp/term.el b/lisp/term.el index a971300c055..e46c2a965c3 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -304,6 +304,7 @@ (require 'cl-lib)) (require 'comint) ; Password regexp. (require 'ansi-color) +(require 'ansi-osc) (require 'ehelp) (require 'ring) (require 'shell) @@ -603,6 +604,33 @@ executed once, when the buffer is created." :type 'hook :group 'term) +(defvar term-osc-handlers nil + "Terminal-specific OSC sequence handler function alist. + +OSC (Operating System Command) is a category of ANSI escape sequence +used in terminal application to introduce custom commands. Terminals +ignore unknown OSC sequences by default. Handlers can be registered here +to add support for new OSC sequences to `term'. + +Functions in this alist are passed matching valid OSC sequences as +they're sent to the terminal. + +Valid OSC sequences are of the form + ESC ] code ; text BEL + ESC ] code ; text ESC \ + +Each entry has the form (CODE . FUNCTION), where CODE is the string that +appears before the semicolon. + +FUNCTION is called with two arguments CODE and TEXT, with TEXT being the +content of the OSC sequence after the semicolon. When the function is +called, the term buffer is active and with point and content valid at +the time the OSC sequence appears in the stream. + +Any code not on this alist is further looked up in `ansi-osc-handlers', +which collects OSC handlers that can also work outside of a terminal +context. For details, see `ansi-osc-apply-on-region'.") + (defvar term-mode-map (let ((map (make-sparse-keymap))) (define-key map "\ep" 'term-previous-input) @@ -3030,6 +3058,10 @@ See `term-prompt-regexp'." "\e\\(?:[DM78c]\\|" ;; another Emacs specific control sequence, "AnSiT[^\n]+\n\\|" + ;; OSC (See [ECMA-48] section 8.3.89 "Operation System Command".) + ;; The spec only allows 0x08-0x0d 0x20-7e, but this regexp also + ;; allows non-ascii (UTF-8) characters. + "\\][^\x00-\x07\x0e-\x1f\x7f]*\\(?:\a\\|\e\\\\\\)?\\|" ;; or an escape sequence (section 5.4 "Control Sequences"), "\\[\\([\x30-\x3F]*\\)[\x20-\x2F]*[\x40-\x7E]\\)\\)") "Regexp matching control sequences handled by term.el.") @@ -3232,6 +3264,33 @@ See `term-prompt-regexp'." (split-string ctl-params ";")) (aref str (1- ctl-end)) private)))) + (?\] ;; An OSC sequence + (let ((seq-str (substring str (+ i 2) ctl-end))) + (string-match + "\\`\\(\\([0-9A-Za-z]+\\);\\)?.*?\\(\a\\|\e\\\\\\)?\\'" + seq-str) + (let ((code (match-string 2 seq-str)) + (text-start (match-end 1)) + (end-mark (match-beginning 3))) + (when (and code end-mark) + (when-let* ((func (cdr (or (assoc-string + code term-osc-handlers) + (assoc-string + code ansi-osc-handlers))))) + (with-demoted-errors "term OSC error: %S" + (funcall + func code + (decode-coding-string + (substring seq-str text-start end-mark) + locale-coding-system t))))) + (when (and (not end-mark) + (>= ctl-end str-length) + (< (- ctl-end i) term--osc-max-bytes)) + ;; Continue ignoring until the end marker. + (setq term-terminal-undecoded-bytes + (substring str i))))) + ;; Consume everything + (setq i ctl-end)) (?D ;; Scroll forward (apparently not documented in ;; [ECMA-48], [ctlseqs] mentions it as C1 ;; character "Index" though). diff --git a/test/lisp/term-tests.el b/test/lisp/term-tests.el index ffb341f3b52..4fcc564cc5d 100644 --- a/test/lisp/term-tests.el +++ b/test/lisp/term-tests.el @@ -419,6 +419,123 @@ This is a reduced example from GNU nano's initial screen." (term-test-screen-from-input 40 1 bytes))))) +(ert-deftest term-ignore-osc () + ;; BEL-terminated OSC sequence + (should (equal "test" + (term-test-screen-from-input + 40 1 "te\e]0;window title\ast"))) + ;; ESC \-terminated OSC sequence + (should (equal "test" + (term-test-screen-from-input + 40 1 "te\e]0;window title\e\\st"))) + ;; Long OSC sequence split into multiple chunks + (should (equal "test" + (term-test-screen-from-input + 40 1 '("te\e]0;win" "dow " " title\ast")))) + ;; OSC sequence that start and ends with the chunk + (should (equal "test" + (term-test-screen-from-input + 40 1 '("te" "\e]0;window " "title\a" "st")))) + + ;; Invalid control characters break out of the OSC sequence, for + ;; safety. + (should (equal "tetitlest" + (term-test-screen-from-input + 40 1 '("te\e]0;window\x05title\ast")))) + + (let ((locale-coding-system 'utf-8-unix)) + ;; An OSC sequence with multibyte UTF-8 characters. This is not + ;; exactly standard-compliant, but too common not to support. + (should (equal "test" + (term-test-screen-from-input + 40 1 "te\e]0;\xce\xb1\xce\xb2\e\\st"))))) + +(ert-deftest term-handle-osc () + (let* ((captured nil) + (handler (lambda (code text) + (push (cons code text) + captured))) + (term-osc-handlers `(("2" . ,handler) + ("1994" . ,handler)))) + + ;; Send OSC sequences to handler + (should (equal "test" + (term-test-screen-from-input + 40 1 "te\e]2;foo\as\e]1994;bar\at"))) + (should (equal '(("2" . "foo") + ("1994" . "bar")) + (nreverse captured))) + + ;; OSC sequences and code can be chunked + (setq captured nil) + (should (equal "test" + (term-test-screen-from-input + 40 1 `("te\e]2;chunked fo" + "o\as\e]19" + "94;chunked ba" + "r\at")))) + (should (equal '(("2" . "chunked foo") + ("1994" . "chunked bar")) + (nreverse captured))) + + ;; OSC sequences can contain multibyte characters + (let ((locale-coding-system 'utf-8-unix)) + (setq captured nil) + (should (equal "test" + (term-test-screen-from-input + 40 1 "te\e]2;\xce\xb1\xce\xb2\e\\st"))) + (should (equal '(("2" . "αβ")) captured))) + + ;; Ignore unhandled and invalid OSC sequences + (setq captured nil) + (should (equal + "test" + (term-test-screen-from-input + 40 1 "t\e]3;unhandled\aest"))) + (should-not captured) + (should (equal + "test" + (term-test-screen-from-input + 40 1 "t\e]2missing semicolon\aest"))) + (should-not captured) + + (should (equal + "test" + (term-test-screen-from-input + 40 1 "t\e]2;not ended\003est"))) + (should-not captured))) + +(ert-deftest term-call-ansi-osc-handlers () + (let* ((captured nil) + (osc-handler (lambda (code text) + (push (list 'osc code text) + captured))) + (term-handler (lambda (code text) + (push (list 'term code text) + captured))) + (ansi-osc-handlers `(("1" . ,osc-handler) + ("2" . ,osc-handler) + ("3" . ,osc-handler))) + (term-osc-handlers `(("2" . ,term-handler) + ("3" . nil)))) + + (should + (equal + "test" + (term-test-screen-from-input + 40 1 (concat + "te" + "\e]1;a\a" ;; sent to osc-handler + "\e]2;b\a" ;; sent to term-handler + "\e]3;c\a" ;; ignored; disabled in term + "\e]4;d\a" ;; ignored; not registered + "st")))) + (should + (equal + '((osc "1" "a") + (term "2" "b")) + (nreverse captured))))) + (provide 'term-tests) ;;; term-tests.el ends here commit 3939623d76baae16374937d865294577f86fc743 Author: Eli Zaretskii Date: Thu Jun 12 09:49:44 2025 +0300 ; * etc/NEWS: Fix last change. diff --git a/etc/NEWS b/etc/NEWS index 153fa6797ff..3f8335bd111 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2170,9 +2170,9 @@ You can now use the mouse wheel to scroll the calendar by 3 months. With the shift modifier, it scrolls by one month. With the meta modifier, it scrolls by year. -*** Simpler month and year navigation binds in calendar. -The month and year navigation binds 'M-}', 'M-{', 'C-x ]' and 'C-x [' -now admit the alternatives '}', '{', ']' and '['. +*** Simpler key bindings for navigation in calendar by months and by years. +The month and year navigation key bindings 'M-}', 'M-{', 'C-x ]' and +'C-x [' now have the alternative keys '}', '{', ']' and '['. * New Modes and Packages in Emacs 31.1 commit fbb77abc816844ccad761d246cfb833c424ae0b8 Author: Paul Nelson Date: Tue Jun 10 11:33:05 2025 +0200 Add simpler binds for calendar month/year navigation * lisp/calendar/calendar.el (calendar-mode-map): Add keybindings '{' and '}' for month navigation, '[' and ']' for year navigation (bug#78753). * doc/emacs/calendar.texi (Calendar Unit Motion): Document them. diff --git a/doc/emacs/calendar.texi b/doc/emacs/calendar.texi index 56f297db5d0..b3558448975 100644 --- a/doc/emacs/calendar.texi +++ b/doc/emacs/calendar.texi @@ -84,12 +84,16 @@ Move point one week forward (@code{calendar-forward-week}). @item C-p Move point one week backward (@code{calendar-backward-week}). @item M-@} +@itemx @} Move point one month forward (@code{calendar-forward-month}). @item M-@{ +@itemx @{ Move point one month backward (@code{calendar-backward-month}). @item C-x ] +@itemx ] Move point one year forward (@code{calendar-forward-year}). @item C-x [ +@itemx [ Move point one year backward (@code{calendar-backward-year}). @end table @@ -114,12 +118,16 @@ week. @kbd{C-f} (@code{calendar-forward-day}) and @kbd{C-b} @kbd{C-p}, just as they normally are in other modes. @kindex M-@} @r{(Calendar mode)} +@kindex @} @r{(Calendar mode)} @findex calendar-forward-month @kindex M-@{ @r{(Calendar mode)} +@kindex @{ @r{(Calendar mode)} @findex calendar-backward-month @kindex C-x ] @r{(Calendar mode)} +@kindex ] @r{(Calendar mode)} @findex calendar-forward-year @kindex C-x [ @r{(Calendar mode)} +@kindex [ @r{(Calendar mode)} @findex calendar-backward-year The commands for motion by months and years work like those for weeks, but move a larger distance. The month commands @kbd{M-@}} @@ -137,6 +145,9 @@ to the beginning or end of a paragraph, whereas these month and year commands move by an entire month or an entire year, keeping the same date within the month or year. + You can also use the simpler to type keystrokes @kbd{@}} and @kbd{@{} +to navigate by month, and @kbd{]} and @kbd{[} to navigate by year. + All these commands accept a numeric argument as a repeat count. For convenience, the digit keys and the minus sign specify numeric arguments in Calendar mode even without the Meta modifier. For example, diff --git a/etc/NEWS b/etc/NEWS index 81f0215deda..153fa6797ff 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2169,6 +2169,11 @@ is bound to 'C-l' in the calendar buffer. You can now use the mouse wheel to scroll the calendar by 3 months. With the shift modifier, it scrolls by one month. With the meta modifier, it scrolls by year. + +*** Simpler month and year navigation binds in calendar. +The month and year navigation binds 'M-}', 'M-{', 'C-x ]' and 'C-x [' +now admit the alternatives '}', '{', ']' and '['. + * New Modes and Packages in Emacs 31.1 diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el index c448955450e..1c98de98b9b 100644 --- a/lisp/calendar/calendar.el +++ b/lisp/calendar/calendar.el @@ -1603,7 +1603,9 @@ Otherwise, use the selected window of EVENT's frame." (define-key map "\C-b" 'calendar-backward-day) (define-key map "\C-p" 'calendar-backward-week) (define-key map "\e{" 'calendar-backward-month) + (define-key map "{" 'calendar-backward-month) (define-key map "\C-x[" 'calendar-backward-year) + (define-key map "[" 'calendar-backward-year) (define-key map "\C-f" 'calendar-forward-day) (define-key map "\C-n" 'calendar-forward-week) (define-key map [left] 'calendar-backward-day) @@ -1611,7 +1613,9 @@ Otherwise, use the selected window of EVENT's frame." (define-key map [right] 'calendar-forward-day) (define-key map [down] 'calendar-forward-week) (define-key map "\e}" 'calendar-forward-month) + (define-key map "}" 'calendar-forward-month) (define-key map "\C-x]" 'calendar-forward-year) + (define-key map "]" 'calendar-forward-year) (define-key map "\C-a" 'calendar-beginning-of-week) (define-key map "\C-e" 'calendar-end-of-week) (define-key map "\ea" 'calendar-beginning-of-month) commit 81a3e4e51167be51c63eae682331210bc62f7280 Author: Michael Albinus Date: Wed Jun 11 19:20:43 2025 +0200 Make file-notify--call-handler more robust * lisp/filenotify.el (file-notify--call-handler): Make it more robust. (Bug#78712) diff --git a/lisp/filenotify.el b/lisp/filenotify.el index 9acf7651df5..96c2c46d1df 100644 --- a/lisp/filenotify.el +++ b/lisp/filenotify.el @@ -233,16 +233,18 @@ It is nil or a `file-notify--rename' defstruct where the cookie can be nil.") (and (stringp file1) (string-equal (file-notify--watch-filename watch) (file-name-nondirectory file1)))) - (when file-notify-debug - (message - "file-notify-callback %S %S %S %S %S %S %S" - desc action file file1 watch - (file-notify--watch-absolute-filename watch) - (file-notify--watch-directory watch))) - (funcall (file-notify--watch-callback watch) - (if file1 - (list desc action file file1) - (list desc action file))))) + ;; The callback could have removed in `file-notify--rm-descriptor'. + (when (file-notify--watch-callback watch) + (when file-notify-debug + (message + "file-notify-callback %S %S %S %S %S %S %S" + desc action file file1 watch + (file-notify--watch-absolute-filename watch) + (file-notify--watch-directory watch))) + (funcall (file-notify--watch-callback watch) + (if file1 + (list desc action file file1) + (list desc action file)))))) (defun file-notify--handle-event (desc actions file file1-or-cookie) "Handle an event returned from file notification. commit 7e62c2cf3aadb52397bcff8439d00084cd36afa0 Author: Robert Pluim Date: Tue Jun 10 09:52:39 2025 +0200 Normalize URL path correctly for http * lisp/url/url-http.el (url-http-create-request): Prepend "/" if it's missing from the filename. (Bug#78640) diff --git a/lisp/url/url-http.el b/lisp/url/url-http.el index 4258da33a33..eb5d5c13722 100644 --- a/lisp/url/url-http.el +++ b/lisp/url/url-http.el @@ -325,8 +325,10 @@ Use `url-http-referer' as the Referer-header (subject to `url-privacy-level')." url-http-target-url) nil 'any nil))) (ref-url (url-http--encode-string url-http-referer))) - (if (equal "" real-fname) - (setq real-fname "/")) + ;; RFC 3986 section 6.2.3 says an empty path should be normalized to + ;; "/", even if the filename is non-empty. (Bug#78640) + (unless (string-match-p "\\`/" real-fname) + (setq real-fname (concat "/" real-fname))) (setq no-cache (and no-cache (string-match "no-cache" no-cache))) (if auth (setq auth (concat "Authorization: " auth "\r\n"))) commit 8be65cf6e02ffdc6396af61a13413c7065c832d9 Author: Sean Whitton Date: Wed Jun 11 15:09:07 2025 +0100 ; etc/NEWS: Clarify VC entry about missing vs. removed files. diff --git a/etc/NEWS b/etc/NEWS index e762e5ae8e1..81f0215deda 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1793,14 +1793,15 @@ files, and 'C-x v v' behaved subtly differently for the two statuses. The combination of these differences between backends and in 'C-x v v' behavior was confusing. Now, -- the Git backend properly marks files as missing if you just delete - them instead of using 'C-x v x' - in VC-Dir, you can use 'C-x v v' on missing files to mark them as removed - when committing, you can include missing files in a set of files with different statuses, just like you've always been able to include removed files. +In addition, the Git backend has been fixed to display missing files as +'missing' instead of incorrectly subsuming them to the 'removed' status. + There is still some further work to do to rationalize VC's handling of file removal. commit 1468daf1d1b3ea2916384e4ae78050a9451a64d8 Author: Alan Mackenzie Date: Wed Jun 11 13:43:50 2025 +0000 Amend CC Mode so that the test suite in XEmacs runs error free * lisp/progmodes/cc-awk.el (awk-font-lock-keywords): Reformulate this using backquote and ,@. Only include the entry for _" in Emacs. * lisp/progmodes/cc-defs.el (c--mapcan, c--set-difference) c--intersection, c--macroexpand-all, c--delete-duplicates): No longer use the existence of cl-lib.el as the criterion for what to expand to. (c-min-property-position): Use c-next-single-property-change rather than next-single-property-change. This now works in XEmacs. * lisp/progmodes/cc-engine.el (c-invalidate-sws-region-after-del) (c-invalidate-sws-region-after-ins, c-forward-sws) (c-backward-sws, c-find-decl-spots): Replace next/previous-single-property-change by c-next/previous-single-property-change to ensure functionality in XEmacs. (c-forward-sws, c-backward-sws): Handle NO-BREAKING-SPACE as whitespace. This corrects the error in hardspace.c in the test suite. * lisp/progmodes/cc-fonts.el (c-font-lock-ml-strings): Refactor some nested `if's into a cond form. Don't fontify multiline string delimiters in XEmacs, in keeping with its string conventions. * lisp/progmodes/cc-langs.el (c-populate-syntax-table): Set the syntax of NO-BREAKING-SPACE to whitespace rather than punctuation. * lisp/progmodes/cc-mode.el (c-before-change): Use c-previous-single-property-change rather than previous-single-property-change to ensure functionality in XEmacs. diff --git a/lisp/progmodes/cc-awk.el b/lisp/progmodes/cc-awk.el index 4b07c99924c..d9172bce8fc 100644 --- a/lisp/progmodes/cc-awk.el +++ b/lisp/progmodes/cc-awk.el @@ -962,9 +962,9 @@ ;; in XEmacs 21.4.4. acm 2002/9/19. (defconst awk-font-lock-keywords (eval-when-compile - (list - ;; Function declarations. - `(,(c-make-font-lock-search-function + `( + ;; Function declarations. + (,(c-make-font-lock-search-function "^\\s *\\(func\\(tion\\)?\\)\\s +\\(\\(\\sw+\\(::\\sw+\\)?\\)\\s *\\)?\\(([^()]*)\\)?" '(1 'font-lock-keyword-face t) ;; We can't use LAXMATCH in `c-make-font-lock-search-function', so.... @@ -983,15 +983,15 @@ nil)))) ;; Variable names. - (cons - (concat "\\<" - (regexp-opt - '("ARGC" "ARGIND" "ARGV" "BINMODE" "CONVFMT" "ENVIRON" - "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR" "FPAT" "FS" "FUNCTAB" - "IGNORECASE" "LINT" "NF" "NR" "OFMT" "OFS" "ORS" "PREC" - "PROCINFO" "RLENGTH" "ROUNDMODE" "RS" "RSTART" "RT" "SUBSEP" - "SYMTAB" "TEXTDOMAIN") t) "\\>") - 'font-lock-variable-name-face) + ,(cons + (concat "\\<" + (regexp-opt + '("ARGC" "ARGIND" "ARGV" "BINMODE" "CONVFMT" "ENVIRON" + "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR" "FPAT" "FS" "FUNCTAB" + "IGNORECASE" "LINT" "NF" "NR" "OFMT" "OFS" "ORS" "PREC" + "PROCINFO" "RLENGTH" "ROUNDMODE" "RS" "RSTART" "RT" "SUBSEP" + "SYMTAB" "TEXTDOMAIN") t) "\\>") + 'font-lock-variable-name-face) ;; Special file names. (acm, 2002/7/22) ;; The following regexp was created by first evaluating this in GNU Emacs 21.1: @@ -1003,7 +1003,7 @@ ;; regexp so that a " must come before, and either a " or heuristic stuff after. ;; The surrounding quotes are fontified along with the filename, since, semantically, ;; they are an indivisible unit. - '("\\(\"/dev/\\(fd/[0-9]+\\|p\\(\\(\\(gr\\)?p\\)?id\\)\\|\ + ("\\(\"/dev/\\(fd/[0-9]+\\|p\\(\\(\\(gr\\)?p\\)?id\\)\\|\ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\ \\(\\(\"\\)\\|\\([^\"/\n\r][^\"\n\r]*\\)?$\\)" (1 font-lock-variable-name-face t) @@ -1015,22 +1015,22 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\ ;; , replacing "lport", "rhost", and "rport" with "[[:alnum:]]+". ;; This cannot be combined with the above pattern, because the match number ;; for the (optional) closing \" would then exceed 9. - '("\\(\"/inet[46]?/\\(\\(raw\\|\\(tc\\|ud\\)p\\)/[[:alnum:]]+/[[:alnum:]]+/[[:alnum:]]+\\)\\)\\>\ + ("\\(\"/inet[46]?/\\(\\(raw\\|\\(tc\\|ud\\)p\\)/[[:alnum:]]+/[[:alnum:]]+/[[:alnum:]]+\\)\\)\\>\ \\(\\(\"\\)\\|\\([^\"/\n\r][^\"\n\r]*\\)?$\\)" (1 font-lock-variable-name-face t) (6 font-lock-variable-name-face t t)) ;; Keywords. - (concat "\\<" - (regexp-opt - '("BEGIN" "BEGINFILE" "END" "ENDFILE" - "break" "case" "continue" "default" "delete" - "do" "else" "exit" "for" "getline" "if" "in" "next" - "nextfile" "return" "switch" "while") - t) "\\>") + ,(concat "\\<" + (regexp-opt + '("BEGIN" "BEGINFILE" "END" "ENDFILE" + "break" "case" "continue" "default" "delete" + "do" "else" "exit" "for" "getline" "if" "in" "next" + "nextfile" "return" "switch" "while") + t) "\\>") ;; Builtins. - `(eval . (list + (eval . (list ,(concat "\\<" (regexp-opt @@ -1045,32 +1045,33 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\ "\\>") 0 c-preprocessor-face-name)) - ;; Directives - `(eval . '("@\\(include\\|load\\|namespace\\)\\>" 0 ,c-preprocessor-face-name)) + ;; Directives + (eval . '("@\\(include\\|load\\|namespace\\)\\>" 0 ,c-preprocessor-face-name)) - ;; gawk debugging keywords. (acm, 2002/7/21) - ;; (Removed, 2003/6/6. These functions are now fontified as built-ins) - ;; (list (concat "\\<" (regexp-opt '("adump" "stopme") t) "\\>") - ;; 0 'font-lock-warning-face) + ;; gawk debugging keywords. (acm, 2002/7/21) + ;; (Removed, 2003/6/6. These functions are now fontified as built-ins) + ;; (list (concat "\\<" (regexp-opt '("adump" "stopme") t) "\\>") + ;; 0 'font-lock-warning-face) - ;; User defined functions with an apparent spurious space before the - ;; opening parenthesis. acm, 2002/5/30. - `(,(concat "\\(\\w\\|_\\)" c-awk-escaped-nls* "\\s " + ;; User defined functions with an apparent spurious space before the + ;; opening parenthesis. acm, 2002/5/30. + (,(concat "\\(\\w\\|_\\)" c-awk-escaped-nls* "\\s " c-awk-escaped-nls*-with-space* "(") (0 'font-lock-warning-face)) - ;; Double :: tokens, or the same with space(s) around them. - #'c-awk-font-lock-invalid-namespace-separators + ;; Double :: tokens, or the same with space(s) around them. + c-awk-font-lock-invalid-namespace-separators - ;; Space after \ in what looks like an escaped newline. 2002/5/31 - '("\\\\\\s +$" 0 font-lock-warning-face t) + ;; Space after \ in what looks like an escaped newline. 2002/5/31 + ("\\\\\\s +$" 0 font-lock-warning-face t) - ;; Unbalanced string (") or regexp (/) delimiters. 2002/02/16. - '("\\s|" 0 font-lock-warning-face t nil) - ;; gawk 3.1 localizable strings ( _"translate me!"). 2002/5/21 - '("\\(_\\)\\s|" 1 font-lock-warning-face) - '("\\(_\\)\\s\"" 1 font-lock-string-face) ; FIXME! not for XEmacs. 2002/10/6 - )) + ;; Unbalanced string (") or regexp (/) delimiters. 2002/02/16. + ("\\s|" 0 font-lock-warning-face t nil) + ;; gawk 3.1 localizable strings ( _"translate me!"). 2002/5/21 + ("\\(_\\)\\s|" 1 font-lock-warning-face) + ,@(unless (featurep 'xemacs) + '(("\\(_\\)\\s\"" 1 font-lock-string-face))) + )) "Default expressions to highlight in AWK mode.") ;; ACM 2002/9/29. Movement functions, e.g. for C-M-a and C-M-e diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 9f9f076641b..e806fb754aa 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el @@ -188,9 +188,12 @@ This variant works around bugs in `eval-when-compile' in various (subrp (symbol-function 'mapcan))) ;; XEmacs and Emacs >= 26. `(mapcan ,fun ,liszt)) - ((eq c--cl-library 'cl-lib) - ;; Emacs >= 24.3, < 26. - `(cl-mapcan ,fun ,liszt)) + ;; The following was commented out on 2025-06-02. cl-mapcan fails in an + ;; obscure fashion in c-keywords-obarray. See that c-lang-defvar for + ;; details. + ;; ((eq c--cl-library 'cl-lib) + ;; ;; Emacs >= 24.3, < 26. + ;; `(cl-mapcan ,fun ,liszt)) (t ;; Emacs <= 24.2. It would be nice to be able to distinguish between ;; compile-time and run-time use here. @@ -199,16 +202,16 @@ This variant works around bugs in `eval-when-compile' in various (defmacro c--set-difference (liszt1 liszt2 &rest other-args) ;; Macro to smooth out the renaming of `set-difference' in Emacs 24.3. (declare (debug (form form &rest [symbolp form]))) - (if (eq c--cl-library 'cl-lib) - `(cl-set-difference ,liszt1 ,liszt2 ,@other-args) - `(set-difference ,liszt1 ,liszt2 ,@other-args))) + (if (fboundp 'set-difference) + `(set-difference ,liszt1 ,liszt2 ,@other-args) + `(cl-set-difference ,liszt1 ,liszt2 ,@other-args))) (defmacro c--intersection (liszt1 liszt2 &rest other-args) ;; Macro to smooth out the renaming of `intersection' in Emacs 24.3. (declare (debug (form form &rest [symbolp form]))) - (if (eq c--cl-library 'cl-lib) - `(cl-intersection ,liszt1 ,liszt2 ,@other-args) - `(intersection ,liszt1 ,liszt2 ,@other-args))) + (if (fboundp 'intersection) + `(intersection ,liszt1 ,liszt2 ,@other-args) + `(cl-intersection ,liszt1 ,liszt2 ,@other-args))) (eval-and-compile (defmacro c--macroexpand-all (form &optional environment) @@ -221,9 +224,9 @@ This variant works around bugs in `eval-when-compile' in various (defmacro c--delete-duplicates (cl-seq &rest cl-keys) ;; Macro to smooth out the renaming of `delete-duplicates' in Emacs 24.3. (declare (debug (form &rest [symbolp form]))) - (if (eq c--cl-library 'cl-lib) - `(cl-delete-duplicates ,cl-seq ,@cl-keys) - `(delete-duplicates ,cl-seq ,@cl-keys)))) + (if (fboundp 'delete-duplicates) + `(delete-duplicates ,cl-seq ,@cl-keys) + `(cl-delete-duplicates ,cl-seq ,@cl-keys)))) (defmacro c-font-lock-flush (beg end) "Declare the region BEG...END's fontification as out-of-date. @@ -1367,7 +1370,7 @@ MODE is either a mode symbol or a list of mode symbols." ((and (< -from- -to-) (get-text-property -from- ,property)) -from-) - ((< (setq pos (next-single-property-change -from- ,property nil -to-)) + ((< (setq pos (c-next-single-property-change -from- ,property nil -to-)) -to-) pos) (most-positive-fixnum)))) diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 48c11fab861..b5e2ce4a0d5 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -2033,11 +2033,11 @@ comment at the start of cc-engine.el for more info." ; comment delimiters are 2 ; chars long. (or (get-text-property end 'c-in-sws) - (next-single-property-change end 'c-in-sws nil - (cdr c-sws-lit-limits)) + (c-next-single-property-change end 'c-in-sws nil + (cdr c-sws-lit-limits)) (get-text-property end 'c-is-sws) - (next-single-property-change end 'c-is-sws nil - (cdr c-sws-lit-limits)))) + (c-next-single-property-change end 'c-is-sws nil + (cdr c-sws-lit-limits)))) (cdr c-sws-lit-limits)))) (defun c-invalidate-sws-region-after-ins (end) @@ -2055,10 +2055,10 @@ comment at the start of cc-engine.el for more info." limits (cons (point) (progn (c-end-of-macro) (point))))) (when (memq lit-type '(c c++ pound)) - (let ((next-in (next-single-property-change (car limits) 'c-in-sws - nil (cdr limits))) - (next-is (next-single-property-change (car limits) 'c-is-sws - nil (cdr limits)))) + (let ((next-in (c-next-single-property-change (car limits) 'c-in-sws + nil (cdr limits))) + (next-is (c-next-single-property-change (car limits) 'c-is-sws + nil (cdr limits)))) (and (or next-in next-is) (cdr limits))))))) @@ -2141,7 +2141,7 @@ comment at the start of cc-engine.el for more info." ;; Skip simple ws and do a quick check on the following character to see ;; if it's anything that can't start syntactic ws, so we can bail out ;; early in the majority of cases when there just are a few ws chars. - (c-skip-ws-chars-forward " \t\n\r\f\v") + (c-skip-ws-chars-forward " \t\n\r\f\v ") (when (or (looking-at c-syntactic-ws-start) (and c-opt-cpp-prefix (looking-at c-noise-macro-name-re)) @@ -2154,7 +2154,7 @@ comment at the start of cc-engine.el for more info." 'c-is-sws t)) ;; Find the last rung position to avoid setting properties in all ;; the cases when the marked rung is complete. - ;; (`next-single-property-change' is certain to move at least one + ;; (`c-next-single-property-change' is certain to move at least one ;; step forward.) (setq rung-pos (1- (c-next-single-property-change rung-is-marked 'c-is-sws nil rung-end-pos))) @@ -2182,7 +2182,7 @@ comment at the start of cc-engine.el for more info." ;; If the `c-in-sws' region extended past the last ;; `c-is-sws' char we have to go back a bit. (or (get-text-property (1- (point)) 'c-is-sws) - (goto-char (previous-single-property-change + (goto-char (c-previous-single-property-change (point) 'c-is-sws))) (backward-char)) @@ -2191,7 +2191,7 @@ comment at the start of cc-engine.el for more info." rung-pos (point) (point-max)) (setq rung-pos (point)) - (and (> (c-skip-ws-chars-forward " \t\n\r\f\v") 0) + (and (> (c-skip-ws-chars-forward " \t\n\r\f\v ") 0) (not (eobp)))) ;; We'll loop here if there is simple ws after the last rung. @@ -2258,7 +2258,7 @@ comment at the start of cc-engine.el for more info." (and c-opt-cpp-prefix (looking-at c-opt-cpp-start) (setq macro-start (point)) - (progn (c-skip-ws-chars-backward " \t") + (progn (c-skip-ws-chars-backward " \t ") (bolp)) (or (bobp) (progn (backward-char) @@ -2298,7 +2298,7 @@ comment at the start of cc-engine.el for more info." ;; We've searched over a piece of non-white syntactic ws. See if this ;; can be cached. (setq next-rung-pos (point)) - (c-skip-ws-chars-forward " \t\n\r\f\v") + (c-skip-ws-chars-forward " \t\n\r\f\v ") (setq rung-end-pos (min (1+ (point)) (point-max))) (if (or @@ -2395,7 +2395,7 @@ comment at the start of cc-engine.el for more info." ;; bail out early in the majority of cases when there just are a few ws ;; chars. Newlines are complicated in the backward direction, so we can't ;; skip over them. - (c-skip-ws-chars-backward " \t\f") + (c-skip-ws-chars-backward " \t\f ") (when (and (not (bobp)) (save-excursion (or (and @@ -2423,7 +2423,7 @@ comment at the start of cc-engine.el for more info." (setq simple-ws-beg (or attr-end ; After attribute. (match-end 1) ; Noise macro, etc. (match-end 0))) ; c-syntactic-ws-end - (c-skip-ws-chars-backward " \t\n\r\f\v") + (c-skip-ws-chars-backward " \t\n\r\f\v ") (if (setq rung-is-marked (text-property-any (point) (min (1+ rung-pos) (point-max)) 'c-is-sws t)) @@ -2447,7 +2447,7 @@ comment at the start of cc-engine.el for more info." ;; The following search is the main reason that `c-in-sws' ;; and `c-is-sws' aren't combined to one property. - (goto-char (previous-single-property-change + (goto-char (c-previous-single-property-change (point) 'c-in-sws nil (point-min))) (unless (get-text-property (point) 'c-is-sws) ;; If the `c-in-sws' region extended past the first @@ -2460,10 +2460,10 @@ comment at the start of cc-engine.el for more info." (point) rung-pos (point-min)) (setq rung-pos (point)) - (if (and (< (min (c-skip-ws-chars-backward " \t\f\v") + (if (and (< (min (c-skip-ws-chars-backward " \t\f\v ") (progn (setq simple-ws-beg (point)) - (c-skip-ws-chars-backward " \t\n\r\f\v"))) + (c-skip-ws-chars-backward " \t\n\r\f\v "))) 0) (setq rung-is-marked (text-property-any (point) rung-pos @@ -2543,7 +2543,7 @@ comment at the start of cc-engine.el for more info." ;; the macro, and then `simple-ws-beg' must be kept on the ;; same side of those comments. (goto-char simple-ws-beg) - (c-skip-ws-chars-backward " \t\n\r\f\v") + (c-skip-ws-chars-backward " \t\n\r\f\v ") (if (eq (char-before) ?\\) (forward-char)) (forward-line 1) @@ -2556,7 +2556,7 @@ comment at the start of cc-engine.el for more info." t))) ((/= (save-excursion - (c-skip-ws-chars-forward " \t\n\r\f\v" simple-ws-beg) + (c-skip-ws-chars-forward " \t\n\r\f\v " simple-ws-beg) (setq next-rung-pos (point))) simple-ws-beg) ;; Skipped over comments. Must put point at the end of @@ -2593,8 +2593,8 @@ comment at the start of cc-engine.el for more info." ;; We've searched over a piece of non-white syntactic ws. See if this ;; can be cached. (setq next-rung-pos (point)) - (c-skip-ws-chars-backward " \t\f\v") - + (c-skip-ws-chars-backward " \t\f\v ") + (if (or ;; Cache if we started either from a marked rung or from a ;; completely uncached position. @@ -2603,7 +2603,7 @@ comment at the start of cc-engine.el for more info." ;; Cache if there's a marked rung in the encountered simple ws. (save-excursion - (c-skip-ws-chars-backward " \t\n\r\f\v") + (c-skip-ws-chars-backward " \t\n\r\f\v ") (text-property-any (point) (min (1+ next-rung-pos) (point-max)) 'c-is-sws t))) @@ -6548,7 +6548,7 @@ comment at the start of cc-engine.el for more info." ;; inside a comment? (while (and (not (bobp)) (c-got-face-at (1- (point)) c-literal-faces)) - (goto-char (previous-single-property-change + (goto-char (c-previous-single-property-change (point) 'face nil (point-min)))) ; No limit. FIXME, perhaps? 2020-12-07. ;; XEmacs doesn't fontify the quotes surrounding string @@ -6718,7 +6718,7 @@ comment at the start of cc-engine.el for more info." (goto-char start-in-literal) (goto-char cfd-start-pos) (while (progn - (goto-char (previous-single-property-change + (goto-char (c-previous-single-property-change (point) 'c-type nil start-in-literal)) (and (> (point) start-in-literal) (not (eq (c-get-char-property (point) 'c-type) diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 9837b0c6d39..76a60ae110c 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -1989,19 +1989,19 @@ casts and declarations are fontified. Used on level 2 and higher." (>= (point) (cadar string-delims)) (or (not (cdr string-delims)) (< (point) (cadr string-delims)))) - (if (cdr string-delims) - (goto-char (cadr string-delims)) - (if (equal (c-get-char-property (1- (cadar string-delims)) - 'syntax-table) - '(15)) ; "Always" the case. - ;; The next search should be successful for an unterminated ml - ;; string inside a macro, but not for any other unterminated - ;; string. - (progn - (or (c-search-forward-char-property 'syntax-table '(15) limit) - (goto-char limit)) - (setq string-delims nil)) - (c-benign-error "Missing '(15) syntax-table property at %d" + (cond + ((cdr string-delims) + (goto-char (cadr string-delims))) + ((equal (c-get-char-property (1- (cadar string-delims)) + 'syntax-table) + '(15)) ; "Always" the case. + ;; The next search should be successful for an unterminated ml + ;; string inside a macro, but not for any other unterminated + ;; string. + (or (c-search-forward-char-property 'syntax-table '(15) limit) + (goto-char limit)) + (setq string-delims nil)) + (t (c-benign-error "Messing '(15) syntax-table property at %d" (1- (cadar string-delims))) (setq string-delims nil)))) @@ -2009,10 +2009,14 @@ casts and declarations are fontified. Used on level 2 and higher." ((and string-delims (cdr string-delims) (>= (point) (cadr string-delims))) - (c-put-font-lock-face (cadr string-delims) (1+ (cadr string-delims)) - 'font-lock-string-face) - (c-remove-font-lock-face (1+ (cadr string-delims)) - (caddr string-delims)) + (unless (featurep 'xemacs) + (c-put-font-lock-face (cadr string-delims) (1+ (cadr string-delims)) + 'font-lock-string-face)) + (c-remove-font-lock-face + (if (featurep 'xemacs) + (cadr string-delims) + (1+ (cadr string-delims))) + (caddr string-delims)) (goto-char (caddr string-delims)) (setq string-delims nil)) @@ -2021,10 +2025,11 @@ casts and declarations are fontified. Used on level 2 and higher." (if (cdr string-delims) (progn (c-remove-font-lock-face (caar string-delims) - (1- (cadar string-delims))) - (c-put-font-lock-face (1- (cadar string-delims)) - (cadar string-delims) - 'font-lock-string-face)) + (cadar string-delims)) + (unless (featurep 'xemacs) + (c-put-font-lock-face (1- (cadar string-delims)) + (cadar string-delims) + 'font-lock-string-face))) (c-put-font-lock-face (caar string-delims) (cadar string-delims) 'font-lock-warning-face)) (goto-char (cadar string-delims))))) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 772b09e1f97..dc9b8b7aed9 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -346,7 +346,7 @@ the comment syntax to handle both line style \"//\" and block style (modify-syntax-entry ?& "." table) (modify-syntax-entry ?| "." table) (modify-syntax-entry ?\' "\"" table) - (modify-syntax-entry ?\240 "." table) + (modify-syntax-entry ?\240 " " table) ;; Set up block and line oriented comments. The new C ;; standard mandates both comment styles even in C, so since diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 126cca5c071..9c89a7db4b7 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -2291,7 +2291,7 @@ with // and /*, not more generic line and block comments." (end1 (or (and (eq (get-text-property end 'face) 'font-lock-comment-face) - (previous-single-property-change end 'face)) + (c-previous-single-property-change end 'face)) end))) (when (>= end1 beg) ; Don't hassle about changes entirely in ; comments. @@ -2311,8 +2311,8 @@ with // and /*, not more generic line and block comments." (setq type-pos (if (get-text-property (1- end1) 'c-type) end1 - (previous-single-property-change end1 'c-type - nil lim)))) + (c-previous-single-property-change end1 'c-type + nil lim)))) (setq type (get-text-property (max (1- type-pos) lim) 'c-type)) (when (memq type '(c-decl-id-start c-decl-type-start)) commit bf418cd836c40795ec4ee19de5c5742d3ca698ea Author: Sean Whitton Date: Wed Jun 11 11:28:24 2025 +0100 vc-next-action: Leave files unregistered if user aborts the checkin * lisp/vc/vc.el (vc-only-files-state-and-model): Don't call vc-register. (vc-checkin): New REGISTER parameter. Call vc-register when it's non-nil. (vc-next-action): Pass new REGISTER parameter to vc-checkin. diff --git a/etc/NEWS b/etc/NEWS index 23b76da8cb2..e762e5ae8e1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1777,10 +1777,10 @@ These correspond to the existing 'z p' to pop a stash and 'P' to pop the stash at point (deleting the stash at point is also bound to 'C-k'). --- -*** VC Directory now offers to register files when checking in mixed filesets. +*** VC Directory can now register files when checking in mixed filesets. Previously, if some files to be checked in were unregistered but others were added, removed or edited, Emacs would refuse to proceed. -Now Emacs prompts to first register the unregistered files, so that all +Now Emacs prompts to register the unregistered files, so that all files in the fileset are in a compatible state for a checkin. +++ diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 356eb2d7370..291d5d02fc8 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -1377,12 +1377,25 @@ BACKEND is the VC backend responsible for FILES." ((cl-subsetp states '(added missing removed edited)) (setq state 'edited)) - ;; Special, but common case: - ;; checking in both changes and new files at once. - ((and (cl-subsetp states '(added missing removed edited unregistered)) - (y-or-n-p "Some files are unregistered; register them first?")) - (vc-register (list backend - (cdr (assq 'unregistered states-alist)))) + ;; Special, but common case: checking in both changes and new + ;; files at once. The actual registration is delayed until + ;; `vc-checkin' so that if the user changes their mind while + ;; entering the log message, we leave things as we found them. + ;; + ;; An alternative would be to delay it until the backend + ;; `vc-*-checkin'. The advantages would be that those + ;; functions could complete the whole operation in fewer total + ;; shell commands, and if the checkin itself fails they could + ;; ensure the file is left unregistered then too (e.g. for Git + ;; we may be able to use 'git add -N', though that would still + ;; require a subsequent 'git reset'). + ;; The disadvantage would be a more complex VC API because we + ;; would have to distinguish between backends which can and + ;; can't handle registration and checkin together. + ((and (cl-subsetp states + '(added missing removed edited unregistered)) + (y-or-n-p "\ +Some files are unregistered; register them before checking in?")) (setq state 'edited)) (t @@ -1470,7 +1483,7 @@ from which to check out the file(s)." (let* ((vc-fileset (vc-deduce-fileset nil t 'state-model-only-files)) (backend (car vc-fileset)) (files (nth 1 vc-fileset)) - ;; (fileset-only-files (nth 2 vc-fileset)) + (fileset-only-files (nth 2 vc-fileset)) ;; FIXME: We used to call `vc-recompute-state' here. (state (nth 3 vc-fileset)) ;; The backend should check that the checkout-model is consistent @@ -1550,6 +1563,9 @@ from which to check out the file(s)." (with-current-buffer visited (read-only-mode -1))))))) ;; Allow user to revert files with no changes + ;; FIXME: This will never do anything because STATE will never + ;; be `up-to-date' in this branch of the cond. + ;; How did the code end up like this? --spwhitton (save-excursion (let (to-revert) (dolist (file files) @@ -1570,17 +1586,22 @@ from which to check out the file(s)." ;; Remaining files need to be committed (if (not ready-for-commit) (message "No files remain to be committed") - (if (not verbose) - (vc-checkin ready-for-commit backend) - (let* ((revision (read-string "New revision or backend: ")) - (revision-downcase (downcase revision))) - (if (member - revision-downcase - (mapcar (lambda (arg) (downcase (symbol-name arg))) - vc-handled-backends)) - (let ((vsym (intern revision-downcase))) - (dolist (file files) (vc-transfer-file file vsym))) - (vc-checkin ready-for-commit backend nil nil revision))))))) + ;; In the case there actually are any unregistered files then + ;; `vc-deduce-backend', via `vc-only-files-state-and-model', + ;; has already prompted the user to approve registering them. + (let ((register (cl-remove-if #'vc-backend fileset-only-files))) + (if (not verbose) + (vc-checkin ready-for-commit backend nil nil nil nil register) + (let* ((revision (read-string "New revision or backend: ")) + (revision-downcase (downcase revision))) + (if (member + revision-downcase + (mapcar (lambda (arg) (downcase (symbol-name arg))) + vc-handled-backends)) + (let ((vsym (intern revision-downcase))) + (dolist (file files) (vc-transfer-file file vsym))) + (vc-checkin ready-for-commit backend + nil nil revision nil register)))))))) ;; locked by somebody else (locking VCSes only) ((stringp state) ;; In the old days, we computed the revision once and used it on @@ -1891,7 +1912,8 @@ Type \\[vc-next-action] to check in changes.") (substitute-command-keys "Please explain why you stole the lock. Type \\`C-c C-c' when done")))) -(defun vc-checkin (files backend &optional comment initial-contents rev patch-string) +(defun vc-checkin + (files backend &optional comment initial-contents rev patch-string register) "Check in FILES. COMMENT is a comment string; if omitted, a buffer is popped up to accept @@ -1901,6 +1923,9 @@ initial contents of the log entry buffer. The optional argument REV may be a string specifying the new revision level (only supported for some older VCSes, like RCS and CVS). The optional argument PATCH-STRING is a string to check in as a patch. +If the optional argument REGISTER is non-nil, it should be a list of +files to register before checking in; if any of these are already +registered the checkin will abort. Runs the normal hooks `vc-before-checkin-hook' and `vc-checkin-hook'." (run-hooks 'vc-before-checkin-hook) @@ -1917,6 +1942,7 @@ Runs the normal hooks `vc-before-checkin-hook' and `vc-checkin-hook'." ;; RCS 5.7 gripes about whitespace-only comments too. (unless (and comment (string-match "[^\t\n ]" comment)) (setq comment "*** empty log message ***")) + (when register (vc-register (list backend files))) (cl-labels ((do-it () ;; We used to change buffers to get local value of ;; `vc-checkin-switches', but the (singular) local