【问题标题】:Use customization buffer to supply arguments to a function使用自定义缓冲区为函数提供参数
【发布时间】:2012-10-20 16:40:54
【问题描述】:
我需要使用很多参数交互调用一个函数(目前是 7,但它会增长)。连续阅读所有论点会产生糟糕的体验。例如,我要求用户输入一个类名。类名可以由它所在的包完全限定。所以如果用户认为它必须是完全合格的,然后我稍后要求他们提供包名,那么用户就没有办法回去修复错误了。
输入的许多方面也很难同时处理。例如,我需要确保某些字符不会以某种模式出现在正在读取的字符串等中。如果输入的最后一项验证失败,用户重新启动整个过程会感到沮丧,而如果我有一个自定义缓冲区可供我使用,我可以简单地阻止他们提交更改,如果它没有验证并保留已经提交的良好值。
tl;博士
我正在寻找一种方法来打开自定义缓冲区并将用户输入读入以交互方式调用的函数。有什么办法吗?
【问题讨论】:
标签:
emacs
customization
interactive
【解决方案1】:
我建议使用 Emacs Widget Library 而不是自定义缓冲区本身。 Emacs info 在 Widget Library 上有一个很棒的部分。您可以使用 C-h i m Widget RET 从 emacs 访问它。或者您可以访问 HTML 版本here。这是手册中小部件示例的 sn-p。
(require 'widget)
(eval-when-compile
(require 'wid-edit))
(defvar widget-example-repeat)
(defun widget-example ()
"Create the widgets from the Widget manual."
(interactive)
(switch-to-buffer "*Widget Example*")
(kill-all-local-variables)
(make-local-variable 'widget-example-repeat)
(let ((inhibit-read-only t))
(erase-buffer))
(remove-overlays)
(widget-insert "Here is some documentation.\n\n")
(widget-create 'editable-field
:size 13
:format "Name: %v " ; Text after the field!
"My Name")
(widget-create 'menu-choice
:tag "Choose"
:value "This"
:help-echo "Choose me, please!"
:notify (lambda (widget &rest ignore)
(message "%s is a good choice!"
(widget-value widget)))
'(item :tag "This option" :value "This")
'(choice-item "That option")
'(editable-field :menu-tag "No option" "Thus option"))
(widget-create 'editable-field
:format "Address: %v"
"Some Place\nIn some City\nSome country.")
(widget-insert "\nSee also ")
(widget-create 'link
:notify (lambda (&rest ignore)
(widget-value-set widget-example-repeat
'("En" "To" "Tre"))
(widget-setup))
"other work")
(widget-insert
" for more information.\n\nNumbers: count to three below\n")
(setq widget-example-repeat
(widget-create 'editable-list
:entry-format "%i %d %v"
:notify (lambda (widget &rest ignore)
(let ((old (widget-get widget
':example-length))
(new (length (widget-value widget))))
(unless (eq old new)
(widget-put widget ':example-length new)
(message "You can count to %d." new))))
:value '("One" "Eh, two?" "Five!")
'(editable-field :value "three")))
(widget-insert "\n\nSelect multiple:\n\n")
(widget-create 'checkbox t)
(widget-insert " This\n")
(widget-create 'checkbox nil)
(widget-insert " That\n")
(widget-create 'checkbox
:notify (lambda (&rest ignore) (message "Tickle"))
t)
(widget-insert " Thus\n\nSelect one:\n\n")
(widget-create 'radio-button-choice
:value "One"
:notify (lambda (widget &rest ignore)
(message "You selected %s"
(widget-value widget)))
'(item "One") '(item "Another One.") '(item "A Final One."))
(widget-insert "\n")
(widget-create 'push-button
:notify (lambda (&rest ignore)
(if (= (length (widget-value widget-example-repeat))
3)
(message "Congratulation!")
(error "Three was the count!")))
"Apply Form")
(widget-insert " ")
(widget-create 'push-button
:notify (lambda (&rest ignore)
(widget-example))
"Reset Form")
(widget-insert "\n")
(use-local-map widget-keymap)
(widget-setup))