vim入门--(4)多文件打开与缓冲区

作者 by adtxl / 2022-01-05 / 暂无评论 / 446 个足迹

1.单文件的打开

在vim中,如果我们已经打开了一个文件,再想打开目录中的其它文件,不退出vim的情况下可以使用下面的方式

  • 打开文件使用:e 文件名;可以使用<Ctrl+D>来查看有哪些文件,及用Tab进行自动完成
  • 存盘使用:w

2.已经存在交换文件

出现这种情况原因一般有两种

  1. 你上次编辑这个文件时,发生了意外崩溃。
  2. 你已经在使用另外一个 Vim 会话编辑这个文件了。

当进程 ID(process ID)后面没有“STILL RUNNING”这样的字样时,那就是情况 1;否则,就是情况 2 了。

下图即为情况1,此时按r可以恢复上次的编辑状态。需要注意的是,在恢复之后,Vim仍然不会删除这个崩溃时的交换文件。因此,在确定文件内容无误并保存文件后,可以重新打开,然后按d删除该交换文件。当然,如果你一开始就就觉得目前的文件不需要恢复,可以一开始就直接按d把交换文件删除。

image.png

如果你已经在另一个 Vim 会话里编辑文件的话,我们就会在进程 ID 后面看到“STILL RUNNING”的字样;同时,Vim 界面上也没有了删除(Delete)交换文件这一选项。

这时,大部分情况侠我们应当使用 q 或 a(绝大部分情况下没有区别)放弃编辑,并找到目前已经打开的 Vim 窗口,从那里继续。少数情况下,我们只是要查看文件,那也可以选择 o 只读打开文件。需要使用 e 强行编辑的情况很少,需要非常谨慎——比如,你确认另外有 Vim 会话,但里面不会去做任何修改,这是我目前想得出来的唯一的合理需求。

imageb644be59d297faa3.png

3. 多文件的打开方式

打开多个文件可以使用通配符,如vim *.h *.c

在上面的命令后,Vim 建立了一个文件列表,并且暂时只打开其中的第一个文件。接下来,用户可以决定,要编辑哪个文件,或者查看列表,或者提前退出,等等。

为此,Vim 提供了以下命令:

  • :args:可以显示“参数”,即需要编辑的多个文件的列表
  • :args 文件名:使用新的文件名替换参数列表
  • :next(可缩写为 :n):打开下一个文件;如当前文件修改(未存盘)则会报错中止,但如果命令后面加!则会放弃修改内容,其他命令也类似
  • :Next(缩写 :N):previous(缩写 :prev):打开上一个文件
  • :first 或 :rewind:回到列表中的第一个文件
  • :last:打开列表中的最后一个文件

使用上面的命令,假设一个简单的使用场景,我们现在需要在某个目录下的所有 .cpp 和 .h 文件开头贴入一段版权声明,就可以按下面操作

  1. 在终端里进入到目标目录下
  2. 使用 vim *.cpp *.hgvim *.cpp *.h 来打开需要编辑的文件
  3. 对于第一个文件,使用之前的方法贴入所需的文本
  4. 使用 V 进入行选择的可视模式,移动光标选中所需的文本,然后使用 y 复制选中的各行
  5. 执行命令:set autowrite,告诉 Vim 在切换文件时自动存盘
  6. 执行命令 :n|normal ggP,切换到下一个文件并执行正常模式命令 ggP,跳转到文件开头并贴入文本
  7. 确认修改无误后,键入 :、上箭头和回车,重复执行上面的命令
  8. 待 Vim 报错说已经在最后一个文件里,使用 :w存盘,或 :wq(亦或更快的 ZZ)存盘退出

另外,Vim 还能解决一个 shell 相关的不一致性问题。如果我们要编辑的文件除了当前目录下的,还有所有子目录下的,在大部分 shell 下,包括 Linux 上缺省的 Bash,我们需要使用*.cpp *.h **/*.cpp **/*.h来挑选这些文件,重复、麻烦。Vim 在此处采用了类似于 Zsh 的简化语法,**也包含了当前目录。这样,我们只需把上面第 2 步改成下面这样即可:

  • 键入 vim 进入 Vim,然后使用:args **/*.cpp **/*.h来打开需要编辑的文件

4. 缓冲区的管理和切换

Vim 里会对每一个已打开或要打开的文件创建一个缓冲区,这个缓冲区就是文件在 Vim 中的映射。在多文件编辑的时候你也会有同样数量的缓冲区。不过,缓冲区的数量常常会更高,因为你用:e等命令打开的文件不会改变“命令行参数”(只被命令行或 :args 命令修改),但同样会增加缓冲区的数量。此外,:args代表参数列表 / 文件列表,真的只是文件的列表而已。缓冲区中有更多信息的,最最基本的就是记忆了光标的位置。在 Vim 里,除了切换到下一个文件这样的批处理操作外,操作缓冲区的命令比简单操作文件的命令更为方便。作为对比,我们来看一下文件列表和缓冲区列表的命令的结果。

下图为列表命令:args的结果

image5d8d13a3d9cbe4d5.png

下图为列表命令:ls的结果

image6046c7057a2a1c9c.png

可以看到,两者都展示了文件,都标示出了当前编辑的文件(分别使用方括号和%a)。不过,缓冲区列表中明显有更多的信息:

  • 文件名前面有编号;我们也马上就会说到利用编号的命令。
  • 除了当前活跃文件的标记%a,还有个文件被标成了#,这表示最近的缓冲区;缓冲区列表里还可能有其他标记,如+表示缓冲区已经被修改。
  • 文件名后面有行号,表示光标在文件中的位置。

常用的缓冲区命令跟前面文件列表相关的命令有很大的相似性,因此我在这儿一起讲,可以帮助你记忆:

  • :buffers 或 :ls:可以显示缓冲区的列表:buffer 缓冲区列表里的编号(:buffer 可缩写为 :b):跳转到编号对应的缓冲区;如当前缓冲区已被修改(未存盘)则会报错中止,但如果命令后面加 ! 则会放弃修改内容;其他命令也类似
  • :bdelete 缓冲区列表里的编号(:bdelete 可缩写为 :bd):删除编号对应的缓冲区;编号省略的话删除当前缓冲区
  • :bnext(缩写 :bn):跳转到下一个缓冲区
  • :bNext(缩写 :bN)或 :bprevious(缩写 :bp):跳转到上一个缓冲区
  • :bfirst:brewind:跳转到缓冲区列表中的第一个文件
  • :blast:跳转到缓冲区列表中的最后一个文件

还有很常见的一种情况是,我们需要在两个文件之间切换。Vim 对最近编辑的文件(上面提到的列表里标有#的文件)有特殊的支持,使用快捷键 <Ctrl-^>可以在最近的两个缓冲区之间来回切换。这个快捷键还有一个用法是在前面输入缓冲区的编号:比如,用1<Ctrl-^> 可以跳转到第一个缓冲区(跟命令行模式的命令 :bfirst 或 :b1 效果相同)。

从实际使用的角度,使用缓冲区列表有点像打开最近使用的文件菜单(但缓冲区列表不会存盘),可以当作一种快速切换到最近使用的文件的方式。

缓冲区是文件在某个 Vim 会话里的映射。这意味着,如果某个 Vim 会话里不同的窗口或标签页(下一讲里会讨论)编辑的是同一个文件,它们对应到的也会是同一个缓冲区。更重要的是,文件 / 缓冲区的修改在同一个 Vim 会话里是完全同步的——这就不会像在多会话编辑时那样发生冲突和产生错误了。

独特见解