Ecco il mio modo super hacky per simulare l'associazione di eventi down / up chiave sfruttando i timer.
Nel complesso, suggerirei di seguire la risposta di Sigma, ma hai chiesto un modo per chiudere l'anteprima lasciando andare, quindi sono obbligato a provare.
Fondamentalmente quello che puoi fare è associare una funzione che sarà la tua funzione "keydown" a un keybinding e all'interno di quell'azione, avviare un timer inattivo che esegue una funzione che è la tua funzione "keyup", finché si tiene premuto il dati i tasti, la funzione "keydown" si attiverà ripetutamente e ciò inibirà il funzionamento dei timer inattivi. Ovviamente è necessario compensare il fatto che il comando si attiverà ripetutamente, probabilmente riconducendo la chiave a una sorta di funzione noop nella funzione "keydown", quindi rilegando la funzione "keydown" nella funzione "keyup".
Quindi per il tuo caso d'uso la tua funzione "keydown" aprirà un buffer di anteprima con i contenuti del file in quel punto e in quel buffer di anteprima associerà la stessa combinazione di tasti a un comando noop like. La tua funzione "keydown" avvierà anche un timer di inattività che eliminerà il buffer di anteprima e ripristinerà la tua posizione.
Per farla breve ecco il codice:
Associa questa funzione a una combinazione di tasti (che ho usato C-M-v), quando lo premi in cima al nome di un file si aprirà un nuovo buffer che mostra il contenuto del file in quel punto, quando lo lasci andare tornerai all'originale buffer.
(setq lexical-binding t)
(defun quick-view-file-at-point ()
"Preview the file at point then jump back after some idle time.
In order for this to work you need to bind this function to a key combo,
you cannot call it from the minibuffer and let it work.
The reason it works is that by holding the key combo down, you inhibit
idle timers from running so as long as you hold the key combo, the
buffer preview will still display."
(interactive)
(let* ((buffer (current-buffer))
(file (thing-at-point 'filename t))
(file-buffer-name (format "*preview of %s*" file)))
(if (and file (file-exists-p file))
(let ((contents))
(if (get-buffer file)
(setq contents (save-excursion
(with-current-buffer (get-buffer file)
(font-lock-fontify-buffer)
(buffer-substring (point-min) (point-max)))))
(let ((new-buffer (find-file-noselect file)))
(with-current-buffer new-buffer
(font-lock-mode t)
(font-lock-fontify-buffer)
(setq contents (buffer-substring (point-min) (point-max))))
(kill-buffer new-buffer)))
(switch-to-buffer (get-buffer-create file-buffer-name))
(setq-local header-line-format "%60b")
(delete-region (point-min) (point-max))
(save-excursion (insert contents))
(local-set-key (kbd "C-M-v") (lambda () (interactive) (sit-for .2)))
(run-with-idle-timer
.7
nil
(lambda ()
(switch-to-buffer buffer)
(kill-buffer file-buffer-name))))
(message "no file to preview at point!"))))
Anche qui è una gif in azione, tutto ciò che faccio è:
- posiziona il cursore sul file
- tenere premuto il mio tasto
- viene visualizzata l'anteprima
- quando lascio andare, l'anteprima viene uccisa e sei tornato dove eri.
Una cosa importante da notare sono i secondi del timer inattivo, nel mio codice l'ho usato .7
ma è un po 'un numero magico, vuoi mantenerlo davvero piccolo, ma se vedi l'anteprima lampeggiare due volte prova ad alzarlo di 1/10 di secondo ogni volta finché non trovi il posto giusto per la tua macchina.
* Nota anche che nella funzione cerco di fare una fontificazione del buffer di anteprima ma non sono riuscito a farlo funzionare, quello sarà il prossimo passo per renderlo più utile. **