Могу ли я повторить макрос с «оператором точки»?

15

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

@q...

и это эффективно звонить @q4 раза. С поведением по умолчанию, это работает только тогда , когда «д» имеет одну команду, например dw, xили iHello<esc>. (Это имеет смысл, поскольку «.» Повторяет последнее изменение , а не последние нажатия клавиш / команду)

Я также хотел бы иметь эту работу с подсчетами. Например, набрав:

3@q.

будет эффективно так же, как работает @q6 раз. Как я могу настроить это поведение?

Джеймс
источник
1
Не совсем то, что вы просите, но, возможно, это будет полезно github.com/wincent/replay . Эта запись записывает последний макрос и воспроизводит его при нажатииEnter
grodzik
К вашему сведению, @@повторяет последний макрос, поэтому, если вы спрашиваете это ради отображений и тому подобного, он должен работать для вас.
Шахбаз

Ответы:

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()
Antony
источник
Это работает фантастически! После публикации этого вопроса мой рабочий процесс изменился, поэтому я не хочу больше повторять макросы с точкой. Тем не менее, это работает очень хорошо, так что я все равно приму это (хотя я, вероятно, не добавлю это к своему .vimrc)
Джеймс
Не беспокойтесь, интересная проблема, независимо!
Энтони
1
Редактировать: разрешить воспроизведение макроса .сразу после записи.
Энтони
Я думаю, что \<plug>qstopдолжно быть раньше qв функции QStart
Стив Vermeulen
6

Для повторения вашего последнего макроса вы можете использовать, @@так 3@@что, по сути, запускается @q 3 раза Однако @ нажатия клавиш могут быть громоздкими, поэтому в моем .vimrc у меня есть строки:

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

Это позволяет мне использовать свой лидерный ключ (,) плюс m для запуска последнего макроса. Затем вам может предшествовать это число, чтобы повторить макрос.

Теперь 3,mэквивалентно 3@@. Та же сумма ключей и нет необходимости удерживать Shift.

РЕДАКТИРОВАТЬ : После переосмысления этого я придумал новый макрос. nmap <leader>. @@ Это также работает, когда ему предшествует число, так 3,.что теперь 3@@хотелось бы увидеть эту работу, чтобы я мог передать макрос буквы и повторить этот макрос вместо последнего макроса.

Shadoath
источник
ОП хочет 3@q.запустить @q6 раз. Это не делает этого.
user41805
Перечитывая твой вопрос, я не уверен, что это отвечает на него. Можете ли вы привести пример, когда вы будете использовать 3@q.? Казалось бы, вы могли бы просто добавить его с подсчетом. Я склонен устанавливать поиск перед началом макроса, а затем использовать nв макросе, чтобы перейти к началу, где он может быть воспроизведен.
17
5

Вы можете записать использование макроса в другом макросе и повторить это.

qqdwq
qr2@qq

Теперь все 3@rравно что бегать @qшесть раз.

jjaderberg
источник
1

По умолчанию spaceв vim указано «переместить правый 1 символ», который уже покрыт l, поэтому я переназначил пространство для повторного запуска макроса из буфера q:

noremap <Space> @q

Чтобы использовать, просто qqсначала запишите макрос , остановите запись, qа затем нажмите, spaceчтобы воспроизвести.

brain_bacon
источник
К вашему сведению, по той причине, что вы заявляете (это не обязательный ключ), многие люди используют пространство в качестве ключа лидера, так что может быть не так много людей с ним свободным, как вы думаете. :)
B Layer
0

Поскольку я не использую ,и не люблю простое решение для ввода, это работает для меня:

:map , @@
Нил МакГилл
источник