Last active
March 21, 2018 01:39
-
-
Save mjkramer/1bddf7dca70908862758eb833c43b3bc to your computer and use it in GitHub Desktop.
fewer dired buffers, for your health!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(with-eval-after-load 'dired | |
(substitute-key-definition 'dired-find-file 'my/diredp-find-file-reuse-dir-buffer dired-mode-map) | |
(substitute-key-definition 'dired-mouse-find-file 'my/diredp-mouse-find-file-reuse-dir-buffer dired-mode-map) | |
(substitute-key-definition 'dired-up-directory 'my/diredp-up-directory-reuse-dir-buffer dired-mode-map)) | |
(defun my/diredp-find-file-reuse-dir-buffer () ; Not bound | |
"Like `dired-find-file', but reuse Dired buffers. | |
Unlike `dired-find-alternate-file' this does not use | |
`find-alternate-file' unless (1) the target is a directory that is not | |
yet visited as a Dired buffer, and (2) the current (Dired) buffer is | |
not visited also in some other window (possibly in an iconified | |
frame)." | |
(interactive) | |
(set-buffer-modified-p nil) | |
(let ((file (dired-get-file-for-visit))) | |
(my/diredp--reuse-dir-buffer-helper file))) | |
(defun my/diredp-mouse-find-file-reuse-dir-buffer (event &optional find-file-func find-dir-func) ; Not bound | |
"Like `dired-mouse-find-file', but reuse Dired buffers. | |
Unlike `dired-find-alternate-file' this does not use | |
`find-alternate-file' unless (1) the target is a directory that is not | |
yet visited as a Dired buffer, and (2) the current (Dired) buffer is | |
not visited also in some other window (possibly in an iconified | |
frame). | |
Non-nil optional args FIND-FILE-FUNC and FIND-DIR-FUNC specify | |
functions to visit the file and directory, respectively. | |
Defaults: `find-file' and `dired', respectively." | |
(interactive "e") | |
(let (window pos file) | |
(save-excursion | |
(setq window (posn-window (event-end event)) | |
pos (posn-point (event-end event))) | |
(unless (windowp window) (error "No file chosen")) | |
(set-buffer (window-buffer window)) | |
(goto-char pos) | |
(setq file (dired-get-file-for-visit))) | |
(select-window window) | |
(my/diredp--reuse-dir-buffer-helper file find-file-func find-dir-func))) | |
(defun my/diredp-up-directory-reuse-dir-buffer (&optional other-window) ; Not bound | |
"Like `diredp-up-directory', but reuse Dired buffers. | |
With a prefix arg, Dired the parent directory in another window. | |
On MS Windows, moving up from a root Dired buffer does not kill that | |
buffer (the Windows drives buffer is not really a Dired buffer)." | |
(interactive "P") | |
(let* ((dir (dired-current-directory)) | |
(dirfile (directory-file-name dir)) | |
(up (file-name-directory dirfile))) | |
(or (dired-goto-file dirfile) | |
;; Only try `dired-goto-subdir' if buffer has more than one dir. | |
(and (cdr dired-subdir-alist) (dired-goto-subdir up)) ; It is a subdir inserted in current Dired. | |
(progn (my/diredp--reuse-dir-buffer-helper up nil nil other-window) | |
(dired-goto-file dir)) | |
(and (memq system-type '(windows-nt ms-dos)) (diredp-w32-drives other-window))))) | |
(defun my/diredp--reuse-dir-buffer-helper (file &optional find-file-func find-dir-func other-window) | |
"Helper for commands `diredp-*-reuse-dir-buffer' commands. | |
Non-nil optional args FIND-FILE-FUNC and FIND-DIR-FUNC specify | |
functions to visit the file and directory, respectively. | |
Defaults: `find-file' and `dired', respectively. | |
Unlike `dired-find-alternate-file' this does not use | |
`find-alternate-file' unless (1) the target is a directory that is not | |
yet visited as a Dired buffer, and (2) the current (Dired) buffer is | |
not visited also in some other window (possibly in an iconified | |
frame)." | |
(setq find-file-func (or find-file-func (if other-window #'find-file-other-window #'find-file)) | |
find-dir-func (or find-dir-func (if other-window #'dired-other-window #'dired))) | |
(let (;; This binding prevents problems with preserving point in windows displaying Dired buffers, because | |
;; reverting a Dired buffer empties it, which changes the places where the markers used by | |
;; `switch-to-buffer-preserve-window-point' point. | |
(switch-to-buffer-preserve-window-point (and (boundp 'switch-to-buffer-preserve-window-point) ; Emacs 24+ | |
(or (not (boundp 'dired-auto-revert-buffer)) | |
(not dired-auto-revert-buffer)) | |
switch-to-buffer-preserve-window-point)) | |
(find-file-run-dired t) | |
(wins ()) | |
(alt-find-file-func (if other-window | |
#'find-alternate-file-other-window | |
#'find-alternate-file)) | |
dir-bufs) | |
(if (or (not (file-directory-p file)) ; New is a not a directory | |
(dired-buffers-for-dir file) ; or there is a Dired buffer for it, even as a subdir. | |
(and (setq dir-bufs (dired-buffers-for-dir default-directory)) ; Dired bufs for current (old). | |
(progn | |
(dolist (buf dir-bufs) | |
(setq wins (append wins (get-buffer-window-list buf 'NOMINI 0)))) | |
(setq wins (delq nil wins)) | |
(cdr wins)))) ; More than one window showing current Dired buffer. | |
(if (file-directory-p file) | |
(or (and (cdr dired-subdir-alist) (dired-goto-subdir file)) ; New is a subdir inserted in current | |
(funcall find-dir-func file)) | |
(funcall find-file-func (file-name-sans-versions file t))) | |
(funcall alt-find-file-func (file-name-sans-versions file t))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment