2011-09-13 13 views
1

我試圖在vim中定義一個新的命令,它調用一個帶有當前文件名稱的外部腳本,但稍作修改。以下是我定義的命令:在新的命令定義中調用vim substitute()和展開()調用

:command MyNewCommand !/tmp/myscript.sh substitute(expand("%:p"), "-debug", "", 'g') 

換句話說,myscript.sh需要一個參數,它是正在編輯的文件的完整路徑,在刪除路徑字符串「-debug」。我的命令定義不起作用,因爲不是傳遞路徑名,vim似乎將整個字符串本身傳遞,以單詞'substitute'開始,以myscript.sh。我如何定義命令來做我想做的事?謝謝 :)。

回答

3

更改命令定義如下。

:command! MyNewCommand call system('/tmp/myscript.sh ' . 
\ shellescape(substitute(expand('%:p'), '-debug', '', 'g'))) 

要查看命令的輸出與替換echocall

+0

非常棒!感謝指針! – PonyEars

2

可以使用類似的解決方案@ IB的一個,但!它會顯示你的shell命令的輸出(當expand('%:p')包含新行還將處理情況(它可以的,如果FS是完全兼容POSIX)):

command MyNewCommand execute '!/tmp/myscript.sh' shellescape(substitute(expand('%:p'), '-debug', '', 'g')) 
+3

您是否嘗試運行該命令?它不適用於包含換行符的文件名!這並不奇怪,因爲Vim幫助指出'換行符結束{cmd},接下來被解釋爲一個後面的「:」命令。但是,如果在換行符之前有一個反斜槓,它將被移除並繼續{cmd}。' (參見':h:!')。所以,至少有必要使用'shellescape()'函數來跳過文件名。順便說一句,使用'system()'適當引用文件名(它們周圍的單引號對Bash有效)適用於大多數情況。 –

+0

@ib:你是否使用換行符在文件名上運行它?喘氣! +1爲'shellescape'雖然:) – sehe

+0

@sehe:是的,可以確定我做了'$ echo OK>「$(printf'a \ nb')」','$ echo FAIL> a',然後在Vim中做了':exe'!cat'「a \ nb」'和':exe'!cat'shellescape(「a \ nb」)''。 –

0

通用的方法是建立一個字符串,然後execute它。您的命令中的問題是substitute(expand(...未被評估,並且按原樣傳遞。

因此,在一個通用的例子

command MyNewCommand OldCommand expand("%:p") 

應轉換爲

command MyNewCommand execute 'OldCommand '.expand("%:p") 

這樣MyNewCommand只會調用execute與表達'OldCommand '.expand("%:p")execute將評估表達式,因此expand()將被計算爲文件名並連接到'OldCommand ',從而生成'OldCommand myfilename'形式的字符串。然後該字符串作爲Ex命令由相同的execute執行。