Function: treemacs--follow-each-dir
treemacs--follow-each-dir is a byte-compiled function defined in
treemacs-core-utils.el.
Signature
(treemacs--follow-each-dir BTN DIR-PARTS PROJECT)
Documentation
Starting at BTN follow (goto and open) every single dir in DIR-PARTS.
Return the button that is found or the symbol follow-failed if the search
failed. PROJECT is used for determining whether Git actions are appropriate.
Source Code
;; Defined in ~/.emacs.d/elpa/treemacs-20251226.1307/treemacs-core-utils.el
(define-inline treemacs--follow-each-dir (btn dir-parts project)
"Starting at BTN follow (goto and open) every single dir in DIR-PARTS.
Return the button that is found or the symbol `follow-failed' if the search
failed. PROJECT is used for determining whether Git actions are appropriate."
(inline-letevals (btn dir-parts project)
(inline-quote
(let* ((root (treemacs-button-get ,btn :path))
(git-future (treemacs--git-status-process root ,project))
(last-index (- (length ,dir-parts) 1))
(depth (treemacs-button-get ,btn :depth)))
(goto-char ,btn)
;; point is currently on the next closest dir to the followed file we could get
;; from the dom, so we expand it to keep going
(pcase (treemacs-button-get ,btn :state)
('dir-node-closed (treemacs--expand-dir-node ,btn :git-future git-future))
('root-node-closed (treemacs--expand-root-node ,btn)))
(catch 'follow-failed
(let ((index 0)
(dir-part nil))
;; for every item in dir-parts append it to the already found path for a new
;; 'root' to follow, so for root = /x/ and dir-parts = [src, config, foo.el]
;; consecutively try to move to /x/src, /x/src/confg and finally /x/src/config/foo.el
(while ,dir-parts
(setq dir-part (pop ,dir-parts)
root (treemacs-join-path root dir-part)
,btn
(let (current-btn)
(cl-block search
;; first a plain text-based search for the current dir-part string
;; then we grab the node we landed at and see what's going on
;; there's a couple ways this can go
(while (progn (goto-char (line-end-position)) (search-forward dir-part nil :no-error))
(setq current-btn (treemacs-current-button))
(cond
;; somehow we landed on a line where there isn't even anything to look at
;; technically this should never happen, but better safe than sorry
((null current-btn)
(cl-return-from search))
;; the search matched a custom button - skip those, as they cannot match
;; and their :paths are not strings, which would cause the following checks
;; to crash
((treemacs-button-get current-btn :custom))
;; perfect match - return the node we're at
((treemacs-is-path root :same-as (treemacs-button-get current-btn :path))
(cl-return-from search current-btn))
;; perfect match - taking collapsed dirs into account
;; return the node, but make sure to advance the loop variables an
;; appropriate nuber of times, since a collapsed directory is basically
;; multiple search iterations bundled as one
((and (treemacs-button-get current-btn :collapsed)
(treemacs-is-path (treemacs-button-get current-btn :path) :parent-of root))
(dotimes (_ (car (treemacs-button-get current-btn :collapsed)))
(setq root (concat root "/" (pop ,dir-parts)))
(cl-incf index))
(cl-return-from search current-btn))
;; node we're at has a smaller depth than the one we started from
;; that means we overshot our target and there's nothing to be found here
((>= depth (treemacs-button-get current-btn :depth))
(cl-return-from search)))))))
(unless ,btn (throw 'follow-failed 'follow-failed))
(goto-char ,btn)
;; don't open dir at the very end of the list since we only want to put
;; point in its line
(when (and (eq 'dir-node-closed (treemacs-button-get ,btn :state))
(< index last-index))
(treemacs--expand-dir-node ,btn :git-future git-future))
(setq index (1+ index))))
,btn)))))