使用defcustom创建可自定义值时,如何验证用户的输入?

Bri*_*ell 5 emacs elisp

我正在编写一个将演变为软件包的elisp文件,因此将其某些变量转换为defcustom语句并进行了文档记录。其中一些defcustom变量是相关的,我想验证通过Customize系统输入的值,以确保关系成立。

这是我所拥有的一个例子:

(defcustom widget-canonical-names '("my_widget" . "widget_assembly 8911_j4")
  "Documentation"
  :type '(alist :key-type (string :tag "Widget's short name")
                :value-type (string :tag "Full widget name"))
  :risky nil
  :group 'widgets)
(defcustom widget-colors '("my_widget" . "brown")
  "Documentation"
  :type '(alist :key-type (string :tag "Widget's short name")
                :value-type (color :tag "color of the widget"))
  :risky nil
  :group 'widgets)
(defcustom widget-paths '("my_widget" . "~/widgets")
  "Documentation"
  :type '(alist :key-type (string :tag "Widget's short name")
                :value-type (directory :tag "support files for widget"))
  :risky nil
  :group 'widgets)
Run Code Online (Sandbox Code Playgroud)

因此,有一些小部件,它们具有各种设置,并且我需要能够仅知道小部件的简称来访问小部件的任意设置。我想制作某种验证功能(不幸的是,四处寻找“ emacs defcustom validate”并没有帮助),以便如果用户在列表中输入widget-paths或未widget-colorswidget-canonical-names列表中输入小部件名称,他们将获得“你确定吗?” 警告,请注意输入不匹配的名称。我可以将这样的验证功能附加到我的defcustoms吗?如果是这样,它的语法是什么?

当然,理想的情况是只让用户输入一次短名称,但是我无法从elisp文档“ Composite Types”中弄清楚该怎么做。因此,对我的问题的更好回答将告诉我如何安排一个defcustom建立类似于此Python字典的数据结构的方法:

customized_widgets = {
    "my_widget": { "canonical_name": "widget_assembly 8911_j4",
                   "widget_color": "brown",
                   "widget_path": "~/widgets",
                 },
    "another_widget": { "canonical_name" : "widget_obsolete 11.0",
                        "widget_color": "blue",
                        "widget_path": "~/blue_widgets",
                      },
     }
Run Code Online (Sandbox Code Playgroud)

因此:如何获得所需的行为,根据要用来访问它们的数据对设置进行分组,或者在用户输入可能不一致的数据时通过验证功能警告用户?

use*_*342 5

这将定义与该Python结构最接近的Emacs等价物,将字典表示为列表,将内部字典的固定键表示为符号。

(defcustom my-customized-widgets ()
  "My widget customization alist"
  :type '(alist
          :tag "Widgets"
          :key-type (string :tag "Short name")
          :value-type
          (set
           :format "%v"
           :entry-format "%b %v"
           (cons :format "%v"
                 (const :format "" widget-canonical-name)
                 (string :tag "CName"))
           (cons :format "%v"
                 (const :format "" widget-color)
                 (color :tag "Color"))
           (cons :format "%v"
                 (const :format "" widget-path)
                 (directory :tag " Path"))))
  :group 'widgets)
Run Code Online (Sandbox Code Playgroud)

  • 我注意到了我的代码的另一个问题:它要求规范名称,颜色和路径必须完全按照该顺序排列,这与您的Python订阅者的精神(即无序)不符。如果仅通过定制添加值,则仍然可以使用,但是如果有人以错误的顺序手动添加了值,定制将无法识别它。我现在已经对其进行了编辑以使用`set`,它对订单并不挑剔,但是允许将某些项目留在复选框之外,而我找不到删除该复选框的方法。除了复选框以外,它看起来与上一个版本非常相似。 (2认同)