Дергать при наличии складок - PullRequest
2 голосов
/ 01 мая 2019

У меня установлено относительное число, и мой метод сгибания имеет отступ.Рассмотрим следующее 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

Если я на последней строке, относительный номер покажет что-то вроде

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

и я хочу вернуть строку, которая 2 строки до текущей строки, как мне говорит относительный номер.Так что я делаю

:.-2y

Но это фактически выдернет весь сложенный блок.

Q : есть ли способ все еще дергать нужные мне строки, не имеяделать какие-то странные арифметические операции *?

* Арифметические действия должны быть

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

Это очень непрактично для скорости

1 Ответ

2 голосов
/ 03 мая 2019

Насколько я знаю, нет способа изменить поведение команды yank, чтобы она работала так, как вы хотите, чтобы она работала, поскольку значения ". + X" раскрываются до того, как они попадают в саму команду, иЯ не знаю ни одного способа изменить поведение этого.

Но, с небольшим vimscript, эта проблема разрешима.Я написал пару функций 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")

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...