Aquí está mi manera súper hacky de simular la vinculación de eventos arriba / abajo de la tecla aprovechando los temporizadores.
En general, sugeriría seguir la respuesta de Sigma, pero usted solicitó una forma de cerrar la vista previa al dejar ir, así que estoy obligado a intentarlo.
Básicamente, lo que puede hacer es vincular alguna función que será su función "keydown" a una combinación de teclas y dentro de esa acción, inicie un temporizador inactivo que ejecute una función que es su función "keyup", siempre que mantenga presionada la tecla teclas dadas, la función "keydown" se activará una y otra vez y esto inhibirá la ejecución de los temporizadores inactivos. Por supuesto, debe compensar el hecho de que el comando se disparará una y otra vez, probablemente volviendo a vincular la tecla a algún tipo de función noop en su función "keydown", y luego volviendo a vincular la función "keydown" en la función "keyup".
Entonces, para su caso de uso, su función "keydown" abrirá un búfer de vista previa con el contenido del archivo en el punto y en ese búfer de vista previa, vinculará la misma combinación de teclas a algún comando similar a un noop. Su función "keydown" también iniciará un temporizador inactivo que eliminará su búfer de vista previa y lo restaurará a donde estaba.
Larga historia corta aquí está el código:
Vincula esta función a un combo de teclas (que usé C-M-v), cuando lo presionas sobre el nombre de un archivo, se abrirá un nuevo búfer que muestra el contenido del archivo en ese momento, cuando lo sueltes, volverás al original 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!"))))
También aquí hay un gif en acción, todo lo que hago es:
- coloco mi cursor sobre el archivo
- mantén presionado el teclado
- se muestra la vista previa
- cuando lo dejo ir, la vista previa se mata y vuelves a donde estabas.
Una cosa importante a tener en cuenta son los segundos del temporizador inactivo, en mi código que utilicé .7
pero es una especie de número mágico, desea mantenerlo realmente pequeño, pero si ve que la vista previa parpadea dos veces, intente aumentarlo 1/10 por segundo cada vez hasta que encuentre el lugar adecuado para su máquina.
* También tenga en cuenta que en la función trato de hacer una fuente del búfer de vista previa pero no pude hacerlo funcionar, ese será el siguiente paso para hacerlo más útil. **