Como usar corretamente o defcustom?

15

Como a maioria dos usuários do Emacs, eu personalizei um modo alterando as variáveis. O que nunca me ocorreu é toda a mentalidade de programação por trás de personalizar isso e aquilo. Percebi isso quando comecei a olhar para o código fonte do eshell. Eu não sou um programador elisp, mas especificamente em-ls.elparece usar defcustom, defgroupetc. Isso parece ser uma sombra mundial de variáveis globalmente definido que os usa código elisp. Então, uma pergunta seria: o uso de defcustomoutra maneira de fazer variáveis ​​globais (personalizáveis)?

Alguém pode me indicar como usar corretamente (primeiro entender) toda a ideia por trás defcustom, quando usar, por que, quando não? Talvez um exemplo para iniciantes para um iniciante no elisp.

147pm
fonte
Você poderia esclarecer o que está perguntando? Deseja saber quando usar as customizeinstalações e quando personalizar manualmente? Ou você está interessado em escrever um modo? A última é a situação em que você pode realmente usar coisas como defcustomessas.
Dan

Respostas:

20

O sistema de personalização é um recurso interno do Emacs projetado para resolver com precisão o problema que você descreve - a programação pode não ser a maneira ideal para o usuário médio configurar seu editor.

O ponto de entrada principal para a funcionalidade de personalização é M-x customize RET(ou Options > Customize Emacs > Top-level Customization Groupno menu). A partir daí, você verá um sistema de menus interativo para ajustar as configurações. Essa interface impõe que todas as configurações sejam do tipo correto (número, sequência, cor, etc.), evitando a principal fonte de erro encontrada quando os usuários configuram o Emacs programaticamente. Se o usuário optar por persistir as alterações feitas na interface do usuário, as configurações serão armazenadas em uma seção especial no arquivo de inicialização do usuário (leia-se .emacs:).

defcustomé um invólucro em torno da funcionalidade Emacs Lisp de nível inferior, defvarque declara a variável e a torna visível na interface de personalização. Ele também permite que o desenvolvedor forneça metadados extras necessários para exibir um controle interativo apropriado - ou seja, que tipo de valor é armazenado nessa variável? Uma string arbitrária? Um número? Uma escolha entre um conjunto fixo de opções? etc. defgroupé uma construção de agrupamento para essas opções personalizáveis, para que possam ser organizadas em uma boa hierarquia.

Essa funcionalidade deve ser usada sempre que um dado for considerado uma opção configurável para o usuário, em vez de um detalhe interno da biblioteca.

Aqui está um exemplo simples extraído de uma pequena biblioteca minha:

(defgroup checkbox nil
  "Quick manipulation of textual checkboxes."
  :group 'convenience)

(defcustom checkbox-states '("[ ]" "[x]")
  "Checkbox states to cycle between.
First item will be the state for new checkboxes."
  :group 'checkbox
  :type '(repeat string))

O defgroupcria um novo grupo na interface Personalização no convenienceitem de nível superior . Eu então precisava de uma variável para armazenar os possíveis estados da caixa de seleção. Eu poderia ter usado defvar, mas como quero que isso seja facilmente personalizável, optei por usá-lo defcustom. A :groupparte indica que pertence ao grupo definido anteriormente e :typeindica que é uma sequência de cadeias. Há também um valor padrão e uma descrição. Existem também recursos adicionais (não mostrados aqui) para transformar valores inseridos pelo usuário.

Se agora eu corro M-x customize RETe navego para Convenience > Checkbox, vejo o seguinte:

interface de personalização

Não é a interface mais bonita do mundo, mas observe que ele possui ferramentas interativas para personalizar o valor de "Estados da caixa de seleção" ( checkbox-statesinternamente). Ele mostra os valores atuais da sequência, juntamente com os botões INS(inserir) e DEL(excluir), e permite editar os valores da sequência nas caixas de edição. Quando terminarmos, podemos decidir se devemos aplicar nossas alterações, revertê-las ou aplicá-las e salvá-las para sessões futuras.

Camdez
fonte
2
Bom post! As vantagens mais significativas do Customizing (e defcustom) são que ele cuida automaticamente de : (1) verificação de tipo , para ajudar a impedir que você atribua um valor incorreto a uma variável (desde que o escritor tenha se defcustomesforçado para fornecer um tipo razoável check), (2) inicialização ( :initialize) e cções de atualização (acionadas) ( :set).
Tirou
Obrigado! Atualizei a postagem para refletir suas sugestões.
Camdez 27/08/2015
7

O uso de defcustom é outra maneira de executar variáveis ​​globais (personalizáveis)?

Sim. Especialmente se você quiser que os usuários do seu código possam alterar variáveis ​​facilmente através da interface de personalização do Mx .

O defcustom oferece dois benefícios importantes para seus usuários: documentação e segurança de tipo. É bom ter documentação lá. A segurança de tipo permite especificar quais tipos de valores válidos suas variáveis ​​podem receber.

É claro que defvar é bom se tudo o que você está fazendo é personalizar por si mesmo e não antecipar um uso mais amplo. No entanto, alguns diriam que manter o defcustom completamente é um bom hábito a inculcar.

Alguém pode me apontar para iluminar sobre como usar corretamente ...

A página de manual do defcustom tem mais esclarecimentos. O tópico Personalizações no manual possui detalhes completos.

... quando usar, por que, quando não?

Pessoalmente, acho o defcustom menos complicado durante o desenvolvimento, pois não preciso lidar com problemas de recarga com o defvar e o setq.

Usuário Emacs
fonte