1

I need a function to execute before the minibuffer is entered, not after (minibuffer-setup-hook style). Is there any way I can achieve this effect with advice or other emacs systems?

I would like to defer some minibuffer setup until the minibuffer is actually used, to speed up startup time.

5
  • 5
    What do you mean by "initializes"? What does it need to execute after (not just before)? Describe your real need: the problem you are trying to solve. Provide more detail. Beware of a possible X-Y problem here.
    – Drew
    Commented Dec 24, 2014 at 18:37
  • Like Drew says, it will help a great deal if you explain exactly what you want to accomplish. But without knowing that, maybe defadvice using :before would help? I must admit I'm just guesing though, given the aforementioned lack of information. Commented Dec 24, 2014 at 20:11
  • @Drew Thanks, I've clarified my position. The reason I don't say why is any mention of startup time causes causes everyone to go bananas and suggest avoiding the problem with the emacs server or other similar strategies. (ignoring solutions to the original problem) Those are not options for me.
    – PythonNut
    Commented Dec 27, 2014 at 18:14
  • It's still not clear what you mean by "before the minibuffer is entered". In my world-view, minibuffer-setup-hook is run before the minibuffer is entered, so obviously, you mean something different.
    – Stefan
    Commented Dec 28, 2014 at 14:50
  • @Stefan one example, (add-hook 'minibuffer-setup-hook 'ido-ubiquitous-mode) doesn't enable ido-ubiquitous-mode early enough. You can only tell the mode is enabled on the second time the minibuffer is entered.
    – PythonNut
    Commented Dec 28, 2014 at 21:55

1 Answer 1

1

The function that sets up the minibuffer is read_minibuf in minibuf.c. As of Emacs 24, it is called from the primitives read-from-minibuffer and read-no-blanks-input, and Fread_from_minibuffer is in turned called from read-string. The hook minibuffer-setup-hook is the first piece of Lisp code that read_minibuf executes. If that's too late for you, you're going to need to run your code before any of read-from-minibuffer, read-no-blanks-input and read-string is executed. In earlier Emacs versions, there were more functions that called read_minibuf via C, especially completing-read, but these now go via Lisp.

Here's some code for Emacs ≥24.4 that sets up a one-time advice executed before the first time one of these functions executed.

(defun before-first-read-from-minibuffer (&rest ignored)
  (message "Before first read-from-minibuffer")
  (advice-remove 'read-from-minibuffer 'before-first-read-from-minibuffer)
  (advice-remove 'read-no-blanks-input 'before-first-read-from-minibuffer)
  (advice-remove 'read-string 'before-first-read-from-minibuffer))
(advice-add 'read-from-minibuffer :before 'before-first-read-from-minibuffer)
(advice-add 'read-no-blanks-input :before 'before-first-read-from-minibuffer)
(advice-add 'read-string :before 'before-first-read-from-minibuffer)

The corresponding code with the older advice facility that works in previous Emacs versions would be something like:

(defadvice read-from-minibuffer
    (before before-first-read-from-minibuffer activate)
  (message "Before first read-from-minibuffer")
  (ad-remove-advice 'read-from-minibuffer 'before 'before-first-read-from-minibuffer)
  (ad-activate 'read-from-minibuffer))
4
  • Possibly you need to ad-activate the advice again? I admit, this is one of the reasons nadvice was written. I'll check into this. I admit, it's been a while since I looked at this problem.
    – PythonNut
    Commented Jun 8, 2015 at 3:19
  • I'm afraid this still isn't early enough. (i.e. for activating modes that redefine completing-read like ido-ubiquitous). Maybe I can think of another solution...
    – PythonNut
    Commented Jun 9, 2015 at 0:07
  • So you're changing the question now: you want something that runs before invoking completing-read, not something that runs before entering a minibuffer. You can apply the same technique to completing-read. But you do seem to be on a spiral where the only thing that's early enough is the first pre-command-hook, and if it gets to that, you should just do it in your init file. Commented Jun 9, 2015 at 0:19
  • No. I do not expect you to do any more work. You have correctly answered the question, and that is that. I'm just realizing myself that my solution untenable anyway, (although it may be fixable), but I say this only so you know I tested your solution.
    – PythonNut
    Commented Jun 9, 2015 at 0:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.