编辑
Nvim 的 :help
页面,生成 于 源代码,使用 tree-sitter-vimdoc 解析器。
编辑文件
在 Vim 中编辑文件意味着
1. 将文件读入缓冲区 2. 使用编辑器命令更改缓冲区 3. 将缓冲区写入文件
当前文件 只要你不写入缓冲区,原始文件将保持不变。如果你开始编辑文件(将文件读入缓冲区),文件名将被记录为“当前文件名”。这也称为当前缓冲区名称。它可以在命令行上与 "%" 结合使用
:_%。
备用文件 如果已经存在当前文件名,则该文件名将成为备用文件名。它可以在命令行上与 "#" 结合使用
:_#,你可以使用
CTRL-^ 命令在当前文件和备用文件之间切换。但是,当使用
:keepalt 时,备用文件名不会更改。每个窗口都会记住一个备用文件名。
:keepalt :keepa :keepalt
{cmd}
在保留当前备用文件名的情况下执行
{cmd}
。请注意,间接调用的命令(例如,使用函数调用的命令)仍然可能设置备用文件名。
所有文件名都存储在缓冲区列表中。当你输入一个文件名以进行编辑(例如,使用 ":e filename")或写入(例如,使用 ":w filename")时,文件名将被添加到列表中。你可以使用缓冲区列表来记住你编辑了哪些文件,并使用
CTRL-^ 命令快速从一个文件切换到另一个文件(例如,复制文本)。首先输入文件的编号,然后按
CTRL-^
。
{count}
CTRL-G
与 CTRL-G
相同,但会打印包含完整路径的当前文件名。如果计数大于 1,还会给出当前缓冲区编号。
如果行中存在占用屏幕上多个位置的字符(
<Tab>
或特殊字符),或者使用每个列多个字节的字符(当
'encoding' 为 utf-8 时,大于 0x7F 的字符),则字节列和屏幕列都将显示,以连字符分隔。
v_g_CTRL-G
{Visual}
g
CTRL-G
与 "g
CTRL-G
" 相似,但会显示可视选择的区域的词、字符、行和字节计数。在块模式下,还会显示列计数。(有关
{Visual}
,请参阅
Visual-mode。)
:file_f :f[ile][!]
{name}
将当前文件名设置为
{name}
。可选的 ! 会避免截断消息,就像
:file 一样。如果缓冲区以前有名称,则该名称将成为
备用文件名。将创建一个未列出的缓冲区来保存旧名称。
:0file:0f[ile][!] 删除当前缓冲区的名称。可选的 ! 会避免截断消息,就像
:file 一样。
Vim 会记住你输入的完整路径文件名。在大多数情况下,显示文件名时只显示你输入的名称,但如果你使用了 ":cd" 命令
:cd,则使用完整路径文件名。
主目录替换 如果环境变量 $HOME 已设置,并且文件名以该字符串开头,则它通常显示为用 "~" 替换了 HOME。这样做是为了保持文件名简短。在读取或写入文件时,仍然使用完整名称,"~" 仅在显示文件名时使用。当替换文件名会导致结果仅为 "~" 时,将使用 "~/" 代替(以避免将选项设置为 $HOME 与
'backupext' 设置为 "~" 混淆)。
写入缓冲区时,默认使用当前文件名。因此,当你给出 "ZZ" 或 ":wq" 命令时,原始文件将被覆盖。如果你不想这样做,可以通过在 ":write" 命令中给出文件名参数,将缓冲区写入另一个文件。例如
vim testfile
[change the buffer with editor commands]
:w newfile
:q
这将创建一个名为 "newfile" 的文件,它是 "testfile" 的修改副本。文件 "testfile" 将保持不变。无论如何,如果设置了
'backup' 选项,Vim 会在覆盖原始文件之前重命名或复制原始文件。如果你发现需要原始文件,可以使用该文件。另请参阅
'patchmode' 选项。备份文件的名称通常与原始文件名相同,并在其后附加了
'backupext'。默认的 "~" 有点奇怪,是为了避免意外覆盖现有文件。如果你更喜欢 ".bak",请更改
'backupext' 选项。通过设置
'backupdir',可以将备份文件放置在另一个目录中。
当你开始编辑时没有给出文件名,"No File" 将显示在消息中。如果 ":write" 命令使用了文件名参数,则当前文件的名称将被设置为该文件名。这仅在
'cpoptions' 中包含 'F' 标志时发生(默认情况下包含在内)
cpo-F。这在空缓冲区中输入文本然后将其写入文件时非常有用。如果
'cpoptions' 包含 'f' 标志(默认情况下不包含)
cpo-f,则文件名将为 ":read file" 命令设置。这在没有参数启动 Vim,然后执行 ":read file" 以开始编辑文件时非常有用。当文件名已设置且
'filetype' 为空时,将触发文件类型检测自动命令。
not-edited因为文件名是在没有真正开始编辑该文件的情况下设置的,所以你受到保护,不会覆盖该文件。这是通过设置 "notedited" 标志来实现的。你可以使用
CTRL-G
或 ":file" 命令查看此标志是否已设置。如果设置了 "notedited" 标志,消息将包含 "[Not edited]"。当将缓冲区写入当前文件名(使用 ":w!")时,"notedited" 标志将被重置。
放弃 Vim 会记住你是否修改了缓冲区。你可以免受丢失所做的更改。如果你尝试在不写入的情况下退出,或者想要开始编辑另一个文件,Vim 将拒绝这样做。为了覆盖此保护,请在命令中添加一个 '!'。然后更改将丢失。例如:"q" 如果缓冲区已更改,则不起作用,但 ":q!" 将起作用。要查看缓冲区是否已更改,请使用 "CTRL-G" 命令。如果缓冲区已更改,消息将包含字符串 "[Modified]",或者如果 'm' 标志在
'shortmess' 中,则消息将包含 "+"。
:edit_# :e# :e[dit] [++opt] [+cmd] #[count] 编辑第 [count] 个缓冲区(如
:files 所示)。此命令与 [count]
CTRL-^
相同。但是,如果备用缓冲区没有文件名,则 ":e #" 不起作用,而
CTRL-^
仍然起作用。另请参阅
++opt 和
+cmd。
:{count}fin[d][!] [++opt] [+cmd]
{file}
与 ":find" 相同,但使用
'path' 中的第
{count}
个匹配项。因此,":2find file" 将在
'path' 中找到的第二个 "file" 进行查找。当
'path' 中的文件匹配项少于要求时,你将收到错误消息。
:ex :ex [++opt] [+cmd] [file] 与
:edit 相同。
CTRL-^ CTRL-6 CTRL-^
编辑备用文件。通常情况下,备用文件是之前编辑的文件。这是在两个文件之间快速切换的一种方法。它等同于 ":e #", 只是它在没有文件名时也能工作。
如果
'autowrite' 或
'autowriteall' 选项打开并且缓冲区已更改,则写入它。通常情况下,^ 字符位于 6 键上,按住 CTRL 并按下 6 键就会产生我们所说的
CTRL-^
。但在某些非美式键盘上,
CTRL-^
的产生方式不同。
{count}
CTRL-^
编辑缓冲区列表中的第 [count] 个文件(等同于 ":e #[count]")。这是在文件之间快速切换的一种方法。有关更多详细信息,请参见上面的
CTRL-^。
使 gf 始终像那样工作
:map gf :e <cfile><CR>
如果该名称是超文本链接,看起来像 "type://machine/path",则需要
netrw 插件。对于 Unix,'~' 字符将被展开,例如 "~user/file"。环境变量也将被展开
expand-env。
v_gf
{Visual}
[count]gf 与 "gf" 相同,但突出显示的文本将用作要编辑的文件的名称。
'isfname' 被忽略。将跳过前导空格,否则所有空格和特殊字符都将包含在文件名中。(有关
{Visual}
,请参见
Visual 模式。)
gF [count]gF 与 "gf" 相同,只是如果文件名后面跟着一个数字,则光标将定位在文件中的该行上。文件名和数字必须用非文件名(参见
'isfname')和非数字字符分隔。" line " 也被识别,就像它在
:verbose command UserCmd
的输出中使用一样。文件名、分隔符和数字之间的空格将被忽略。示例
eval.c:10
eval.c @ 20
eval.c (30)
eval.c 40
v_gF
{Visual}
[count]gF 与 "v_gf" 相同。
这些命令用于开始编辑单个文件。这意味着该文件将被读入缓冲区,并且当前文件名将被设置。打开的文件取决于当前目录,请参见
:cd。
如果弄乱了缓冲区并想重新开始,可以使用 ":e!" 命令。":e" 命令只有在更改了当前文件名时才有用。
注意:对于 Unix 以外的系统:在使用接受单个文件名的命令(例如 ":edit file")时,文件名中的空格是允许的,但尾随空格将被忽略。这在经常在文件名中嵌入空格的系统(例如 MS-Windows)上很有用。例如,命令 ":e Long File Name " 将编辑文件 "Long File Name"。在使用接受多个文件名的命令(例如 ":next file1 file2")时,嵌入的空格必须用反斜杠进行转义。
要避免通配符的特殊含义,请在前面添加一个反斜杠。但是,在 MS-Windows 上,反斜杠是路径分隔符,而 "path\[abc]" 在 "[" 在
'isfname' 选项中时仍被视为通配符。避免这种情况的一个简单方法是使用 "path\[[]abc]",这将匹配文件 "path\[abc]"。
starstar-wildcard 在 Unix、Win32、macOS 和少数其他系统上,可以展开 "**"(但这可能取决于你在 Unix 和 macOS 上的
'shell' 设置。已知它在 zsh 上可以正常工作;对于 bash,这需要至少 bash 版本 >= 4.X)。这允许搜索目录树。这将深入到 100 个目录。请注意,某些命令的执行方式略有不同,请参见
file-searching。示例
:n **/*.txt
查找文件
aaa.txt
subdir/bbb.txt
a/b/c/d/ccc.txt
当非通配符字符用在 "**" 的前面或后面时,它们只匹配顶层目录。它们不会用于树中更深层的目录。例如
:n /usr/inc**/types.h
查找文件
/usr/include/types.h
/usr/include/sys/types.h
/usr/inc/old/types.h
请注意,包含 "/sys" 的路径被包含在内,因为它不需要匹配 "/inc"。因此它就像匹配 "/usr/inc*/*/*...", 而不是 "/usr/inc*/inc*/inc*"。
backtick-expansion `-expansion 在 Unix 和少数其他系统上,还可以使用反引号作为文件名的参数,例如
:next `find . -name ver\\*.c -print`
:view `ls -t *.patch \| head -n1`
Vim 将使用
'shell' 运行反引号中的命令,并将标准输出用作给定 Vim 命令的参数(来自 shell 命令的错误消息将被丢弃)。要查看 Vim 运行的是哪个 shell 命令,请将
'verbose' 选项设置为 4。当 shell 命令返回非零退出代码时,将显示错误消息,并且 Vim 命令将被中止。要避免这种情况,请使 shell 始终返回零,如下所示
:next `find . -name ver\\*.c -print \|\| true`
星号前面的反斜杠是必需的,以防止 shell 在执行 find 程序之前展开 "ver*.c"。shell 管道符号 "|" 前面的反斜杠防止 Vim 将其解析为命令终止符。这也适用于大多数其他系统,但限制是反引号必须围绕整个项目。在第一个反引号的前面或最后一个反引号的后面直接放置文本是不可能的。
`= 可以通过在第一个反引号后面直接放置一个等号来将反引号扩展为 Vim 表达式,而不是作为外部命令,例如
:e `=tempname()`
表达式几乎可以包含任何内容,因此这也可用于避免 '"', "|", '%' 和 '#' 的特殊含义。但是,
'wildignore' 像其他通配符一样适用。
表达式中的环境变量在评估表达式时会被展开,因此这有效
:e `=$HOME .. '/.vimrc'`
这在字符串中使用 $HOME,它将被逐字使用,这很可能不是你想要的
:e `='$HOME' .. '/.vimrc'`
如果表达式返回一个字符串,则名称用换行符分隔。当结果是
List 时,每个项目将用作名称。换行符也分隔名称。请注意,此类表达式只在将文件名用作 Ex 命令参数的地方受支持。
{value}
不能包含空格。它可以是选项的任何有效值。示例
:e ++ff=unix
这将再次编辑同一个文件,并将
'fileformat' 设置为 "unix"。
:w ++enc=latin1 newfile
这将当前缓冲区写入 latin1 格式的 "newfile" 中。
可以有多个 ++opt 参数,用空格隔开。它们必须全部出现在任何
+cmd 参数之前。
++p "++p" 标志在文件不存在时创建文件的父目录。例如,如果编辑 "foo/bar/file.txt",则 ":write ++p" 命令在必要时创建 "foo/bar/",然后再写入文件。
:edit foo/bar/file.txt
:write ++p
如果希望 :write(不带 "++p")始终创建缺少的父目录,请将此 autocmd 添加到你的配置中
" Auto-create parent directories (except for URIs "://").
au BufWritePre,FileWritePre * if @% !~# '\(://\)' | call mkdir(expand('<afile>:p:h'), 'p') | endif
++bad "++bad=" 的参数指定对无法转换的字符和非法字节的处理方式。它可以是以下三种之一: ++bad=X 用单个字节字符替换每个错误字符。 ++bad=keep 保留错误字符而不进行转换。请注意,这可能会导致你的文本中出现非法字节! ++bad=drop 删除错误字符。
默认值类似于 "++bad=?":用问号替换每个错误字符。在某些地方,使用反问号 (0xBF)。
请注意,并非所有命令都使用 ++bad 参数,即使在添加该参数时它们不会报错。例如,
:write。
+cmd [+cmd] [+cmd] 参数可以用来定位光标在新建文件中打开的位置,或者执行其他命令:+ 从最后一行开始。+{num} 从第
{num}
行开始。+/{pat} 从包含
{pat}
的第一行开始。+{command} 在打开新文件后执行
{command}
命令。
{command}
可以是任何 Ex 命令。如果要在
{pat}
或
{command}
中包含空格,请在空格前加反斜杠。反斜杠要加倍。
:edit +/The\ book file
:edit +/dir\ dirname\\ file
:edit +set\ dir=c:\\\\temp file
请注意,在最后一个例子中,反斜杠的数量被减半了两次:一次是由于 "+cmd" 参数,一次是由于 ":set" 命令。
在读取文件时,上述字符会被解释为
<EOL>
。在 DOS 格式(Windows 的默认格式)中,
<CR>
<NL>
和
<NL>
都被解释为
<EOL>
。请注意,在以 DOS 格式写入文件时,对于每个单独的
<NL>
,都会添加
<CR>
字符。另请参见
file-read.
你可以以 DOS 格式读取文件并以 Unix 格式写入文件。这将用
<NL>
替换所有
<CR>
<NL>
对(假设
'fileformats' 包含 "dos")
:e file
:set fileformat=unix
:w
如果你以 Unix 格式读取文件并以 DOS 格式写入文件,所有
<NL>
字符将被替换为
<CR>
<NL>
(假设
'fileformats' 包含 "unix")
:e file
:set fileformat=dos
:w
如果你开始编辑一个新文件,并且
'fileformats' 选项不为空(默认情况),Vim 会尝试检测文件中行的分隔符是否使用指定的格式。当设置为 "unix,dos" 时,Vim 会检查以单个
<NL>
(在 Unix 上使用)或
<CR>
<NL>
对(MS-Windows)结尾的行。只有当所有行都以
<CR>
<NL>
结尾时,
'fileformat' 才会被设置为 "dos",否则它会被设置为 "unix"。当
'fileformats' 包含 "mac" 时,并且在文件中没有找到
<NL>
字符,
'fileformat' 会被设置为 "mac"。
如果在非 MS-Windows 系统上将
'fileformat' 选项设置为 "dos",则会显示 "[dos]" 消息来提醒你发生了异常情况。在 MS-Windows 系统上,如果
'fileformat' 被设置为 "unix",则会显示 "[unix]" 消息。在所有系统上,如果
'fileformat' 被设置为 "mac",则会显示 "[mac]" 消息。
如果
'fileformats' 选项为空并且使用 DOS 格式,但在读取文件时,某些行没有以
<CR>
<NL>
结尾,则 "[CR missing]" 会包含在文件消息中。如果
'fileformats' 选项为空并且使用 Mac 格式,但在读取文件时找到了
<NL>
,则 "[NL missing]" 会包含在文件消息中。
在编辑二进制、可执行文件或 Vim 脚本文件之前,应设置
'binary' 选项。一种简单的方法是使用 "-b" 选项启动 Vim。这将避免使用
'fileformat'。如果没有这样做,你可能会遇到单个
<NL>
字符被意外替换为
<CR>
<NL>
的风险。
前三个值通常在读取文件时自动检测,并在将文本写入文件时使用。在编辑缓冲区时,它看起来好像每一行都有行尾,并且没有
CTRL-Z
(当
'binary' 被设置时除外,它会以不同的方式工作)。
以下是一些使用它们的示例。
如果你想将文件保存为 Unix 格式(每行以 NL 结尾)
setl ff=unix fixeol
你应该在任何类 Unix 系统上执行此操作。此外,现代 MS-Windows 系统也倾向于与此格式良好地配合使用。建议始终使用此格式作为 Vim 脚本。
如果你想在现代环境中使用旧的 MS-DOS 文件,修复行尾并删除
CTRL-Z
,但保持
<CR>
<NL>
样式
<EOL>
setl ff=dos fixeol
这对于许多 MS-Windows 程序来说很有用,它们通常希望使用
<CR>
<NL>
行尾。
如果你想删除最终的
<EOL>
并添加一个最终的
CTRL-Z
(例如,对于像 CP/M 这样的旧系统)
setl ff=dos nofixeol noeol eof
如果你想完全保留文件格式,包括任何最终的
<EOL>
和最终的
CTRL-Z
setl nofixeol
如果你在启动 Vim 时给出多个文件名,这个列表将被记住作为参数列表。你可以跳转到这个列表中的每个文件。
不要将此与缓冲区列表混淆,你可以使用
:buffers 命令查看缓冲区列表。参数列表在 Vi 中已经存在,缓冲区列表是 Vim 中的新功能。参数列表中的每个文件名也会出现在缓冲区列表中(除非它被
:bdel 或
:bwipe 删除)。但缓冲区列表中通常会有参数列表中没有的名称。
有一个全局参数列表,默认情况下它被所有窗口使用。可以为窗口创建本地参数列表,请参见
:arglocal.
你可以使用以下命令以及表达式函数
argc() 和
argv() 来使用参数列表。这些命令都在当前窗口的参数列表上工作。
:ar[gs] [++opt] [+cmd]
{arglist}
:args_f将
{arglist}
定义为新的参数列表并编辑第一个文件。当对当前缓冲区进行了更改并且 Vim 不想
放弃 当前缓冲区时,此操作会失败。另请参见
++opt 和
+cmd.
:ar[gs]! [++opt] [+cmd]
{arglist}
:args_f!将
{arglist}
定义为新的参数列表并编辑第一个文件。丢弃对当前缓冲区的任何更改。另请参见
++opt 和
+cmd.
:[count]arge[dit][!] [++opt] [+cmd]
{name}
..
:arge :argedit 将
{name}
添加到参数列表并编辑它。没有检查重复项,可以将一个文件添加到参数列表两次
:argded。这就像使用
:argadd 然后
:edit(唯一的区别是
:edit 不会更改参数列表,因此参数列表指针不会改变)。文件名中的空格必须用 "\" 转义。[count] 的使用方法与
:argadd 相同。如果当前文件无法被
放弃,则
{name}
仍将被添加到参数列表中,但不会被编辑。不会检查重复项。另请参见
++opt 和
+cmd.
:[count]arga[dd]
{name}
..
:arga :argadd E479 :[count]arga[dd]
E1156将
{name}
添加到参数列表中。当省略
{name}
时,将当前缓冲区名称添加到参数列表中。如果省略了 [count],则
{name}
会被添加到参数列表中当前条目的后面。否则,它们将被添加到第 [count] 个文件之后。如果参数列表是 "a b c",并且 "b" 是当前参数,则这些命令将导致
命令 新参数列表
:argadd x a [b] x c :0argadd x x a [b] c :1argadd x a x [b] c :$argadd x a [b] c x 以及最后一个::+2argadd y a [b] c x y 没有检查重复项,可以将一个文件添加到参数列表两次。你可以使用
:argdedupe 在之后进行修复
:argadd *.txt | argdedupe
当前正在编辑的文件不会改变。
注意:你也可以使用这种方法
:args ## x
这将添加 "x" 项目并对新列表进行排序。
:argd[elete]
{pattern}
..
:argd :argdelete E480 E610 从参数列表中删除与
{pattern}
匹配的文件。
{pattern}
的使用方法与文件模式相同,请参见
file-pattern。 "%" 可以用来删除当前条目。此命令会保留当前编辑的文件,即使它从参数列表中删除也是如此。示例
:argdel *.obj
:[range]argd[elete] 从参数列表中删除第 [range] 个文件。示例
:10,$argdel
删除第 10 个及以后的参数,保留 1-9 个参数。
:$argd
从参数列表中删除所有文件。当范围中的最后一个数字过高时,将删除最后一个参数之前的参数。
:argu :argument :[count]argu[ment] [count] [++opt] [+cmd] 编辑参数列表中的第 [count] 个文件。当省略 [count] 时,使用当前条目。当对当前缓冲区进行了更改并且 Vim 不想
放弃 当前缓冲区时,此操作会失败。另请参见
++opt 和
+cmd.
:[count]argu[ment]! [count] [++opt] [+cmd] 编辑参数列表中的第 [count] 个文件,丢弃对当前缓冲区的任何更改。当省略 [count] 时,使用当前条目。另请参见
++opt 和
+cmd.
:[count]n[ext]! [++opt] [+cmd] 编辑 [count] 个下一个文件,丢弃对缓冲区的任何更改。另请参阅
++opt和
+cmd。
:n[ext]! [++opt] [+cmd]
{arglist}
与
:args_f!相同。
:[count]N[ext] [count] [++opt] [+cmd]
:Next :N E164 编辑参数列表中 [count] 个前一个文件。如果已经修改过文件并且 Vim 不想
放弃当前缓冲区,则会失败。另请参阅
++opt和
+cmd。
:[count]N[ext]! [count] [++opt] [+cmd] 编辑参数列表中 [count] 个前一个文件。丢弃对缓冲区的任何更改。另请参阅
++opt和
+cmd。
:rew[ind]! [++opt] [+cmd] 开始编辑参数列表中的第一个文件。丢弃对缓冲区的任何更改。另请参阅
++opt和
+cmd。
:fir :first :fir[st][!] [++opt] [+cmd] ":rewind" 的另一种名称。
:la[st]! [++opt] [+cmd] 开始编辑参数列表中的最后一个文件。丢弃对缓冲区的任何更改。另请参阅
++opt和
+cmd。
:[count]wn[ext] [++opt]
{file}
将当前文件写入
{file}
并开始编辑 [count] 个下一个文件,除非
{file}
已经存在且
'writeany'选项已关闭。另请参阅
++opt和
+cmd。
:[count]wn[ext]! [++opt]
{file}
将当前文件写入
{file}
并开始编辑 [count] 个下一个文件。另请参阅
++opt和
+cmd。
:[count]wN[ext][!] [++opt] [file]
:wN :wNext :[count]wp[revious][!] [++opt] [file]
:wp :wprevious 与 :wnext 相同,但转到前一个文件而不是下一个文件。
上述命令中的 [count] 默认值为 1。对于某些命令,可以使用两个计数。最后一个(最右边的)计数将被使用。
如果没有 [+cmd] 参数,则光标将定位在该文件的最后一个已知光标位置。如果
'startofline'设置了,则光标将定位在该行的第一个非空白字符,否则将使用最后一个已知列。如果没有最后一个已知光标位置,则光标将位于第一行(Ex 模式下的最后一行)。
{arglist} 参数列表中的通配符将被扩展,文件名将被排序。因此,您可以使用命令
vim *.c
来编辑所有 C 文件。从 Vim 内部,命令
:n *.c
执行相同操作。
使用空格来分隔文件名。在空格或制表符之前放置反斜杠,以将其包含在文件名中。例如,要编辑单个文件“foo bar”
:next foo\ bar
在 Unix 和其他一些系统上,您还可以使用反引号,例如
:next `find . -name \\*.c -print`
星号前面的反斜杠是必需的,以防止在执行 find 程序之前,shell 扩展“*.c”。
arglist-position 当存在参数列表时,您可以在窗口标题(如果有,并且
'title'已开启)以及使用“CTRL-G”命令获得的文件消息中看到您正在编辑哪个文件。您将看到类似于 (4 of 11) 的内容。如果您没有真正编辑参数列表中当前位置的文件,它将是 ((4) of 11)。这意味着您在参数列表中位于第 4 位,但没有编辑参数列表中的第四个文件。当您执行“:e file”时,就会发生这种情况。
LOCAL ARGUMENT LIST
:arglocal :argl[ocal] 创建全局参数列表的本地副本。不会开始编辑另一个文件。
:argl[ocal][!] [++opt] [+cmd]
{arglist}
定义一个新的参数列表,该列表对于当前窗口是本地的。否则,与
:args_f类似。
:argglobal :argg[lobal] 对当前窗口使用全局参数列表。不会开始编辑另一个文件。
:argg[lobal][!] [++opt] [+cmd]
{arglist}
对当前窗口使用全局参数列表。像
:args_f一样定义一个新的全局参数列表。所有使用全局参数列表的窗口都将看到这个新列表。
可以有多个参数列表。它们可以在窗口之间共享。当它们被共享时,在一个窗口中更改参数列表也会在另一个窗口中更改它。
USING THE ARGUMENT LIST
:argdo :[range]argdo[!]
{cmd}
对参数列表中的每个文件执行
{cmd}
,或者,如果指定了 [range],则仅对该范围内的参数执行
{cmd}
。它的工作方式类似于执行以下操作
:rewind
:{cmd}
:next
:{cmd}
etc.
示例
:args *.c
:argdo set ff=unix | update
这将
'fileformat'选项设置为“unix”,并在更改后写入文件。这将对所有
*.c
文件执行。
示例
:args *.[ch]
:argdo %s/\<my_foo\>/My_Foo/ge | update
这将所有 "*.c" 和 "*.h" 文件中的“my_foo”更改为“My_Foo”。“e”标志用于“:substitute”命令,以避免针对没有使用“my_foo”的文件出现错误。“:update”仅在进行了更改时才写入文件。
:w[rite]! [++opt] 类似于“:write”,但在
'readonly'设置或存在其他拒绝写入的原因时,强行写入。
注意: 这可能会更改文件的权限和所有权,并破坏(符号)链接。将“W”标志添加到
'cpoptions'以避免这种情况。
:[range]w[rite][!] [++opt] 将指定的行写入当前文件。这很不寻常,因为文件将不包含缓冲区中的所有行。
:w! :[range]w[rite]! [++opt]
{file}
将指定的行写入
{file}
。覆盖现有文件。
:w_a :write_a E494 :[range]w[rite][!] [++opt] >
Append the specified lines to the current file.
:[range]w[rite][!] [++opt] >>
{file}
将指定的行追加到
{file}
。'!' 强制写入,即使文件不存在。
:w_c :write_c :[range]w[rite] [++opt] !{cmd} 使用 [range] 行作为标准输入执行
{cmd}
(注意前面的空格)。
{cmd}
像“:!{cmd}”一样执行,任何“!”都将被替换为前一个命令
:!。
“:w”命令的默认 [range] 是整个缓冲区 (1,$)。如果您写入整个缓冲区,它将不再被视为已更改。当您使用“:w somefile”将其写入不同的文件时,这取决于
'cpoptions'中的“+”标志。如果包含在内,写入命令将重置
'modified'标志,即使缓冲区本身可能仍然与其文件不同。
如果使用“:w”给出文件名,它将成为备用文件。这可以用在以下情况下,例如,当写入失败时,您想稍后使用“:w #”重试。这可以通过从
'cpoptions'选项中删除“A”标志来关闭。
请注意,
'fsync'选项在此处很重要。如果它被设置了,它可能会使写入速度变慢(但更安全)。
:sav :saveas :sav[eas][!] [++opt]
{file}
使用
{file}
作为名称保存当前缓冲区,并将当前缓冲区的文件名设置为
{file}
。以前的名称将用于备用文件名。需要 [!] 来覆盖现有文件。当
'filetype'为空时,将使用新名称执行文件类型检测,然后写入文件。如果写入成功,
'readonly'将被重置。
:up :update :[range]up[date][!] [++opt] [>>] [file] 类似于 ":write",但只有在缓冲区被修改时才写入。
:wa :wall :wa[ll] 写入所有已更改的缓冲区。没有文件名的缓冲区会引发错误消息。只读的缓冲区不会被写入。
:wa[ll]! 写入所有已更改的缓冲区,包括只读的缓冲区。没有文件名的缓冲区不会被写入,并会引发错误消息。
如果您尝试覆盖已在其他地方更改的文件(除非使用“!”),Vim 会发出警告。请参阅
timestamp。
backup-table
off off 未创建备份 off on 备份当前文件,之后删除(默认) on off 删除旧备份,备份当前文件 on on 删除旧备份,备份当前文件
在某些文件系统中,在崩溃时可能同时丢失备份文件和新写入的文件(文件可能存在,但包含错误数据)。在这种情况下,请尝试恢复,因为交换文件已同步到磁盘,并且可能仍然存在。
:recover
备份是新文件(它是原始文件的副本)还是重命名的原始文件取决于
'backupcopy' 选项。请参阅该选项以了解何时创建副本以及何时重命名文件。
如果创建备份文件失败,则不会执行写入操作。如果您仍然要写入,请在命令中添加“!”。
file-watcher 如果您发现程序存在问题,这些程序会在写入缓冲区时执行(如 inotify、entr 或 fswatch),或者外部应用程序执行 Vim 来编辑文件(如 git),并且这些程序似乎没有注意到原始文件已更改,您可能需要考虑将
'backupcopy' 选项值切换到“yes”。这将确保 Vim 写入这些观察程序期望的同一文件,而不会创建新文件(这将阻止它们检测到文件已更改)。另请参阅
crontab
write-permissions 写入新文件时,权限为读写。对于 unix,掩码为 0o666,并额外应用了 umask。写入只读文件时,Vim 会保留权限,但会清除 s-bit。
write-fail 如果写入新文件失败,您必须小心,不要丢失更改和原始文件。如果不存在备份文件并且写入新文件失败,则您已经丢失了原始文件!在写入文件之前不要退出 Vim!如果创建了备份文件,则会将其放回原始文件的位置(如果可能)。如果您退出 Vim 并丢失了所做的更改,则原始文件大部分仍然存在。如果放回原始文件失败,则会出现错误消息,告知您丢失了原始文件。
ACL ACL 代表访问控制列表。它是一种控制文件访问权限的高级方法。它用于新的 MS-Windows 和 Unix 系统,但仅在文件系统支持时才使用。Vim 尝试在写入文件时保留 ACL 信息。备份文件将获得原始文件的 ACL 信息。ACL 信息还用于检查文件是否为只读(打开文件时)。
xattr E1506 E1508 E1509 xattr 代表扩展属性。它是一种在文件系统中将元数据与文件一起保存的高级方法。它取决于使用的实际文件系统,而 Vim 仅在 Linux 系统上支持它。Vim 尝试在写入文件时保留扩展属性信息。备份文件将获得原始文件的扩展属性。
read-only-share 当 MS-Windows 在网络上共享驱动器时,可以将其标记为只读。这意味着,即使文件只读属性不存在,并且 NT 网络共享驱动器上的 ACL 设置允许写入文件,您仍然无法写入文件。Win32 平台上的 Vim 会检测只读网络驱动器,并将文件标记为只读。您无法使用
:write 覆盖它。
write-device 如果文件名实际上是设备名称,Vim 不会创建备份(这将是不可能的)。您需要使用“!”,因为设备已经存在。Unix 和 MS-Windows 的示例
:w! /dev/lpt0
和 MS-Windows
:w! lpt0
对于 Unix,当名称不引用普通文件或目录时,就会检测到设备。FIFO 或命名管道在 Vim 看来也像是设备。对于 MS-Windows,通过其名称来检测设备:CON CLOCK$ NUL PRN COMn n=1,2,3... 等 LPTn n=1,2,3... 等 这些名称可以是大写或小写。
:q[uit]! 不写入退出,即使当前缓冲区有更改也是如此。缓冲区将被卸载,即使它已设置
'hidden' 也是如此。如果这是最后一个窗口,并且存在修改过的隐藏缓冲区,则会放弃当前缓冲区,并且第一个修改过的隐藏缓冲区将变为当前缓冲区。使用 ":qall!" 始终退出。
:cq[uit] 始终退出,不写入,并返回错误代码。请参阅
:cq。
:wq :wq [++opt] 写入当前文件并关闭窗口。如果这是最后一个
edit-window,则 Vim 会退出。如果文件为只读或缓冲区没有名称,则写入会失败。如果参数列表中的最后一个文件尚未被编辑,则退出会失败。
:wq! [++opt] 写入当前文件并关闭窗口。如果这是最后一个
edit-window,则 Vim 会退出。如果当前缓冲区没有名称,则写入会失败。
:wq [++opt]
{file}
写入
{file}
并关闭窗口。如果这是最后一个
edit-window,则 Vim 会退出。如果参数列表中的最后一个文件尚未被编辑,则退出会失败。
:wq! [++opt]
{file}
写入
{file}
并关闭当前窗口。如果这是最后一个
edit-window,则退出 Vim。
:[range]wq[!] [++opt] [file] 与上述操作相同,但仅写入 [range] 中的行。
:x :xit :[range]x[it][!] [++opt] [file] 类似于 ":wq",但仅在进行更改时才写入。如果已设置
'hidden' 并且存在多个窗口,则在写入文件后,当前缓冲区将变为隐藏状态。
:exi :exit :[range]exi[t][!] [++opt] [file] 与 :xit 相同。
ZZ ZZ 写入当前文件(如果已修改),并关闭当前窗口(与 ":x" 相同)。如果当前文件存在多个窗口,则仅关闭当前窗口。
ZQ ZQ 不检查更改退出(与 ":q!" 相同)。
:conf[irm] qa[ll] 退出 Vim。当一些缓冲区已更改时,会显示提示。请参阅
:confirm。
:qa[ll]! 退出 Vim。对缓冲区的任何更改都将丢失。另请参阅
:cquit,它执行相同的操作,但退出时返回值为非零。
:wqa[ll] [++opt]
:wqa :wqall :xa :xall :xa[ll] 写入所有已修改的缓冲区并退出 Vim。如果存在没有文件名的缓冲区,或者该缓冲区是只读的,或者由于其他原因无法写入,Vim 不会退出。
:conf[irm] wqa[ll] [++opt] :conf[irm] xa[ll] 写入所有已修改的缓冲区并退出 Vim。如果存在只读的缓冲区或由于其他原因无法写入的缓冲区,则会弹出提示。请参阅
:confirm。
:wqa[ll]! [++opt] :xa[ll]! 写入所有已修改的缓冲区(即使是只读的),并退出 Vim。如果存在没有文件名的缓冲区,或者由于其他原因无法写入的缓冲区,Vim 不会退出。
当 "foo" 已经存在时,会要求确认。
:confirm q
如果存在已修改的未保存的缓冲区,系统会提示您保存或放弃每个缓冲区。还可以选择 "保存所有" 或 "放弃所有"。
最佳语法可以通过一些示例展示
:browse e $vim/foo
在 $vim/foo 目录中打开浏览器,并编辑所选文件。
:browse e
在当前缓冲区的目录中打开浏览器,使用当前缓冲区的文件名作为默认值,并将缓冲区保存到所选文件名。
:browse w C:/bar
在 C:/bar 目录中打开浏览器,使用当前缓冲区的文件名作为默认值,并将缓冲区保存到所选文件名。另请参阅
'browsedir' 选项。对于不支持浏览的 Vim 版本,该命令将按原样执行。
browsefilter 对于 MS-Windows,您可以修改浏览对话框中使用的过滤器。通过设置 g:browsefilter 或 b:browsefilter 变量,您可以全局或局部更改缓冲区的过滤器。该变量被设置为格式为 "{filter label}\t{pattern};{pattern}\n" 的字符串,其中 "{filter label}" 是出现在 "Files of Type" 组合框中的文本,而
{pattern}
是过滤文件名的模式。可以使用多个模式,用 ";" 分隔。
例如,要使对话框中只显示 Vim 文件,您可以使用以下命令
let g:browsefilter = "Vim scripts\t*.vim\nVim Startup Files\t*vimrc\n"
您可以通过设置 b:browsefilter 变量,在每个缓冲区的基础上覆盖过滤器设置。您最有可能在文件类型插件中设置 b:browsefilter,这样浏览对话框就会包含与您当前编辑的文件类型相关的条目。缺点:这使得难以开始编辑不同类型的文件。为了克服这个问题,您可能希望在 Windows 上将 "All Files (
.)\t*\n" 作为最后一个过滤器添加,或者在其他平台上添加 "All Files (
)\t\n",这样用户就可以访问任何所需的文件。
为了避免在 Vim 实际上不支持浏览过滤器时设置 browsefilter,您可以使用 has("browsefilter")
if has("browsefilter")
let g:browsefilter = "whatever"
endif
您可以使用
:cd、
:tcd 和
:lcd 更改到另一个目录,这样您就不必在文件名前面输入该目录名。它还会对执行外部命令产生影响,例如 ":!ls" 或 ":te ls"。
存在三种 "作用域" 的当前目录:全局、标签页和窗口。窗口级别的工作目录优先于标签页级别的工作目录,标签页级别的工作目录优先于全局工作目录。如果本地工作目录(标签页或窗口)不存在,则将应用层次结构中下一个更高的作用域。
:cd[!]
{path}
将当前目录更改为
{path}
。如果
{path}
是相对路径,则将在
'cdpath' 中列出的目录中搜索该路径。清除任何窗口级别的目录。不会更改已打开文件的含义,因为会记住其完整路径名。但是,来自
arglist 的文件可能会更改!在 MS-Windows 上,这还会更改活动驱动器。要更改到当前文件的目录
:cd %:h
:cd- E186 :cd[!] - 更改到之前的当前目录(在之前的 ":cd
{path}
" 命令之前)。
:tc :tcd :tc[d][!]
{path}
与
:cd 相同,但仅设置当前标签页的目录。当前窗口也将使用此目录。其他标签页中的窗口以及当前标签页中具有自身窗口级别目录的窗口的当前目录不会更改。
:tcd- :tc[d][!] - 更改到之前的当前目录(在之前的 ":tcd
{path}
" 命令之前)。
:lc :lcd :lc[d][!]
{path}
与
:cd 相同,但仅设置当前窗口的当前目录。其他窗口或标签页的当前目录不会更改。
:lcd- :lc[d][!] - 更改到之前的当前目录(在之前的 ":lcd
{path}
" 命令之前)。
:pw :pwd E187 :pw[d] 打印当前目录名。另请参阅
getcwd()。
:pwd-verbose当
'verbose' 不为零时,
:pwd 还将显示当前目录的作用域。例如
" Set by :cd
:verbose pwd
[global] /path/to/current
" Set by :lcd
:verbose pwd
[window] /path/to/current
" Set by :tcd
:verbose pwd
[tabpage] /path/to/current
只要没有使用过
:lcd 或
:tcd 命令,所有窗口都共享相同的当前目录。使用命令跳转到另一个窗口不会对当前目录造成任何影响。
当
:lcd 已用于某个窗口时,指定的目录将成为该窗口的当前目录。没有使用过
:lcd 命令的窗口将保留全局或标签页级别的目录。当跳转到另一个窗口时,当前目录将更改为最后指定的本地当前目录。如果没有指定本地当前目录,则使用全局或标签页级别的目录。当创建新窗口时,它将继承当前窗口的本地目录。
当更改标签页时,将应用相同的行为。如果当前标签页没有本地工作目录,则使用全局工作目录。
当使用
:cd 命令时,当前窗口和标签页将丢失其本地当前目录,并将从现在开始使用全局当前目录。当使用
:tcd 命令时,只有当前窗口将丢失其本地工作目录。
使用
:cd 后,将使用完整路径名来读取和写入文件。在某些网络文件系统上,这可能会导致问题。使用完整路径名的结果是,当前正在使用的文件名将继续引用同一个文件。例如:如果您有一个文件 a:test 和一个目录 a:vim,则命令 ":e test" ":cd vim" ":w" 将覆盖文件 a:test 而不是写入 a:vim/test。但是,如果您执行 ":w test",则将写入文件 a:vim/test,因为您给出了新的文件名,并且没有引用 ":cd" 之前的文件名。
编辑二进制文件时需要注意一些事项。
编辑可执行文件时,字节数不能改变。只使用 "R" 或 "r" 命令来更改文本。不要使用 "x" 或退格键删除字符。
当没有很多
<EOL>
时,行会变得很长。如果要编辑不适合屏幕的线,请重置
'wrap' 选项。然后将使用水平滚动。如果一行变得太长(参见
限制),则无法编辑该行。读取文件时该行将被拆分。读取文件时也可能出现“内存不足”错误。
在加载文件之前确保
'binary' 选项已设置。否则,
<CR>
<NL>
和
<NL>
都被视为行结束符,当文件写入时,
<NL>
将被替换为
<CR>
<NL>
。
<Nul>
字符在屏幕上显示为 ^@。可以使用 "CTRL-V CTRL-@
" 或 "CTRL-V 000" 输入它们。
要在文件中插入 <NL>
字符,请拆分一行。当将缓冲区写入文件时,<NL>
将被写入 <EOL>
。
Vim 通常会在文件末尾添加一个
<EOL>
(如果不存在)。设置
'binary' 选项会阻止这种情况。如果要添加最终的
<EOL>
,请设置
'endofline' 选项。还可以读取此选项的值以查看最后一行的
<EOL>
是否存在(您无法在文本中看到它)。
Vim 会在您开始编辑文件时记住文件的修改时间戳、模式和大小。这用于避免您拥有同一个文件的两个不同版本(而您对此毫不知情)。
E321 E462 如果要在外界更改文件时自动重新加载文件,请设置
'autoread' 选项。但是,这在您写入文件时不起作用,而只在 Vim 内部未更改文件时才起作用。
忽略时间戳如果您不想被询问或自动重新加载文件,可以使用以下方法
set buftype=nofile
或者,从 Shell 启动 gvim 时
gvim file.log -c "set buftype=nofile"
请注意,如果定义了 FileChangedShell 自动命令,您将不会收到警告消息或提示。预计自动命令将处理此问题。
目录不会发出警告(例如,使用
netrw-browse)。但是,如果您开始编辑一个新文件,并且该文件后来被创建为目录,您会收到警告。
当 Vim 发现文件的时间戳已更改,并且该文件正在缓冲区中编辑但未更改时,Vim 会检查文件的内容是否相等。这是通过再次读取文件(进入隐藏缓冲区,该缓冲区立即再次删除)并比较文本来完成的。如果文本相等,您将不会收到警告。
如果您没有经常收到警告,可以使用以下命令。
:checkt :checktime :checkt[ime] 检查任何缓冲区是否已在外界更改。这会检查并警告您,如果最终会得到文件的两个版本。如果从自动命令、“:global”命令调用,或者未键入,则实际检查将推迟到副作用(重新加载文件)无害的时刻。每个已加载的缓冲区都会检查其关联的文件是否已更改。如果文件已更改,Vim 将采取措施。如果缓冲区中没有更改并且设置了
'autoread',则会重新加载缓冲区。否则,会提供重新加载文件的选项。如果文件已删除,您会收到错误消息。如果文件以前不存在,您会收到警告(如果现在存在)。文件一经检查,时间戳就会重置,您将不再收到警告。语法高亮显示、标记、diff 状态、
'fileencoding'、
'fileformat' 和
'binary' 选项不会更改。参见
v:fcs_choice 以重新加载这些内容(例如,如果代码格式化工具已更改文件)。
:[N]checkt[ime] {filename}
:[N]checkt[ime] [N] 检查特定缓冲区的时间戳。缓冲区可以使用名称、编号或模式来指定。
E813 E814 如果您选择重新加载,Vim 会重新加载缓冲区。如果包含此缓冲区的窗口可见,则重新加载将在该窗口的上下文中进行。否则,将使用一个特殊窗口,以便大多数自动命令都能正常工作。您无法关闭此窗口。还有一些其他限制适用。最好的方法是确保在当前缓冲区之外不会发生任何操作。例如,设置窗口局部选项可能会导致错误的窗口。拆分窗口,在其中执行操作,然后关闭它应该没问题(如果其他自动命令没有副作用)。关闭不相关的窗口和缓冲区会让您陷入困境。
在写入文件之前,会检查时间戳(除非使用了“!”)。如果时间戳已更改,Vim 会询问您是否确实要覆盖该文件。
警告:该文件自读取后已被更改!您真的要写入它吗 (y/n)?
如果按“y”,Vim 将继续写入文件。如果按“n”,写入将中止。如果您使用了“:wq”或“ZZ”,Vim 不会退出,您将获得另一个写入文件的機會。
该消息通常意味着有人在编辑会话开始后向该文件写入内容。这可能是另一个人,在这种情况下,您可能需要检查您对文件的更改和来自其他人的更改是否应该合并。将文件写入另一个名称,并检查差异(可以使用“diff”程序)。
也有可能您自己修改了文件,从另一个编辑会话或使用其他命令(例如,过滤器命令)修改了。然后您就会知道要保留哪个版本的ファイル。
时间检查的准确性取决于文件系统。在 Unix 上,它通常是亚秒级。对于旧的文件系统和 MS-Windows,它通常是一秒。使用 has('nanotime')
检查亚秒级时间戳检查是否可用。
有一种情况您会在没有错误的情况下收到该消息:在 Win32 系统上,在夏令时开始的那天。Win32 库中有一些东西会让 Vim 对小时时差感到困惑。这个问题会在第二天消失。
搜索有三种不同的类型
1) 向下搜索:
星号星号向下搜索使用通配符“*”、“**”以及您的操作系统可能支持的其他通配符。“*”和“**”在 Vim 内部处理,因此在所有操作系统上都能正常工作。请注意,“**”只有在它位于名称开头时才充当特殊通配符。
“*”的使用非常简单:它匹配 0 个或多个字符。在搜索模式中,这将是“.*”。请注意,“.”不用于文件搜索。
“**”更为复杂
它只匹配目录。
默认情况下,它最多匹配 30 个目录深度,因此可以使用它来搜索整个目录树
可以将数字附加到“**”来指定匹配的级别数。因此,“/usr/**2”可以匹配
/usr
/usr/include
/usr/include/sys
/usr/include/g++
/usr/lib
/usr/lib/X11
....
它不匹配“/usr/include/g++/std”,因为这将是三个级别。允许的数字范围是 0(“**0”将被删除)到 100。如果给定的数字小于 0,则默认为 30,如果大于 100,则使用 100。系统对路径长度也有限制,通常是 256 或 1024 字节。
“**”只能位于路径的末尾,或者后面跟着路径分隔符,或者后面跟着数字和路径分隔符。
可以按任何顺序组合“*”和“**”
/usr/**/sys/*
/usr/*tory/sys/**
/usr/**2/sys/*
2) 向上搜索:在此,您可以指定一个目录,然后向上搜索目录树以查找文件。您可以提供停止目录来限制向上搜索。停止目录使用“;”附加到路径(对于
'path' 选项)或文件名(对于
'tags' 选项)。如果要使用多个停止目录,请使用“;”将它们分隔开。如果不想使用停止目录(“向上搜索到根目录”),只需使用“;”。
/usr/include/sys;/usr
将在以下位置进行搜索
/usr/include/sys
/usr/include
/usr
如果使用相对路径,则向上搜索将从 Vim 的当前目录或当前文件的目录开始(如果相对路径以“./”开头并且
'cpoptions' 中不包含“d”)。
如果 Vim 的当前路径是 /u/user_x/work/release,而您执行了以下操作
:set path=include;/u/user_x
然后使用
gf 搜索文件,该文件将在以下位置进行搜索
/u/user_x/work/release/include
/u/user_x/work/include
/u/user_x/include
注意:如果您的
'path' 设置包含一个不存在的目录,Vim 将跳过该不存在的目录,并且如果使用向上搜索,也不会在不存在的目录的父目录中进行搜索。
3) 结合向上/向下搜索:如果 Vim 的当前路径为 /u/user_x/work/release,并且您执行
set path=**;/u/user_x
然后使用
gf 搜索文件,该文件将在以下位置进行搜索
/u/user_x/work/release/**
/u/user_x/work/**
/u/user_x/**
注意!这可能会占用大量时间,因为搜索 '/u/user_x/**' 包含 '/u/user_x/work/**' 和 '/u/user_x/work/release/**'。所以 '/u/user_x/work/release/**' 被搜索了三次,而 '/u/user_x/work/**' 被搜索了两次。
在上面的例子中,您可能希望将 path 设置为
:set path=**,/u/user_x/**
这将搜索
/u/user_x/work/release/**
/u/user_x/**
这搜索了相同的目录,但顺序不同。
请注意,":find"、":sfind" 和 ":tabfind" 命令的自动完成目前不适用于
'path' 中包含 URL 或使用双星号带深度限制 (/usr/**2) 或向上搜索 (;) 符号的项。
管理可信文件。如果没有 ++ 选项,:trust 会将当前缓冲区标记为可信,并使用其内容的哈希值作为键。可信列表存储在磁盘上,Nvim 在重新启动后会重复使用它。
[++deny] 将 [file](如果没有 [file] 则为当前缓冲区)标记为不可信:它永远不会被执行,
'exrc' 将忽略它。