Отображение с движением

12

Я пытаюсь понять, как я могу использовать оператор с последующим движением внутри отображения. Например:

nmap /c c{here we pending for a motion}/<C-r>"<CR>

Карта должна сделать следующее:

  1. Активируйте cоператора и прослушайте следующее движение;
  2. Например, я могу напечатать здесь, t,чтобы изменить все до следующей запятой;
  3. Перейти в режим вставки, удалив все между курсором и запятой;
  4. Удаленный текст автоматически ищется как шаблон

Проще говоря, после удаления движущегося текста я перехожу в режим вставки с выделенными вхождениями удаленного текста. Я был бы очень признателен, если бы кто-нибудь помог мне разобраться в этом деле.

ОБНОВИТЬ

Ответы - почти то, что я хочу. Но! Когда я нажимаю /cw, введите слово вместо слова, затем нажмите <Esc>. После того, как я ожидаю сделать то же самое со следующими вхождениями. Но после нажатия n(перейти к следующему вхождению) и .(повторить последнюю команду) он просто добавляет последний набранный текст вместо его замены. Основная цель картирования - использовать его n/Nи .повторять. Я что-то пропустил?

Тимур Файзрахманов
источник

Ответы:

9

vim поддерживает отображение операторов :h map-operator.

То, что вам нужно, это operatorfuncи отображение. для ваших нужд работают следующие коды. Ну, это всего лишь пример, вы уточняете дальше.

nmap  <silent> /c :set opfunc=SpecialChange<CR>g@
function! SpecialChange(type)
    silent exec 'normal! `[v`]d'    
    silent exec 'let @/=@"' 
    startinsert
endfunction

Обратите внимание, что exec 'let @/=@"'только для выделения кодов в буфере. Если вы не хотите видеть выделение сразу, вы можете простоlet @/=@"

Кент
источник
Я обновил свой вопрос. Кажется, ваш ответ наиболее близок к моим потребностям, но он не делает то же самое со следующим случаем, поэтому я объяснил этот момент в вопросе.
Тимур Файзрахманов
У вас есть два оператора ( /cи i), vim's .просто повторяет последний. Если вы хотите расширить его, проверьте repeatплагин. @TimurFayzrakhmanov также есть :gи :sкоманды, может помочь вам тоже.
Кент
Есть ли странный "в вашем коде 'let @/=@""'? Я думал, что это возможно, например, silent exec 'normal! [v ]c', потому что cоператор делает то, что я ожидаю, за исключением того, что он не добавляет измененный текст в шаблон поиска.
Тимур Файзрахманов
1
@TimurFayzrakhmanov это "" была опечатка .. исправить .. Я cтоже придумал , но он добавил пробел, потому что n-i-n-iя думаю , что есть изменение режима ... сделайте тест, который вы увидите.
Кент
@TimurFayzrakhmanov Вы можете сделать его повторяемым без какого-либо плагина, изменив dна yи startinsertна call feedkeys("cgn", 'n')(см. Мой ответ ниже)
Джером Дальберт
4

Проще реализовать (и документировать) сложные отображения с помощью функций:

function! DoMagic()
   execute "normal! d".input("enter motion: ")
   let @/=@"
   startinsert
endfunction

Затем сделайте ваш вызов вызова этой функции:

nmap /c :call DoMagic()<CR>

Редактировать:

Если ваше намерение выполнить поиск и замену в большом количестве мест , где вы должны попробовать заменить команду: :s. Вы можете изменить свое отображение, чтобы скопировать визуальный выбор в шаблон поиска:

function! DoMagic2()
   normal! gv"ay
   return @a
endfunction

vmap /c :<c-w>%s/<C-r>=DoMagic2()<CR>//gc<left><left><left>
mMontu
источник
1
это даже с «хорошим» пользовательским интерфейсом, работает для нужд ОП и может быть «больше», чем ожидалось, зависит от того, что вы вводите. Например, когда один видит enter motion:, он дал: t,ggVGJZZ ^ _ ^ Это общая проблема для объединения команд
Кент
Это почти то, что я хочу. Например: я нажимаю, /cwзатем набираю что-то вместо слова, затем нажимаю <Esc>. После того, как я хочу сделать то же самое со следующими вхождениями. Но после нажатия n(перейти к следующему вхождению) и .(повторить последнюю команду) он просто добавляет последний набранный текст вместо его замены. Основная цель картирования - использовать его n/Nи .повторять. Я что-то пропустил?
Тимур Файзрахманов
1
Эта функция должна прояснить идею использования функций, когда у вас возникают проблемы со сложными отображениями. Вы должны изменить его, чтобы удовлетворить ваши потребности; попробуйте следовать совету Кента, чтобы .повторить вашу команду.
mMontu
Спасибо за ответ. Это полезно, но я принимаю один в @Kent «s, потому что это делает движение сразу же после того, как я ввожу их (без очереди <CR>с input()).
Тимур Файзрахманов
1
@TimurFayzrakhmanov вы также можете попробовать заменить, как объяснено в обновлении.
mMontu
1

Это решение работает с «повторить последнюю команду» (иначе .):

nmap <silent> /c :set opfunc=ChangeOccurence<CR>g@

function! ChangeOccurence(type)
  exec 'normal! `[v`]y'
  let @/ = @"
  call feedkeys('cgn', 'n')
endfunction

При повторении вам даже не нужно использовать n, вы можете просто использовать .для прямой выборки и замены следующего вхождения, если вы хотите идти быстрее.

При желании, если вам нравится выделение соответствующих слов, вы можете заменить 'cgn'на 'n``cgn'.

Джером Далберт
источник