Dirvish: 基于 Dired 的极简、一站式文件管理器

不敢当不敢当,非常感谢你的安利,吹的都有点过头了哈哈

对的,你理解到了。

顺便报个bug:Invalid face attribute :inherit (mode-line-active)。看了下是dirvish-core.el Line 53 有问题。

这个已经修了,你更新到最新的应该就好了

现在 dirvish-side 应该不会被 delete-other-windows 关掉了。

另外 ace-window 的问题,是因为我一直用的 ace-select-window, 这个命令是尊重 window 的 no-other-window 参数的,但是 ace-window 不会。

dirvish 会打开好多buffer。。。 buffer不能复用么? 我预览了一下我的项目后,发现打开好多buffer

其实 README 里面有写 Dirvish 的 buffer 管理机制,但是我还是详细说一下,因为你对 Dired 的 buffer 复用可能有一些误解。

Dired

Dired 的默认情况是每访问一个路径就新开一个 Dired buffer,如果重复访问某个路径,就会 复用 已经存在的 Dired buffer,这是合理的。可是要命的是这些 buffer 不会自己关掉。你要退出要不停的按 q

对这个问题 Dired 给出了 dired-kill-when-opening-new-dired-buffer (> Emacs 28) 这个选项和 dired-find-alternate-file 这个命令,意思是访问新路径时杀掉当前窗口的旧 Dired buffer,来保证你浏览文件系统的过程中只有一个 Dired buffer 存在。

不过请注意这恰恰破坏了 Dired 原本的 复用 机制。假设你在 ~/foo/bar 展开了一些文件夹,标记了一些文件,当你 dired-up-directory~/foo, ~/foo/bar 就被杀掉了。你再进去,这些标记和折叠状态就没了。如果 ~/foo/bar 是一个很大的文件夹 (比如包含 100000 个文件打开要 2 秒),那你每次访问,每次都要等 2 秒。

Dirvish

Dirvish 是以会话 (session) 的形式存在的。每一个会话包含自己独立的 dirvish-mode buffer 列表,它不会在访问新路径时杀掉旧的 buffer,所以复用机制和 Dired 在不开 dired-kill-when-opening-new-dired-buffer 这个选项的情况时是一致的。 不同的是当你按 q 退出这个会话时,这些 dirvish-mode buffer 就被杀掉了,免去你一直按 q 的麻烦。预览 buffer 的情况也是类似的,按 q 的时候一起杀掉。你也可以利用外部命令来预览文本文件,从而完全避免预览 buffer 的创建,但这是另一个话题了。

Edit: 另外值得一说的是 doom-emacs 的解决办法,它就是在你按 q 的时候不管三七二十一把所有 Dired buffer 都杀掉。好处是简单粗暴,坏处是其他 window/tab/frame 里面的 Dired buffer 也会莫名其妙的被删掉。

我在 doom-emacs 里面,按 q 的时候是会调用它自定义的方法 +dired/quit-all ,有时候就会抛错:

Debugger entered--Lisp error: (wrong-type-argument dirvish nil)
  dirvish-deactivate(nil)
  dirvish-quit-h()
  funcall(dirvish-quit-h)
  (condition-case e (funcall hook) ((debug error) (signal 'doom-hook-error (list hook e))))
  doom-run-hook(dirvish-quit-h)
  run-hook-wrapped(doom-run-hook dirvish-quit-h)
  (condition-case e (run-hook-wrapped hook #'doom-run-hook) ((debug doom-hook-error) (if debug-on-error nil (lwarn hook :error "Error running hook %S because: %s" (if (symbolp (car (cdr e))) (symbol-name (car (cdr e))) (car (cdr e))) (car (cdr (cdr e))))) (signal 'doom-hook-error (cons hook (cdr e)))))
  (let ((hook (car --dolist-tail--))) (condition-case e (run-hook-wrapped hook #'doom-run-hook) ((debug doom-hook-error) (if debug-on-error nil (lwarn hook :error "Error running hook %S because: %s" (if (symbolp (car ...)) (symbol-name (car ...)) (car (cdr e))) (car (cdr (cdr e))))) (signal 'doom-hook-error (cons hook (cdr e))))) (setq --dolist-tail-- (cdr --dolist-tail--)))
  (while --dolist-tail-- (let ((hook (car --dolist-tail--))) (condition-case e (run-hook-wrapped hook #'doom-run-hook) ((debug doom-hook-error) (if debug-on-error nil (lwarn hook :error "Error running hook %S because: %s" (if (symbolp ...) (symbol-name ...) (car ...)) (car (cdr ...)))) (signal 'doom-hook-error (cons hook (cdr e))))) (setq --dolist-tail-- (cdr --dolist-tail--))))
  (let ((--dolist-tail-- hooks)) (while --dolist-tail-- (let ((hook (car --dolist-tail--))) (condition-case e (run-hook-wrapped hook #'doom-run-hook) ((debug doom-hook-error) (if debug-on-error nil (lwarn hook :error "Error running hook %S because: %s" (if ... ... ...) (car ...))) (signal 'doom-hook-error (cons hook (cdr e))))) (setq --dolist-tail-- (cdr --dolist-tail--)))))
  doom-run-hooks(quit-window-hook)
  apply(doom-run-hooks quit-window-hook)
  run-hooks(quit-window-hook)
  apply(run-hooks quit-window-hook)
  #<subr quit-window>(nil)
  apply(#<subr quit-window> nil)
  quit-window(nil)
  apply(quit-window nil)
  +dired/quit-all(nil)
  funcall-interactively(+dired/quit-all nil)
  command-execute(+dired/quit-all)

另外,我在 doom-one-dark 主题下,预览时的颜色不适配,这个怎么解:

这个问题我没遇到,你能稳定复现这个错误吗? 我试着修复了一下,你更新到最新看还会不会遇到这个问题

要么改这个颜色

(set-face-attribute 'ansi-color-blue nil :foreground "#FFFFFF") 

要么直接用 dired 预览

(setq dirvish-preview-dispatchers (remove 'directory-exa dirvish-preview-dispatchers))
1 个赞

好的,我再试试看能不能复现

何不考虑直接用ls或者gls预览?这样不会有exa的颜色问题

也行,我就是不知道 windows 上面怎么样。目前默认是 windows 直接 dired。

你有 windows 环境吗? 有的话帮我看看这个在windows上有没有问题,没什么问题我就把默认换成这个。谢了。

(dirvish-define-preview directory-ls (file)
  "Uses `ls' to generate directory preview."
  (when (file-directory-p file)
    `(shell . ("ls" ,@(split-string dired-listing-switches) "--color=always" ,file))))

(add-to-list 'dirvish-preview-dispatchers 'directory-ls)

我目前也没有用Windows。根据经验,windows上默认用dired是最好的,默认是没有ls的。

左侧是 treemacs 中光标所在行的背景色,怎么能也设置成这种呢,dirvish 这个背景一个是在 icon 哪里不连贯,再一个选中多个时候连成一片有点刺眼,和主题不太搭。

或者未选中的时候,没有颜色,选中的时候使用 dired 选中的样式: 光标在的时候:

选中行的时候:

你的 dirvish-attributes 的值是什么啊? 如果是 nil 的话,那你这个 icon 就不是 dirvish 提供的。

我这边打开是这样的。就 doom 默认配置加上这一行

(setq! dirvish-attributes '(all-the-icons file-size))

你这个好像是自己特殊配置过 all-the-icons-dired ?

是的,因为一开始没有图标,就启动了 all-the-icons-dired-mode

image

另外,这个高亮的颜色支持修改吗,我想改的和选中的那个颜色一样,看着统一一点

不然,单行选中和多行选中看着不一样

你试试看

(setq! dirvish-face-remap-alist
  '((header-line :height 1.04 :box (:line-width 4 :color "#303030"))
    (highlight :inherit (diredfl-flag-mark) :extend t)))

不知道你是不是这个意思

你那个文件名那里怎么颜色不一样啊? 你特意改的吗

和之前比是起了变化,但是不是想要

我没改啥,文件夹哪里,我正常光标放在哪里是和你上面的图是一样,mark之后,就是我图里的样子了

header-line 的颜色可以了

1 个赞