當您在vim中使用{和}進行段落導航時,它會跳過只包含空白但不包含空格的行,儘管它們本來是'空白'的。使{和}忽略僅包含空格的行
我該如何說服vim將段落中的「僅限空白」行用作分段符,這樣{和}會跳轉到它們?
當您在vim中使用{和}進行段落導航時,它會跳過只包含空白但不包含空格的行,儘管它們本來是'空白'的。使{和}忽略僅包含空格的行
我該如何說服vim將段落中的「僅限空白」行用作分段符,這樣{和}會跳轉到它們?
{和}命令可以移動的「段落」,和vim的文檔(見:help paragraph
)說:
注意,一個空行(僅 含空格)不是 段落邊界。
所以你可以做到這一點的唯一方法是重新映射{和}。 喜歡的東西:
nmap { ?^\\s*$<CR>
nmap } /^\\s*$<CR>
可以工作,但你可能要調整此所以它不會改變你的搜索歷史。
我從來沒有爲空白合法只需要線,使我解決這個「問題」,加入以下到我的.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
所以這時如果{和}跳過空白專用線我使用我的映射將其刪除並重試。
這是困擾我很長一段時間的事情。可能「正確」的解決方案是向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}'等似乎工作正常。如果有人有計算工作或修復視覺模式的想法,請告訴我。
補丁的想法是我聽過/讀過的最好的解決方案。 – rossipedia
下面是修改後的版本正確處理數:
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>
在視覺模式下無法使用這些行未註釋:( –
正如前面所說的,如果你運行:help paragraph
你會看到,有空白行不作爲邊界處理。
在平均時間有兩個插件項目,可以幫助:基於其他答案代碼
如果您使用的病原菌,只需從上述站點之一下載。
如果使用Vundle,把你的.vimrc
下列之一:
改進款運動:
Bundle 'vim-scripts/Improved-paragraph-motion'
Vim的段落運動:
Bundle 'dbakker/vim-paragraph-motion'
在重新啓動後運行:BundleInstall
,並且{
}
運動應停止在包含空白字符的行上。
這是一個體面的開始,但有一些問題......立即想到的那些:視覺模式,破壞搜索歷史,正確地設置/重置「hlsearch」,光標閃爍時輕微閃爍命令欄(小調,是的,但仍然很煩人)。 –
無論如何,我認爲這是一個很好的解決方案......而且,如果沒有別的東西出現,它可能是唯一的解決方案(在這種情況下,一些Vim腳本可能會使問題變得更加痛苦)。 –