commit 6cab30620f2234a1759074202caf2beafed12b69 (HEAD, refs/remotes/origin/master) Merge: cbd04ad3d5 85e47d9a9e Author: Stefan Kangas Date: Fri Oct 14 06:31:49 2022 +0200 Merge from origin/emacs-28 85e47d9a9e ; Continued cleanup of "-hooks" commit cbd04ad3d572850775f18bde868c71abcde733ed Author: Michael Albinus Date: Thu Oct 13 21:13:45 2022 +0200 Clarify structure of file-attribute's device number * doc/lispref/buffers.texi (Buffer File Name): Fix description of buffer-file-number. * doc/lispref/files.texi (File Attributes): Clarify type of device number. Describe file-attribute-file-number. (Bug#58446) * etc/NEWS: Mention file-attribute-file-number. * lisp/files.el (buffer-file-number, file-attribute-device-number) (file-attribute-collect): Fix docstring. (file-attribute-file-number): New defsubst. (find-buffer-visiting, find-file-noselect) (set-visited-file-name, basic-save-buffer): * lisp/startup.el (normal-top-level-add-subdirs-to-load-path): * lisp/eshell/em-unix.el (eshell-shuffle-files): Use it. * src/dired.c (Ffile_attributes): Fix docstring. diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index 6a1d125701..b46b6c52d8 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi @@ -427,12 +427,12 @@ It is a permanent local, unaffected by @end defvar @defvar buffer-file-number -This buffer-local variable holds the file number and directory device +This buffer-local variable holds the inode number and directory device number of the file visited in the current buffer, or @code{nil} if no file or a nonexistent file is visited. It is a permanent local, unaffected by @code{kill-all-local-variables}. -The value is normally a list of the form @code{(@var{filenum} +The value is normally a list of the form @code{(@var{inodenum} @var{devnum})}. This pair of numbers uniquely identifies the file among all files accessible on the system. See the function @code{file-attributes}, in @ref{File Attributes}, for more information diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 0e8efa3297..b9d4e87dc7 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -1405,13 +1405,16 @@ a nonnegative integer. @item The filesystem number of the device that the file is on -@code{file-attribute-device-number}), an integer. -This element and the file's inode number -together give enough information to distinguish any two files on the -system---no two files can have the same values for both of these -numbers. +(@code{file-attribute-device-number}), an integer or a cons cell of +integers. The latter is sometimes used by remote files, in order to +distinguish the remote filesystems from the local ones. @end enumerate +The file's inode and device numbers together give enough information +to distinguish any two files on the system---no two files can have the +same values for both of these numbers. This tupel is returned by +@code{file-attribute-file-number}. + For example, here are the file attributes for @file{files.texi}: @example diff --git a/etc/NEWS b/etc/NEWS index ca857056fd..7808c3beb2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1872,7 +1872,7 @@ If non-nil, multiple revisions can be queried. This is done using 'completing-read-multiple'. --- -*** New function 'vc-read-multiple-revisions' +*** New function 'vc-read-multiple-revisions'. This function invokes 'vc-read-revision' with a non-nil value for MULTIPLE. @@ -1880,7 +1880,7 @@ MULTIPLE. *** New command 'vc-prepare-patch'. Patches for any version control system can be prepared using VC. The command will query what commits to send and will compose messages for -your mail user agent. The behaviour of 'vc-prepare-patch' can be +your mail user agent. The behavior of 'vc-prepare-patch' can be modified by the user options 'vc-prepare-patches-separately' and 'vc-default-patch-addressee'. @@ -3147,6 +3147,11 @@ The following generalized variables have been made obsolete: * Lisp Changes in Emacs 29.1 ++++ +** New accessor function 'file-attribute-file-number'. +It returns the list of the inode and device numbers retrieved by +'file-attributes'. This value can be used to identify a file uniquely. + +++ ** New macro 'while-let'. This is like 'when-let', but repeats until a binding form is nil. diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el index 40b83010f9..378b0ceeea 100644 --- a/lisp/eshell/em-unix.el +++ b/lisp/eshell/em-unix.el @@ -372,12 +372,10 @@ Remove the DIRECTORY(ies), if they are empty.") (setq attr (eshell-file-attributes (car files))) (file-attribute-inode-number attr-target) (file-attribute-inode-number attr) - (equal (file-attribute-inode-number attr-target) - (file-attribute-inode-number attr)) (file-attribute-device-number attr-target) (file-attribute-device-number attr) - (equal (file-attribute-device-number attr-target) - (file-attribute-device-number attr))) + (equal (file-attribute-file-number attr-target) + (file-attribute-file-number attr))) (eshell-error (format-message "%s: `%s' and `%s' are the same file\n" command (car files) target))) (t diff --git a/lisp/files.el b/lisp/files.el index 94d110f0b7..1a30148551 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -208,8 +208,8 @@ if the file has changed on disk and you have not edited the buffer." :group 'find-file) (defvar-local buffer-file-number nil - "The device number and file number of the file visited in the current buffer. -The value is a list of the form (FILENUM DEVNUM). + "The inode and device numbers of the file visited in the current buffer. +The value is a list of the form (INODENUM DEVNUM). This pair of numbers uniquely identifies the file. If the buffer is visiting a new file, the value is nil.") (put 'buffer-file-number 'permanent-local t) @@ -2163,7 +2163,7 @@ If there is no such live buffer, return nil." (setq list (cdr list))) found) (let* ((attributes (file-attributes truename)) - (number (nthcdr 10 attributes)) + (number (file-attribute-file-number attributes)) (list (buffer-list)) found) (and buffer-file-numbers-unique (car-safe number) ;Make sure the inode is not just nil. @@ -2366,7 +2366,7 @@ the various files." (let* ((buf (get-file-buffer filename)) (truename (abbreviate-file-name (file-truename filename))) (attributes (file-attributes truename)) - (number (nthcdr 10 attributes)) + (number (file-attribute-file-number attributes)) ;; Find any buffer for a file that has same truename. (other (and (not buf) (find-buffer-visiting @@ -4744,7 +4744,7 @@ the old visited file has been renamed to the new name FILENAME." (setq buffer-file-name truename)))) (setq buffer-file-number (if filename - (nthcdr 10 (file-attributes buffer-file-name)) + (file-attribute-file-number (file-attributes buffer-file-name)) nil)) ;; write-file-functions is normally used for things like ftp-find-file ;; that visit things that are not local files as if they were files. @@ -5733,7 +5733,7 @@ Before and after saving the buffer, this function runs (setq save-buffer-coding-system last-coding-system-used) (setq buffer-file-coding-system last-coding-system-used)) (setq buffer-file-number - (nthcdr 10 (file-attributes buffer-file-name))) + (file-attribute-file-number (file-attributes buffer-file-name))) (if setmodes (condition-case () (progn @@ -8658,19 +8658,25 @@ It is a nonnegative integer." (defsubst file-attribute-device-number (attributes) "The file system device number in ATTRIBUTES returned by `file-attributes'. -It is an integer." +It is an integer or a cons cell of integers." (nth 11 attributes)) +(defsubst file-attribute-file-number (attributes) + "The inode and device numbers in ATTRIBUTES returned by `file-attributes'. +The value is a list of the form (INODENUM DEVNUM). +This pair of numbers uniquely identifies the file." + (nthcdr 10 attributes)) + (defun file-attribute-collect (attributes &rest attr-names) "Return a sublist of ATTRIBUTES returned by `file-attributes'. ATTR-NAMES are symbols with the selected attribute names. Valid attribute names are: type, link-number, user-id, group-id, access-time, modification-time, status-change-time, size, modes, -inode-number and device-number." +inode-number, device-number and file-number." (let ((all '(type link-number user-id group-id access-time modification-time status-change-time - size modes inode-number device-number)) + size modes inode-number device-number file-number)) result) (while attr-names (let ((attr (pop attr-names))) diff --git a/lisp/startup.el b/lisp/startup.el index 04de7e42fe..c7faf4abc6 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -458,7 +458,7 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'." ;; The Windows version doesn't report meaningful inode numbers, so ;; use the canonicalized absolute file name of the directory instead. (setq attrs (or canonicalized - (nthcdr 10 (file-attributes this-dir)))) + (file-attribute-file-number (file-attributes this-dir)))) (unless (member attrs normal-top-level-add-subdirs-inode-list) (push attrs normal-top-level-add-subdirs-inode-list) (dolist (file contents) diff --git a/src/dired.c b/src/dired.c index c2c099f0a5..32c083ad7b 100644 --- a/src/dired.c +++ b/src/dired.c @@ -923,11 +923,12 @@ Elements of the attribute list are: 8. File modes, as a string of ten letters or dashes as in ls -l. 9. An unspecified value, present only for backward compatibility. 10. inode number, as a nonnegative integer. -11. Filesystem device number, as an integer. +11. Filesystem device number, as an integer or a cons cell of integers. Large integers are bignums, so `eq' might not work on them. On most filesystems, the combination of the inode and the device -number uniquely identifies the file. +number uniquely identifies the file. This is provided by the access +function `file-attribute-file-number'. On MS-Windows, performance depends on `w32-get-true-file-attributes', which see. commit 85e47d9a9e809b7278fa6dc282ecb4a7a8f54690 (refs/remotes/origin/emacs-28) Author: Bill Wohler Date: Thu Oct 13 09:49:55 2022 -0700 ; Continued cleanup of "-hooks" * doc/misc/mh-e.texi: Replace mh-kill-folder-suppress-prompt-hook with mh-kill-folder-suppress-prompt-functions. diff --git a/doc/misc/mh-e.texi b/doc/misc/mh-e.texi index ed5c64bb47..3901974ede 100644 --- a/doc/misc/mh-e.texi +++ b/doc/misc/mh-e.texi @@ -3120,7 +3120,7 @@ retracted---without question@footnote{In previous versions of MH-E, this option suppressed the confirmation in @code{mh-kill-folder}. Since this kept most users from setting this option, @code{mh-kill-folder} was modified in version 6.0 to always ask for -confirmation subject to @code{mh-kill-folder-suppress-prompt-hook}. +confirmation subject to @code{mh-kill-folder-suppress-prompt-functions}. @xref{Folders}.}. @cindex MH-Folder mode @@ -3402,7 +3402,7 @@ Hook run by q before quitting MH-E (default: @code{nil}). Hook run by @code{mh-folder-mode} when visiting a new folder (default: @code{nil}). @c ------------------------- -@item mh-kill-folder-suppress-prompt-hook +@item mh-kill-folder-suppress-prompt-functions Abnormal hook run at the beginning of @code{mh-kill-folder} (default: @code{'mh-search-p}). @c ------------------------- commit 10f55975d34dd7299f72fdf8d93fd8cbe2e41e25 Author: Paul Eggert Date: Thu Oct 13 09:33:46 2022 -0700 Improve checks for recent "File exists" fixup * src/fileio.c (Finsert_file_contents): Add an assertion (bug#42431). diff --git a/src/fileio.c b/src/fileio.c index 49553f3c91..b9a57dd580 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -5003,6 +5003,7 @@ by calling `format-decode', which see. */) if (save_errno != 0) { /* Signal an error if visiting a file that could not be opened. */ + eassert (!NILP (visit) && NILP (handler)); report_file_errno ("Opening input file", orig_filename, save_errno); } commit 6efc64395282a960000d6fd9ac2e33ab7c764478 Author: Stefan Kangas Date: Thu Oct 13 15:46:56 2022 +0200 Make `info' treat "\n" in node names as "\s" * lisp/info.el (info): Treat "\n" in node name as "\s". (Bug#57936) diff --git a/lisp/info.el b/lisp/info.el index 292bf93a6f..fabba2734a 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -763,6 +763,11 @@ See a list of available Info commands in `Info-mode'." (read-file-name "Info file name: " nil nil t)) (if (numberp current-prefix-arg) (format "*info*<%s>" current-prefix-arg)))) + (when file-or-node + ;; Info node names don't contain newlines, so allow for easier use + ;; of names that might have been wrapped (in emails, etc.). + (setq file-or-node + (string-replace "\n" " " file-or-node))) (info-setup file-or-node (pop-to-buffer-same-window (or buffer "*info*")))) commit e6c701c8c332e8564ffbb8cd9398c341377323ee Author: Po Lu Date: Thu Oct 13 18:47:49 2022 +0800 Shrink client list window structure * src/xterm.c (struct x_client_list_window): Rearrange members for better alignment. diff --git a/src/xterm.c b/src/xterm.c index 9059ad7136..27a6687348 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1425,9 +1425,6 @@ struct x_client_list_window /* The width and height of the window. */ int width, height; - /* Whether or not the window is mapped. */ - bool mapped_p; - /* A bitmask describing events Emacs was listening for from the window before some extra events were added in `x_dnd_compute_toplevels'. */ @@ -1439,9 +1436,6 @@ struct x_client_list_window /* The next window in this list. */ struct x_client_list_window *next; - /* The Motif protocol style of this window, if any. */ - uint8_t xm_protocol_style; - /* The extents of the frame window in each direction. */ int frame_extents_left; int frame_extents_right; @@ -1452,18 +1446,24 @@ struct x_client_list_window /* The border width of this window. */ int border_width; - /* The rectangles making up the input shape. */ - XRectangle *input_rects; - /* The number of rectangles composing the input shape. */ int n_input_rects; + /* The rectangles making up the input shape. */ + XRectangle *input_rects; + /* The rectangles making up the bounding shape. */ XRectangle *bounding_rects; /* The number of rectangles composing the bounding shape. */ int n_bounding_rects; #endif + + /* The Motif protocol style of this window, if any. */ + uint8_t xm_protocol_style; + + /* Whether or not the window is mapped. */ + bool mapped_p; }; /* List of all toplevels in stacking order, from top to bottom. */ commit 97de273dca8d97039131f9d3f29b2820b5497805 Author: Paul Eggert Date: Thu Oct 13 01:48:10 2022 -0700 Simplify recent "File exists" fix * src/fileio.c (Finsert_file_contents): Simplify previous change that fixed bug#42431. diff --git a/src/fileio.c b/src/fileio.c index a238889803..49553f3c91 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -5000,7 +5000,7 @@ by calling `format-decode', which see. */) unbind_to (count1, Qnil); } - if (NILP (handler) && !NILP (visit) && current_buffer->modtime.tv_nsec < 0) + if (save_errno != 0) { /* Signal an error if visiting a file that could not be opened. */ report_file_errno ("Opening input file", orig_filename, save_errno); commit 12f261c4708d58362c9e080a686b0e41821c6db8 Author: Lars Ingebrigtsen Date: Thu Oct 13 10:08:55 2022 +0200 Fix hl-line-mode/global-hl-line-mode logic again * lisp/hl-line.el (hl-line-mode): Make explicit calls to (hl-line-mode 1) work again when global-hl-line-mode is on (bug#58478). diff --git a/lisp/hl-line.el b/lisp/hl-line.el index 693c94eea8..87bea1017f 100644 --- a/lisp/hl-line.el +++ b/lisp/hl-line.el @@ -156,7 +156,8 @@ line about point in the selected window only." :group 'hl-line ;; If the global mode is switched on, then `M-x hl-line-mode' should ;; switch the mode off in this buffer. - (when global-hl-line-mode + (when (and global-hl-line-mode + (eq arg 'toggle)) (setq hl-line-mode nil) (setq-local global-hl-line-mode nil) (global-hl-line-unhighlight)) commit 4af4df18c54748eaac87be51660f3c80a415a82f Author: Lars Ingebrigtsen Date: Thu Oct 13 09:52:44 2022 +0200 Fix browse-url-emacs for file: URLs on Windows * lisp/net/browse-url.el (browse-url-emacs): Fix up file:///c:/foo/bar URLs on windows (bug#58464). diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index 2d528c4862..1597f3651a 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -1294,6 +1294,11 @@ currently selected window instead." (let ((file (url-unhex-string (url-filename parsed)))) (when-let ((coding (browse-url--file-name-coding-system))) (setq file (decode-coding-string file 'utf-8))) + ;; The local-part of file: URLs on Windows is supposed to + ;; start with an extra slash. + (when (eq system-type 'windows-nt) + (setq file (replace-regexp-in-string + "\\`/\\([a-z]:\\)" "\\1" file))) (funcall func file)) (let ((file-name-handler-alist (cons (cons url-handler-regexp 'url-file-handler) commit 7054481ed5ab588c308cb06a137bab24d777a1ab Author: Juri Linkov Date: Thu Oct 13 10:23:44 2022 +0300 * lisp/outline.el: Rearrange button/margin functions. (outline--make-button-overlay, outline--make-margin-overlay) (outline--insert-open-button, outline--insert-close-button) (outline--fix-up-all-buttons): Move to the section "Button/margin indicators". diff --git a/lisp/outline.el b/lisp/outline.el index b2b36a764c..b87d3ac5e7 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -1059,106 +1059,6 @@ If non-nil, EVENT should be a mouse event." (mouse-set-point event)) (outline-flag-subtree t))) -(defun outline--make-button-overlay (type) - (let ((o (seq-find (lambda (o) - (overlay-get o 'outline-button)) - (overlays-at (point))))) - (unless o - (setq o (make-overlay (point) (1+ (point)))) - (overlay-put o 'evaporate t) - (overlay-put o 'follow-link 'mouse-face) - (overlay-put o 'mouse-face 'highlight) - (overlay-put o 'outline-button t)) - (let ((icon (icon-elements (if (eq type 'close) - (if outline--use-rtl - 'outline-close-rtl - 'outline-close) - 'outline-open))) - (inhibit-read-only t)) - ;; In editing buffers we use overlays only, but in other buffers - ;; we use a mix of text properties, text and overlays to make - ;; movement commands work more logically. - (when (derived-mode-p 'special-mode) - (put-text-property (point) (1+ (point)) 'face (plist-get icon 'face))) - (if-let ((image (plist-get icon 'image))) - (overlay-put o 'display image) - (overlay-put o 'display (concat (plist-get icon 'string) - (string (char-after (point))))) - (overlay-put o 'face (plist-get icon 'face)))) - o)) - -(defun outline--make-margin-overlay (type) - (let ((o (seq-find (lambda (o) - (overlay-get o 'outline-margin)) - (overlays-at (point))))) - (unless o - (setq o (make-overlay (point) (1+ (point)))) - (overlay-put o 'evaporate t) - (overlay-put o 'outline-margin t)) - (let ((icon (icon-elements (if (eq type 'close) - (if outline--use-rtl - 'outline-close-rtl-in-margins - 'outline-close-in-margins) - 'outline-open-in-margins)))) - (overlay-put - o 'before-string - (propertize " " 'display - `((margin ,(if outline--use-rtl - 'right-margin 'left-margin)) - ,(or (plist-get icon 'image) - (plist-get icon 'string)))))) - o)) - -(defun outline--insert-open-button (&optional use-margins) - (with-silent-modifications - (save-excursion - (beginning-of-line) - (if use-margins - (outline--make-margin-overlay 'open) - (when (derived-mode-p 'special-mode) - (let ((inhibit-read-only t)) - (insert " ") - (beginning-of-line))) - (let ((o (outline--make-button-overlay 'open))) - (overlay-put o 'help-echo "Click to hide") - (overlay-put o 'keymap - (define-keymap - "RET" #'outline-hide-subtree - "" #'outline-hide-subtree))))))) - -(defun outline--insert-close-button (&optional use-margins) - (with-silent-modifications - (save-excursion - (beginning-of-line) - (if use-margins - (outline--make-margin-overlay 'close) - (when (derived-mode-p 'special-mode) - (let ((inhibit-read-only t)) - (insert " ") - (beginning-of-line))) - (let ((o (outline--make-button-overlay 'close))) - (overlay-put o 'help-echo "Click to show") - (overlay-put o 'keymap - (define-keymap - "RET" #'outline-show-subtree - "" #'outline-show-subtree))))))) - -(defun outline--fix-up-all-buttons (&optional from to) - (when (or outline--use-buttons outline--use-margins) - (when from - (save-excursion - (goto-char from) - (setq from (line-beginning-position)))) - (outline-map-region - (lambda () - (if (save-excursion - (outline-end-of-heading) - (seq-some (lambda (o) (eq (overlay-get o 'invisible) 'outline)) - (overlays-at (point)))) - (outline--insert-close-button outline--use-margins) - (outline--insert-open-button outline--use-margins))) - (or from (point-min)) (or to (point-max))))) - (define-obsolete-function-alias 'hide-subtree #'outline-hide-subtree "25.1") (defun outline-hide-leaves () @@ -1743,6 +1643,106 @@ With a prefix argument, show headings up to that LEVEL." ;;; Button/margin indicators +(defun outline--make-button-overlay (type) + (let ((o (seq-find (lambda (o) + (overlay-get o 'outline-button)) + (overlays-at (point))))) + (unless o + (setq o (make-overlay (point) (1+ (point)))) + (overlay-put o 'evaporate t) + (overlay-put o 'follow-link 'mouse-face) + (overlay-put o 'mouse-face 'highlight) + (overlay-put o 'outline-button t)) + (let ((icon (icon-elements (if (eq type 'close) + (if outline--use-rtl + 'outline-close-rtl + 'outline-close) + 'outline-open))) + (inhibit-read-only t)) + ;; In editing buffers we use overlays only, but in other buffers + ;; we use a mix of text properties, text and overlays to make + ;; movement commands work more logically. + (when (derived-mode-p 'special-mode) + (put-text-property (point) (1+ (point)) 'face (plist-get icon 'face))) + (if-let ((image (plist-get icon 'image))) + (overlay-put o 'display image) + (overlay-put o 'display (concat (plist-get icon 'string) + (string (char-after (point))))) + (overlay-put o 'face (plist-get icon 'face)))) + o)) + +(defun outline--make-margin-overlay (type) + (let ((o (seq-find (lambda (o) + (overlay-get o 'outline-margin)) + (overlays-at (point))))) + (unless o + (setq o (make-overlay (point) (1+ (point)))) + (overlay-put o 'evaporate t) + (overlay-put o 'outline-margin t)) + (let ((icon (icon-elements (if (eq type 'close) + (if outline--use-rtl + 'outline-close-rtl-in-margins + 'outline-close-in-margins) + 'outline-open-in-margins)))) + (overlay-put + o 'before-string + (propertize " " 'display + `((margin ,(if outline--use-rtl + 'right-margin 'left-margin)) + ,(or (plist-get icon 'image) + (plist-get icon 'string)))))) + o)) + +(defun outline--insert-open-button (&optional use-margins) + (with-silent-modifications + (save-excursion + (beginning-of-line) + (if use-margins + (outline--make-margin-overlay 'open) + (when (derived-mode-p 'special-mode) + (let ((inhibit-read-only t)) + (insert " ") + (beginning-of-line))) + (let ((o (outline--make-button-overlay 'open))) + (overlay-put o 'help-echo "Click to hide") + (overlay-put o 'keymap + (define-keymap + "RET" #'outline-hide-subtree + "" #'outline-hide-subtree))))))) + +(defun outline--insert-close-button (&optional use-margins) + (with-silent-modifications + (save-excursion + (beginning-of-line) + (if use-margins + (outline--make-margin-overlay 'close) + (when (derived-mode-p 'special-mode) + (let ((inhibit-read-only t)) + (insert " ") + (beginning-of-line))) + (let ((o (outline--make-button-overlay 'close))) + (overlay-put o 'help-echo "Click to show") + (overlay-put o 'keymap + (define-keymap + "RET" #'outline-show-subtree + "" #'outline-show-subtree))))))) + +(defun outline--fix-up-all-buttons (&optional from to) + (when (or outline--use-buttons outline--use-margins) + (when from + (save-excursion + (goto-char from) + (setq from (line-beginning-position)))) + (outline-map-region + (lambda () + (if (save-excursion + (outline-end-of-heading) + (seq-some (lambda (o) (eq (overlay-get o 'invisible) 'outline)) + (overlays-at (point)))) + (outline--insert-close-button outline--use-margins) + (outline--insert-open-button outline--use-margins))) + (or from (point-min)) (or to (point-max))))) + (defun outline--fix-buttons-after-change (beg end _len) ;; Handle whole lines (save-excursion (goto-char beg) (setq beg (pos-bol))) commit 3d41cc03d96b0383ad87c985ff48077e39cac985 Author: Juri Linkov Date: Thu Oct 13 10:13:07 2022 +0300 * lisp/outline.el (outline--fix-buttons-after-change): New function. (outline-minor-mode): Use it. (outline--make-margin-overlay): Remove inhibit-read-only. diff --git a/lisp/outline.el b/lisp/outline.el index 93a9247f61..b2b36a764c 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -516,13 +516,7 @@ See the command `outline-mode' for more information on this mode." (set-window-buffer nil (window-buffer))) (when (or outline--use-buttons outline--use-margins) (add-hook 'after-change-functions - (lambda (beg end _len) - (when outline--use-buttons - (remove-overlays beg end 'outline-button t)) - (when outline--use-margins - (remove-overlays beg end 'outline-margin t)) - (outline--fix-up-all-buttons beg end)) - nil t)) + #'outline--fix-buttons-after-change nil t)) (when outline-minor-mode-highlight (if (and global-font-lock-mode (font-lock-specified-p major-mode)) (progn @@ -1105,8 +1099,7 @@ If non-nil, EVENT should be a mouse event." (if outline--use-rtl 'outline-close-rtl-in-margins 'outline-close-in-margins) - 'outline-open-in-margins))) - (inhibit-read-only t)) + 'outline-open-in-margins)))) (overlay-put o 'before-string (propertize " " 'display @@ -1451,6 +1444,9 @@ convenient way to make a table of contents of the buffer." (insert "\n\n")))))) (kill-new (buffer-string))))))) + +;;; Initial visibility + (defcustom outline-default-state nil "If non-nil, some headings are initially outlined. @@ -1629,6 +1625,9 @@ LEVEL, decides of subtree visibility according to beg end))) (run-hooks 'outline-view-change-hook))) + +;;; Visibility cycling + (defun outline--cycle-state () "Return the cycle state of current heading. Return either `hide-all', `headings-only', or `show-all'." @@ -1741,6 +1740,19 @@ With a prefix argument, show headings up to that LEVEL." (setq outline--cycle-buffer-state 'show-all) (message "Show all"))))) + +;;; Button/margin indicators + +(defun outline--fix-buttons-after-change (beg end _len) + ;; Handle whole lines + (save-excursion (goto-char beg) (setq beg (pos-bol))) + (save-excursion (goto-char end) (setq end (pos-eol))) + (when outline--use-buttons + (remove-overlays beg end 'outline-button t)) + (when outline--use-margins + (remove-overlays beg end 'outline-margin t)) + (outline--fix-up-all-buttons beg end)) + (defvar-keymap outline-navigation-repeat-map "C-b" #'outline-backward-same-level