Vim

如何在vim中進行嵌套縮進?

  • November 7, 2020

我想在 vim 中製作 if-fi 語句,其中iabbrev將“自動完成”if-fi子句:

autocmd Filetype sh iabbrev if if<esc>ma<cr>ifi<esc>`ak

這會if產生:

if
fi

沒錯——我不必fi在子句末尾輸入。所以我可以繼續。例如:

if pwd; then
   echo "bla bla"

fi

現在在下面echo,我想嵌套另一個語句,但是這一次,如果我鍵入if它會生成:

if pwd; then
   echo "bla bla"

   if
fi
fi

第二個(嵌套的)if-fi 打破了縮進。fi結局應該是這樣的:

if pwd; then
   echo "bla bla"

   if
   fi
fi

所以第二個if-fi子句是第一個*子句。*但我不知道如何實現這一目標。我有

:set autoindent
:set smartindent

所以 vim 記住 上的縮進級別<cr>,所以我可以在嵌套if-fi的一個退格中獲得正確的縮進。但我不知道我應該做什麼樣的鍵映射來實現這一點。那麼我應該添加什麼鍵映射才能.vimrciabbrevvim 中生成正確的縮進級別?

我沒有重現您遇到的確切問題,filetype=sh並且啟用了縮進外掛,它似乎正在重新感染fi以匹配if我。

但是我可以在您的縮寫中看到一個問題,因為它使用<CR>in normal 模式移動到下一行,然後使用 ani插入fi零件。一方面,它指望下一行已經是空的(否則它只會在fi已經存在的任何內容之前添加。)它也可能導致您的問題,因為在新行上插入通常不會觸發自動縮進插入新行(使用<CR>插入模式或普通模式o命令)會。

我的建議是保持插入模式並使用<C-o>執行單個正常模式命令來設置標記並移動到它。(見:help i_CTRL-O。)

這個縮寫應該很好用:

iabbrev if if<C-o>ma<CR>fi<C-o>`a

請注意,這<CR>是在插入模式下發生的,因此它實際上是在插入新行,並且在插入新行時autoindent通常會受到尊重。

如果您要為每個文件類型設置縮寫,通常應該將它們設置為緩衝區本地,因此如果您有其他緩衝區編輯不同類型的文件,它們將不適用於那裡。您可以通過<buffer>在命令中添加修飾符來做到這一點:

iabbrev <buffer> if if<C-o>ma<cr>fi<C-o>`a

然後,您可以根據需要將其添加到一個autocmd FileTye sh。如果您使用autocmd,您通常希望將其保存在 中augroup,因此如果您再次獲取 vimrc 文件,它不會複製自動命令並在每次匹配文件類型時多次執行它。

我通常的偏好是讓 Vim ftplugin 機制為我處理。為此,只需創建一個名為的文件~/.vim/after/ftplugin/sh.vim並將您的iabbrev <buffer> ...命令直接添加到其中。(不要添加該autocmd部分。)Vim 會自動處理這些,每當檢測到文件類型為 時sh,它會自動獲取所有這些腳本。這使得為特定文件類型獲取許多規則變得更加簡單。您也不會使用所有特定於文件類型的規則來污染您的 vimrc。最後,您無需擔心使用自動命令和映射來轉義那些長行。

引用自:https://unix.stackexchange.com/questions/616745