【问题标题】:When creating a customizable value with defcustom, how can I validate users' entries?使用 defcustom 创建可自定义的值时,如何验证用户的条目?
【发布时间】:2012-09-15 07:28:39
【问题描述】:

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

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

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

所以有小部件,它们有各种设置,我需要能够通过只知道小部件的短名称来访问小部件的任意设置。我想做某种验证功能(不幸的是,谷歌搜索“emacs defcustom validate”并没有帮助),这样如果用户在widget-pathswidget-colors 中输入不在widget-canonical-names 列表,他们得到一个“你确定吗?”警告并注意输入不匹配的名称。我可以将这样的验证功能附加到我的defcustoms 吗?如果是这样,它的语法是什么?

当然,理想的做法是让用户输入一次短名称,但我无法从“复合类型”elisp 文档中弄清楚如何做到这一点。因此,对我的问题的更好回答将告诉我如何安排一个defcustom 来设置类似于此 Python dict 的数据结构:

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",
                      },
     }

那么:我怎样才能获得我想要的行为,根据用于访问它们的数据对设置进行分组,或者当用户输入不一致的数据时验证功能在哪里警告用户?

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:

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

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

    【讨论】:

    • 如果它解决了您的问题,请随时接受答案。 :) 如果不明显,它解决了“理想的做法是让用户输入一次短名称”变体。
    • 我一直在等待接受它,直到我在上下文中尝试过它,我现在已经有了。它还帮助一些自定义文档对我有意义。谢谢。 :)
    • 嗯。生活充满挑战:这为我提供了我需要的数据结构,但代价是在 Customize 中看起来非常丑陋。我最好继续工作。
    • 自定义通常是这样的。 :) 有很多用于创建小部件的选项,而且文档非常稀少。我编辑了答案以使其更具吸引力,至少对我而言 - 看看你是否喜欢它。
    • 我注意到我的代码存在另一个问题:它要求规范名称、颜色和路径完全按照该顺序排列,这不符合您的 Python subdict 的精神,它是无序的。如果仅通过自定义添加值,这仍然有效,但如果有人以错误的顺序手动添加值,自定义将无法识别它。我现在已将其编辑为使用set,这对订单并不挑剔,但允许使用复选框留下一些项目,但我找不到删除的方法。除了复选框之外,它看起来与上一个版本非常相似。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多