使用自定义缓冲区为函数提供参数

时间:2012-10-20 16:40:55

标签: emacs customization interactive

我需要用很多参数交互地调用一个函数(目前它是7,但它会增长)。连续阅读所有论点会产生糟糕的经历。例如,我要求用户输入类名。类名可以通过它所在的包完全限定。因此,如果用户认为它必须完全合格,然后我要求他们提供包名称,则用户无法返回并修复错误。

输入的许多方面也很难同时处理。例如,我需要确保某些字符没有出现在正在读取的字符串中的某个模式中。如果输入在输入的最后一项上未通过验证,则用户重新启动整个过程会感到沮丧,如果我有一个自定义缓冲区,我可以简单地阻止它们提交更改,如果它不验证并保持已经提交的良好值。

TL;博士

我正在寻找一种方法来打开自定义缓冲区并将用户输入读入一个以交互方式调用的函数。有办法吗?

1 个答案:

答案 0 :(得分:1)

我建议使用Emacs Widget Library而不是自定义缓冲区本身。 Emacs信息在Widget库中有一个很好的部分。您可以使用C-h i m Widget RET从emacs访问它。或者您可以访问HTML版本here。以下是手册中小部件示例的片段。

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