Function: eca-chat--update-expandable-content
eca-chat--update-expandable-content is a natively compiled function
defined in eca-chat-expandable.el.
Signature
(eca-chat--update-expandable-content ID LABEL CONTENT &optional APPEND-CONTENT? PARENT-ID)
Documentation
Update to LABEL and CONTENT the expandable content of id ID.
If LABEL is nil, the existing label is preserved. If APPEND-CONTENT? is non-nil, append CONTENT to existing content. If PARENT-ID is provided and block doesn't exist yet, updates the spec in parent.
Source Code
;; Defined in /nix/store/jklqzw6pzz6j4jrbv8wy0iwgi7jlrbld-emacs-packages-deps/share/emacs/site-lisp/elpa/eca-20260928.1827/eca-chat-expandable.el
(defun eca-chat--update-expandable-content (id label content &optional append-content? parent-id)
"Update to LABEL and CONTENT the expandable content of id ID.
If LABEL is nil, the existing label is preserved.
If APPEND-CONTENT? is non-nil, append CONTENT to existing content.
If PARENT-ID is provided and block doesn't exist yet, updates the spec
in parent."
(if-let* ((ov-label (eca-chat--get-expandable-content id)))
;; Block exists (rendered), update it directly
(let* ((ov-content (overlay-get ov-label 'eca-chat--expandable-content-ov-content))
(nested? (overlay-get ov-label 'eca-chat--expandable-content-nested))
(indent (if nested?
eca-chat--expandable-content-nested-indent
eca-chat--expandable-content-base-indent))
(existing (overlay-get ov-content 'eca-chat--expandable-content-content))
(delta (propertize content 'line-prefix indent))
(new-content (if append-content?
(concat existing delta)
delta))
(open? (overlay-get ov-label 'eca-chat--expandable-content-toggle)))
(overlay-put ov-content 'eca-chat--expandable-content-content new-content)
(save-excursion
(when label
;; Update stored icons when the label face changes
(let* ((new-icon-face (get-text-property 0 'font-lock-face label))
(label-indent (when nested? eca-chat--expandable-content-base-indent))
(new-icons (eca-chat--make-expandable-icons new-icon-face label-indent)))
(overlay-put ov-label 'eca-chat--expandable-content-open-icon (car new-icons))
(overlay-put ov-label 'eca-chat--expandable-content-close-icon (cdr new-icons)))
(let* ((children (eca-chat--segments-children
(overlay-get ov-label 'eca-chat--expandable-content-segments)))
(has-content? (or (not (string-empty-p new-content)) children))
(label-prefix (cond
(has-content?
(if open?
(overlay-get ov-label 'eca-chat--expandable-content-close-icon)
(overlay-get ov-label 'eca-chat--expandable-content-open-icon)))
(nested?
(concat eca-chat--expandable-content-base-indent
(make-string (length eca-chat-expandable-block-open-symbol) ?\s)))))
(label-start (overlay-start ov-label))
(label-end (1- (overlay-start ov-content)))
(cur-prefix (get-text-property label-start 'line-prefix)))
;; Skip the delete/re-insert when the rendered label is
;; already up to date; frequent while toolCallPrepare
;; streams argsText updates (#268).
(unless (and (string= (substring-no-properties label)
(buffer-substring-no-properties label-start label-end))
(equal (get-text-property 0 'font-lock-face label)
(get-text-property label-start 'font-lock-face))
(equal (and (stringp label-prefix) (substring-no-properties label-prefix))
(and (stringp cur-prefix) (substring-no-properties cur-prefix))))
(goto-char label-start)
(delete-region (point) label-end)
(eca-chat--insert (propertize (eca-chat--propertize-only-first-word label
'line-prefix label-prefix)
'help-echo "mouse-1 / RET / tab: expand/collapse"))
;; Repaint nested label's line-prefix after label replacement
(eca-chat--paint-nested-label ov-label))))
(when open?
(let ((block-face (overlay-get ov-content 'face)))
(if append-content?
(let ((insert-start (overlay-end ov-content)))
(goto-char insert-start)
(eca-chat--insert delta)
(when block-face
(eca-chat--apply-face-to-line-prefixes
insert-start (overlay-end ov-content) block-face)))
(progn
(delete-region (overlay-start ov-content) (overlay-end ov-content))
(goto-char (overlay-start ov-content))
(eca-chat--insert new-content)
(when block-face
(eca-chat--apply-face-to-line-prefixes
(overlay-start ov-content) (overlay-end ov-content) block-face)))))))
;; When nested, sync updated label/content back to parent's child spec
;; so that toggling the parent closed and reopened preserves latest state
(when nested?
(when-let* ((parent-id (overlay-get ov-label 'eca-chat--expandable-content-parent-id))
(parent-ov (eca-chat--get-expandable-content parent-id))
(segments (overlay-get parent-ov 'eca-chat--expandable-content-segments))
(spec (-first (lambda (s) (and (eq 'child (plist-get s :type))
(string= id (plist-get s :id))))
segments)))
(when label (plist-put spec :label label))
(plist-put spec :content new-content))))
;; Block not rendered yet
(if parent-id
;; Nested: update spec in parent
(when-let* ((parent-ov (eca-chat--get-expandable-content parent-id)))
(let* ((segments (overlay-get parent-ov 'eca-chat--expandable-content-segments))
(existing-spec (-first (lambda (spec) (and (eq 'child (plist-get spec :type))
(string= id (plist-get spec :id))))
segments)))
(if existing-spec
(let* ((old-content (plist-get existing-spec :content))
(new-content (if append-content?
(concat old-content content)
content)))
(when label
(plist-put existing-spec :label label)
(plist-put existing-spec :icon-face (get-text-property 0 'font-lock-face label)))
(plist-put existing-spec :content new-content))
(let ((child-spec (list :type 'child :id id :label label :content content
:icon-face (get-text-property 0 'font-lock-face label))))
(overlay-put parent-ov 'eca-chat--expandable-content-segments
(append segments (list child-spec)))
(when (overlay-get parent-ov 'eca-chat--expandable-content-toggle)
(eca-chat--render-nested-block parent-ov child-spec))))))
;; Top-level: create the block so toolCallRun et al. don't
;; silently lose content when no toolCallPrepare preceded them.
(eca-chat--add-expandable-content id label (or content "")))))