如何在 vim 中保存文件後執行 bash/zsh 命令?
我在我的 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 命令。有沒有我可以使用的條件語句 likeif [ -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 解決方案要復雜得多。