自動指令 (Autocmd)

Nvim 的 :help 頁面,是從 原始碼 使用 tree-sitter-vimdoc 解析器 產生 而來。


自動命令 autocommand
基本說明請參閱使用者手冊的 40.3 節。

1. 簡介 autocmd-intro

您可以指定在讀取或寫入檔案、進入或離開緩衝區或視窗,以及離開 Vim 時自動執行的命令。例如,您可以建立一個自動指令,為符合 *.c 的檔案設定 'cindent' 選項。您也可以使用自動指令來實現進階功能,例如編輯壓縮檔案 (請參閱 gzip-example)。通常將自動指令放置在您的 vimrc 檔案中。
E203 E204 E143 E855 E937 E952 警告:使用自動指令非常強大,可能會導致意料之外的副作用。請小心不要破壞您的文字。
最好先在可拋棄的檔案副本上進行一些測試。例如:如果您使用自動指令在開始編輯檔案時解壓縮,請確保寫入時壓縮的自動指令可以正確運作。
請為中途發生錯誤做好準備(例如,磁碟已滿)。Vim 大部分可以復原緩衝區的變更,但您可能需要手動清理其他檔案的變更(例如,壓縮已解壓縮的檔案)。
如果 BufRead* 事件允許您編輯壓縮檔案,則 FileRead* 事件也應執行相同的操作(這在某些罕見情況下可以進行復原)。盡可能為 File* 和 Buf* 事件使用相同的自動指令是一個好主意。

2. 定義自動指令 autocmd-define

:au :autocmd :au[tocmd] [group] {event} {aupat} [++once] [++nested] {cmd}{cmd} 新增到 Vim 會自動執行的命令清單中,當檔案符合 {aupat} autocmd-pattern 時,會在 {event} 觸發。 注意: 引號字元會被視為 :autocmd 的參數,且不會開始註解。Nvim 總是在現有的自動指令之後新增 {cmd},以便它們按照定義的順序執行。關於 [++nested],請參閱 autocmd-nestedautocmd-once
如果提供 [++once],則命令會執行一次,然後移除(「一次性」)。
特殊的模式 <buffer> 或 <buffer=N> 定義了緩衝區本機自動指令。請參閱 autocmd-buflocal
注意: ":autocmd" 命令只有在 "|" 出現在預期的模式位置時,才能後接另一個命令。這會正常運作
:augroup mine | au! BufRead | augroup END
但是這會將 "augroup" 視為已定義命令的一部分
:augroup mine | au! BufRead * | augroup END
:augroup mine | au BufRead * set tw=70 | augroup END
您可以將群組名稱放入命令中
:au! mine BufRead *
:au mine BufRead * set tw=70
或者使用 :execute
:augroup mine | exe "au! BufRead *" | augroup END
:augroup mine | exe "au BufRead * set tw=70" | augroup END
autocmd-expand
請注意,當定義自動指令時,":autocmd" 引數中的特殊字元(例如 "%"、"<cword>")不會展開。這些字元會在辨識到事件並執行 {cmd} 時展開。唯一的例外是 "<sfile>" 在定義自動指令時展開。範例
:au BufNewFile,BufRead *.html so <sfile>:h/html.vim
這裡 Vim 會將 <sfile> 展開為包含此行的檔案名稱。
:autocmd 會將自動指令新增到清單中,無論它們是否已經存在。當您的 .vimrc 檔案被執行兩次時,自動指令會出現兩次。為了避免這種情況,請在群組中定義您的自動指令,以便您可以輕鬆地清除它們
augroup vimrc
  " Remove all vimrc autocommands
  autocmd!
  au BufNewFile,BufRead *.html so <sfile>:h/html.vim
augroup END
如果您不想移除所有自動指令,則可以使用變數來確保 Vim 只包含一次自動指令
:if !exists("autocommands_loaded")
:  let autocommands_loaded = 1
:  au ...
:endif
當未提供 [group] 引數時,Vim 會使用目前的群組(使用 ":augroup" 定義);否則,Vim 會使用以 [group] 定義的群組。請注意,[group] 必須事先定義。您無法使用 ":au group ..." 定義新的群組;請改用 ":augroup"。
在測試自動指令時,您可能會發現 'verbose' 選項很有用
:set verbose=9
此設定會使 Vim 在執行自動指令時將它們回顯出來。
在腳本中定義自動指令時,它將能夠呼叫腳本本機的函式並使用腳本本機的對應。當觸發事件並執行命令時,它將在定義該命令的腳本上下文中執行。如果命令中使用了 <SID>,則此項很重要。
執行命令時,一個命令的訊息會覆寫先前的訊息。這與手動執行命令時不同。螢幕大部分不會向上捲動,因此不會有要求按下 Enter 鍵的提示。當一個命令輸出兩個訊息時,仍然可能發生這種情況。

3. 移除自動指令 autocmd! autocmd-remove

:au[tocmd]! [group] {event} {aupat} [++once] [++nested] {cmd} 移除與 {event}{aupat} 相關的所有自動指令,並新增命令 {cmd}。關於 [++once],請參閱 autocmd-once。關於 [++nested],請參閱 autocmd-nested
:au[tocmd]! [group] {event} {aupat} 移除與 {event}{aupat} 相關的所有自動指令。
:au[tocmd]! [group] * {aupat} 移除與所有事件的 {aupat} 相關的所有自動指令。
:au[tocmd]! [group] {event} 移除 {event} 的所有自動指令。 警告: 您不應該在沒有為 BufRead 和其他常見事件建立群組的情況下執行此操作,這可能會破壞外掛程式、語法突顯等。
:au[tocmd]! [group] 移除所有自動指令。 注意: 引號會被視為 :autocmd 的參數,且不會開始註解。 警告: 您通常不應該在沒有群組的情況下執行此操作,它會破壞外掛程式、語法突顯等。
當未提供 [group] 引數時,Vim 會使用目前的群組(使用 ":augroup" 定義);否則,Vim 會使用以 [group] 定義的群組。

4. 列出自動指令 autocmd-list

:au[tocmd] [group] {event} {aupat} 顯示與 {event}{aupat} 相關的自動指令。
:au[tocmd] [group] * {aupat} 顯示與所有事件的 {aupat} 相關的自動指令。
:au[tocmd] [group] {event} 顯示 {event} 的所有自動指令。
:au[tocmd] [group] 顯示所有自動指令。
如果您提供 [group] 引數,則 Vim 只會列出 [group] 的自動指令;否則,Vim 會列出所有群組的自動指令。請注意,此引數行為與定義和移除自動指令的行為不同。
為了列出緩衝區本機自動指令,請使用 <buffer> 或 <buffer=N> 形式的模式。請參閱 autocmd-buflocal
:autocmd-verbose
'verbose' 為非零值時,列出自動指令也會顯示它上次定義的位置。範例
:verbose autocmd BufEnter
FileExplorer  BufEnter
    *          call s:LocalBrowse(expand("<amatch>"))
        Last set from /usr/share/vim/vim-7.0/plugin/NetrwPlugin.vim
如需更多資訊,請參閱 :verbose-cmd
您可以指定以逗號分隔的事件名稱清單。此清單中不能使用空白。此命令會套用至清單中的所有事件。
對於讀取檔案,有四種可能的事件:BufNewFile 開始編輯不存在的檔案 BufReadPre BufReadPost 開始編輯現有檔案 FilterReadPre FilterReadPost 讀取具有篩選器輸出的暫存檔 FileReadPre FileReadPost 任何其他檔案讀取 Vim 在讀取檔案時只會使用這四種事件類型中的一種。「Pre」和「Post」事件會在讀取檔案之前和之後觸發。
請注意,不允許「*ReadPre」事件和所有 Filter 事件的自動指令變更目前的緩衝區(如果發生這種情況,您會收到錯誤訊息)。這是為了防止檔案讀取到錯誤的緩衝區。
請注意,'modified' 旗標會在執行 BufReadPost 和 BufNewFile 自動指令後重設。但是,如果 'modified' 選項是由自動指令設定的,則不會發生這種情況。
您可以使用 'eventignore' 選項來忽略一些事件或所有事件。
events {event} Nvim 可辨識下列事件。名稱不區分大小寫。
BufAdd
BufAdd 在將新的或現有的未列出緩衝區新增到緩衝區清單之後(啟動期間除外,請參閱 VimEnter),或者重新命名已列出的緩衝區。在 BufEnter 之前。 注意:目前的緩衝區 "%" 不是目標緩衝區 "<afile>"、"<abuf>"。<buffer=abuf> BufDelete
BufDelete 從緩衝區清單中刪除緩衝區之前。可能會先呼叫 BufUnload(如果緩衝區已載入)。也用於重新命名緩衝區清單中的緩衝區之前。 注意:目前的緩衝區 "%" 不是目標緩衝區 "<afile>"、"<abuf>"。<buffer=abuf> 請勿變更為另一個緩衝區。BufEnter
BufEnter 在進入(造訪、切換至)新的或現有的緩衝區之後。適用於設定檔案類型選項。比較 BufNew,它不會為現有的緩衝區觸發。在 BufAdd 之後。在 BufReadPost 之後。BufFilePost
BufFilePost 在使用 ":file" 或 ":saveas" 命令變更目前緩衝區的名稱之後。BufFilePre
BufFilePre 在使用 ":file" 或 ":saveas" 命令變更目前緩衝區的名稱之前。BufHidden
BufHidden 在緩衝區變成隱藏之前:當沒有視窗顯示緩衝區,但緩衝區未卸載或刪除時。
當離開 Vim 時,不適用於 ":qa" 或 ":q"。 注意:目前的緩衝區 "%" 不是目標緩衝區 "<afile>"、"<abuf>"。<buffer=abuf> BufLeave
BufLeave 在離開至另一個緩衝區之前。當離開或關閉目前的視窗,且新目前的視窗不是同一個緩衝區時也適用。
當離開 Vim 時,不適用於 ":qa" 或 ":q"。 BufModifiedSet
BufModifiedSet 在緩衝區的 'modified' 值變更之後。BufNew
BufNew 在建立新緩衝區之後(除了啟動期間,請參閱 VimEnter)或重新命名現有的緩衝區時觸發。與 BufEnter 不同,訪問(切換到)現有的緩衝區不會再次觸發此事件。 注意:目前的緩衝區 "%" 並非目標緩衝區 "<afile>"、"<abuf>"。<buffer=abuf> 另請參閱 BufAddBufNewFileBufNewFile
BufNewFile 在開始編輯不存在的檔案時觸發。可用於讀取骨架檔案。BufRead BufReadPost BufRead 或 BufReadPost 在開始編輯新緩衝區時,將檔案讀取到緩衝區之後,處理模式行之前觸發。請參閱 BufWinEnter 以在處理模式行後執行某些操作。也會在
以讓緩衝區獲得名稱的方式寫入未命名的緩衝區時觸發
成功還原檔案後觸發
執行 ":filetype detect" 時,針對 "filetypedetect" 群組觸發。不觸發於
:read file 指令
當檔案不存在時觸發。BufReadCmd
BufReadCmd 在開始編輯新緩衝區之前觸發。應將檔案讀取到緩衝區。Cmd-event BufReadPre E200 E201 BufReadPre 在開始編輯新緩衝區時,將檔案讀取到緩衝區之前觸發。如果檔案不存在,則不會使用。BufUnload
BufUnload 在卸載緩衝區之前,當緩衝區中的文字將要被釋放時觸發。在 BufWritePost 之後,BufDelete 之前觸發。當 Vim 即將退出時,會為所有已載入的緩衝區觸發。 注意:目前的緩衝區 "%" 並非目標緩衝區 "<afile>"、"<abuf>"。<buffer=abuf> 請勿切換緩衝區或視窗!當退出且 v:dying 為 2 或更大時,不會觸發。BufWinEnter
BufWinEnter 在緩衝區顯示於視窗中之後觸發。這可能發生在緩衝區載入時(處理模式行之後),或是當顯示隱藏的緩衝區時(不再隱藏)。
不會為不帶參數的 :split 觸發,因為緩衝區沒有變更;或為已在視窗中開啟檔案的 :split 觸發。會為帶有目前緩衝區名稱的 ":split" 觸發,因為它會重新載入該緩衝區。BufWinLeave
BufWinLeave 在緩衝區從視窗中移除之前觸發。當它仍在另一個視窗中可見時,不會觸發。在退出時也會觸發。在 BufUnload、BufHidden 之前觸發。 注意:目前的緩衝區 "%" 並非目標緩衝區 "<afile>"、"<abuf>"。<buffer=abuf> 當退出且 v:dying 為 2 或更大時,不會觸發。BufWipeout
BufWipeout 在完全刪除緩衝區之前觸發。BufUnload 和 BufDelete 事件可能會先被呼叫(如果緩衝區已載入且在緩衝區列表中)。也用於在緩衝區重新命名之前(即使它不在緩衝區列表中)。 注意:目前的緩衝區 "%" 並非目標緩衝區 "<afile>"、"<abuf>"。<buffer=abuf> 請勿變更為另一個緩衝區。BufWrite BufWritePre BufWrite 或 BufWritePre 在將整個緩衝區寫入檔案之前觸發。BufWriteCmd
BufWriteCmd 在將整個緩衝區寫入檔案之前觸發。應該執行檔案的寫入操作,並且如果成功,則重置 'modified',除非 'cpo' 中有 '+' 且寫入到另一個檔案 cpo-+。不應變更緩衝區內容。當指令重置 'modified' 時,還原資訊會被調整以將舊的還原狀態標記為 'modified',如同 :write 所做的一樣。Cmd-event BufWritePost
BufWritePost 在將整個緩衝區寫入檔案之後觸發(應撤銷 BufWritePre 的指令)。ChanInfo
ChanInfo 通道狀態已變更時觸發,例如 RPC 通道的用戶端描述了自己。設定這些 v:event 鍵:info。有關 info 字典的格式,請參閱 nvim_get_chan_info()ChanOpen
ChanOpen 在通道開啟之後立即觸發。設定這些 v:event 鍵:info。有關 info 字典的格式,請參閱 nvim_get_chan_info()CmdUndefined
CmdUndefined 當使用未定義的使用者命令時觸發。適用於僅在使用時定義命令。模式會與命令名稱比對。<amatch><afile> 都會擴展為命令名稱。 注意:在定義命令之前,自動完成功能將無法運作。另一種方法是始終定義使用者命令,並讓它調用自動載入的函式。請參閱 autoloadCmdlineChanged
CmdlineChanged 在對命令列內的文字進行變更後觸發。請小心不要弄亂命令列,這可能會導致 Vim 鎖定。<afile> 會擴展為 cmdline-charCmdlineEnter
CmdlineEnter 在進入命令列後觸發(包括在映射中使用 ":" 的非互動式用法:請改用 <Cmd> 以避免此問題)。模式會與 cmdline-char 比對。<afile> 會擴展為 cmdline-char。設定這些 v:event 鍵:cmdlevel cmdtype。CmdlineLeave
CmdlineLeave 在離開命令列之前觸發(包括在映射中使用 ":" 的非互動式用法:請改用 <Cmd> 以避免此問題)。<afile> 會擴展為 cmdline-char。設定這些 v:event 鍵:abort (可變) cmdlevel cmdtype。 注意:abort 只能從 false 變更為 true:無法透過將其變更為 false 來執行已中止的命令列。CmdwinEnter
CmdwinEnter 在進入命令列視窗之後觸發。適用於為此特殊類型的視窗設定特定選項。<afile> 會擴展為單個字元,表示命令列的類型。cmdwin-charCmdwinLeave
CmdwinLeave 在離開命令列視窗之前觸發。適用於清除使用 CmdwinEnter 完成的任何全域設定。<afile> 會擴展為單個字元,表示命令列的類型。cmdwin-charColorScheme
ColorScheme 在載入色彩配置後觸發。:colorscheme 如果找不到色彩配置,則不會觸發。模式會與色彩配置名稱比對。<afile> 可用於此選項實際設定的檔案名稱,而 <amatch> 則可用於新的色彩配置名稱。
ColorSchemePre
ColorSchemePre 在載入色彩配置之前觸發。:colorscheme 適用於在載入另一個色彩配置之前,設定移除由色彩配置新增的內容。
CompleteChanged CompleteChanged
每次插入模式完成選單變更之後觸發。不會在彈出式選單隱藏時觸發,請改用 CompleteDonePreCompleteDone
設定這些 v:event 鍵:completed_item。請參閱 complete-items。height 可見項目數量。width 螢幕儲存格。row 頂部螢幕列。col 最左側螢幕欄。size 項目總數。scrollbar 如果可見則為 TRUE。
非遞迴 (事件無法自行觸發)。無法變更文字。textlock
也可以透過呼叫 pum_getpos() 取得彈出式視窗的大小和位置。
CompleteDonePre
CompleteDonePre 在插入模式完成後觸發。無論是完成某些內容或放棄完成時都會觸發。ins-completion 可以使用 complete_info(),資訊會在觸發 CompleteDonePre 之後清除。v:completed_item 變數包含有關已完成項目的資訊。
CompleteDone
CompleteDone 在插入模式完成後觸發。無論是完成某些內容或放棄完成時都會觸發。ins-completion 無法使用 complete_info(),資訊會在觸發 CompleteDone 之前清除。如果需要,請使用 CompleteDonePre。v:completed_item 提供已完成的項目。
設定這些 v:event 鍵:reason。完成的原因。可以是下列其中一項
"accept":使用 complete_CTRL-Y 接受完成。
"cancel":使用 complete_CTRL-E、按下非關鍵字字元或觸發新的完成而取消完成。
CursorHold
CursorHold 當使用者在 'updatetime' 指定的時間內沒有按下任何按鍵時觸發。在使用者按下按鍵之前不會觸發(亦即,如果您離開 Vim 去泡咖啡,不會每隔 'updatetime' 毫秒觸發 :))。有關預覽標籤的資訊,請參閱 CursorHold-example。此事件僅在普通模式中觸發。當等待輸入指令引數,或在運算子之後移動時,不會觸發。在錄製時,CursorHold 事件不會觸發。q <CursorHold>
在內部,自動命令由 <CursorHold> 按鍵觸發。在運算式映射中,getchar() 可能會看到此字元。
注意:此事件無法使用互動式指令。沒有按下 Enter 的提示,畫面會直接更新(在需要時)。 注意:未來可能會提供另一個選項來設定時間。提示:要強制更新狀態列,請使用
:let &ro = &ro
CursorHoldI
CursorHoldI 與 CursorHold 類似,但在插入模式中觸發。當等待另一個按鍵時不會觸發,例如在 CTRL-V 之後,也不會在 CTRL-X 模式中觸發 insert_expand
CursorMoved
CursorMoved 在普通模式或視覺模式中移動游標或移動到另一個視窗後觸發。當游標行的文字已變更時也會觸發,例如使用 "x"、"rx" 或 "p"。並非總是在有預鍵入時、在腳本檔案中執行指令時或在運算子處於暫止狀態時觸發。有關範例,請參閱 match-parens 注意:無法使用 :noautocmd 跳過。請注意:此事件觸發非常頻繁,請勿執行使用者不期望或速度緩慢的任何操作。CursorMovedC
CursorMovedC 在命令列中移動游標後觸發。請小心不要弄亂命令列,這可能會導致 Vim 鎖定。<afile> 會擴展為 cmdline-charCursorMovedI
CursorMovedI 在插入模式中移動游標後觸發。當彈出式選單可見時不會觸發。其他方面與 CursorMoved 相同。DiffUpdated
DiffUpdated 在差異更新後觸發。根據使用的差異類型(內部或外部),這可以在每次變更或執行 :diffupdate 時觸發。DirChanged
DirChanged 在目前目錄變更後觸發。模式可以是:「window」在 :lcd 時觸發、「tabpage」在 :tcd 時觸發、「global」在 :cd 時觸發、「auto」在'autochdir'時觸發。會設定這些 v:event 鍵:cwd:目前工作目錄,scope: "global"、"tabpage"、"window",changed_window:如果我們因切換視窗(或標籤頁)而觸發事件,則為 v:true,<afile> 會設定為新的目錄名稱。非遞迴(事件無法觸發自身)。DirChangedPre
DirChangedPre 當目前目錄即將變更時觸發,如同DirChanged。模式與DirChanged相同。會設定這些 v:event 鍵:directory:新的工作目錄,scope:"global"、"tabpage"、"window",changed_window:如果我們因切換視窗(或標籤頁)而觸發事件,則為 v:true,<afile> 會設定為新的目錄名稱。非遞迴(事件無法觸發自身)。ExitPre
ExitPre 當使用 :quit:wq 以會使 Vim 結束的方式,或使用 :qall 時,在 QuitPre 之後觸發。可用於關閉任何非必要的視窗。如果存在未自動儲存的已修改緩衝區,則退出可能仍然會被取消,請使用 VimLeavePre 進行真正的退出。另請參閱 QuitPreWinClosedFileAppendCmd
FileAppendCmd 在附加到檔案之前觸發。應執行將內容附加到檔案的操作。使用 '[ 和 ']' 標記來表示行範圍。Cmd-event FileAppendPost
FileAppendPost 在附加到檔案之後觸發。FileAppendPre
FileAppendPre 在附加到檔案之前觸發。使用 '[ 和 ']' 標記來表示行範圍。FileChangedRO
FileChangedRO 在首次變更唯讀檔案之前觸發。可用於從原始碼控制系統檢出檔案。當變更由自動指令引起時不會觸發。在緩衝區中首次變更或在設定 'readonly' 後首次變更時觸發,就在變更應用於文字之前。警告:如果自動指令移動游標,則變更的效果未定義。E788
無法切換緩衝區。您可以重新載入緩衝區,但無法編輯另一個。E881
如果行數變更,儲存以進行還原可能會失敗,並且變更將會中止。FileChangedShell
FileChangedShell 當 Vim 注意到檔案的修改時間自開始編輯以來已變更時觸發。當檔案的屬性變更或檔案的大小變更時也會觸發。時間戳記 針對每個已變更的檔案觸發,在
執行 shell 命令後
當設定 'autoread' 且緩衝區未變更時不使用。如果存在 FileChangedShell 自動指令,則不會給出警告訊息和提示。v:fcs_reason 指示發生了什麼事。設定 v:fcs_choice 來控制接下來會發生什麼。注意:目前的緩衝區 "%" 不是目標緩衝區 "<afile>" 和 "<abuf>"。<buffer=abuf> E246 E811 無法切換、跳轉或刪除緩衝區。非遞迴(事件無法觸發自身)。FileChangedShellPost
FileChangedShellPost 在處理了在 Vim 外部變更的檔案後觸發。可用於更新狀態列。FileReadCmd
FileReadCmd 在使用 ":read" 命令讀取檔案之前觸發。應執行讀取檔案的操作。Cmd-event FileReadPost
FileReadPost 在使用 ":read" 命令讀取檔案之後觸發。請注意,Vim 會將 '[ 和 ']' 標記設定為所讀取的第一行和最後一行。這可以用於對剛讀取的行進行操作。FileReadPre
FileReadPre 在使用 ":read" 命令讀取檔案之前觸發。FileType
FileType 當 'filetype' 選項已設定時觸發。模式會比對檔案類型。<afile> 是設定此選項的檔案名稱。<amatch>'filetype' 的新值。無法切換視窗或緩衝區。請參閱 檔案類型FileWriteCmd
FileWriteCmd 在寫入檔案之前,當不寫入整個緩衝區時觸發。應執行寫入檔案的操作。不應變更緩衝區。使用 '[ 和 ']' 標記來表示行範圍。Cmd-event FileWritePost
FileWritePost 在寫入檔案之後,當不寫入整個緩衝區時觸發。FileWritePre
FileWritePre 在寫入檔案之前,當不寫入整個緩衝區時觸發。使用 '[ 和 ']' 標記來表示行範圍。FilterReadPost
FilterReadPost 在從篩選命令讀取檔案之後觸發。Vim 會根據目前緩衝區的名稱檢查模式,如同 FilterReadPre 一樣。當 'shelltemp' 關閉時不會觸發。FilterReadPre E135 FilterReadPre 在從篩選命令讀取檔案之前觸發。Vim 會根據目前緩衝區的名稱檢查模式,而不是篩選命令輸出的暫存檔名稱。當 'shelltemp' 關閉時不會觸發。FilterWritePost
FilterWritePost 在為篩選命令寫入檔案或使用外部 diff 進行 diff 時(請參閱 DiffUpdated 了解內部 diff)觸發。Vim 會根據目前緩衝區的名稱檢查模式,如同 FilterWritePre 一樣。當 'shelltemp' 關閉時不會觸發。FilterWritePre
FilterWritePre 在為篩選命令寫入檔案或使用外部 diff 進行 diff 之前觸發。Vim 會根據目前緩衝區的名稱檢查模式,而不是篩選命令輸出的暫存檔名稱。當 'shelltemp' 關閉時不會觸發。FocusGained
FocusGained Nvim 取得焦點時觸發。FocusLost
FocusLost Nvim 失去焦點時觸發。也可能在彈出 GUI 對話方塊時觸發。FuncUndefined
FuncUndefined 當使用未定義的使用者函數時觸發。適用於僅在使用時定義函數。模式會比對函數名稱。<amatch><afile> 都會設定為函數名稱。注意:當編寫 Vim 指令碼時,更好的選擇是使用自動載入的函數。請參閱 自動載入函數UIEnter
UIEnter 在 UI 透過 nvim_ui_attach() 連線後,或在內建 TUI 啟動後,在 VimEnter 之後觸發。會設定這些 v:event 鍵:chan:UI 的通道 ID UILeave
UILeave 在 UI 從 Nvim 斷線後,或在內建 TUI 停止後,在 VimLeave 之後觸發。會設定這些 v:event 鍵:chan:UI 的 通道 ID InsertChange
InsertChange 當在插入或取代模式下輸入 <Insert> 時觸發。v:insertmode 變數會指示新模式。請小心不要移動游標或執行任何使用者不期望的操作。InsertCharPre
InsertCharPre 當在插入模式下輸入字元時,在插入字元之前觸發。v:char 變數會指示輸入的字元,並且可以在事件期間變更以插入不同的字元。當 v:char 設定為多個字元時,此文字會按字面插入。
無法變更文字。textlock InsertEnter
InsertEnter 就在啟動插入模式之前觸發。也適用於取代模式和虛擬取代模式。v:insertmode 變數會指示模式。請小心不要執行任何使用者不期望的操作。游標會在之後恢復。如果您不希望這樣,請將 v:char 設定為非空字串。InsertLeavePre
InsertLeavePre 就在離開插入模式之前觸發。當使用 CTRL-O i_CTRL-O 時也會觸發。請小心不要變更模式或使用 :normal,這很可能會造成問題。InsertLeave
InsertLeave 就在離開插入模式之後觸發。當使用 CTRL-O i_CTRL-O 時也會觸發。但不適用於 i_CTRL-CMenuPopup
MenuPopup 就在顯示彈出式選單(在滑鼠右鍵下方)之前觸發。適用於調整游標或滑鼠指標下的選單。模式會比對一或兩個字元,這些字元代表模式:n 一般 v 可視 o 運算子等待 i 插入 c 命令列 tl 終端機 ModeChanged
ModeChanged 在變更模式後觸發。模式會比對 'old_mode:new_mode',例如比對 *:c 來模擬 CmdlineEnter。會設定以下 v:event 值:old_mode 變更前的模式。new_mode 新模式,也由以非零參數呼叫的 mode() 傳回。當觸發 ModeChanged 時,old_mode 的值會是上次觸發事件時 new_mode 的值。這將在每次輕微的模式變更時觸發。使用範例:在進入可視模式時使用相對行號
:au ModeChanged [vV\x16]*:* let &l:rnu = mode() =~# '^[vV\x16]'
:au ModeChanged *:[vV\x16]* let &l:rnu = mode() =~# '^[vV\x16]'
:au WinEnter,WinLeave * let &l:rnu = mode() =~# '^[vV\x16]'
OptionSet
OptionSet 在設定選項之後(除了在啟動期間)。autocmd-pattern 會與長選項名稱進行比對。<amatch> 指示已設定哪個選項。
v:option_type 指示它是全域作用域還是局部作用域。v:option_command 指示使用了哪種類型的 set/let 命令(請追蹤標籤查看表格)。v:option_new 指示新設定的值。v:option_oldlocal 具有舊的局部值。v:option_oldglobal 具有舊的全域值。v:option_old 指示舊的選項值。
只有在使用:set:setlocalmodeline 設定選項時,才會設定 v:option_oldlocal。同樣地,只有在使用 :set:setglobal 時,才會設定 v:option_oldglobal
這不會設定 <abuf>,您可以使用 bufnr()
請注意,當使用 :set 設定全域-局部選項時,v:option_old 是舊的全域值。但是,對於所有非全域-局部的選項,它是舊的局部值。
使用範例:檢查'backupdir''undodir'選項中的目錄是否存在,如果目錄尚不存在,則建立該目錄。
注意:請勿在此自動命令期間重設相同的選項,這可能會破壞外掛程式。您始終可以使用:noautocmd來防止觸發OptionSet。
非遞迴:自動命令中的 :set 不會再次觸發 OptionSet。
不會在啟動時觸發。
QuickFixCmdPre
QuickFixCmdPre 在執行 quickfix 命令之前(:make:lmake:grep:lgrep:grepadd:lgrepadd:vimgrep:lvimgrep:vimgrepadd:lvimgrepadd:cfile:cgetfile:caddfile:lfile:lgetfile:laddfile:helpgrep:lhelpgrep:cexpr:cgetexpr:caddexpr:cbuffer:cgetbuffer:caddbuffer)。該模式會與正在執行的命令進行比對。當使用 :grep'grepprg' 設定為 "internal" 時,它仍然會比對 "grep"。此命令不能用於設定 'makeprg''grepprg' 變數。如果此命令導致錯誤,則不會執行 quickfix 命令。QuickFixCmdPost
QuickFixCmdPost 類似於 QuickFixCmdPre,但在執行 quickfix 命令之後,在跳到第一個位置之前。對於 :cfile:lfile 命令,它會在讀取錯誤檔案後以及移動到第一個錯誤之前執行。請參閱 QuickFixCmdPost-exampleQuitPre
QuitPre 當使用 :quit:wq:qall 時,在決定是否關閉目前視窗或退出 Vim 之前。對於 :wq,會在觸發 QuitPre 之前寫入緩衝區。如果目前視窗是最後一個普通視窗,則可以使用它來關閉任何非必要的視窗。另請參閱 ExitPreWinClosedRemoteReply
RemoteReply 當收到來自作為伺服器運作的 Vim 的回覆 server2client() 時。該模式會與 {serverid} 進行比對。<amatch> 等於傳送回覆的 {serverid},而 <afile> 則是實際的回覆字串。請注意,即使定義了自動命令,也應使用 remote_read() 讀取回覆以使用它。SearchWrapped
SearchWrapped 如果搜尋使用 nN 在文件周圍回到開始/結束位置,則在進行搜尋後觸發。RecordingEnter
RecordingEnter 當巨集開始錄製時。模式是目前檔案名稱,而 reg_recording() 是目前使用的暫存器。RecordingLeave
RecordingLeave 當巨集停止錄製時。模式是目前檔案名稱,而 reg_recording() 是錄製的暫存器。只有在此事件之後才會更新 reg_recorded()。設定這些 v:event 金鑰:regcontents regname SafeState
SafeState 當沒有任何待處理時,準備等待使用者輸入字元。在以下情況下,不會觸發此事件
有運算子正在等待
使用 "r 進入暫存器
正在執行命令的一半
正在執行對應
有預先輸入
插入模式完成處於作用中
命令列完成處於作用中 您可以使用 mode() 來找出 Vim 處於哪個狀態。可能是
視覺模式
正常模式
插入模式
命令列模式 根據您要執行的操作,您也可以使用 state() 檢查更多內容,例如螢幕是否已針對訊息捲動。
SessionLoadPost
SessionLoadPost 在載入使用 :mksession 命令建立的工作階段檔案之後。SessionWritePost
SessionWritePost 在透過呼叫 :mksession 命令寫入工作階段檔案之後。ShellCmdPost
ShellCmdPost 在使用 :!cmd:make:grep 執行 shell 命令之後。可用於檢查是否有任何已變更的檔案。對於非阻塞的 shell 命令,請參閱 job-controlSignal
Signal 在 Nvim 收到訊號之後。模式會與訊號名稱進行比對。僅支援 "SIGUSR1" 和 "SIGWINCH"。範例
autocmd Signal SIGUSR1 call some#func()
ShellFilterPost
ShellFilterPost 在使用 ":{range}!cmd"、":w !cmd" 或 ":r !cmd" 執行 shell 命令之後。可用於檢查是否有任何已變更的檔案。SourcePre
SourcePre 在載入 Vimscript/Lua 檔案之前。:source <afile> 是要載入的檔案名稱。SourcePost
SourcePost 在載入 Vimscript/Lua 檔案之後。:source <afile> 是要載入的檔案名稱。如果載入被中斷,則不會觸發。在觸發 SourceCmd 自動命令之後也會觸發。SourceCmd
SourceCmd 當載入 Vimscript/Lua 檔案時。:source <afile> 是要載入的檔案名稱。自動命令必須載入該檔案。Cmd-event SpellFileMissing
SpellFileMissing 當嘗試載入拼字檢查檔案但找不到時。該模式會與語言進行比對。<amatch> 是語言,'encoding' 也很重要。請參閱 spell-SpellFileMissingStdinReadPost
StdinReadPost 在啟動期間,從 stdin 讀取到緩衝區後,在執行 modeline 之前。-- StdinReadPre
StdinReadPre 在啟動期間,從 stdin 讀取到緩衝區之前。-- SwapExists
SwapExists 在開始編輯檔案時偵測到現有的交換檔案。僅當可以選擇處理情況的方式時,Vim 會詢問使用者該怎麼做。 v:swapname 變數會保留找到的交換檔案名稱,<afile> 是正在編輯的檔案。v:swapcommand 可能包含要在開啟的檔案中執行的命令。這些命令應將 v:swapchoice 變數設定為具有一個字元的字串,以告知 Vim 接下來應執行什麼操作: 'o' 以唯讀方式開啟 'e' 無論如何編輯檔案 'r' 復原 'd' 刪除交換檔案 'q' 退出,不要編輯檔案 'a' 中止,如同按下 CTRL-C 當設定為空字串時,將會詢問使用者,就像沒有 SwapExists 自動命令一樣。E812
無法變更到另一個緩衝區、變更緩衝區名稱或變更目錄。Syntax
Syntax 當設定了 'syntax' 選項時。該模式會與語法名稱進行比對。<afile> 會展開為設定此選項的檔案名稱。<amatch> 會展開為 'syntax' 的新值。請參閱 :syn-onTabEnter
TabEnter 在進入索引標籤頁面之後。tab-page 在 WinEnter 之後。在 BufEnter 之前。TabLeave
TabLeave 在離開索引標籤頁面之前。tab-page 在 WinLeave 之後。TabNew
TabNew 當建立新的索引標籤頁面時。tab-page 在 WinEnter 之後。在 TabEnter 之前。TabNewEntered
TabNewEntered 在進入新的索引標籤頁面之後。tab-page 在 BufEnter 之後。TabClosed
TabClosed 在關閉索引標籤頁面之後。<afile> 會展開為索引標籤頁面編號。TermOpen
TermOpen 當 終端機工作開始時。可用於設定終端機緩衝區。TermEnter
TermEnter 在進入 終端機模式之後。在 TermOpen 之後。TermLeave
TermLeave 在離開 終端機模式之後。在 TermClose 之後。TermClose
TermClose 當 終端機工作結束時。設定這些 v:event 金鑰:status TermRequest
TermRequest 當 :terminal 子處理程序發出 OSC 或 DCS 序列時。設定 v:termrequestevent-data 是請求字串。TermResponse
TermResponse 當 Nvim 收到來自主機終端機的 OSC 或 DCS 回覆時。設定 v:termresponseevent-data 是回覆字串。可能會在另一個事件期間觸發(檔案 I/O、shell 命令或任何其他需要時間的操作)。範例
-- Query the terminal palette for the RGB value of color 1
-- (red) using OSC 4
vim.api.nvim_create_autocmd('TermResponse', {
  once = true,
  callback = function(args)
    local resp = args.data
    local r, g, b = resp:match("\027%]4;1;rgb:(%w+)/(%w+)/(%w+)")
  end,
})
io.stdout:write("\027]4;1;?\027\\")
TextChanged
TextChanged 在正常模式中變更目前緩衝區中的文字後。也就是在 b:changedtick 變更之後(也包括在定義 TextChanged 自動命令之前發生的情況)。當有預先輸入或有運算子正在等待時,則不會觸發。注意:無法使用 :noautocmd 跳過。請小心:這會非常頻繁地觸發,請勿執行使用者不期望或速度慢的任何操作。TextChangedI
TextChangedI 在插入模式下,當目前緩衝區的文字發生變更時觸發。當快顯選單可見時不會觸發。其他方面與 TextChanged 相同。TextChangedP
TextChangedP 在插入模式下,當目前緩衝區的文字發生變更時觸發,僅限於快顯選單可見時。其他方面與 TextChanged 相同。TextChangedT
TextChangedT 在終端機模式下,當目前緩衝區的文字發生變更時觸發。其他方面與 TextChanged 相同。TextYankPost
TextYankPost 在 yank刪除指令執行後立即觸發,但如果使用了黑洞暫存器 quote_ 或使用了 setreg() 則不會觸發。模式必須為 "*"。設定以下 v:event 鍵:inclusive operator regcontents regname regtype visual。inclusive 旗標與 '['] 標記結合使用,可以用來計算操作的精確區域。
非遞迴 (事件無法觸發自身)。無法變更文字。textlock User
User 不會自動執行。使用 :doautocmd 來觸發此事件,通常用於外掛程式中的「自訂事件」。範例
:autocmd User MyPlugin echom 'got MyPlugin event'
:doautocmd User MyPlugin
UserGettingBored
UserGettingBored 當使用者按下相同按鍵 42 次時觸發。開玩笑的! :-) VimEnter
VimEnter 在完成所有啟動程序後觸發,包括載入 vimrc 檔案、執行 "-c cmd" 引數、建立所有視窗並在其中載入緩衝區。在此事件觸發之前,v:vim_did_enter 變數會被設定,因此您可以執行
if v:vim_did_enter
  call s:init()
else
  au VimEnter * call s:init()
endif
VimLeave
VimLeave 在 Vim 結束前觸發,就在寫入 .shada 檔案後。僅執行一次,如同 VimLeavePre。使用 v:dying 來偵測異常結束。使用 v:exiting 來取得結束代碼。如果 v:dying 為 2 或更大則不會觸發。VimLeavePre
VimLeavePre 在 Vim 結束前觸發,就在寫入 .shada 檔案之前。如果與結束時目前緩衝區的名稱相符,則只會執行一次。主要用於 "*" 模式。
:autocmd VimLeavePre * call CleanupStuff()
使用 v:dying 來偵測異常結束。使用 v:exiting 來取得結束代碼。如果 v:dying 為 2 或更大則不會觸發。VimResized
VimResized 在 Vim 視窗調整大小後觸發,因此 'lines' 和/或 'columns' 發生變更。但啟動時不會觸發。VimResume
VimResume 在 Nvim 從暫停狀態恢復後觸發。VimSuspend
VimSuspend 在 Nvim 進入暫停狀態前觸發。WinClosed
WinClosed 在關閉視窗時觸發,就在從視窗佈局中移除視窗之前。模式會與視窗 ID 比對。<amatch><afile> 都會設定為視窗 ID。在 WinLeave 之後觸發。非遞迴 (事件無法觸發自身)。另請參閱ExitPreQuitPreWinEnter
WinEnter 在進入另一個視窗後觸發。當 Vim 剛啟動時,第一個視窗不會觸發。適用於設定視窗高度。如果視窗用於另一個緩衝區,Vim 會在 WinEnter 自動指令之後執行 BufEnter 自動指令。 注意:對於分割和標籤頁指令,WinEnter 事件會在分割或標籤指令之後,但在載入檔案之前觸發。
WinLeave
WinLeave 在離開視窗前觸發。如果接下來要進入的視窗是另一個緩衝區,Vim 會在 WinLeave 自動指令之前執行 BufLeave 自動指令 (但對於 ":new" 則不會)。當結束 Vim 時,對於 ":qa" 或 ":q" 不會使用。在 WinClosed 之前觸發。WinNew
WinNew 當建立新視窗時觸發。當 Vim 剛啟動時,第一個視窗不會觸發。在 WinEnter 之前觸發。
WinScrolled
WinScrolled 在目前標籤頁中的任何視窗捲動文字 (水平或垂直) 或變更寬度或高度後觸發。請參閱win-scrolled-resized
模式會與第一個捲動或調整大小的視窗的視窗 ID 比對。<amatch><afile> 都會設定為視窗 ID
v:event 會設定有關大小和捲動變更的資訊。WinScrolled-event
僅在啟動完成並完成第一次螢幕重新繪製後才開始觸發。在定義第一個 WinScrolled 或 WinResized 事件時不會觸發,但在新增更多事件時可能會觸發。
非遞迴:在執行 WinScrolled 事件的指令時,此事件不會觸發。但是,如果指令導致視窗捲動或變更大小,則稍後會觸發另一個 WinScrolled 事件。
WinResized
WinResized 在目前標籤頁中的視窗變更寬度或高度後觸發。請參閱win-scrolled-resized
v:event 會設定有關大小變更的資訊。WinResized-event
WinScrolled 的模式、觸發和遞迴行為相同。
:autocmd{aupat} 引數可以是逗號分隔的列表。這就像是分別為每個模式提供指令一樣。因此,此指令
:autocmd BufRead *.txt,*.info set et
等同於
:autocmd BufRead *.txt set et
:autocmd BufRead *.info set et
檔案模式 {aupat} 會以兩種方式測試是否與檔案名稱相符: 1. 當模式中沒有 '/' 時,Vim 只會檢查是否與檔案名稱的尾部 (不包含其開頭的目錄路徑) 相符。 2. 當模式中有 '/' 時,Vim 會檢查是否與短檔案名稱 (您輸入的名稱) 和完整檔案名稱 (展開為完整路徑並解析符號連結後) 相符。
特殊模式 <buffer> 或 <buffer=N> 用於緩衝區本機自動指令 autocmd-buflocal。此模式不會與緩衝區的名稱比對。
範例
:autocmd BufRead *.txt                set et
為所有文字檔案設定 'et' 選項。
:autocmd BufRead /vim/src/*.c        set cindent
為 /vim/src 目錄中的 C 檔案設定 'cindent' 選項。
:autocmd BufRead /tmp/*.c        set ts=5
如果您有從 "/tmp/test.c" 到 "/home/nobody/vim/src/test.c" 的連結,並且您開始編輯 "/tmp/test.c",則此自動指令會相符。
注意:若要比對路徑的一部分,但不是從根目錄開始,請使用 "*" 作為第一個字元。範例
:autocmd BufRead */doc/*.txt        set tw=78
例如,此自動指令將會為 "/tmp/doc/xx.txt" 和 "/usr/home/piet/doc/yy.txt" 執行。目錄的數量在這裡並不重要。
與模式比對的檔案名稱是在展開萬用字元之後。因此,如果您發出此指令
:e $ROOTDIR/main.$EXT
引數會先展開為
/usr/root/main.py
然後才與自動指令的模式比對。在使用 FileReadCmd 等事件時請小心,<amatch> 的值可能與您預期的不同。
環境變數可以用在模式中
:autocmd BufRead $VIMRUNTIME/doc/*.txt  set expandtab
而且 ~ 可以用於主目錄 (如果已定義 $HOME)
:autocmd BufWritePost ~/.config/nvim/init.vim   so <afile>
:autocmd BufRead ~archive/*      set readonly
環境變數會在定義自動指令時展開,而不是在執行自動指令時展開。這與指令不同!
檔案模式
模式的解釋方式大多與檔案名稱中使用的方式相同: * 符合任何字元序列; 不尋常:包含路徑分隔符號 ? 符合任何單一字元 \? 符合 '?' . 符合 '.' ~ 符合 '~' , 分隔模式 \, 符合 ',' { } 類似於 模式 中的 \( \) ,在 { } 內:類似於 模式 中的 \| \} 文字 } \{ 文字 { \\\{n,m\} 類似於 模式 中的 \{n,m} \ 特殊含義類似於 模式 中的 [ch] 符合 'c' 或 'h' [^ch] 符合除 'c' 和 'h' 之外的任何字元
請注意,對於所有系統,'/' 字元都用於路徑分隔符號 (即使是 Windows)。這樣做是因為反斜線在模式中很難使用,並且可以使自動指令在不同系統之間可攜。
可以使用 模式 項目,但它們可能無法按預期運作,因為對上述內容進行了轉換。
自動指令變更
當事件觸發時,會與模式比對。在其中一個自動指令中變更緩衝區名稱,甚至刪除緩衝區,都不會變更將要執行的自動指令。範例
au BufEnter *.foo  bdel
au BufEnter *.foo  set modified
這將會刪除目前緩衝區,然後在已成為目前緩衝區的緩衝區中設定 'modified'。Vim 不會考慮到 "*.foo" 與該緩衝區名稱不相符。它會將 "*.foo" 與事件觸發時緩衝區的名稱比對。
但是,對於使用 :bwipe 清除的緩衝區,不會執行緩衝區本機自動指令。在使用 :bdel 刪除緩衝區後,緩衝區實際上仍然存在 (它會變成未列出),因此仍然會執行自動指令。
緩衝區本機自動指令會附加到特定的緩衝區。如果緩衝區沒有名稱,且名稱與特定模式不符,則這些指令很有用。但這也表示必須明確地將它們新增到每個緩衝區。
緩衝區本機自動指令不使用模式,而是使用以下其中一種形式: <buffer> 目前緩衝區 <buffer=99> 緩衝區編號 99 <buffer=abuf> 使用 <abuf> (僅在執行自動指令時) <abuf>
範例
:au CursorHold <buffer>  echo 'hold'
:au CursorHold <buffer=33>  echo 'hold'
:au BufNewFile * au CursorHold <buffer=abuf>  echo 'hold'
自動指令的所有指令也適用於緩衝區本機自動指令,只需使用特殊字串而不是模式即可。範例
:au! * <buffer>                     " remove buffer-local autocommands for
                                 " current buffer
:au! * <buffer=33>                     " remove buffer-local autocommands for
                                 " buffer #33
:bufdo :au! CursorHold <buffer>  " remove autocmd for given event for all
                                 " buffers
:au * <buffer>                     " list buffer-local autocommands for
                                 " current buffer
請注意,當為目前緩衝區定義自動指令時,它會與緩衝區編號一起儲存。因此,它會使用 "<buffer=12>" 形式,其中 12 是目前緩衝區的編號。例如,當列出自動指令時,您會看到此內容。
若要測試緩衝區本機自動指令是否存在,請使用 exists() 函數,如下所示
:if exists("#CursorHold#<buffer=12>") | ... | endif
:if exists("#CursorHold#<buffer>") | ... | endif    " for current buffer
當清除緩衝區時,其緩衝區本機自動指令當然也會消失。請注意,當刪除緩衝區時,例如使用 ":bdel",它只會變成未列出,自動指令仍然存在。若要查看移除緩衝區本機自動指令
:set verbose=6
無法為不存在的緩衝區定義緩衝區本機自動指令。

8. 群組 autocmd-groups

自動指令可以放在群組中。這對於移除或執行一組自動指令很有用。例如,所有用於語法高亮的自動指令都會放在 "highlight" 群組中,以便在 GUI 啟動時執行 ":doautoall highlight BufRead"。
當沒有選擇特定的群組時,Vim 會使用預設群組。預設群組沒有名稱。您無法單獨執行預設群組中的自動指令;您只能透過執行所有群組的自動指令來執行它們。
通常,當自動執行自動指令時,Vim 會使用所有群組的自動指令。只有在使用 ":doautocmd" 或 ":doautoall" 執行自動指令,或定義或刪除自動指令時,群組才重要。
群組名稱可以包含任何字元,除了空白字元。群組名稱 "end" 已保留(也包含大寫)。
群組名稱區分大小寫。請注意,這與事件名稱不同!
:aug :augroup :aug[roup] {名稱} 為以下 ":autocmd" 指令定義自動指令群組名稱。名稱 "end" 或 "END" 選擇預設群組。為避免混淆,名稱應與現有的 {事件} 名稱不同,因為這很可能不會達到您預期的效果。
:augroup-delete E367 W19 E936 :aug[roup]! {名稱} 刪除自動指令群組 {名稱}。如果仍有自動指令使用此群組,請勿使用此指令!如果這樣做,您將收到警告。當群組是目前群組時,您將收到錯誤 E936。
若要輸入特定群組的自動指令,請使用此方法:1. 使用 ":augroup {名稱}" 選取群組。2. 使用 ":au!" 刪除任何舊的自動指令。3. 定義自動指令。4. 使用 "augroup END" 返回預設群組。
範例
:augroup uncompress
:  au!
:  au BufEnter *.gz        %!gunzip
:augroup END
這可以防止自動指令被定義兩次(例如,在再次執行 vimrc 檔案後)。
檔案瀏覽器
有一個群組是 Vim 可以識別的:FileExplorer。如果此群組存在,Vim 會假設可以編輯目錄,並會觸發一個列出該目錄中檔案的插件。這由 netrw 插件使用。這允許您執行
browse edit

9. 執行自動指令 autocmd-execute

Vim 也可以非自動地執行自動指令。如果您已變更自動指令,或當 Vim 執行了錯誤的自動指令時(例如,檔案模式比對錯誤),這非常有用。
請注意,'eventignore' 選項也適用於此處。此選項中列出的事件將不會導致任何指令被執行。
:do :doau :doaut :doautocmd E217 :do[autocmd] [<nomodeline>] [群組] {事件} [檔案名稱] 將符合 [檔案名稱] 的自動指令(預設值:目前檔案名稱)套用至目前緩衝區。您可以在目前檔案名稱與正確的模式不符、變更設定後,或為特定事件執行自動指令時使用此指令。也可以在自動指令內使用此指令,以便您可以將一個擴充功能的自動指令建立在另一個擴充功能之上。範例
:au BufEnter *.cpp so ~/.config/nvim/init_cpp.vim
:au BufEnter *.cpp doau BufEnter x.c
請小心避免無限迴圈。autocmd-nested
當未給定 [群組] 引數時,Vim 會執行所有群組的自動指令。當包含 [群組] 引數時,Vim 只會執行該群組中符合的自動指令。未定義的群組會產生錯誤。<nomodeline>
在套用自動指令後,會處理模型行,以便它們的設定會在編輯檔案時覆蓋自動指令的設定。如果指定 <nomodeline>,則會跳過此步驟。您可能希望對載入緩衝區時不使用的事件使用 <nomodeline>,例如 User。如果沒有執行符合的自動指令,也會跳過模型行。
:doautoa :doautoall :doautoa[ll] [<nomodeline>] [群組] {事件} [檔案名稱] 類似於 ":doautocmd",但會將自動指令套用至每個已載入的緩衝區。目前的緩衝區最後執行。
請注意,[檔案名稱] 用於選取自動指令,而不是套用它們的緩衝區。範例
augroup mine
  autocmd!
  autocmd FileType * echo expand('<amatch>')
augroup END
doautoall mine FileType Loaded-Buffer
執行此腳本時,您會看到與已載入的緩衝區數量一樣多的 "Loaded-Buffer" 回顯。
小心:請勿將此指令用於會刪除緩衝區、變更為另一個緩衝區或變更緩衝區內容的自動指令;結果是無法預測的。此指令適用於設定選項、變更高亮顯示之類的自動指令。

10. 使用自動指令 autocmd-use

對於寫入檔案,有四組可能的事件。Vim 對於寫入指令只會使用其中一組事件
BufWriteCmd BufWritePre BufWritePost 寫入整個緩衝區 FilterWritePre FilterWritePost 寫入至篩選暫存檔 FileAppendCmd FileAppendPre FileAppendPost 附加至檔案 FileWriteCmd FileWritePre FileWritePost 任何其他檔案寫入
當存在符合的 "*Cmd" 自動指令時,會假設它將執行寫入動作。不會執行進一步的寫入,並且不會觸發其他事件。Cmd-event
請注意,"*WritePost" 指令應復原由 "*WritePre" 指令造成的對緩衝區的任何變更;否則,寫入檔案將會產生變更緩衝區的副作用。
在執行自動指令之前,要寫入行的緩衝區會暫時變成目前的緩衝區。除非自動指令變更目前的緩衝區或刪除先前目前的緩衝區,否則先前目前的緩衝區會再次成為目前的緩衝區。
"*WritePre" 和 "*AppendPre" 自動指令不得刪除要寫入行的緩衝區。
'[ 和 '] 標記具有特殊的位置
在 "*ReadPre" 事件之前,'[ 標記會設定為剛好在要插入新行的上方的那一行。
在 "*ReadPost" 事件之前,'[ 標記會設定為剛讀取的第一行,'] 標記會設定為最後一行。
在執行 "*WriteCmd"、"*WritePre" 和 "*AppendPre" 自動指令之前,'[ 標記會設定為要寫入的第一行,'] 標記會設定為最後一行。小心:當使用變更緩衝區的指令時,'[ 和 '] 會變更。
在預期檔案名稱的指令中,您可以使用 "<afile>" 來表示正在讀取的檔案名稱 :<afile>(您也可以使用 "%" 表示目前檔案名稱)。"<abuf>" 可以用於表示目前有效緩衝區的緩衝區編號。這也適用於沒有名稱的緩衝區。但是,它不適用於沒有緩衝區的檔案(例如,使用 ":r file")。
gzip-範例
用於讀取和寫入壓縮檔的範例
:augroup gzip
:  autocmd!
:  autocmd BufReadPre,FileReadPre        *.gz set bin
:  autocmd BufReadPost,FileReadPost        *.gz '[,']!gunzip
:  autocmd BufReadPost,FileReadPost        *.gz set nobin
:  autocmd BufReadPost,FileReadPost        *.gz execute ":doautocmd BufReadPost " .. expand("%:r")
:  autocmd BufWritePost,FileWritePost        *.gz !mv <afile> <afile>:r
:  autocmd BufWritePost,FileWritePost        *.gz !gzip <afile>:r
:  autocmd FileAppendPre                *.gz !gunzip <afile>
:  autocmd FileAppendPre                *.gz !mv <afile>:r <afile>
:  autocmd FileAppendPost                *.gz !mv <afile> <afile>:r
:  autocmd FileAppendPost                *.gz !gzip <afile>:r
:augroup END
"gzip" 群組用於能夠使用 ":autocmd!" 刪除任何現有的自動指令,以便在檔案被執行兩次時使用。
("<afile>:r" 是不含副檔名的檔案名稱,請參閱 :_%:)
為 BufNewFile、BufRead/BufReadPost、BufWritePost、FileAppendPost 和 VimLeave 事件執行的指令不會設定或重設緩衝區的變更標誌。當您使用 BufReadPost 自動指令解壓縮緩衝區時,您仍然可以使用 ":q" 退出。當您在 BufWritePost 中使用 ":undo" 來復原由 BufWritePre 指令所做的變更時,您仍然可以執行 ":q"(這也會讓 "ZZ" 起作用)。如果您希望將緩衝區標記為已修改,請設定 'modified' 選項。
若要從自動指令執行一般模式指令,請使用 ":normal" 指令。請小心使用!如果一般模式指令未完成,使用者需要輸入字元(例如,在 ":normal m" 之後,您需要輸入一個標記名稱)。
如果您希望緩衝區在變更後保持未修改狀態,請重設 'modified' 選項。這使得可以使用 ":q" 而不是 ":q!" 退出緩衝區。
autocmd-nested E218 預設情況下,自動指令不會巢狀。例如,如果您在自動指令中使用 ":e" 或 ":w",Vim 不會為這些指令執行 BufRead 和 BufWrite 自動指令。如果您想要這樣做,請針對您想要巢狀的指令使用 "++nested" 旗標。例如
:autocmd FileChangedShell *.c ++nested e!
巢狀限制為 10 層,以避免遞迴迴圈。
可以在自動指令中使用 ":au" 指令。這可以是一個自我修改指令!這對於只需要執行一次的自動指令非常有用。
如果您想要跳過一個指令的自動指令,請使用 :noautocmd 指令修飾詞或 'eventignore' 選項。
注意:當讀取檔案(使用 ":read file" 或篩選器指令)且檔案中的最後一行沒有 <EOL> 時,Vim 會記住這一點。在下一次寫入(使用 ":write file" 或篩選器指令)時,如果將同一行再次寫入為檔案中的最後一行,且設定了 'binary',則 Vim 不會提供 <EOL>。這使得剛讀取的行上的篩選器指令寫入與讀取相同的檔案,並使得剛篩選的行上的寫入指令寫入與從篩選器讀取的相同檔案。例如,另一種寫入壓縮檔的方法
:autocmd FileWritePre *.gz   set bin|'[,']!gzip
:autocmd FileWritePost *.gz  undo|set nobin
autocommand-pattern
您可以指定多個模式,以逗號分隔。以下是一些範例
:autocmd BufRead   *                set tw=79 nocin ic infercase fo=2croq
:autocmd BufRead   .letter        set tw=72 fo=2tcrq
:autocmd BufEnter  .letter        set dict=/usr/lib/dict/words
:autocmd BufLeave  .letter        set dict=
:autocmd BufRead,BufNewFile   *.c,*.h        set tw=0 cin noic
:autocmd BufEnter  *.c,*.h        abbr FOR for (i = 0; i < 3; ++i)<CR>{<CR>}<Esc>O
:autocmd BufLeave  *.c,*.h        unabbr FOR
用於 makefile(makefile、Makefile、imakefile、makefile.unix 等)
:autocmd BufEnter  ?akefile*        set include=^s\=include
:autocmd BufLeave  ?akefile*        set include&
永遠從第一個函式開始編輯 C 檔案
:autocmd BufRead   *.c,*.h        1;/^{
如果沒有上方的 "1;",搜尋將從輸入檔案的位置開始,而不是從檔案的開頭開始。
skeleton template 在開啟新檔案時讀取骨架(範本)檔案
:autocmd BufNewFile  *.c        0r ~/vim/skeleton.c
:autocmd BufNewFile  *.h        0r ~/vim/skeleton.h
:autocmd BufNewFile  *.java        0r ~/vim/skeleton.java
在寫入 "*.html" 檔案時,在其中插入目前的日期和時間
:autocmd BufWritePre,FileWritePre *.html   ks|call LastMod()|'s
:fun LastMod()
:  if line("$") > 20
:    let l = 20
:  else
:    let l = line("$")
:  endif
:  exe "1," .. l .. "g/Last modified: /s/Last modified: .*/Last modified: " ..
:  \ strftime("%Y %b %d")
:endfun
您需要在檔案的前 20 行中有一行 "Last modified: <date time>" 才能使其運作。Vim 會將 <date time>(以及同一行中它之後的任何內容)替換為目前的日期和時間。說明:ks 使用標記 's' 標記目前位置 call LastMod() 呼叫 LastMod() 函式以執行工作 's 將游標返回到舊位置 LastMod() 函式會檢查檔案是否少於 20 行,然後使用 ":g" 指令來尋找包含 "Last modified: " 的行。對於這些行,會執行 ":s" 指令以將現有的日期替換為目前的日期。使用 ":execute" 指令來使用 ":g" 和 ":s" 指令的表示式。日期是使用 strftime() 函式取得的。您可以變更其引數以取得另一個日期字串。
當在命令列輸入 :autocmd 時,可以適當地完成事件和指令名稱(使用 <Tab>CTRL-D 等)。
Vim 會按照您指定的順序執行所有符合的自動指令。建議您使用 "*" 作為檔案模式,以便第一個自動指令用於所有檔案。這表示您可以在此處為任何設定定義您喜歡的預設值,如果還有另一個符合的自動指令,它將會覆寫這些預設值。但是,如果沒有其他符合的自動指令,那麼至少會復原您的預設設定(如果從另一個自動指令符合的檔案輸入此檔案)。請注意,"*" 也會比對以 "." 開頭的檔案,這與 Unix shell 不同。
autocmd-searchpat
自動指令不會變更目前的搜尋模式。Vim 會在執行自動指令前儲存目前的搜尋模式,然後在自動指令執行完成後還原它們。這表示自動指令不會影響以 'hlsearch' 選項所高亮的字串。在自動指令內,您仍然可以正常使用搜尋模式,例如使用 "n" 命令。如果您想要讓自動指令設定搜尋模式,以便在自動指令執行完成後使用,請使用 ":let @/ =" 命令。無法在自動指令中使用 ":nohlsearch" 來關閉搜尋高亮。請在 'shada' 選項中使用 'h' 旗標,以便在啟動 Vim 時停用搜尋高亮。
指令-事件
當使用 "*Cmd" 事件之一時,預期的相符自動指令會進行檔案讀取、寫入或來源化。這可以在處理特殊類型檔案時使用,例如在遠端系統上。注意:如果您以錯誤的方式使用這些事件,可能會導致無法讀取或寫入相符的檔案!請務必正確測試您的自動指令。最好的方式是使用一個永遠不會匹配正常檔案名稱的模式,例如 "ftp://*"。
當定義 BufReadCmd 時,Vim 將難以還原崩潰的編輯工作階段。當從原始檔案還原時,Vim 只會讀取交換檔案中找不到的檔案部分。由於使用 BufReadCmd 時無法做到這一點,請使用 :preserve 命令,以確保還原時不需要原始檔案。您可能只想在預期檔案會被修改時執行此操作。
對於檔案讀取和寫入指令,v:cmdarg 變數會保存有效的 "++enc=" 和 "++ff=" 參數。這些參數應用於讀取/寫入檔案的指令。當使用 "!" 時,v:cmdbang 變數為 1,否則為 0。
請參閱 $VIMRUNTIME/plugin/netrwPlugin.vim 以取得範例。

11. 停用自動指令 autocmd-disable

若要暫時停用自動指令,請使用 'eventignore' 選項。請注意,這可能會導致意外的行為,請務必在使用後還原 'eventignore',並使用包含 :finally:try 區塊。
:noautocmd :noa 若要僅針對一個指令停用自動指令,請使用 ":noautocmd" 指令修飾符。這將在以下指令執行期間將 'eventignore' 設定為 "all"。範例
:noautocmd w fname.gz
這將寫入檔案,而不會觸發 gzip 外掛程式所定義的自動指令。
請注意,某些自動指令不會立即觸發,而是稍後才會觸發。這特別適用於 CursorMovedTextChanged
主要
指令索引
快速參考