Mappatura con movimento


12

Sto cercando di capire come posso usare l'operatore con il movimento successivo all'interno di una mappatura. Per esempio:

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

La mappa dovrebbe effettuare le seguenti operazioni:

  1. Attiva l' coperatore e ascolta il movimento successivo;
  2. Ad esempio, posso digitare qui t,per cambiare tutto prima della virgola successiva;
  3. Vai alla modalità di inserimento eliminando tutto tra il cursore e la virgola;
  4. Il testo eliminato viene cercato automaticamente come modello

Quindi, per dirla in modo semplice, dopo che il testo animato è stato rimosso, sono lasciato in modalità di inserimento con occorrenze evidenziate del testo eliminato. Le sarei molto grato se qualcuno mi aiutasse a risolvere questo caso.

AGGIORNARE

Le risposte sono quasi ciò che voglio. Ma! Quando premo /cw, digito qualcosa invece della parola, quindi premo <Esc>. Dopo mi aspetto di fare lo stesso con le occorrenze successive. Ma dopo aver premuto n(vai alla prossima occorrenza) e .(ripeti l'ultimo comando) basta anteporre l'ultimo testo digitato invece di sostituirlo. L'obiettivo principale della mappatura è usarlo con n/Ne .ripetere. Ho perso qualcosa?

Risposte:


9

vim supporta la mappatura dell'operatore :h map-operator.

Ciò di cui hai bisogno è un operatorfunce un mapping. per le tue esigenze, i seguenti codici funzionano. Bene, è solo un esempio, perfezionate ulteriormente.

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

Si noti che exec 'let @/=@"'solo per evidenziare i codici nel buffer. Se non vuoi vedere immediatamente l'evidenziazione, puoi semplicementelet @/=@"


Ho aggiornato la mia domanda. Sembra che la tua risposta sia la più vicina alle mie esigenze, ma non fa lo stesso con la prossima occorrenza, quindi ho spiegato quel momento della domanda.
Timur Fayzrakhmanov,

Hai due operatori (il /ce i) vim .ripete solo l'ultimo. Se vuoi estenderlo, controlla il repeatplugin. @TimurFayzrakhmanov ci sono anche :ge :scomandi, può aiutarti anche tu.
Kent,

C'è strano "nel tuo codice 'let @/=@""'? Ho pensato che fosse possibile, ad esempio silent exec 'normal! [v ]c', perché l' coperatore fa ciò che mi aspetto, tranne per il fatto che non aggiunge il testo modificato al modello di ricerca.
Timur Fayzrakhmanov,

1
@TimurFayzrakhmanov "" era un errore di battitura .. correzione .. Anche io mi è venuta in mente c, tuttavia ha aggiunto uno spazio, perché c'è un cambio di modalità n-i-n-icredo ... fai qualche test che vedrai.
Kent,

@TimurFayzrakhmanov puoi renderlo ripetibile senza alcun plugin cambiando din ye startinsertin call feedkeys("cgn", 'n')(vedi la mia risposta di seguito)
Jerome Dalbert

4

È più semplice implementare (e documentare) mappature complesse utilizzando le funzioni:

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

Quindi fai in modo che la tua mappatura chiami quella funzione:

nmap /c :call DoMagic()<CR>

Modificare:

Se la vostra intenzione è quella di eseguire la ricerca e sostituzione in un gran numero di posti si dovrebbe provare il comando substitute: :s. È possibile modificare la mappatura per copiare la selezione visiva nel modello di ricerca:

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

vmap /c :<c-w>%s/<C-r>=DoMagic2()<CR>//gc<left><left><left>

1
questo è anche con una "bella" UI, funziona per le necessità dell'OP e può essere "più" del previsto, dipende da cosa hai inserito. Ad esempio, quando uno vede enter motion:, ha dato: t,ggVGJZZ ^ _ ^ È un problema comune per la concatenazione dei comandi
Kent,

Questo è quasi quello che voglio. Ad esempio: premo /cwquindi digito qualcosa anziché la parola, quindi premo <Esc>. Dopo voglio fare lo stesso con le ricorrenze successive. Ma dopo aver premuto n(vai alla prossima occorrenza) e .(ripeti l'ultimo comando) basta anteporre l'ultimo testo digitato invece di sostituirlo. L'obiettivo principale della mappatura è usarlo con n/Ne .ripetere. Ho perso qualcosa?
Timur Fayzrakhmanov,

1
Questa funzione serve a chiarire l'idea di utilizzare le funzioni in caso di problemi con i mapping complessi. Dovresti cambiarlo per soddisfare le tue esigenze; prova a seguire il consiglio di Kent per .ripetere il comando.
lunedì

Grazie per la risposta. E 'utile anche, ma accettare una 's il @Kent, perché fare il movimento subito dopo li ho tipo (senza attesa <CR>da input()).
Timur Fayzrakhmanov,

1
@TimurFayzrakhmanov potresti anche provare il sostituto, come spiegato nell'aggiornamento.
lunedì

1

Questa soluzione funziona con "ripeti l'ultimo comando" (aka .):

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

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

Quando ripeti, non hai nemmeno bisogno di usare n, puoi semplicemente usare .per recuperare direttamente e sostituire la ricorrenza successiva se vuoi andare più veloce.

Facoltativamente, se ti piace evidenziare le parole corrispondenti, puoi sostituirlo 'cgn'con 'n``cgn'.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.