[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/bufferlo 41e4786fd7 186/192: Final stretch 1.1-pre WIP.
From: |
ELPA Syncer |
Subject: |
[elpa] externals/bufferlo 41e4786fd7 186/192: Final stretch 1.1-pre WIP. |
Date: |
Sat, 19 Apr 2025 15:58:23 -0400 (EDT) |
branch: externals/bufferlo
commit 41e4786fd7396391ddff9f4e2fc5c6cc40928609
Author: shipmints <shipmints@gmail.com>
Commit: Flo Rommel <mail@florommel.de>
Final stretch 1.1-pre WIP.
- Correct 'bufferlo-kill-buffers' and
'bufferlo-kill-orphan-buffers' 'internal-too' and hidden buffer
filtering (the logic had been inverted).
- Refine 'bufferlo--bookmark-tab-handler' terminology from
success/failure to restored/skipped.
- Improve bookmark auto save handling to avoid timer reentrancy
issues and improve handling bookmark.el prompts which should
also address minibuffer prompts changing focus.
- Remove arguments from 'bufferlo--bookmark-tab-make' and
'bufferlo--bookmark-frame-make' (that code was unused).
- Improve 'bufferlo--kill-buffer-safely' to avoid spurious
window creation by kill-buffer when the buffer is on the sole
window of a frame.
- Refine 'bufferlo--close-active-bookmarks' tab-tag logic to tag
only tabs on bookmarked tabs.
- README corrected default for
'bufferlo-bookmark-tab-failed-buffer-policy'.
- General typos, docstring improvement, and some formatting improvements.
- flymake/byte compiler noise.
---
README.org | 4 +-
bufferlo.el | 325 ++++++++++++++++++++++++++++++++----------------------------
2 files changed, 174 insertions(+), 155 deletions(-)
diff --git a/README.org b/README.org
index cceff0f1f1..f1d882d6d4 100644
--- a/README.org
+++ b/README.org
@@ -587,11 +587,11 @@ Note: 'raise is considered to act as 'clear by bookmark
set loading.
#+end_src
#+begin_src emacs-lisp
;; handle buffer bookmarks that could not be restored
- (setq bufferlo-bookmark-tab-failed-buffer-policy 'placeholder) ; placeholder
buffer and buffer name; the default
+ (setq bufferlo-bookmark-tab-failed-buffer-policy nil) ; ignore; the default
+ (setq bufferlo-bookmark-tab-failed-buffer-policy 'placeholder) ; placeholder
buffer and buffer name
(setq bufferlo-bookmark-tab-failed-buffer-policy 'placeholder-orig) ;
placeholder buffer with original buffer name
(setq bufferlo-bookmark-tab-failed-buffer-policy "*scratch*") ; default to a
specific buffer
(setq bufferlo-bookmark-tab-failed-buffer-policy
#'my/failed-bookmark-handler) ; function to call that returns a buffer
- (setq bufferlo-bookmark-tab-failed-buffer-policy nil) ; ignore
#+end_src
*** Bookmark set options
diff --git a/bufferlo.el b/bufferlo.el
index 0ddfd422b6..35be9efb28 100644
--- a/bufferlo.el
+++ b/bufferlo.el
@@ -27,30 +27,27 @@
;;; Commentary:
-;; With bufferlo, every frame and tab (i.e., tab-bar-mode tab) has an
-;; additional manageable local buffer list. A buffer is added to the
-;; local buffer list when displayed in the frame/tab (e.g., by opening a
-;; new file in the tab or by switching to the buffer from the global
-;; buffer list).
-
-;; Using Emacs's built-in buffer-list frame parameter, bufferlo
-;; integrates seamlessly with all standard frame and tab management
-;; facilities, including undeletion of frames and tabs, tab duplication
-;; and moving, frame cloning, and session persistence with desktop.el
-;; (though bufferlo frame and tab bookmarks offer an alternative
-;; persistence method).
-
-;; Bufferlo provides extensive management functions for its local lists
-;; and offers features on top of switch-buffer functions, buffer menu,
-;; and ibuffer. You can configure any command that selects a buffer to
-;; use the local buffer list via bufferlo-anywhere-mode.
-
-;; In addition, bufferlo offers lightweight Emacs bookmarks-based
-;; persistence for frames, tabs, and sets of frames/tabs to help you
-;; manage your transient workflows. Bufferlo bookmarks are compatible
-;; with built-in features such as bookmark-bmenu-list and third-party
-;; packages such as consult which offers consult-bookmark for interactive
-;; bookmark selection.
+;; With bufferlo, every frame and tab (i.e., `tab-bar-mode' tab) has an
+;; additional manageable local buffer list. A buffer is added to the local
+;; buffer list when displayed in the frame/tab (e.g., by opening a new file in
+;; the tab or by switching to the buffer from the global buffer list).
+
+;; Using Emacs's built-in buffer-list frame parameter, bufferlo integrates
+;; seamlessly with all standard frame and tab management facilities, including
+;; undeletion of frames and tabs, tab duplication and moving, frame cloning,
+;; and session persistence with `desktop' (though bufferlo frame and tab
+;; bookmarks offer an alternative persistence method).
+
+;; Bufferlo provides extensive management functions for its local lists and
+;; offers features on top of switch-buffer functions, buffer menu, and
+;; `ibuffer'. You can configure any command that selects a buffer to use the
+;; local buffer list via bufferlo-anywhere-mode.
+
+;; In addition, bufferlo offers lightweight Emacs bookmarks-based persistence
+;; for frames, tabs, and sets of frames/tabs to help you manage your transient
+;; workflows. Bufferlo bookmarks are compatible with built-in features such
+;; as `bookmark-bmenu-list' and third-party packages such as consult which
+;; offers consult-bookmark for interactive bookmark selection.
;;; Code:
@@ -612,8 +609,8 @@ Each function takes the following arguments:
bookmark-name: source bookmark name
effective-bookmark-name: nil, if tab bookmark cleared
tab: the handled tab
- succ-buffer-names: list of buffer names successfully restored
- fail-buffer-names: list of buffer names that could not be restored"
+ restored-buffer-names: list of restored buffer names
+ skipped-buffer-names: list of skipped buffer names"
:package-version '(bufferlo . "1.1")
:type 'hook)
@@ -659,7 +656,7 @@ This is controlled by
`bufferlo-bookmarks-auto-save-interval'.")
(setq bufferlo--bookmarks-auto-save-timer
(run-with-timer
bufferlo-bookmarks-auto-save-interval
- bufferlo-bookmarks-auto-save-interval
+ nil ; We reschedule in `bufferlo-bookmarks-save'.
#'bufferlo-bookmarks-save))))
(defcustom bufferlo-bookmarks-auto-save-interval 0
@@ -1532,7 +1529,7 @@ advised functions. Honors
`bufferlo-bookmark-frame-duplicate-policy'."
(throw :abort t))
('raise
;; NOTE: We throw nil here!
- ;; We delete the frame ourselfs before raising.
+ ;; We delete the frame ourselves before raising.
(delete-frame)
(bufferlo--bookmark-raise abm)
(throw :abort nil)))
@@ -1573,7 +1570,7 @@ Honors `bufferlo-bookmark-tab-duplicate-policy'."
(throw :abort t))
('raise
;; NOTE: We throw nil here!
- ;; We delete the frame ourselfs before raising.
+ ;; We delete the frame ourselves before raising.
(let (tab-bar-tab-prevent-close-functions)
(tab-bar-close-tab))
;; Find bookmark to raise; tab numbers changes when closing.
@@ -1740,11 +1737,12 @@ If BUFFER is nil, the current buffer is killed."
(when (and (one-window-p 'no-mini)
(eq (window-deletable-p) 'frame))
;; Kill the requested buffer but leave one live window on a "hidden"
- ;; buffer. The caller will close the tab or frame under its control.
- (switch-to-buffer-other-window " *bufferlo temp*"))
+ ;; buffer. The caller may close the tab or frame under its control.
+ (switch-to-buffer " *bufferlo temp*" 'norecord 'force-same-window))
(let ((frame-auto-hide-function) ; inhibit automatic frame deletion
;; No interference for buffer replacement selection
- (switch-to-prev-buffer-skip))
+ (switch-to-prev-buffer-skip)
+ (switch-to-prev-buffer-skip-regexp))
(kill-buffer buffer)))
(defun bufferlo--kill-buffer-forced (buffer)
@@ -1797,8 +1795,8 @@ argument INTERNAL-TOO is non-nil."
(buffers (seq-filter
(lambda (b)
(not (and
- (or internal-too
- (not (string-prefix-p " " (buffer-name b))))
+ (and (not internal-too)
+ (string-prefix-p " " (buffer-name b)))
(string-match-p exclude (buffer-name b)))))
kill-list)))
(dolist (b buffers)
@@ -1818,8 +1816,8 @@ Buffers matching `bufferlo-kill-buffers-exclude-filters'
are never killed."
(buffers (seq-filter
(lambda (b)
(not (and
- (or internal-too
- (not (string-prefix-p " " (buffer-name b))))
+ (and (not internal-too)
+ (string-prefix-p " " (buffer-name b)))
(string-match-p exclude (buffer-name b)))))
(bufferlo--get-orphan-buffers))))
(dolist (b buffers)
@@ -2388,23 +2386,20 @@ local buffer list to use. If it is nil, the current
frame is used."
(mapcar #'bufferlo--bookmark-get-for-buffer
buffers)))
-(defun bufferlo--bookmark-tab-make (&optional frame)
- "Get the bufferlo tab bookmark for the current tab in FRAME.
-FRAME specifies the frame; the default value of nil selects the current frame."
- (setq frame (or frame (selected-frame)))
- (with-selected-frame frame
- (let ((filtered-buffers
- (bufferlo--bookmark-filter-buffers))
- (current-tab (bufferlo--current-tab)))
- `((tab-explicit-name . ,(when (alist-get 'explicit-name current-tab)
- (alist-get 'name current-tab)))
- (tab-group . ,(alist-get 'group current-tab))
- (buffer-bookmarks . ,(bufferlo--bookmark-get-for-buffers-in-tab
+(defun bufferlo--bookmark-tab-make ()
+ "Make the tab bookmark record for the current frame and tab."
+ (let ((filtered-buffers
+ (bufferlo--bookmark-filter-buffers))
+ (current-tab (bufferlo--current-tab)))
+ `((tab-explicit-name . ,(when (alist-get 'explicit-name current-tab)
+ (alist-get 'name current-tab)))
+ (tab-group . ,(alist-get 'group current-tab))
+ (buffer-bookmarks . ,(bufferlo--bookmark-get-for-buffers-in-tab
+ filtered-buffers))
+ (buffer-list . ,(mapcar #'buffer-name
filtered-buffers))
- (buffer-list . ,(mapcar #'buffer-name
- filtered-buffers))
- (window . ,(window-state-get (frame-root-window) 'writable))
- (handler . ,#'bufferlo--bookmark-tab-handler)))))
+ (window . ,(window-state-get (frame-root-window) 'writable))
+ (handler . ,#'bufferlo--bookmark-tab-handler))))
(defun bufferlo--ws-replace-buffer-names (ws replace-alist)
"Replace buffer names according to REPLACE-ALIST in the window state WS."
@@ -2438,13 +2433,13 @@ and quit which are cumbersome during set loading.")
"Get the duplicate policy for THING BOOKMARK-NAME.
THING should be either \"frame\" or \"tab\".
Ask the user if DEFAULT-POLICY is set to \\='prompt.
-MODE can be one of \\='load \\='save \\='undelete, depending on the invoking
-action.
-EMBEDDED-TAB is non-nil if the tab bookmark is embedded in a frame bookmark.
-This functions throws :abort when the user quits.
+MODE can be one of \\='load \\='save \\='undelete, depending on the
+invoking action.
+EMBEDDED-TAB is non-nil if the tab bookmark is embedded in a frame
+bookmark. This functions throws :abort when the user quits.
-The varaible `bufferlo--bookmark-set-loading' should be non-nil if the function
-is invoked as part of a bookmark set restoration.
+The variable `bufferlo--bookmark-set-loading' should be non-nil if the
+function is invoked as part of a bookmark set restoration.
The functions presents the user with the following options:
allow, clear, ignore, raise, help, quit
@@ -2607,6 +2602,9 @@ invoking action. This functions throws :abort when the
user quits."
(_ (throw :abort t)))))
(defun bufferlo--bookmark-insert-placeholer (orig-name)
+ "`bufferlo--bookmark-tab-handler' helper function.
+Use ORIG-NAME to create a placeholder buffer for buffers that failed to
+restore."
(let ((buffer-existed (get-buffer orig-name))
(fail-buffer
(cond
@@ -2665,8 +2663,8 @@ Returns nil on success, non-nil on abort."
(orig-bookmark-name bookmark-name)
(abm (assoc bookmark-name (bufferlo--active-bookmarks)))
(disconnect-tbm-p)
- (succ-buffer-names)
- (fail-buffer-names)
+ (restored-buffer-names)
+ (skipped-buffer-names)
(msg)
(msg-append (lambda (s) (setq msg (concat msg "; " s)))))
@@ -2743,7 +2741,7 @@ Returns nil on success, non-nil on abort."
(progn
(funcall (or (bookmark-get-handler
record)
'bookmark-default-handler)
- record)
+ record)
(run-hooks 'bookmark-after-jump-hook)
nil)
(error
@@ -2757,8 +2755,8 @@ Returns nil on success, non-nil on abort."
(if restore-failed
(progn
(bufferlo--bookmark-insert-placeholer
orig-name)
- (push orig-name fail-buffer-names))
- (push orig-name succ-buffer-names))
+ (push orig-name skipped-buffer-names))
+ (push orig-name restored-buffer-names))
(unless (eq (current-buffer) dummy)
;; Return a list of (cons <string> <buffer>).
@@ -2819,8 +2817,8 @@ Returns nil on success, non-nil on abort."
bookmark-name
(unless disconnect-tbm-p bookmark-name)
(bufferlo--current-tab)
- succ-buffer-names
- fail-buffer-names)
+ restored-buffer-names
+ skipped-buffer-names)
buffer))))
(add-hook 'bookmark-after-jump-hook bm-after-jump-hook-sym -99)
(when not-jump
@@ -2828,29 +2826,34 @@ Returns nil on success, non-nil on abort."
;; Log message
(unless (or no-message bufferlo--bookmark-handler-no-message)
- (message "Restored bufferlo tab bookmark%s%s"
+ (message "Restored bufferlo tab bookmark%s%s%s%s"
(if orig-bookmark-name (format ": %s" orig-bookmark-name) "")
- (or msg "")))
- ; explicitly return success; abort returns non-nil
+ (or msg "")
+ (if restored-buffer-names
+ (format " (%s)"
+ (mapconcat #'identity restored-buffer-names ",
")) "")
+ (if skipped-buffer-names
+ (format " (skipped: %s)"
+ (mapconcat #'identity skipped-buffer-names ", "))
"")))
+ ;; Explicitly return success; abort returns non-nil
nil)))
;; We use a short name here as bookmark-bmenu-list hard codes width of 8 chars
(put #'bufferlo--bookmark-tab-handler 'bookmark-handler-type "B-Tab")
(put #'bufferlo--bookmark-tab-handler 'bookmark-inhibit 'insert)
-(defun bufferlo--bookmark-frame-make (&optional frame)
- "Make a bufferlo frame bookmark.
-FRAME specifies the frame; the default value of nil selects the current frame."
- (let* ((tabs (funcall tab-bar-tabs-function frame))
- (orig-tab (1+ (tab-bar--current-tab-index tabs frame)))
- (tab-bar-tab-post-select-functions)
- (tabs-to-bookmark))
+(defun bufferlo--bookmark-frame-make ()
+ "Make a bufferlo frame bookmark record for the current frame."
+ (let ((tabs (funcall tab-bar-tabs-function))
+ (orig-tab (1+ (tab-bar--current-tab-index)))
+ (tab-bar-tab-post-select-functions)
+ tabs-to-bookmark)
(dotimes (i (length tabs))
(tab-bar-select-tab (1+ i))
(let* ((curr (alist-get 'current-tab tabs))
(name (alist-get 'name curr))
(explicit-name (alist-get 'explicit-name curr))
- (tbm (bufferlo--bookmark-tab-make frame)))
+ (tbm (bufferlo--bookmark-tab-make)))
(if explicit-name
(push (cons 'tab-name name) tbm)
(push (cons 'tab-name nil) tbm))
@@ -2859,7 +2862,7 @@ FRAME specifies the frame; the default value of nil
selects the current frame."
`((tabs . ,(reverse tabs-to-bookmark))
(current . ,orig-tab)
(bufferlo--frame-geometry . ,(funcall bufferlo-frame-geometry-function
- (or frame (selected-frame))))
+ (selected-frame)))
(handler . ,#'bufferlo--bookmark-frame-handler))))
(defun bufferlo--bookmark-frame-get-load-policy ()
@@ -3738,19 +3741,21 @@ This closes their associated bookmarks and kills their
buffers."
(assq 'current-tab (funcall tab-bar-tabs-function nil))))
(defun bufferlo--bookmark-tab-save (name &optional no-overwrite no-message msg)
- "Save the current tab as a bookmark.
+"Save the current tab as a bookmark.
NAME is the bookmark's name. If NO-OVERWRITE is non-nil, record
the new bookmark without throwing away the old one. NO-MESSAGE
inhibits the save status message. If MSG is non-nil, it is added
-to the save message."
- (bookmark-store name (bufferlo--bookmark-set-location
- (bufferlo--bookmark-tab-make))
- no-overwrite)
- (setf (alist-get 'bufferlo-bookmark-tab-name
- (cdr (bufferlo--current-tab)))
- name)
- (unless no-message
- (message "Saved bufferlo tab bookmark: %s%s" name (if msg msg ""))))
+to the save message.
+
+This function operates on the current frame and its current tab."
+(bookmark-store name (bufferlo--bookmark-set-location
+ (bufferlo--bookmark-tab-make))
+ no-overwrite)
+(setf (alist-get 'bufferlo-bookmark-tab-name
+ (cdr (bufferlo--current-tab)))
+ name)
+(unless no-message
+ (message "Saved bufferlo tab bookmark: %s%s" name (if msg msg ""))))
(defun bufferlo-bookmark-tab-save (name &optional no-overwrite no-message)
"Save the current tab as a bookmark.
@@ -4071,10 +4076,16 @@ Equality test is \\='equal."
(defun bufferlo--bookmarks-save (active-bookmark-names active-bookmarks
&optional no-message)
"Save the bookmarks in ACTIVE-BOOKMARK-NAMES indexed by ACTIVE-BOOKMARKS.
Specify NO-MESSAGE to inhibit the bookmark save status message."
- (let ((bookmarks-saved nil)
- (start-time (current-time)))
- ;; Inhibit built-in bookmark file saving until we're done
- (let ((bookmark-save-flag nil))
+ (let (bookmarks-saved)
+ ;; Offer to reload before we update bookmark entries. NOTE: There is
+ ;; still a potential race condition if the bookmark file changes via
+ ;; another process during this loop and the user will be prompted below
+ ;; when `bookmark-save' is called so we inhibit loading again around that
+ ;; call.
+ (bookmark-maybe-load-default-file)
+ ;; Inhibit built-in bookmark file saving and reloading until we're done.
+ (let (bookmark-save-flag
+ bookmark-watch-bookmark-file)
(dolist (abm-name active-bookmark-names)
(when-let* ((abm (assoc abm-name active-bookmarks))
(abm-type (alist-get 'type (cadr abm)))
@@ -4085,7 +4096,7 @@ Specify NO-MESSAGE to inhibit the bookmark save status
message."
(bufferlo--bookmark-frame-save abm-name nil t))
((eq abm-type 'tbm)
(let ((orig-tab-number (1+ (tab-bar--current-tab-index)))
- (tab-bar-tab-post-select-functions))
+ tab-bar-tab-post-select-functions)
(tab-bar-select-tab (alist-get 'tab-number (cadr abm)))
(bufferlo--bookmark-tab-save abm-name nil t)
(tab-bar-select-tab orig-tab-number))))
@@ -4095,10 +4106,12 @@ Specify NO-MESSAGE to inhibit the bookmark save status
message."
(let ((inhibit-message (or no-message
(not (memq
bufferlo-bookmarks-auto-save-messages
(list 'saved t))))))
- (bookmark-save)
- (message "Saved bufferlo bookmarks: %s, in %.2f second(s)"
- (mapconcat 'identity bookmarks-saved ", ")
- (float-time (time-subtract (current-time) start-time)))))
+ (let (bookmark-watch-bookmark-file ; see NOTE: above
+ (start-time (current-time)))
+ (bookmark-save)
+ (message "Saved bufferlo bookmarks: %s, in %.2f second(s)"
+ (mapconcat 'identity bookmarks-saved ", ")
+ (float-time (time-subtract (current-time) start-time))))))
(t
(when (and (not no-message)
(memq bufferlo-bookmarks-auto-save-messages
@@ -4127,61 +4140,65 @@ be saved will take precedence.
Duplicate bookmarks are handled according to
`bufferlo-bookmarks-save-duplicates-policy'."
(interactive)
- (catch :abort
- (let* ((frames (if all
- (frame-list)
- (pcase bufferlo-bookmarks-save-frame-policy
- ('current
- (list (selected-frame)))
- ('other
- (seq-filter (lambda (x) (not (eq x (selected-frame))))
- (frame-list)))
- (_ (frame-list)))))
- ;; Get the active bookmarks for the frames captured by the current
- ;; bufferlo-bookmarks-save-frame-policy only
- (abms (bufferlo--active-bookmarks frames))
-
- ;; Override bufferlo-bookmarks-save-predicate-functions on prefix
arg
- (bufferlo-bookmarks-save-predicate-functions
- (if (or all (consp current-prefix-arg))
- (list #'bufferlo-bookmarks-save-all-p)
- bufferlo-bookmarks-save-predicate-functions))
-
- ;; Filter the bookmark names to save
- (abm-names-to-save
- (seq-filter (lambda (x) (not (null x)))
- (mapcar
- (lambda (abm)
- (let ((abm-name (car abm)))
- (when (run-hook-with-args-until-success
-
'bufferlo-bookmarks-save-predicate-functions
- abm-name)
- abm-name)))
- abms)))
-
- ;; There may be open bookmarks that are duplicates
- (dupes-to-save (bufferlo--list-duplicates abm-names-to-save))
- ;; We'll handle these bookmarks according to the duplicate-policy
- (duplicate-policy bufferlo-bookmarks-save-duplicates-policy))
-
- (when (> (length dupes-to-save) 0)
- (when (eq duplicate-policy 'prompt)
- (pcase (with-local-quit
- (read-answer
- (format "Duplicate active bookmarks %s: Allow to save,
Disallow to cancel "
- dupes-to-save)
- '(("allow" ?a "Allow duplicate")
- ("disallow" ?d "Disallow duplicates; cancel saving")
- ("help" ?h "Help")
- ("quit" ?q "Quit with no changes"))))
- ("allow" (setq duplicate-policy 'allow))
- ("disallow" (setq duplicate-policy 'disallow))
- (_ (throw :abort t))))
- (pcase duplicate-policy
- ('allow)
- (_ (throw :abort t))))
-
- (bufferlo--bookmarks-save abm-names-to-save abms))))
+ (unwind-protect ; restart the timer in case the user quits any prompts
+ (catch :abort
+ (let* ((frames (if all
+ (frame-list)
+ (pcase bufferlo-bookmarks-save-frame-policy
+ ('current
+ (list (selected-frame)))
+ ('other
+ (seq-filter (lambda (x) (not (eq x
(selected-frame))))
+ (frame-list)))
+ (_ (frame-list)))))
+ ;; Get the active bookmarks for the frames captured by the
current
+ ;; bufferlo-bookmarks-save-frame-policy only
+ (abms (bufferlo--active-bookmarks frames))
+
+ ;; Override bufferlo-bookmarks-save-predicate-functions on
prefix arg
+ (bufferlo-bookmarks-save-predicate-functions
+ (if (or all (consp current-prefix-arg))
+ (list #'bufferlo-bookmarks-save-all-p)
+ bufferlo-bookmarks-save-predicate-functions))
+
+ ;; Filter the bookmark names to save
+ (abm-names-to-save
+ (seq-filter (lambda (x) (not (null x)))
+ (mapcar
+ (lambda (abm)
+ (let ((abm-name (car abm)))
+ (when (run-hook-with-args-until-success
+
'bufferlo-bookmarks-save-predicate-functions
+ abm-name)
+ abm-name)))
+ abms)))
+
+ ;; There may be open bookmarks that are duplicates
+ (dupes-to-save (bufferlo--list-duplicates abm-names-to-save))
+ ;; We'll handle these bookmarks according to the
duplicate-policy
+ (duplicate-policy bufferlo-bookmarks-save-duplicates-policy))
+
+ (when (> (length dupes-to-save) 0)
+ (when (eq duplicate-policy 'prompt)
+ (pcase (with-local-quit
+ (read-answer
+ (format "Duplicate active bookmarks %s: Allow to save,
Disallow to cancel "
+ dupes-to-save)
+ '(("allow" ?a "Allow duplicate")
+ ("disallow" ?d "Disallow duplicates; cancel saving")
+ ("help" ?h "Help")
+ ("quit" ?q "Quit with no changes"))))
+ ("allow" (setq duplicate-policy 'allow))
+ ("disallow" (setq duplicate-policy 'disallow))
+ (_ (throw :abort t))))
+ (pcase duplicate-policy
+ ('allow)
+ (_ (throw :abort t))))
+
+ (bufferlo--bookmarks-save abm-names-to-save abms)))
+ ;; Run the timer again only after this function is complete to avoid race
+ ;; conditions with user prompts.
+ (bufferlo--bookmarks-auto-save-timer-maybe-start)))
(defun bufferlo-bookmark--frame-save-on-delete (frame)
"`frame-delete' advice for saving the current frame bookmark on deletion.
@@ -4439,10 +4456,12 @@ which defaults to all frames, if not specified."
;; They are removed in that pass. If the user quits when prompted, the
;; tags are cleared on all tabs before being reassigned in the first
;; pass..
- ;; Clear any lingering tab tags.
+ ;;
+ ;; Clear any lingering tab tags on bookmarked tabs.
(dolist (frame (frame-list))
(dolist (tab (funcall tab-bar-tabs-function frame))
- (setf (alist-get 'bufferlo--tab-tag (cdr tab)) nil)))
+ (when (alist-get 'bufferlo-bookmark-tab-name tab)
+ (setf (alist-get 'bufferlo--tab-tag (cdr tab)) nil))))
;; Now assign fresh tab tags.
(let ((tab-tag 0))
(dolist (tbm tbms)
- [elpa] externals/bufferlo b431ec33cf 159/192: Synchronize tab bookmark entries bookmark list and buffer list, (continued)
- [elpa] externals/bufferlo b431ec33cf 159/192: Synchronize tab bookmark entries bookmark list and buffer list, ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo 82bb850da9 163/192: Tab bookmarks now save/restore the tab's explicit-name and group, ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo febbdfb9ee 161/192: Improve 'bufferlo-mode-line' and mode on/off behavior, ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo e7041c36a3 160/192: Silence byte-compiler, ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo 812892ec92 164/192: Allow both old and new define-ibuffer-op macro references to coexist, ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo 8f1d0c395f 165/192: Merge branch 'florommel:xp-sess' into xp-sess, ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo d93d6ed0ff 183/192: Update documentation, ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo b941f7fe12 171/192: Fix and simplify undo-tab and undelete-frame, ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo c2424a1c1f 180/192: Big bang: dupe handling, Emacs workarounds, package-versions, misc., ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo 512723ec41 178/192: Wrap bookmark--jump-via to ignore display-func for bufferlo bookmarks, ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo 41e4786fd7 186/192: Final stretch 1.1-pre WIP.,
ELPA Syncer <=
- [elpa] externals/bufferlo 25e8f6d4fa 174/192: Workaround for bookmark--jump-via in Emacs 31, ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo ebd1acf5a4 169/192: Inhibit 'tab-bar-tab-post-select-functions' where needed, ELPA Syncer, 2025/04/19
- [elpa] externals/bufferlo 71c5e2a4de 182/192: Streamline bufferlo--bookmark-get-duplicate-policy, ELPA Syncer, 2025/04/19