]> code.delx.au - gnu-emacs-elpa/blob - packages/ztree/ztree-dir.el
Merge commit 'c0de8a8ad0f0abbc12bce35fc4a0feebc8892f48'
[gnu-emacs-elpa] / packages / ztree / ztree-dir.el
1 ;;; ztree-dir.el --- Text mode directory tree -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2013-2016 Free Software Foundation, Inc.
4 ;;
5 ;; Author: Alexey Veretennikov <alexey.veretennikov@gmail.com>
6 ;;
7 ;; Created: 2013-11-11
8 ;;
9 ;; Keywords: files tools
10 ;; URL: https://github.com/fourier/ztree
11 ;; Compatibility: GNU Emacs 24.x
12 ;;
13 ;; This file is part of GNU Emacs.
14 ;;
15 ;; GNU Emacs is free software: you can redistribute it and/or modify
16 ;; it under the terms of the GNU General Public License as published by
17 ;; the Free Software Foundation, either version 3 of the License, or
18 ;; (at your option) any later version.
19 ;;
20 ;; GNU Emacs is distributed in the hope that it will be useful,
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 ;; GNU General Public License for more details.
24 ;;
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
27 ;;
28 ;;; Commentary:
29 ;;
30 ;; Add the following to your .emacs file:
31 ;;
32 ;; (push (substitute-in-file-name "path-to-ztree-directory") load-path)
33 ;; (require 'ztree-dir)
34 ;;
35 ;; Call the ztree interactive function:
36 ;; M-x ztree-dir
37 ;; Open/close directories with double-click, Enter or Space keys
38 ;;
39 ;;; Issues:
40 ;;
41 ;;; TODO:
42 ;; 1) Add some file-handling and marking abilities
43 ;;
44 ;;; Code:
45
46 (require 'ztree-util)
47 (require 'ztree-view)
48 (eval-when-compile (require 'cl-lib))
49
50 ;;
51 ;; Constants
52 ;;
53
54 (defconst ztree-hidden-files-regexp "^\\."
55 "Hidden files regexp.
56 By default all filest starting with dot '.', including . and ..")
57
58 ;;
59 ;; Configurable variables
60 ;;
61
62 (defvar ztree-dir-move-focus nil
63 "If set to true moves the focus to opened window when the
64 user press RETURN on file ")
65
66 (defvar-local ztree-dir-filter-list (list ztree-hidden-files-regexp)
67 "List of regexp file names to filter out.
68 By default paths starting with dot (like .git) are ignored.
69 One could add own filters in the following way:
70
71 (setq-default ztree-dir-filter-list (cons \"^.*\\.pyc\" ztree-dir-filter-list))
72 ")
73
74 (defvar-local ztree-dir-show-filtered-files nil
75 "Show or not files from the filtered list.")
76
77
78 ;;
79 ;; Faces
80 ;;
81
82 (defface ztreep-header-face
83 '((((type tty pc) (class color)) :foreground "lightblue" :weight bold)
84 (((background dark)) (:height 1.2 :foreground "lightblue" :weight bold))
85 (t :height 1.2 :foreground "darkblue" :weight bold))
86 "*Face used for the header in Ztree buffer."
87 :group 'Ztree :group 'font-lock-highlighting-faces)
88 (defvar ztreep-header-face 'ztreep-header-face)
89
90
91 (define-minor-mode ztreedir-mode
92 "A minor mode for displaying the directory trees in text mode."
93 ;; initial value
94 nil
95 ;; modeline name
96 " Dir"
97 ;; The minor mode keymap
98 `(
99 (,(kbd "H") . ztree-dir-toggle-show-filtered-files)))
100
101
102
103
104 ;;
105 ;; File bindings to the directory tree control
106 ;;
107
108 (defun ztree-insert-buffer-header ()
109 "Insert the header to the ztree buffer."
110 (let ((start (point)))
111 (insert "Directory tree")
112 (insert "\n")
113 (insert "==============")
114 (set-text-properties start (point) '(face ztreep-header-face)))
115 (insert "\n"))
116
117 (defun ztree-file-not-hidden (filename)
118 "Determines if the file with FILENAME should be visible."
119 (let ((name (ztree-file-short-name filename)))
120 (and (not (or (string= name ".") (string= name "..")))
121 (or
122 ztree-dir-show-filtered-files
123 (not (cl-find-if (lambda (rx) (string-match rx name)) ztree-dir-filter-list))))))
124
125
126 (defun ztree-find-file (node hard)
127 "Find the file at NODE.
128
129 If HARD is non-nil, the file is opened in another window.
130 Otherwise, the ztree window is used to find the file."
131 (when (and (stringp node) (file-readable-p node))
132 (cond ((and hard ztree-dir-move-focus)
133 (find-file-other-window node))
134 (hard
135 (save-selected-window (find-file-other-window node)))
136 (t
137 (find-file node)))))
138
139
140 (defun ztree-dir-toggle-show-filtered-files ()
141 "Toggle visibility of the filtered files."
142 (interactive)
143 (setq ztree-dir-show-filtered-files (not ztree-dir-show-filtered-files))
144 (message (concat (if ztree-dir-show-filtered-files "Show" "Hide") " filtered files"))
145 (ztree-refresh-buffer))
146
147
148
149
150 ;;;###autoload
151 (defun ztree-dir (path)
152 "Create an interactive buffer with the directory tree of the PATH given."
153 (interactive "DDirectory: ")
154 (when (and (file-exists-p path) (file-directory-p path))
155 (let ((buf-name (concat "*Directory " path " tree*")))
156 (ztree-view buf-name
157 (expand-file-name (substitute-in-file-name path))
158 #'ztree-file-not-hidden
159 #'ztree-insert-buffer-header
160 #'ztree-file-short-name
161 #'file-directory-p
162 #'string-equal
163 (lambda (x) (directory-files x 'full))
164 nil ; face
165 #'ztree-find-file) ; action
166 (ztreedir-mode))))
167
168
169
170 (provide 'ztree-dir)
171 ;;; ztree-dir.el ends here