“점 연산자”로 매크로를 반복 할 수 있습니까?


15

.명령 으로 매크로를 반복 할 수 있습니까 ? 예를 들어 다음과 같이 입력하고 싶습니다.

@q...

효과적으로 @q4 번 전화하십시오 . 기본 동작을 사용하면 'q'에 단일 명령 (예 dw: x, 또는) 이있는 경우에만 작동합니다 iHello<esc>. ( '.' 은 마지막 키 스트로크 / 명령이 아닌 마지막 변경을 반복하기 때문에 의미가 있습니다. )

나는 또한이 작업을 카운트로하고 싶습니다. 예를 들어, 다음을 입력하십시오.

3@q.

실제로 @q6 번 달리는 것과 같습니다 . 이 동작을 어떻게 구성 할 수 있습니까?


1
정확히 당신이 요구하는 것은 아니지만 아마도 github.com/wincent/replay 도움이 될 것 입니다 . 이것은 마지막으로 기록 된 매크로를 기록하고 눌러서 누르면 재생됩니다.Enter
grodzik

참고로, @@마지막 매크로를 반복하므로 매핑을 위해 이것을 요청하는 경우 효과가 있습니다.
Shahbaz 2016 년

답변:


7

이것을 시도하십시오. 이후 @g@(더미 모션과 함께 l) 사용 되도록 다시 매핑 하여 마지막 연산자가되고로 반복합니다 ..

" When . repeats g@, repeat the last macro.
fun! AtRepeat(_)
    " If no count is supplied use the one saved in s:atcount.
    " Otherwise save the new count in s:atcount, so it will be
    " applied to repeats.
    let s:atcount = v:count ? v:count : s:atcount
    " feedkeys() rather than :normal allows finishing in Insert
    " mode, should the macro do that. @@ is remapped, so 'opfunc'
    " will be correct, even if the macro changes it.
    call feedkeys(s:atcount.'@@')
endfun

fun! AtSetRepeat(_)
    set opfunc=AtRepeat
endfun

" Called by g@ being invoked directly for the first time. Sets
" 'opfunc' ready for repeats with . by calling AtSetRepeat().
fun! AtInit()
    " Make sure setting 'opfunc' happens here, after initial playback
    " of the macro recording, in case 'opfunc' is set there.
    set opfunc=AtSetRepeat
    return 'g@l'
endfun

" Enable calling a function within the mapping for @
nno <expr> <plug>@init AtInit()
" A macro could, albeit unusually, end in Insert mode.
ino <expr> <plug>@init "\<c-o>".AtInit()

fun! AtReg()
    let s:atcount = v:count1
    let c = nr2char(getchar())
    return '@'.c."\<plug>@init"
endfun

nmap <expr> @ AtReg()

내가 생각할 수있는 많은 코너 케이스를 처리하려고했습니다. 당신은 반복 할 수 있습니다 @:.. 이후에을 (를) 누를 때 까지 카운트 @또는 .유지됩니다 ..

이것은 까다 롭고, 무언가가 도중에 깨지지 않을 것이라고 확신하지 않습니다. 따라서 이에 대한 보증, 보증 또는 약속은 없습니다.

개인적으로, 나는 .마지막 변화 에 대한 세분화 된 반복 과 매크로의 반복 사이에 차이가있는 것이 좋습니다 @@.

편집하다

나는 지금까지 갔을 .때 매크로를 기록한 후 즉시 눌러 재생할 수있는 코드를 추가 할 수 있다고 생각 했습니다.

fun! QRepeat(_)
    call feedkeys('@'.s:qreg)
endfun

fun! QSetRepeat(_)
    set opfunc=QRepeat
endfun

fun! QStop()
    set opfunc=QSetRepeat
    return 'g@l'
endfun

nno <expr> <plug>qstop QStop()
ino <expr> <plug>qstop "\<c-o>".QStop()

let s:qrec = 0
fun! QStart()
    if s:qrec == 1
        let s:qrec = 0
        return "q\<plug>qstop"
    endif
    let s:qreg = nr2char(getchar())
    if s:qreg =~# '[0-9a-zA-Z"]'
        let s:qrec = 1
    endif
    return 'q'.s:qreg
endfun

nmap <expr> q QStart()

환상적입니다! 이 질문을 게시 한 후 워크 플로우가 변경되었으므로 더 이상 점이있는 매크로를 반복 할 수는 없습니다. 그러나 이것은 실제로 잘 작동하므로 어쨌든 그것을 받아 들일 것입니다 (아마도 그것을 추가하지 않을 것입니다 .vimrc)
James

걱정하지 않고 재미있는 문제!
Antony

1
편집 : .녹화 후 바로 매크로를 재생할 수 있습니다.
Antony

내가 생각 \<plug>qstop하기 전에해야 qQStart 기능에
스티브 베르 메울 렌에게

6

마지막 매크로를 사용할 수있는 반복하기 @@때문에 3@@기본적으로 3 번 @q 실행하는 것입니다. 그러나 @ 키 입력은 다루기 어려울 수 있으므로 내 .vimrc에는 다음 줄이 있습니다.

  "- Lazy macro repeat
  nmap <leader>m @@

이를 통해 리더 키 (,)와 m을 사용하여 마지막 매크로를 실행할 수 있습니다. 그런 다음 숫자를 앞에 붙여 매크로를 반복 할 수 있습니다.

이제는 3,m에 해당 3@@합니다. 동일한 총 키로 Shift 키를 누를 필요가 없습니다.

편집 : 이것을 다시 생각하면 새로운 매크로가 나타났습니다. nmap <leader>. @@ 이것은 또한 앞에 숫자가있을 때 작동하므로 3,.이제는 3@@이 작업을보고 싶습니다. 그래서 매크로 문자를 전달하고 마지막 매크로 대신 매크로를 반복 할 수 있습니다.


OP는 6 번 3@q.실행 하려고 합니다 @q. 그렇지 않습니다.
41805

귀하의 질문을 다시 읽고 이것이 확실하지 않습니다. 언제 사용 3@q.하는지 예를 들어 주 시겠습니까? 카운트 앞에 붙일 수도 있습니다. 매크로를 시작하기 전에 검색을 설정 한 다음 매크로를 사용 n하여 재생할 수있는 시작 부분으로 이동하는 경향이 있습니다.
Shadoath

5

다른 매크로에서 매크로 사용을 기록하고 반복 할 수 있습니다.

qqdwq
qr2@qq

이제 6 번 3@r달리는 것과 같습니다 @q.


1

spacevim에서 기본적 으로 "오른쪽 1 문자 이동"은 이미 포함되어 l있으므로 q 버퍼에서 매크로를 다시 실행할 공간을 다시 매핑했습니다.

noremap <Space> @q

사용하려면 qq먼저 매크로 q를 기록한 다음 기록을 중지 한 다음 space을 눌러 재생하십시오.


참고로, (필수 키는 아님) 많은 사람들이 공간을 리더 키로 사용하므로 많은 사람들이 자유롭게 생각할 수는 없습니다. :)
B 레이어

0

사용 ,하기 쉽고 간단한 입력하기 쉬운 솔루션을 좋아하기 때문에 이것은 저에게 효과적입니다.

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