Roife
1
日常使用 emacs 时,我习惯开大量的 buffer,并用 C-x b 进行切换。这些文件来自多个项目/目录,并且有很多文件会重名。例如我进行 rust 项目开发时,就可能会打开多个 crates 的 lib.rs
。
虽然 Emacs 自带的 buffer-name 有一套针对同名文件的注释机制,但是这个机制只会利用上层文件夹的不同名字加标记,很多时候我依然找不到想要的文件。我觉得更好的机制是直接使用相对项目根目录的路径作为项目名,例如 ~/github/rust-project/crates/xxx/lib.rs
使用 rust-project/crates/xxx/lib.rs
。
电报群的群友推荐了这个 package,我试了一下非常好用,所以来分享一下:
配置:
(use-package buffer-name-relative
:straight (:host codeberg :repo "ideasman42/emacs-buffer-name-relative")
:hook (after-init . buffer-name-relative-mode)
:config
(setq buffer-name-relative-prefix '("" . "/")))
3 个赞
不知道这个能不能满足你? 它是 built-in 的:
;; 多个同名 buffer 时的设置
(use-package uniquify
:custom
(uniquify-buffer-name-style 'reverse)
(uniquify-separator " • ")
(uniquify-after-kill-buffer-p t)
(uniquify-ignore-buffers-re "^\\*"))
Roife
3
我希望没有同名的情况下也进行重命名🤣 这样方便和 consult 配合。因为 consult 中默认会在 C-x b 里面展示 recentf 的列表,所以就算我没有打开同名的文件,但是已经打开的 buffer 也有可能会历史记录里面的某个文件同名
consult+marginlia 完全能看出来吧?
wsug
6
可以像其它编辑器(vsc,notepad+)一样把文件的根目录显示在buffer最上方,我显示在header-line,切换buffer用
counsel-switch-buffer`
kinono
8
如果只是想用 consult 过滤的时候可以输入路径的话,可以试试这个 advice:
(defun my-project-root ()
(when-let ((project (project-current nil)))
(if (fboundp #'project-root)
(project-root project)
(car (project-roots project)))))
(define-advice consult--buffer-pair (:around (_ buffer) show-path)
"Also show path for file buffers so the user can filter them by path."
(let ((dir (or (my-project-root) default-directory)))
(if-let ((path (buffer-file-name buffer)))
(progn (when (file-in-directory-p path dir)
(setq path (file-relative-name path dir)))
(cons path buffer))
(cons (buffer-name buffer) buffer))))
我没有修改 buffer name 的原因是我的 tab-bar 里面要用它们作为 tab 的名字。
3 个赞
不错的包,代码写得也比较整洁,除了每个函数头上的 (declare (important-return-value nil))
不知道是什么作用。目前的个人配置:
(use-package buffer-name-relative
:diminish
:commands buffer-name-relative-mode
:config
(setq buffer-name-relative-prefix '("<" . "> ")
buffer-name-relative-fallback 'default)
(defun buffer-name-relative-root-path-from-project (filepath)
"Return the PROJECT directory from FILEPATH or nil."
(let ((result nil))
(when (fboundp 'project-root)
(let ((dir (if (file-directory-p filepath)
(directory-file-name filepath)
(file-name-directory filepath))))
(when dir
(condition-case-unless-debug err
(setq result (project-root (project-current nil dir)))
(error (message "Error finding PROJECT root name: %s" err))))))
result))
(setq buffer-name-relative-root-functions '(buffer-name-relative-root-path-from-project)))
1 个赞
用了一段时间,感觉 buffer-name-relative 很容易导致我的 buffer-name 过长,在 modeline 中的显示效果很不好 , 所以目前弃用了。现在用的是楼上推荐的 consult 过滤 advice。