Selectrum: Set enable-recursive-minibuffers automatically

Created on 28 May 2020  路  12Comments  路  Source: raxod502/selectrum

Expected Behavior

Let's say I want to evaluate the variable magit-completing-read-function from the minibuffer. I'd hit M-: to bring up the Eval: prompt, then I'd type magit- and expect to see a list of viable variable candidates.

Current Behavior

After bringing up the Eval: prompt, I type magit-, hit TAB and I get an error saying Command attempted to use minibuffer while in minibuffer.

Steps to reproduce

  1. Start Emacs with emacs -q
  2. Load Selectrum (I ran load-file and found selectrum.el in my .emacs.d/ directory)
  3. Type M-: ema TAB (I'm not sure what the completion candidates are here

It seems to only happen if there are candidates to complete. If you type a string like asdfasdf it will just say no matches in the minibuffer.

Most helpful comment

I think you both forgot to set enable-recursive-minibuffers to t? @raxod502 Maybe selectrum-mode should do this by default?

All 12 comments

I met the same issue. Here is the backtrace (with some long line truncated):

Debugger entered--Lisp error: (error "Command attempted to use minibuffer while in minibuffer")
  read-from-minibuffer("Completion: " nil (keymap (9 . selectrum-insert-current-candidate) (10 . selectrum-submit-exact...
  selectrum-read("Completion: " (... ... ... ... ... ... ... ... ... ... ... ... ... ... ...) :may-modify-candidates t)...
  selectrum-completion-in-region(#<marker at 8 in  *Minibuf-1*> 11 [0 0 ansi-color-apply-overlay-face isearch--state-po...
  completion-in-region(#<marker at 8 in  *Minibuf-1*> 11 [0 0 ansi-color-apply-overlay-face isearch--state-pop-fun--cma...
  completion-at-point()
  funcall-interactively(completion-at-point)
  call-interactively(completion-at-point nil nil)
  command-execute(completion-at-point)
  read-from-minibuffer("Eval: " nil (keymap (9 . completion-at-point) (27 keymap (9 . completion-at-point)) keymap (rem...
  read--expression("Eval: ")
  byte-code("\301\302!\303\10!B\207" [current-prefix-arg read--expression "Eval: " eval-expression-get-print-arguments]...
  call-interactively(eval-expression nil nil)
  command-execute(eval-expression)

Completion in minibuffer incurs selectrum-completion-in-region who calls selecttrum-read who itself uses the minibuffer.

Completion in minibuffer is useful: when type elisp with"M-:", when enter shell command with "M-!", etc. So it is quite frustrating that selectrum makes completion in minibuffer not work.

As a temporary workaround, I checkout to commit prior to 8857a8fbf05aaaf231eff9c681427166c286bf35. Hope this can be fixed soon.

I think you both forgot to set enable-recursive-minibuffers to t? @raxod502 Maybe selectrum-mode should do this by default?

You are right! After setting enable-recursive-minibuffers to t, it works. Thanks!

Hi @clemera , but here comes another issue when in a remote buffer (TRAMP),

  • If I checkout 2b49ab4aeff2647dc1c996b73d8f190feff38e98 (so that no selectrum-completion-in-region), if I use "M-! ls ~/" then "<TAB>", home files on this remote machine are shown. This is expected.
  • But if I use master and set enable-recursive-minibuffers to t, home files on my local machine are shown.

Do you experience this, or it is again due to my incorrect config?

Thanks for discovering this, that seems to be a bug with file completion for selectrum-completion-in-region. Could you open another issue for that?

OK, thanks again for your timely reply!

I am a little reluctant to automatically bind enable-recursive-minibuffers. After all, some people want the default behavior (perhaps it was Stefan Monnier who said he liked it?), and if we bind the variable to non-nil automatically, then there's no way for the user to enforce that setting.

On the other hand, I suppose we could have a variable selectrum-enable-recursive-minibuffers which, if non-nil, means enable-recursive-minibuffers gets set to non-nil. I think that would be a fine idea, and quite easy to add. The value of this new variable could be non-nil by default.

I think that's a good idea. If I get some time tomorrow I can try my hand at creating a PR for that.

Ran into this today and was puzzled :) Couldn't selectrum catch the error defensively (checking if that's enabled) and then display a more helpful error message in the minibuffer? Like

Requires enable-recursive-minibuffers to be non-nil for completion to work here

Yes, that seems like a good idea, I agree.

I just ran into this issue now that I've switched over to selectrum. Couldn't selectrum automatically bind it to t when it's asked to do completion, ie. if I'm inside M-: and press <TAB>, I clearly want to get completion. I think at this point selectrum should simply make sure that won't error out with (let ((enable-recursive-minibuffers t)) ...), so that it can provide the user with the requested functionality without changing the defaults elsewhere.

Alternatively, maybe use a popup buffer if recursive minibuffers are disabled, the way default completion (and icomplete) do in this situation? I don't know how much of a rewrite making selectrum able to use a non-minibuffer buffer would be.

Thanks @mathrick for bringing my attention to this issue again. With #397 the value is let bound for the commands which need it, this is also what the built-in describe-... commands do.

Was this page helpful?
0 / 5 - 0 ratings