Search code examples
emacselispminibuffer

How to use a minibuffer-exit-hook with read-string


I have not been able to get the minibuffer-exit-hook to play nice with read-string. As far as I can tell, I should no longer be in the minibuffer after finishing up with read-string. However, the condition (minibufferp) says I'm still in the minibuffer even though read-string finished. read-string is written in C, so I can't add the hook there (i.e., at the tail end of the read-string function).

"Documentation [minibuffer-exit-hook]:  Normal hook run just after exit from minibuffer.

[After thinking a little more about this, I'm pretty sure it's a bug -- so I filed a bug report: bug#16524. As I learn more, I'll update this thread.

(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))))))

Solution

  • Running a hook after you truly exited the minibuffer is rather pointless: you could be in any kind of buffer (since minibuffer use can be triggered from anywhere) and you hence know very little about the current context (unless you use a buffer-local exit-hook, I guess).

    If you want to run a hook when the selected window changes, then your best option is probably to use a post-command-hook that stores the current selected-window in an auxiliary variable and uses it to compare to the previous selected-window.