한 레지스터에서 임의의 수의 레지스터로 텍스트를 어떻게 이동할 수 있습니까?


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)^Aregister에 저장된 증가 함수를 사용하여 이것을 수행하는 매크로가 "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

마지막 줄이 2 씩 증가하여 현재 줄의 사본 5 개를 만들려면

: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 문제 qustions에 많은 문제 중 하나입니다. 가장 선의적인 답변은 귀하의 질문에 대한 고품질의 직접 답변이지만 실제 문제와 관련하여 궁극적으로 쓸모없는 반면, 저의 덜 답변 된 답변은 근본적인 문제에 대한 실제 해결책입니다. 두 가지 대답은 모두 맞지만 다른 질문에 대답하면 결정하기가 어렵습니다. 그것이 저라면, 핵심 문제를 해결하는 대답을 받아 들일 것입니다… 그러나 그것은 바로 저입니다.
romainl

6

사용 getreg하여setreg

q레지스터 에서 복사하려면 15:

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레지스터 에서 복사하려면 15:

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 2019

@ jamessan 좋은 제안, 감사합니다. 이것들을 올바르게 사용하고 있습니까?
wchargin

선택적인 두 번째 인수를 getreg ()에 추가하도록 편집했습니다. 레지스터의 가능한 평가가 아닌 레지스터의 내용을 반환하기 때문입니다.
jamessan

1

한 레지스터의 내용을 다른 레지스터에 빠르고 쉽게 복사하려면 질문에 직접 대답하기 위해 다음을 .vimrc에 넣을 수 있습니다. 그런 다음 <leader>rcabregister의 내용을 register 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

아 맞아. 결정된.
Steve Vermeulen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.