Как я могу использовать завершение режима вставки в макросе?

11

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

a
b
c
d
e

в это

arezzo
bywords
czars
détente
eyrie

Что у меня так далеко:

  • наведите курсор на букву a
  • начать запись макроса qq
  • a войти в режим вставки
  • <C-x><C-k> - perform dictionary completion on the character before cursor - in this case the lettera`
  • <C-p>выберите последний элемент в списке завершения, который появляется, в моей системе это слово arezzo. (Примечание: я longestвключил в свои 'completeopt'настройки, которые необходимы для <C-p>работы таким образом во время завершения:) 'set completeopt=longest,menuone,preview'.
  • <C-y> принять завершение
  • ^[^[ выход из режима вставки
  • j перейти на следующую строку, готовый сделать ту же операцию на следующей строке
  • q остановить запись

когда я создаю макрос и выполняю шаги вручную, все работает нормально, однако когда я выполняю макрос, я вижу сообщение, вспыхивающее в командной строке, что-то вроде:

сканирование файла словаря

и ничего не происходит, из команд в макросе только jвыполняется, то есть курсор перемещается вниз по линии, но ни одна из команд завершения не выполняется.
Можно ли использовать завершение режима вставки в макросе, и если да, то как я могу это сделать?

the_velour_fog
источник
Я не понимаю ваш <C-p>шаг ... когда я делаю это в моем vim, он просто выдает сообщение back at original- не выбирает последний элемент ... Я дважды использовал клавишу со стрелкой вверх, чтобы выбрать последнее слово (мой случай azures), нажал Enter и тогда Esc+j+q.. тогда он работает довольно хорошо при выполнении макроса
Sundeep
1
@ spasic ах хороший момент, я должен был упомянуть, но я использую set completeopt=longest,menuone,previewего longestвариант, который вызывает <C-p>немедленную вставку. Если я удалю longestиз completeoptстроки, я получу то же поведение, что и вы. Кроме того, да, клавиши со стрелками работали! спасибо (я забыл, что вы можете использовать их для навигации по списку завершения)
the_velour_fog
Возможно, всплывающее меню мешает. Возможно, попробуйте :set completeopt=и a<c-x><c-k><esc>jкак ваш макрос.
Энтони
@Antony Я не уверен, почему <Cp> не работал, но клавиши со стрелками работали.
the_velour_fog

Ответы:

2

РЕДАКТИРОВАТЬ : На самом деле вы после завершения словаря; вам не обязательно нужен режим вставки (режим Ctrl + X), чтобы сделать это. Как вы обнаружили, это делает работу с макросами настоящей болью. Приведенный ниже скрипт можно использовать для завершения словаря без режима вставки, чтобы вы могли легко повторить его внутри макроса.

Добавьте приведенный ниже код в свой .vimrcфайл, закройте и снова откройте все окна vim, чтобы получить новую функцию, а затем запишите себя поочередно, нажимая, <C-k>чтобы выполнить завершение и jперейти к следующей строке. Я добавил проверку для longestопции, и если она отключена, она выбирает случайную запись, используя системное случайное время. Если он находит longestопцию, он вручную ищет самую длинную подходящую запись в словаре и вставляет ее.

Если вам не нравится <C-k>отображение, не стесняйтесь менять его по своему усмотрению. Он должен работать с любым отображением, которое вам нравится.

Кроме того, команда, возвращающая выражение для сопоставления для оценки, добавляет \<esc>символ в конец, чтобы мы автоматически выходили из режима вставки после каждой вставки, и 0cwвпереди, чтобы перейти в режим вставки для начала, и убедитесь, что мы перезаписали все слово. правильно. В зависимости от того, какое именно поведение вы хотите (если ваши слова не bcwнаходятся в начале каждой строки), вы можете использовать вместо этого фактическое начало слова. Однако тогда вы увидите некоторые странности, когда вернетесь к словам, начинающим строку. Вероятно, есть более продвинутая команда, чтобы игнорировать окончание строки и выполнить оба сразу, но я не смог найти ее.

map <expr> <C-k> CompleteDictionary()
fun! CompleteDictionary()
    let cword = expand(“<cword>”)
    let res = []
    for m in readfile(&dictionary)
        if m =~ '^' . cword
            call add(res, m)
        endif
    endfor
    if &completeopt =~ 'longest'
        let max = 0
        let maxindex = 0
        let index = 0
        for item in res
            if strlen(item) > max
                let max = strlen(item)
                let maxindex = index
            endif
            let index = index + 1
        endfor
        return "0cw" . res[maxindex] . "\<esc>"
    else
        return "0cw" . res[system('@echo %RANDOM%') % len(res)] . "\<esc>"
    endif
endfun

Кроме того, не составит труда расширить здесь логику для создания альтернативных отображений (используя, например, параметры функции), которые выполняют любую функцию, которую обеспечивает режим вставки. Я буду рад помочь с любыми такими требованиями и обновить этот скрипт, как у меня есть время.

Тим
источник
Это звучит как правдоподобное объяснение проблемы, но я попробовал оба предложенных вами решения, но ни одно из них не помогло.
Богатое
Ты sleepтоже пробовал команду?
Тим
Да, хотя только с вашим предложенным значением 5 секунд. Вам удалось заставить любое решение работать? Не могли бы вы опубликовать полный список шагов?
Богатое
Я не тот человек, который написал вопрос. Тем не менее, я могу воспроизвести проблему: вы должны добавить длинный , чтобы , completeoptкак описано в комментариях (опять - таки, не мной). редактировать : К сожалению, 'longest'требуется для ctrl-pшага: нет ctrl-y. Тем не менее шаги , описанные в вопрос-Аскер работы для меня в vim -Nu NONEс completeoptизм.
Богатое
Я думаю, что нашел решение, дай мне несколько минут, чтобы обновить ответ.
Тим