I want to do something VERY simple. I want to create a minor mode, which when enabled sets a buffer-local variable (say left-margin-width, for instance) with a specific value.

I can do this:

(define-minor-mode margin-mode
  (setq left-margin-width 3))

Now, I want the variable to take back it's global value when margin-mode is disabled. To me this seems like a very natural use-case, but apparently I can't find a simple and easy way to do his yet! Once enabled, the variable retains it's value until the buffer is closed. Which is very undesirable.



Minor modes are toggles. Defining a minor mode also creates a variabel with the same name. This variable is toggled when enabling/disabling the minor mode.
So following code works:

(define-minor-mode margin-mode
  (if (not margin-mode)
      (setq left-margin-width 3)
    (setq left-margin-width (default-value 'left-margin-width))))

Elisp is a Lisp-n type language. This means there exist separate namespaces for function names and variable names. You can have a variable and a function with the same name. This is used here.

(instead of resetting the local variable with (setq left-margin-width (default-value 'left-margin-width)) you could also use (kill-local-variable 'left-margin-width).

To get more info on how to define minor modes, read the documentation. you can access the documentation with C-h f define-minor-mode <RET>

  • Thanks. I kinda knew this. I was wondering if it was workable without using an explicit condition check. – sixter Dec 15 '20 at 9:53
  • Also this wouldn't work with the margins cause apparently setting the variable isn't enough. – sixter Dec 15 '20 at 10:07
  • 1
    C-h v left-margin-width tells you that you have to call set-window-buffer to make changes to this variable take effect. But this was not what you asked about, so I expected, you already know this. – jue Dec 15 '20 at 21:14
  • 1
    Have a look at public source code minor modes, most use a if or when or unless and the minor-mode variable to act according. – jue Dec 15 '20 at 21:17

See C-hf kill-local-variable for reverting a buffer-local variable to the global state.

If you just set the buffer-local value to the variable's current default value, then it's still a buffer-local value (i.e. it won't reflect future changes to the default).

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.