├── README.org ├── dired-toggle.el └── screenshot.png /README.org: -------------------------------------------------------------------------------- 1 | #+HTML: MELPA 2 | #+HTML: MELPA Stable 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 --------------------------------------------------------------------------------