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
    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 Dec 24 '14 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. – Eric James Michael Ritz Dec 24 '14 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 Dec 27 '14 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 Dec 28 '14 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 Dec 28 '14 at 21:55
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))
  • 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 Jun 8 '15 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 Jun 9 '15 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. – Gilles Jun 9 '15 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 Jun 9 '15 at 0:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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