Как правильно использовать defcustom?

15

Как и большинство пользователей Emacs, я настроил режим, изменив переменные. Что мне никогда не приходило в голову, так это весь менталитет программистов, стоящий за настраиваемым этим и этим. Я понял это, когда начал изучать исходный код eshell. Я не Elisp программист, а конкретно , em-ls.elкажется, использует defcustom, defgroupи т.д. Это , казалось бы, теневой мир глобально определенных переменных , которые Elisp код использует. Таким образом, один вопрос был бы: используется ли defcustomдругой способ создания (настраиваемых) глобальных переменных?

Кто-нибудь может подсказать мне, как правильно использовать (сначала понять) всю идею позади defcustom, когда использовать, почему, когда нет? Может быть, начинающий пример для начинающих elisp.

147pm
источник
Не могли бы вы уточнить, что вы спрашиваете? Вы хотите знать, когда использовать customizeоборудование, а когда настраивать вручную? Или вы заинтересованы в написании режима? Последняя ситуация - это ситуация, в которой вы действительно можете использовать такие вещи defcustomи тому подобное.
Дан

Ответы:

20

Система настройки - это встроенная функция Emacs, предназначенная для точного решения проблемы, которую вы описываете, - программирование не может быть идеальным способом для обычного пользователя настроить свой редактор.

Основной точкой входа в функцию настройки является M-x customize RET(или Options > Customize Emacs > Top-level Customization Groupиз меню). Оттуда вы увидите интерактивную систему меню для настройки параметров. Этот интерфейс гарантирует, что все параметры имеют правильный тип (число, строка, цвет и т. Д.), Избегая основного источника ошибок, возникающих при программной настройке Emacs. Если пользователь решает сохранить какие-либо изменения, сделанные в пользовательском интерфейсе, настройки сохраняются в специальном разделе файла инициализации пользователя (читай:) .emacs.

defcustomэто обертка вокруг низкоуровневой функциональности Emacs Lisp, defvarкоторая объявляет переменную и делает ее видимой в интерфейсе настройки. Это также позволяет разработчику предоставлять дополнительные метаданные, необходимые для отображения соответствующего интерактивного элемента управления, т. Е. Какой тип значения хранится в этой переменной? Произвольная строка? Число? Выбор из фиксированного набора опций? и т.д. defgroup- это группирующая конструкция для этих настраиваемых параметров, так что они могут быть упорядочены в хорошую иерархию.

Эта функциональность должна использоваться каждый раз, когда часть данных должна рассматриваться как настраиваемая опция для пользователя, а не как внутренняя деталь библиотеки.

Вот простой пример, взятый из моей небольшой библиотеки:

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

defgroupСоздает новую группу в настройках интерфейса под верхним уровнем convenienceэлемента. Затем мне понадобилась переменная для хранения возможных состояний флажков. Я мог бы использовать defvar, но так как я хочу, чтобы это было легко настраиваемым, я решил использовать defcustom. :groupЧасть указывает на то, что он принадлежит к ранее определенной группе, и :typeуказывает на то, что она представляет собой последовательность строк. Там также значение по умолчанию и описание. Есть также дополнительные возможности (здесь не показаны) для преобразования значений, введенных пользователем.

Если я сейчас запустлю M-x customize RETи перейду к Convenience > Checkbox, я увижу следующее:

интерфейс настройки

Это не самый красивый интерфейс в мире, но обратите внимание, что он имеет интерактивные инструменты для настройки значения «Состояния флажков» ( checkbox-statesвнутри). Он показывает текущие строковые значения вместе с кнопками INS(вставка) и DEL(удаление) и позволяет нам редактировать строковые значения в полях редактирования. Когда мы закончим, мы можем решить, применять ли наши изменения, отменить их или применить и сохранить их для будущих сессий.

camdez
источник
2
Хороший пост! Наиболее существенными преимуществами пользовательской настройки (и defcustom) является то, что она автоматически заботится о : (1) проверке типов , чтобы помочь вам избежать присвоения неверного значения переменной (при условии, что автор defcustomприложил усилия для предоставления разумного типа) проверка), (2) инициализация ( :initialize) и обновление ction (запущено) ( :set).
Дрю
Благодарность! Я обновил пост, чтобы отразить ваши предложения.
Камдез
7

Является ли использование defcustom другим способом создания (настраиваемых) глобальных переменных?

Да. Особенно, если вы хотите, чтобы пользователи вашего кода могли легко изменять переменные через интерфейс настройки Mx .

defcustom предоставляет пользователям два важных преимущества: документация и безопасность типов. Документация это приятно иметь прямо там. Тип безопасности позволяет указать, какие виды допустимых значений могут принимать ваши переменные.

Конечно, defvar - это хорошо, если все, что вы делаете, это настраиваете для себя и не ожидаете более широкого использования. Тем не менее, некоторые скажут, что придерживаться defcustom насквозь - хорошая привычка для прививания.

Кто-нибудь может подсказать мне, как правильно использовать ...

Страница руководства для defcustom имеет дополнительные пояснения. Тема настроек в руководстве содержит полную информацию.

... когда использовать, почему, когда нет?

Лично я считаю defcustom менее громоздким во время разработки, так как мне не приходится сталкиваться с проблемами перезагрузки с помощью defvar и setq.

Пользователь Emacs
источник