Function: combobulate-nav-to-defun

combobulate-nav-to-defun is a natively compiled function defined in combobulate-navigation.el.

Signature

(combobulate-nav-to-defun DIRECTION &optional NODE)

Documentation

Navigate to a defun in DIRECTION, possibly from NODE.

DIRECTION must be forward or backward.

Source Code

;; Defined in /nix/store/b5fvrwzi3zvkabyzx0in6gw1cj963z46-emacs-packages-deps/share/emacs/site-lisp/combobulate-navigation.el
(defun combobulate-nav-to-defun (direction &optional node)
  "Navigate to a defun in DIRECTION, possibly from NODE.

DIRECTION must be `forward' or `backward'."
  (when-let* ((current-node (or node
                                (combobulate--get-nearest-navigable-node)
                                (combobulate-node-at-point)))
              (min-depth most-positive-fixnum)
              (tree (save-excursion
                      (combobulate-move-to-node current-node (eq direction 'backward))
                      (combobulate-build-sparse-tree direction combobulate-navigable-nodes
                                                     (if (eq direction 'backward)
                                                         #'combobulate-node-before-point-p
                                                       #'combobulate-node-on-or-after-point-p)))))
    (let ((valid-nodes)
          (current-node-depth
           ;; determine the smallest depth in the tree and also the
           ;; depth of `current-node'.
           (combobulate-walk-tree tree
                                  (lambda (leaf depth)
                                    (setq min-depth (min depth min-depth))
                                    (when (combobulate-node-eq current-node leaf)
                                      ;; once we've found
                                      ;; `current-node' in the tree,
                                      ;; we unwind the walk; no need
                                      ;; to continue.
                                      (throw 'stop depth))
                                    (cons depth leaf)))))
      ;; if we get anything but a number back, default to node depth
      ;; 0
      (when (consp current-node-depth)
        (setq current-node-depth 0))
      ;; now walk the tree again. This time it's to find matches
      ;; that satisfy `combobulate-beginning-of-defun-behavior'
      (combobulate-walk-tree
       tree
       (lambda (leaf depth)
         (when (and (if (eq 'forward direction)
                        (or (combobulate-point-near-node leaf)
                            (combobulate-node-on-or-after-point-p leaf))
                      (combobulate-node-before-point-p leaf))
                    (or
                     ;; we can always match against nodes at the
                     ;; root depth. we need this in case current
                     ;; node depth is root-level.
                     (= depth min-depth)
                     (when (eq 'backward direction)
                       (cond
                        ;;; methods of movement of use to combobulate only (probably.)
                        ((eq 'sibling-only combobulate-beginning-of-defun-behavior)
                         (= depth current-node-depth))
                        ;;; methods of movement of interest to users.
                        ;; `self-and-sibling-first' matches the defun
                        ;; we're in and any other defun at the same or
                        ;; lower depth than we're currently at
                        ((eq 'self-and-sibling-first combobulate-beginning-of-defun-behavior)
                         (<= depth current-node-depth))
                        ;; `parent' matches only nodes at a depth less
                        ;; than our current node depth, including self
                        ((eq 'parent combobulate-beginning-of-defun-behavior)
                         (or (< depth current-node-depth)
                             (combobulate-node-eq leaf current-node)))
                        ;; `root' means we only match the minimum depth.
                        ((eq 'root combobulate-beginning-of-defun-behavior)
                         (= depth min-depth))
                        ;; `linear' matches any defun at any depth
                        ((eq 'linear combobulate-beginning-of-defun-behavior) t)))))
           (push leaf valid-nodes))
         (cons depth leaf)))
      (if (eq 'forward direction)
          (car (last valid-nodes))
        (car valid-nodes)))))