ChatGPT解决这个技术问题 Extra ChatGPT

The difference between setq and setq-default in Emacs Lisp

I have a question about Emacs Lisp. What is the difference between setq and setq-default?

Tutorials say setq takes effect in the local buffer while setq-default affects all buffers.

For example, if I wrote (setq a-var a-vars-value) in init.el, I found after starting Emacs and opening a new buffer, the a-var is also there and its value is a-vars-value. I thought it was not supposed to be there. It seems there is no difference between setq and setq-default.

Is there something wrong with my understanding?

For example:

I wrote (setq hello 123) in the init.el file, and I run emacs abuffer in the shell, then I input "hello C-x C-e", it shows "123". The same happens when I run this in all new buffers. I wrote (setq tab-width 4) in the init.el file. When I run tab-width C-x C-e, it shows "8" (Current mode is 'Text'). However, when I use (setq-default tab-width 4), it show "4". I can't explain this phenomenon.


d
dfan

Some variables in Emacs are "buffer-local", meaning that each buffer is allowed to have a separate value for that variable that overrides the global default. tab-width is a good example of a buffer-local variable.

If a variable is buffer-local, then setq sets its local value in the current buffer and setq-default sets the global default value.

If a variable is not buffer-local, then setq and setq-default do the same thing.

In your case 2, (setq tab-width 4) set the buffer-local value of tab-width to 4 in the current buffer, leaving the global default value of tab-width still at 8, so when you evaluated tab-width in a different buffer that had no local value, you saw that 8. Then, when you set the default value to 4, that buffer picked it up, since it still had no local value.


when I (sets tab-width 4), and evaluate it, it is always 8 in every buffer. I don't know why. Seems it does not take effect. But when I use (sets-default tab-width 4), it takes effect in every buffer. I also do not know why:(
tab-width is a buffer-local variable. So when you (setq tab-width 4), it is only set to 4 in the current buffer. All other buffers retain a tab-width of the global default, 8. When you (setq-default tab-width 4), you are changing the global default of tab-width to 4, so now every buffer that has not defined tab-width itself has that new default.
Yes. See the list of emacs' Sequence of Actions at Startup. Reading the init file is step 12, and bringing up the initial buffer is step 23.
ah, enlightened. So when i (setq tab-width 4), no buffer is initialized and there is no specific buffer that corresponds to '(setq tab-width 4)'. In this case, this config in 'init.el' is somewhat useless, am i right?
@ruanhao If you (setq tab-width 4) in the init.el, then it will only apply to that buffer (init.el). If you want this change to apply to all new buffers, then (setq-default tab-width 4) will accomplish this. Additionally, if you want to create a mode for a specific type of file, you would probably want to use (setq tab-width 4) so as not to override the global default.