Разница между setq и setq-default в Emacs Lisp

89

У меня вопрос о Emacs Lisp. В чем разница между setq и setq-default ?

В руководствах говорится, что setq действует в локальном буфере, а setq-default влияет на все буферы.

Например, если я написал (setq a-var a-vars-value) в init.el , я обнаружил, что после запуска Emacs и открытия нового буфера, a-var тоже присутствует, и его значение равно a-vars-value . Я думал, этого не должно было быть. Кажется, нет разницы между setq и setq-default .

Что-то не так с моим пониманием?

Например:

  1. Я написал (setq hello 123) в файле init.el и запускаю emacs abuffer в оболочке, затем ввожу «hello Cx Ce» , отображается «123». То же самое происходит, когда я запускаю это во всех новых буферах.

  2. Я написал (setq tab-width 4) в файле init.el. Когда я запускаю Cx Ce шириной табуляции , он показывает «8» (текущий режим - «Текст»). Однако, когда я использую (setq-default tab-width 4) , отображается «4». Я не могу объяснить это явление.

Ruanhao
источник

Ответы:

100

Некоторые переменные в Emacs являются "локальными для буфера", что означает, что каждому буферу разрешено иметь отдельное значение для этой переменной, которое отменяет глобальное значение по умолчанию. tab-width- хороший пример локальной переменной в буфере.

Если переменная является локальной в буфере, то setqустанавливает ее локальное значение в текущем буфере и setq-defaultустанавливает глобальное значение по умолчанию.

Если переменная не является локальной в буфере, то setqи setq-defaultсделайте то же самое.

В вашем случае 2 (setq tab-width 4)установите значение 4 tab-widthдля локального буфера в текущем буфере, оставив глобальное значение по умолчанию равным tab-width8, поэтому, когда вы выполняли оценку tab-widthв другом буфере, у которого не было локального значения, вы видели это 8. Затем когда вы устанавливаете значение по умолчанию на 4, этот буфер забирает его, так как он все еще не имеет локального значения.

dfan
источник
когда I (устанавливает ширину табуляции 4) и оценивает ее, всегда 8 в каждом буфере. Не знаю почему. Кажется, это не действует. Но когда я использую (set-default tab-width 4), он действует в каждом буфере. Я тоже не знаю почему :(
ruanhao
(setq tab-width 4)вступает в силу в буфере, в котором вы вычислили выражение; если вы оцениваете его в *scratch*буфере, проверьте его значение в этом буфере.
Tripleee
tab-widthпеременная, локальная в буфере. Поэтому, когда вы (setq tab-width 4), он установлен только на 4 в текущем буфере. Все остальные буферы сохраняют tab-widthглобальное значение по умолчанию, 8. Когда (setq-default tab-width 4)вы меняете глобальное значение по умолчанию, равное tab-width4, теперь каждый буфер, который не определил tab-widthсам себя, имеет это новое значение по умолчанию.
dfan
3
Да. См. Список последовательности действий emacs при запуске . Чтение файла инициализации - это шаг 12, а
вызов
1
@ruanhao Если вы (setq tab-width 4) в init.el, тогда он будет применяться только к этому буферу (init.el). Если вы хотите, чтобы это изменение применялось ко всем новым буферам, то (setq-default tab-width 4) выполнит это. Кроме того, если вы хотите создать режим для определенного типа файла, вы, вероятно, захотите использовать (setq tab-width 4), чтобы не переопределять глобальное значение по умолчанию.
Hemm