使{和}忽略仅包含空格的行

时间:2009-12-05 18:37:18

标签: vim

当您使用{和}在vim中按段落导航时,它会跳过除空格之外什么都没有的行,尽管它们是“空白”。

我怎样才能说服vim将“仅限空白”行视为分节符,以便{和}跳转到它们?

5 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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}'等似乎工作正常。如果有人有计数工作或修复视觉模式的想法,请告诉我。

答案 2 :(得分:2)

如前所述,如果你运行:help paragraph,你会看到带有空格的行不被视为边界。

与此同时,有两个插件项目可以提供帮助:

如果您使用Pathogen,只需从上述其中一个网站下载。

如果您使用Vundle,请在.vimrc

中添加以下内容之一
  • 改进段落动作:

    Bundle 'vim-scripts/Improved-paragraph-motion'
    
  • Vim Paragraph Motion:

    Bundle 'dbakker/vim-paragraph-motion'
    

重启后运行:BundleInstall{ }动作应停在包含空白字符的行上。

答案 3 :(得分:1)

{和}命令按“段落”移动,vim的文档(参见:help paragraph)说:

  

请注意一个空白行(仅限   包含空格)不是   段落边界。

所以你能做到这一点的唯一方法就是重新映射{和}。 类似的东西:

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

可行,但您可能需要调整此值,以免改变搜索记录。

答案 4 :(得分: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

那么如果 {} 只跳过空白行,我会使用我的映射将其删除并重试。