Come rilevare sequenze di tasti che non modificano il buffer?


8

Qual è il modo migliore per rilevare sequenze di tasti (ad esempio tramite un hook) che non modificano il buffer? Intendo cose come i tasti freccia per indicare il movimento, le chiamate a beginning-of-buffer, ecc.

La ragione di ciò è che sto lavorando su alcuni ycmdbinding per emacs e mi piacerebbe essere in grado di rilevare (almeno euristicamente) quando l'utente ha smesso di modificare e si sta spostando nel buffer. Questo è un buon momento per spedire il contenuto del buffer per l'analisi. Il client vim lo fa quando l'utente esce dalla modalità di inserimento e sto cercando di emulare quel comportamento.


8
Potresti essere interessato ai timer di inattività per questo tipo di cose: gnu.org/software/emacs/manual/html_node/elisp/Idle-Timers.html
giordano,

2
Un'altra idea (o un perfezionamento dell'idea con i timer di inattività): consiglia self-insert-commanddi annullare e riprogrammare un timer invece di utilizzare un timer di inattività. In questo modo, anche se l'utente fa qualcosa, il timer non viene ripristinato a meno che il "qualcosa" non sia l'inserimento di testo.
mbork,

2
mbork: after-change-functionsè un meccanismo generale per reagire alle modifiche del testo.
phils,

1
Usa a post-command-hook. Ciò si innescherà su tutto, quindi potrebbe essere necessario fare un po 'di filtraggio su ciò che lo ha attivato prima di intraprendere qualsiasi azione tu voglia.
Malabarba,

1
Non sono sicuro che sia rilevante per questo particolare problema, ma la buffer-chars-modified-tickfunzione può essere utile.
Jon O.,

Risposte:


2

Aggiungi i seguenti hook:

  • A pre-command-hook, imposta alcune variabili sentinella su t: questo segnala che il comando non è cambiato.
  • A after-change-functions, impostare questo valore di sentinella su nil. (È un gancio, non sembra proprio uno; grazie a @phils per averlo sottolineato.)
  • Per post-command-hook, controlla questo valore sentinella ed esegui la tua funzione.

Questo potrebbe funzionare o meno a seconda dell'ordine di esecuzione. In caso contrario, fammi sapere nei commenti qui sotto.


Quando esco dal lavoro, posterò un esempio.


Ora devo andare a lavorare ...
Sean Allred,

2
Non consigliare l'autoinserimento. Usa le funzioni post-modifica
Malabarba,

Ci proverò quando ne avrò la possibilità.
circa

4
@abingham Come regola generale, i ganci sono preferibili ai consigli. I ganci sono progettati appositamente per allegare funzioni, mentre i consigli sono modi per collegare qualcosa in luoghi inaspettati. In questo caso particolare, inoltre, non è consigliabile consigliare alcune funzioni molto fondamentali, poiché interagisce in modo sgradevole con la compilazione di byte.
Malabarba,

2
Penso che Sean intendesse riferirsi a post-self-insert-hook(quel pezzetto della risposta sembra confondere quel gancio con la consulenza self-insert-command). In ogni caso, penso che in genere preferiresti after-change-functionsperché in realtà fa quello che vuoi (poiché l'autoinserimento non è l'unico tipo di battitura del tasto che modifica il buffer).
phils,

0

Solo un pensiero -

Questo non dovrebbe riguardare davvero i "tasti", ma i comandi - non importa come vengono eseguiti, no ? Se ho capito bene, stai davvero cercando un modo per dire se un dato comando che viene invocato modifica il buffer.

In tal caso, forse fai qualcosa del genere:

  • Metti una funzione su pre-command-hook(1) registra il valore corrente di (buffer-modified-p)e poi (2) usa set-modified-pper rendere il buffer non modificato.

  • Metti una funzione su post-command-hookquel (1) controlla se il comando ha modificato il buffer (confrontando il valore registrato con il nuovo valore corrente di (buffer-modified-p)), quindi agisce di conseguenza, e (2) se il nuovo valore viene nilquindi resettato al valore pre-modifica usando set-modified-p.

Tipo di mano pesante (controlla per ogni comando che viene invocato), ma potrebbe valere la pena provare.

Se la parte " agisce di conseguenza " è solo una no-op per tutti i comandi di modifica del buffer e se è anche una no-op per molti comandi non modificabili (ad es. Perché l'hai appena eseguita su un precedente comando non modificabile), allora almeno non farai quell'azione " agisce di conseguenza " più del necessario. Ma la parte di controllo da sola potrebbe essere costosa / eccessiva (rallenta troppo le cose) - prova a vedere.

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.