command模式下命令的匹配及help内容的搜索

一、command模式下命令如何匹配

在command模式下,输入:h默认执行的是help,但事实上,还有字典序更靠前的hardcopy命令,那为什么这个h匹配的不是hardcopy而是help呢?
在代码中其实已经做了说明ex_cmds.h:

/*
* This array maps ex command names to command codes.
* The order in which command names are listed below is significant --
* ambiguous abbreviations are always resolved to be the first possible match
* (e.g. "r" is taken to mean "read", not "rewind", because "read" comes
* before "rewind").
* Not supported commands are included to avoid ambiguities.
*/
EX(CMD_help, "help", ex_help,
BANG|EXTRA|NOTRLCOM,
ADDR_LINES),
EX(CMD_helpclose, "helpclose", ex_helpclose,
RANGE|NOTADR|COUNT|TRLBAR,
ADDR_LINES),
EX(CMD_helpfind, "helpfind", ex_helpfind,
EXTRA|NOTRLCOM,
ADDR_LINES),
EX(CMD_helpgrep, "helpgrep", ex_helpgrep,
EXTRA|NOTRLCOM|NEEDARG,
ADDR_LINES),
EX(CMD_helptags, "helptags", ex_helptags,
NEEDARG|FILES|TRLBAR|CMDWIN,
ADDR_LINES),
EX(CMD_hardcopy, "hardcopy", ex_hardcopy,
RANGE|COUNT|EXTRA|TRLBAR|DFLALL|BANG,
ADDR_LINES),
在匹配的时候,使用用户提供的命令字符串和内置命令字符串匹配,由于help在数组中最靠前,所以当输入h的时候,最早完成匹配的就是help,但是ha第一个匹配的就是hardcopy。这意味着在查找匹配的时候不能使用二分查找
ex_docmd.c
static char_u *
find_command(exarg_T *eap, int *full UNUSED)
{
……
for ( ; (int)eap->cmdidx < (int)CMD_SIZE;
eap->cmdidx = (cmdidx_T)((int)eap->cmdidx + 1))
if (STRNCMP(cmdnames[(int)eap->cmdidx].cmd_name, (char *)eap->cmd,
(size_t)len) == 0)
{
#ifdef FEAT_EVAL
if (full != NULL
&& cmdnames[(int)eap->cmdidx].cmd_name[len] == NUL)
*full = TRUE;
#endif
break;
}
……
}

二、help如何实现

文件中内容
/home/harry/vim81/share/vim/vim81/doc/tags
2578 :lprevious quickfix.txt /*:lprevious*
2579 :lr quickfix.txt /*:lr*
2580 :lrewind quickfix.txt /*:lrewind*
2581 :ls windows.txt /*:ls*
2582 :lt tagsrch.txt /*:lt*
2583 :ltag tagsrch.txt /*:ltag*
tag.c
/*
* Jump to a tag that has been found in one of the tag files
*
* returns OK for success, NOTAGFILE when file not found, FAIL otherwise.
*/
static int
jumpto_tag(
char_u *lbuf_arg, /* line from the tags file for this tag */
int forceit, /* :ta with ! */
int keep_help) /* keep help flag (FALSE for cscope) */
{
……
}
在windows.txt文件中,可以看到,其中有"*:ls*",这个对应的就是2581行中最后一列的"*:ls*"
:files[!] [flags] *:files*
:buffers[!] [flags] *:buffers* *:ls*
:ls[!] [flags]
Show all buffers. Example:
1 #h "/test/text" line 1 ~ 2u "asdf" line 0 ~ 3 %a + "version.c" line 1 ~

三、tag文件格式

在vim中通过下面命令查看
:help tags-file-format
从其说明可以看到
The lines in the tags file must have one of these three formats:
1. {tagname} {TAB} {tagfile} {TAB} {tagaddress}
2. {tagfile}:{tagname} {TAB} {tagfile} {TAB} {tagaddress}
3. {tagname} {TAB} {tagfile} {TAB} {tagaddress} {term} {field} ..
The first is a normal tag, which is completely compatible with Vi. It is the only format produced by traditional ctags implementations. This is often used for functions that are global, also referenced in other files.
The lines in the tags file can end in <LF> or <CR><LF>. On the Macintosh <CR> also works. The <CR> and <NL> characters can never appear inside a line.
其中tagaddress是一个Ex命令
{tagaddress} The Ex command that positions the cursor on the tag. It can be any Ex command, although restrictions apply (see
|tag-security|). Posix only allows line numbers and search
commands, which are mostly used.

 

posted on 2021-05-14 21:18  tsecer  阅读(155)  评论(0编辑  收藏  举报

导航