Come posso mappare d [count] d?


18

NB Questo non è un duplicato di Come funziona il comando "d3fg"? Si prega di leggere prima di votare per chiudere!

Sono arrivato a un punto morto nella mia ricerca per far funzionare le piccole eliminazioni come quelle grandi . Il problema che ho è che non riesco a capire come rimappare i comandi come d3d. In realtà, non riesco nemmeno a capire come funzionano in primo luogo, né trovarne alcuna menzione nell'aiuto di Vim. *

d3jè semplice: applica l' doperatore al 3jmovimento,

3ddè anche semplice: esegue il ddcomando con un "conteggio" di 3.

d3d sembra che dovrebbe essere semplice, applica l' doperatore al ... ma che cos'è 3d? Non è un movimento. Se digiti 3dda solo, Vim lo considera come un conteggio seguito da un operatore e attende pazientemente ulteriori input.

E non puoi applicare operatori ad altri operatori. ddnon è descritto nella guida come una sequenza di due operatori. È un comando separato a due tasti. (cfr dc. che non fa nulla).

Inoltre, non sembra essere il caso che il posizionamento del conteggio sia flessibile per i comandi che richiedono due sequenze di tasti: 2gjsposta il cursore su due righe dello schermo, ma g2jscarta completamente i primi due tasti e sposta il cursore su una riga.

Quindi, come funziona? È solo un caso speciale nel codice interno di Vim? Esiste un modo per creare una d[count]dmappatura?

EDIT : è un oggetto di testo? :h text-objectsnon include nella lista dei "comandi di selezione oggetto testo", ma poi non comprende dd in una lista di delezioni "raggruppato da piccole a grandi oggetti". E d2awcancella la parola sotto il cursore e quella successiva. D'altra parte, c2dnon fa nulla.

* Sono sicuro che alcuni di essi debbano esistere, ma non riesco a trovarlo. Ho letto :help deleting, :help motion.txte provato :helpgrep dNdper tutti i valori di N da 1-9 .


2
Penso che l'ultimo dfunga da conferma; Quindi è lo stesso di d3<CR>. y3ye c3cfunziona allo stesso modo ... Non riesco a trovare alcun documento su questo, sia in Vim: help, vi (1), nvi (1), sia nelle specifiche POSIX ... Si comporta allo stesso modo in vie nvibtw .
Martin Tournoij,

1
In un certo senso, ddè identico a d_. _porta il cursore sul primo non vuoto sulla ( [count]-1) riga in basso, ma è in senso lineare, quindi se accoppiato con un operatore, opera su intere linee. Per questa ragione, ha senso che un conteggio possa apparire tra le due ds.
Tommaso

Risposte:


28

Modalità operatore in attesa

Tra digitando un operatore (come d, co gU) e un movimento (come w, i}o /foo<CR>), Vim è in modalità Operator-pending. È possibile creare mappature per questo usando :omape :onoremap.

Nel mio esempio, ho intenzione di mappare l'Operatore in attesa da w. Questa è una scelta casuale, perché non so per cosa tu abbia voluto usarlo.

Crea un omap

Creiamo un mapping per din modalità Operatore in sospeso. Suppongo che stiamo scrivendo VimScript qui (come nel tuo .vimrc), quindi ometterò :i primi .

onoremap d w

Questo fa ddagire come dw. Fa anche d[count]dcomportarsi come d[count]w. Ma scommetto che non volevi influenzare il comportamento di dd(cioè, non [count]fornito).

Mapping delle espressioni

I mapping delle espressioni consentono di valutare un'espressione VimScript per produrre il lato destro del mapping. L'espressione dovrebbe essere valutata in una stringa. I mapping delle espressioni sono indicati dalla <expr>parola chiave.

Vim ha anche alcune variabili integrate che vengono popolate in vari momenti e sono spesso utili durante le mappature. Uno di questi è v:count, che viene [count]fornito a un operatore o movimento.

Mettiamo tutto insieme. Se non [count]viene fornito, v:countlo sarà 0. Possiamo dire alla nostra mappatura di usare solo din quel caso.

onoremap <expr> d v:count == 0 ? 'd' : 'w'

Ora si ddcomporta come predefinito (elimina una riga), ma d[count]dsi comporta come d[count]w. Freddo!

Limita l'uso dopo l' doperatore

Potresti notare qualcosa, però. Ora cdsi comporta anche come cw. Questo potrebbe non essere un problema, ma per completezza, limitiamolo in modo che funzioni solo dopo l' doperatore.

Vim ha un'altra variabile, v:operatorche contiene l'operatore utilizzato più di recente. Controlliamo anche quello, prima di fare qualcosa di speciale.

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : 'w'

NOTA: poiché i :mapcomandi possono essere concatenati |, dobbiamo evitarli nella nostra espressione qui. Quindi ||diventa l' operatore logico OR \|\|.

Bene, così cde c[count]dsono tornato a non fare nulla, proprio come una volta. Questo è buono in modo che altri plugin possano definire cd.

Non voglio solo eliminare qualche altro movimento

Se vuoi mappare d[count]dqualcosa di completamente diverso, niente a che fare con l'eliminazione del testo, possiamo farlo funzionare anche noi.

Quando si digitano i comandi in modalità Normale e si inizia a digitare un comando per errore, è possibile premere <Esc>per annullare quel comando. Lo stesso vale per i tuoi mapping.

Facciamo d[count]dcambiare la linea corrente in qualunque cosa [count]sia.

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : '<Esc>cc' . v:count . '<Esc>'

L'ultima parte della mappatura è un'espressione VimScript: <Esc>cc' . v:count . '<Esc>'. Ciò significa <Esc>annullare il dcomando in sospeso , quindi ccmodificare la riga corrente, v:countdigitare il valore di [count](in modalità Inserisci) e <Esc>tornare alla modalità normale. Si noti che stiamo costruendo una stringa qui utilizzando l'operatore di concatenazione VimScript, ..


Il tuo caso d'uso sarà probabilmente diverso da quello che ho delineato qui, ma spero che questo ti aiuti a far rotolare la palla.

Buon taglio!


Bella risposta! Upvoted. Ho collegato al mio caso d'uso (anche su vi.SE) all'inizio della domanda, ma immagino che tu debba averlo perso. Fondamentalmente ho bisogno di fare :omap d d(!), Ma sfortunatamente la modalità in attesa dell'operatore non viene mai effettivamente raggiunta a causa della mia mappatura per d che imposta la funzione di operatore personalizzato. Spero che sia possibile modificare le cose per far d3dfunzionare come dovrebbe, però. (Fammi sapere se hai qualche idea, o sentiti libero di pubblicare una soluzione completa all'altra domanda se preferisci.) Se non riesco a capirlo presto, accetterò questo e posterò un'altra domanda più specifica. Grazie!
Rich

1
In realtà, ripensandoci, lo accetto adesso. Hai spiegato sia come creare una simile mappatura, sia come funziona sotto il cofano, quali erano le due cose che ho chiesto.
Rich
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.