Різниця між 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". Я не можу пояснити це явище.

Відповіді:


100

Деякі змінні в Emacs є "buffer-local", що означає, що кожен буфер може мати окреме значення для цієї змінної, яка замінює загальне значення за замовчуванням. tab-widthє хорошим прикладом буферно-локальної змінної.

Якщо змінна є локально-буферною, тоді setqвстановлює її локальне значення в поточному буфері та setq-defaultвстановлює глобальне значення за замовчуванням.

Якщо змінна не буфер локальної, то setqі setq-defaultробити те ж саме.

У вашому випадку 2 (setq tab-width 4)встановіть для місцевого буфера значення tab-width4 у поточному буфері, залишивши загальне значення за замовчуванням tab-widthрівним 8, тому, коли ви обчислювали tab-widthв іншому буфері, який не мав локального значення, ви побачили, що 8. Потім, коли ви встановлюєте значення за замовчуванням до 4, цей буфер піднімає його, оскільки воно все ще не має локального значення.


коли I (встановлює ширину табуляції 4) і обчислює її, вона завжди дорівнює 8 у кожному буфері. Не знаю чому. Здається, це не набирає чинності. Але коли я використовую (набори-ширина вкладки за замовчуванням 4), це набуває чинності в кожному буфері. Я також не знаю чому :(
ruanhao

(setq tab-width 4)набуває чинності в буфері, де ви оцінили вираз; якщо ви оцінюєте його в *scratch*буфері, то дослідіть його значення в цьому буфері.
триплеє

tab-widthє локально-буферною змінною. Отже, коли ви (setq tab-width 4), для поточного буфера встановлено значення 4. У всіх інших буферах зберігається a tab-widthзагального значення за замовчуванням, 8. Коли ви (setq-default tab-width 4)змінюєте загальне значення за замовчуванням tab-widthна 4, тож тепер кожен буфер, який не визначився tab-width, має це нове значення за замовчуванням.
dfan

3
Так. Перегляньте список послідовності дій emacs під час запуску . Читання файлу init - це крок 12, а виведення початкового буфера - крок 23.
dfan

1
@ruanhao Якщо ви (setq tab-width 4) у init.el, то це стосуватиметься лише цього буфера (init.el). Якщо ви хочете, щоб ця зміна застосовувалася до всіх нових буферів, тоді (setq-default tab-width 4) це зробить. Крім того, якщо ви хочете створити режим для певного типу файлу, ви, мабуть, захочете використовувати (setq tab-width 4), щоб не замінити загальне значення за замовчуванням.
Хемм
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.