Как можно перенести текст из одного регистра в произвольное количество регистров?

10

Есть ли способ «передать» текст из регистра в другой регистр или набор регистров? Например, перейти "qк регистрам "1через "5.

Я часто хочу создать несколько разные версии одного и того же макроса, поэтому полезно иметь возможность скопировать макрос «шаблона» в несколько регистров, а затем изменить каждый из них на месте.

Чтобы привести практический пример, вот проблема, которая вызвала этот вопрос для меня.

Мне нужно превратить следующую строку из языка описания оборудования во множество повторяющихся блоков,

RAM64(in=in, load=load0, address=address[0..5], out=out1);

в

RAM64(in=in, load=load1, address=address[0..5], out=out2);
RAM64(in=in, load=load2, address=address[0..5], out=out3);
RAM64(in=in, load=load3, address=address[0..5], out=out4);
RAM64(in=in, load=load4, address=address[0..5], out=out5);

У меня есть макрос, который выполняет это, используя функцию приращения, yypW^At)^Aкоторую я сохранил в регистре "a.

Иногда мне нужно, чтобы шаблон приращения был немного другим, например,

RAM512(in=in, load=load1, address=address[0..8], out=out2);
RAM512(in=in, load=load2, address=address[0..8], out=out4);
RAM512(in=in, load=load3, address=address[0..8], out=out6);
RAM512(in=in, load=load4, address=address[0..8], out=out8);

где макрос в реестре "bбудет yypW^At)^A^A.

Я хочу, чтобы регистр сделал это, но для каждого приращения от 1-5. Регистр "aможно было (как-то) скопировать в регистры с b по e. Затем я вставлял каждый регистр в буфер, вносил необходимые изменения (добавлял больше терминов, изменял символ, следующий за tдвижением и т. Д.) И возвращал измененное выражение обратно в регистр. В идеале этот последний шаг может быть даже включен в команду (ы) для копирования регистров

Это избавляет меня от повторения всех символов в макросе, которые НЕ требуют изменения. Для моего примера это может быть тривиально, но я могу предвидеть времена, когда было бы очень полезно сделать то, что я прошу.

Комплект
источник
5
Кроме того, я не рекомендовал бы использовать пронумерованные регистры. Единственными «безопасными» регистрами являются буквенные регистры. Все остальные регистры автоматически устанавливаются Vim.
jamessan

Ответы:

7

Макросы - это просто текст.

Откройте новый пустой буфер и поместите туда свой макрос. Вы можете дублировать строки, изменить одну вещь здесь и что-то еще в другом месте, затем восстановить строку и сразу же использовать ее @".

Нет необходимости загрязнять ваши регистры, особенно регистры номеров, которые служат совершенно другой цели.

-- редактировать --

Теперь ваш вопрос легче понять, когда вы добавили какое-то объяснение.

Оказывается, вам нужно только изменить исходную запись, чтобы достичь цели, не играя с регистрами, как если бы они были переменными:

:let i = 1                     " define variable i
qa                             " start recording in register a
yy                             " yank the line
p                              " paste it
W                              " move to next WORD
<C-v><C-a>                     " increment number
t)                             " jump to the other number to increment
:norm <C-r>=i<CR><C-v><C-a>    " increment the number by i
q                              " stop recording

Чтобы создать 5 копий текущей строки с последним увеличением числа на 2:

:let i = 2|norm 5@a

или 12 копий с последним увеличением числа на 23:

:let i = 23|norm 12@a
romainl
источник
Договорились о числовых регистрах - но что, если вы хотите использовать это в команде, и вам нужны регистры, которые начинаются одинаково, но становятся другими?
wchargin
@WChargin, пожалуйста, объясни.
romainl
Как и в, возможно , я хочу сделать что - то с повернутыми копиями строки, так что если abcdeв @q, то я хочу @x="bcdea", @y="abcde"и @z="eabcd". Я мог бы начать с разрешения @x, @yи @zвсе равны, @qа затем изменить их по мере необходимости. Очевидно, что я только что сделал это, но кажется , что там может быть некоторые случаи , когда что - то подобное может быть полезным.
wchargin
2
@Kit, я немного обеспокоен отсутствием практического примера в твоем вопросе, который сразу же пахнет как XY. Я почти уверен, что вы неправильно используете регистры, поэтому я хотел бы прочитать объяснение того, что вы пытаетесь сделать.
romainl
1
@Kit, это одна из многих проблем с XY. Наиболее одобренный ответ - это высококачественный прямой ответ на ваш вопрос, но в конечном счете бесполезный в контексте вашей реальной проблемы, в то время как мой менее одобренный ответ - это реальное решение вашей основной проблемы. Оба ответа верны, но они отвечают на разные вопросы, что затрудняет решение. Если бы это был я, я бы принял ответ, который касается моей основной проблемы ... но это только я.
Ромен
6

Использование getregиsetreg

Копировать из qв регистры 1- 5:

let src=getreg('q', 1)
for i in range(1, 5)
    call setreg(i, src)
endfor

Чтобы скопировать в более общий список:

let src=getreg('q', 1)
for i in ['a', 'c', 'e']
    call setreg(i, src)
endfor

С помощью execute

Копировать из qв регистры 1- 5:

for i in range(1, 5)
   execute 'let @' . i . '=@a'
endfor

Чтобы скопировать в более общий список:

for i in ['a', 'c', 'e']
    execute 'let @' . i . '=@a'
endfor

Объяснение. Команду letможно использовать как let @x=@y, которая копирует регистр yдля регистрации x. По сути, мы просто строим эти команды в цикле (изменяя значение xв приведенной выше форме) и executeвводим их.

wchargin
источник
1
Там нет необходимости использовать :exeздесь. Функции getreg()и setreg()были бы чище.
Jamessan
@jamessan Хорошее предложение, спасибо - правильно ли я их использую?
wchargin
Я отредактировал его, добавив необязательный второй аргумент в getreg (), поскольку он возвращает содержимое регистра, а не возможную оценку его.
Jamessan
1

Чтобы напрямую ответить на вопрос, если вы хотите быстро и легко скопировать содержимое одного регистра в другой, вы можете поместить следующее в ваш .vimrc. Затем вы можете выполнить <leader>rcabкопирование содержимого регистра aдля регистрации b. В качестве примера я выбрал <leader>rc«регистрационную копию»

function! s:CopyRegister()
    let sourceReg = nr2char(getchar())

    if sourceReg !~# '\v^[a-z0-9]'
        echo "Invalid register given: " . sourceReg
        return
    endif

    let destinationReg = nr2char(getchar())

    if destinationReg !~# '\v^[a-z0-9]'
        echo "Invalid register given: " . destinationReg
        return
    endif

    call setreg(destinationReg, getreg(sourceReg, 1))
    echo "Replaced register '". destinationReg ."' with contents of register '". sourceReg ."'"
endfunction

" rc = register copy
nnoremap <leader>rc :call <sid>CopyRegister()<cr>
Стив Вермейлен
источник
1
Я бы порекомендовал getreg(sourceReg, 1).
jamessan
Ах да, правда. Исправлена.
Стив Вермейлен