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

    refactor(side): simplify file opening
    
    With this change, opening a file from the side window offers these options:
    
    - `dired-find-file`: Opens the file in the most recently used window.
    - `dired-find-alternate-file`: Opens the file and closes the side window.
    - `dired-find-file-other-window`: Opens the file in a new split window.
    
    Users who preferred the removed `dirvish-side-auto-close` option can 
replicate
    this behavior by customizing `dirvish-side-open-file-action`.
    
    This approach simplifies configuration and leverages existing window 
splitting
    preferences, such as `split-width-threshold`.
---
 dirvish.el                 | 32 +++++++++++++------------
 docs/CUSTOMIZING.org       | 14 +++++++----
 docs/EXTENSIONS.org        |  2 +-
 extensions/dirvish-side.el | 58 +++++++++++++++++++++-------------------------
 4 files changed, 54 insertions(+), 52 deletions(-)

diff --git a/dirvish.el b/dirvish.el
index e32f2a2241..950fe781f7 100644
--- a/dirvish.el
+++ b/dirvish.el
@@ -335,9 +335,9 @@ seconds.  DEBOUNCE defaults to 
`dirvish-redisplay-debounce'."
 (defmacro dirvish-save-dedication (&rest body)
   "Run BODY after undedicating window, restore dedication afterwards."
   (declare (debug (&rest form)))
-  `(let ((dedicated (window-dedicated-p)))
-     (set-window-dedicated-p nil nil)
-     (prog1 ,@body (set-window-dedicated-p nil dedicated))))
+  `(let* ((w (selected-window)) (ded (window-dedicated-p w)))
+     (set-window-dedicated-p w nil)
+     (prog1 ,@body (and (window-live-p w) (set-window-dedicated-p w ded)))))
 
 (defsubst dirvish-curr ()
   "Return Dirvish session attached to current buffer, if there is any."
@@ -429,7 +429,7 @@ Set process's SENTINEL and PUTS accordingly."
   (size-fixed ()                      :documentation "passes to 
`window-size-fixed' for ROOT-WINDOW.")
   (root-conf #'ignore                 :documentation "is a function to apply 
extra configs for INDEX buffer.")
   (root-window-fn ()                  :documentation "is a function used to 
create the ROOT-WINDOW for DV.")
-  (open-file-fn #'ignore              :documentation "is a function called 
before opening a file.")
+  (open-file #'dirvish-open-file      :documentation "is a function to handle 
file opening.")
   (curr-layout ()                     :documentation "is the working layout 
recipe of DV.")
   (ff-layout dirvish-default-layout   :documentation "is a full-frame layout 
recipe.")
   (ls-switches dired-listing-switches :documentation "is the directory listing 
switches.")
@@ -488,11 +488,12 @@ FROM-QUIT is used to signify the calling command."
   (let* ((idx (dv-index dv)) (ff (dv-curr-layout dv)) (wcon (dv-winconf dv))
          (server-buf? (lambda (root) (with-current-buffer (cdr root)
                                   (bound-and-true-p server-buffer-clients))))
-         keep roots kill-buffer-hook)
+         (keep (list idx)) roots kill-buffer-hook)
     (cl-loop with killer = (lambda (r) (unless (member r keep) (kill-buffer 
(cdr r))))
              for root in (setq roots (dv-roots dv))
              if (or (get-buffer-window (cdr root)) (funcall server-buf? root))
-             do (push root keep) finally do (mapc killer roots))
+             do (cl-pushnew root keep :test #'equal)
+             finally do (mapc killer roots))
     (when (and ff wcon) (set-window-configuration wcon))
     (set-window-fringes
      nil (frame-parameter nil 'left-fringe) (frame-parameter nil 'left-fringe))
@@ -550,6 +551,14 @@ FROM-QUIT is used to signify the calling command."
                  (dv-preview-dispatchers dv) (dirvish--preview-dps-validate)
                  (dv-attributes dv) (dirvish--attrs-expand attrs))))
 
+(defun dirvish-open-file (dv find-fn file)
+  "Open FILE using FIND-FN for default DV sessions."
+  (let ((cur (current-buffer)) fbuf)
+    (unwind-protect (funcall find-fn file)
+      (unless (eq (setq fbuf (current-buffer)) cur)
+        (dirvish--clear-session dv)
+        (dirvish-save-dedication (switch-to-buffer fbuf))))))
+
 (cl-defun dirvish--find-entry (find-fn entry)
   "Find ENTRY using FIND-FN in current dirvish session.
 FIND-FN can be one of `find-file', `find-alternate-file',
@@ -576,15 +585,8 @@ filename or a string with format of `dirvish-fd-bufname'."
              (cl-return-from dirvish--find-entry)))
       (cl-return-from dirvish--find-entry (dirvish--kill-buffer cur)))
     (if directory? (dirvish-save-dedication (funcall find-fn entry))
-      (funcall (dv-open-file-fn dv))
-      (dirvish--clear-session dv)
-      ;; if focusing a file window, do not kill previous buffer
-      (when (and (not (dirvish-curr)) (eq find-fn 'find-alternate-file))
-        (setq find-fn 'find-file))
-      (unwind-protect
-          (dirvish-save-dedication (funcall find-fn entry))
-        ;; opening aborted, e.g. user answered `no' on big file alert prompt.
-        (when (eq (current-buffer) cur) (quit-window))))))
+      (mapc #'dirvish--kill-buffer (dv-preview-buffers dv))
+      (funcall (dv-open-file dv) dv find-fn entry))))
 
 ;;;; Preview
 
diff --git a/docs/CUSTOMIZING.org b/docs/CUSTOMIZING.org
index 373c007b09..aced181da8 100644
--- a/docs/CUSTOMIZING.org
+++ b/docs/CUSTOMIZING.org
@@ -427,6 +427,14 @@ you don't have to require them explicitly if you installed 
dirvish from MELPA or
 =/path/to/dirvish/extensions/= is in your ~load-path~).
 
 #+begin_src emacs-lisp
+(use-package dired
+  :config
+  (setq dired-listing-switches
+        "-l --almost-all --human-readable --group-directories-first 
--no-group")
+  ;; this command is useful when you want to close the window of `dirvish-side'
+  ;; automatically when opening a file
+  (put 'dired-find-alternate-file 'disabled nil))
+
 (use-package dirvish
   :ensure t
   :init
@@ -448,14 +456,11 @@ you don't have to require them explicitly if you 
installed dirvish from MELPA or
         '(vc-state subtree-state nerd-icons collapse git-msg file-time 
file-size)
         dirvish-side-attributes
         '(vc-state nerd-icons collapse file-size))
-  (setq dired-listing-switches
-        "-l --almost-all --human-readable --group-directories-first 
--no-group")
   :bind ; Bind `dirvish-fd|dirvish-side|dirvish-dwim' as you see fit
   (("C-c f" . dirvish)
    :map dirvish-mode-map          ; Dirvish inherits `dired-mode-map'
-   ;; ("o" . dired-up-directory)  ; So you can adjust dired bindings here
+   ;; (";" . dired-up-directory)  ; So you can adjust dired bindings here
    ("?"   . dirvish-dispatch)     ; contains most of sub-menus in dirvish 
extensions
-   ("a"   . dirvish-quick-access)
    ("f"   . dirvish-history-go-forward)
    ("b"   . dirvish-history-go-backward)
    ("y"   . dirvish-yank-menu)
@@ -466,6 +471,7 @@ you don't have to require them explicitly if you installed 
dirvish from MELPA or
    ("r"   . dirvish-quicksort)    ; remapped `dired-sort-toggle-or-edit'
    ("v"   . dirvish-vc-menu)      ; remapped `dired-view-file'
    ("TAB" . dirvish-subtree-toggle)
+   ("M-a" . dirvish-quick-access)
    ("M-f" . dirvish-file-info-menu)
    ("M-l" . dirvish-ls-switches-menu)
    ("M-m" . dirvish-mark-menu)
diff --git a/docs/EXTENSIONS.org b/docs/EXTENSIONS.org
index 6543328068..e8ab56331a 100644
--- a/docs/EXTENSIONS.org
+++ b/docs/EXTENSIONS.org
@@ -182,7 +182,7 @@ as a sidebar in the frame.  These customization options are 
available:
 + ~dirvish-side-display-alist~: Display actions for the side window.
 + ~dirvish-side-window-parameters~: Window parameters for the side window.
 + ~dirvish-side-width~: Width of the side window.
-+ ~dirvish-side-open-file-window-function~: Set window of for opened files.
++ ~dirvish-side-open-file-action~: Action to perform before opening a file in 
a side window.
 + ~dirvish-side-auto-expand~: Whether to auto expand parent directories of 
current file.
 
 When ~dirvish-side-follow-mode~ is enabled, the visible side session will 
select
diff --git a/extensions/dirvish-side.el b/extensions/dirvish-side.el
index 242b432e30..a3ecb2d74e 100644
--- a/extensions/dirvish-side.el
+++ b/extensions/dirvish-side.el
@@ -43,45 +43,21 @@ See `dirvish-mode-line-format' for details."
 See `dirvish-attributes' for details."
   :group 'dirvish :type '(repeat (symbol :tag "Dirvish attribute")))
 
-(defcustom dirvish-side-open-file-action 'mru
-  "The action of how to open a file in side window.
-The value can be one of:
-
-- \\='mru    - open the file in the most-recent-used window.
-- \\='split  - open the file below the mru window.
-- \\='vsplit - open the file in a vertical split window.
-- a function that returns a target window for the file buffer,
-  such as `ace-select-window'."
+(defcustom dirvish-side-open-file-action nil
+  "Action to perform before opening a file in a side window.
+The value is a function called before switching to the file buffer.  The
+most recent used window is select if it is nil."
   :group 'dirvish
-  :type '(choice (const :tag "open the file in the most-recent-used window" 
mru)
-                 (const :tag "open the file below the mru window" split)
-                 (const :tag "open the file in a vertical split window" vsplit)
+  :type '(choice (const :tag "open the file in the most-recent-used window" 
nil)
                  (function :tag "custom function")))
 
-(defcustom dirvish-side-auto-close nil
-  "Whether to auto close the side session after opening a file."
-  :group 'dirvish :type 'boolean)
-
 (defcustom dirvish-side-auto-expand t
   "Whether to auto expand parent directories of current file.
 If non-nil, expand all the parent directories of current buffer's
 filename until the project root when opening a side session."
   :group 'dirvish :type 'boolean)
 
-(defun dirvish-side-open-file-fn ()
-  "Called before opening a file in side sessions."
-  (when (dv-curr-layout (dirvish-curr)) (dirvish-layout-toggle))
-  (when dirvish-side-auto-close (quit-window))
-  (let* ((mru (get-mru-window nil nil t)))
-    (select-window (cond ((functionp dirvish-side-open-file-action)
-                          (funcall dirvish-side-open-file-action))
-                         ((eq dirvish-side-open-file-action 'mru) mru)
-                         ((eq dirvish-side-open-file-action 'split)
-                          (with-selected-window mru (split-window-below)))
-                         ((eq dirvish-side-open-file-action 'vsplit)
-                          (with-selected-window mru (split-window-right)))))))
-
-(defun dirvish-side-root-conf-fn (buffer)
+(defun dirvish-side-root-conf (buffer)
   "Setup BUFFER for side session."
   (let ((name (buffer-name buffer)))
     (unless (string-prefix-p " *SIDE :: " name)
@@ -108,6 +84,24 @@ filename until the project root when opening a side 
session."
                (enlarge-window-horizontally (- w (window-width)))))))
     (select-window win)))
 
+(defun dirvish-side-open-file (dv find-fn file)
+  "Open FILE using FIND-FN for default DV sessions."
+  (let ((idx (current-buffer)) fbuf)
+    (unwind-protect (if (eq find-fn 'find-file-other-window)
+                        (funcall find-fn file) ; a new window is split
+                      (dirvish-save-dedication (funcall find-fn file)))
+      (cond ((eq (setq fbuf (current-buffer)) idx) nil)
+            ((eq find-fn 'find-file-other-window) (dirvish--clear-session dv))
+            (t (dirvish--clear-session dv)
+               (setf (dv-curr-layout dv) nil)
+               (if (buffer-live-p idx) ; `find-alternate-file' kills idx
+                   (dirvish-save-dedication (switch-to-buffer idx))
+                 (delete-window))
+               (when (dirvish-curr) (other-window 1))
+               (when (functionp dirvish-side-open-file-action)
+                 (funcall dirvish-side-open-file-action))
+               (dirvish-save-dedication (switch-to-buffer fbuf)))))))
+
 (defun dirvish-side--session-visible-p ()
   "Return the root window of visible side session."
   (cl-loop
@@ -144,9 +138,9 @@ filename until the project root when opening a side 
session."
                   :type 'side
                   :size-fixed 'width
                   :dedicated t
-                  :root-conf #'dirvish-side-root-conf-fn
+                  :root-conf #'dirvish-side-root-conf
                   :root-window-fn #'dirvish-side-root-window-fn
-                  :open-file-fn #'dirvish-side-open-file-fn)))
+                  :open-file #'dirvish-side-open-file)))
          (r-win (dv-root-window dv)))
     (setq r-win (dirvish--create-root-window dv))
     (with-selected-window r-win

Reply via email to