Usr_12

Nvim :help 页面,生成源代码 使用 tree-sitter-vimdoc 解析器。


VIM 用户手册 - 作者 Bram Moolenaar
巧妙的技巧
通过组合多个命令,您可以让 Vim 完成几乎所有事情。本章将介绍一些有用的组合。这将使用前几章介绍的命令以及一些其他命令。
12.1 替换一个词 12.2 将 "Last, First" 更改为 "First Last" 12.3 对列表进行排序 12.4 反转行顺序 12.5 统计单词 12.6 查找手册页 12.7 修剪空白 12.8 查找单词的使用位置
下一章:usr_20.txt 快速输入命令行命令 上一章:usr_11.txt 从崩溃中恢复 目录:usr_toc.txt

替换一个词

可以使用 substitute 命令将一个词的所有出现替换为另一个词
:%s/four/4/g
"%" 范围表示在所有行中替换。末尾的 "g" 标志会导致一行中的所有单词都被替换。如果您的文件还包含 "thirtyfour",则此操作不会产生正确的结果。它将被替换为 "thirty4"。为了避免这种情况,请使用 "\<" 项来匹配单词的开头
:%s/\<four/4/g
显然,这在 "fourteen" 上仍然会出错。使用 "\>" 来匹配单词的结尾
:%s/\<four\>/4/g
如果您正在编程,您可能希望在注释中替换 "four",但在代码中不替换。由于这很难指定,因此添加 "c" 标志以让 substitute 命令提示您进行每次替换
:%s/\<four\>/4/gc

在多个文件中替换

假设您想在一个以上的文件中替换一个词。您可以编辑每个文件并手动输入命令。使用记录和回放速度要快得多。假设您有一个包含 C++ 文件的目录,所有文件都以 ".cpp" 结尾。有一个名为 "GetResp" 的函数,您希望将其重命名为 "GetAnswer"。
vim *.cpp 启动 Vim,定义参数列表以包含所有 C++ 文件。您现在位于第一个文件中。 qq 开始记录到 q 寄存器中 :%s/\<GetResp\>/GetAnswer/g 对第一个文件进行替换。 :wnext 写入此文件并移动到下一个文件。 q 停止记录。 @q 执行 q 寄存器。这将重放替换和 ":wnext"。您可以验证这不会产生错误消息。 999@q 对剩余文件执行 q 寄存器。
在最后一个文件处,您将收到错误消息,因为 ":wnext" 无法移动到下一个文件。这将停止执行,并且所有操作都已完成。
注意: 回放记录的序列时,错误会停止执行。因此,请确保在记录时不会收到错误消息。
有一个问题:如果其中一个 .cpp 文件不包含 "GetResp" 这个词,您将收到错误消息,并且替换将停止。为了避免这种情况,请向 substitute 命令添加 "e" 标志
:%s/\<GetResp\>/GetAnswer/ge
"e" 标志告诉 ":substitute" 未找到匹配项不是错误。

12.2 将 "Last, First" 更改为 "First Last"

您有一个以这种形式命名的列表
Doe, John
Smith, Peter
您想将其更改为
John Doe
Peter Smith
这可以使用一个命令完成
:%s/\([^,]*\), \(.*\)/\2 \1/
让我们将其分解成几个部分。显然,它以 substitute 命令开头。 "%" 是行范围,代表整个文件。因此,替换将在文件中的每一行中完成。substitute 命令的参数是 "/from/to/"。斜杠分隔了 "from" 模式和 "to" 字符串。这是 "from" 模式包含的内容
\([^,]*\), \(.*\)
第一个部分 \( \) 匹配 "Last" \( \) 匹配任何不是逗号的字符 [^,] 任意次数 * 匹配 ", " 逐字匹配 , 第二个部分 \( \) 匹配 "First" \( \) 任何字符 . 任意次数 *
在 "to" 部分中,我们有 "\2" 和 "\1"。这些称为反向引用。它们引用模式中 \( \) 部分匹配的文本。"\2" 引用由第二个 \( \) 匹配的文本,即 "First" 名称。"\1" 引用第一个 \( \),即 "Last" 名称。您可以在 substitute 命令的 "to" 部分中使用多达九个反向引用。"\0" 代表整个匹配的模式。substitute 命令中还有几个特殊项目,请参阅 sub-replace-special.

12.3 对列表进行排序

在 Makefile 中,您经常有一个文件列表。例如
OBJS = \
version.o \
pch.o \
getopt.o \
util.o \
getopt1.o \
inp.o \
patch.o \
backup.o
要对这个列表进行排序,请通过外部排序命令过滤文本
/^OBJS
j
:.,/^$/-1!sort
这将转到第一行,其中 "OBJS" 是该行中的第一个内容。然后它向下移动一行并过滤行,直到下一行空行。您也可以在 Visual 模式中选择行,然后使用 "!sort"。这样做更容易输入,但在行数很多时工作量更大。结果如下
OBJS = \
backup.o
getopt.o \
getopt1.o \
inp.o \
patch.o \
pch.o \
util.o \
version.o \
请注意,每行末尾的反斜杠用于指示行继续。排序后,这是错误的!位于末尾的 "backup.o" 行没有反斜杠。现在它排序到另一个位置,它必须有一个反斜杠。最简单的解决方案是使用 "A \<Esc>" 添加反斜杠。如果您确保在最后一行之后有一个空行,则可以保留最后一行中的反斜杠。这样,您就不会再遇到这个问题。

12.4 反转行顺序

:global 命令可以与 :move 命令组合使用,将第一行之前的行全部移动,从而得到一个反转的文件。命令是
:global/^/move 0
缩写
:g/^/m 0
"^" 正则表达式匹配行的开头(即使该行是空行)。:move 命令将匹配的行移动到虚构的第零行之后,因此当前匹配的行成为文件的首行。由于 :global 命令不会被更改的行号搞混,因此 :global 会继续匹配文件的其余所有行,并将每个行都设置为第一个。
这在行范围内也有效。首先移动到第一行之上并用 "mt" 标记它。然后将光标移动到范围内的最后一行,并键入
:'t+1,.g/^/m 't

12.5 统计单词

有时您必须编写一个具有最大单词数的文本。Vim 可以为您统计单词。当您要统计整个文件中的单词时,请使用以下命令
g CTRL-G
不要在 g 后面输入空格,这只是为了便于阅读命令。输出如下
Col 1 of 0; Line 141 of 157; Word 748 of 774; Byte 4489 of 4976
您可以看到您位于哪个单词 (748) 以及文件中单词的总数 (774)。
当文本仅是文件的一部分时,您可以将光标移动到文本的开头,键入 "g CTRL-G",将光标移动到文本的结尾,再次键入 "g CTRL-G",然后使用您的思维来计算单词位置的差值。这是一种很好的练习,但还有更简单的方法。使用 Visual 模式选择您要统计单词的文本。然后键入 g CTRL-G。结果
Selected 5 of 293 Lines; 70 of 1884 Words; 359 of 10928 Bytes
有关统计单词、行和其他项目的其他方法,请参阅 count-items.

12.6 查找手册页 find-manpage

在编辑 shell 脚本或 C 程序时,您正在使用一个您想要查找其手册页的命令或函数(这在 Unix 上)。让我们先使用一个简单的方法:将光标移动到您要查找帮助的单词上,然后按
K
Nvim 将在该词上运行 :Man。如果找到了手册页,它将被显示出来。您还可以使用 :Man 命令在手册页上打开一个窗口
:Man csh
您可以四处滚动,并且文本会被突出显示。这使您可以找到您要查找的帮助。使用 CTRL-W w 跳转到您正在处理的文本所在的窗口。要在特定部分中查找手册页,请先输入部分号。例如,要在第 3 部分中查找 "echo"
:Man 3 echo
要跳转到另一个手册页,该手册页以 "word(1)" 的典型形式出现在文本中,请在上面按 CTRL-]。进一步的 ":Man" 命令将使用相同的窗口。
要显示光标下单词的手册页,请使用以下方法
K
例如,您想在编辑此行时了解 "strstr()" 的返回值
if ( strstr (input, "aap") == )
将光标移动到 "strstr" 上的某个位置,然后键入 "K"。将打开一个窗口来显示 strstr() 的手册页。

12.7 修剪空白

有些人认为行尾的空格和制表符毫无用处、浪费且难看。要删除每行末尾的空格,请执行以下命令
:%s/\s\+$//
使用行范围 "%",因此这适用于整个文件。":substitute" 命令匹配的模式是 "\s\+$"。这将找到空格字符 (\s),一个或多个空格字符 (\+),在行尾 ($) 之前。稍后将解释如何编写这样的模式,请参阅 usr_27.txt。substitute 命令的 "to" 部分为空:"//"。因此,它用空字符替换,有效地删除了匹配的空格。
另一种浪费空格的做法是在制表符之前放置空格。通常,这些空格可以在不更改空格数量的情况下删除。但并非总是如此!因此,您最好手动进行。使用以下搜索命令
/
您无法看到它,但在该命令中制表符之前有一个空格。因此它是 "/<Space><Tab>"。现在使用 "x" 删除空格,并检查空格数量是否发生变化。如果发生变化,您可能需要插入一个制表符。键入 "n" 以查找下一个匹配项。重复此操作,直到找不到更多匹配项。

12.8 查找单词的使用位置

如果您是 Unix 用户,您可以将 Vim 和 grep 命令结合使用来编辑包含给定单词的所有文件。如果您正在开发一个程序,并且想要查看或编辑包含特定变量的所有文件,这将非常有用。例如,假设您想编辑包含 "frame_counter" 这个词的所有 C 程序文件。为此,您使用以下命令
vim `grep -l frame_counter *.c`
让我们详细看看这个命令。grep 命令在文件集中搜索给定的单词。由于指定了 -l 参数,该命令只会列出包含该单词的文件,而不会打印匹配的行。它正在搜索的单词是 "frame_counter"。实际上,这可以是任何正则表达式。(注意:grep 用于正则表达式的规则与 Vim 不完全相同。)整个命令用反引号 (`) 括起来。这告诉 Unix shell 运行这个命令并假装结果是在命令行上键入的。所以发生的事情是 grep 命令运行并产生一个文件列表,这些文件被放在 Vim 命令行上。这将导致 Vim 编辑作为 grep 输出的文件列表。然后,您可以使用 ":next" 和 ":first" 等命令浏览文件。

查找每行

上面的命令只找到包含该单词的文件。您仍然需要在文件中找到该单词。Vim 有一个内置命令,您可以使用它来搜索一组文件中的给定字符串。例如,如果您想在所有 C 程序文件中查找 "error_string" 的所有出现,请输入以下命令
:grep error_string *.c
这将导致 Vim 在所有指定的文件 (*.c) 中搜索字符串 "error_string"。编辑器现在将打开找到匹配项的第一个文件,并将光标定位在第一个匹配行上。要转到下一个匹配行(无论它在哪个文件),使用 ":cnext" 命令。要转到上一个匹配项,使用 ":cprev" 命令。使用 ":clist" 查看所有匹配项及其位置。":grep" 命令使用外部命令 grep(在 Unix 上)或 findstr(在 Windows 上)。您可以通过设置选项 'grepprg' 来更改此设置。
下一章:usr_20.txt 快速键入命令行命令
版权:参见 manual-copyright vim:tw=78:ts=8:noet:ft=help:norl
主页
命令索引
快速参考