2010-07-08 60 views
4

我有什麼至今:如何編寫vim函數來輸出系統命令的結果?

function! GetMarker() 
    return system('echo $random `date` | md5sum | cut -d" " -f1') 
endfunction 

我希望能夠做一個:getmarker並讓它在我的光標插入系統命令的輸出,沒有新的生產線。

function!function之間的區別是什麼?

編輯:在你們之前,我需要隨機字符串來標記代碼中的部分,以便我可以通過在我的待辦事項維基中引用我的筆記再次找到它們。

回答

5

Edit1。拿兩個。試圖吸收Luc的反饋。沒有臨時文件(readfile()原來在VIM 6.x中不可用,我在某些系統上)。

:function InsertCmd(cmd) 
:  let l = system(a:cmd) 
:  let l = substitute(l, '\n$', '', '') 
:  exe "normal a".l 
:  redraw! 
:endfunction 

:imap <silent> <F5> <C-O>:call InsertCmd('echo date \| md5sum \| cut -d" " -f1')<CR> 
:map <silent> <F5> :call InsertCmd('echo date \| md5sum \| cut -d" " -f1')<CR> 

:put不能使用,因爲它工作在行方式。我用<C-O>代替<Esc>...<Insert>。我離開了重繪,因爲它有助於調用命令生成輸出到stderr的情況。

或者用<C-R>=

:function InsertCmd(cmd) 
:  let l = system(a:cmd) 
:  let l = substitute(l, '\n$', '', '') 
:  return l 
:endfunction 

:imap <silent> <F5> <C-R>=InsertCmd('echo date \| md5sum \| cut -d" " -f1')<CR> 

也就是function!function之間的區別?

大多數時間在命令結束時感嘆意味着強制執行。 (建議查看:help,因爲不同的命令使用!的方式不同,但VIM會嘗試記錄所有形式的命令。)對於function,它告訴VIM覆蓋此函數的先前定義。例如。如果將上面的代碼放入func1.vim文件中,則第一次:source func1.vim可以正常工作,但第二次將失敗,並且函數InsertCmd已被定義。


我曾嘗試實施過一次something similar here。我不擅長VIM編程,因此看起來很蹩腳,Luc的建議應該優先考慮。

這裏去反正:

:function InsertCmd(cmd) 
:  exe ':silent !'.a:cmd.' > /tmp/vim.insert.xxx 2>/dev/null' 
:  let l = readfile('/tmp/vim.insert.xxx', '', 1) 
:  exe "normal a".l[0] 
:  redraw! 
:endfunction 

:imap <silent> <F5> <Esc>:call InsertCmd('hostname')<CR><Insert> 
:map <silent> <F5> :call InsertCmd('hostname')<CR> 

儘管是瘸腿的,它的工作原理雖然。

+0

如果您的方法有一個問題,它與臨時文件有關。多個用戶不能使用相同的腳本。最好使用tempname()。否則,可能會增強一些內容: - 不重繪, - 返回l [0], - 並將其插入' ='以避免與光標位置有關的錯誤。 – 2010-07-09 09:58:49

+0

@Luc:' =' - 非常非常酷。 'tempname()' - 很好的瞭解。感謝您的建議。 – Dummy00001 2010-07-09 12:23:29

+0

「命令結束時的感嘆號意味着強制執行。」這不是真的。有很多反例。見':g',':delm',':put',... – 2010-07-12 15:36:24

5

您可以修剪/的Chomp與matchstr()substitute[:-2]最後一個換行符等

function s:GetMarker() 
    let res = system('echo $random `date` | md5sum | cut -d" " -f1') 
    " then either 
    let res = matchstr(res, '.*\ze\n') 
    " or 
    let res = res[:-2] 
    " or 
    let res = substitute(res, '\n$', '', '') 
    return res 
endfunction 
command! -nargs=0 GetMarker put=s:GetMarker() 

敲打功能/命令的定義(以「!」),將允許您源定義它的腳本幾次,從而更新你正在維護的功能/命令,而不必退出vim。

+0

這仍然插入一個新行的散列,有沒有辦法讓它插入光標? – 2010-07-10 19:36:58

+0

是的。你將不得不玩像exe +正常的東西。但命令不是這種文本操作的最佳構造。 - >'命令! -nargs = 0 GetMarker exe「正常\ = s:GetMarker()\ 」' – 2010-07-12 15:39:26

0

我遇到了類似的問題,試圖映射熱鍵來插入當前的日期和時間。我通過包括<退格>解決了換行問題,但是當我縮進時退格符會插入換行符(退格鍵會終止最後一個字符,但是當我縮進時,我得到換行符並且只有選項卡將會消失)。

所以我這樣做 - 剛滿smartindent關閉,插入的文本,然後將其重新打開:

imap <F5> <esc>:set nosmartindent<CR>a<C-R>=system('echo $random `date` \| md5sum \| cut -d" " - f1')<CR><Backspace><esc>:set smartindent<CR>a 

...它的工作原理,但它得到取消縮進,如果你坐在一個新的自動縮進行。要解決這個問題,插入字符來保存你的地方,然後逃生,關閉smartindent,甩掉多餘的字符,並做休息:

imap <F5> x<esc>:set nosmartindent<CR>a<backspace><C-R>=system('echo $random `date` \| md5sum \| cut -d" " -f1')<CR><Backspace><esc>:set smartindent<CR>a 

這似乎是工作。

相關問題