Is there a way to detect when a minor mode is turned on. For web-mode, I would like to know when indent-tabs-mode is turned on.

Please note that what I need is to detect this when the user has begun to edit the buffer with indent-tabs-mode turned off and then decides to turn it on.

  • 1
    indent-tabs-mode is not a mode, it's a variable. Very confusing, I know. – wasamasa Feb 21 '15 at 9:21
  • Can (if '(indent-tabs-mode) ... help? – Name Feb 21 '15 at 9:37
  • you're right ... that's obvious ! I guess I'll have to follow the thread on emacs-devel about a hook on variable value change – fxbois Feb 21 '15 at 9:38
  • 2
    Why not simply turn it on in web-mode? – Lindydancer Feb 21 '15 at 12:29
  • 5
    @fxbois this looks like an XY problem. Instead, ask us what you're really trying to do, and we might have better solutions than the one you thought of. ;-) (And don't hold your breath for that variable hook thread.) – Malabarba Feb 21 '15 at 18:52

You can test the truth value of the variable indent-tabs-mode, which will be nil if it's off and non-nil if it's on.

For your specific use case, making sure it's turned on as of the first edit, you can add a little function to first-change-hook. From the docstring:

Documentation: A list of functions to call before changing a buffer which is unmodified. The functions are run using the run-hooks function.

So, you could test for a nil value, but since you always want it turned on, you could skip the test:

(defun force-tabs-in-web-mode ()
  (when (eq major-mode 'web-mode)  ; I'm assuming it's web-mode
    (setq indent-tabs-mode t)))

(add-hook 'first-change-hook #'force-tabs-in-web-mode)
  • I think you may have misunderstood his second paragraph. In the cases where indent-tabs-mode is initially off, he wants to detect if the user turns it on some time after he started editing the buffer. He doesn't want to detect whether it's turned on at the time of first change. Anyway, that's what it seems to me. – Malabarba Feb 21 '15 at 18:59
  • @Malabarba: after re-reading, I think you're right. I agree with the comment you left on OP's question: a revised question will probably get more useful answers. – Dan Feb 21 '15 at 19:05
  • @Malabarba you're totally right – fxbois Feb 21 '15 at 21:43

If you want to respect the user's indentation choice (as you should), the right way is to just do the right thing when indenting, you don't need to keep track if the variable was changed.

Your two options are:

  • Instead of manually removing/inserting whitespace at beginning-of-line, just use either indent-to or indent-line-to. These functions automatically respect the indent-tabs-mode variable.

  • If you need to do it manually for some reason, just check the value of indent-tabs-mode inside your indentation function and act accordingly.

  • You summarize a little bit too much. To deal with tab indentation I need to change some parameters (especially lineup params) ... please look at web-mode-use-tabs – fxbois Feb 24 '15 at 10:11
  • @fxbois sure, I'll look into it tomorrow. But, by the name, it sounds like this parameter is just duplicating the functionality of indent-tabs-mode. If that's the case you simply shouldn't have such a parameter, you should simply look at indent-tabs-mode. – Malabarba Feb 24 '15 at 10:30

From the emacs manual's section on minor modes:

Most minor modes also have a "mode variable", with the same name as the mode command. Its value is non-nil if the mode is enabled, and nil if it is disabled.

For example, associated to abbrev-mode, the function and minor mode, there is the variable abbrev-mode whose documentation is:

abbrev-mode is a variable defined in `C source code'. Its value is nil

Automatically becomes buffer-local when set. This variable is safe as a file local variable if its value satisfies the predicate booleanp.

Documentation: Non-nil if Abbrev mode is enabled. Use the command abbrev-mode to change this variable.

As this indicates, in general the variable should be changed via the command.

As mentioned in the comments the case of indent-tab-mode is unusual, there is no corresponding function, just the variable. Anyway you can test for whether it is set or not via

(if indent-tab-mode
  • I know this, as I have written, I need to know when this var has its value changed. As you wrote it, detecting if a minor mode is turned on is easy. What I need to know is when this minor mode is toggled. – fxbois Feb 21 '15 at 17:18
  • @fxbois Provide a little more context on why you need that, and we may be able to provide an alternate solution. – Malabarba Feb 21 '15 at 19:01
  • @Malabarba to adjust web-mode settings to play nicely with tab indentation requirements. – fxbois Feb 21 '15 at 21:45
  • Then your question is not clear to me. Why not set a variable to the value of indent-tab-mode when the web-mode starts and compare the current value of indent-tab-mode to that? – Andrew Swann Feb 22 '15 at 12:30
  • I won't compare this each time I indent a line. I was wondering if a cleaner solution existed. – fxbois Feb 22 '15 at 19:16

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