Mapeo con movimiento

12

Estoy tratando de entender cómo puedo usar el operador con el movimiento posterior dentro de un mapeo. Por ejemplo:

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

El mapa debe hacer lo siguiente:

  1. Active el coperador y escuche el próximo movimiento;
  2. Por ejemplo, puedo escribir aquí t,para cambiar todo antes de la próxima coma;
  3. Vaya al modo de inserción eliminando todo entre el cursor y la coma;
  4. El texto eliminado se busca automáticamente como un patrón

Para decirlo de manera simple, después de eliminar el texto de movimiento, me dejo en modo de inserción con las ocurrencias resaltadas del texto eliminado. Estaría muy agradecido si alguien me ayudara a resolver este caso.

ACTUALIZAR

Las respuestas son casi lo que quiero. ¡Pero! Cuando presione /cw, escriba algo en lugar de la palabra, luego presione <Esc>. Después espero hacer lo mismo con las próximas ocurrencias. Pero después de presionar n(ir a la siguiente aparición) y .(repetir el último comando) simplemente antepone el último texto escrito en lugar de reemplazarlo. El objetivo principal del mapeo es usarlo con n/Ny .para repetir. ¿Me he perdido algo?

Timur Fayzrakhmanov
fuente

Respuestas:

9

vim admite mapeo de operador :h map-operator.

Lo que necesitas es un operatorfuncy un mapeo. para sus necesidades, los siguientes códigos funcionan. Bueno, es solo un ejemplo, refinas aún más.

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

Tenga en cuenta que exec 'let @/=@"'solo para resaltar los códigos en el búfer. Si no desea ver el resaltado de inmediato, puede simplementelet @/=@"

Kent
fuente
He actualizado mi pregunta. Parece que su respuesta es la más cercana a mis necesidades, pero no hace lo mismo con la próxima aparición, por lo que he explicado ese momento en la pregunta.
Timur Fayzrakhmanov
Tienes dos operadores (el /cy i) vim .solo repite el último. Si desea extenderlo, verifique el repeatcomplemento. @TimurFayzrakhmanov también hay :gy :scomandos, pueden ayudarte también.
Kent
¿Hay algo extraño "en tu código 'let @/=@""'? Pensé que era posible, por ejemplo silent exec 'normal! [v ]c', porque el coperador hace lo que esperaba, excepto que no agrega el texto modificado al patrón de búsqueda.
Timur Fayzrakhmanov
1
@TimurFayzrakhmanov "" fue un error tipográfico ... arreglo ... También se me ocurrió c, sin embargo, agregó un espacio, porque hay un cambio de modo n-i-n-i, supongo ... haz alguna prueba que verás.
Kent
@TimurFayzrakhmanov puede hacerlo repetible sin ningún complemento cambiando da yy startinsertpara call feedkeys("cgn", 'n')(vea mi respuesta a continuación)
Jerome Dalbert
4

Es más fácil implementar (y documentar) asignaciones complejas mediante el uso de funciones:

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

Luego haga que su mapeo llame a esa función:

nmap /c :call DoMagic()<CR>

Editar:

Si su intención es llevar a cabo la búsqueda y reemplazar en un gran número de lugares a los que debe tratar el comando sustituto: :s. Puede cambiar su mapeo para copiar la selección visual al patrón de búsqueda:

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

vmap /c :<c-w>%s/<C-r>=DoMagic2()<CR>//gc<left><left><left>
mMontu
fuente
1
esto es incluso con una interfaz de usuario "agradable", funciona para la necesidad de OP y puede ser "más" de lo esperado, depende de lo que ingrese. Por ejemplo, cuando uno ve enter motion:, dio: t,ggVGJZZ ^ _ ^ Es un problema común para la concatenación de comandos
Kent
Eso es casi lo que quiero. Por ejemplo: presiono y /cwluego escribo algo en lugar de la palabra, luego presiono <Esc>. Después quiero hacer lo mismo con las próximas ocurrencias. Pero después de presionar n(ir a la siguiente aparición) y .(repetir el último comando) simplemente antepone el último texto escrito en lugar de reemplazarlo. El objetivo principal del mapeo es usarlo con n/Ny .para repetir. ¿Me he perdido algo?
Timur Fayzrakhmanov
1
Esta función es para aclarar la idea de usar funciones cuando tiene problemas con asignaciones complejas. Debe cambiarlo para satisfacer sus necesidades; intente seguir los consejos de Kent para que .repita su comando.
mMontu
Gracias por la respuesta. También es útil, pero acepto el @Kent, porque hace un movimiento inmediatamente después de que los escribo (sin pendiente <CR>de input()).
Timur Fayzrakhmanov
1
@TimurFayzrakhmanov también puedes probar el sustituto, como se explica en la actualización.
mMontu
1

Esta solución funciona con "repetir último comando" (también conocido como .):

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

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

Al repetir, ni siquiera necesita usar n, solo puede usar .para buscar directamente y reemplazar la siguiente ocurrencia si desea ir más rápido.

Opcionalmente, si desea resaltar las palabras coincidentes, puede reemplazar 'cgn'por 'n``cgn'.

Jerome Dalbert
fuente