【问题标题】:VIM: How to move cursor down to last line of text in a block without changing column?VIM:如何在不更改列的情况下将光标向下移动到块中的最后一行文本?
【发布时间】:2019-11-25 19:49:34
【问题描述】:

通常我想以相同的方式编辑文本块中的每一行,所以我会输入

<C-V>}

这实现了选择整个块,但不幸的是超过了块的最后一行并改变了光标位置。因此,我必须按 k ,然后按顺序更正光标位置。通常我发现在我到达最后一行之前按j 会更容易。有没有更简单的方法来实现这一点?

示例:我想更改以下内容

std::cerr << "abc::blah " << std::endl;
std::cerr << "def::text " << std::endl;
std::cerr << "ggg::something " << std::endl;
std::cerr << "xyz::else " << std::endl;
std::cerr << "qrs::random " << std::endl;

到:

std::cerr << "Foo::blah " << std::endl;
std::cerr << "Foo::text " << std::endl;
std::cerr << "Foo::something " << std::endl;
std::cerr << "Foo::else " << std::endl;
std::cerr << "Foo::random " << std::endl;

所以我发现自己将光标放在第一行的第一个 a 上,然后输入&lt;C-V&gt;jjjjecFoo&lt;ESC&gt;

有没有办法将光标向下移动到块的末尾而不经过它或更改列,即相当于按 j 直到块的最后一行?

【问题讨论】:

  • 插件github.com/vim-utils/vim-vertical-move 似乎可以满足您的需求(虽然我没有亲自尝试过)。不幸的是,现在想不出没有插件的方法(不使用/计算行号,这几乎是您的解决方案,但使用 4j 而不是 jjjj)。
  • 是的,这看起来就是我要找的东西!

标签: vim


【解决方案1】:

据我所知,没有内置任何东西,但你可以定义一个自定义映射(g} 似乎合适),如this answer on vi.stackexchange.com 所示:

vnoremap <silent> g} :<C-U>call cursor(line("'}")-1,col("'>"))<CR>`<1v``

我发现的唯一问题是当段落的最后一行也是缓冲区的最后一行时它不起作用,但是额外的j 将修复选择。

【讨论】:

  • it doesn't work when the last line of the paragraph is also the last line of the buffer 正如我在回答中提到的那样,要解决这种情况,需要::&lt;C-U&gt;call cursor(line("'}")-empty(getline(line("'}"))),col("'&gt;"))&lt;CR&gt;
【解决方案2】:

您可以定义一个自定义:help :map-operator,它只使用移动的行号,但保留当前列:

"<Leader>gl{motion} Jump to the line at the end of {motion}; keep the
"           current column.
function! s:SetCursor( lnum, virtcol )
    call cursor(a:lnum, 0)
    execute 'normal!' a:virtcol . '|'
endfunction
function! OnlyLineJumpOperator( type ) abort
    call s:SetCursor(line("']"), virtcol('.'))
endfunction
function! OnlyLineJumpVisual( type ) abort
    normal! gv
    call OnlyLineJumpOperator(a:type)
endfunction
function! s:OnlyOneCoordinateJumpExpression( what, mode ) abort
    let &opfunc = printf('Only%sJump%s', a:what, a:mode)
    return (a:mode ==# 'Visual' ? "\<C-\>\<C-n>" : '') . 'g@'
endfunction
nnoremap <expr> <Leader>gl     <SID>OnlyOneCoordinateJumpExpression('Line', 'Operator')
xnoremap <expr> <Leader>gl     <SID>OnlyOneCoordinateJumpExpression('Line', 'Visual')

这样,您的用例将变为&lt;C-v&gt;&lt;Leader&gt;gl}ecFoo&lt;Esc&gt;

奖金

为了完整起见,您还可以添加相反的映射(保留行并仅更改列):

"<Leader>g|{motion} Jump to the column at the end of {motion}; keep the
"           current line.
function! OnlyColumnJumpOperator( type ) abort
    execute 'normal!' virtcol("']") . '|'
endfunction
function! OnlyColumnJumpVisual( type ) abort
    normal! gv
    call OnlyColumnJumpOperator(a:type)
endfunction
nnoremap <expr> <Leader>g<Bar> <SID>OnlyOneCoordinateJumpExpression('Column', 'Operator')
xnoremap <expr> <Leader>g<Bar> <SID>OnlyOneCoordinateJumpExpression('Column', 'Visual')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-16
    • 1970-01-01
    相关资源
    最近更新 更多