This is similar to many other questions but nothing is leaping out..

I'm a fan of selectrum (similar to helm and ido I gather): e.g. hit M-x and start typing, it'll find matches and list them.

I'd like selectrum-mode enabled during all modes (at least prog-modes), but not during a shell (M-x shell); I'm fine with a specific list of modes to disable it (i.e. enable for all, then disable selectively) or enable for specific modes, i.e. it's handy during non-prog to find-file for opening, but when in shell I want regular shell (bash/etc) based tab completion to occur.

Simple enable of selectrum is:

(selectrum-mode +1)

But this is global in all modes, all the time, so the simpler tab-completion goes instead to selectrum.

I tried putting it in an add-hook:

(add-hook 'prog-mode-hook 'selectrum-mode)

but this just enables it globally when first entering a prog-mode, I think; its not limited to prog modes. And really, I'd like it on all the time, barring some modes. The question is can selectrum be non-global at all, and even if it's a global-only minor mode, can it be toggled on and off automagically?

Without changing selectrum-mode's code to be non-global (if that's possible), I wonder if there's a way to enable/disable it selectively per mode.

What is best practice?

If it's global, could it be toggled on and off when toggling buffers? Perhaps a code fragment to hook switching buffers and disable as appropriate; i.e. on switch buffer, check if entering the list of modes, and then check if selectrum-mode is on, and then (selectrum-mode -1) if needed. This seems cumbersome and likely there is a more elegant approach.

Your help is appreciated; always love to learn something!

edit: Noticed there is a hook buffer-list-update-hook which might be usable, so perhaps I'll learn enough elisp to build the if-mode-active disable code, but I'm sure there's a much more elegant solution.


Attempting answering my own question:

Try 1: partially works, but as per comments below doesn't seem reliable

Create a wrapper global mode, that is selective about when it enables.

(define-global-minor-mode my-global-selectrum-mode selectrum-mode
  (lambda ()
    (when (not (memq major-mode
                     (list 'shell-mode)))

(my-global-selectrum-mode 1)

edit: Try 2: Enable/disable the global minor mode on buffer changes

;; turn selectrum on globally
(selectrum-mode +1)
;; Turn off selectrum on first entry into a new comint-mode (shell) buffer.
(add-hook 'comint-mode-hook (lambda () (selectrum-mode -1)))
;; Toggle selectrum after every buffer switch, avoiding the minibuffer.
(add-hook 'buffer-list-update-hook
          (lambda ()
            (unless (eq major-mode 'minibuffer-inactive-mode)
              (selectrum-mode (if (derived-mode-p 'comint-mode) -1 +1)))))

Stolen from: https://lists.gnu.org/archive/html/help-gnu-emacs/2018-07/msg00002.html

  • Usually best to use (derived-mode-p 'shell-mode) to test a buffer's major mode, as that will also catch modes derived from shell-mode. – phils Jan 15 at 7:08
  • I also recommend using the define-globalized-minor-mode name, and being very clear about distinguishing between "globalized" modes and "global" modes, because they are very different concepts in practice. (A "global" mode has no buffer-local state; a "globalized" mode comprises a "global" mode which controls (en-masse, in multiple buffers) the state of a "buffer-local" mode (which does the real work). – phils Jan 15 at 7:14
  • Hmm. I don't think you've ended up with the right approach. github.com/raxod502/selectrum/blob/… indicates that selectrum-mode is a regular global mode; either on or off, and not per-buffer; so your globalized mode is enabling a global minor mode, rather than a buffer-local minor mode. That's not going to work out. – phils Jan 15 at 7:20
  • phils - I think you're right. So since its a on/off global, then what could be the approach? am I back to the (bad, maybe workable) idea of turning the global mode on or off on buffer change? Would that work or worth a shot? Or a better idea? – jeffatzayo Jan 15 at 14:17
  • Updated my post with another possible solution. Pretty blunt, toggling the whole global minor-mode on and off on buffer changes but whatever gets me through the day at this point ;) (I think ivy is also global on/off, but I don't reliush going through ivy vs ido vs helm vs selectrum again) – jeffatzayo Jan 15 at 15:28

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.