Różnica między setq i setq-default w Emacs Lisp

89

Mam pytanie dotyczące Emacsa Lispa. Jaka jest różnica między setq i setq-default ?

Samouczki mówią, że setq działa w buforze lokalnym, podczas gdy setq-default wpływa na wszystkie bufory.

Na przykład, jeśli napisałem (setq a-var a-vars-value) w init.el , znalazłem po uruchomieniu Emacsa i otwarciu nowego bufora, a-var też tam jest i jego wartość to a-vars-value . Myślałem, że to nie powinno tam być. Wygląda na to, że nie ma różnicy między setq i setq-default .

Czy jest coś nie tak z moim zrozumieniem?

Na przykład:

  1. Napisałem (setq hello 123) w pliku init.el i uruchamiam emacs abuffer w powłoce, potem wpisuję "hello Cx Ce" , pokazuje "123". To samo dzieje się, gdy uruchamiam to we wszystkich nowych buforach.

  2. Napisałem (setq tab-width 4) w pliku init.el. Kiedy uruchamiam Cx Ce o szerokości tabulacji , pokazuje "8" (aktualny tryb to 'Tekst'). Jednak kiedy używam (setq-default tab-width 4) , pokazuje "4". Nie potrafię wyjaśnić tego zjawiska.

ruanhao
źródło

Odpowiedzi:

100

Niektóre zmienne w Emacsie są „lokalnymi buforami”, co oznacza, że ​​każdy bufor może mieć osobną wartość dla tej zmiennej, która zastępuje globalną wartość domyślną. tab-widthjest dobrym przykładem zmiennej lokalnej bufora.

Jeśli zmienna jest lokalna w buforze, setqustawia jej wartość lokalną w bieżącym buforze i setq-defaultustawia globalną wartość domyślną.

Jeśli zmienna nie jest bufor-local, wtedy setqi setq-defaultzrobić to samo.

W twoim przypadku 2 (setq tab-width 4)ustaw lokalną wartość bufora tab-widthna 4 w bieżącym buforze, pozostawiając globalną wartość domyślną tab-widthwciąż równą 8, więc kiedy oceniłeś tab-widthw innym buforze, który nie miał wartości lokalnej, zobaczyłeś to 8. Następnie, kiedy ustawisz wartość domyślną na 4, bufor odebrał go, ponieważ nadal nie miał wartości lokalnej.

dfan
źródło
kiedy I (ustawia tab-width 4) i oceniam to, zawsze wynosi 8 w każdym buforze. Nie wiem dlaczego. Wygląda na to, że nie działa. Ale kiedy używam (ustawia domyślną szerokość tabulacji 4), działa to w każdym buforze. Nie wiem też dlaczego :(
ruanhao
(setq tab-width 4)działa w buforze, w którym oceniłeś wyrażenie; jeśli oceniasz go w *scratch*buforze, sprawdź jego wartość w tym buforze.
tripleee
tab-widthjest zmienną lokalną w buforze. Więc kiedy ty (setq tab-width 4), jest ustawiony na 4 w bieżącym buforze. Wszystkie inne bufory zachowują tab-widthglobalną wartość domyślną 8. Kiedy (setq-default tab-width 4)zmieniasz globalną wartość domyślną tab-widthna 4, więc teraz każdy bufor, który tab-widthsam się nie zdefiniował , ma nową wartość domyślną.
dfan,
3
Tak. Zobacz listę sekwencji działań emacsa podczas uruchamiania . Czytanie pliku init to krok 12, a
wywołanie
1
@ruanhao Jeśli (setq tab-width 4) w init.el, to będzie to dotyczyło tylko tego bufora (init.el). Jeśli chcesz, aby ta zmiana została zastosowana do wszystkich nowych buforów, to (setq-default tab-width 4) osiągnie to. Dodatkowo, jeśli chcesz stworzyć tryb dla określonego typu pliku, prawdopodobnie będziesz chciał użyć (setq tab-width 4), aby nie przesłonić globalnego ustawienia domyślnego.
Hemm