为什么Vim专家更喜欢缓冲区而不是标签?

2c2*_*c2c 210 vi vim

不懂缓冲区.当我在同一个选项卡上打开3个文件并关闭我的窗口时,我一般都很恼火地发现下次打开其中一个文件时,有一些奇怪的交换文件挥之不去,给我一些麻烦的消息.但是我一次又一次地读到这些东西是我错过的生产力必杀技,而且这些标签是为了让平民使用.

所以我问你,Vim专家:在标签上使用缓冲区有什么好处?我不知道差异有多大差别,但我认为自己只是在初级中级水平上操作Vim.是:ls :b#真的速度远远超过gt荷兰国际集团在吗?我觉得它必须比这更深入.

rom*_*inl 437

正如ZyX在#vim上所说的那样,这个问题听起来像"为什么Vim专家喜欢美味而不是温暖?" .

"Vim专家"不喜欢缓冲区而不是标签:它们使用缓冲区作为它们的文件代理,并使用标签页作为它们的工作空间.缓冲区和标签页有不同的用途,所以优先选择一个和另一个没有任何意义.

缓冲区和制表符的问题是混乱,由独立事实的组合引起.

  1. 大多数"现代"文本编辑器和IDE使用选项卡隐喻来表示加载的文件.该隐喻充当信息系统 - 它向用户显示打开的文件及其状态 - 以及作为交互设备 - 它允许用户操纵(重新排序,选择,关闭......)这些打开的文件.尽管存在许多限制,但标签无处不在,人们已经习惯了它们,并期望它们无处不在.

  2. Vim 在7.0中引入了标签页,作为其用户创建临时"工作区"的一种方式.其功能,特定选项,特定命令或其:help部分中没有任何内容表明标签页可以或应该用作文件代理.

    当然,除了"标签页" 的名称外观之外什么都没有,这会导致很多混乱.

  3. 如果没有:set hidden,默认情况下禁用并且不容易找到,Vim使得无法在不写入当前缓冲区或放弃其更改的情况下切换到另一个缓冲区.不知道该选项的新用户别无选择,只能转向使用繁重的窗口或者找到他们能找到的最接近的"标签式"功能:标签页.

"标签页"对于该功能来说是一个不幸的名称选择,尤其是在阅读文档浪费时间这一主题的时代.

在Vim中,标签页是一个构建在windows之上的抽象,它们本身就是一个构建在缓冲区之上的抽象.每个新级别都会添加有用的功能但会限制您的工作流程

"缓冲方式"

使用基于缓冲区的工作流,您使用的文件沿着单个维度分布.您可以遍历缓冲区,可以通过键入部分名称(完成)或其编号来访问特定缓冲区,您可以在缓冲区之间切换,您可以非常轻松地定位它们.基本上没有摩擦.

  1. 八个缓冲区打开,只有一个可见:

    八个缓冲区打开

  2. 按号码切换:

    按号码切换

  3. 按名称切换:

    按名称切换

缓冲区是Vim的文件代理.如果你考虑文件,你会考虑缓冲区.

"窗口方式"

使用基于窗口的工作流程,您的"文件"既可以分布在同一个"虚拟"维度上,也可以分配给使用缓冲区其他两个"物理"维度的维度.但是找到这些尺寸的笛卡尔空间几乎完全分开:移动到另一个缓冲区仍然意味着"移动到另一个文件"但移动到另一个窗口却没有.对应于所需文件的缓冲区可以显示在该窗口中,但也可以显示在另一个窗口中,可能显示在另一个标签页中,或者根本不显示.

对于Windows,在打开的文件之间导航要么变得过于复杂,要么过于简单,即使使用'switchbuf':sb.主要是因为你被迫使用两组命令来实现基本相同的东西:访问缓冲区.

如下所述,Windows可以使用它们,但它们没有在任何人的工作流程中替换缓冲区所需的功能.

在这里,我正在研究Vim colorscheme.这两个窗口是同一个缓冲区的不同视图:顶部的一个用作参考,一个颜色代码表用在colorscheme中,底部一个是我工作的地方:

在colorscheme上工作

Windows不是作为文件代理设计的,不能组成一个:它们是"容器"或"视口",旨在为您提供缓冲区视图.不多也不少.

"标签方式"

使用基于选项卡的工作流程,您基本上可以尝试模仿您以前编辑器中习惯的用户体验,同时完全忽略Vim选项卡页面的本质.如果我们暂时忘记这个策略通常非常没有效果,那么就像使用Windows一样,迫使Vim坚持"一个文件=一个标签"范例而不会失去很多灵活性也是不可能的.

仍然使用与上述相同的文件,tabline占用了大量空间,几乎没有任何好处.我的所有文件和所有标签都被调用,javascript*.vim所以我无法做到3gt并且相信我会最终到达正确的位置,并且无法按名称到达特定标签.[Quickfix List]除此之外,它的标签很可能是非常无益但完全合乎逻辑的...因为没有实际的方法将文件/缓冲区绑定到标签页,所以基本上只剩下一种在标签页之间导航的实用方法/ buffers/files:循环.

是的,我的标语只有8个标签,想象一下,如果我有20个!

  1. 在8个标签页中打开8个缓冲区(错误)

    错误

  2. 两个特定任务的两个选项卡(右)

    对

标签页是"容器"或"视口",旨在包含一个或多个窗口,它们本身也是设计用于包含缓冲区的"容器".

结论

"Vim专家"(让我们假设我可以像我一样说话)不喜欢缓冲区而不是标签:他们只是按照设计使用Vim,并且非常适合这种设计:

  • "Vim专家"有2个,30个或97个缓冲区加载,非常高兴他们不必处理空间分布;

  • 当他们需要比较两个文件或在当前缓冲区的一部分中工作而另一部分作为参考时,"Vim专家"会使用windows,因为这就是它们的用途;

  • 当他们需要在项目的单独部分工作一段时间而不搞乱他们当前的观点时,"Vim专家"会加载一个全新的标签页.

  • 作为一个"Vim专家",我可以说超过4*百*个缓冲区"打开"(真正"列出,但卸载,除了少数几个")是我处理像NeoVim这样的项目的常规情况(我只是打开所有`*.c`,`*.h`,`scripts/*`和`test/**/*.lua`文件).鉴于我的终端只有239列宽,"每个标签一个文件"的方法是不可能使用的. (14认同)
  • 有关其他链接,请参阅我的[有效使用缓冲区](http://stackoverflow.com/a/21338192/438329)帖子 (9认同)
  • 拥有20个缓冲区的@DavidEG根本没有问题,因此真的不需要插件.另一方面,20个标签页 - 无论它们是否令人信​​服的文件代理 - 都不适合大多数屏幕,插件或不适合. (7认同)
  • @BenjaminRH,我吃[我自己的狗粮](https://github.com/romainl/Apprentice). (5认同)
  • 并且考虑到有许多插件(Command-T,...)使得在缓冲区和/或文件之间切换更容易使用选项卡来处理任何相对较大的项目是没有意义的.neovim与≈500"有趣"的文件是一个大项目,但不是最大的.当你面对处理这些项目的必要性时,你总是使用某种搜索来导航它(使用Command-T和朋友进行文件/标签搜索,以及进行符号定义的各种方式),因此你绝对没有理由使用标签这样:在任何情况下,您都不会使用制表符绑定功能来导航项目. (3认同)
  • @StevenLu 你真的读过我的答案吗? (3认同)
  • 你应该再读一遍,因为你两次都错过了要点。这里有一个总结,仅供您参考:**缓冲区、窗口和选项卡页都有自己的位置,仅凭原则偏向其中一个是没有意义的**。如果这个答案有任何偏见,那将是反对滥用这些东西中的任何一个,而不是反对使用它们。 (3认同)
  • @Kache,是的,这正是我的观点的核心:你可以使用Windows和标签页来获取它们的内容但不是文件代理.所以争论不是人们应该使用**标签页还是缓冲区**人们是否应该使用**标签页作为文件代理.** (2认同)
  • @ icc97,我不知道有一个程序以令人信服的方式处理这两个限制,包括 Vim。选项卡标题总是以一种或另一种方式出现乱码(只有文件名或 Vim 所做的很可怕),选项卡本身最终要么堆叠且不可读,要么超出视口且不可读,用户被迫使用鼠标将鼠标悬停在选项卡上以获取更多信息。标签很难吸。 (2认同)
  • 1) 实际上是非常标准的,但角落案例很容易得到。2)并不是真正“处理”它,它更像是“避免”它。Sublime 的 Ctrl+P(就像它的前辈和它的模仿者一样)本身是比列表、树和选项卡更好的替代品,这些列表、树和选项卡都有许多可用性问题。缓冲区绝对是要走的路。在 Vim 和其他地方。 (2认同)
  • 我基本上同意这个非常好的答案。只是有一点需要补充。_有时_这与节省击键次数无关,甚至与效率无关。仅缓冲区的使用会对智力产生影响,因为您需要记住编程时可能不需要的名称。有时,直观地看到其他缓冲区名称(没有额外的`:ls`)会让人松一口气。 (2认同)

Jon*_*ink 67

我以前把所有的缓冲区在一个单独的标签,但我厌倦了不断gtgT-ing到处.

我也觉得缓冲区太难管理了.

以下是一些完全改变了我之前观点的技巧:

这是我典型的工作流程:

  • 打开Vim,并使用:e(通常使用正则表达式:e src/**/F*Bar.js)打开缓冲区
  • 意识到我需要打开另一个文件.也:e用于此.如果我想在此缓冲区和当前打开的缓冲区之间切换,我将使用:sp:vsp在单独的窗口中打开它.
  • 重复,直到我有3-5个文件,我将使用上面的项目符号列表中的技术切换,在您的缓冲区之间飞行.
  • 如果我想用缓冲区"重新开始",只需关闭Vim并重新打开.

我觉得经过一周左右的时间强制使用这些新模式后,我可以更容易地看到我打开了哪些缓冲区,以及如何在几个自动笔画中找到它们中的任何一个.

  • 令人遗憾的是,像这样的善意用户/新手友好解释获得了大约3%的非常自以为是,贬义过于复杂的答案的赞成,例如最高投票的答案.我甚至不知道`gT`是切换标签的命令,我一直在寻找'ctrl + tab`的替代品.所以,非常感谢你真正帮助新用户,而不仅仅是让他们感到愚蠢. (17认同)
  • 我不得不说我的评论对@ romainl的答案不公平,他很乐意回答我的问题.但当然有人试图学习Vim你的答案更容易理解,但一旦你真正了解了一点,他的答案就更完整了. (8认同)
  • 我认为@romainl 的回答非常有用,它让我们清楚地了解了缓冲区、窗口和选项卡的设计方式以及它们的用途。即便如此,我认为 Vim 用户还是会抓住机会在 [你不理解 vi](/sf/ask/85287331/) 中回答问题-vim/1220118#1220118) 时尚,这可能令人沮丧。 (4认同)
  • 不记得我从哪里得到的,但是`nnoremap <leader> b:ls <CR>:b <space>`非常适合快速切换缓冲区,因为它显示了当前打开的缓冲区的列表。同样,接受部分名称(只要只有一个匹配项)。 (3认同)

Ing*_*kat 10

选项卡的缺点是您一次只能看到一个内容.因此,如果您在浏览器中使用它们,则会丢失并排查看多个缓冲区,甚至在拆分中查看同一文件的单独部分.因此,许多人建议仅使用制表符来隔离不同的工作区(例如,一个用于Java项目,另一个用于待办事项列表,第三个用于攻击脚本).

您描述的问题使您看起来使用Vim错误.要么(大部分)都有一个专用的实例.然后,如果重新编辑它们,隐藏的缓冲区将"重新出现"(现在您可以使用缓冲区列表来调用它们),并且不会有交换文件消息.或者,每个项目/文件/编辑会话使用单独的Vim实例,但是:quit当您完成文件时,养成完全每个实例的习惯.

  • 作为对选项卡的有趣重新发现,[tabman](https://github.com/kien/tabman.vim) 可以生成一个类似于 NerdTree 的侧面板,其中详细说明了每个选项卡中显示的所有缓冲区。 (2认同)

Pau*_*ker 8

将 2c 扔进堆里。

TLDR;:b *part-of-filename*是在缓冲区列表中查找您需要的文件的最佳方法,即它比缓冲区编号、选项卡或用于跟踪文件的窗口更快,认知负荷更小。

打开 30 个缓冲区对我来说没什么(即我没有打扫卫生),而且使用缓冲区的好处在于它根本不会减慢我的速度。事实上,当我打开需要它的文件四天后,它会加快速度,打电话:b *part-of-filename*,它神奇地出现,给同事和腼腆的集体主义者留下了深刻的印象。

缓冲区用于文件。

要有效:

  • 从精心挑选的根目录中打开一个重要的第一个文件
  • 打开后续文件 :e
  • 使用lsALL当你第一次开始获得良好的心理模型(你不能神交你看不到的东西,精神或字面意思)的时间
  • 从来没有:q,它吹
  • 进入:b你的肌肉记忆
  • :b1 适合您打开的第一个文件,否则数字和字母很快就会变得笨拙
  • :b# 适合切换到最后一个文件,这是一个常见的需求
  • :bd#当您切换到临时文件,完成您需要执行的操作,切换回:b#,现在想要关闭该临时文件时非常有用
  • :b *part-of-filename* 否则是在列表中查找您需要的文件的最佳方式,即它比用于跟踪文件的缓冲区编号、选项卡或窗口更快,并且具有更少的认知负载。

唯一的烦恼:b *part-of-filename*是有时你还没有打开文件,你需要先回去:e path/to/full-filename

选项卡用于区分真正不相关的文件。

或者保持一个特定的窗口布局方便(免责声明:我自己从未使用过它)。

或者用于很少使用但可以预见需要的文件。对我来说,这通常是commitMessage我在工作时注释的文件,因此在进行提交时我不必考虑太多。gt:b com<enter>(如果你觉得幸运,否则:b com<tab><enter>)更快

  • :tabe commitMessage
  • gt或者gT也是肌肉记忆的最爱

窗口拆分用于视觉比较信息

或者可以立即访问重要信息(说实话,除非该信息以某种方式我需要:e使用日志文件进行实时更新,否则我通常只是将内容拉入当前文件并在那里处理)。

  • :vspC-w v打开垂直拆分即左 | 对,然后使用:b:e来获取你想要的文件
  • :spC-w s打开水平分割,即顶部/底部
  • C-w C-w 即双 Ctrl-w,围绕可用窗口旋转
  • C-w c 关闭当前窗口
  • C-w o 关闭所有其他窗口,仅保持当前状态


Jul*_*tin 7

另一个提示是,当使用缓冲区名称作为参数:buffer时,您不必指定整个名称.但是,如果多个缓冲区与给定参数匹配,则不会切换缓冲区.

缓冲区名称的任何片段都可用于匹配.例如,如果你有缓冲区request_manager.javaqueue_manager.java然后:buffer que:b que比赛他们两个,但将切换到queue_manager.java,因为它在一开始匹配.