Tagsrch

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


标签和特殊搜索
参见用户手册第 29.1 节的介绍。

1. 跳转到标签 tag-commands

tag tags 标签是在“tags”文件中出现的标识符。它是一种可以跳转到的标签。例如:在 C 程序中,每个函数名都可以用作标签。“tags”文件必须由像 ctags 这样的程序生成,才能使用标签命令。
使用“:tag”命令,光标将定位在标签上。使用CTRL-] 命令,光标所在的关键字将用作标签。如果光标不在关键字上,则使用光标右侧的第一个关键字。
“:tag”命令对 C 程序非常有效。如果您看到一个对函数的调用并想知道该函数的功能,将光标定位在函数名内并按下CTRL-]。这将带您到函数定义。一种简单的返回方式是使用CTRL-T 命令。另请阅读下面关于标签栈的内容。
:ta :tag E426 E429 :[count]ta[g][!] {name} 跳转到{name}的定义,使用 tags 文件中的信息。将{name} 放入标签栈。有关 [!] 的信息,请参见 tag-!{name} 可以是正则表达式模式,请参见 tag-regexp。当有多个匹配{name} 的标签时,跳转到第 [count] 个。当省略 [count] 时,跳转到第一个。有关跳转到其他匹配标签的信息,请参见 tag-matchlist
g<LeftMouse> g<LeftMouse>
<C-LeftMouse> <C-LeftMouse> CTRL-] CTRL-] 跳转到光标下的关键字的定义。与“:tag {name}”相同,其中{name} 是光标下或光标后的关键字。当有多个匹配{name} 的标签时,跳转到第 [count] 个。当没有给出 [count] 时,跳转到第一个。有关跳转到其他匹配标签的信息,请参见 tag-matchlist
v_CTRL-]
{Visual}CTRL-] 与“:tag {name}”相同,其中{name} 是突出显示的文本。
telnet-CTRL-]
CTRL-] 是默认的 telnet 转义键。当您键入CTRL-] 以跳转到标签时,您将获得 telnet 提示符。大多数版本的 telnet 允许更改或禁用默认的转义键。参见 telnet 手册页。您可以telnet -E {Hostname} 来禁用转义字符,或telnet -e {EscapeCharacter} {Hostname} 来指定另一个转义字符。如果可能,请尝试使用“ssh”而不是“telnet”来避免此问题。
tag-priority
当有多个标签匹配时,使用以下优先级:1. “FSC” 当前文件的完全匹配静态标签。2. “F C” 当前文件的完全匹配全局标签。3. “F ” 另一个文件的完全匹配全局标签。4. “FS ” 另一个文件的完全匹配静态标签。5. “ SC” 当前文件的忽略大小写匹配静态标签。6. “ C” 当前文件的忽略大小写匹配全局标签。7. “ ” 另一个文件的忽略大小写匹配全局标签。8. “ S ” 另一个文件的忽略大小写匹配静态标签。
请注意,当当前文件更改时,优先级列表大部分不会更改,以避免在使用“:tnext”时造成混淆。在使用“:tag {name}”时,它会更改。
'ignorecase' 选项关闭时,使用“:tag”命令不会找到忽略大小写匹配。
'tagcase' 为“followic”
'tagcase' 为“followscs”,并且'ignorecase' 选项关闭,'smartcase' 选项关闭,或者模式包含大写字母。
'tagcase' 为“match”
'tagcase' 为“smart”,并且模式包含大写字母。
使用模式(以“/”开头)
用于“:tselect”
'tagcase' 为“followic”,并且'ignorecase' 打开时
'tagcase' 为“followscs”,并且'ignorecase' 打开,或者'smartcase' 选项打开,并且模式不包含大写字母时
'tagcase' 为“ignore”时
'tagcase' 为“smart”,并且模式不包含大写字母时
请注意,使用忽略大小写标签搜索会禁用 tags 文件中的二进制搜索,这会导致速度变慢。可以通过折叠大小写排序 tags 文件来避免这种情况。有关说明,请参见'tagbsearch' 选项。

2. 标签栈 tag-stack tagstack E425

标签栈会记住您跳转到的标签以及从何处跳转。只有在'tagstack' 选项设置为 true 时,标签才会被推入栈中。
g<RightMouse> g<RightMouse>
<C-RightMouse> <C-RightMouse> CTRL-T CTRL-T 跳转到标签栈中 [count] 个较旧的条目(默认值为 1)。
:po :pop E555 E556 :[count]po[p][!] 跳转到标签栈中 [count] 个较旧的条目(默认值为 1)。有关 [!] 的信息,请参见 tag-!
:[count]ta[g][!] 跳转到标签栈中 [count] 个较新的条目(默认值为 1)。有关 [!] 的信息,请参见 tag-!
:tags
:tags 显示标签栈的内容。活动条目用“>”标记。
“:tags”的输出如下所示
# TO tag FROM line in file/text 1 1 main 1 harddisk2:text/vim/test > 2 2 FuncA 58 i = FuncA(10); 3 1 FuncC 357 harddisk2:text/vim/src/amiga.c
此列表显示了您跳转到的标签以及跳转前的光标位置。较旧的标签位于顶部,较新的标签位于底部。
“>”指向活动条目。这是下一个“:tag”命令将使用的标签。CTRL-T 和“:pop”命令将使用活动条目上方的位置。
“TO”下面的数字是匹配列表中当前匹配的编号。请注意,这在使用“:pop”或“:tag”时不会更改。
行号和文件名被记住,以便能够返回到使用标签命令之前的那个位置。即使删除/插入行,行号也是正确的,除非这是由另一个程序完成的(例如,另一个 Vim 实例)。
对于当前文件,“file/text”列显示该位置的文本。会删除缩进,并且会截断长行以适合窗口。
您可以使用多个命令跳转到以前使用过的标签。一些示例
“:pop”或CTRL-T 定位到上一个标签之前{count}CTRL-T 定位到{count} 个更旧的标签之前“:tag” 定位到下一个标签“:0tag” 定位到最后一个使用的标签
最明显的用法是在浏览程序的调用图时。考虑以下调用图
main ---> FuncA ---> FuncC ---> FuncB
(说明:main 调用 FuncA 和 FuncB;FuncA 调用 FuncC)。您可以使用CTRL-] 在对 FuncA 的调用上从 main 跳转到 FuncA。然后,您可以使用CTRL-] 跳转到 FuncC。如果您现在想要返回到 main,可以使用CTRL-T 两次。然后,您可以使用CTRL-] 跳转到 FuncB。
如果您发出“:ta {name}”或CTRL-] 命令,该标签将被插入到栈中的当前位置。如果栈已满(它可以容纳多达 20 个条目),则最旧的条目将被删除,并且较旧的条目向上移动一个位置(它们的索引号减 1)。如果最后一个使用的条目不在底部,则最后一个使用的条目下面的条目将被删除。这意味着调用图中一个旧的分支将丢失。在执行完上述命令后,标签栈将如下所示
# TO tag FROM line in file/text 1 1 main 1 harddisk2:text/vim/test 2 1 FuncB 59 harddisk2:text/vim/src/main.c
gettagstack() 函数返回指定窗口的标签栈。settagstack() 函数修改窗口的标签栈。
tagstack-examples
:tag 一样写入标签栈,但使用用户定义的跳转器 #jump_to_tag 函数
" Store where we're jumping from before we jump.
let tag = expand('<cword>')
let pos = [bufnr()] + getcurpos()[1:]
let item = {'bufnr': pos[0], 'from': pos, 'tagname': tag}
if jumper#jump_to_tag(tag)
        " Jump was successful, write previous location to tag stack.
        let winid = win_getid()
        let stack = gettagstack(winid)
        let stack['items'] = [item]
        call settagstack(winid, stack, 't')
endif
将标签栈的当前索引设置为 4
call settagstack(1005, {'curidx' : 4})
将新条目推入标签栈
let pos = [bufnr('myfile.txt'), 10, 1, 0]
let newtag = [{'tagname' : 'mytag', 'from' : pos}]
call settagstack(2, {'items' : newtag}, 'a')
E73
当您尝试在标签栈中没有任何内容时使用它时,您将收到一条错误消息。

3. 标签匹配列表 tag-matchlist E427 E428

当有多个匹配的标签时,可以使用以下命令在它们之间跳转。请注意,这些命令不会更改标签栈,它们会保留相同的条目。
:ts :tselect :ts[elect][!] [name] 列出与 [name] 匹配的标签,使用 tags 文件中的信息。当省略 [name] 时,将使用标签栈中的最后一个标签名。有关 [!] 的信息,请参见 tag-!。第一列中的“>”表示列表中的当前位置(如果有)。[name] 可以是正则表达式模式,请参见 tag-regexp。有关列表中使用的优先级,请参见 tag-priority。示例输出
  # pri kind tag                file
  1 F        f    mch_delay                os_amiga.c
                mch_delay(msec, ignoreinput)
> 2 F        f    mch_delay                os_msdos.c
                mch_delay(msec, ignoreinput)
  3 F        f    mch_delay                os_unix.c
                mch_delay(msec, ignoreinput)
Type number and <Enter> (empty cancels):
有关“pri”列的说明,请参见 tag-priority。请注意,这取决于当前文件,因此使用“:tselect xxx”可能会产生不同的结果。“kind”列给出标签的类型(如果它包含在 tags 文件中)。“info”列显示 tags 文件中可以找到的信息。它取决于生成 tags 文件的程序。当列表很长时,您可能会收到more-prompt。如果您已经看到您想使用的标签,您可以键入“q”并输入编号。
:sts :stselect :sts[elect][!] [name] 执行“:tselect[!] [name]”,并为选定的标签拆分窗口。
g]
g] 与CTRL-] 相似,但使用“:tselect”而不是“:tag”。
v_g]
{Visual}g] 与“g]”相同,但使用突出显示的文本作为标识符。
:tj :tjump :tj[ump][!] [name] 与“:tselect”类似,但当只有一个匹配项时,直接跳转到标签。
:stj :stjump :stj[ump][!] [name] 执行“:tjump[!] [name]”,并为选定的标签拆分窗口。
g_CTRL-]
g CTRL-]CTRL-] 相似,但使用 ":tjump" 而不是 ":tag"。
v_g_CTRL-]
{Visual}g CTRL-] 与 "g CTRL-]" 相同,但使用高亮显示的文本作为标识符。
:tn :tnext ]t :[count]tn[ext][!] 跳转到 [count] 个下一个匹配的标签(默认值为 1)。有关 [!] 的信息,请参阅 tag-!
:tp :tprevious [t :[count]tp[revious][!] 跳转到 [count] 个上一个匹配的标签(默认值为 1)。有关 [!] 的信息,请参阅 tag-!
:tN :tNext :[count]tN[ext][!] 与 ":tprevious" 相同。
:tr :trewind [T :[count]tr[ewind][!] 跳转到第一个匹配的标签。如果提供了 [count],则跳转到第 [count] 个匹配的标签。有关 [!] 的信息,请参阅 tag-!
:tf :tfirst :[count]tf[irst][!] 与 ":trewind" 相同。
:tl :tlast ]T :tl[ast][!] 跳转到最后一个匹配的标签。有关 [!] 的信息,请参阅 tag-!
:lt :ltag :lt[ag][!] [name] 跳转到标签 [name] 并将匹配的标签添加到当前窗口的新位置列表中。[name] 可以是正则表达式模式,请参阅 tag-regexp。如果未提供 [name],则使用标签堆栈中的最后一个标签名称。用于定位标签行的搜索模式以 "\V" 为前缀,以转义所有特殊字符(非常非魔术)。显示匹配标签的位置列表独立于标签堆栈。有关 [!] 的信息,请参阅 tag-!
如果没有其他消息,Vim 将显示已跳转到的匹配标签以及匹配标签的数量。
tag 1 of 3 or more
"或更多" 用于指示 Vim 尚未尝试所有标签文件。多次使用 ":tnext" 或使用 ":tlast" 时,可能会找到更多匹配项。
如果由于其他消息而您没有看到此消息,或者您只想了解自己的位置,则此命令将再次显示它(并跳转到上次相同的标签)。
:0tn
tag-skip-file
如果找到一个匹配标签,但文件不存在,则跳过该匹配项并使用下一个匹配标签。Vim 会报告这一点,以通知您缺少文件。如果已到达匹配项列表的末尾,则会显示错误消息。
tag-preview
标签匹配列表也可以在预览窗口中使用。命令与上述命令相同,只是前面加了一个 "p"。
:pts :ptselect :pts[elect][!] [name] 执行 ":tselect[!] [name]" 并将新标签显示在 "Preview" 窗口中。有关更多信息,请参阅 :ptag
:ptj :ptjump :ptj[ump][!] [name] 执行 ":tjump[!] [name]" 并将新标签显示在 "Preview" 窗口中。有关更多信息,请参阅 :ptag
:ptn :ptnext ]CTRL-T :[count]ptn[ext][!] 在预览窗口中使用 ":tnext"。请参阅 :ptag
:ptp :ptprevious [CTRL-T :[count]ptp[revious][!] 在预览窗口中使用 ":tprevious"。请参阅 :ptag
:ptN :ptNext :[count]ptN[ext][!] 与 ":ptprevious" 相同。
:ptr :ptrewind :[count]ptr[ewind][!] 在预览窗口中使用 ":trewind"。请参阅 :ptag
:ptf :ptfirst :[count]ptf[irst][!] 与 ":ptrewind" 相同。
:ptl :ptlast :ptl[ast][!] 在预览窗口中使用 ":tlast"。请参阅 :ptag

4. 标签详细信息 tag-details

static-tag
静态标签是为特定文件定义的标签。在 C 程序中,这可能是静态函数。
在 Vi 中,跳转到标签会设置当前搜索模式。这意味着在跳转到标签后,"n" 命令不会搜索与跳转到标签之前相同的模式。Vim 不会这样做,因为我们认为这是一个错误。如果您真的想要旧的 Vi 行为,请在 'cpoptions' 中设置 't' 标志。
tag-binary-search
Vim 在标签文件中使用二进制搜索来快速找到所需的标签。但这只有在标签文件按 ASCII 字节值排序的情况下才能起作用。因此,如果没有找到匹配项,则会使用线性搜索再次尝试。如果您只想使用线性搜索,请重置 'tagbsearch' 选项。或者更好:对标签文件进行排序!
请注意,在不查找具有特定名称的标签时,二进制搜索将被禁用。当忽略大小写且使用不以固定字符串开头的正则表达式时,就会发生这种情况。标签搜索可能会慢很多。前者可以通过对标签文件进行大小写折叠排序来避免。有关详细信息,请参阅 'tagbsearch'
tag-regexp
":tag" 和 ":tselect" 命令接受正则表达式参数。有关可以使用哪些特殊字符,请参阅 pattern。如果参数以 "/" 开头,则将其用作模式。如果参数不以 "/" 开头,则将其视为字面值,作为完整的标签名称。示例
:tag main
跳转到优先级最高的标签 "main"。
:tag /^get
跳转到以 "get" 开头且优先级最高的标签。
:tag /norm
列出所有包含 "norm" 的标签,包括 "id_norm"。如果参数既存在于字面值中,又在用作正则表达式时匹配,则字面匹配具有更高的优先级。例如,":tag /open" 在 "open_file" 和 "file_open" 之前匹配 "open"。使用模式时会忽略大小写。如果您想匹配大小写,请在模式中使用 "\C"。
tag-!
如果标签位于当前文件中,则此操作始终有效。否则,执行的操作取决于当前文件是否已更改、是否将 "!" 添加到命令以及 'autowrite''winfixbuf' 选项。
tag in file winfixbuf autowrite
current file changed ! option option action
----------------------------------------------------------------------------- yes x x off x goto tag no no x off x read other file, goto tag no yes yes off x abandon current file, read other file, goto tag no yes no off on write current file, read other file, goto tag no yes no off off fail yes x yes x x goto tag no no no on x fail no yes no on x fail no yes no on on fail no yes no on off fail -----------------------------------------------------------------------------
如果标签位于当前文件中,则该命令始终有效。
如果标签位于另一个文件中,并且当前文件未更改,则另一个文件将成为当前文件并被读入缓冲区。
如果标签位于另一个文件中,当前文件已更改,并且将 "!" 添加到命令,则对当前文件的更改将丢失,另一个文件将成为当前文件并被读入缓冲区。
如果标签位于另一个文件中,当前文件已更改,并且 'autowrite' 选项已开启,则会写入当前文件,另一个文件将成为当前文件并被读入缓冲区。
如果标签位于另一个文件中,当前文件已更改,并且 'autowrite' 选项已关闭,则该命令将失败。如果您想保存更改,请使用 ":w" 命令,然后使用不带参数的 ":tag" 命令。这是因为该标签无论如何都会被放入堆栈中。如果您想丢弃更改,可以使用 ":tag!" 命令。
如果标签位于另一个文件中,并且窗口包含 'winfixbuf',则该命令将失败。如果标签位于同一个文件中,则可能会成功。
tag-security
请注意,Vim 禁止某些命令,出于安全原因。这就像对当前目录中的 exrc/vimrc 文件使用 'secure' 选项一样。请参阅 trojan-horsesandbox。当 {tagaddress} 更改缓冲区时,您将收到一条警告消息:"WARNING: tag command changed a buffer!!!" 在将来的版本中,更改缓冲区将变得不可能。所有这一切都是出于安全原因:有人可能在标签文件中隐藏了一个恶意命令,否则它会不被察觉。示例
:$d|/tag-function-name/
在 Vi 中,当搜索标签时,":tag" 命令会设置最后一个搜索模式。在 Vim 中不会这样做,之前的搜索模式仍然被记住,除非 'cpoptions' 中存在 't' 标志。
tags-option
'tags' 选项是文件名列表。每个文件都会被搜索以查找标签。这可以用于使用与默认文件 "tags" 不同的标签文件。它也可以用于访问公共标签文件。
当以下情况发生时,将不使用列表中的下一个文件
已找到当前缓冲区的匹配静态标签。
已找到匹配的全局标签。这也取决于是否忽略大小写。当以下情况发生时,会忽略大小写
'tagcase' 为 "followic" 且 'ignorecase' 已设置
'tagcase' 为 "ignore"
'tagcase' 为 "smart" 且模式仅包含小写字符。
'tagcase' 为 "followscs" 且 'smartcase' 已设置,并且模式仅包含小写字符。如果未忽略大小写,并且标签文件只有不匹配大小写的匹配项,则会搜索下一个标签文件以查找匹配大小写的匹配项。如果没有找到匹配大小写的标签,则使用第一个不匹配大小写的匹配项。如果忽略大小写,并且找到了匹配或不匹配大小写的匹配全局标签,则使用该标签,不再搜索其他标签文件。
如果标签文件名以 "./" 开头,则 "." 将被当前文件的路径替换。这使得可以使用当前文件所在目录中的标签文件(无论当前目录是什么)。使用 "./" 的想法是,您可以定义首先搜索哪个标签文件:在当前目录中 ("tags,./tags") 或在当前文件所在的目录中 ("./tags,tags")。
例如
:set tags=./tags,tags,/home/user/commontags
在此示例中,标签将首先在当前文件所在目录中的文件 "tags" 中搜索。接下来是当前目录中的 "tags" 文件。如果在那里没有找到,则会搜索文件 "/home/user/commontags" 以查找该标签。
可以通过在 'cpoptions' 中包含 'd' 标志来关闭此功能,以使其与 Vi 兼容。然后,"./tags" 将是当前目录中的标签文件,而不是当前文件所在的目录中的标签文件。
可以使用空格代替逗号。然后,需要使用反斜杠才能将空格包含在字符串选项中。
:set tags=tags\ /home/user/commontags
要在文件名中包含空格,请使用三个反斜杠。要在文件名中包含逗号,请使用两个反斜杠。例如,使用
:set tags=tag\\\ file,/home/user/common\\,tags
用于文件“tag file”和“/home/user/common,tags”。'tags' 选项的值将为“tag\ file,/home/user/common\,tags”。
如果 'tagrelative' 选项处于开启状态(默认情况下为开启状态)并且使用另一个目录中的标签文件,则该标签文件中的文件名相对于标签文件所在的目录。

5. 标签文件格式 tags-file-format E431

ctags jtags 可以使用外部命令(例如“ctags”)创建标签文件。它将包含每个函数的标签。某些版本的“ctags”还会为每个“#defined”宏、类型定义、枚举等创建标签。
一些生成标签文件的程序:ctags 在大多数 Unix 系统上都能找到。仅支持 C。仅执行基本工作。universal ctags 基于 exuberant ctags 的维护版本。参见 https://ctags.ioExuberant_ctags
exuberant ctags 支持 C、C++、Java、Fortran、Eiffel 等。参见 https://ctags.sourceforge.net。自 2009 年以来没有新版本。JTags 用于 Java,以 Java 编写。可以在 https://www.fleiner.com/jtags/ 找到。ptags.py 用于 Python,以 Python 编写。可在 Python 源代码目录的 Tools/scripts/ptags.py 中找到。
标签文件中的行必须具有以下两种格式之一
1. {tagname} {TAB} {tagfile} {TAB} {tagaddress} 2. {tagname} {TAB} {tagfile} {TAB} {tagaddress} {term} {field} ..
以前支持一种旧格式,参见 tag-old-static.
第一种格式是普通标签,与 Vi 完全兼容。它是传统 ctags 实现生成的唯一格式。这通常用于全局函数,也在其他文件中引用。
标签文件中的行可以以 <NL><CR><NL> 结尾。在 Macintosh 上,<CR> 也能工作。<CR><NL> 字符永远不会出现在行内。
第二种格式是新的。它在每行末尾的可选字段中包含了附加信息。它向后兼容 Vi。它只受新版本的 ctags 支持(例如 Universal ctags 或 Exuberant ctags)。
{tagname} 标识符。通常是函数的名称,但可以是任何标识符。它不能包含 <Tab>{TAB} 一个 <Tab> 字符。注意:以前版本允许此处使用任何空白字符。这已被放弃,以便允许 {tagfile} 中包含空格。 {tagfile} 包含 {tagname} 定义的文件。它可以具有绝对路径或相对路径。它可能包含环境变量和通配符(尽管通配符的使用值得怀疑)。它不能包含 <Tab>{tagaddress} 将光标定位在标签上的 Ex 命令。它可以是任何 Ex 命令,尽管存在限制(参见 tag-security)。Posix 仅允许使用行号和搜索命令,这些命令主要用于此目的。 {term} ;" 两个字符,分号和双引号。它被 Vi 解释为注释的开始,这将导致后面的内容被忽略。这是为了向后兼容 Vi,它会忽略后面的字段。示例
APP        file        /^static int APP;$/;"        v
{tagaddress} 不是行号或搜索模式时,{term} 必须是 |;"。在此,竖线结束命令(不包括竖线),;" 用于让 Vi 忽略该行的其余部分。示例
APP        file.c        call cursor(3, 4)|;"        v
{field} .. 一系列可选字段。每个字段都有以下形式
<Tab>{fieldname}:{value}
{fieldname} 标识字段,只能包含字母字符 [a-zA-Z]。{value} 是任何字符串,但不能包含 <Tab>。这些字符是特殊的:"\t" 代表 <Tab> "\r" 代表 <CR> "\n" 代表 <NL> "\\" 代表单个 '\' 字符
有一个字段没有 ':'。这是标签的种类。它被处理得好像它前面有“kind:”。在上面的示例中,这是“kind:v”(通常是变量)。有关它生成的种类,请参见 ctags 的文档,在 ctags 中,您可以使用 ctags --list-kinds
目前 Vim 识别的唯一其他字段是“file:”(具有空值)。它用于静态标签。
标签文件中的第一行可以包含以 !_TAG_ 开头的行。这些行将被排序到第一行,只有以 "!" 开头的罕见标签才会排序到它们之前。Vim 识别两个项目。第一个是指示文件是否已排序的行。当找到此行时,Vim 会使用二进制搜索标签文件
!_TAG_FILE_SORTED<Tab>1<Tab>{anything}
可以对标签文件进行大小写折叠排序,以避免在忽略大小写时进行线性搜索。(当 'ignorecase' 设置且 'tagcase' 为“followic”,或者当 'tagcase' 为“ignore”时,将忽略大小写。)有关详细信息,请参见 'tagbsearch'。然后应该使用值 '2'
!_TAG_FILE_SORTED<Tab>2<Tab>{anything}
Vim 识别的另一个标签是标签文件的编码
!_TAG_FILE_ENCODING<Tab>utf-8<Tab>{anything}
此处,“utf-8” 是用于标签的编码。然后 Vim 将把要搜索的标签从 'encoding' 转换为标签文件的编码。在列出标签时,会发生相反的操作。如果转换失败,将使用未转换的标签。
tag-search
该命令可以是任何 Ex 命令,但通常是搜索命令。示例
tag1 file1 /^main(argc, argv)/
tag2 file2 108
该命令始终使用 'magic' 未设置的状态执行。搜索模式中唯一的特殊字符是 "^"(行首)和 "$"(<EOL>)。参见 pattern。请注意,您必须在搜索文本中的每个反斜杠之前放置一个反斜杠。这是为了向后兼容 Vi。
E434 E435 如果该命令是普通搜索命令(以 "/" 或 "?" 开头和结尾),则会进行一些特殊处理
搜索从文件的第 1 行开始。搜索的方向对于 "/" 为向前,对于 "?" 为向后。请注意,'wrapscan' 无关紧要,始终搜索整个文件。
如果搜索失败,将尝试再次进行搜索,但忽略大小写。如果这也失败,将搜索
"^tagname[ \t]*("
(带有 '^' 前缀和 "[ \t]*(" 后缀的标签)。当使用函数名时,这将找到函数名(当它在第 0 列时)。这将有助于在自标签文件创建以来函数的参数发生更改时找到函数名。如果此搜索也失败,将执行另一个搜索,使用
"^[#a-zA-Z_].*\<tagname[ \t]*("
这意味着:以 '#' 或标识符开头的行,并且包含标签,后面跟着空白字符和 '('. 这将找到宏名称和带有类型前缀的函数名。
tag-old-static
直到 2019 年 3 月(补丁 8.1.1092),才支持过时的格式:{tagfile}:{tagname} {TAB} {tagfile} {TAB} {tagaddress}
这种格式仅用于静态标签。现在它已过时,被第二种格式取代。它只受 Elvis 1.x、较旧的 Vim 版本和一些版本的 ctags 支持。静态标签通常用于局部函数,这些函数只在 {tagfile} 文件中引用。请注意,对于静态标签,{tagfile} 的两次出现必须完全相同。另请参见下面的 tags-option,了解如何使用静态标签。
支持已被删除,因为当您可以更新到新的 Vim 版本时,您也应该能够将 ctags 更新到支持第二种格式的版本。
这些命令在当前文件中以及所有遇到的包含文件(递归)中查找字符串。这可以用于查找变量、函数或宏的定义。如果您只想在当前缓冲区中搜索,请使用 pattern-searches 中列出的命令。
当遇到包含另一个文件的一行时,将在继续在当前缓冲区中搜索之前搜索该文件。还会搜索包含文件包含的文件。如果找不到包含文件,它将被静默忽略。使用 :checkpath 命令来发现哪些文件找不到,可能是您的 'path' 选项设置不正确。注意:会搜索包含文件,而不是可能正在编辑该文件的缓冲区。仅对于当前文件,才会使用缓冲区中的行。
该字符串可以是任何关键字或已定义的宏。对于关键字,将找到任何匹配项。对于已定义的宏,只会找到与 'define' 选项匹配的行。默认值为 "^#\s*define",适用于 C 程序。对于其他语言,您可能需要更改它。有关 C++ 的示例,请参见 'define'。该字符串不能包含行尾,只会找到行内的匹配项。
当为已定义的宏找到匹配项时,如果一行以反斜杠结尾,则行的显示将从下一行继续。
以 "[" 开头的命令从当前文件的开头开始搜索。以 "]" 开头的命令从当前光标位置开始搜索。
使用 'include' 选项来定义包含另一个文件的一行。默认值为 "\^#\s*include",适用于 C 程序。注意:Vim 无法识别 C 语法,如果 'include' 选项匹配 "#ifdef/#endif" 内部的行或注释内的行,则仍会对其进行搜索。使用 'isfname' 选项来识别匹配模式后出现的文件名。
使用 'path' 选项来查找不包含绝对路径的包含文件的目录。
使用 'comments' 选项来定义显示单行或跳转到行的命令。它定义了可能开始注释的模式。这些行在搜索中被忽略,除非使用 [!]。一个例外:当一行与模式 "^# *define" 匹配时,它不被认为是注释。
如果您想要列出匹配项,然后选择一个进行跳转,您可以使用映射来为您执行此操作。以下是一个示例
:map <F4> [I:let nr = input("Which one: ")<Bar>exe "normal " .. nr .. "[\t"<CR>
[i
[i 显示包含光标下关键字的第一行。搜索从文件的开头开始。看起来像注释的行被忽略(参见 'comments' 选项)。如果给出了计数,则会显示第 n 个匹配行,并且不会忽略注释行。
]i
]i 与 "[i" 相似,但从当前光标位置开始。
:is :isearch :[range]is[earch][!] [count] [/]pattern[/] 类似 "[i" 和 "]i",但在 [range] 行中搜索(默认:整个文件)。有关 [/] 和 [!],请参见 :search-args
[I
[I 显示包含光标下关键字的所有行。将显示找到行的文件名和行号。搜索从文件开头开始。
]I
]I 类似 "[I",但从当前光标位置开始。
:il :ilist :[range]il[ist][!] [/]pattern[/] 类似 "[I" 和 "]I",但在 [range] 行中搜索(默认:整个文件)。有关 [/] 和 [!],请参见 :search-args
[_CTRL-I
[ CTRL-I 跳到包含光标下关键字的第一行。搜索从文件开头开始。类似注释的行将被忽略(参见 'comments' 选项)。如果指定了计数,则跳到第计数个匹配行,并且不会忽略注释行。
]_CTRL-I
] CTRL-I 类似 "[ CTRL-I",但从当前光标位置开始。
:ij :ijump :[range]ij[ump][!] [count] [/]pattern[/] 类似 "[ CTRL-I" 和 "] CTRL-I",但在 [range] 行中搜索(默认:整个文件)。有关 [/] 和 [!],请参见 :search-args
CTRL-W CTRL-I CTRL-W_CTRL-I CTRL-W_i CTRL-W i 打开一个新窗口,光标位于包含光标下关键字的第一行上。搜索从文件开头开始。类似注释的行将被忽略(参见 'comments' 选项)。如果指定了计数,则跳到第计数个匹配行,并且不会忽略注释行。
:isp :isplit :[range]isp[lit][!] [count] [/]pattern[/] 类似 "CTRL-W i" 和 "CTRL-W i",但在 [range] 行中搜索(默认:整个文件)。有关 [/] 和 [!],请参见 :search-args
[d
[d 显示包含光标下宏定义的第一行。搜索从文件开头开始。如果指定了计数,则显示第计数个匹配行。
[d-default
默认情况下跳到当前缓冲区中的上一个诊断。 vim.diagnostic.jump() default-mappings
]d
]d 类似 "[d",但从当前光标位置开始。
]d-default
默认情况下跳到当前缓冲区中的下一个诊断。 vim.diagnostic.jump() default-mappings
:ds :dsearch :[range]ds[earch][!] [count] [/]string[/] 类似 "[d" 和 "]d",但在 [range] 行中搜索(默认:整个文件)。有关 [/] 和 [!],请参见 :search-args
[D
[D 显示包含光标下宏定义的所有行。将显示找到行的文件名和行号。搜索从文件开头开始。
[D-default
默认情况下跳到当前缓冲区中的第一个诊断。 vim.diagnostic.jump() default-mappings
]D
]D 类似 "[D",但从当前光标位置开始。
]D-default
默认情况下跳到当前缓冲区中的最后一个诊断。 vim.diagnostic.jump() default-mappings
:dli :dlist :[range]dli[st][!] [/]string[/] 类似 [D]D,但在 [range] 行中搜索(默认:整个文件)。有关 [/] 和 [!],请参见 :search-args。请注意,:dl 的作用类似于带有 "l" 标志的 :delete,而不是 :dlist
[_CTRL-D
[ CTRL-D 跳到包含光标下关键字的第一行宏定义。搜索从文件开头开始。如果指定了计数,则跳到第计数个匹配行。
]_CTRL-D
] CTRL-D 类似 "[ CTRL-D",但从当前光标位置开始。
:dj :djump :[range]dj[ump][!] [count] [/]string[/] 类似 "[ CTRL-D" 和 "] CTRL-D",但在 [range] 行中搜索(默认:整个文件)。有关 [/] 和 [!],请参见 :search-args
CTRL-W CTRL-D CTRL-W_CTRL-D CTRL-W_d CTRL-W d 打开一个新窗口,光标位于包含光标下关键字的第一行宏定义上。搜索从文件开头开始。如果指定了计数,则跳到第计数个匹配行。
:dsp :dsplit :[range]dsp[lit][!] [count] [/]string[/] 类似 "CTRL-W d",但在 [range] 行中搜索(默认:整个文件)。有关 [/] 和 [!],请参见 :search-args
:checkp :checkpath :checkp[ath] 列出所有找不到的包含文件。
:checkp[ath]! 列出所有包含文件。
:search-args
上面命令的常用参数:[!] 如果包含,则在被识别为注释的行中查找匹配项。如果排除,则当该行被识别为注释(根据 'comments')时,匹配项将被忽略,或者匹配项位于 C 注释中(在 "//" 之后或在 /* */ 中)。请注意,如果该行被识别为注释,但注释在该行中间结束,则可能会错过匹配项。如果该行是注释,但未被识别(根据 'comments'),则无论如何都可能会在其中找到匹配项。示例
/* comment
   foobar */
找到了 "foobar" 的匹配项,因为这一行没有被识别为注释(即使语法高亮确实识别了它)。 注意: 由于宏定义大多不像注释,因此对于 ":dlist"、":dsearch" 和 ":djump",[!] 不会产生影响。 [/] 可以用 "/" 将模式括起来。如果没有 "/",则只匹配完整的单词,使用模式 "\<pattern\>"。只有在第二个 "/" 之后,才能使用 "|" 附加下一个命令。示例
:isearch /string/ | echo "the last one"
对于 ":djump"、":dsplit"、":dlist" 和 ":dsearch" 命令,模式被用作字面字符串,而不是搜索模式。
可以为 Vim 提供一个函数,该函数将生成用于命令(如 :tag:tselect 以及普通模式标签命令,如 CTRL-])的标签列表。
用于生成标签列表的函数由 'tagfunc' 选项指定。该函数将使用三个参数调用:pattern 在标签搜索期间使用的标签标识符或模式。flags 包含控制函数行为的标志的字符串。info 包含以下条目的字典:buf_ffname 可以用于优先级的完整文件名。user_data 自定义数据字符串,如果之前由 tagfunc 存储在标签堆栈中。
请注意,在使用参数名称时,需要在前面加上 "a:"。
目前,最多可以向标签函数传递三个标志:'c' 该函数是由正在处理的普通命令调用的(助记符:标签函数可以使用光标周围的上下文来更好地生成标签列表。)'i' 在插入模式下,用户正在完成一个标签(使用 i_CTRL-X_CTRL-]'completeopt' 包含 t)。'r' tagfunc 的第一个参数应解释为 模式(参见 tag-regexp),例如在使用
:tag /pat
它在插入模式下完成时也会出现。如果不存在此标志,则参数通常被直接视为完整的标签名称。
请注意,当设置了 'tagfunc' 时,tag-priority 中描述的标签优先级不适用。相反,优先级与函数返回的列表中元素的排序顺序完全一致。 E987
该函数应返回一个 Dict 条目的列表。每个 Dict 至少应包含以下条目,并且每个值都必须是字符串:name 标签的名称。filename 定义标签的文件的名称。它要么相对于当前目录,要么是完整的路径。cmd 用于在文件中定位标签的 Ex 命令。这可以是 Ex 搜索模式或行号。请注意,格式类似于 taglist(),这使得可以使用其输出生成结果。以下字段是可选的:kind 标签的类型。user_data 存储在标签堆栈中的自定义数据字符串,可用于区分操作之间的标签。
如果该函数返回 v:null 而不是 List,则将执行标准标签查找。
不允许从 'tagfunc' 内部更改标签堆栈。 E986 不允许从 'tagfunc' 内部关闭窗口或更改窗口。 E1299
以下是用于 'tagfunc' 的一个假设函数示例。它使用 taglist() 的输出生成结果:按文件名反向排序的标签列表。
function TagFunc(pattern, flags, info)
  function CompareFilenames(item1, item2)
    let f1 = a:item1['filename']
    let f2 = a:item2['filename']
    return f1 >=# f2 ?
                \ -1 : f1 <=# f2 ? 1 : 0
  endfunction
  let result = taglist(a:pattern)
  call sort(result, "CompareFilenames")
  return result
endfunc
set tagfunc=TagFunc
Main
Commands index
Quick reference