如何将文本从一个寄存器移动到任意数量的寄存器?


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存储在register中"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);

其中,在寄存器中的宏"byypW^At)^A^A

我想要一个寄存器来执行此操作,但是对于从1-5开始的每个增量。"a可以(以某种方式)将该寄存器复制到寄存器b到e。然后,我将每个寄存器粘贴到缓冲区中,进行所需的修改(添加更多项,更改跟随t运动的字符等),然后将修改后的表达式重新拉回到寄存器中。理想情况下,该最后一步甚至可以包含在复制寄存器的命令中

这使我不必重复宏中不需要更改的所有字符。以我的示例为例,这可能是微不足道的,但我可以预见,在某些时候做我想做的事情可能会很有帮助。


5
顺便说一句,我不建议使用编号寄存器。唯一的“安全”寄存器是字母寄存器。Vim自动设置所有其他寄存器。
jamessan 2015年

Answers:


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 2015年

@WChargin,请解释。
romainl 2015年

如,或许我想做一个字符串的循环副本什么的,所以,如果abcde@q的话,我想@x="bcdea"@y="abcde"@z="eabcd"。我可能首先让@x@y@z全部等于@q,然后根据需要对其进行修改。显然,我只是弥补了这一点,但似乎在某些情况下,类似的事情可能有用。
wchargin 2015年

2
@Kit,我有点担心您的问题中没有实际的例子,这立即使它闻起来像XY。我几乎可以肯定您正在滥用寄存器,所以我很想阅读您要尝试做的解释。
romainl 2015年

1
@Kit,这是XY问题解决方案的众多问题之一。最受好评的答案是对您问题的高质量直接答案,但最终在您的实际问题中无用,而我最受好评的答案是针对您的基本问题的实际解决方案。两种答案都是正确的,但它们回答的问题不同,这使您难以决定。如果是我,我会接受能解决我的核心问题的答案……但这就是我。
romainl 2015年

6

使用getregsetreg

要复制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 2015年

@jamessan好的建议,谢谢—我是否正确使用了这些?
wchargin 2015年

我已经对其进行了编辑,以将可选的第二个参数添加到getreg(),因为这将返回寄存器的内容,而不是对其进行可能的评估。
jamessan 2015年

1

要直接回答该问题,如果您想快速轻松地将一个寄存器的内容复制到另一个寄存器,可以将以下内容放入.vimrc中。然后,您可以执行<leader>rcab将register的内容复制a到register 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 2015年

是的,是的。固定。
Steve Vermeulen'2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.