branch: externals/bufferlo
commit 7417b5175c3c4440d6fb7bd8fd5364e567373514
Author: shipmints <shipmi...@gmail.com>
Commit: shipmints <shipmi...@gmail.com>

    Discussion items updates.
    
    - Bookmark saving exclude and include filters now nil by default.
    - mode-line lighter is now text.
    - Defensive read-answer with-local-quit wrappers.
    - Frame handler now has unwind-protect to delete the new frame if not 
needed.
    - Frame handler now selects the new frame (mac default different than 
linux).
---
 bufferlo.el | 291 +++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 150 insertions(+), 141 deletions(-)

diff --git a/bufferlo.el b/bufferlo.el
index 759679bf36..c07c989fab 100644
--- a/bufferlo.el
+++ b/bufferlo.el
@@ -106,20 +106,12 @@ This is a list of regular expressions that match buffer 
names."
   "If non-nil, and `save-place-mode' mode is on, inhibit point in bookmarks."
   :type 'boolean)
 
-(defcustom bufferlo-bookmark-buffers-exclude-filters
-  (list
-   (rx bos " " (1+ anything)) ; ignores "invisible" buffers; e.g., " 
*Minibuf...", " markdown-code-fontification:..."
-   (rx bos "*" (1+ anything) "*")) ; ignores "special" buffers; e.g;, 
"*Messages*", "*scratch*", "*occur*"
+(defcustom bufferlo-bookmark-buffers-exclude-filters nil
   "Buffers that should be excluded from bufferlo bookmarks.
 This is a list of regular expressions to filter buffer names."
   :type '(repeat regexp))
 
-(defcustom bufferlo-bookmark-buffers-include-filters
-  (list
-   (rx bos "*shell*")
-   (rx bos "*" (1+ anything) "-shell*") ; project.el shell buffers
-   (rx bos "*eshell*")
-   (rx bos "*" (1+ anything) "-eshell*")) ; project.el eshell buffers
+(defcustom bufferlo-bookmark-buffers-include-filters nil
   "Buffers that should be stored in bufferlo bookmarks.
 This is a list of regular expressions to filter buffer names."
   :type '(repeat regexp))
@@ -461,8 +453,7 @@ Set to 0 to disable the timer. Units are whole integer 
seconds."
                 (const :tag "Saved only" saved)
                 (const :tag "Not-saved only" notsaved)))
 
-;; Yes, it's a playful cow, but the water buffalo "🐃" is dark and hard to see.
-(defcustom bufferlo-mode-line-lighter-prefix " 🐮"
+(defcustom bufferlo-mode-line-lighter-prefix " Bfl"
   "Bufferlo mode-line lighter prefix."
   :type 'string)
 
@@ -803,11 +794,12 @@ the adviced functions. Honors 
`bufferlo-bookmark-frame-clone-policy'."
     (when fbm
       (when (eq clone-policy 'prompt)
         (pcase (let ((read-answer-short t))
-                 (read-answer "Disassociate cloned/undeleted frame bookmark: 
Allow, Disassociate "
-                              '(("allow" ?a "Allow bookmark")
-                                ("disassociate" ?d "Disassociate bookmark")
-                                ("help" ?h "Help")
-                                ("quit" ?q "Quit--retains the bookmark"))))
+                 (with-local-quit
+                   (read-answer "Disassociate cloned/undeleted frame bookmark: 
Allow, Disassociate "
+                                '(("allow" ?a "Allow bookmark")
+                                  ("disassociate" ?d "Disassociate bookmark")
+                                  ("help" ?h "Help")
+                                  ("quit" ?q "Quit--retains the bookmark")))))
           ("disassociate" (setq clone-policy 'disassociate))
           (_ (setq clone-policy 'allow)))) ; allow, quit cases
       (pcase clone-policy
@@ -1503,12 +1495,13 @@ this bookmark is embedded in a frame bookmark."
                  (duplicate-policy bufferlo-bookmark-tab-duplicate-policy))
         (when (eq duplicate-policy 'prompt)
           (pcase (let ((read-answer-short t))
-                   (read-answer "Tab bookmark active in another tab: Allow, 
Clear bookmark after loading, Raise existing "
-                                '(("allow" ?a "Allow duplicate")
-                                  ("clear" ?c "Clear the bookmark after 
loading")
-                                  ("raise" ?r "Raise the existing tab 
bookmark")
-                                  ("help" ?h "Help")
-                                  ("quit" ?q "Quit with no changes"))))
+                   (with-local-quit
+                     (read-answer "Tab bookmark active in another tab: Allow, 
Clear bookmark after loading, Raise existing "
+                                  '(("allow" ?a "Allow duplicate")
+                                    ("clear" ?c "Clear the bookmark after 
loading")
+                                    ("raise" ?r "Raise the existing tab 
bookmark")
+                                    ("help" ?h "Help")
+                                    ("quit" ?q "Quit with no changes")))))
             ("allow" (setq duplicate-policy 'allow))
             ("clear" (setq duplicate-policy 'clear))
             ("raise" (setq duplicate-policy 'raise))
@@ -1527,18 +1520,19 @@ this bookmark is embedded in a frame bookmark."
         (let ((overwrite-policy bufferlo-bookmark-tab-overwrite-policy))
           (when (eq overwrite-policy 'prompt)
             (pcase (let ((read-answer-short t))
-                     (read-answer "Overwrite current tab, New tab "
-                                  '(("overwrite" ?o "Overwrite tab")
-                                    ("new" ?n "New tab")
-                                    ("help" ?h "Help")
-                                    ("quit" ?q "Quit with no changes"))))
+                     (with-local-quit
+                       (read-answer "Overwrite current tab, New tab "
+                                    '(("overwrite" ?o "Overwrite tab")
+                                      ("new" ?n "New tab")
+                                      ("help" ?h "Help")
+                                      ("quit" ?q "Quit with no changes")))))
               ("overwrite" (setq overwrite-policy 'overwrite))
               ("new" (setq overwrite-policy 'new))
               (_ (throw :noload t))))
           (pcase overwrite-policy
             ('overwrite)
             ('new
-             (unless current-prefix-arg ; user new tab suppression
+             (unless (consp current-prefix-arg) ; user new tab suppression
                (tab-bar-new-tab-to))))))
       (let* ((ws (copy-tree (alist-get 'window bookmark)))
              (dummy (generate-new-buffer " *bufferlo dummy buffer*")) ; TODO: 
needs unwind-protect or make-finalizer?
@@ -1579,11 +1573,12 @@ this bookmark is embedded in a frame bookmark."
             (let ((clear-policy 
bufferlo-bookmark-tab-load-into-bookmarked-frame-policy))
               (when (eq clear-policy 'prompt)
                 (pcase (let ((read-answer-short t))
-                         (read-answer "Tab bookmark conflicts with frame 
bookmark: Allow tab bookmark, Clear tab bookmark "
-                                      '(("allow" ?a "Allow tab bookmark")
-                                        ("clear" ?c "Clear tab bookmark")
-                                        ("help" ?h "Help")
-                                        ("quit" ?q "Quit--retains the 
bookmark"))))
+                         (with-local-quit
+                           (read-answer "Tab bookmark conflicts with frame 
bookmark: Allow tab bookmark, Clear tab bookmark "
+                                        '(("allow" ?a "Allow tab bookmark")
+                                          ("clear" ?c "Clear tab bookmark")
+                                          ("help" ?h "Help")
+                                          ("quit" ?q "Quit--retains the 
bookmark")))))
                   ("clear" (setq clear-policy 'clear))
                   (_ (setq clear-policy 'allow)))) ; allow, quit cases
               (pcase clear-policy
@@ -1627,90 +1622,101 @@ FRAME specifies the frame; the default value of nil 
selects the current frame."
 The argument BOOKMARK is the to-be restored frame bookmark created via
 `bufferlo--bookmark-frame-get'.  The optional argument NO-MESSAGE inhibits
 the message after successfully restoring the bookmark."
-  (catch :noload
-    (let ((bookmark-name (bookmark-name-from-full-record bookmark))
-          (duplicate-policy bufferlo-bookmark-frame-duplicate-policy)
-          (msg))
-      (if-let ((abm (assoc bookmark-name (bufferlo--active-bookmarks))))
-          (progn
-            (when (eq duplicate-policy 'prompt)
-              (pcase (let ((read-answer-short t))
-                       (read-answer "Frame bookmark already active: Allow, 
Clear bookmark after loading, Raise existing "
-                                    '(("allow" ?a "Allow duplicate")
-                                      ("clear" ?c "Clear the bookmark after 
loading")
-                                      ("raise" ?r "Raise the frame with the 
existing bookmark")
-                                      ("help" ?h "Help")
-                                      ("quit" ?q "Quit with no changes"))))
-                ("allow" (setq duplicate-policy 'allow))
-                ("clear" (setq duplicate-policy 'clear))
-                ("raise" (setq duplicate-policy 'raise))
-                (_ (throw :noload t))))
-            (when (eq duplicate-policy 'raise)
-              (bufferlo--bookmark-raise abm)
-              (throw :noload t)))
-        (setq duplicate-policy nil)) ; signal not a duplicate
-      (when (and
-             bufferlo-bookmark-frame-load-make-frame
-             (not current-prefix-arg) ; user make-frame suppression
-             (not pop-up-frames)) ; make-frame implied by functions like 
`bookmark-jump-other-frame'
-        (make-frame))
-      (let ((fbm (frame-parameter nil 'bufferlo-bookmark-frame-name))
-            (load-policy bufferlo-bookmark-frame-load-policy))
-        (if fbm
-            (progn
-              (when (eq load-policy 'prompt)
-                (pcase (let ((read-answer-short t))
-                         (read-answer "Frame already bookmarked: load and 
retain Current, Replace with new, Merge with existing "
-                                      '(("current" ?c "Replace frame, retain 
the current bookmark")
-                                        ("replace" ?r "Replace frame, adopt 
the loaded bookmark")
-                                        ("merge" ?m "Merge the new tab content 
with the existing bookmark")
-                                        ("help" ?h "Help")
-                                        ("quit" ?q "Quit with no changes"))))
-                  ("current" (setq load-policy 
'replace-frame-retain-current-bookmark))
-                  ("replace" (setq load-policy 
'replace-frame-adopt-loaded-bookmark))
-                  ("merge" (setq load-policy 'merge))
-                  (_ (throw :noload t))))
-              (pcase load-policy
-                ('disallow
-                 (when (not (equal fbm bookmark-name)) ; allow reloads of 
existing bookmark
-                   (unless no-message (message "Frame already bookmarked as 
%s; not loaded." fbm))
-                   (throw :noload t)))
-                ('replace-frame-retain-current-bookmark
-                 (setq msg (concat msg (format "; retained existing bookmark 
%s." fbm))))
-                ('replace-frame-adopt-loaded-bookmark
-                 (setq msg (concat msg (format "; adopted loaded bookmark %s." 
fbm)))
-                 (setq fbm bookmark-name))
-                ('merge
-                 (setq msg (concat msg (format "; merged tabs from bookmark 
%s." bookmark-name))))))
-          (setq fbm bookmark-name)) ; not already bookmarked
-        (unless (eq load-policy 'merge)
-          (if (>= emacs-major-version 28)
-              (tab-bar-tabs-set nil)
-            (set-frame-parameter nil 'tabs nil)))
-        (let ((first (if (eq load-policy 'merge) nil t))
-              (tab-bar-new-tab-choice t))
-          (mapc
-           (lambda (tbm)
-             (if first
-                 (setq first nil)
-               (tab-bar-new-tab-to))
-             (bufferlo--bookmark-tab-handler tbm t 'embedded-tab)
-             (when-let (tab-name (alist-get 'tab-name tbm))
-               (tab-bar-rename-tab tab-name)))
-           (alist-get 'tabs bookmark)))
-        (tab-bar-select-tab (alist-get 'current bookmark))
-        (pcase duplicate-policy
-          ('allow)
-          ('clear
-           (setq fbm nil))
-          ('clear-warn
-           (setq fbm nil)
-           (setq msg (concat msg "; cleared frame bookmark"))))
-        (set-frame-parameter nil 'bufferlo-bookmark-frame-name fbm))
-      (unless no-message
-        (message "Restored bufferlo frame bookmark%s%s"
-                 (if bookmark-name (format ": %s" bookmark-name) "")
-                 (if msg msg ""))))))
+  (let ((new-frame)
+        (keep-new-frame))
+    (unwind-protect
+        (catch :noload
+          (let ((bookmark-name (bookmark-name-from-full-record bookmark))
+                (duplicate-policy bufferlo-bookmark-frame-duplicate-policy)
+                (msg))
+            (if-let ((abm (assoc bookmark-name (bufferlo--active-bookmarks))))
+                (progn
+                  (when (eq duplicate-policy 'prompt)
+                    (pcase (let ((read-answer-short t))
+                             (with-local-quit
+                               (read-answer "Frame bookmark already active: 
Allow, Clear bookmark after loading, Raise existing "
+                                            '(("allow" ?a "Allow duplicate")
+                                              ("clear" ?c "Clear the bookmark 
after loading")
+                                              ("raise" ?r "Raise the frame 
with the existing bookmark")
+                                              ("help" ?h "Help")
+                                              ("quit" ?q "Quit with no 
changes")))))
+                      ("allow" (setq duplicate-policy 'allow))
+                      ("clear" (setq duplicate-policy 'clear))
+                      ("raise" (setq duplicate-policy 'raise))
+                      (_ (throw :noload t))))
+                  (when (eq duplicate-policy 'raise)
+                    (bufferlo--bookmark-raise abm)
+                    (throw :noload t)))
+              (setq duplicate-policy nil)) ; signal not a duplicate
+            (when (and
+                   bufferlo-bookmark-frame-load-make-frame
+                   (not (consp current-prefix-arg)) ; user make-frame 
suppression
+                   (not pop-up-frames)) ; make-frame implied by functions like 
`bookmark-jump-other-frame'
+              (setq new-frame (make-frame)))
+            (let ((fbm (frame-parameter nil 'bufferlo-bookmark-frame-name))
+                  (load-policy bufferlo-bookmark-frame-load-policy))
+              (if fbm
+                  (progn
+                    (when (eq load-policy 'prompt)
+                      (pcase (let ((read-answer-short t))
+                               (with-local-quit
+                                 (read-answer "Current frame already 
bookmarked: load and retain Current, Replace with new, Merge with existing "
+                                              '(("current" ?c "Replace frame, 
retain the current bookmark")
+                                                ("replace" ?r "Replace frame, 
adopt the loaded bookmark")
+                                                ("merge" ?m "Merge the new tab 
content with the existing bookmark")
+                                                ("help" ?h "Help")
+                                                ("quit" ?q "Quit with no 
changes")))))
+                        ("current" (setq load-policy 
'replace-frame-retain-current-bookmark))
+                        ("replace" (setq load-policy 
'replace-frame-adopt-loaded-bookmark))
+                        ("merge" (setq load-policy 'merge))
+                        (_ (throw :noload t))))
+                    (pcase load-policy
+                      ('disallow
+                       (when (not (equal fbm bookmark-name)) ; allow reloads 
of existing bookmark
+                         (unless no-message (message "Frame already bookmarked 
as %s; not loaded." fbm))
+                         (throw :noload t)))
+                      ('replace-frame-retain-current-bookmark
+                       (setq msg (concat msg (format "; retained existing 
bookmark %s." fbm))))
+                      ('replace-frame-adopt-loaded-bookmark
+                       (setq msg (concat msg (format "; adopted loaded 
bookmark %s." fbm)))
+                       (setq fbm bookmark-name))
+                      ('merge
+                       (setq msg (concat msg (format "; merged tabs from 
bookmark %s." bookmark-name))))))
+                (setq fbm bookmark-name)) ; not already bookmarked
+              (with-selected-frame (or new-frame (selected-frame))
+                (unless (eq load-policy 'merge)
+                  (if (>= emacs-major-version 28)
+                      (tab-bar-tabs-set nil)
+                    (set-frame-parameter nil 'tabs nil)))
+                (let ((first (if (eq load-policy 'merge) nil t))
+                      (tab-bar-new-tab-choice t))
+                  (mapc
+                   (lambda (tbm)
+                     (if first
+                         (setq first nil)
+                       (tab-bar-new-tab-to))
+                     (bufferlo--bookmark-tab-handler tbm t 'embedded-tab)
+                     (when-let (tab-name (alist-get 'tab-name tbm))
+                       (tab-bar-rename-tab tab-name)))
+                   (alist-get 'tabs bookmark)))
+                (tab-bar-select-tab (alist-get 'current bookmark))
+                (pcase duplicate-policy
+                  ('allow)
+                  ('clear
+                   (setq fbm nil))
+                  ('clear-warn
+                   (setq fbm nil)
+                   (setq msg (concat msg "; cleared frame bookmark"))))
+                (set-frame-parameter nil 'bufferlo-bookmark-frame-name fbm)))
+            (when new-frame
+              (setq keep-new-frame t))
+            (unless no-message
+              (message "Restored bufferlo frame bookmark%s%s"
+                       (if bookmark-name (format ": %s" bookmark-name) "")
+                       (if msg msg "")))))
+      (if (and new-frame (not keep-new-frame))
+          (delete-frame new-frame)
+        (raise-frame (or new-frame (selected-frame)))))))
 
 (put #'bufferlo--bookmark-frame-handler 'bookmark-handler-type "B-Frame") ; 
short name here as bookmark-bmenu-list hard codes width of 8 chars
 
@@ -1990,11 +1996,12 @@ Duplicate bookmarks are handled according to
                (duplicate-policy bufferlo-bookmarks-save-duplicates-policy))
       (when (eq duplicate-policy 'prompt)
         (pcase (let ((read-answer-short t))
-                 (read-answer (format "Duplicate active bookmarks %s: Allow to 
save, Disallow to cancel " duplicate-bookmarks)
-                              '(("allow" ?a "Allow duplicate")
-                                ("disallow" ?d "Disallow duplicates; cancel 
saving")
-                                ("help" ?h "Help")
-                                ("quit" ?q "Quit with no changes"))))
+                 (with-local-quit
+                   (read-answer (format "Duplicate active bookmarks %s: Allow 
to save, Disallow to cancel " duplicate-bookmarks)
+                                '(("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 :nosave t))))
@@ -2002,7 +2009,7 @@ Duplicate bookmarks are handled according to
         ('allow)
         (_ (throw :nosave t))))
     (let ((bufferlo-bookmarks-save-predicate-functions
-           (if (or all current-prefix-arg)
+           (if (or all (consp current-prefix-arg))
                (list #'bufferlo-bookmarks-save-all-p)
              bufferlo-bookmarks-save-predicate-functions))
           (frames (if all
@@ -2053,7 +2060,7 @@ current or new frame according to
         (tab-bar-new-tab-choice t)
         (new-tab-frame nil)
         (bufferlo-bookmarks-load-predicate-functions
-         (if (or all current-prefix-arg)
+         (if (or all (consp current-prefix-arg))
              (list #'bufferlo-bookmarks-load-all-p)
            bufferlo-bookmarks-load-predicate-functions)))
     (dolist (bookmark-name (bufferlo--bookmark-get-names 
#'bufferlo--bookmark-tab-handler))
@@ -2118,11 +2125,12 @@ current or new frame according to
 Use a prefix argument to narrow the candidates to frame tabs, or
 a double prefix argument to narrow to tab bookmark candidates."
   (interactive)
-  (let* ((bookmark-names (apply 'bufferlo--bookmark-get-names
-                          (cond
-                           ((and current-prefix-arg (eq (prefix-numeric-value 
current-prefix-arg) 4)) (list #'bufferlo--bookmark-frame-handler))
-                           ((and current-prefix-arg (eq (prefix-numeric-value 
current-prefix-arg) 16)) (list #'bufferlo--bookmark-tab-handler))
-                           (t bufferlo--bookmark-handlers))))
+  (let* ((bookmark-names
+          (apply 'bufferlo--bookmark-get-names
+                 (cond
+                  ((and (consp current-prefix-arg) (eq (prefix-numeric-value 
current-prefix-arg) 4)) (list #'bufferlo--bookmark-frame-handler))
+                  ((and (consp current-prefix-arg) (eq (prefix-numeric-value 
current-prefix-arg) 16)) (list #'bufferlo--bookmark-tab-handler))
+                  (t bufferlo--bookmark-handlers))))
          (comps
           (completion-all-completions
            (completing-read "Load bookmark(s): "
@@ -2156,12 +2164,12 @@ Specify a prefix argument to imply FORCE."
          (tbm (alist-get 'bufferlo-bookmark-tab-name 
(tab-bar--current-tab-find)))
          (duplicate-fbm (> (length (seq-filter (lambda (x) (equal fbm (car 
x))) (bufferlo--active-bookmarks nil 'fbm))) 1))
          (duplicate-tbm (> (length (seq-filter (lambda (x) (equal tbm (car 
x))) (bufferlo--active-bookmarks nil 'tbm))) 1)))
-    (when (or force current-prefix-arg duplicate-fbm)
+    (when (or force (consp current-prefix-arg) duplicate-fbm)
       (set-frame-parameter nil 'bufferlo-bookmark-frame-name nil))
-    (when (or force current-prefix-arg duplicate-tbm)
+    (when (or force (consp current-prefix-arg) duplicate-tbm)
       (setf (alist-get 'bufferlo-bookmark-tab-name
                        (cdr (bufferlo--current-tab)))
-                 nil))))
+            nil))))
 
 (defun bufferlo-clear-active-bookmarks ()
   "Clear all active bufferlo frame and tab bookmarks.
@@ -2176,7 +2184,7 @@ disturbing existing bookmarks, or where auto-saving is 
enabled
 and you want to avoid overwriting stored bookmarks, perhaps with
 transient work."
   (interactive)
-  (when (or current-prefix-arg
+  (when (or (consp current-prefix-arg)
             (y-or-n-p "Clear all active bufferlo bookmarks? "))
     (dolist (frame (frame-list))
       (set-frame-parameter frame 'bufferlo-bookmark-frame-name nil)
@@ -2228,14 +2236,15 @@ all unless a prefix argument is specified."
          (abm-names (mapcar #'car abms)))
     (if (null abms)
         (message "No active bufferlo bookmarks")
-      (unless current-prefix-arg
+      (unless (consp current-prefix-arg)
         (pcase (let ((read-answer-short t))
-                 (read-answer "Save bookmarks before closing them: All, 
Predicate, No save "
-                              '(("all" ?a "Save all active bookmarks")
-                                ("pred" ?p "Save predicate-filtered bookmarks, 
if set")
-                                ("nosave" ?n "Don't save")
-                                ("help" ?h "Help")
-                                ("quit" ?q "Quit"))))
+                 (with-local-quit
+                   (read-answer "Save bookmarks before closing them: All, 
Predicate, No save "
+                                '(("all" ?a "Save all active bookmarks")
+                                  ("pred" ?p "Save predicate-filtered 
bookmarks, if set")
+                                  ("nosave" ?n "Don't save")
+                                  ("help" ?h "Help")
+                                  ("quit" ?q "Quit")))))
           ("all"
            (bufferlo-bookmarks-save 'all))
           ("pred"

Reply via email to