A diferença entre setq e setq-default no Emacs Lisp

89

Tenho uma pergunta sobre o Emacs Lisp. Qual é a diferença entre setq e setq-default ?

Os tutoriais dizem que setq tem efeito no buffer local, enquanto setq-default afeta todos os buffers.

Por exemplo, se eu escrevi (setq a-var a-vars-value) em init.el , descobri depois de iniciar o Emacs e abrir um novo buffer, o a-var também está lá e seu valor é a-vars-value . Achei que não deveria estar lá. Parece que não há diferença entre setq e setq-default .

Há algo de errado com meu entendimento?

Por exemplo:

  1. Escrevi (setq hello 123) no arquivo init.el e executo o emacs abuffer no shell, depois insiro "hello Cx Ce" , ele mostra "123". O mesmo acontece quando eu executo isso em todos os novos buffers.

  2. Eu escrevi (setq tab-width 4) no arquivo init.el. Quando executo o Cx Ce de largura de tabulação , ele mostra "8" (o modo atual é 'Texto'). No entanto, quando eu uso (setq-default tab-width 4) , ele mostra "4". Não consigo explicar esse fenômeno.

ruanhão
fonte

Respostas:

100

Algumas variáveis ​​no Emacs são "locais de buffer", o que significa que cada buffer pode ter um valor separado para aquela variável que sobrescreve o padrão global. tab-widthé um bom exemplo de uma variável local de buffer.

Se uma variável é local de buffer, setqdefine seu valor local no buffer atual e setq-defaultdefine o valor padrão global.

Se uma variável não é tampão-local, em seguida, setqe setq-defaultfazer a mesma coisa.

No seu caso 2, (setq tab-width 4)defina o valor local do buffer tab-widthcomo 4 no buffer atual, deixando o valor padrão global de tab-widthainda em 8, então quando você avaliou tab-widthem um buffer diferente que não tinha valor local, você viu que 8. Então, quando você configura o valor padrão para 4, esse buffer o pega, já que ainda não tem valor local.

dfan
fonte
quando eu (define tab-width 4) e avalio isso, é sempre 8 em cada buffer. Não sei por quê. Parece que não tem efeito. Mas quando eu uso (sets-default tab-width 4), ele tem efeito em todos os buffers. Também não sei porquê :(
ruanhao
(setq tab-width 4)tem efeito no buffer onde você avaliou a expressão; se você avaliá-lo no *scratch*buffer, examine seu valor nesse buffer.
tripleee
tab-widthé uma variável local do buffer. Então, quando você (setq tab-width 4), é definido apenas como 4 no buffer atual. Todos os outros buffers retêm um tab-widthdo padrão global, 8. Quando você (setq-default tab-width 4), está alterando o padrão global de tab-widthpara 4, agora cada buffer que não se definiu tab-widthtem esse novo padrão.
dfan
3
Sim. Veja a lista de sequência de ações do emacs na inicialização . Ler o arquivo init é a etapa 12 e trazer o buffer inicial é a etapa 23.
dfan
1
@ruanhao Se você (setq tab-width 4) no init.el, ele só se aplicará a esse buffer (init.el). Se você quiser que essa alteração se aplique a todos os novos buffers, (setq-default tab-width 4) fará isso. Além disso, se você deseja criar um modo para um tipo específico de arquivo, você provavelmente deseja usar (setq tab-width 4) para não substituir o padrão global.
Hemm