0

I want to set default value of scroll-margin to 3 but for ansi-term I want it to be 0. To do this I have added a hook to term-mode-hook which worked fine.

(setq scroll-margin 3)                          
(add-hook 'term-mode-hook                       
          (lambda ()                                 
            (make-local-variable 'scroll-margin)
            (setq scroll-margin 0)))            

But earlier I used unless to do the same thing which didn't work and I don't understand why. Could someone please help why below snippet didn't work to do the same task?

(unless (derived-mode-p 'term-mode)
  (setq scroll-margin 3))
7
  • Did you execute that code by hand? In your init file? In a hook? What was the mode of the buffer that was current when you executed it?
    – NickD
    Oct 11 '20 at 15:00
  • @NickD I entered this code in my init.el file, saved it and opened a new emacs instant. With the first snippet, I could see positive results whereas after second snippet, I didn't see what I expected. Oct 11 '20 at 18:26
  • Right - your init.el gets executed in the context of a buffer (probably *scratch*) whose major mode (probably lisp-interaction-mode) is not a derived mode of term-mode, so the conditional evaluates to nil and scroll-margin is left at its default value (probably 0).
    – NickD
    Oct 11 '20 at 18:39
  • I expected it to work like: unless current mode is not term-mode, set scroll-margin to 3 and when major mode is term-mode, keep it to default which is 0. Where am I going wrong in understanding? Oct 12 '20 at 11:41
0

When you add the second bit of code into your init.el:

(unless (derived-mode-p 'term-mode)
  (setq scroll-margin 3))

and that code gets executed, it asks: "Is the mode of the current buffer a derived mode of term-mode?" - the answer is "No", since the current buffer is *scratch*, the major mode is lisp-interaction-mode and that is not a derived mode of term-mode. You can do that experiment yourself: create a file foo.el in the current directory and add this to is:

(message (symbol-name major-mode))
(message (buffer-name))

(message (if (derived-mode-p 'term-mode) "True" "False"))

(unless (derived-mode-p 'term-mode)
  (setq scroll-margin 3))


Now start up emacs with this file as your init file:

emacs -Q -l foo.el`

and check the *Messages* buffer - you should see something like this:

lisp-interaction-mode
*scratch*
False

As you can see, the conditional evaluates to nil, so the setting of scroll-margin is skipped.[1]

To summarize: when the contents of init.el are evaluated, that is done in a buffer that is unrelated to any term-mode buffer you later create, so it cannot possibly have an effect.

The first code fragment:

(setq scroll-margin 3)                          
(add-hook 'term-mode-hook                       
          (lambda ()                                 
            (make-local-variable 'scroll-margin)
            (setq scroll-margin 0)))        

says: unconditionally set scroll-margin to 3. Then, when you create a new buffer and set its major mode to term-mode (or a derived mode of it), the term-mode-hook is run: that calls all of the functions in the hook and in particular the function you added, which sets scroll-margin to 0 locally in that buffer.

The effect is that scroll-margin is 3 in all buffers, except for term-mode buffers (and buffers whose mode is a derived mode of term-mode) where scroll-margin is set to 0 for those buffers only.

[1] The details might vary, depending on how exactly you start. E.g. if I copy the above foo.el to $HOME/.emacs and start up emacs without any options, I get fundamental-mode instead of lisp-interaction-modebut there is no other significant difference.

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.