Emacs 快速切换 buffer

在 Emacs 中管理 buffer 一直让我很头疼 我喜欢在 Emacs 中开多个文件,但是切换起来往往很麻烦 我不喜欢记文件的名字,因此在切换 buffer 时往往要找半天 除了 Tabbar 以外,一些编辑器(如 ST)将打开的文件显示在侧边栏的设置我很喜欢 有类似的插件可以实现这些功能吗?

1 个赞

Speedbar,内置的,能显示文件,也能用来管理缓冲区,还能用来显示 imenu 的索引。

不过从来没试过。在 Emacs 里面各种 bar 都是邪教,尤其是对于以避免使用鼠标来提高效率的用户来说。而且对于 GNU/Emacs 来说,所有 buffer 都是混在一块的,工具占用的 buffer 可能遭致混乱。

Speedbar 默认是新开一个 frame,如果不习惯,有 sr-speedbar 可以设置为 split window。

1 个赞

见: Spacemacs 文件跳转怎么使用最佳? - #10,来自 frapples

可以看看 (emacs) Buffers 中介绍的一些方法

我不了解 Tabbar 和 ST,既然你喜欢它们的话,就用它们,因为即便 Emacs 有类似的插件,你可能又会觉得没有 Tabbar 和 ST 的好。

主要是如果我打开了五六个文件,然后记不住名字 切换的时候要先 C-x b 然后找到对应的 buffer 健入后才能切换 我希望有一个可以始终显示 buffer 的插件

每次切换忘了 buffer 名字后都要先预览所有buffer 再输入,我觉得如果有一个地方能一直显示 buffer 列表的话会更好

我用hydra,感觉也很快。

(defhydra hydra-skan-user-buffers-next (:body-pre (my/next-user-buffer)
                                                  :hint nil)
  "skan user buffers"
  ("]" my/next-user-buffer)
  ("[" my/previous-user-buffer)
  ("k" kill-this-buffer)
  ("q" nil))
(defhydra hydra-skan-user-buffers-prev (:body-pre (my/previous-user-buffer)
                                                  :hint nil)
  "skan user buffers"
  ("]" my/next-user-buffer)
  ("[" my/previous-user-buffer)
  ("k" kill-this-buffer)
  ("q" nil))
(global-set-key (kbd "C-x ]") 'hydra-skan-user-buffers-next/body)
(global-set-key (kbd "C-x [") 'hydra-skan-user-buffers-prev/body)

my/next-user-buffer 可以根据自己需要定义,比如排除带星号的buffer,排除特定mode的buffer等。也可以直接用 自带的 next-buffer

有的被修改的buffer无法切换,就需要切换前保存一下,可以用advice修改switch-to-buffer的行为。

(defadvice switch-to-buffer (before save-buffer-now activate)
  (when buffer-file-name (save-buffer)))
(defadvice ido-switch-buffer (before save-buffer-now activate)
  (when buffer-file-name (save-buffer)))

这样按一下 C-x ],然后连续按 [ 或 ] 就可以快速的浏览buffer了,中途可以随时 按 k 关掉buffer。

1 个赞

如果是鼠标党,有个可点击的列表,确实方便一些。在我看来 Buffers 菜单已经符合需求,伸手就能够得着,也不用打字/记忆,可为什么还要在屏幕上开辟一块区域,持久地展示它?

这也许就是习惯的力量吧,有个随时看得见的侧栏,内心更笃定?

作为键盘党,平时都习惯了整个屏幕都是编辑区,对侧栏相关的扩展了解有限。

neotree/dirtree 等类似扩展,都只是显示文件树。

speedbar/sr-speedbar 倒是又 buffer list,但它不能同时显示文件树。buffer 与树不可兼得,只能在两种状态下切换,跟 VSCode 这些编辑器还是有些不同:

Emacs speedbar

+--------+------------------+          +--------+------------------+
|        |                  |  switch  |        |                  |
| buffer |                  | -------> | file   |                  |
| list   |                  | <------- | tree   |                  |
|        |                  |          |        |                  |
|        |                  |          |        |                  |
|        |                  |          |        |                  |
|        |                  |          |        |                  |
+--------+------------------+          +--------+------------------+

VSCode

+--------+------------------+
|        |                  |
| buffer |                  |
| list   |                  |
|--------|                  |
| file   |                  |
| tree   |                  |
|        |                  |
+--------+------------------+

最后想到在 Emacs 界失传已久的 ECB(Emacs Code Browser),曾经是各种入门配置文章必讲的扩展:

+--------+------------------+
| dir    |                  |
| tree   |                  |
|--------|                  |
| file   |                  |
| list   |                  |
|--------|                  |
| member |                  |
| list   |                  |
|--------|                  |
| buffer |                  |
| list   |                  |
+--------+------------------+

Speedbar 就是能一直显示的侧边栏啊

失传原因:

“不符合Emacs哲学”

spacemacs里习惯打开多个工程项目的上百个buffer,如果使用buffer标签页类似的东西,界面显示会很难看。

spacemacs里有个菜单选项叫Perspectives,翻译过来就是视角。Perspectives和layout的关系,我还没弄清楚。 个人理解,

  1. layout,用来解决“重启spacemacs,可以使用SPC l L快速打开之前打开的所有buffer和窗口布局”;
  2. Perspectives,就是不同视角,去浏览buffer和使用窗口布局。
  3. 一个layout可以定义N个Perspectives。
  4. layout可以保存为文本,方便下次重启恢复。

现在,我只创建一个layout,在这个layout下创建了N个Perspectives,每个Perspectives有N个buffer,可以使用SPC l b去查阅。 好处是:

  1. buffer分类很清晰;
  2. 每次重启spacemacs可以快速回归上一次的编辑状态。
  3. 如果项目过期,我会新建一个layout。

网上,也找不到类似太多的介绍,不过我自己很喜欢这样的操作方式。如果有人熟悉Perspectives和layout的关系,请一定告诉我。谢谢

3 个赞

譬如我用了 Tabbar 打开了A B C三个文件 那么我可以直接用 s-1 s-2 s-3 切换 然后用buffer只能输入名字然后切换 就算是 ace-jump-buffer 也要先看清字母然后按下键跳转 显然要慢很多

如果开了数十个乃至近百个缓冲就 GG 了。 个人习惯嘛,很难说服的。

平时不会开那么多。。。 所以希望是两种方式可以混用

我将 s-left 映射到 'previous-buffer 和 s-right 映射到 'next-buffer 现在对我来说效果很好

(global-set-key (kbd "s-<left>") 'previous-buffer)
(global-set-key (kbd "s-<right>") 'next-buffer)

Edit: ignore useless buffers with asterisks (such as *Messages*) while switching buffers

;; ignore useless buffers while switching (set-frame-parameter (selected-frame) 'buffer-predicate (lambda (buf) (not (string-match-p “^*” (buffer-name buf)))))

It works better now!!

3 个赞

如果是spacemacs的话,Spc b i, ibuffer, https://i.imgur.com/mrKPFnz.png

我在spacemacs里,试了一下,打开了100个buffer,每个文件大小也就几KB的样子。 公司是linux,家里是windows;打开100个buffer,内存占用也就150MB的样子。 我记得子龙山人说过,他的buffer是几千个。

如果有兴趣,可以把一个工程的所有源代码,选中后鼠标拖进spacemacs里,看看CPU/内存资源占用的情况。

buffer list 只适合少量的文件,如果打开的文件多到屏幕放不下,buffer list 就鸡肋了。也不是 previous-buffer/next-buffer 映射快捷键能解决的,如果按快捷超过5下才能找到你要的 buffer,效率就低了,同时你要高度关注切换到屏幕上的内容。

还是要回归到键盘,通过文件/buffer名字查找,或者用鼠标操作文件树。

不是 ~c-c b~ 吗?

感觉 Emacs 内置的 ibuffer 就挺好用的。

如无必要,勿增实体。

我深度怀疑 helm-buffer 之类的插件,其实是把内置的功能削弱了。