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

    Proper duplicate detection when loading bookmark sets
    
    Also, improve grammar on a few messages.
---
 README.org  |   4 ++
 bufferlo.el | 136 ++++++++++++++++++++++++++++++++++++++++--------------------
 2 files changed, 96 insertions(+), 44 deletions(-)

diff --git a/README.org b/README.org
index 73145b794a..e1281b00ce 100644
--- a/README.org
+++ b/README.org
@@ -567,8 +567,11 @@ settings.
   ;; allow duplicate active frame bookmarks in the Emacs session
   (setq bufferlo-bookmark-frame-duplicate-policy 'prompt) ; default
   (setq bufferlo-bookmark-frame-duplicate-policy 'allow) ; old default behavior
+  (setq bufferlo-bookmark-frame-duplicate-policy 'clear) ; silently clear the 
loaded frame bookmark
+  (setq bufferlo-bookmark-frame-duplicate-policy 'clear-warn) ; clear the 
loaded frame bookmark with a message
   (setq bufferlo-bookmark-frame-duplicate-policy 'raise) ; do not load, raise 
the existing frame
 #+end_src
+Note: 'raise is considered to act as 'clear by bookmark set loading.
 #+begin_src emacs-lisp
   ;; retain the bookmark when cloning a bookmarked frame via `clone-frame' or 
C-x 5 c
   (setq bufferlo-bookmark-frame-clone-policy 'prompt) ; default
@@ -599,6 +602,7 @@ settings.
   (setq bufferlo-bookmark-tab-duplicate-policy 'clear-warn) ; clear the loaded 
tab bookmark with a message
   (setq bufferlo-bookmark-tab-duplicate-policy 'raise) ; do not load, raise 
the existing frame/tab
 #+end_src
+Note: 'raise is considered to act as 'clear by bookmark set loading.
 #+begin_src emacs-lisp
   ;; allow inferior tab bookmark on a bookmarked frame (Note: frame bookmarks 
supersede tab bookmarks when saving)
   (setq bufferlo-bookmark-tab-in-bookmarked-frame-policy 'prompt) ; default
diff --git a/bufferlo.el b/bufferlo.el
index 155c7f18df..29a71e01bf 100644
--- a/bufferlo.el
+++ b/bufferlo.el
@@ -273,7 +273,9 @@ conditions.
 \\='clear-warn issues a warning message about the frame losing
 its bookmark.
 
-\\='raise will raise the frame with the existing bookmark."
+\\='raise will raise the frame with the existing bookmark.
+
+Note: \\='raise is considered \\='clear during bookmark-set loading."
   :type '(radio (const :tag "Prompt" prompt)
                 (const :tag "Allow" allow)
                 (const :tag "Clear (silently)" clear)
@@ -330,7 +332,9 @@ reified frame bookmark behavior.
 bookmark.
 
 \\='raise raises the first found existing tab bookmark and its
-frame."
+frame.
+
+Note: \\='raise is considered \\='clear during bookmark-set loading."
   :type '(radio (const :tag "Prompt" prompt)
                 (const :tag "Allow" allow)
                 (const :tag "Clear (silently)" clear)
@@ -1949,36 +1953,68 @@ FRAME specifies the frame; the default value of nil 
selects the current frame."
                (when-let* ((replace (assoc (cadr bc) replace-alist)))
                  (setf (cadr bc) (cdr replace)))))))))
 
+(defvar bufferlo--bookmark-set-loading nil
+  "Let bind to t when a bookmark set is being loaded.
+This controls `bufferlo--bookmark-get-duplicate-policy' to inhibit raise
+and quit which are cumbersome during set loading.")
+
 (defun bufferlo--bookmark-get-duplicate-policy (bookmark-name thing 
default-policy mode)
   "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 is either \\='load or \\='save, depending on the invoking action.
 This functions throws :abort when the user quits."
-  (if (not (eq default-policy 'prompt))
-      default-policy
-    (pcase (let ((read-answer-short t))
-             (with-local-quit
-               (read-answer
-                (format "%s bookmark name \"%s\" already active: Allow, %s, 
Raise existing "
-                        (capitalize thing)
-                        bookmark-name
-                        (if (eq mode 'save)
-                            "Clear other bookmark"
-                          "Clear bookmark after loading"))
-                `(("allow" ?a "Allow duplicate")
-                  ("clear" ?c
-                   ,(if (eq mode 'save)
-                        (format "Clear the other %s's bookmark association" 
thing)
-                      (format "Clear this %s's bookmark association after 
loading" thing)))
-                  ("raise" ?r
-                   ,(format "Raise the %s with the active bookmark and quit" 
thing))
-                  ("help" ?h "Help")
-                  ("quit" ?q "Quit and abort")))))
-      ("allow" 'allow)
-      ("clear" 'clear)
-      ("raise" 'raise)
-      (_ (throw :abort t)))))
+  (cond
+   (bufferlo--bookmark-set-loading
+    (if (not (eq default-policy 'prompt))
+        ;; transform default raise policy to clear
+        (if (eq default-policy 'raise)
+            'clear
+          default-policy)
+      (pcase (let ((read-answer-short t))
+               (with-local-quit
+                 (read-answer
+                  (format "%s bookmark name \"%s\" already active: Allow, %s "
+                          (capitalize thing)
+                          bookmark-name
+                          (if (eq mode 'save)
+                              "Clear other bookmark"
+                            "Clear bookmark after loading"))
+                  `(("allow" ?a "Allow duplicate")
+                    ("clear" ?c
+                     ,(if (eq mode 'save)
+                          (format "Clear the other %s's bookmark association" 
thing)
+                        (format "Clear this %s's bookmark association after 
loading" thing)))
+                    ("help" ?h "Help")
+                    ("quit" ?q "Quit to clear")))))
+        ("allow" 'allow)
+        ("clear" 'clear)
+        (_ 'clear))))
+   (t
+    (if (not (eq default-policy 'prompt))
+        default-policy
+      (pcase (let ((read-answer-short t))
+               (with-local-quit
+                 (read-answer
+                  (format "%s bookmark name \"%s\" already active: Allow, %s, 
Raise existing "
+                          (capitalize thing)
+                          bookmark-name
+                          (if (eq mode 'save)
+                              "Clear other bookmark"
+                            "Clear bookmark after loading"))
+                  `(("allow" ?a "Allow duplicate")
+                    ("clear" ?c
+                     ,(if (eq mode 'save)
+                          (format "Clear the other %s's bookmark association" 
thing)
+                        (format "Clear this %s's bookmark association after 
loading" thing)))
+                    ("raise" ?r
+                     ,(format "Raise the %s with the active bookmark and quit" 
thing))
+                    ("help" ?h "Help")
+                    ("quit" ?q "Quit to abort")))))
+        ("allow" 'allow)
+        ("clear" 'clear)
+        ("raise" 'raise)
+        (_ (throw :abort t)))))))
 
 (defun bufferlo--bookmark-tab-get-replace-policy ()
   "Get the replace policy for tab bookmarks.
@@ -1992,7 +2028,7 @@ This functions throws :abort when the user quits."
                             '(("replace" ?o "Replace tab")
                               ("new" ?n "New tab")
                               ("help" ?h "Help")
-                              ("quit" ?q "Quit and abort")))))
+                              ("quit" ?q "Quit to abort")))))
       ("replace" 'replace)
       ("new" 'new)
       (_ (throw :abort t)))))
@@ -2020,7 +2056,7 @@ invoking action.  This functions throws :abort when the 
user quits."
                                    "Clear frame bookmark, set tab bookmark"
                                  "Clear tab bookmark"))
                   ("help" ?h "Help")
-                  ("quit" ?q "Quit and abort")))))
+                  ("quit" ?q "Quit to abort")))))
       ("allow" 'allow)
       ("clear" 'clear)
       (_ (throw :abort t)))))
@@ -2161,7 +2197,7 @@ This functions throws :abort when the user quits."
                   ("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 and abort")))))
+                  ("quit" ?q "Quit to abort")))))
       ("current" 'replace-frame-retain-current-bookmark)
       ("replace" 'replace-frame-adopt-loaded-bookmark)
       ("merge" 'merge)
@@ -2246,13 +2282,14 @@ the message after successfully restoring the bookmark."
           (tab-bar-select-tab (alist-get 'current bookmark))
 
           ;; Handle duplicate frame bookmark
-          (pcase duplicate-policy
-            ;; Do nothing for 'allow or nil
-            ('clear
-             (setq fbm nil))
-            ('clear-warn
-             (setq fbm nil)
-             (funcall msg-append "cleared frame bookmark")))
+          (when abm
+            (pcase duplicate-policy
+              ;; Do nothing for 'allow or nil
+              ('clear
+               (setq fbm nil))
+              ('clear-warn
+               (setq fbm nil)
+               (funcall msg-append "cleared frame bookmark"))))
 
           (set-frame-parameter nil 'bufferlo-bookmark-frame-name fbm)
 
@@ -2298,7 +2335,10 @@ CANDIDATES are the prompt options to select."
     (setq comps (seq-uniq (mapcar (lambda (x) (substring-no-properties x)) 
comps)))))
 
 (defvar bufferlo--frameset-save-filter ; filter out vs. 
frameset-persistent-filter-alist
-  '(alpha
+  '(;; bufferlo parameters
+    bufferlo-bookmark-frame-name
+    ;; Emacs parameters
+    alpha
     alpha-background
     auto-lower
     auto-raise
@@ -2364,7 +2404,8 @@ CANDIDATES are the prompt options to select."
     z-group))
 
 (defvar bufferlo--frameset-restore-filter
-  '(GUI:bottom
+  '(;; Emacs parameters
+    GUI:bottom
     GUI:font
     GUI:fullscreen
     GUI:height
@@ -2484,7 +2525,8 @@ the message after successfully restoring the bookmark."
   (let* ((bookmark-name (bookmark-name-from-full-record bookmark-record))
          (bufferlo-bookmark-names (bookmark-prop-get bookmark-record 
'bufferlo-bookmark-names))
          (abm-names (mapcar #'car (bufferlo--active-bookmarks)))
-         (active-bookmark-names (seq-intersection bufferlo-bookmark-names 
abm-names)))
+         (active-bookmark-names (seq-intersection bufferlo-bookmark-names 
abm-names))
+         (bufferlo--bookmark-set-loading t))
     (if (assoc bookmark-name bufferlo--active-sets)
         (message "Bufferlo set \"%s\" is already active" bookmark-name)
       (message "Close or clear active bufferlo bookmarks: %s" 
active-bookmark-names)
@@ -2534,9 +2576,8 @@ the message after successfully restoring the bookmark."
                 (with-selected-frame frame
                   (when (frame-parameter nil 'bufferlo--frame-to-restore)
                     ;; (lower-frame) ; attempt to reduce visual flashing
-                    (when-let* ((fbm-name (frame-parameter nil 
'bufferlo-bookmark-frame-name)))
+                    (when-let* ((fbm-name (frame-parameter nil 
'bufferlo--bookmark-frame-name)))
                       (let ((bufferlo-bookmark-frame-load-make-frame nil)
-                            (bufferlo-bookmark-frame-duplicate-policy 'allow)
                             (bufferlo-bookmark-frame-load-policy 
'replace-frame-adopt-loaded-bookmark)
                             (bufferlo--bookmark-handler-no-message t))
                         (bufferlo--bookmark-jump fbm-name))
@@ -2596,13 +2637,20 @@ message."
                     (bufferlo--tbms . ,tbm-names))
                   tabsets)))
         (when fbm-frames
-          ;; Set a flag we can use to identify restored frames (this is
-          ;; removed in the handler during frame restoration). Save
+          ;; Set a flag we can use to identify restored frames (this
+          ;; is removed in the handler during frame restoration). Save
           ;; frame geometries for more accurate restoration than
           ;; frameset-restore provides.
+          ;;
+          ;; Squirrel away 'bufferlo-bookmark-frame-name which we ask
+          ;; frameset-save to filter out to avoid restored frames
+          ;; being considered bookmarked as they need duplicate
+          ;; detection.
           (dolist (frame fbm-frames)
             (set-frame-parameter frame 'bufferlo--frame-to-restore t)
-            (set-frame-parameter frame 'bufferlo--frame-geometry (funcall 
bufferlo-frame-geometry-function frame)))
+            (set-frame-parameter frame 'bufferlo--frame-geometry (funcall 
bufferlo-frame-geometry-function frame))
+            (set-frame-parameter frame 'bufferlo--bookmark-frame-name
+                                 (frame-parameter frame 
'bufferlo-bookmark-frame-name)))
           ;; frameset-save squirrels away width/height text-pixels iff
           ;; fullscreen is not nil and frame-resize-pixelwise is t.
           (let ((frame-resize-pixelwise t))

Reply via email to