给资深用户的 Vim 指南
本文是从头开始教授 Vim 的系列文章的第五篇:
你能想象一个冒险家,越来越深入一个神秘的洞穴,知道等待她的是什么(主要是岩石和蝙蝠),但同时希望被一些稀有的宝石和被遗弃的宝藏所惊喜吗?
这就是我深入探索 Vim 世界时的感受。我知道我总能发现一些有价值的东西:一个新的按键、一个强大的命令,或者一些细微的技巧,都能提升我对我最爱的编辑器的控制力。
在过去的几篇文章中,我尝试引导您探索 Vim 的“洞穴”,帮助您发现最珍贵的钻石。在本文中,我们将继续探索以下内容:b
- 一些用于在 INSERT 模式下完成的按键。
- 我们可以在命令行模式下使用的有用的按键。
- 什么是缩写以及如何使用它们。
- 如何将当前 Vim 实例的全局选项和映射保存到文件中。
- 如何保存和恢复 Vim 会话。
- viminfo 文件(或 Neovim 的 shada 文件)的用途是什么。
- 如何将 Vim 命令输出重定向到文件或寄存器中。
带上你的背包、头灯和绳索,让我们去寻找一些新的心灵宝藏。
插入模式下的完成
在上一篇文章中,我们已经学习了 INSERT 模式下的一些常用按键。您还可以使用其他一些有趣的按键来完成补全。这些按键都以另一个键为前缀,CTRL+x
即 。
Vim 需要编译该+insert_expand
功能才能使这些按键起作用。
前几个命令允许您在不离开 INSERT 模式的情况下上下滚动缓冲区:
CTRL+x CTRL+y
- 向上滚动CTRL+x CTRL+e
- 向下滚动
其他几个功能只有在你想补全已经输入的内容时才有用。以下是我认为最有用的几个:
CTRL+x CTRL-l
- 从缓冲区的内容中完成一整行。CTRL+x CTRL-f
- 补全光标下的文件路径。如果文件路径也包含,则会扩展环境变量。CTRL+x s
- 附有拼写建议。CTRL+x CTRL+v
- 完成命令行历史记录。CTRL+x CTRL+i
- 补充当前文件和包含文件中的关键字。这些文件位于选项中path
。
您还可以使用同义词库或词典的补全功能,甚至全能补全来自动补全编程语言。如果您想深入了解这些理念,Vim 的帮助正等待着您释放好奇心。
Vim 帮助
:help i_CTRL-x
:help ins-completion
:help compl-omni-filetypes
命令行模式下的按键
本系列文章对 INSERT 和 VISUAL 模式的按键倾注了大量心血。那么 COMMAND LINE 模式呢?是时候向这位老朋友致敬了。
首先,好消息是:INSERT 模式下的按键操作在 COMMAND LINE 模式下基本也能用。总而言之,我们已经有一堆可以操作的按键了。是不是很棒?
从缓冲区复制到命令行
你有没有想过在命令行模式下从缓冲区复制一些东西?最无聊的做法是回到普通模式下的缓冲区,把你想要的内容复制到寄存器中,然后回到命令行模式,再把你想要的内容复制出来。就像在插入模式下一样,你可以CTRL+r
在命令行模式下使用 加上寄存器的名称来复制其内容。
或者您可以使用以下按键:
CTRL+r CTRL+f
- 复制f
缓冲区光标下的文件名。CTRL+r CTRL+w
- 复制w
缓冲区光标下的命令。CTRL+r CTRL+a
- 复制缓冲区光标下的 WORD。CTRL+r CTRL+l
- 复制l
缓冲区光标下的线。
搜索
如果设置了此选项incsearch
,它会在您输入搜索内容时高亮显示。不仅如此,您还可以使用CTRL+g
和CTRL+t
键浏览每个匹配项,而无需离开命令行模式。
一行中的多个命令
这不是一个按键,但它仍然很有用。你可以用竖线分隔多个命令,然后在一行中运行它们。例如:
:set filetype?|echo "it's done!"
如果命令接受管道作为参数,则此方法无效。例如::!ls | wc
。
Vim 帮助
:help Command-line-mode
:help ex−edit−index
缩写
现在让我们来看看一些完全不同的东西:Vim 缩写。此功能可以在按下 后自动将一个单词替换为另一个单词SPACE
。你可以在 INSERT 和 COMMAND-LINE 模式下使用缩写。
例如,如果您经常将“the”拼写错误为“teh”(我们大多数人都会发生这种情况),您可以自动将“teh”替换为“the”。
让我们看看可以用来输出和操作缩写的命令:
:abbreviate
或:ab
- 列出所有创建的缩写。:abbreviate <string>
或:ab <string>
- 列出以字符串开头的缩写<string>
。:abbreviate <string> <replacement>
或者:ab <string> <replacement>
- 为每种模式创建一个新的缩写。:unabbreviate <ab>
或者:una <ab>
——删除缩写<ab>
。:abclear
或:abc
- 删除所有缩写。
使用 列出缩写时:ab
,您会在输出的第一列看到不同的字母。它们指示您可以在哪种模式下使用它们:
i
用于i
nsert 模式。c
用于c
命令行模式。!
对两者而言。
如果要列出或创建一种精确模式的缩写,可以在命令开头使用i
或:c
:iab
- 列出 INSERT 模式下可用的所有缩写。:cab <string> <replacement>
- 创建仅在命令行模式下可用的新缩写。iabc
- 在插入模式下删除所有缩写。
如果您决定使用命令的长格式,则效果会有所不同。例如,:iabbreviate
不起作用;请使用“缩写”,例如:iabbrev
、:cabbrev
或:iunabbrev
。
您可以将缩写用于不同的目的,如以下不同示例所示:
:iab @@ myemail@email.com
- 输入您的电子邮件:iab BTW by the way
- 展开首字母缩略词:iab sign Jane Doe™<cr>jane@doe.com
- 插入您的签名:iab <expr> cdate strftime('%Y-%m-%d')
- 插入c
当前日期:cab uuidgen r! uuidgen
- 运行命令时插入 UUID:uuidgen
最后,如果您输入了缩写,但不想在点击时展开它SPACE
,请改用CTRL+v
然后SPACE
。
Vim 帮助
:help abbreviations
将 Vim 的选项和映射保存到文件中
现在让我们进入本文的核心:将您当前的选项、按键映射或整个会话保存到一个文件中。
如果您在 Vim 中进行实验,更改了一堆选项和映射,但不记得具体更改了什么,或者您想知道按下按键时会运行什么命令,您可以将每个选项和全局映射(不同于 Vim 的默认值)输出到一个文件中。
为此,您可以运行命令:mkexrc <filepath>
或:mk <file>
将这些选项和映射输出到文件 中<filepath>
。如果使用相对路径,它将相对于您所在的工作目录(要显示它,请使用:pwd
)。
您还可以添加感叹号!
来:mk
覆盖文件。例如,:mk! myfile
将创建文件myfile
,如果文件已存在则覆盖它。
在这里,你可以打开你编写的文件,并将所需的任何选项或映射复制到 vimrc 中。你也可以使用命令 直接将文件 source 到另一个 Vim 实例中:source <filepath>
。
我已经在Vim 中级用户:source
指南中写过如何重新加载 vimrc 的命令。你可以用这个命令来加载任何包含 Vimscript 的文件。
Vim 会话
如果您想要保存和恢复比选项和全局映射更多的内容,您可以使用 Vim 会话。
创建并加载会话
会话由所有视图(视图是附加到窗口的设置的集合)和当前 Vim 实例的全局设置组成。
将会话保存到文件中,稍后在另一个 Vim 实例中打开它,岂不是很有趣?它还能让你恢复所有缓冲区、窗口和本地设置!那样生活就会更加丰富多彩了。
为此,您可以使用命令:mksession <filepath>
或:mks <filepath>
。然后,您可以使用 在另一个 Vim 实例中获取会话:source <filepath>
。
!
与往常一样,如果文件已存在,您可以在命令中添加感叹号来覆盖该文件。
例如,这里有一些我编写的用于vimrc
操作会话的映射:
nnoremap <leader>ss :mksession! $VIMCONFIG/sessions/
- 映射以s
进行s
会话nnoremap <leader>sl :source $VIMCONFIG/sessions/
- 映射到l
加载s
会话
每次按下LEADER ss
,我都可以输入会话的名称并保存。我所有的会话都集中在同一个目录中。
微调 Vim 的会话
该选项sessionoptions
包含一组用逗号分隔的值,
。这些值将决定会话文件中保存的内容,以及文件读取时将恢复的内容。
以下是您可以使用的最有趣的值:
blank
- 保存包含没有名称的缓冲区的窗口。buffers
- 保存隐藏和未加载的缓冲区。只有窗口中的缓冲区在没有此值的情况下才会恢复。curdir
- 保存当前目录。folds
- 保存折叠信息。globals
- 保存以大写字母开头且名称中至少包含一个大写字母的全局变量。help
- 保存帮助窗口。localoptions
- 将本地选项和映射保存到窗口或缓冲区。options
- 保存所有选项和映射。resize
- 保存窗口的大小。tabpages
- 保存所有打开的标签页。如果没有此值,则仅保存当前标签页。terminal
- 保存终端窗口。
请注意,默认的全局选项或全局映射不会保存在会话文件中。这意味着,如果您打开了 Vim 实例并且已经修改了一些默认值,加载会话并不会将它们重置为默认值。
Vim 帮助
:help :sessionoptions
:help views-sessions
:help :mksession
文件 viminfo 或 shada
当你关闭编辑器时,Vim 会自动将信息保存到一个文件中。根据你所使用的编辑器,保存的文件会有所不同:
- 对于 Vim,它是 viminfo 文件。
- 对于 Neovim,它是 shada 文件(用于
sh
aredda
ta)。它不能是符号链接。
在 Unix 系统(Linux 和 macOS)上,每个文件都可以在以下文件路径中找到:
- viminfo -
$HOME/.viminfo
- 沙达-
$XDG_DATA_HOME/nvim/shada/main.shada
shadafile
您可以通过分别设置或的值来更改 shada 或 viminfo 文件的名称。如果您不想使用这些文件,viminfofile
也可以设置 的值。NONE
每次关闭 Vim 实例时,您可以保存以下内容:
- 命令行历史记录。
- 搜索历史记录。
- 输入行历史记录。
- 非空寄存器的内容。
- 多个文件的小写标记。
- 文件标记(大写标记)。
- 最后搜索或替代模式。
- 缓冲区列表。
- 全局变量(仅当它们与默认值不同时)。
您可以通过更改以下选项的值来更精确地配置要保存的内容:
- 对于 Vim,选项
viminfo
。 - 对于 Neovim,选项
shada
。
选项的值以逗号分隔,
。以下是最有用的:
!
- 保存和恢复全局变量(其名称不应包含小写字母)。
您可以在每个值后面添加一个数字:
<
- 指定每个寄存器保存的最大行数。如果未包含此值,则保存所有行。如果您不想保存寄存器,请使用该值<0
。%
- 保存和恢复缓冲区列表。您可以用数字指定最多可存储的缓冲区数量。'
- 指定记住的最大标记文件数量。它还会保存我们在上一篇文章中看到的跳转列表和更改列表。/
和:
- 保存的命令行历史记录中的搜索模式和条目数量。history
如果未指定,则使用该选项。f0
- 不要存储任何大写标记。s
- 以 KiB(千字节)为单位指定项目内容的最大大小。- 对于viminfo文件来说,只适用于寄存器。
- 对于 shada 文件,它适用于除缓冲区列表和标题之外的所有项目。
例如,:set shada=!,'100,<50,s100
保存全局变量,最多标记 100 个文件,每个寄存器最多 50 行,每项最多 100Kib。vim 的对应代码如下:set viminfo=!,'100,<50,s100
。
Vim 会在你关闭编辑器时写入 viminfo 文件,并在你打开新编辑器时加载该文件。不过,你也可以使用以下命令输出、保存或加载该文件:
对于 Vim:
:oldfiles
或:ol
- 显示 viminfo 文件中存储的所有标记文件。:rviminfo
或者:rv
——阅读 viminfo 文件。:wviminfo
或者:wv
——写入 viminfo 文件。
对于 Neovim:
:oldfiles
或:o
- 显示所有存储在 shada 文件中带有标记的文件。:rshada
或者:rs
- 阅读shada文件。:wshada
或者:ws
- 写入 shada 文件。
在这些命令中添加一个感叹号(:rv!
例如或:rs!
)以允许文件中设置的所有内容覆盖当前 Vim 实例中的所有内容。
viminfo 文件是使用其一种方言编写的。如果您更愿意尝试,可以直接修改它。shada 文件使用messagepack格式。
Vim 帮助
:help viminfo
:help 'viminfo'
:help 'viminfofile'
Neovim 帮助
:help shada
:help 'shada'
:help 'shadafile'
重定向
如果你想将 Vim 命令的输出保存到文件或寄存器中,该怎么办?这个命令:redir
可以满足你的需求。更准确地说:
:redir > <file>
- 将每个命令的输出写入文件<file>
。- 使用
:redir!
(带有感叹号!
)覆盖文件。 - 使用
>>
而不是 来>
附加到文件。
- 使用
:redir @<reg>
- 将每个命令的输出写入寄存器<reg>
。:redir @<reg>>>
- 将每个命令的输出附加到寄存器<reg>
。:redir => <var>
- 将每个命令的输出写入变量<var>
。:redir END
- 结束重定向。
例如,如果您想sessionoptions
使用.vimrc
当前值设置变量,您可以执行以下操作:
:redir >> $VIMCONFIG/.vimrc
:set sessionoptions?
:redir END
运行 后:redir END
,不会再向文件中写入任何内容。您只能进行一次重定向,因此声明新的重定向将自动关闭之前的重定向。
我们来看另一个例子。您可以运行以下命令将sessionoptions
当前值附加到选项的声明中:
:redir @+>>
:set sessionoptions?
:redir END
a
使用命名寄存器的大写版本(从到 的寄存器z
)将附加 Vim 命令的输出,而无需使用>>
。例如,:redir @A
。
最后一个例子,这次使用变量来存储命令的输出:
:redir => my_var
:set sessionoptions?
:redir END
:echo my_var
Vim 帮助
:help :redir
过滤命令输出
能够在 Vim 中保存命令输出很好,但如果我们想过滤它们怎么办?
为此,我们可以使用命令:它将根据模式:filter /<pattern>/ <cmd>
过滤命令。<cmd>
<pattern>
让我们举几个例子:
:filter /content/ buffers
- 仅输出部分文件路径匹配的缓冲区content
。:filter /archives/ oldfiles
- 仅输出部分文件路径与 匹配的标记文件archives
。如您所见,模式不必匹配整行,只需匹配部分即可。您可以!
在命令filter
(filter!
) 后添加感叹号来反转匹配,即输出所有与模式不匹配的内容。
此命令并非与所有 Ex 命令兼容。例如,它与命令 不兼容:register
。
Vim 帮助
:help :filter
下一步:面向专家用户的 Vim
我们从这篇文章中学到了什么?
- 您可以使用新的 INSERT 模式子菜单,先按一次键,
CTRL+x
然后按另一次键。 - 您可以在命令行模式下使用大多数按键来进入“插入”模式。您还可以使用
CTRL+r
第二个按键直接在命令行中复制缓冲区中的内容。 - 缩写是为了防止你因为拼写错误而敲击键盘。它并非唯一的用途;它的应用范围无限广阔。
- 您可以使用命令 来获取包含 Vimscript 命令的任何文件
:source
。 - 您可以使用 保存 Vim 实例的当前设置
:mk <file>
。 - 您还可以使用命令保存当前的 Vim 会话
:mks <file>
。 - 每次关闭 Vim 时,都会写入 viminfo 文件(如果
viminfo
选项不为空)。如果您使用 Neovim,viminfo 文件将被替换为 shada 文件。 - 每次打开 Vim 时,都会读取 viminfo 文件(或 shada 文件)。
- 您可以使用重定向(命令
:redir
)来保留文件或注册不同 Vim 命令的输出。 - 您可以使用命令过滤某些 Vim 命令的输出
:filter
。
在本系列文章中,我们已经见识了 Vim 的众多强大功能,它们都唾手可得。但 Vim 真正的强大之处在于它的灵活性。因此,在下一篇文章《Vim 专家用户指南》中,我们将化身为 Vim 的“学徒神”(或“女神”),探索如何根据我们更深层次的需求来塑造我们的 Vim 世界。
摆脱鼠标束缚
您是否想要构建一个以 Linux shell 和 Vim 为核心的无鼠标开发环境?
在键盘和鼠标之间切换会消耗认知能量。本书将逐步指导您搭建基于 Linux 的开发环境,让您的双手始终保持在键盘上。
将您用来处理输入设备的脑力集中到它应该去的地方:您所创造的东西。
鏂囩珷鏉ユ簮锛�https://dev.to/phantas0s/a-vim-guide-for-veteran-users-3p50