Comment utiliser correctement defcustom?

15

Comme la plupart des utilisateurs d'Emacs, j'ai personnalisé un mode en changeant les variables. Ce qui ne m'est jamais venu à l'esprit, c'est toute la mentalité de programmation derrière le fait d'avoir ceci et cela personnalisable. Je l'ai réalisé lorsque j'ai commencé à regarder une partie du code source d'Eshell. Je ne suis pas un programmeur elisp, mais em-ls.elsemble spécifiquement utiliser defcustom, defgroupetc. Cela semble être un monde virtuel de variables définies globalement que le code elisp utilise. Une question serait donc: l'utilisation d' defcustomune autre manière de faire des variables globales (personnalisables)?

Quelqu'un peut-il m'indiquer comment utiliser correctement (comprendre d'abord) toute l'idée derrière defcustom, quand l'utiliser, pourquoi, quand non? Peut-être un exemple de débutant pour un débutant élisp.

147pm
la source
Pourriez-vous clarifier ce que vous demandez? Voulez-vous savoir quand utiliser les customizeinstallations et quand les personnaliser à la main? Ou êtes-vous intéressé à écrire un mode? Ce dernier est la situation dans laquelle vous pourriez vous retrouver à utiliser des choses comme defcustomet similaires.
Dan

Réponses:

20

Le système de personnalisation est une fonction intégrée d'Emacs conçue pour résoudre précisément le problème que vous décrivez - la programmation n'est peut-être pas le moyen idéal pour l'utilisateur moyen de configurer son éditeur.

Le point d'entrée principal de la fonctionnalité de personnalisation est M-x customize RET(ou à Options > Customize Emacs > Top-level Customization Grouppartir du menu). De là, vous verrez un système de menu interactif pour ajuster les paramètres. Cette interface garantit que tous les paramètres sont du type correct (nombre, chaîne, couleur, etc.), évitant une source d'erreur majeure rencontrée lorsque les utilisateurs configurent Emacs par programme. Si l'utilisateur choisit de conserver les modifications qu'il effectue via l'interface utilisateur, les paramètres sont stockés dans une section spéciale du fichier d'initialisation de l'utilisateur (lire:) .emacs.

defcustomest un wrapper autour de la fonctionnalité Emacs Lisp de niveau inférieur, defvarqui déclare la variable et la rend visible dans l'interface de personnalisation. Il permet également au développeur de fournir les métadonnées supplémentaires nécessaires pour afficher un contrôle interactif approprié, c'est-à-dire quel type de valeur est stocké dans cette variable? Une chaîne arbitraire? Un numéro? Un choix parmi un ensemble fixe d'options? etc. defgroupest une construction de regroupement pour ces options personnalisables afin qu'elles puissent être organisées en une belle hiérarchie.

Cette fonctionnalité doit être utilisée chaque fois qu'un élément de données doit être considéré comme une option configurable pour l'utilisateur plutôt que comme un détail interne de la bibliothèque.

Voici un exemple simple extrait d'une petite bibliothèque à moi:

(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))

Le defgroupcrée un nouveau groupe dans l'interface de personnalisation sous l' convenienceélément de niveau supérieur . J'avais alors besoin d'une variable pour stocker les états possibles des cases à cocher. J'aurais pu utiliser defvar, mais comme je veux que cela soit facilement personnalisable, j'ai choisi de l'utiliser defcustom. La :groupportion indique qu'elle appartient au groupe précédemment défini et la :typeindique qu'il s'agit d'une séquence de chaînes. Il y a aussi une valeur par défaut et une description. Il existe également des fonctionnalités supplémentaires (non représentées ici) pour transformer les valeurs entrées par l'utilisateur.

Si je cours maintenant M-x customize RETet que je navigue vers Convenience > Checkbox, je vois ce qui suit:

interface de personnalisation

Ce n'est pas la plus belle interface au monde, mais notez qu'elle possède des outils interactifs pour personnaliser la valeur des «états de case à cocher» (en checkbox-statesinterne). Il affiche les valeurs de chaîne actuelles avec les boutons INS(insérer) et DEL(supprimer) et nous permet de modifier les valeurs de chaîne dans les zones d'édition. Lorsque nous avons terminé, nous pouvons décider d'appliquer nos modifications, de les annuler ou de les appliquer et de les enregistrer pour les sessions futures.

camdez
la source
2
Bon post! Les avantages les plus importants du Customizing (et defcustom) sont qu'il prend automatiquement en charge : (1) la vérification de type , pour vous empêcher d'attribuer une valeur incorrecte à une variable (à condition que le rédacteur du ait defcustomfait l'effort de fournir un type raisonnable check), (2) initialization ( :initialize) et update ctions (triggered) ( :set).
Drew
Merci! J'ai mis à jour le message pour refléter vos suggestions.
camdez
7

L'utilisation de defcustom est-elle une autre façon de faire des variables globales (personnalisables)?

Oui. Surtout si vous voulez que les utilisateurs de votre code puissent changer facilement les variables via l' interface de personnalisation Mx .

defcustom offre deux avantages importants à vos utilisateurs: la documentation et la sécurité du type. La documentation est agréable à avoir sur place. La sécurité des types permet de spécifier quels types de valeurs valides vos variables peuvent prendre.

Bien sûr, defvar est bien si tout ce que vous faites est de personnaliser vous-même et ne prévoyez pas une utilisation plus large. Cependant, certains diraient que rester inchangé avec la coutume est une bonne habitude.

Quelqu'un peut-il m'indiquer comment utiliser correctement ...

La page de manuel de defcustom contient des clarifications supplémentaires. La rubrique Personnalisations du manuel contient tous les détails.

... quand l'utiliser, pourquoi, quand pas?

Personnellement, je trouve defcustom moins lourd lors du développement car je n'ai pas à gérer les problèmes de rechargement avec defvar et setq.

Utilisateur Emacs
la source