├── README.org
├── dired-toggle.el
└── screenshot.png
/README.org:
--------------------------------------------------------------------------------
1 | #+HTML:
2 | #+HTML:
3 |
4 | *** Description
5 |
6 | =dired-toggle= command could toggle to show dired buffer as a sidebar
7 | for current directory(similar to =dired-sidebar=, but more
8 | lightweight). The sidebar buffer also enabled a minor mode named
9 | =dired-toggle-mode=, and it only contains one buffer instance, change
10 | directories in it will not create news buffers.
11 |
12 | Usage:
13 | #+BEGIN_SRC elisp
14 | (use-package dired-toggle
15 | :defer t
16 | :bind (("" . #'dired-toggle)
17 | :map dired-mode-map
18 | ("q" . #'dired-toggle-quit)
19 | ([remap dired-find-file] . #'dired-toggle-find-file)
20 | ([remap dired-up-directory] . #'dired-toggle-up-directory)
21 | ("C-c C-u" . #'dired-toggle-up-directory))
22 | :config
23 | (setq dired-toggle-window-size 32)
24 | (setq dired-toggle-window-side 'left)
25 |
26 | ;; Optional, enable =visual-line-mode= for our narrow dired buffer:
27 | (add-hook 'dired-toggle-mode-hook
28 | (lambda () (interactive)
29 | (visual-line-mode 1)
30 | (setq-local visual-line-fringe-indicators '(nil right-curly-arrow))
31 | (setq-local word-wrap nil))))
32 | #+END_SRC
33 |
34 | Source: https://github.com/fasheng/dired-toggle
35 |
36 | *** Install
37 |
38 | You could install it easily through [[http://melpa.milkbox.net/#/getting-started][melpa]] by typing =M-x
39 | package-install dired-toggle=
40 |
41 | *** Screen shot
42 |
43 | [[file:screenshot.png]]
44 |
45 | (Enabled [[https://github.com/jtbm37/all-the-icons-dired][all-the-icons-dired]] and [[https://github.com/Fuco1/dired-hacks#dired-subtree][dired-subtree]] in screenshot)
46 |
47 | *** License
48 |
49 | GNU General Public License, Version 3.0
50 |
--------------------------------------------------------------------------------
/dired-toggle.el:
--------------------------------------------------------------------------------
1 | ;;; dired-toggle.el --- Show dired as sidebar and will not create new buffers when changing dir
2 | ;;
3 | ;; Copyright (C) 2013, Xu FaSheng
4 | ;;
5 | ;; Author: Xu FaSheng
6 | ;; Maintainer: Xu FaSheng
7 | ;; Version: 0.1
8 | ;; URL: https://github.com/fasheng/dired-toggle
9 | ;; Keywords: dired, sidebar
10 | ;; Compatibility: GNU Emacs: 24.x
11 | ;;
12 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13 | ;;
14 | ;; This program is free software; you can redistribute it and/or
15 | ;; modify it under the terms of the GNU General Public License as
16 | ;; published by the Free Software Foundation; either version 3, or
17 | ;; (at your option) any later version.
18 | ;;
19 | ;; This program is distributed in the hope that it will be useful,
20 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 | ;; General Public License for more details.
23 | ;;
24 | ;; You should have received a copy of the GNU General Public License
25 | ;; along with this program; see the file COPYING. If not, write to
26 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
27 | ;; Floor, Boston, MA 02110-1301, USA.
28 | ;;
29 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30 | ;;
31 | ;;; Commentary:
32 | ;;
33 | ;; Description:
34 | ;;
35 | ;; `dired-toggle' command could toggle to show dired buffer as a
36 | ;; sidebar for current directory(similar to `dired-sidebar', but more
37 | ;; lightweight). The sidebar buffer also enabled a minor mode named
38 | ;; `dired-toggle-mode', and it only contains one buffer instance,
39 | ;; change directories in it will not create news buffers.
40 | ;;
41 | ;; Usage:
42 | ;;
43 | ;; (use-package dired-toggle
44 | ;; :defer t
45 | ;; :bind (("" . #'dired-toggle)
46 | ;; :map dired-mode-map
47 | ;; ("q" . #'dired-toggle-quit)
48 | ;; ([remap dired-find-file] . #'dired-toggle-find-file)
49 | ;; ([remap dired-up-directory] . #'dired-toggle-up-directory)
50 | ;; ("C-c C-u" . #'dired-toggle-up-directory))
51 | ;; :config
52 | ;; (setq dired-toggle-window-size 32)
53 | ;; (setq dired-toggle-window-side 'left)
54 |
55 | ;; ;; Optional, enable =visual-line-mode= for our narrow dired buffer:
56 | ;; (add-hook 'dired-toggle-mode-hook
57 | ;; (lambda () (interactive)
58 | ;; (visual-line-mode 1)
59 | ;; (setq-local visual-line-fringe-indicators '(nil right-curly-arrow))
60 | ;; (setq-local word-wrap nil))))
61 | ;;
62 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
63 | ;;
64 | ;;; Code:
65 |
66 | (require 'dired)
67 |
68 | (defvar dired-toggle-buffer-name "*Dired Toggle*"
69 | "Target buffer name for `dired-toggle'.")
70 |
71 | (defvar dired-toggle-window-size 24
72 | "Target window size for `dired-toggle'.")
73 |
74 | (defvar dired-toggle-window-side 'left
75 | "Target window's place side for `dired-toggle', could be 'left, 'right,
76 | 'below or 'above, more information to see `split-window'.")
77 |
78 | (defvar dired-toggle-modeline-lighter " DiredTog"
79 | "Modeline lighter for `dired-toggle-mode'.")
80 |
81 | (defvar-local dired-toggle-refwin nil
82 | "Mark the referred window that jumping from.")
83 |
84 | (defvar dired-toggle-dired-mode-name 'dired-mode
85 | "Setup the default dired mode working with `dired-toggle-mode'.")
86 |
87 | (defun dired-toggle-list-dir (buffer dir &optional mode)
88 | "List target directory in a buffer."
89 | (let ((mode (or mode dired-toggle-dired-mode-name)))
90 | (with-current-buffer buffer
91 | (setq default-directory dir)
92 | (if (eq mode major-mode)
93 | (setq dired-directory dir)
94 | (funcall mode dir))
95 | (dired-toggle-mode 1)
96 | ;; default-directory and dired-actual-switches are set now
97 | ;; (buffer-local), so we can call dired-readin:
98 | (unwind-protect
99 | (progn (dired-readin))))))
100 |
101 | ;;;###autoload
102 | (defun dired-toggle-quit ()
103 | "Quit action under `dired-toggle-mode'."
104 | (interactive)
105 | (if (one-window-p)
106 | (quit-window)
107 | (delete-window)))
108 |
109 | ;;;###autoload
110 | (defun dired-toggle-find-file ()
111 | "Wraper for `dired-find-file', use `find-alternate-file' instead so will not
112 | create new buffer when changing directory, and will keep `dired-toggle-mode' and
113 | `dired-hide-details-mode' states after opening new direcoty."
114 | (interactive)
115 | (let* ((dired-toggle-enabled (if dired-toggle-mode 1 0))
116 | (dired-hide-details-enabled (if dired-hide-details-mode 1 0))
117 | (buffer (current-buffer))
118 | (file (dired-get-file-for-visit))
119 | (dir-p (file-directory-p file)))
120 | (if dir-p ;open a directory
121 | ;; (dired-toggle-list-dir buffer (file-name-as-directory file))
122 | (find-alternate-file file)
123 | ;; open a file, and delete the referred window firstly
124 | (if (and (window-live-p dired-toggle-refwin)
125 | (not (window-minibuffer-p dired-toggle-refwin))
126 | ;; Some times `dired-toggle-refwin' maybe dired-toggle
127 | ;; window itself, so just ignore it.
128 | (not (equal (selected-window) dired-toggle-refwin)))
129 | (delete-window dired-toggle-refwin))
130 | (dired-find-file))
131 | (when (eq major-mode 'dired-mode)
132 | (dired-toggle-mode dired-toggle-enabled)
133 | (dired-hide-details-mode dired-hide-details-enabled))))
134 |
135 | ;;;###autoload
136 | (defun dired-toggle-up-directory ()
137 | "Wraper for `dired-up-directory', use `find-alternate-file' instead so will
138 | not create new buffer when changing directory, and will keep `dired-toggle-mode'
139 | and `dired-hide-details-mode' states after opening new direcoty."
140 | (interactive)
141 | (let* ((dired-toggle-enabled (if dired-toggle-mode 1 0))
142 | (dired-hide-details-enabled (if dired-hide-details-mode 1 0))
143 | (dir (dired-current-directory))
144 | (up (file-name-directory (directory-file-name dir))))
145 | (or (dired-goto-file (directory-file-name dir))
146 | ;; Only try dired-goto-subdir if buffer has more than one dir.
147 | (and (cdr dired-subdir-alist)
148 | (dired-goto-subdir up))
149 | (progn
150 | (set-buffer-modified-p nil)
151 | (find-alternate-file "..")
152 | (dired-goto-file dir)))
153 | (when (eq major-mode 'dired-mode)
154 | (dired-toggle-mode dired-toggle-enabled)
155 | (dired-hide-details-mode dired-hide-details-enabled))))
156 |
157 | (defvar dired-toggle-mode-map (make-sparse-keymap)
158 | "Keymap for `dired-toggle-mode'.")
159 |
160 | (defvar dired-toggle-mode-hook nil
161 | "Function(s) to call after `dired-toggle-mode' enabled.")
162 |
163 | (define-minor-mode dired-toggle-mode
164 | "Assistant minor mode for `dired-toggle'."
165 | :lighter dired-toggle-modeline-lighter
166 | :keymap dired-toggle-mode-map
167 | :after-hook dired-toggle-mode-hook)
168 |
169 | (defun dired-toggle--get-window ()
170 | "Get the dired-toggle window."
171 | (let* (target-window)
172 | (dolist (w (window-list))
173 | (when (and (window-live-p w) (buffer-live-p (window-buffer w)))
174 | (with-current-buffer (window-buffer w)
175 | (when (bound-and-true-p dired-toggle-mode)
176 | (setq target-window w)))))
177 | target-window))
178 |
179 | (defun dired-toggle--do (&optional dir file)
180 | "Toggle current buffer's directory.
181 | DIR is the target direcoty, FILE is the file to be selected."
182 | (let* ((file (or file (buffer-file-name)))
183 | (dir (or dir (if file (file-name-directory file) default-directory)))
184 | (win (frame-root-window))
185 | (buf (buffer-name))
186 | (size dired-toggle-window-size)
187 | (side dired-toggle-window-side)
188 | (target-bufname dired-toggle-buffer-name)
189 | (target-buf (get-buffer-create target-bufname))
190 | (target-window (dired-toggle--get-window))
191 | (dired-buffer-with-same-dir (dired-find-buffer-nocreate dir))
192 | (new-dired-buffer-p
193 | (or (not dired-buffer-with-same-dir)
194 | (not (string= target-bufname
195 | (buffer-name dired-buffer-with-same-dir))))))
196 | (if target-window ;hide window if target buffer is shown
197 | (if (one-window-p)
198 | (quit-window)
199 | (delete-window target-window))
200 | ;; Else show target buffer in a side window
201 | (progn
202 | (setq target-window (split-window win (- size) side))
203 | (select-window target-window)
204 | (switch-to-buffer target-buf)
205 | ;; init dired-mode
206 | (if new-dired-buffer-p
207 | (dired-toggle-list-dir target-buf dir))
208 | (with-current-buffer target-buf
209 | (dired-hide-details-mode 1)
210 | ;; TODO mark the referred window that jumping from
211 | (setq-local dired-toggle-refwin win)
212 | ;; try to select target file
213 | (if file
214 | (or (dired-goto-file file)
215 | ;; toggle off omit mode if is on, and try to select file again
216 | (when (and (boundp 'dired-omit-mode) dired-omit-mode)
217 | (dired-omit-mode 0)
218 | (or (dired-goto-file file)
219 | ;; restore omit mode if could not select file again
220 | (dired-omit-mode 1)))))
221 | ;; if cursor at begin of buffer, select the first item
222 | (if (eq (point) 1)
223 | (dired-next-line 1)))))))
224 |
225 | ;;;###autoload
226 | (defun dired-toggle (&optional prefix)
227 | "Toggle current buffer's directory."
228 | (interactive "P")
229 | (if prefix
230 | (dired-toggle-project-root)
231 | (dired-toggle--do)))
232 |
233 | ;;;###autoload
234 | (defun dired-toggle-project-root (&optional prefix)
235 | "Toggle current project root directory."
236 | (interactive "P")
237 | (if prefix
238 | (dired-toggle--do)
239 | (let* ((dir (cdr (project-current 'prompt))))
240 | (dired-toggle--do dir))))
241 |
242 | (provide 'dired-toggle)
243 |
244 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
245 | ;;; dired-toggle.el ends here
246 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fasheng/dired-toggle/7fe5fe35c63d1b0da14d6d6d52bdf6b2a5410ba7/screenshot.png
--------------------------------------------------------------------------------