branch: elpa/dirvish
commit 5487761d1c922491f6d25098187cc5ef9ec5f201
Author: Alex Lu <hellosimon1...@hotmail.com>
Commit: Alex Lu <hellosimon1...@hotmail.com>

    feat(core): add `dirvish-ensure-up-dir-undedicated` option
---
 dirvish-extras.el          |  2 +-
 dirvish.el                 | 41 +++++++++++++++++++++++++++--------------
 extensions/dirvish-fd.el   |  4 ++--
 extensions/dirvish-side.el |  6 +++---
 4 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/dirvish-extras.el b/dirvish-extras.el
index dc4b8d607a..a3ac39afb7 100644
--- a/dirvish-extras.el
+++ b/dirvish-extras.el
@@ -228,7 +228,7 @@ possibly one or more parent windows."
       (with-selected-window (dv-root-window dv) (quit-window)))
     (setf (dv-curr-layout dv) new-layout)
     (with-selected-window (dirvish--create-root-window dv)
-      (dirvish--switch-to-buffer buf)
+      (dirvish-save-dedication (switch-to-buffer buf))
       (dirvish--init-session dv))))
 
 ;;;###autoload
diff --git a/dirvish.el b/dirvish.el
index 60027301b6..0d1dd39f34 100644
--- a/dirvish.el
+++ b/dirvish.el
@@ -168,6 +168,10 @@ Set it to nil to use the default `mode-line-format'."
   "Whether to hide cursor in dirvish buffers."
   :group 'dirvish :type 'boolean)
 
+(defcustom dirvish-window-fringe 1
+  "Window fringe for dirvish windows."
+  :group 'dirvish :type 'integer)
+
 (defconst dirvish-emacs-bin
   (cond
    ((and invocation-directory invocation-name)
@@ -212,9 +216,13 @@ The UI of dirvish is refreshed only when there has not 
been new
 input for `dirvish-redisplay-debounce' seconds."
   :group 'dirvish :type 'float)
 
-(defcustom dirvish-window-fringe 1
-  "Window fringe for dirvish windows."
-  :group 'dirvish :type 'integer)
+(defcustom dirvish-ensure-up-dir-undedicated t
+  "If t, `dired-up-directory' uses the same window when if it is dedicated."
+  :group 'dirvish :type 'boolean
+  :set
+  (lambda (k v) (set k v)
+    (if v (advice-add 'dired-up-directory :around #'dirvish-save-dedication-a)
+      (advice-remove 'dired-up-directory #'dirvish-save-dedication-a))))
 
 (cl-defgeneric dirvish-clean-cache () "Clean cache for selected files." nil)
 (cl-defgeneric dirvish-build-cache () "Build cache for current directory." nil)
@@ -294,6 +302,14 @@ seconds.  DEBOUNCE defaults to 
`dirvish-redisplay-debounce'."
        (and (timerp ,timer) (cancel-timer ,timer))
        (setq ,timer (run-with-idle-timer ,debounce nil ,fn)))))
 
+(defmacro dirvish-save-dedication (&rest body)
+  "Run BODY after undedicating window, restore dedication afterwards."
+  (declare (debug (&rest form)))
+  `(progn
+     (let ((dedicated (window-dedicated-p)))
+       (set-window-dedicated-p nil nil)
+       (prog1 ,@body (set-window-dedicated-p nil dedicated)))))
+
 (defmacro dirvish-define-attribute (name docstring &rest body)
   "Define a Dirvish attribute NAME.
 An attribute contains a pair of predicate/rendering functions
@@ -401,13 +417,6 @@ ALIST is window arguments passed to 
`window--display-buffer'."
          (new-window (split-window-no-error nil size side)))
     (window--display-buffer buffer new-window 'window alist)))
 
-(defun dirvish--switch-to-buffer (buffer)
-  "Switch to BUFFER with window undedicated."
-  (let ((dedicated (window-dedicated-p)) (win (selected-window)))
-    (set-window-dedicated-p win nil)
-    (prog1 (switch-to-buffer buffer)
-      (set-window-dedicated-p win dedicated))))
-
 (defun dirvish--kill-buffer (buffer)
   "Kill BUFFER without side effects."
   (and (buffer-live-p buffer)
@@ -467,7 +476,7 @@ If INHIBIT-HIDING is non-nil, do not hide the buffer."
 ;;;; Core
 
 (cl-defstruct (dirvish (:conc-name dv-))
-  "Define dirvish session ('DV' for short) struct."
+  "Define dirvish session (`DV' for short) struct."
   (type ()                :documentation "is the type of DV.")
   (root-window ()         :documentation "is the root/main window of DV.")
   (dedicated ()           :documentation "passes to `set-window-dedicated-p' 
for ROOT-WINDOW.")
@@ -479,7 +488,7 @@ If INHIBIT-HIDING is non-nil, do not hide the buffer."
    dirvish-default-layout :documentation "is a full-frame layout recipe.")
   (ls-switches
    dired-listing-switches :documentation "is the directory listing switches.")
-  (scopes ()              :documentation "are the 'environments' such as init 
frame of DV.")
+  (scopes ()              :documentation "are the environment of DV such as 
its init frame.")
   (preview-buffers ()     :documentation "holds all file preview buffers of 
DV.")
   (preview-window ()      :documentation "is the window to display preview 
buffer.")
   (name (cl-gensym)       :documentation "is an unique symbol to identify DV.")
@@ -645,6 +654,10 @@ ARGS is a list of keyword arguments for `dirvish' struct."
 
 ;;;; Advices
 
+(defun dirvish-save-dedication-a (fn args)
+  "Ensure FN and ARGS applied with window undedicated."
+  (dirvish-save-dedication (apply fn args)))
+
 (defun dirvish-find-entry-a (&optional entry)
   "Find ENTRY in current dirvish session.
 ENTRY can be a filename or a string with format of
@@ -656,7 +669,7 @@ buffer, it defaults to filename under the cursor when it is 
nil."
                        ((string-suffix-p "/" entry)
                         (user-error
                          (concat entry " is not a valid directory"))))))
-    (if buffer (dirvish--switch-to-buffer buffer)
+    (if buffer (dirvish-save-dedication (switch-to-buffer buffer))
       (let* ((ext (downcase (or (file-name-extension entry) "")))
              (file (expand-file-name entry))
              (process-connection-type nil)
@@ -692,7 +705,7 @@ buffer, it defaults to filename under the cursor when it is 
nil."
   (when-let* ((dv dirvish--this) ((dv-preview-window dv)))
     (dirvish--init-session dv)
     (with-selected-window (dv-preview-window dv)
-      (dirvish--switch-to-buffer image-dired-thumbnail-buffer)))
+      (switch-to-buffer image-dired-thumbnail-buffer)))
   (let ((buf (funcall fn))
         (fun (lambda () (let ((buf (get-text-property
                                (point) 'associated-dired-buffer)))
diff --git a/extensions/dirvish-fd.el b/extensions/dirvish-fd.el
index b436bd9d65..4c78fba6f8 100644
--- a/extensions/dirvish-fd.el
+++ b/extensions/dirvish-fd.el
@@ -339,7 +339,7 @@ value 16, let the user choose the root directory of their 
search."
         (message "`fd' process terminated")))
     (with-selected-window (dv-root-window dv)
       (unless (eq (current-buffer) buf)
-        (dirvish--switch-to-buffer buf)))
+        (dirvish-save-dedication (switch-to-buffer buf))))
     (with-current-buffer buf
       (setq-local dirvish-fd--input input
                   dirvish-fd--output (dirvish-fd--parse-output)
@@ -451,7 +451,7 @@ The command run is essentially:
         (set-process-sentinel proc #'dirvish-fd-proc-sentinel)
         (dirvish-fd--argparser (split-string (or fd-switches "")))
         (process-put proc 'info (list pattern dir dv))))
-    (dirvish--switch-to-buffer buffer)))
+    (dirvish-save-dedication (switch-to-buffer buffer))))
 
 
 ;;;###autoload
diff --git a/extensions/dirvish-side.el b/extensions/dirvish-side.el
index f8ebfb57e3..cf296b500f 100644
--- a/extensions/dirvish-side.el
+++ b/extensions/dirvish-side.el
@@ -15,8 +15,7 @@
 
 (require 'dirvish-subtree)
 
-(defcustom dirvish-side-display-alist
-  '((side . left) (slot . -1) (dedicated . t))
+(defcustom dirvish-side-display-alist '((side . left) (slot . -1))
   "Display alist for `dirvish-side' window."
   :group 'dirvish :type 'alist)
 
@@ -77,7 +76,8 @@ filename until the project root when opening a side session."
 (defun dirvish-side-root-window-fn ()
   "Create root window according to `dirvish-side-display-alist'."
   (let ((win (display-buffer-in-side-window
-              (dirvish--util-buffer "temp") dirvish-side-display-alist)))
+              (dirvish--util-buffer "temp")
+              (append '((dedicated . t)) dirvish-side-display-alist))))
     (cl-loop for (key . value) in dirvish-side-window-parameters
              do (set-window-parameter win key value))
     (with-selected-window win

Reply via email to