I've seen this question a lot. But none of the replies fixed my issue: the minor mode stays on in others modes.

So far, I have tried:

(use-package stickyfunc-enhance
  ;; (add-to-list 'semantic-default-submodes 'global-semantic-stickyfunc-mode)
  ;; (defun turn-on-semantic () (semantic-mode 1) (require 'stickyfunc-enhance))
  ;; (add-hook 'python-mode-hook 'turn-on-semantic)
  (add-hook 'python-mode-hook
            (lambda ()
              (add-to-list 'semantic-default-submodes 'global-semantic-stickyfunc-mode)
              (semantic-mode 1)
              (require 'stickyfunc-enhance))))

My issue with those 2 approaches is that semantic-mode will stay on in all major modes once I visited a Python buffer.

How can I turn off semantic-mode in all other modes? Do I have to manually turn it off on prog-mode-hook?

Trying kaushalmodi's solution:

(use-package stickyfunc-enhance
  (add-to-list 'semantic-default-submodes 'global-semantic-stickyfunc-mode)
  (defun me/enable-semantic-maybe ()
    "Maybe enable `semantic-mode'."
    (if (derived-mode-p 'python-mode)
        (lambda ()
          (semantic-mode 1)
          (require 'stickyfunc-enhance))
      (semantic-mode -1)))
  (add-hook 'change-major-mode-hook #'me/enable-semantic-maybe))

Yields me:

Making python-shell-interpreter local to  *Python Internal [792caf12c778150badeeede64c068cee]* while let-bound!
Making python-shell-interpreter-args local to  *Python Internal [792caf12c778150badeeede64c068cee]* while let-bound!

2 Answers 2


The best solution I have found to restrict semantic-mode to certain buffers only is to set semantic-inhibit-functions. For example you can add a function that inhibits semantic in buffers not in python mode as follows

(defun my-inhibit-semantic-p ()
  (not (equal major-mode 'python-mode)))

(with-eval-after-load 'semantic
      (add-to-list 'semantic-inhibit-functions #'my-inhibit-semantic-p))

Looking at the source code in semantic.el, it looks like semantic-mode is a global minor mode. So once activated, it will be activated in all the buffers; and once deactivated, it will be deactivated in all.

You can probably have something like below that enables semantic mode only when you open a specific mode buffer (but I am not sure how well it will behave when you have buffers open with different major modes):

(defun my/enable-semantic-mode-maybe ()
  (if (derived-mode-p 'python-mode)
      (semantic-mode 1)
    (semantic-mode -1)))
(add-hook 'change-major-mode-hook #'my/enable-semantic-mode-maybe)

From semantic.el:

(define-minor-mode semantic-mode
  "Toggle parser features (Semantic mode).
With a prefix argument ARG, enable Semantic mode if ARG is
positive, and disable it otherwise.  If called from Lisp, enable
Semantic mode if ARG is omitted or nil.

;; -- snip --     

  :global t ; <-- GLOBAL MODE

;; -- snip --
  • Alright, that looks a cleaner that what I was going for with prog-mode-hook (if even it was working). However, can you tell me why did you use a # ? Does byte-compiled means it will be computed in the first step that .elc is? Aug 18, 2015 at 16:07
  • 1
    It's a good coding practice to use #' (sharp-quote) where a function symbol argument is expected. [More reading] Aug 18, 2015 at 16:10
  • I have errors. Updated question. Aug 18, 2015 at 16:39
  • @MathieuMarques Couple of things.. you would use (progn instead of (lambda () there to wrap the stuff that should happen if the if condition is true. Also I would require stickyfunc-enhance in the very beginning in the :init before you reference global-semantic-stickyfunc-mode. As for the actual error, I would start a new question with a more directed question + tags. I think though that the problem is with you using lambda instead of progn. Aug 18, 2015 at 16:43
  • Yes I realize now I mixed up both, thanks for the help :). Aug 18, 2015 at 16:48

Your Answer

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

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