Change tree widget text node
I wrote a piece of code that creates a tree widget:
(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))))
The resulting tree widget looks like this: the arguments :tag
become node labels:
[-] one
`-[+] two
Now I want to change the labels from my program, but setting the value :tag
with widget-put
will not change anything in the buffer. How can i do this?
source to share
For whatever reason, the tree widget's label node is stored as the first item in the property :children
, so you need to get that value and change its property :tag
, not a :tag
property of the tree widget itself.
After changing the property, :tag
you need to force the widget to refresh. You can do this with widget-value-set
. Since you don't actually want to change the value, just assign the same value again; it will still have the same widget redrawing effect.
For example, to update the top level node:
(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))))
This leads to:
[-] 12:39:19
`-[+] two
To update a child of a node, simply dig it out with a property :children
, keeping in mind that the first "child" is not strictly a child:
(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)))))
With this final result:
[-] 12:39:19
`-[+] 12:40:41
source to share