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]) HAVE_TREE_SITTER=no TREE_SITTER_OBJ= +NEED_DYNLIB=no if test "${with_tree_sitter}" != "no"; then 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 LIBS=$OLD_LIBS if test "$ac_cv_func_ts_set_allocator" = yes; then AC_DEFINE(HAVE_TREE_SITTER, 1, [Define if using tree-sitter.]) + NEED_DYNLIB=yes else AC_MSG_ERROR([Tree-sitter library exists but its version is too old]); TREE_SITTER_CFLAGS= @@ -4145,7 +4147,6 @@ AC_SUBST(DYNAMIC_LIB_SECONDARY_SUFFIX) LIBMODULES= HAVE_MODULES=no MODULES_OBJ= -NEED_DYNLIB=no MODULES_SUFFIX="${DYNAMIC_LIB_SUFFIX}" MODULES_SECONDARY_SUFFIX="${DYNAMIC_LIB_SECONDARY_SUFFIX}" 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." (if (zerop (call-process (expand-file-name invocation-name invocation-directory) - nil t t "-no-comp-spawn" "--batch" "-l" + nil t t "-no-comp-spawn" "-Q" "--batch" "-l" temp-file)) (progn (delete-file temp-file) @@ -4005,7 +4005,7 @@ display a message." :command (list (expand-file-name invocation-name invocation-directory) - "-no-comp-spawn" "--batch" + "-no-comp-spawn" "-Q" "--batch" "--eval" ;; Suppress Abort dialogs on MS-Windows "(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." (command (save-excursion (eshell-bol) (skip-syntax-forward " ") - (thing-at-point 'sexp)))) - (if (and (file-remote-p default-directory) + (thing-at-point 'sexp))) + (prefix (file-remote-p default-directory))) + (if (and prefix ;; We can't formally parse the input. But if there is ;; one of these operators behind us, then looking at ;; the first command would not be sensible. So be @@ -93,14 +94,9 @@ insertion." (or eshell-prefer-lisp-functions (not (eshell-search-path command)))))))) (let ((map (make-sparse-keymap)) - (start (if tilde-before (1- (point)) (point))) - (localname - (tramp-file-name-localname - (tramp-dissect-file-name default-directory)))) + (start (if tilde-before (1- (point)) (point)))) (when tilde-before (delete-char -1)) - (insert - (substring default-directory 0 - (string-search localname default-directory))) + (insert prefix) (unless tilde-before (insert "/")) ;; Typing a second slash undoes the insertion, for when ;; 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: (mail-abbrevs-setup)) ((message-mail-alias-type-p 'ecomplete) (ecomplete-setup))) - (add-hook 'completion-at-point-functions #'eudc-capf-complete -1 t) (add-hook 'completion-at-point-functions #'message-completion-function nil t) (unless buffer-file-name (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." :initialize #'custom-initialize-default :set (lambda (sym val) (set-default sym val) - (setq tab-bar--fixed-width-hash nil)) + (setq tab-bar--auto-width-hash nil)) :group 'tab-bar :version "29.1") @@ -1048,17 +1048,17 @@ tab bar might wrap to the second line when it shouldn't.") tab-bar-tab-group-inactive) "Resize tabs only with these faces.") -(defvar tab-bar--fixed-width-hash nil +(defvar tab-bar--auto-width-hash nil "Memoization table for `tab-bar-auto-width'.") (defun tab-bar-auto-width (items) "Return tab-bar items with resized tab names." - (unless tab-bar--fixed-width-hash - (define-hash-table-test 'tab-bar--fixed-width-hash-test + (unless tab-bar--auto-width-hash + (define-hash-table-test 'tab-bar--auto-width-hash-test #'equal-including-properties #'sxhash-equal-including-properties) - (setq tab-bar--fixed-width-hash - (make-hash-table :test 'tab-bar--fixed-width-hash-test))) + (setq tab-bar--auto-width-hash + (make-hash-table :test 'tab-bar--auto-width-hash-test))) (let ((tabs nil) ;; list of resizable tabs (non-tabs "") ;; concatenated names of non-resizable tabs (width 0)) ;; resize tab names to this width @@ -1086,7 +1086,7 @@ tab bar might wrap to the second line when it shouldn't.") (setf (nth 2 item) (with-memoization (gethash (list (selected-frame) width (nth 2 item)) - tab-bar--fixed-width-hash) + tab-bar--auto-width-hash) (let* ((name (nth 2 item)) (len (length name)) (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." t)) +(defun whitespace--clone () + "Hook function run after `make-indirect-buffer' and `clone-buffer'." + (when (whitespace-style-face-p) + (setq-local whitespace-bob-marker + (copy-marker (marker-position whitespace-bob-marker) + (marker-insertion-type whitespace-bob-marker))) + (setq-local whitespace-eob-marker + (copy-marker (marker-position whitespace-eob-marker) + (marker-insertion-type whitespace-eob-marker))))) + + (defun whitespace-color-on () "Turn on color visualization." (when (whitespace-style-face-p) @@ -2111,6 +2122,8 @@ resultant list will be returned." ;; The -1 ensures that it runs before any ;; `font-lock-mode' hook functions. -1 t) + (add-hook 'clone-buffer-hook #'whitespace--clone nil t) + (add-hook 'clone-indirect-buffer-hook #'whitespace--clone nil t) ;; Add whitespace-mode color into font lock. (setq whitespace-font-lock-keywords @@ -2204,6 +2217,8 @@ resultant list will be returned." (remove-hook 'before-change-functions #'whitespace-buffer-changed t) (remove-hook 'after-change-functions #'whitespace--update-bob-eob t) + (remove-hook 'clone-buffer-hook #'whitespace--clone t) + (remove-hook 'clone-indirect-buffer-hook #'whitespace--clone t) (font-lock-remove-keywords nil whitespace-font-lock-keywords) (font-lock-flush))) 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, { /* Transfer data and metadata to disk, retrying if interrupted. fsync can report a write failure here, e.g., due to disk full - under NFS. But ignore EINVAL, which means fsync is not - supported on this file. */ + under NFS. But ignore EINVAL (and EBADF on Windows), which + means fsync is not supported on this file. */ while (fsync (desc) != 0) if (errno != EINTR) { - if (errno != EINVAL) + if (errno != EINVAL +#ifdef WINDOWSNT + && errno != EBADF +#endif + ) ok = 0, save_errno = errno; break; } 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." '(whitespace-mode 1)) ,@body))) +(defmacro whitespace--with-buffer-selected (buffer-or-name &rest body) + (declare (debug (form body)) (indent 1)) + `(save-window-excursion + (with-current-buffer (or ,buffer-or-name (current-buffer)) + (with-selected-window (display-buffer (current-buffer)) + ,@body)))) + (defun whitespace-tests--faceup (&rest lines) "Convenience wrapper around `faceup-test-font-lock-buffer'. Returns non-nil if the concatenated LINES match the current @@ -337,6 +344,74 @@ buffer's content." (whitespace-mode 1) (should (not (buffer-modified-p)))))) +(ert-deftest whitespace-tests--indirect-clone-breaks-base-markers () + "Specific regression test for Bug#59618." + (whitespace-tests--with-test-buffer '(face empty) + (insert "\nx\n\n") + (let ((base (current-buffer)) + ;; `unwind-protect' is not used to clean up `indirect' + ;; because the buffer should only be killed on success. + (indirect (clone-indirect-buffer (buffer-name) nil))) + (should (eq (marker-buffer whitespace-bob-marker) base)) + (should (eq (marker-buffer whitespace-eob-marker) base)) + (whitespace--with-buffer-selected indirect + ;; Mutate the indirect buffer to update its bob/eob markers. + (execute-kbd-macro (kbd "z RET M-< a"))) + ;; With Bug#59618, the above mutation would cause the base + ;; buffer's markers to point inside the indirect buffer because + ;; the indirect buffer erroneously shared marker objects with + ;; the base buffer. Killing the indirect buffer would then + ;; invalidate those markers (make them point nowhere). + (kill-buffer indirect) + (should (eq (marker-buffer whitespace-bob-marker) base)) + (should (eq (marker-buffer whitespace-eob-marker) base))))) + +(defun whitespace-tests--check-markers (buf bpos epos) + (with-current-buffer buf + (should (eq (marker-buffer whitespace-bob-marker) buf)) + (should (eq (marker-position whitespace-bob-marker) bpos)) + (should (eq (marker-buffer whitespace-eob-marker) buf)) + (should (eq (marker-position whitespace-eob-marker) epos)))) + +(ert-deftest whitespace-tests--indirect-clone-markers () + "Test `whitespace--clone' on indirect clones." + (whitespace-tests--with-test-buffer '(face empty) + (insert "\nx\n\n") + (let ((base (current-buffer)) + ;; `unwind-protect' is not used to clean up `indirect' + ;; because the buffer should only be killed on success. + (indirect (clone-indirect-buffer nil nil))) + (whitespace-tests--check-markers base 2 4) + (whitespace--with-buffer-selected indirect + (whitespace-tests--check-markers indirect 2 4) + ;; Mutate the buffer to trigger `after-change-functions' and + ;; thus `whitespace--update-bob-eob'. + (execute-kbd-macro (kbd "z RET M-< a")) + (whitespace-tests--check-markers indirect 1 8)) + (kill-buffer indirect) + ;; When the buffer was modified above, the new "a" character at + ;; the beginning moved the base buffer's markers by one. Emacs + ;; did not run the base buffer's `after-change-functions' after + ;; the indirect buffer was edited (Bug#46982), so the end result + ;; is just the shift by one. + (whitespace-tests--check-markers base 3 5)))) + +(ert-deftest whitespace-tests--regular-clone-markers () + "Test `whitespace--clone' on regular clones." + (whitespace-tests--with-test-buffer '(face empty) + (insert "\nx\n\n") + (let ((orig (current-buffer)) + ;; `unwind-protect' is not used to clean up `clone' because + ;; the buffer should only be killed on success. + (clone (clone-buffer))) + (whitespace-tests--check-markers orig 2 4) + (whitespace--with-buffer-selected clone + (whitespace-tests--check-markers clone 2 4) + (execute-kbd-macro (kbd "z RET M-< a")) + (whitespace-tests--check-markers clone 1 8)) + (kill-buffer clone) + (whitespace-tests--check-markers orig 2 4)))) + (provide 'whitespace-tests) ;;; whitespace-tests.el ends here