Вот мой супер хакерский способ имитировать привязку событий нажатия клавиш вниз / вверх, используя таймеры.
В целом, я хотел бы предложить ответ Сигмы, но вы попросили способ закрыть предварительный просмотр, отпустив, поэтому я обязан попробовать.
По сути, вы можете привязать некоторую функцию, которая будет вашей функцией «keydown», к привязке клавиш, и внутри этого действия запустить таймер простоя, который выполняет функцию, которая является вашей функцией «keyup», до тех пор, пока вы удерживаете по заданным клавишам функция «keydown» будет срабатывать снова и снова, и это будет препятствовать работе таймеров простоя. Конечно, вам нужно компенсировать тот факт, что команда будет запускаться снова и снова, вероятно, связав ключ с какой-то noop-функцией в вашей функции «keydown», а затем повторно связав функцию «keydown» в функции «keyup».
Таким образом, для вашего варианта использования ваша функция «keydown» откроет буфер предварительного просмотра с содержимым файла в точке и в этом буфере предварительного просмотра свяжет тот же комбо-ключ с какой-то noop-подобной командой. Ваша функция «keydown» также запустит таймер простоя, который удалит ваш буфер предварительного просмотра и вернет вас туда, где вы были.
Короче говоря, вот код:
Свяжите эту функцию с комбинацией клавиш (которую я использовал C-M-v), когда вы нажимаете ее поверх имени файла, он открывает новый буфер, отображающий содержимое файла в момент, когда вы отпустите, вы будете переключены обратно к оригиналу буфера.
(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!"))))
Также вот гиф этого в действии, все, что я делаю, это:
- поместите мой курсор на файл
- нажмите и удерживайте нажатой клавишу
- предварительный просмотр отображается
- когда я отпущу, предварительный просмотр убит, и вы вернулись туда, где вы были.
Одна важная вещь, которую нужно отметить, это секунды таймера простоя, в моем коде, который я использовал, .7
но это своего рода магическое число, вы хотите, чтобы оно было действительно маленьким, но если вы видите, что предварительный просмотр мигает дважды, попробуйте увеличивать его на 1/10 в секунду каждый раз пока вы не найдете подходящее место для вашей машины.
* Также обратите внимание, что в функции я пытаюсь сделать некоторую фонификацию буфера предварительного просмотра, но я не смог заставить его работать, это будет следующим шагом в том, чтобы сделать его более полезным. **