branch: master
commit aa7f07a096704244c530c649741ed9c3999f07ee
Author: Alexey Veretennikov <[email protected]>
Commit: Alexey Veretennikov <[email protected]>
Added Backspace support
---
README.md | 2 +-
ztree.el | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 56 insertions(+), 10 deletions(-)
diff --git a/README.md b/README.md
index 0c67b9c..ccb4d33 100644
--- a/README.md
+++ b/README.md
@@ -19,4 +19,4 @@ Call the `ztree` interactive function:
M-x ztree
```
-Open/close directories with double-click, `RET` or `Space` keys.
+Open/close directories with double-click, `RET` or `Space` keys. To jump to
the parent directory, hit `Backspace` key.
diff --git a/ztree.el b/ztree.el
index 4391b95..231c8e5 100644
--- a/ztree.el
+++ b/ztree.el
@@ -37,9 +37,8 @@
;;; Issues:
;;
;;; TODO:
-;; 1) bind Backspace to close current directory
-;; 2) Add some file-handling and marking abilities
-;; 3) More syntax highlighting
+;; 1) Add some file-handling and marking abilities
+;; 2) More syntax highlighting
;;
;;
;;; Change Log:
@@ -68,6 +67,16 @@
"List of regexp for file/directory names to filter out")
(make-variable-buffer-local 'ztree-filter-list)
+(defvar ztree-start-line nil
+ "Index of the start line - the root")
+(make-variable-buffer-local 'ztree-start-line)
+
+(defvar ztree-parent-lines-array nil
+ "Array of parent lines, there the ith value of the array
+is the parent line for line i. If ith value is i - it is the root
+line")
+(make-variable-buffer-local 'ztree-parent-lines-array)
+
;;
;; Major mode definitions
;;
@@ -78,6 +87,9 @@
(define-key map (kbd "SPC") 'ztree-perform-action)
(define-key map [double-mouse-1] 'ztree-perform-action)
(define-key map (kbd "g") 'ztree-refresh-buffer)
+ (if window-system
+ (define-key map (kbd "<backspace>") 'ztree-move-up-directory)
+ (define-key map "\177" 'ztree-move-up-directory))
map)
"Keymap for `ztree-mode'.")
@@ -128,6 +140,13 @@ filename for the line specified"
"Find if the directory is in the list of expanded directories"
(ztree-find ztree-expanded-dir-list #'(lambda (x) (string-equal x dir))))
+
+(defun ztree-set-parent-for-line (line parent)
+ (aset ztree-parent-lines-array (- line ztree-start-line) parent))
+
+(defun ztree-get-parent-for-line (line)
+ (aref ztree-parent-lines-array (- line ztree-start-line)))
+
(defun scroll-to-line (line)
"Recommended way to set the cursor to specified line"
(goto-char (point-min))
@@ -155,6 +174,18 @@ filename for the line specified"
ztree-expanded-dir-list))
(push dir ztree-expanded-dir-list)))
+
+(defun ztree-move-up-directory ()
+ "Action on Backspace key: to jump to the line of a parent directory"
+ (interactive)
+ (when ztree-parent-lines-array
+ (let* ((line (line-number-at-pos (point)))
+ (parent (ztree-get-parent-for-line line)))
+ (scroll-to-line parent))))
+
+
+
+
(defun file-basename (file)
"Base file/directory name. Taken from
http://lists.gnu.org/archive/html/emacs-devel/2011-01/msg01238.html"
(file-name-nondirectory (directory-file-name file)))
@@ -225,11 +256,26 @@ apparently shall not be visible"
(ztree-draw-horizontal-line (+ 3 (* offset 4))
(+ 7 (* offset 4))
child)))))))
+
+(defun ztree-fill-parent-array (tree)
+ ;; set the root line
+ (let ((root (car tree))
+ (children (cdr tree)))
+ (dolist (child children)
+ (if (atom child)
+ (ztree-set-parent-for-line child root)
+ (progn
+ (ztree-set-parent-for-line (car child) root)
+ (ztree-fill-parent-array child))))))
-
+
(defun ztree-insert-directory-contents (path)
;; insert path contents with initial offset 0
- (let ((tree (ztree-insert-directory-contents-1 path 0)))
+ (let ((tree (ztree-insert-directory-contents-1 path 0))
+ (num-of-items (- (line-number-at-pos (point)) ztree-start-line)))
+ (setq ztree-parent-lines-array (make-vector num-of-items 0))
+ (ztree-set-parent-for-line ztree-start-line ztree-start-line)
+ (ztree-fill-parent-array tree)
(ztree-draw-tree tree 0)))
@@ -247,8 +293,7 @@ apparently shall not be visible"
(when (not (or (string-equal short-dir-name ".")
(string-equal short-dir-name "..")
(ztree-file-is-in-filter-list short-dir-name)))
- (push (ztree-insert-directory-contents-1 dir (1+ offset))
- children))))
+ (push (ztree-insert-directory-contents-1 dir (1+ offset))
children))))
(dolist (file files)
(let ((short-file-name (file-basename file)))
(when (not (ztree-file-is-in-filter-list short-file-name))
@@ -284,7 +329,8 @@ apparently shall not be visible"
(insert "Directory tree")
(newline)
(insert "==============")
- (newline))
+ (newline)
+ (setq ztree-start-line (line-number-at-pos (point))))
(defun ztree-refresh-buffer (&optional line)
@@ -296,7 +342,7 @@ apparently shall not be visible"
(erase-buffer)
(ztree-insert-buffer-header)
(ztree-insert-directory-contents ztree-start-dir)
- (scroll-to-line (if line line 3))
+ (scroll-to-line (if line line ztree-start-line))
(toggle-read-only)))