diff options
| author | Stefan Kangas | 2022-12-22 06:30:09 +0100 |
|---|---|---|
| committer | Stefan Kangas | 2022-12-22 06:30:09 +0100 |
| commit | 08bb91c7df4ebf0dd9de4d55575aaaed87a9b339 (patch) | |
| tree | 245f7772c6466026384bed6c7f95af1b78235bb3 | |
| parent | ad5a67996ddf23df904c09165475759e2e0a68b1 (diff) | |
| parent | e59216d3be86918b995bd63273c851ebc6176a83 (diff) | |
| download | emacs-08bb91c7df4ebf0dd9de4d55575aaaed87a9b339.tar.gz emacs-08bb91c7df4ebf0dd9de4d55575aaaed87a9b339.zip | |
Merge from origin/emacs-29
e59216d3be8 * Invoke spawed Emacs processes with '-Q' when native com...
777b383dd0f Fix Eshell electric slash when used from the root directo...
c088cdad9e9 Fix the --without-all build with tree-sitter
ec9fbad908d Fix write-region to null device on MS-Windows
f35da111990 message: Do not default to eudc-capf-complete yet
98c16a8c883 ; * lisp/tab-bar.el: Remaining renaming of "fixed-width" ...
d76d7a3bebf whitespace: Avoid mutating original buffer's markers in c...
| -rw-r--r-- | configure.ac | 3 | ||||
| -rw-r--r-- | lisp/emacs-lisp/comp.el | 4 | ||||
| -rw-r--r-- | lisp/eshell/em-elecslash.el | 14 | ||||
| -rw-r--r-- | lisp/gnus/message.el | 1 | ||||
| -rw-r--r-- | lisp/tab-bar.el | 14 | ||||
| -rw-r--r-- | lisp/whitespace.el | 15 | ||||
| -rw-r--r-- | src/fileio.c | 10 | ||||
| -rw-r--r-- | test/lisp/whitespace-tests.el | 75 |
8 files changed, 113 insertions, 23 deletions
diff --git a/configure.ac b/configure.ac index 5bd6645a256..6e9b11986c7 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -3222,6 +3222,7 @@ AC_SUBST([JSON_OBJ]) | |||
| 3222 | 3222 | ||
| 3223 | HAVE_TREE_SITTER=no | 3223 | HAVE_TREE_SITTER=no |
| 3224 | TREE_SITTER_OBJ= | 3224 | TREE_SITTER_OBJ= |
| 3225 | NEED_DYNLIB=no | ||
| 3225 | 3226 | ||
| 3226 | if test "${with_tree_sitter}" != "no"; then | 3227 | if test "${with_tree_sitter}" != "no"; then |
| 3227 | dnl Tree-sitter 0.20.2 added support to change the malloc it uses | 3228 | dnl Tree-sitter 0.20.2 added support to change the malloc it uses |
| @@ -3247,6 +3248,7 @@ if test "${with_tree_sitter}" != "no"; then | |||
| 3247 | LIBS=$OLD_LIBS | 3248 | LIBS=$OLD_LIBS |
| 3248 | if test "$ac_cv_func_ts_set_allocator" = yes; then | 3249 | if test "$ac_cv_func_ts_set_allocator" = yes; then |
| 3249 | AC_DEFINE(HAVE_TREE_SITTER, 1, [Define if using tree-sitter.]) | 3250 | AC_DEFINE(HAVE_TREE_SITTER, 1, [Define if using tree-sitter.]) |
| 3251 | NEED_DYNLIB=yes | ||
| 3250 | else | 3252 | else |
| 3251 | AC_MSG_ERROR([Tree-sitter library exists but its version is too old]); | 3253 | AC_MSG_ERROR([Tree-sitter library exists but its version is too old]); |
| 3252 | TREE_SITTER_CFLAGS= | 3254 | TREE_SITTER_CFLAGS= |
| @@ -4145,7 +4147,6 @@ AC_SUBST(DYNAMIC_LIB_SECONDARY_SUFFIX) | |||
| 4145 | LIBMODULES= | 4147 | LIBMODULES= |
| 4146 | HAVE_MODULES=no | 4148 | HAVE_MODULES=no |
| 4147 | MODULES_OBJ= | 4149 | MODULES_OBJ= |
| 4148 | NEED_DYNLIB=no | ||
| 4149 | MODULES_SUFFIX="${DYNAMIC_LIB_SUFFIX}" | 4150 | MODULES_SUFFIX="${DYNAMIC_LIB_SUFFIX}" |
| 4150 | MODULES_SECONDARY_SUFFIX="${DYNAMIC_LIB_SECONDARY_SUFFIX}" | 4151 | MODULES_SECONDARY_SUFFIX="${DYNAMIC_LIB_SECONDARY_SUFFIX}" |
| 4151 | 4152 | ||
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index 2c306d892c7..7fec370d474 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el | |||
| @@ -3716,7 +3716,7 @@ Prepare every function for final compilation and drive the C back-end." | |||
| 3716 | (if (zerop | 3716 | (if (zerop |
| 3717 | (call-process (expand-file-name invocation-name | 3717 | (call-process (expand-file-name invocation-name |
| 3718 | invocation-directory) | 3718 | invocation-directory) |
| 3719 | nil t t "-no-comp-spawn" "--batch" "-l" | 3719 | nil t t "-no-comp-spawn" "-Q" "--batch" "-l" |
| 3720 | temp-file)) | 3720 | temp-file)) |
| 3721 | (progn | 3721 | (progn |
| 3722 | (delete-file temp-file) | 3722 | (delete-file temp-file) |
| @@ -4005,7 +4005,7 @@ display a message." | |||
| 4005 | :command (list | 4005 | :command (list |
| 4006 | (expand-file-name invocation-name | 4006 | (expand-file-name invocation-name |
| 4007 | invocation-directory) | 4007 | invocation-directory) |
| 4008 | "-no-comp-spawn" "--batch" | 4008 | "-no-comp-spawn" "-Q" "--batch" |
| 4009 | "--eval" | 4009 | "--eval" |
| 4010 | ;; Suppress Abort dialogs on MS-Windows | 4010 | ;; Suppress Abort dialogs on MS-Windows |
| 4011 | "(setq w32-disable-abort-dialog t)" | 4011 | "(setq w32-disable-abort-dialog t)" |
diff --git a/lisp/eshell/em-elecslash.el b/lisp/eshell/em-elecslash.el index 091acb9a861..0ce3a4cc963 100644 --- a/lisp/eshell/em-elecslash.el +++ b/lisp/eshell/em-elecslash.el | |||
| @@ -74,8 +74,9 @@ insertion." | |||
| 74 | (command (save-excursion | 74 | (command (save-excursion |
| 75 | (eshell-bol) | 75 | (eshell-bol) |
| 76 | (skip-syntax-forward " ") | 76 | (skip-syntax-forward " ") |
| 77 | (thing-at-point 'sexp)))) | 77 | (thing-at-point 'sexp))) |
| 78 | (if (and (file-remote-p default-directory) | 78 | (prefix (file-remote-p default-directory))) |
| 79 | (if (and prefix | ||
| 79 | ;; We can't formally parse the input. But if there is | 80 | ;; We can't formally parse the input. But if there is |
| 80 | ;; one of these operators behind us, then looking at | 81 | ;; one of these operators behind us, then looking at |
| 81 | ;; the first command would not be sensible. So be | 82 | ;; the first command would not be sensible. So be |
| @@ -93,14 +94,9 @@ insertion." | |||
| 93 | (or eshell-prefer-lisp-functions | 94 | (or eshell-prefer-lisp-functions |
| 94 | (not (eshell-search-path command)))))))) | 95 | (not (eshell-search-path command)))))))) |
| 95 | (let ((map (make-sparse-keymap)) | 96 | (let ((map (make-sparse-keymap)) |
| 96 | (start (if tilde-before (1- (point)) (point))) | 97 | (start (if tilde-before (1- (point)) (point)))) |
| 97 | (localname | ||
| 98 | (tramp-file-name-localname | ||
| 99 | (tramp-dissect-file-name default-directory)))) | ||
| 100 | (when tilde-before (delete-char -1)) | 98 | (when tilde-before (delete-char -1)) |
| 101 | (insert | 99 | (insert prefix) |
| 102 | (substring default-directory 0 | ||
| 103 | (string-search localname default-directory))) | ||
| 104 | (unless tilde-before (insert "/")) | 100 | (unless tilde-before (insert "/")) |
| 105 | ;; Typing a second slash undoes the insertion, for when | 101 | ;; Typing a second slash undoes the insertion, for when |
| 106 | ;; you really do want to type a local absolute file name. | 102 | ;; you really do want to type a local absolute file name. |
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index e7d11b597b3..6c10a4ae976 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el | |||
| @@ -3191,7 +3191,6 @@ Like `text-mode', but with these additional commands: | |||
| 3191 | (mail-abbrevs-setup)) | 3191 | (mail-abbrevs-setup)) |
| 3192 | ((message-mail-alias-type-p 'ecomplete) | 3192 | ((message-mail-alias-type-p 'ecomplete) |
| 3193 | (ecomplete-setup))) | 3193 | (ecomplete-setup))) |
| 3194 | (add-hook 'completion-at-point-functions #'eudc-capf-complete -1 t) | ||
| 3195 | (add-hook 'completion-at-point-functions #'message-completion-function nil t) | 3194 | (add-hook 'completion-at-point-functions #'message-completion-function nil t) |
| 3196 | (unless buffer-file-name | 3195 | (unless buffer-file-name |
| 3197 | (message-set-auto-save-file-name)) | 3196 | (message-set-auto-save-file-name)) |
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 065116d5129..69283cce145 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el | |||
| @@ -1029,7 +1029,7 @@ This variable has effect only when `tab-bar-auto-width' is non-nil." | |||
| 1029 | :initialize #'custom-initialize-default | 1029 | :initialize #'custom-initialize-default |
| 1030 | :set (lambda (sym val) | 1030 | :set (lambda (sym val) |
| 1031 | (set-default sym val) | 1031 | (set-default sym val) |
| 1032 | (setq tab-bar--fixed-width-hash nil)) | 1032 | (setq tab-bar--auto-width-hash nil)) |
| 1033 | :group 'tab-bar | 1033 | :group 'tab-bar |
| 1034 | :version "29.1") | 1034 | :version "29.1") |
| 1035 | 1035 | ||
| @@ -1048,17 +1048,17 @@ tab bar might wrap to the second line when it shouldn't.") | |||
| 1048 | tab-bar-tab-group-inactive) | 1048 | tab-bar-tab-group-inactive) |
| 1049 | "Resize tabs only with these faces.") | 1049 | "Resize tabs only with these faces.") |
| 1050 | 1050 | ||
| 1051 | (defvar tab-bar--fixed-width-hash nil | 1051 | (defvar tab-bar--auto-width-hash nil |
| 1052 | "Memoization table for `tab-bar-auto-width'.") | 1052 | "Memoization table for `tab-bar-auto-width'.") |
| 1053 | 1053 | ||
| 1054 | (defun tab-bar-auto-width (items) | 1054 | (defun tab-bar-auto-width (items) |
| 1055 | "Return tab-bar items with resized tab names." | 1055 | "Return tab-bar items with resized tab names." |
| 1056 | (unless tab-bar--fixed-width-hash | 1056 | (unless tab-bar--auto-width-hash |
| 1057 | (define-hash-table-test 'tab-bar--fixed-width-hash-test | 1057 | (define-hash-table-test 'tab-bar--auto-width-hash-test |
| 1058 | #'equal-including-properties | 1058 | #'equal-including-properties |
| 1059 | #'sxhash-equal-including-properties) | 1059 | #'sxhash-equal-including-properties) |
| 1060 | (setq tab-bar--fixed-width-hash | 1060 | (setq tab-bar--auto-width-hash |
| 1061 | (make-hash-table :test 'tab-bar--fixed-width-hash-test))) | 1061 | (make-hash-table :test 'tab-bar--auto-width-hash-test))) |
| 1062 | (let ((tabs nil) ;; list of resizable tabs | 1062 | (let ((tabs nil) ;; list of resizable tabs |
| 1063 | (non-tabs "") ;; concatenated names of non-resizable tabs | 1063 | (non-tabs "") ;; concatenated names of non-resizable tabs |
| 1064 | (width 0)) ;; resize tab names to this width | 1064 | (width 0)) ;; resize tab names to this width |
| @@ -1086,7 +1086,7 @@ tab bar might wrap to the second line when it shouldn't.") | |||
| 1086 | (setf (nth 2 item) | 1086 | (setf (nth 2 item) |
| 1087 | (with-memoization (gethash (list (selected-frame) | 1087 | (with-memoization (gethash (list (selected-frame) |
| 1088 | width (nth 2 item)) | 1088 | width (nth 2 item)) |
| 1089 | tab-bar--fixed-width-hash) | 1089 | tab-bar--auto-width-hash) |
| 1090 | (let* ((name (nth 2 item)) | 1090 | (let* ((name (nth 2 item)) |
| 1091 | (len (length name)) | 1091 | (len (length name)) |
| 1092 | (close-p (get-text-property (1- len) 'close-tab name)) | 1092 | (close-p (get-text-property (1- len) 'close-tab name)) |
diff --git a/lisp/whitespace.el b/lisp/whitespace.el index 9bc6ad9db46..558be1841ab 100644 --- a/lisp/whitespace.el +++ b/lisp/whitespace.el | |||
| @@ -2093,6 +2093,17 @@ resultant list will be returned." | |||
| 2093 | t)) | 2093 | t)) |
| 2094 | 2094 | ||
| 2095 | 2095 | ||
| 2096 | (defun whitespace--clone () | ||
| 2097 | "Hook function run after `make-indirect-buffer' and `clone-buffer'." | ||
| 2098 | (when (whitespace-style-face-p) | ||
| 2099 | (setq-local whitespace-bob-marker | ||
| 2100 | (copy-marker (marker-position whitespace-bob-marker) | ||
| 2101 | (marker-insertion-type whitespace-bob-marker))) | ||
| 2102 | (setq-local whitespace-eob-marker | ||
| 2103 | (copy-marker (marker-position whitespace-eob-marker) | ||
| 2104 | (marker-insertion-type whitespace-eob-marker))))) | ||
| 2105 | |||
| 2106 | |||
| 2096 | (defun whitespace-color-on () | 2107 | (defun whitespace-color-on () |
| 2097 | "Turn on color visualization." | 2108 | "Turn on color visualization." |
| 2098 | (when (whitespace-style-face-p) | 2109 | (when (whitespace-style-face-p) |
| @@ -2111,6 +2122,8 @@ resultant list will be returned." | |||
| 2111 | ;; The -1 ensures that it runs before any | 2122 | ;; The -1 ensures that it runs before any |
| 2112 | ;; `font-lock-mode' hook functions. | 2123 | ;; `font-lock-mode' hook functions. |
| 2113 | -1 t) | 2124 | -1 t) |
| 2125 | (add-hook 'clone-buffer-hook #'whitespace--clone nil t) | ||
| 2126 | (add-hook 'clone-indirect-buffer-hook #'whitespace--clone nil t) | ||
| 2114 | ;; Add whitespace-mode color into font lock. | 2127 | ;; Add whitespace-mode color into font lock. |
| 2115 | (setq | 2128 | (setq |
| 2116 | whitespace-font-lock-keywords | 2129 | whitespace-font-lock-keywords |
| @@ -2204,6 +2217,8 @@ resultant list will be returned." | |||
| 2204 | (remove-hook 'before-change-functions #'whitespace-buffer-changed t) | 2217 | (remove-hook 'before-change-functions #'whitespace-buffer-changed t) |
| 2205 | (remove-hook 'after-change-functions #'whitespace--update-bob-eob | 2218 | (remove-hook 'after-change-functions #'whitespace--update-bob-eob |
| 2206 | t) | 2219 | t) |
| 2220 | (remove-hook 'clone-buffer-hook #'whitespace--clone t) | ||
| 2221 | (remove-hook 'clone-indirect-buffer-hook #'whitespace--clone t) | ||
| 2207 | (font-lock-remove-keywords nil whitespace-font-lock-keywords) | 2222 | (font-lock-remove-keywords nil whitespace-font-lock-keywords) |
| 2208 | (font-lock-flush))) | 2223 | (font-lock-flush))) |
| 2209 | 2224 | ||
diff --git a/src/fileio.c b/src/fileio.c index e7c2af81421..66ce6b30887 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -5376,12 +5376,16 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename, | |||
| 5376 | { | 5376 | { |
| 5377 | /* Transfer data and metadata to disk, retrying if interrupted. | 5377 | /* Transfer data and metadata to disk, retrying if interrupted. |
| 5378 | fsync can report a write failure here, e.g., due to disk full | 5378 | fsync can report a write failure here, e.g., due to disk full |
| 5379 | under NFS. But ignore EINVAL, which means fsync is not | 5379 | under NFS. But ignore EINVAL (and EBADF on Windows), which |
| 5380 | supported on this file. */ | 5380 | means fsync is not supported on this file. */ |
| 5381 | while (fsync (desc) != 0) | 5381 | while (fsync (desc) != 0) |
| 5382 | if (errno != EINTR) | 5382 | if (errno != EINTR) |
| 5383 | { | 5383 | { |
| 5384 | if (errno != EINVAL) | 5384 | if (errno != EINVAL |
| 5385 | #ifdef WINDOWSNT | ||
| 5386 | && errno != EBADF | ||
| 5387 | #endif | ||
| 5388 | ) | ||
| 5385 | ok = 0, save_errno = errno; | 5389 | ok = 0, save_errno = errno; |
| 5386 | break; | 5390 | break; |
| 5387 | } | 5391 | } |
diff --git a/test/lisp/whitespace-tests.el b/test/lisp/whitespace-tests.el index 3e94d7e921b..12f6cb99a23 100644 --- a/test/lisp/whitespace-tests.el +++ b/test/lisp/whitespace-tests.el | |||
| @@ -42,6 +42,13 @@ nil, `whitespace-mode' is left disabled." | |||
| 42 | '(whitespace-mode 1)) | 42 | '(whitespace-mode 1)) |
| 43 | ,@body))) | 43 | ,@body))) |
| 44 | 44 | ||
| 45 | (defmacro whitespace--with-buffer-selected (buffer-or-name &rest body) | ||
| 46 | (declare (debug (form body)) (indent 1)) | ||
| 47 | `(save-window-excursion | ||
| 48 | (with-current-buffer (or ,buffer-or-name (current-buffer)) | ||
| 49 | (with-selected-window (display-buffer (current-buffer)) | ||
| 50 | ,@body)))) | ||
| 51 | |||
| 45 | (defun whitespace-tests--faceup (&rest lines) | 52 | (defun whitespace-tests--faceup (&rest lines) |
| 46 | "Convenience wrapper around `faceup-test-font-lock-buffer'. | 53 | "Convenience wrapper around `faceup-test-font-lock-buffer'. |
| 47 | Returns non-nil if the concatenated LINES match the current | 54 | Returns non-nil if the concatenated LINES match the current |
| @@ -337,6 +344,74 @@ buffer's content." | |||
| 337 | (whitespace-mode 1) | 344 | (whitespace-mode 1) |
| 338 | (should (not (buffer-modified-p)))))) | 345 | (should (not (buffer-modified-p)))))) |
| 339 | 346 | ||
| 347 | (ert-deftest whitespace-tests--indirect-clone-breaks-base-markers () | ||
| 348 | "Specific regression test for Bug#59618." | ||
| 349 | (whitespace-tests--with-test-buffer '(face empty) | ||
| 350 | (insert "\nx\n\n") | ||
| 351 | (let ((base (current-buffer)) | ||
| 352 | ;; `unwind-protect' is not used to clean up `indirect' | ||
| 353 | ;; because the buffer should only be killed on success. | ||
| 354 | (indirect (clone-indirect-buffer (buffer-name) nil))) | ||
| 355 | (should (eq (marker-buffer whitespace-bob-marker) base)) | ||
| 356 | (should (eq (marker-buffer whitespace-eob-marker) base)) | ||
| 357 | (whitespace--with-buffer-selected indirect | ||
| 358 | ;; Mutate the indirect buffer to update its bob/eob markers. | ||
| 359 | (execute-kbd-macro (kbd "z RET M-< a"))) | ||
| 360 | ;; With Bug#59618, the above mutation would cause the base | ||
| 361 | ;; buffer's markers to point inside the indirect buffer because | ||
| 362 | ;; the indirect buffer erroneously shared marker objects with | ||
| 363 | ;; the base buffer. Killing the indirect buffer would then | ||
| 364 | ;; invalidate those markers (make them point nowhere). | ||
| 365 | (kill-buffer indirect) | ||
| 366 | (should (eq (marker-buffer whitespace-bob-marker) base)) | ||
| 367 | (should (eq (marker-buffer whitespace-eob-marker) base))))) | ||
| 368 | |||
| 369 | (defun whitespace-tests--check-markers (buf bpos epos) | ||
| 370 | (with-current-buffer buf | ||
| 371 | (should (eq (marker-buffer whitespace-bob-marker) buf)) | ||
| 372 | (should (eq (marker-position whitespace-bob-marker) bpos)) | ||
| 373 | (should (eq (marker-buffer whitespace-eob-marker) buf)) | ||
| 374 | (should (eq (marker-position whitespace-eob-marker) epos)))) | ||
| 375 | |||
| 376 | (ert-deftest whitespace-tests--indirect-clone-markers () | ||
| 377 | "Test `whitespace--clone' on indirect clones." | ||
| 378 | (whitespace-tests--with-test-buffer '(face empty) | ||
| 379 | (insert "\nx\n\n") | ||
| 380 | (let ((base (current-buffer)) | ||
| 381 | ;; `unwind-protect' is not used to clean up `indirect' | ||
| 382 | ;; because the buffer should only be killed on success. | ||
| 383 | (indirect (clone-indirect-buffer nil nil))) | ||
| 384 | (whitespace-tests--check-markers base 2 4) | ||
| 385 | (whitespace--with-buffer-selected indirect | ||
| 386 | (whitespace-tests--check-markers indirect 2 4) | ||
| 387 | ;; Mutate the buffer to trigger `after-change-functions' and | ||
| 388 | ;; thus `whitespace--update-bob-eob'. | ||
| 389 | (execute-kbd-macro (kbd "z RET M-< a")) | ||
| 390 | (whitespace-tests--check-markers indirect 1 8)) | ||
| 391 | (kill-buffer indirect) | ||
| 392 | ;; When the buffer was modified above, the new "a" character at | ||
| 393 | ;; the beginning moved the base buffer's markers by one. Emacs | ||
| 394 | ;; did not run the base buffer's `after-change-functions' after | ||
| 395 | ;; the indirect buffer was edited (Bug#46982), so the end result | ||
| 396 | ;; is just the shift by one. | ||
| 397 | (whitespace-tests--check-markers base 3 5)))) | ||
| 398 | |||
| 399 | (ert-deftest whitespace-tests--regular-clone-markers () | ||
| 400 | "Test `whitespace--clone' on regular clones." | ||
| 401 | (whitespace-tests--with-test-buffer '(face empty) | ||
| 402 | (insert "\nx\n\n") | ||
| 403 | (let ((orig (current-buffer)) | ||
| 404 | ;; `unwind-protect' is not used to clean up `clone' because | ||
| 405 | ;; the buffer should only be killed on success. | ||
| 406 | (clone (clone-buffer))) | ||
| 407 | (whitespace-tests--check-markers orig 2 4) | ||
| 408 | (whitespace--with-buffer-selected clone | ||
| 409 | (whitespace-tests--check-markers clone 2 4) | ||
| 410 | (execute-kbd-macro (kbd "z RET M-< a")) | ||
| 411 | (whitespace-tests--check-markers clone 1 8)) | ||
| 412 | (kill-buffer clone) | ||
| 413 | (whitespace-tests--check-markers orig 2 4)))) | ||
| 414 | |||
| 340 | (provide 'whitespace-tests) | 415 | (provide 'whitespace-tests) |
| 341 | 416 | ||
| 342 | ;;; whitespace-tests.el ends here | 417 | ;;; whitespace-tests.el ends here |