Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to do proper DOM manipulation? #801

Closed
Townk opened this issue Apr 12, 2021 · 6 comments
Closed

How to do proper DOM manipulation? #801

Townk opened this issue Apr 12, 2021 · 6 comments

Comments

@Townk
Copy link

Townk commented Apr 12, 2021

This is a question / doc request for those, like me, that use Treemacs extension API on their own package.

My first package to use Treemacs is org-ol-tree, which tries to display an Org buffer as an Outline tree on a side window.

The basic tree building, expanding, collapsing, and renaming all work just fine, and I could not be happier.

My problem started when I tried to implement a feature that allow users to "move" headlines around, like they would do on and actual Org file. The org part of the feature works without any problem, but I can't get the Treemacs API to work as I expected!

For instance, when I'm on a headline and I press M-left, my package promotes the headline on the Org buffer, and tries to do the same on the tree. What I tried to do, was to erase the tree buffer, and rebuild the tree with the updated version of the Org buffer. This seams to work as the tree gets updated, but I can't navigate to the correct position, so the tree ultimately stays collapsed.

This is a gif showing the current behavior:

CleanShot 2021-04-11 at 22 57 58

The relevant function on my package is the refresh, which I'm reproducing here:

(defun org-ol-tree-action--refresh (&optional prevent-rebuild target-section-id target-state)
  "Refresh the Outline tree.

If PREVENT-REBUILD is non nil, this function just refresh the buffer content
without refreshing the base data.

If TARGET-SECTION-ID is not nil, uses it instead of the current headline id.

If TARGET-STATE is not nil, use it instead of the one on the current headline."
  (interactive)

  (when org-ol-tree--buffer-p
    (let* ((headline (org-ol-tree-core--current-headline))
           (target-section-id (or target-section-id (when headline
                                                      (org-ol-tree-core--headline-id headline))))
           (target-state (or target-state
                             (org-ol-tree-core--state (org-ol-tree-core--node-get :state)))))

      (unless prevent-rebuild
        (org-ol-tree-ui--build-outline-tree))

      (org-ol-tree-action--goto-root)
      (org-ol-tree-core--collapse)
      (org-ol-tree-action--goto-setion target-section-id target-state)
      (message "Refresh completed"))))

You can see this function on my refactor branch here.

So, my question/request is this:

How to manipulate the tree structure on Treemacs, update it, and save/restore node position correctly?

@Townk
Copy link
Author

Townk commented Apr 12, 2021

I forgot to mention, that after I refresh the tree couple times, I start getting errors on Treemacs functions:

Debugger entered--Lisp error: (void-function nil)
  nil(#<marker (moves after insertion) at 59 in *OrgOutlineTree:org-ol-tree/README.org*>)
  treemacs--reopen-node(#<marker (moves after insertion) at 59 in *OrgOutlineTree:org-ol-tree/README.org*> nil)
  treemacs--reentry((:custom root "1"))
  (progn (let* ((key (get-text-property node :path))) (let ((dom-node (gethash key treemacs-dom nil))) (if dom-node (progn (let* ((v dom-node)) (aset v 5 node)) (let ((--dolist-tail-- ...)) (while --dolist-tail-- (let ... ... ...))) (let ((parent-dom-node ...)) (if parent-dom-node (progn ...)))) (setq dom-node (record 'treemacs-dom-node key nil nil nil node nil nil)) (prog1 nil (puthash (progn (progn ...)) dom-node treemacs-dom))))) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize))
  (let (buffer-read-only) (put-text-property (or (previous-single-property-change (1+ node) 'button) (point-min)) (or (next-single-property-change node 'button) (point-max)) :state 'treemacs-org-ol-parent-section-open-state) (beginning-of-line) (let* ((new-sym (org-ol-tree-ui--section-icon (org-ol-tree-core--node-get :headline node) 'expanded))) (save-excursion (let ((len (length new-sym))) (goto-char (- (let* (...) (or ... ...)) len)) (insert new-sym) (delete-char len)))) (goto-char (or (next-single-property-change node 'button) (point-max))) (progn (insert (apply #'concat (let* ((depth depth) (prefix (concat "\n" ...)) (item (car items)) (strings)) (if item (progn (let ... ...))) (nreverse strings))))) (progn (let* ((key (get-text-property node :path))) (let ((dom-node (gethash key treemacs-dom nil))) (if dom-node (progn (let* (...) (aset v 5 node)) (let (...) (while --dolist-tail-- ...)) (let (...) (if parent-dom-node ...))) (setq dom-node (record 'treemacs-dom-node key nil nil nil node nil nil)) (prog1 nil (puthash (progn ...) dom-node treemacs-dom))))) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize)))
  (let* ((p (point))) (let (buffer-read-only) (put-text-property (or (previous-single-property-change (1+ node) 'button) (point-min)) (or (next-single-property-change node 'button) (point-max)) :state 'treemacs-org-ol-parent-section-open-state) (beginning-of-line) (let* ((new-sym (org-ol-tree-ui--section-icon (org-ol-tree-core--node-get :headline node) 'expanded))) (save-excursion (let ((len (length new-sym))) (goto-char (- (let* ... ...) len)) (insert new-sym) (delete-char len)))) (goto-char (or (next-single-property-change node 'button) (point-max))) (progn (insert (apply #'concat (let* ((depth depth) (prefix ...) (item ...) (strings)) (if item (progn ...)) (nreverse strings))))) (progn (let* ((key (get-text-property node :path))) (let ((dom-node (gethash key treemacs-dom nil))) (if dom-node (progn (let* ... ...) (let ... ...) (let ... ...)) (setq dom-node (record ... key nil nil nil node nil nil)) (prog1 nil (puthash ... dom-node treemacs-dom))))) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize))) (count-lines p (point)))
  (save-excursion (let* ((p (point))) (let (buffer-read-only) (put-text-property (or (previous-single-property-change (1+ node) 'button) (point-min)) (or (next-single-property-change node 'button) (point-max)) :state 'treemacs-org-ol-parent-section-open-state) (beginning-of-line) (let* ((new-sym (org-ol-tree-ui--section-icon (org-ol-tree-core--node-get :headline node) 'expanded))) (save-excursion (let ((len ...)) (goto-char (- ... len)) (insert new-sym) (delete-char len)))) (goto-char (or (next-single-property-change node 'button) (point-max))) (progn (insert (apply #'concat (let* (... ... ... ...) (if item ...) (nreverse strings))))) (progn (let* ((key (get-text-property node :path))) (let ((dom-node ...)) (if dom-node (progn ... ... ...) (setq dom-node ...) (prog1 nil ...)))) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize))) (count-lines p (point))))
  (prog1 (save-excursion (let* ((p (point))) (let (buffer-read-only) (put-text-property (or (previous-single-property-change (1+ node) 'button) (point-min)) (or (next-single-property-change node 'button) (point-max)) :state 'treemacs-org-ol-parent-section-open-state) (beginning-of-line) (let* ((new-sym (org-ol-tree-ui--section-icon ... ...))) (save-excursion (let (...) (goto-char ...) (insert new-sym) (delete-char len)))) (goto-char (or (next-single-property-change node 'button) (point-max))) (progn (insert (apply #'concat (let* ... ... ...)))) (progn (let* ((key ...)) (let (...) (if dom-node ... ... ...))) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize))) (count-lines p (point)))) (if treemacs-move-forward-on-expand (progn (let* ((parent (let (...) (if result ...))) (child (next-button parent))) (if (equal parent (get-text-property child :parent)) (progn (forward-line 1)))))))
  (let ((items (reverse (org-ol-tree-core--headline-children (org-ol-tree-core--node-get :headline node)))) (depth (1+ (get-text-property node :depth))) (parent-dom-node (let* ((key (get-text-property node :path))) (gethash key treemacs-dom nil)))) (prog1 (save-excursion (let* ((p (point))) (let (buffer-read-only) (put-text-property (or (previous-single-property-change ... ...) (point-min)) (or (next-single-property-change node ...) (point-max)) :state 'treemacs-org-ol-parent-section-open-state) (beginning-of-line) (let* ((new-sym ...)) (save-excursion (let ... ... ... ...))) (goto-char (or (next-single-property-change node ...) (point-max))) (progn (insert (apply ... ...))) (progn (let* (...) (let ... ...)) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize))) (count-lines p (point)))) (if treemacs-move-forward-on-expand (progn (let* ((parent (let ... ...)) (child (next-button parent))) (if (equal parent (get-text-property child :parent)) (progn (forward-line 1))))))))
  treemacs--do-expand-org-ol-parent-section(#<marker (moves after insertion) at 31 in *OrgOutlineTree:org-ol-tree/README.org*>)
  (let* ((node (let ((result (text-property-not-all (point-at-bol) (point-at-eol) 'button nil))) (if result (progn (copy-marker result t)))))) (if (null node) (progn (throw '--cl-block-__body__-- (treemacs-pulse-on-failure "There is nothing to do here.")))) (if (not (eq 'treemacs-org-ol-parent-section-closed-state (get-text-property node :state))) (progn (throw '--cl-block-__body__-- (treemacs-pulse-on-failure "This function cannot expand a node of type '%s'." (propertize (format "%s" (get-text-property node :state)) 'face 'font-lock-type-face))))) (treemacs--do-expand-org-ol-parent-section node))
  (catch '--cl-block-__body__-- (let* ((node (let ((result (text-property-not-all ... ... ... nil))) (if result (progn (copy-marker result t)))))) (if (null node) (progn (throw '--cl-block-__body__-- (treemacs-pulse-on-failure "There is nothing to do here.")))) (if (not (eq 'treemacs-org-ol-parent-section-closed-state (get-text-property node :state))) (progn (throw '--cl-block-__body__-- (treemacs-pulse-on-failure "This function cannot expand a node of type '%s'." (propertize (format "%s" ...) 'face 'font-lock-type-face))))) (treemacs--do-expand-org-ol-parent-section node)))
  treemacs-expand-org-ol-parent-section(#<marker (moves after insertion) at 31 in *OrgOutlineTree:org-ol-tree/README.org*>)
  treemacs--reopen-node(#<marker (moves after insertion) at 31 in *OrgOutlineTree:org-ol-tree/README.org*> nil)
  treemacs--reentry((:custom root))
  (progn (let* ((key (get-text-property node :path))) (let ((dom-node (gethash key treemacs-dom nil))) (if dom-node (progn (let* ((v dom-node)) (aset v 5 node)) (let ((--dolist-tail-- ...)) (while --dolist-tail-- (let ... ... ...))) (let ((parent-dom-node ...)) (if parent-dom-node (progn ...)))) (setq dom-node (record 'treemacs-dom-node key nil nil nil node nil nil)) (prog1 nil (puthash (progn (progn ...)) dom-node treemacs-dom))))) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize))
  (let (buffer-read-only) (put-text-property (or (previous-single-property-change (1+ node) 'button) (point-min)) (or (next-single-property-change node 'button) (point-max)) :state 'treemacs-org-ol-doc-open-state) (beginning-of-line) (save-excursion (let ((len (length treemacs-icon-org-ol-doc-open))) (goto-char (- (let* ((button ...)) (or (previous-single-property-change ... ...) (point-min))) len)) (insert treemacs-icon-org-ol-doc-open) (delete-char len))) (goto-char (or (next-single-property-change node 'button) (point-max))) (progn (insert (apply #'concat (let* ((depth depth) (prefix (concat "\n" ...)) (item (car items)) (strings)) (if item (progn (let ... ...))) (nreverse strings))))) (progn (let* ((key (get-text-property node :path))) (let ((dom-node (gethash key treemacs-dom nil))) (if dom-node (progn (let* (...) (aset v 5 node)) (let (...) (while --dolist-tail-- ...)) (let (...) (if parent-dom-node ...))) (setq dom-node (record 'treemacs-dom-node key nil nil nil node nil nil)) (prog1 nil (puthash (progn ...) dom-node treemacs-dom))))) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize)))
  (let* ((p (point))) (let (buffer-read-only) (put-text-property (or (previous-single-property-change (1+ node) 'button) (point-min)) (or (next-single-property-change node 'button) (point-max)) :state 'treemacs-org-ol-doc-open-state) (beginning-of-line) (save-excursion (let ((len (length treemacs-icon-org-ol-doc-open))) (goto-char (- (let* (...) (or ... ...)) len)) (insert treemacs-icon-org-ol-doc-open) (delete-char len))) (goto-char (or (next-single-property-change node 'button) (point-max))) (progn (insert (apply #'concat (let* ((depth depth) (prefix ...) (item ...) (strings)) (if item (progn ...)) (nreverse strings))))) (progn (let* ((key (get-text-property node :path))) (let ((dom-node (gethash key treemacs-dom nil))) (if dom-node (progn (let* ... ...) (let ... ...) (let ... ...)) (setq dom-node (record ... key nil nil nil node nil nil)) (prog1 nil (puthash ... dom-node treemacs-dom))))) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize))) (count-lines p (point)))
  (save-excursion (let* ((p (point))) (let (buffer-read-only) (put-text-property (or (previous-single-property-change (1+ node) 'button) (point-min)) (or (next-single-property-change node 'button) (point-max)) :state 'treemacs-org-ol-doc-open-state) (beginning-of-line) (save-excursion (let ((len (length treemacs-icon-org-ol-doc-open))) (goto-char (- (let* ... ...) len)) (insert treemacs-icon-org-ol-doc-open) (delete-char len))) (goto-char (or (next-single-property-change node 'button) (point-max))) (progn (insert (apply #'concat (let* (... ... ... ...) (if item ...) (nreverse strings))))) (progn (let* ((key (get-text-property node :path))) (let ((dom-node ...)) (if dom-node (progn ... ... ...) (setq dom-node ...) (prog1 nil ...)))) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize))) (count-lines p (point))))
  (prog1 (save-excursion (let* ((p (point))) (let (buffer-read-only) (put-text-property (or (previous-single-property-change (1+ node) 'button) (point-min)) (or (next-single-property-change node 'button) (point-max)) :state 'treemacs-org-ol-doc-open-state) (beginning-of-line) (save-excursion (let ((len ...)) (goto-char (- ... len)) (insert treemacs-icon-org-ol-doc-open) (delete-char len))) (goto-char (or (next-single-property-change node 'button) (point-max))) (progn (insert (apply #'concat (let* ... ... ...)))) (progn (let* ((key ...)) (let (...) (if dom-node ... ... ...))) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize))) (count-lines p (point)))) (if treemacs-move-forward-on-expand (progn (let* ((parent (let (...) (if result ...))) (child (next-button parent))) (if (equal parent (get-text-property child :parent)) (progn (forward-line 1)))))))
  (let ((items (reverse (org-ol-tree-core--headline-children (org-ol-tree-core--node-get :headline node)))) (depth (1+ (get-text-property node :depth))) (parent-dom-node (let* ((key (get-text-property node :path))) (gethash key treemacs-dom nil)))) (prog1 (save-excursion (let* ((p (point))) (let (buffer-read-only) (put-text-property (or (previous-single-property-change ... ...) (point-min)) (or (next-single-property-change node ...) (point-max)) :state 'treemacs-org-ol-doc-open-state) (beginning-of-line) (save-excursion (let (...) (goto-char ...) (insert treemacs-icon-org-ol-doc-open) (delete-char len))) (goto-char (or (next-single-property-change node ...) (point-max))) (progn (insert (apply ... ...))) (progn (let* (...) (let ... ...)) (treemacs--reentry (get-text-property node :path)) (org-ol-tree-ui--window-resize))) (count-lines p (point)))) (if treemacs-move-forward-on-expand (progn (let* ((parent (let ... ...)) (child (next-button parent))) (if (equal parent (get-text-property child :parent)) (progn (forward-line 1))))))))
  treemacs--do-expand-org-ol-doc(#<marker (moves after insertion) at 5 in *OrgOutlineTree:org-ol-tree/README.org*>)
  (let* ((node (let ((result (text-property-not-all (point-at-bol) (point-at-eol) 'button nil))) (if result (progn (copy-marker result t)))))) (if (null node) (progn (throw '--cl-block-__body__-- (treemacs-pulse-on-failure "There is nothing to do here.")))) (if (not (eq 'treemacs-org-ol-doc-closed-state (get-text-property node :state))) (progn (throw '--cl-block-__body__-- (treemacs-pulse-on-failure "This function cannot expand a node of type '%s'." (propertize (format "%s" (get-text-property node :state)) 'face 'font-lock-type-face))))) (treemacs--do-expand-org-ol-doc node))
  (catch '--cl-block-__body__-- (let* ((node (let ((result (text-property-not-all ... ... ... nil))) (if result (progn (copy-marker result t)))))) (if (null node) (progn (throw '--cl-block-__body__-- (treemacs-pulse-on-failure "There is nothing to do here.")))) (if (not (eq 'treemacs-org-ol-doc-closed-state (get-text-property node :state))) (progn (throw '--cl-block-__body__-- (treemacs-pulse-on-failure "This function cannot expand a node of type '%s'." (propertize (format "%s" ...) 'face 'font-lock-type-face))))) (treemacs--do-expand-org-ol-doc node)))
  treemacs-expand-org-ol-doc()
  (let nil (treemacs-expand-org-ol-doc))
  (cond ((eq val 'treemacs-org-ol-doc-closed-state) (let nil (treemacs-expand-org-ol-doc))) ((eq val 'treemacs-org-ol-parent-section-closed-state) (let nil (treemacs-expand-org-ol-parent-section))))
  (let* ((val (org-ol-tree-core--node-get :state node))) (cond ((eq val 'treemacs-org-ol-doc-closed-state) (let nil (treemacs-expand-org-ol-doc))) ((eq val 'treemacs-org-ol-parent-section-closed-state) (let nil (treemacs-expand-org-ol-parent-section)))))
  org-ol-tree-core--expand()
  (let (buffer-read-only) (erase-buffer) (treemacs-ORG-OL-DOC-extension) (org-ol-tree-core--node-put :headline (org-ol-tree-core--create-dom) (org-ol-tree-core--root-node)) (org-ol-tree-core--expand) (save-excursion (goto-char (point-max)) (insert "\n")))
  (save-current-buffer (set-buffer buffer) (let (buffer-read-only) (erase-buffer) (treemacs-ORG-OL-DOC-extension) (org-ol-tree-core--node-put :headline (org-ol-tree-core--create-dom) (org-ol-tree-core--root-node)) (org-ol-tree-core--expand) (save-excursion (goto-char (point-max)) (insert "\n"))))
  (let ((buffer (if org-ol-tree--buffer-p (current-buffer) org-ol-tree--buffer))) (if buffer nil (user-error "Cannot rebuild the Outline tree from an unrelated ...")) (save-current-buffer (set-buffer buffer) (let (buffer-read-only) (erase-buffer) (treemacs-ORG-OL-DOC-extension) (org-ol-tree-core--node-put :headline (org-ol-tree-core--create-dom) (org-ol-tree-core--root-node)) (org-ol-tree-core--expand) (save-excursion (goto-char (point-max)) (insert "\n")))))
  org-ol-tree-ui--build-outline-tree()
  (if prevent-rebuild nil (org-ol-tree-ui--build-outline-tree))
  (let* ((headline (org-ol-tree-core--current-headline)) (target-section-id (or target-section-id (if headline (progn (org-ol-tree-core--headline-id headline))))) (target-state (or target-state (org-ol-tree-core--state (org-ol-tree-core--node-get :state))))) (if prevent-rebuild nil (org-ol-tree-ui--build-outline-tree)) (org-ol-tree-action--goto-root) (org-ol-tree-core--collapse) (org-ol-tree-action--goto-setion target-section-id target-state) (message "Refresh completed"))
  (progn (let* ((headline (org-ol-tree-core--current-headline)) (target-section-id (or target-section-id (if headline (progn (org-ol-tree-core--headline-id headline))))) (target-state (or target-state (org-ol-tree-core--state (org-ol-tree-core--node-get :state))))) (if prevent-rebuild nil (org-ol-tree-ui--build-outline-tree)) (org-ol-tree-action--goto-root) (org-ol-tree-core--collapse) (org-ol-tree-action--goto-setion target-section-id target-state) (message "Refresh completed")))
  (if org-ol-tree--buffer-p (progn (let* ((headline (org-ol-tree-core--current-headline)) (target-section-id (or target-section-id (if headline (progn ...)))) (target-state (or target-state (org-ol-tree-core--state (org-ol-tree-core--node-get :state))))) (if prevent-rebuild nil (org-ol-tree-ui--build-outline-tree)) (org-ol-tree-action--goto-root) (org-ol-tree-core--collapse) (org-ol-tree-action--goto-setion target-section-id target-state) (message "Refresh completed"))))
  org-ol-tree-action--refresh(nil "2")
  (progn (save-current-buffer (set-buffer org-ol-tree--org-buffer) (save-excursion (goto-char headline-point) (if promote-tree (org-promote-subtree) (org-promote)))) (org-ol-tree-action--refresh nil target-id))
  (if (> headline-level 1) (progn (save-current-buffer (set-buffer org-ol-tree--org-buffer) (save-excursion (goto-char headline-point) (if promote-tree (org-promote-subtree) (org-promote)))) (org-ol-tree-action--refresh nil target-id)))
  (let* ((headline (org-ol-tree-core--current-headline)) (headline-point (org-ol-tree-core--headline-marker headline)) (headline-id (org-ol-tree-core--headline-id headline)) (headline-level (org-ol-tree-core--headline-level headline)) (parent (org-ol-tree-core--headline-parent headline)) (parent-level (if parent (org-ol-tree-core--headline-level parent) 0)) (target-id (org-ol-tree-core--section-string (if (> (- headline-level parent-level) 1) (cdr (org-ol-tree-core--section-from-string headline-id)) (org-ol-tree-core--next-section headline-id (1- headline-level)))))) (if (> headline-level 1) (progn (save-current-buffer (set-buffer org-ol-tree--org-buffer) (save-excursion (goto-char headline-point) (if promote-tree (org-promote-subtree) (org-promote)))) (org-ol-tree-action--refresh nil target-id))))
  (progn (let* ((headline (org-ol-tree-core--current-headline)) (headline-point (org-ol-tree-core--headline-marker headline)) (headline-id (org-ol-tree-core--headline-id headline)) (headline-level (org-ol-tree-core--headline-level headline)) (parent (org-ol-tree-core--headline-parent headline)) (parent-level (if parent (org-ol-tree-core--headline-level parent) 0)) (target-id (org-ol-tree-core--section-string (if (> (- headline-level parent-level) 1) (cdr (org-ol-tree-core--section-from-string headline-id)) (org-ol-tree-core--next-section headline-id (1- headline-level)))))) (if (> headline-level 1) (progn (save-current-buffer (set-buffer org-ol-tree--org-buffer) (save-excursion (goto-char headline-point) (if promote-tree (org-promote-subtree) (org-promote)))) (org-ol-tree-action--refresh nil target-id)))))
  (if org-ol-tree--buffer-p (progn (let* ((headline (org-ol-tree-core--current-headline)) (headline-point (org-ol-tree-core--headline-marker headline)) (headline-id (org-ol-tree-core--headline-id headline)) (headline-level (org-ol-tree-core--headline-level headline)) (parent (org-ol-tree-core--headline-parent headline)) (parent-level (if parent (org-ol-tree-core--headline-level parent) 0)) (target-id (org-ol-tree-core--section-string (if (> ... 1) (cdr ...) (org-ol-tree-core--next-section headline-id ...))))) (if (> headline-level 1) (progn (save-current-buffer (set-buffer org-ol-tree--org-buffer) (save-excursion (goto-char headline-point) (if promote-tree ... ...))) (org-ol-tree-action--refresh nil target-id))))))
  org-ol-tre-action--promote-node(nil)
  org-ol-tre-action--promote-section()
  #<subr funcall-interactively>(org-ol-tre-action--promote-section)
  apply(#<subr funcall-interactively> org-ol-tre-action--promote-section)
  funcall-interactively(org-ol-tre-action--promote-section)
  #<subr call-interactively>(org-ol-tre-action--promote-section nil nil)
  apply(#<subr call-interactively> (org-ol-tre-action--promote-section nil nil))
  explain-pause--wrap-call-interactively(#<subr call-interactively> org-ol-tre-action--promote-section nil nil)
  apply(explain-pause--wrap-call-interactively #<subr call-interactively> (org-ol-tre-action--promote-section nil nil))
  call-interactively(org-ol-tre-action--promote-section nil nil)
  command-execute(org-ol-tre-action--promote-section)

@Alexander-Miller
Copy link
Owner

Sorry for the late response, I've been busy renovating for the last couple of days.

Now to your question:

Treemacs does not have a dom that can be manipulated. There exists a backing
data structure that I call a dom, but it's descriptive, it depicts the current
state of the tree and its purpose is to help me to quickly navigate without the
need for expensive text searches.

The api for modifying treemacs is quite a bit more simple and high-level. You'll
want to use one of

  • treemacs-update-node
  • treemacs-delete-single-node
  • treemacs-do-insert-single-node

(In fact I just noticed that the last one doesn't work with extensions, so
update-node is what you'll want to use. )

How to manipulate the tree structure on Treemacs, update it, and save/restore
node position correctly?

As you can see there's not much of an api to manipulate treemacs directly. The
assumption is that you change the underlying data source and call a refresh and
treemacs handles the rest all on its own. Including the parts of saving and
restoring node positions and state.

Before we start digging into the specific troubles you're having I would ask you
to have a look at #677 and the treelib branch. I am in the process of a major
update of the extensions module with quite a few improvements like a simpler api
and support for asynchronicity. It is not quite ready the be officially used
yet, but not much is missing.

So if you make the jump now you'll save yourself the trouble of rewriting things
in the future. You'll also have an easy time pushing for changes you'd like to
see while the new api is not yet released and your POV will be quite valuable
for me. I'll also have a much easier time debugging bugs like the one you're
seeing because the new api does not use macros to generate entire functions.

@Townk
Copy link
Author

Townk commented Apr 23, 2021

Hey Alexander, thanks for the response, and don't worry about taking long to reply. I myself have to deliver a task at work that is keeping me away from my pet project. Anyway, I believe some time next week I will get couple weeks of vacation and will dive deep into my project. I will be more than happy to use the new API. Once I get that started I will update this ticket to let you know the status.

@stale
Copy link

stale bot commented Oct 7, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Oct 7, 2021
@Alexander-Miller
Copy link
Owner

Stayin alive.

@stale stale bot removed the stale label Oct 9, 2021
@stale
Copy link

stale bot commented Dec 8, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Dec 8, 2021
@stale stale bot closed this as completed Dec 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants