Aqui está minha maneira super hacky de simular a ligação de eventos de down / up de chave, aproveitando os temporizadores.
No geral, eu sugeriria seguir a resposta da Sigma, mas você pediu uma maneira de fechar a pré-visualização deixando ir, então sou obrigado a tentar.
Basicamente, o que você pode fazer é vincular alguma função que será sua função "keydown" a uma combinação de teclas e, dentro dessa ação, iniciar um timer ocioso que execute uma função que é sua função "keyup", desde que você mantenha pressionado o botão dadas as teclas, a função "keydown" será acionada repetidamente e isso inibirá a execução dos temporizadores ociosos. É claro que você precisa compensar o fato de que o comando será acionado repetidamente, provavelmente religando a tecla a algum tipo de função noop na função "keydown" e, em seguida, religando a função "keydown" na função "keyup".
Portanto, para o seu caso de uso, a função "keydown" abrirá um buffer de visualização com o conteúdo do arquivo no ponto e nesse buffer de visualização vinculará a mesma combinação de teclas a algum comando noop like. Sua função "keydown" também iniciará um timer ocioso que excluirá seu buffer de visualização e restaurará você de volta onde estava.
Para encurtar a história, aqui está o código:
Vincule esta função a uma combinação de teclas (que eu usei C-M-v); quando você a pressiona sobre um nome de arquivo, ele abre um novo buffer exibindo o conteúdo do arquivo no momento; quando você o solta, volta para o original. amortecedor.
(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!"))))
Também aqui está um gif dele em ação, tudo o que faço é:
- coloque meu cursor sobre o arquivo
- pressione e segure minha tecla
- a visualização é exibida
- quando eu solto, a visualização é interrompida e você volta para onde estava.
Uma coisa importante a observar são os segundos do temporizador inativo, no meu código que usei, .7
mas é um número mágico, você deseja mantê-lo muito pequeno, mas se a visualização piscar duas vezes, tente aumentá-lo 1/10 por segundo a cada vez até encontrar o local certo para sua máquina.
* Observe também que, na função, tento fazer alguma fonte do buffer de visualização, mas não consegui fazê-lo funcionar, esse será o próximo passo para torná-lo mais útil. **