在有褶皱的情况下猛拉

时间:2019-05-01 17:43:18

标签: vim

我设置了relativenumber,并且我的折叠方法是缩进的。考虑以下mwe:

I want to copy this
    This is indented
    Just like this
now copy

带有褶皱,这就像

I want to copy this
+-- 2 lines bla bla    
now copy

如果我在最后一行,则relativenumber将显示类似

  2 I want to copy this
  1 +-- 2 lines bla bla    
4   now copy

我想删除当前行之前 2行的行,因为relativenumber告诉我。 所以我

:.-2y

但这实际上将拉动整个折叠的块。

Q :是否有办法在不需要执行任何怪异算法的情况下仍然吸引我需要的行?

*算术应为

(Actual number) = (Relative number) + (Number of folded lines) - (Number of folds),

这对于速度来说是不切实际的

1 个答案:

答案 0 :(得分:2)

据我所知,无法更改yank命令的行为以使其按您希望的方式工作,因为“。+ x”的值在到达命令本身之前已经展开,并且我不知道有什么方法可以改变这种行为。

但是,只需一点点脚本,就可以解决此问题。我写了几个vim函数,可以让您运行想要执行的确切逻辑。

此代码段将允许您以相对于当前位置的相对范围运行yank命令,并且该命令将按您希望的方式运行:

" This file is created to handle the case in which the y ex command behaves
" different than expected when it is run with relative line number.
" Those functions behaves a bit different than the behavior of the y command,
" the y command gets the argument as range before it, with a range relative or
" absolute. The functions in this module gets a relative range from the current
" line (they can get a negative range as well).
" Those functions have commands at the bottom of the script, they should be used
" to run the function (and can be re-mapped to different values, for shorter
" typing).

" Yank a single line, getting only the line you want to yank. The value of the
" line should be relative to the current line.
function! s:YankByEnd(end_line)
    " Save the current location, to know where to return to.
    let current_line = line('.')

    " Copy the wanted line.
    if a:end_line > 0
        execute 'normal ' . string(a:end_line) . 'jyy'
    elseif a:end_line < 0
        let move_by = a:end_line * -1
        execute 'normal ' . string(move_by) . 'kyy'
    else
        execute 'normal yy'
    endif

    " Return to the original location.
    execute 'normal ' . current_line . 'gg'
endfunction

" Yank a range of lines, getting the lines you want to yank. The value of the
" lines should be relative to the current line.
function! s:YankByStartAndEnd(start_line, end_line)
    " Save the current location, to know where to return to.
    let current_line = line('.')

    " Get the start line.
    if a:start_line > 0
        execute 'normal ' . string(a:start_line) . 'j'
    elseif a:start_line < 0
        let move_by = a:start_line * -1
        execute 'normal ' . string(move_by) . 'k'
    endif
    let start_line = line('.')
    execute 'normal ' . current_line . 'gg'

    " Get the end line.
    if a:end_line > 0
        execute 'normal ' . string(a:end_line) . 'j'
    elseif a:end_line < 0
        let move_by = a:end_line * -1
        execute 'normal ' . string(move_by) . 'k'
    endif
    let end_line = line('.')
    execute 'normal ' . current_line . 'gg'

    " Copy the lines
    execute start_line . "," end_line . "yank"

    " Return to the original location.
    execute 'normal ' . current_line . 'gg'
endfunction

command! -nargs=1 YankSingleLine call <SID>YankByEnd(<f-args>)
command! -nargs=* YankMultipleLines call <SID>YankByStartAndEnd(<f-args>)

如果您将添加此文件并为其提供源文件(或将其直接添加到vimrc中),则可以根据需要运行命令。 例如,要运行您想在原始示例中运行的命令,只需运行以下命令:

:YankSingleLine -2

想要的行将被拉动。

我也有一个脚本,可以执行相同的操作,但是它更通用,可以运行更多命令,而不仅仅是特定的yank命令。 这是脚本:

" This file is created to handle the case in which an ex command behaves
" different than expected when it is run with relative line number and folds.
" Those functions behaves a bit different than the behavior of the regular ex
" command.
" A regular ex command gets the argument as range before it, with a range 
" relative or absolute. The functions in this module gets a relative range 
" from the current line (they can get a negative range as well) and the command 
" to run.

" Run an ex command on a single line. The value of the line should be relative 
" to the current line.
function! RunByEnd(end_line, command)
    " Save the current location, to know where to return to.
    let current_line = line('.')

    " Get the line to run the command on.
    if a:end_line > 0
        execute 'normal ' . string(a:end_line) . 'j'
    elseif a:end_line < 0
        let move_by = a:end_line * -1
        execute 'normal ' . string(move_by) . 'k'
    endif
    let end_line = line(".")

    " Get back to the original location.
    execute 'normal ' . current_line . 'gg'

    " Run the command.
    execute end_line . a:command
endfunction

" Run an ex command on a range of lines. The value of the lines should be 
" relative to the current line.
function! RunByStartAndEnd(start_line, end_line, command)
    " Save the current location, to know where to return to.
    let current_line = line('.')

    " Get the start line.
    if a:start_line > 0
        execute 'normal ' . string(a:start_line) . 'j'
    elseif a:start_line < 0
        let move_by = a:start_line * -1
        execute 'normal ' . string(move_by) . 'k'
    endif
    let start_line = line('.')
    execute 'normal ' . current_line . 'gg'

    " Get the end line.
    if a:end_line > 0
        execute 'normal ' . string(a:end_line) . 'j'
    elseif a:end_line < 0
        let move_by = a:end_line * -1
        execute 'normal ' . string(move_by) . 'k'
    endif
    let end_line = line('.')

    " Return to the original location.
    execute 'normal ' . current_line . 'gg'

    " Run the given command.
    execute start_line . "," end_line . a:command
endfunction

使用它,您将能够运行所需的任何命令,但是您需要添加要运行的原始命令。

要使用此脚本解决您的问题,可以运行以下命令:

:致电RunByEnd(-2,“ y”)