更改树小部件节点的文本

时间:2014-08-03 11:41:34

标签: emacs elisp

我写了一段代码来创建一个树小部件:

(require 'tree-widget)

(defun my-create-tree-widget ()
  (interactive)
  (with-current-buffer (get-buffer-create "*my-tree-widget*")
    (setq-local my-tree-widget
        (widget-create
         'tree-widget
         :open t
         :tag "one"
         :args
         (list (widget-convert
            'tree-widget
            :tag "two"
            :args (mapcar (apply-partially #'widget-convert 'item)
                      '("three" "four"))))))
    (switch-to-buffer (current-buffer))))

生成的树窗口小部件如下所示,:tag个参数成为节点的标签:

[-] one
 `-[+] two

现在我想更改程序中的标签,但将:tag值设置为widget-put并不会更改缓冲区中的任何内容。我怎么能做到这一点?

1 个答案:

答案 0 :(得分:2)

由于某种原因,树窗口小部件节点的标签存储为:children属性中的第一个元素,因此您需要检索该值,并更改其:tag属性,而不是{ {1}}树小部件本身的属性。

更改:tag属性后,您需要强制更新小部件。您可以使用:tag执行此操作。由于您实际上并不想更改该值,因此只需重新分配相同的值即可;它仍然具有重绘窗口小部件的相同效果。

例如,要更新顶级节点:

widget-value-set

这导致:

(defun my-change-tree-widget-first-level ()
  (interactive)
  (let ((node (car (widget-get my-tree-widget :children))))
    (widget-put node :tag (format-time-string "%T"))
    ;; Redraw
    (widget-value-set node (widget-value node))))

要更新子节点,只需使用[-] 12:39:19 `-[+] two 属性进行挖掘,同时记住第一个" child"元素严格来说不是一个孩子:

:children

有了这个最终结果:

(defun my-change-tree-widget-second-level ()
  (interactive)
  (let ((second-level (cadr (widget-get my-tree-widget :children))))
    (unless (tree-widget-p second-level)
      (error "This is not the tree widget"))
    (let ((node (car (widget-get second-level :children))))
      (widget-put node :tag (format-time-string "%T"))
      ;; Redraw
      (widget-value-set node (widget-value node)))))