我一直不太清楚怎么像 tree(1)
那样画目录结构,今天上午发现了一个专门处理树状结构数据的库:
我用它以树状图的方式展示 Git 项目,比如我的 Emacs 配置:
(上图中的 lisp
目录被我折叠了,因为其下的文件太多了,不方便截图)
代码
(defun chunyang-git-tree ()
(interactive)
(require 'hierarchy)
(let ((files (split-string
(shell-command-to-string "git ls-files -z")
(string 0) t))
(hierarchy (hierarchy-new)))
;; Fill the hierarchy
(hierarchy-add-trees
hierarchy
;; Set . as the root since tree-widget.el requires only one root
(mapcar (lambda (f) (concat "./" f)) files)
(lambda (f)
"Return parent directory of F."
(if (directory-name-p f)
(file-name-directory (directory-file-name f))
(file-name-directory f))))
;; Draw the hierarchy
(switch-to-buffer
(hierarchy-tree-display
hierarchy
(lambda (f _)
"Insert basename of F."
(insert
(if (directory-name-p f)
(file-name-nondirectory (directory-file-name f))
(file-name-nondirectory f))))))
;; Unfold
(goto-char (point-min))
(while (progn (widget-button-press (point))
(widget-forward 1)
(/= (point) (point-min))))))
目前的实现就是这样,但还有不少值得改进的地方,比如:
- 一个 Git 项目对应一个独立 Buffer
- 用 Side Window 展示这个 Buffer,像 IDE 那样
- 设置 Tree Widget 中的 Action,即打开文件
- 排序(上图中貌似正好是倒着排的)