[英]vim: map command with confirmation to key
我在我的.vimrc中為我正在使用的版本控制系統編寫了一些宏(Perforce)(請不要為vim建議perforce插件,我試過它,我不喜歡它)。 它們都可以正常工作,除了恢復宏,它由於確認提示而中斷(我需要這樣做,所以我不會意外地指責我的變化)。 它目前看起來像這樣:
map <F8> :if confirm('Revert to original?', "&Yes\n&No", 1)==1 | !p4 revert <C-R>=expand("%:p")<CR><CR><CR>:edit<CR> | endif
當vim嘗試加載文件時,這會導致bash抱怨:
bin/bash: -c: line 0: syntax error near unexpected token `('
看看緩沖區bash看到的,看起來錯誤是vim在第一個管道之后發送了所有內容,而不僅僅是用於bash的部分。 我嘗試了一些替代方案,但我似乎無法使其工作。 當我刪除管道和endif(使用速記if)時,我已經讓它正確顯示確認對話框,但是在用戶給出響應之后vim會抱怨。
我想你想要這樣的東西:
:map <F8> :if confirm('Revert to original?', "&Yes\n&No", 1)==1 <Bar> exe "!p4 revert" . expand("%:p") <Bar> edit <Bar> endif<CR><CR>
請記住:map
是一個愚蠢的擊鍵序列:你將F8
映射到必須是一系列擊鍵,如果鍵入的話。 在:if
語句中間的<CR>
並不意味着'並且如果條件為真,則在此時執行命令時按Enter
'; 這意味着'在輸入:if
命令'的過程中按Enter
,這顯然不是你想要的。
從內到外,隨時將它構建成一塊:
:if
要執行'有時'位,所以有一個:endif
跟隨它。 !
以下所有內容都傳遞給shell,包括|
通常表示另一個Vim命令開始的字符。 這是合理的,因為|
是一個在shell命令中使用的完美字符。 所以我們需要一些包含shell命令的方法。 :exe
可以做到這一點; 它將提供的字符串作為命令執行 - 其參數(作為字符串)具有已定義的結尾。 所以一般形式是:if condition | exe "!shell command" | endif
:if condition | exe "!shell command" | endif
:if condition | exe "!shell command" | endif
。 :exe
使這很容易,因為您可以簡單地將命令的字符串常量部分與表達式的結果連接起來。 所以命令變成:exe "!p4 revert" . expand("%:p")
:exe "!p4 revert" . expand("%:p")
- 在文件上自行嘗試,並在繼續之前檢查它是否符合要求。 :if confirm('Revert to original?', "&Yes\\n&No", 1)==1 | exe "!p4 revert" . expand("%:p") | edit | endif
:if confirm('Revert to original?', "&Yes\\n&No", 1)==1 | exe "!p4 revert" . expand("%:p") | edit | endif
:if confirm('Revert to original?', "&Yes\\n&No", 1)==1 | exe "!p4 revert" . expand("%:p") | edit | endif
- 在定義映射之前再次嘗試。 |
確實結束映射並表示下一個Vim命令的開始。 在您的原始映射定義中,僅在條件結束時(在加載文件后使用:map <F8>
檢查)並且在定義映射的Vim文件上立即運行!p4
部分! 你需要改變每個|
在您的<Bar>
命令中,類似於在命令中按Enter
的方式需要寫為<CR>
。 這為您提供了上面的映射。 首先在命令行輸入它,然后執行:map <F8>
再次:map <F8>
以檢查它是否符合您的想法。 然后嘗試按F8
。 使用管道將多個vim命令串在一起並不是特別明確,並且存在許多偏心。 關鍵的是,(參見:help :bar
)它不能在像shell命令之類的命令之后使用:!
看到一個|
字符作為其參數。
您可能會發現使用system()
函數更容易。
例如
:echo system("p4 revert " . shellescape(expand("%:p")))
shellescape()
包裝器非常有用,以防你在文件名中有空格或引號等字符(或者巧妙地命名它; rm -rf ~
(不要在家里試試!))。
為了創建更易讀/可維護的代碼,您可能希望將代碼移動到一個函數中:
function Revert()
if confirm('Revert to original?', "&Yes\n&No", 1)==1
return system("p4 revert " . shellescape(expand("%:p")))
endif
endfunction
您可以在宏中使用:call
或:echo
命令訪問它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.