2014-11-01 23 views
1

函數調用,我使用,我從Vimcasts Vim中得preserve the cursor position when executing a command功能:奇怪的循環行爲與保留在Vim中

" A command to preserve last search and cursor position after running another 
" command. See: http://vimcasts.org/episodes/tidying-whitespace/ 
function! Preserve(command) 
    " Preparation: save last search, and cursor position. 
    let [email protected]/ 
    let l = line(".") 
    let c = col(".") 
    " Do the business: 
    execute a:command 
    " Clean up: restore previous search history, and cursor position 
    let @/=_s 
    call cursor(l, c) 
endfunction 

" Strip trailing whitespace 
nmap <Leader>$ :call Preserve("%s/\\s\\+$//e")<CR> 

它工作得很好了帶尾隨空白映射我在這裏表示,但不是當我打電話給一個外部命令是這樣的:

" Reformat a plain text document to use hard wrapping and uniform spacing 
" Note: This uses the BSD `fmt` program. The GNU coreutils version takes 
" different options. 
nmap <Leader>f :call Preserve("%!fmt -s -78")<CR> 
vnoremap <Leader>f :call Preserve("'<,'>!fmt -s -78")<CR> 

第一測繪工作正常,但第二個表現出奇怪的循環行爲。舉例來說,如果我有一個文本文件是這樣的:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut laboret dolore magna aliqua. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 

Sed ut perspiciatis unde omnis iste natus error sit. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? 

At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Itaque reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat. 

當我選擇在視覺模式的那些行對其進行過濾,該命令可以運行出現五次。以下是我在輸出中看到的內容:

5 lines filtered 
5 lines filtered 
5 lines filtered 
5 lines filtered 
5 lines filtered 
Press ENTER or type command to continue 

如果文件有10行,那麼它們將被過濾10次。它仍然正確地過濾區域,但我很困惑爲什麼它循環。我認爲這與保留功能有關,因爲在保存之外運行命令不會顯示循環。

注:我認爲這是這個問題的適當位置,但closing of the Vi/Vim proposal讓我想知道我應該在哪裏發佈這樣的問題。請讓我知道是否有更合適的論壇。

回答

2

當您在多行視覺選擇中調用某個功能時,該選擇中的每一行都會調用該功能。由於您的視覺選擇包含5行Preserve()函數您傳遞給它的命令被稱爲5次。

解決方法很簡單,在range參數添加到函數定義:

function! Preserve() range 

這樣的說法,該功能被稱爲只有一次,你可以讓它或底層命令處理的可視範圍本身。

請參閱:help func-range

另一種 - 稍有髒 - 解決辦法是修改您的映射,這樣它被稱爲只有一次調用該函數之前刪除範圍:

map <key> :<C-u>call Function(args)<CR> 

:help c_ctrl-u