2009-12-05 30 views
16

當您在vim中使用{和}進行段落導航時,它會跳過只包含空白但不包含空格的行,儘管它們本來是'空白'的。使{和}忽略僅包含空格的行

我該如何說服vim將段落中的「僅限空白」行用作分段符,這樣{和}會跳轉到它們?

回答

1

{和}命令可以移動的「段落」,和vim的文檔(見:help paragraph)說:

注意,一個空行(僅 含空格)不是 段落邊界。

所以你可以做到這一點的唯一方法是重新映射{和}。 喜歡的東西:

nmap { ?^\\s*$<CR> 
nmap } /^\\s*$<CR> 

可以工作,但你可能要調整此所以它不會改變你的搜索歷史。

+0

這是一個體面的開始,但有一些問題......立即想到的那些:視覺模式,破壞搜索歷史,正確地設置/重置「hlsearch」,光標閃爍時輕微閃爍命令欄(小調,是的,但仍然很煩人)。 –

+0

無論如何,我認爲這是一個很好的解決方案......而且,如果沒有別的東西出現,它可能是唯一的解決方案(在這種情況下,一些Vim腳本可能會使問題變得更加痛苦)。 –

0

我從來沒有爲空白合法只需要線,使我解決這個「問題」,加入以下到我的.vimrc

" Highlight spaces at the end of lines. 
highlight link localWhitespaceError Error 
au Syntax * syn match localWhitespaceError /\(\zs\%#\|\s\)\+$/ display 

" Remove end of line white space. 
noremap <Leader>r ma:%s/\s\+$//e<CR>`a 

所以這時如果{}跳過空白專用線我使用我的映射將其刪除並重試。

2

這是困擾我很長一段時間的事情。可能「正確」的解決方案是向vim本身提交一個補丁,這將允許您使用正則表達式自定義段落邊界(如:設置段落,但實際上是有用的)。

在此期間,我做了一個函數和一對夫婦的映射,幾乎做正確的事:

function! ParagraphMove(delta, visual) 
    normal m' 
    normal | 
    if a:visual 
     normal gv 
    endif 

    if a:delta > 0 
     " first whitespace-only line following a non-whitespace character 
     let pos1 = search("\\S", "W") 
     let pos2 = search("^\\s*$", "W") 
     if pos1 == 0 || pos2 == 0 
      let pos = search("\\%$", "W") 
     endif 
    elseif a:delta < 0 
     " first whitespace-only line preceding a non-whitespace character 
     let pos1 = search("\\S", "bW") 
     let pos2 = search("^\\s*$", "bW") 
     if pos1 == 0 || pos2 == 0 
      let pos = search("\\%^", "bW") 
     endif 
    endif 
    normal | 
endfunction 

nnoremap <silent> } :call ParagraphMove(1, 0)<CR> 
onoremap <silent> } :call ParagraphMove(1, 0)<CR> 
" vnoremap <silent> } :call ParagraphMove(1, 1)<CR> 
nnoremap <silent> { :call ParagraphMove(-1, 0)<CR> 
onoremap <silent> { :call ParagraphMove(-1, 0)<CR> 
" vnoremap <silent> { :call ParagraphMove(-1, 1)<CR> 

這並不正確正確處理像「4}」或視覺模式計數(在你的危險中取消註釋vnoremap行),但對於不會破壞當前搜索模式而不閃爍的東西似乎可以。另外,'d}','y}'等似乎工作正常。如果有人有計算工作或修復視覺模式的想法,請告訴我。

+0

補丁的想法是我聽過/讀過的最好的解決方案。 – rossipedia

6

下面是修改後的版本正確處理數:

function! ParagraphMove(delta, visual, count) 
    normal m' 
    normal | 
    if a:visual 
     normal gv 
    endif 

    if a:count == 0 
     let limit = 1 
    else 
     let limit = a:count 
    endif 

    let i = 0 
    while i < limit 
     if a:delta > 0 
      " first whitespace-only line following a non-whitespace character   
      let pos1 = search("\\S", "W") 
      let pos2 = search("^\\s*$", "W") 
      if pos1 == 0 || pos2 == 0 
       let pos = search("\\%$", "W") 
      endif 
     elseif a:delta < 0 
      " first whitespace-only line preceding a non-whitespace character   
      let pos1 = search("\\S", "bW") 
      let pos2 = search("^\\s*$", "bW") 
      if pos1 == 0 || pos2 == 0 
       let pos = search("\\%^", "bW") 
      endif 
     endif 
     let i += 1 
    endwhile 
    normal | 
endfunction 

nnoremap <silent> } :<C-U>call ParagraphMove(1, 0, v:count)<CR> 
onoremap <silent> } :<C-U>call ParagraphMove(1, 0, v:count)<CR> 
" vnoremap <silent> } :<C-U>call ParagraphMove(1, 1)<CR> 
nnoremap <silent> { :<C-U>call ParagraphMove(-1, 0, v:count)<CR> 
onoremap <silent> { :<C-U>call ParagraphMove(-1, 0, v:count)<CR> 
" vnoremap <silent> { :<C-U>call ParagraphMove(-1, 1)<CR> 
+0

在視覺模式下無法使用這些行未註釋:( –

2

正如前面所說的,如果你運行:help paragraph你會看到,有空白行不作爲邊界處理。

在平均時間有兩個插件項目,可以幫助:基於其他答案代碼


如果您使用的病原菌,只需從上述站點之一下載。

如果使用Vundle,把你的.vimrc下列之一:

  • 改進款運動:

    Bundle 'vim-scripts/Improved-paragraph-motion' 
    
  • Vim的段落運動:

    Bundle 'dbakker/vim-paragraph-motion' 
    

在重新啓動後運行:BundleInstall,並且{}運動應停止在包含空白字符的行上。