Bash

如何在 vim 中保存文件後執行 bash/zsh 命令?

  • May 18, 2020

我在我的 zshrc 中有一個別名,以便我可以編輯.zshrc,然後在 vim 中編輯後立即獲取它alias zshrc='vi ~/.zshrc && source ~/.zshrc,但即使我什麼也沒做,它也會載入文件。我希望它僅在我使用過時才載入文件,:w或者:wq如果我決定不更改任何內容,它不會不必要地重新載入它。

vim ~/.zshrc退出狀態將是0如果它成功或如果它失敗則非零。顯然,不同類型的故障會產生不同的非零回報。例如,如果我在 vim 中使用:q!vs ,vim 等效的退出狀態會是什麼:wq。也許我可以將我的 bashif語句集中在返回的退出狀態上,例如if [ $? = 113 ]; then source ~/.zshrc; fi. 我的第一個想法是它會0在任何成功打開 vim 時返回,但終端必須有某種方式來查看在 vim 內部執行了哪些 vim 命令。有沒有我可以使用的條件語句 like if [ -exec $(vim ~/.zshrc) = ":wq" ]; then source ~/.zshrc; fi. 這顯然不是一個真實的 if 條件,但有沒有辦法完成這樣的事情?

這也可能很有用,例如,如果我正在處理一個.c文件並想查看它是否在保存和退出 vim 後立即編譯,例如if [ -exec $(vim main.c) = ":wq" ]; then gcc main.c -o main && ./main; fi.

Vi(m) 以狀態 0 退出,除非它無法啟動,或者它正在執行一個腳本,該腳本強制以非零狀態退出(我不確定這是否可能),或者它被信號殺死。您無法區分:q!:wq通過退出狀態。

您可以檢查文件在您啟動編輯器和退出編輯器之間是否發生了變化。您無法判斷此編輯器會話中文件是否已更改,但我認為這並不重要。嚴格來說,如果不保持打開文件,就無法檢查文件是否發生變化,但檢查相同文件名的 inode 更改時間就足夠接近了。

zmodload -F zsh/stat b:zstat
edit-and-source-if-changed () {
 local filename=$@[$#]
 local original_ctime="$(zstat +ctime -- $filename)" 2>/dev/null
 vim "$@" || return
 [[ -n $original_ctime ]] || return
 if [[ $original_ctime != "$(zstat +ctime -- $filename 2>/dev/null)" ]]; then
   echo source $filename
 fi
}

您可以在 Vim 退出時執行命令,也可以在保存文件後執行命令。因此,在 Vim 內部,您可以在保存文件時設置一個變數,然後在退出程式碼中,如果設置了該變數,則執行一些命令來創建一個具有固定名稱的文件。在呼叫 Vim 的程式碼中,檢查該文件是否存在。這會更精確,但比上面的純 shell 解決方案要復雜得多。

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