Vantagens de definir variáveis ​​com setq em vez de custom.el?

69

Vejo muitas pessoas (autores de extensão e outros) dar exemplos de configuração com setq:

(setq foo 'bar)

Esses parâmetros geralmente são definidos com defcustom, disponibilizando-os para personalização custom.el.

Eu normalmente uso custom.elpara configurá-los. Em vez disso, haveria alguma vantagem em usar setqou os dois métodos são aproximadamente equivalentes?

J David Smith
fonte

Respostas:

86

Algumas pessoas podem pensar que é mais simples de usar setq. Algumas pessoas podem pensar que é mais lispy. Na realidade, é ingênuo no caso geral.

É verdade que, para algumas opções de usuário, isso não importa. Mas para outros, isso importa, e setqé a abordagem errada para essas opções. Então, como regra geral, setqé a abordagem errada.

Se você usar custom-set-variablesou em customize-set-variablevez de setq, ou se você usar a interface do usuário Personalizar (por exemplo M-x customize-option), terá certeza de que qualquer código de inicialização ou atualização pretendido necessário para o valor da opção será automaticamente acionado e executado conforme necessário. Se você usar setq, isso não será feito.

Agora, também é o caso de a maioria das opções de usuário, especialmente muitas escritas para bibliotecas de terceiros, não fazem uso das defcustompalavras - chave :sete :initialize, e o uso setqnão importa para elas. Mas muitas opções de baunilha do Emacs usam essas palavras-chave e, para aquelas que o fazem, setqnão é a coisa certa. Portanto, se você deseja usar o código Lisp e não a interface do usuário Personalizar para definir suas opções, é melhor usar custom-set-variablesou em customize-set-variablevez de setq. Nunca dói e às vezes ajuda (muito).

Mas o que eu recomendo é fazer as duas coisas:

  • Use a interface do usuário Personalizar em vez de escrever o código Lisp para isso.

  • Defina a variávelcustom-file , para que o Customize grave personalizações nesse arquivo e não no seu arquivo init ( ~/.emacs). IOW, mantenha seu código de inicialização escrito à mão separado do código automático escrito por Customize.

Desenhou
fonte
5
Acho que vale a pena mencionar que, mesmo com os parâmetros: set e: initialize, o setq ainda funciona se for lido antes do carregamento do pacote.
Malabarba 24/09
2
@Willyfrog Você pode votar!
Zane Shelby
17
não tenho certeza sobre isso Drew. A coisa toda de personalização é bastante complexa. Sem ele, o sistema emacs é muito mais simples. A personalização é uma camada que não combina exatamente com o elisp. Por um lado, ele ordena todos os vars por alfabetos. Além disso, muitas customizações não são sobre variáveis ​​(por exemplo, ganchos, chaves), portanto, não podem ser customizadas. Então você tem uma situação de código elisp manual de qualquer maneira.
Xah Lee
4
@XahLee. Bem, eu tenho certeza. ;-) Mas sim, Customize é o que é. Não é o melhor para chaves, ganchos, palavras-chave de bloqueio de fonte, tabelas de exibição etc. Mas, para o que ele faz (opções e faces), ele se sai muito bem. Não que a interface do usuário seja maravilhosa, mas o manuseio de gatilhos, a verificação de tipo etc. é útil. I até mesmo desejo programadores poderiam (opcionalmente) usar coisas como :typecom defvar- Eu não acho que isso deve ser limitado a opções de usuário. Infelizmente, muitos programadores são preguiçosos no uso :typee o resultado não é muito útil (isso não é culpa do Customize).
Drew
2
Ponto de dados: Nas minhas 3.300 linhas de código init do Emacs, desenvolvidas ao longo de quase um ano, fui mordido usando em setqvez de customize-set-variableexatamente uma vez. (Aquela vez foi para auto-revert-interval, e eu mais tarde percebeu que o uso setq antes de carregamento autorevertera realmente muito mais rápido que usar customize-set-variable.)
Radon Rosborough
38

Prefiro setqmais customizepor vários motivos:

  1. Em primeiro lugar, ele permite que as variáveis ​​sejam configuradas programaticamente (como em (setq foo (calculate-foo))). Eu uso esse poder o tempo todo em minha configuração para manter as coisas secas. Para mim, o objetivo principal do uso do Emacs é a programação, e a customizeinterface não faz nada além de atrapalhar.
  2. setqpresta-se melhor ao controle de versão e organização de código. Dividi minha inicialização entre dezenas de arquivos; se tudo estivesse em um custom.elarquivo enorme , seria muito mais difícil encontrar e editar rapidamente as configurações.
  3. Isso é subjetivo, mas para mim toda a customizeinterface parece uma relíquia horrível das piores UIs dos anos 90. Eu preferiria editar texto com o poder do Emacs qualquer dia.

@Drew faz alguns pontos positivos sobre algumas sutilezas com :sete :initialize. Uso o Emacs há anos e raramente encontro problemas assim. Quando eu faço, é fácil de trocar setqpara custom-set-variableem casos específicos.

shosti
fonte
10
1. Você pode configurar variáveis ​​de personalização programaticamente com customize-set-variable(s), e é melhor por causa dos gatilhos que eles executam automaticamente. 2. Você pode usar vários comandos de personalização para ver todas as suas variáveis ​​definidas e / ou salvas em diferentes hierarquias, para obter a organização de diferentes grupos automaticamente, sem precisar usar arquivos separados no controle de versão. 3. Melhorou muito. Se você não gostar da interface do usuário, ainda poderá usar a personalização programaticamente e através dos comandos interativos que evitam o modo de personalização para obter todos os outros benefícios do uso da personalização.
Nick McCurdy
24

Uma vantagem de usar em setqvez de customizeé legibilidade. Um é livre para anotar cada personalização ao seu gosto, o que IMO melhora a legibilidade. Também é possível agrupar personalizações relacionadas, o que melhora a modularidade. Finalmente, eu diria que navegar através de um buffer elisp é mais "fácil" do que navegar na interface do usuário e nos widgets.

Por outro lado, a personalização permite reverter facilmente para valores padrão que podem ser inestimáveis ​​quando as coisas dão errado.

EDIT: A resposta de Drew fornece uma excelente razão para usar, customize-set-variablesque pode fornecer todas as vantagens que apontei. No entanto, a UI de personalização não se presta a configurações portáteis entre plataformas diferentes tão facilmente quanto o elisp bruto. Se você precisar que uma variável tenha a configuração dependente do sistema operacional, será necessário fazer o fallback para elisp em muitos casos. Meu argumento sobre a navegação mais fácil nos buffers elisp ainda permanece.

Vamsi
fonte
Você também pode reverter para o valor padrão com setq, basta comentar a setqlinha e reiniciar o emacs.
T. Verron
3
Sim, mas a personalização pode reverter sem reinicializações desagradáveis. Altamente útil para experimentar novas configurações.
Vamsi 24/09
2
Com relação à anotação, a interface de personalização permite adicionar um comentário a cada variável que você altera.
Andrew Swann
custom-set-variables é "elisp bruto" e eu o uso todos os dias em várias máquinas. Apenas copie-o para fora do local onde o personaliza o grava (se você não o escreveu).
Croad Langshan #
A interface <kbd> Mx customize- * </kbd> possui um campo "comment" que permite armazenar um comentário junto com uma variável.
kdb 11/10
-1

Outra alternativa é usar o pacote de uso de John Wiegley . Isso fornece uma maneira programática de configurar pacotes que funcionam bem com o processo de inicialização de pacotes do emacs 24+. Aqui está um exemplo de uso do leia-me:

(use-package color-moccur
  :commands (isearch-moccur isearch-all)
  :bind (("M-s O" . moccur)
         :map isearch-mode-map
         ("M-o" . isearch-moccur)
         ("M-O" . isearch-moccur-all))
  :custom (isearch-lazy-highlight t)
  :config (use-package moccur-edit))

O ponto é que use package é uma macro e não avalia seus argumentos imediatamente. Os parâmetros :inite :configsão avaliados em diferentes estágios do processo de inicialização, possibilitando a configuração de cada pacote em um único local, mas cada parte sendo executada no estágio apropriado de inicialização.

Sem algo parecido, use-packagealguns pacotes exigem que parte de seu código de inicialização seja anterior (package-initialize)e outra parte seja posterior. Se você tem muitos pacotes assim, suas primeiras inicializações teriam que ser intercaladas.

Outro benefício use-packageé que ele pode instalar automaticamente os pacotes ausentes usando o package.el se você levar o .emacs para uma nova máquina ou se você compartilhar sua configuração com outro usuário e toda a inicialização puder ser adiada até que um pacote realmente precise ser carregado.

Também existem argumentos de palavras-chave adicionais que permitem mais controle sobre o processo de inicialização.

Tudo o que foi dito, uma grande vantagem da personalização é que ela mostra o que há para ser configurado em qualquer pacote. Essa é uma das razões pelas quais ainda o uso em muitos dos meus pacotes.

Daniel Mahler
fonte
2
Na verdade, isso não responde à pergunta. Na sua própria resposta, você usa setq sem explicar o porquê.
J David Smith
3
Eu acho que use-packageele próprio oferece vantagens da configuração modularizada, além de importar e configurar pacotes em um único local. Mas sim, o exemplo está usando setq. Poderia muito bem ter usado customize-set-variableaqui? Não tenho certeza. Poderíamos / devemos trocá-lo (ou customize-set-value) por setq?
Mike3
4
Altere o exemplo para que ele use a :custompalavra - chave.
Toon Claes