Как использовать минибуфер-выход-крюк со строкой чтения

Я не смог получить minibuffer-exit-hook хорошо играть с read-string, Насколько я могу судить, я больше не должен быть в минибуфере после окончания read-string, Тем не менее, условие (minibufferp) говорит, что я все еще в минибуфере, хотя read-string законченный. read-string написано на C, поэтому я не могу добавить хук там (т. е. в хвостовой части read-string функция).

"Документация [минибуфер-выход-крюк]: Обычный крюк запускается сразу после выхода из минибуфера.

[Подумав немного больше об этом, я почти уверен, что это ошибка - поэтому я подал отчет об ошибке: ошибка #16524. Как я узнаю больше, я буду обновлять эту тему.

(defun test ()
  (interactive)
  (read-string "Prompt: " "testing"))

(add-hook 'minibuffer-exit-hook (lambda ()
  (cond
    ((minibufferp)
      (message "Focus is still in the minibuffer:  %s" (buffer-name)))
    (t (message "Contragulations -- focus is now in: %s." (buffer-name))))))

2 ответа

Решение

Выполнять ловушку после того, как вы действительно вышли из минибуфера, довольно бессмысленно: вы можете находиться в буфере любого типа (поскольку использование минибуфера может быть инициировано из любого места), и, следовательно, вы очень мало знаете о текущем контексте (если вы не используете выход из буфера локально хук, наверное).

Если вы хотите запустить ловушку, когда выбранное окно изменяется, то, вероятно, лучше всего использовать post-command-hook который сохраняет текущее выбранное окно во вспомогательной переменной и использует его для сравнения с предыдущим выбранным окном.

Строка документа не является точной; это все. Хук запускается при вводе текста в минибуфере (больше не возможно). Буфер, который является текущим при его запуске, все еще является минибуфером. (И это так и должно быть, FWIW.)

Обратите внимание, что в руководстве Elisp это выглядит немного иначе (но, опять же, не очень точно):

 This is a normal hook that is run whenever the minibuffer is
 entered.

("Всякий раз", то есть примерно в то же время, что и не обязательно после.)

Если вы хотите сделать что-то после каждого использования read-string в своем коде, затем определите функцию, которая выполняет следующее: сначала (read-string...)тогда все, что вы хотите сделать дальше. И используйте эту функцию.

Если вам нужно повлиять также на другие вызовы read-stringКроме тех, что вы пишете в своем коде, тогда советуйте функцию read-string выполнить любое действие после завершения ванильного кода.

Например:

(defadvice read-string (after fooness activate)
   (message "buffer: %S" (current-buffer)))

[Примечание: да, вы можете посоветовать примитивы (функции, написанные на C). Раньше вы даже могли консультировать специальные формы, но они регрессивно убрали эту функцию.]

Другие вопросы по тегам