Function: c-ts-mode--prev-sibling

c-ts-mode--prev-sibling is a byte-compiled function defined in c-ts-mode.el.gz.

Signature

(c-ts-mode--prev-sibling NODE PARENT BOL &rest _)

Documentation

Return the start of the previous named sibling of NODE.

This anchor handles the special case where the previous sibling is a labeled_statement or preproc directive; in that case, return the child of the labeled statement instead. (Actually, recursively go down until
the node isn't a labeled_statement or preproc.) E.g.,

label:
  int x = 1;
  int y = 2;

The anchor of "int y = 2;" should be "int x = 1;" rather than the labeled_statement.

Return nil if a) there is no prev-sibling, or b) prev-sibling doesn't have a child.

PARENT is NODE's parent, BOL is the beginning of non-whitespace characters of the current line.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/c-ts-mode.el.gz
(defun c-ts-mode--prev-sibling (node parent bol &rest _)
  "Return the start of the previous named sibling of NODE.

This anchor handles the special case where the previous sibling is a
labeled_statement or preproc directive; in that case, return the child
of the labeled statement instead.  (Actually, recursively go down until
the node isn't a labeled_statement or preproc.)  E.g.,

label:
  int x = 1;
  int y = 2;

The anchor of \"int y = 2;\" should be \"int x = 1;\" rather than
the labeled_statement.

Return nil if a) there is no prev-sibling, or b) prev-sibling
doesn't have a child.

PARENT is NODE's parent, BOL is the beginning of non-whitespace
characters of the current line."
  (when-let* ((prev-sibling
               (or (treesit-node-prev-sibling node t)
                   (treesit-node-prev-sibling
                    (treesit-node-first-child-for-pos parent bol) t)
                   (treesit-node-child parent -1 t)))
              (continue t))
    (save-excursion
      (while (and prev-sibling continue)
        (pcase (treesit-node-type prev-sibling)
          ;; Get the statement in the label.
          ("labeled_statement"
           (setq prev-sibling (treesit-node-child prev-sibling 2)))
          ;; Get the last statement in the preproc.  Tested by
          ;; "Prev-Sibling When Prev-Sibling is Preproc" test.
          ((or "preproc_if" "preproc_ifdef")
           (setq prev-sibling (treesit-node-child prev-sibling -2)))
          ((or "preproc_elif" "preproc_else")
           (setq prev-sibling (treesit-node-child prev-sibling -1)))
          ((or "#elif" "#else")
           (setq prev-sibling (treesit-node-prev-sibling
                               (treesit-node-parent prev-sibling) t)))
          ;; If the start of the previous sibling isn't at the beginning
          ;; of a line, something's probably not quite right, go a step
          ;; further. (E.g., comment after a statement.)  If the
          ;; previous sibling is the first named node, then anchor to
          ;; that, e.g. when returning an aggregate and starting the
          ;; items on the same line as {.
          (_ (goto-char (treesit-node-start prev-sibling))
             (if (or (looking-back (rx bol (* whitespace))
                                   (line-beginning-position))
                     (treesit-node-eq (treesit-node-child parent 0 t)
                                      prev-sibling))
                 (setq continue nil)
               (setq prev-sibling
                     (treesit-node-prev-sibling prev-sibling)))))))
    ;; This could be nil if a) there is no prev-sibling or b)
    ;; prev-sibling doesn't have a child.
    (treesit-node-start prev-sibling)))