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

你之前有写只支持 vertico/selectrum 后面去掉了,我以为不依赖了呢

谢谢懒猫哥 :grin:。 其实我最早的时候是想用 EAF 预览图片的,性能比较好,不像 Dirvish 现在这样还要先缓存比较大的图片才能不卡。可是那个时候我没在 EAF 里面找到类似 find-file-noselect 这样的返回一个 buffer 的接口,就作罢了。

在EAF中用 find-file-noselect ? 这样用的目的是啥, 好奇一下。

对,我开发EAF文件管理器最主要的目的是看图片,因为有时候拍了很多图片,要把那些拍的不好的mark以后统一删除。

传统的 dired, 看一张返回一下很麻烦

Gnome这种文件管理器也是要弹出一个图片预览窗口,发现不好看的图片时再返回文件管理器又找不到是哪一张图片,这时候对比文件名异常痛苦。

最后我发现 ranger 这种双栏设计,特别适合批量管理图片,一直按J去看下一张图片,遇到不好的就顺手 mark 一下,全部看完统一删除。

不好意思我没讲清楚,不是要在 EAF 里面用这个函数,说的是我想用 EAF 作为 Dired 的图片预览器。因为那个时候还没有 EAF 文件管理器,不过是有 eaf-open 这个函数的。但是他每次会打开一个窗口,我想要的是只给我 buffer,然后我放到我已经开好的预览窗口里。

可以参考 EAF RSS Reader 的做法:

  1. 首先弄一个特定名称的Buffer(也就是你说的preview buffer)
  2. 每次更换文件的时候,切换到 preview buffer, 传递一个文件 URL 进去
  3. 然后利用 EAF file manager eaf-file-manager/src/components at master · emacs-eaf/eaf-file-manager · GitHub 里面的 Preview 组件加载特定的 JavaScript 库就行了

这样做既可以左边用 Dired, 右边用EAF来预览。

EAF预览的好处是可以用很多现成的JavaScript库快速渲染不同的多媒体文件不会卡住Emacs(因为是在EAF的Python进程中),传统的Emacs异步进程的方法主要是利用外部工具生成缓存的方式,代码写的很复杂,同时如果外部进程和Emacs交换数据比较多的时候也会卡一下。

我之所以不用Dired混合EAF的方式,主要我真的太讨厌 Dired 那一堆 hacking way 的插件了,维护起来太麻烦,现在的EAF文件管理器基本上替换了我以前所有Dired的功能(包括wdired、find、mark、copy、move、 delete、sort等等),还附加了预览、多线程、图标、左右对齐和Git等功能,扩展起来比Dired这种方式要清晰很多。

我之所以不用Dired混合EAF的方式,主要我真的太讨厌 Dired 那一堆 hacking way 的插件了,维护起来太麻烦

确实如此。要让 dired 和大家写的那些插件配合起来实在太难了。dired.el 就不是为这个时代的文件管理器写的东西,每次看那些 regex 的东西都头大。可是架不住大家都要拿它当画布涂涂改改,插件和插件之间冲突是家常便饭。这和 magit 这种顶层就考虑好的东西很不一样。我也考虑过要不要像 treemacs 那样写个新的,后来想想算了,也不会好到哪里去,毕竟还有 Emacs 的图形能力在制约。不过好处是这个东西这么多年大家也接受了,简单使用的话也没有什么配置成本。

可以参考 EAF RSS Reader 的做法:

你说的这个我下次用 EAF 的时候一定试试看,不懂再来问你 :grimacing:

加油, dired 能被你改成这样,已经非常不容易了。

Dired 也有他的好处就是整个Buffer都是Text, 可以利用Emacs很多内在的插件相互协调。

感谢大佬鼓励 :fist:

底下的菜单是怎么弄的?

dirvish-dispatch

话说dispatch这个词语在编程里面到底是有什么特殊意义吗,我记得在C++多线程里面,有个dispatch函数,可以线程将会变为不可join,一直运行到退出,而且之前也在许多的例程里面见过。

一般是在 visitor design pattern 里会出现这个吧。我这里用这个词只是因为这个菜单起到的作用和 magit-dispatch 比较像,就沿用了。

woo, 原来如此,非科班,设计模式到现在还没有学过 :grin:

请教一下, dirvish 有可以记录最近打开目录的 hook 吗?

比如dired recentfiles这里提到 dired 可以用dired-after-readin-hook

你发的这个链接里的

(add-hook 'dired-after-readin-hook 'recentd-track-opened-file)
(add-hook 'kill-buffer-hook 'recentd-track-closed-file)

不是直接就能用吗。dired 本身的 hook 和 dirvish 是兼容的。

(ring-elements dirvish--history-ring) 是 dirvish 的访问历史。

另外还有 dirvish-show-history 命令。

1 个赞

感谢,因为一直尝试的第二种:

(add-hook 'dired-after-readin-hook 'recentf-track-opened-file)))

这个方法,在 dired 里面可以,在 dirvish 里面不可行,以为 dirvish 不能用这个hook

结果换函数recentd-track-opened-file后可行了

用了几次,想替代neotree,不知道是不是不会配置,总有点奇怪。有几个问题。

  1. dirvish-side的scope目前似乎不支持buffer, 也就是说如果我同时在一个frame中编辑本地和远程两个文件, 那么使用dirvish-side来浏览的时候,如果先打开了本地的目录,那么只要在在这个tab中就一直是本地的目录。而不会随着当前编辑文件的改变而自动follow工作目录? 这个更像是treemac的思路?不知道有办法来实现neotree那种neo-smart-open的跟踪功能么?

  2. 如果换另一种思路,不使用dirvish-side而使用dirvish, 同时将depth设置为1,那么在编辑远程的时候会遇到的问题是默认tramp上的预览不会自动打开。 于是就很尴尬。而如果使用dirvish-side, 设置的attribute也不会生效, 可能是考虑到 vc-state和file-icon这种在远程访问时会有些慢?有没有办法可以使得attribute在dirvish-side的窗口中在远程也生效?

emacs小白, 如果问题太弱智请包涵。

不知道有办法来实现neotree那种neo-smart-open的跟踪功能么?

这个应该不难实现。我等会加一个。

同时将depth设置为1

不用设置这个,远程连接会强制使用 0,也就是不显示父目录,少点性能开销。

编辑远程的时候会遇到的问题是默认tramp上的预览不会自动打开

这个相对于本地预览要特殊处理一下,不然很卡。之前说要写忘记了。

设置的attribute也不会生效, 可能是考虑到 vc-state和file-icon这种在远程访问时会有些慢?

是的,涉及到 I/O, 很慢。不过也许可以给个选项,让连接速度快的或者 host 在本地网络的可以试试看。

emacs小白, 如果问题太弱智请包涵。

没有,你提的东西挺有价值的。

1 个赞

加了两个选项

;; 对应于 neo-smart-open
(setq dirvish-side-follow-buffer-file t)

;; 使 remote host 使用和本地一样的特性。(默认 nil)
;; warning: 除非你的 ssh 非常快,否则你会感到严重延迟。
(setq dirvish-enabled-features-on-remote '(extras vc))

另外 tramp 的文件预览也就位了。

Peek 2022-04-15 17-13

1 个赞