Nvim :help
頁面,由 產生,來源為 source,使用 tree-sitter-vimdoc 解析器。
ctags *.c"ctags" 是一個獨立的程式。大多數 Unix 系統已經安裝了它。如果您還沒有安裝它,可以在以下位置找到 Universal ctags:https://ctags.io
:tag startlist即使函式 "startlist" 位於另一個檔案中,此命令也會找到它。
CTRL-]
命令會跳轉到游標下的單字的標籤。這使得探索複雜的 C 程式碼變得容易。例如,假設您在函式 "write_block" 中。您可以看到它呼叫了 "write_line"。但是 "write_line" 做什麼?將游標放在 "write_line" 的呼叫上,然後按下 CTRL-]
,您就會跳轉到此函式的定義。"write_line" 函式呼叫 "write_char"。您需要找出它做了什麼。因此,您將游標放在 "write_char" 的呼叫上,然後按下 CTRL-]
。現在您位於 "write_char" 的定義處。+-------------------------------------+ |void write_block(char **s; int cnt) | |{ | | int i; | | for (i = 0; i < cnt; ++i) | | write_line(s[i]); | |} | | +-----------|-------------------------+ | CTRL-] | | +----------------------------+ +--> |void write_line(char *s) | |{ | | while (*s != 0) | | write_char(*s++); | |} | | +--------|-------------------+ | CTRL-] | | +------------------------------------+ +--> |void write_char(char c) | |{ | | putchar((int)(unsigned char)c); | |} | +------------------------------------+
CTRL-T
命令會回到上一個標籤。在上面的範例中,您會回到 "write_line" 函式中呼叫 "write_char" 的位置。此命令接受計數參數,指示要跳回多少個標籤。您已經前進,現在又後退。讓我們再次前進。以下命令會跳轉到清單頂端的標籤:tag您可以在其前面加上計數,並向前跳轉該數量的標籤。例如:「:3tag」。
CTRL-T
也可以在前面加上計數。因此,這些命令允許您使用 CTRL-]
向下瀏覽呼叫樹,並使用 CTRL-T
向上返回。使用 ":tags" 來找出您在哪裡。:stag tagname要分割目前視窗並跳轉到游標下的標籤,請使用此命令
CTRL-W ]如果指定了計數,則新視窗將具有該高度的行數。
:set tags=./tags,./../tags,./*/tags這會在與目前檔案相同的目錄中、高一層的目錄中以及所有子目錄中尋找標籤檔案。這相當多的標籤檔案,但可能仍然不夠。例如,當編輯 "~/proj/src" 中的檔案時,您將找不到標籤檔案 "~/proj/sub/tags"。對於這種情況,Vim 提供了一個選項,可以在整個目錄樹中搜尋標籤檔案。範例
:set tags=~/proj/**/tags
cd ~/proj ctags -R .這樣做的好處是 Universal/Exuberant ctags 可以識別各種檔案類型。因此,這不僅適用於 C 和 C++ 程式,也適用於 Eiffel 甚至 Vim 指令碼。請參閱 ctags 文件以進行調整。現在您只需要告訴 Vim 您的大型標籤檔案在哪裡
:set tags=~/proj/tags
:tnext重複此操作以尋找其他符合項。如果有很多,您可以選擇要跳轉到哪一個
:tselect tagnameVim 將向您顯示一個選項清單
<CR>
終止)<Tab>
:tag write_<Tab>您將獲得第一個符合項。如果它不是您想要的,請按
<Tab>
直到找到正確的符合項。有時您只知道函式名稱的一部分。或者您有許多以相同字串開頭但結尾不同的標籤。然後您可以告訴 Vim 使用模式來尋找標籤。假設您要跳轉到包含 "block" 的標籤。首先輸入此內容:tag /block現在使用命令列完成:按下
<Tab>
。Vim 將找到所有包含 "block" 的標籤,並使用第一個符合項。標籤名稱前的 "/" 告訴 Vim,後面的內容不是文字標籤名稱,而是模式。您可以在此處使用搜尋模式的所有項目。例如,假設您要選擇一個以 "write_" 開頭的標籤:tselect /^write_"^" 指定標籤以 "write_" 開頭。否則,它也會在標籤名稱的中間找到。同樣,結尾的 "$" 可確保模式與標籤的結尾匹配。
CTRL-]
會將您帶到游標下識別符的定義,因此您可以使用識別符名稱清單作為目錄。以下是一個範例。首先建立識別符清單(這需要 Universal 或 Exuberant ctags)ctags --c-types=f -f functions *.c現在啟動 Vim 而不開啟檔案,並在 Vim 中以垂直分割視窗編輯此檔案
vim :vsplit functions該視窗包含所有函式的清單。還有其他一些內容,但您可以忽略它們。執行 ":setlocal ts=99" 來稍微清理一下。在此視窗中,定義一個映射
:nnoremap <buffer> <CR> 0ye<C-W>w:tag <C-R>"<CR>將游標移動到包含您要前往的函式的行。現在按下
<Enter>
。Vim 將轉到另一個視窗並跳轉到選定的函式。:ptag write_charVim 將開啟一個視窗,並跳轉到標籤 "write_char"。然後它會將您帶回原始位置。因此,您可以繼續輸入,而無需使用
CTRL-W
命令。如果函式的名稱出現在文字中,您可以使用以下命令在預覽視窗中取得其定義CTRL-W }有一個指令碼會自動顯示游標下單字定義的文字。請參閱 CursorHold-example。
:pclose要在預覽視窗中編輯特定檔案,請使用 ":pedit"。這對於編輯標頭檔案非常有用,例如
:pedit defs.h最後,可以使用 ":psearch" 在目前檔案和任何包含的檔案中尋找單字,並在預覽視窗中顯示符合項。當使用您沒有標籤檔案的程式庫函式時,這特別有用。範例
:psearch popen這會在預覽視窗中顯示 "stdio.h" 檔案,並包含 popen() 函式的原型。
FILE *popen __P((const char *, const char *));
您可以使用 'previewheight' 選項來指定預覽視窗開啟時的高度。#ifdef USE_POPEN
fd = popen("ls", "r")
#else
fd = fopen("tmp", "w")
#endif
但它們可能會更長,甚至有巢狀結構。將游標放在 "#ifdef" 上,然後按下 %。Vim 會跳到 "#else"。再次按下 % 會將您帶到 "#endif"。再按一次 % 會將您帶回 "#ifdef"。當結構是巢狀時,Vim 會找到匹配的項目。這是一個檢查您是否忘記 "#endif" 的好方法。當您在 "#if" - "#endif" 內部時,您可以使用以下命令跳到它的開頭:[#如果您不是在 "#if" 或 "#ifdef" 之後,Vim 會發出嗶聲。要向前跳到下一個 "#else" 或 "#endif",請使用:
]#這兩個命令會跳過它們遇到的任何 "#if" - "#endif" 區塊。範例:
[(
])
/* - */
註解。+-> +-> /* | [/ | * A comment about --+ [/ | +-- * wonderful life. | ]/ | */ <-+ | +-- foo = bar * 3; --+ | ]/ /* a short comment */ <-+
[IVim 會列出它找到的匹配行。不僅在目前檔案中,也在所有包含的檔案中(以及包含在其中的檔案等等)。結果如下所示:
structs.h 1: 29 unsigned column; /* column number */與使用標籤或預覽視窗相比,其優勢在於會搜尋包含的檔案。在大多數情況下,這樣可以找到正確的宣告。即使標籤檔案已過時,或者您沒有包含檔案的標籤,也是如此。然而,要讓 "[I" 發揮作用,必須滿足一些條件。首先,'include' 選項必須指定檔案的包含方式。預設值適用於 C 和 C++。對於其他語言,您必須變更它。
:checkpath它會列出找不到的包含檔案。也會列出找到的檔案所包含的檔案。以下是輸出的範例:
:set path+=/usr/local/X11當有很多子目錄時,可以使用 "*" 萬用字元。範例:
:set path+=/usr/*/include這會在 "/usr/local/include" 以及 "/usr/X11/include" 中尋找檔案。
:set path+=/projects/invent/**/include這會在以下目錄中尋找檔案:
:checkpath!您會得到一個(非常長的)包含檔案清單,它們包含的檔案等等。為了縮短清單,Vim 會為先前找到的檔案顯示 "(已列出)",並且不會再次列出其中的包含檔案。
[<Tab>您也可以使用 "[
CTRL-I
",因為 CTRL-I
與按下 <Tab>
相同。3[<Tab>會跳到清單中的第三個項目。請記住,您可以使用
CTRL-O
跳回您開始的位置。[D同樣地,這會在包含的檔案中搜尋。'define' 選項指定定義 "[D" 項目的行的外觀。您可以變更它,使其適用於 C 或 C++ 以外的其他語言。與 "[D" 相關的命令有:
gD提示:跳到定義處。此命令對於尋找在本機宣告的變數或函式(在 C 術語中為 "static")非常有用。範例(游標在 "counter" 上):
+-> static int counter = 0; | | int get_counter(void) gD | { | ++counter; +-- return counter; }
gd這會回到目前函式的開頭,並尋找游標下單字的第一個出現位置。實際上,它會向後搜尋到第一欄中 "{" 上方的空白行。從那裡開始,它會向前搜尋識別碼。範例(游標在 "idx" 上):
int find_entry(char *name) { +-> int idx; | gd | for (idx = 0; idx < table_len; ++idx) | if (strcmp(table[idx].name, name) == 0) +-- return idx; }