Як можна перемістити текст з одного реєстру до довільної кількості регістрів?


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

Домовилися про числові регістри - але що робити, якщо ви хочете використовувати це в команді, і вам потрібні регістри, які починаються однаково, але стають іншими?
wchargin

@WChargin, будь ласка, поясніть.
romainl

Як і в, можливо , я хочу зробити що - то з поверненими копіями рядки, так що якщо abcdeв @q, то я хочу @x="bcdea", @y="abcde"і @z="eabcd". Я можу почати з дозволу @x, @yі @zвсі рівні @qта потім змінивши їх за потребою. Очевидно, що я тільки що зробив це, але здається , що там може бути деякі випадки , коли що - щось подібне може бути корисним.
wchargin

2
@Kit, мене трохи турбує відсутність практичного прикладу у вашому питанні, що негайно сприймає запах як XY. Я майже впевнений, що ви неправильно використовуєте регістри, тому я хотів би прочитати пояснення того, що ви намагаєтесь зробити.
romainl

1
@Kit, це одна з багатьох проблем з питаннями XY проблеми. Відповідь, яка найбільше відповідає, - це якісна пряма відповідь на ваше запитання, але в кінцевому рахунку марна в контексті вашої реальної проблеми, тоді як моя менш обґрунтована відповідь - це фактичне рішення вашої основної проблеми. Обидві відповіді правильні, але вони відповідають на різні запитання, що ускладнює вам рішення. Якби це я, я би прийняв відповідь, яка стосується мого основного питання ... але це тільки я.
romainl

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вкладаємо їх.


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

Ага так, правда. Виправлено.
Стів Вермеулен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.