Interesting problem. Looks like the editor runs the post-command-hook
every time it enters a new command-loop, i.e. a recursive-edit
. But we can start with minibuffer-setup-hook
, which executes a function after entering the minibuffer. While this allows the inserting of input, it is too soon to exit the minibuffer, because the catch hasn't been setup yet.
(defmacro with-minibuffer-input (form &rest inputs)
(declare (indent 1))
`(minibuffer-with-setup-hook
(lambda ()
(minibuffer-input-provider ',inputs))
,form))
That's were we need to wrap the 'arguments' in our own 'command loop', which get's executed every time we enter a recursive-edit
, at which point it pops one argument and throws one level up, via exit-minibuffer
.
;; -*- lexical-binding: t -*-
(defun minibuffer-input-provider (inputs)
(let ((hook (make-symbol "hook")))
(fset hook (lambda ()
(remove-hook 'post-command-hook hook)
(when inputs
(when (= 0 (minibuffer-depth))
(error "Too many inputs"))
(when (cdr inputs)
(add-hook 'post-command-hook hook))
(insert (pop inputs))
(exit-minibuffer))))
(add-hook 'post-command-hook hook)))
(with-minibuffer-input (call-interactively 'find-file)
"/")
(with-minibuffer-input (call-interactively 'occur)
"\\(foo\\)\\(bar\\)" "\\1");;C-u C-x C-e
;;foobar
(with-minibuffer-input (call-interactively 'replace-string)
"foo" "bar")
;; foo
interactive
clause. When called from elisp, your should be able to pass the information as a function argument. Of course, this does not help you, in case the function you are trying to call doesn't follow this design.