Accept marker as position in treesit.c functions (bug#80830)

* src/treesit.c (treesit_check_positive_integer): Remove.
(treesit_check_position):
(Ftreesit_node_first_child_for_pos):
(Ftreesit_node_descendant_for_range):
(Ftreesit_query_capture):
(Ftreesit__linecol_at): Use fix_position.

* test/src/treesit-tests.el:
(treesit-query-marker-position): Test.
This commit is contained in:
Yuan Fu
2026-04-16 23:05:59 -07:00
parent cbbe2b5f55
commit 5ea181a75e
2 changed files with 25 additions and 20 deletions

View File

@@ -2891,16 +2891,6 @@ or no affected ranges, return nil. */)
/*** Node API */ /*** Node API */
/* Check that OBJ is a positive integer and signal an error if
otherwise. */
static void
treesit_check_positive_integer (Lisp_Object obj)
{
CHECK_INTEGER (obj);
if (XFIXNUM (obj) < 0)
xsignal1 (Qargs_out_of_range, obj);
}
static void static void
treesit_check_node (Lisp_Object obj) treesit_check_node (Lisp_Object obj)
{ {
@@ -2916,13 +2906,12 @@ treesit_check_node (Lisp_Object obj)
xsignal1 (Qtreesit_node_buffer_killed, obj); xsignal1 (Qtreesit_node_buffer_killed, obj);
} }
/* Check that OBJ is a positive integer and it is within the visible /* Check that OBJ is a positive integer/marker and it is within the
portion of BUF. */ visible portion of BUF. */
static void static void
treesit_check_position (Lisp_Object obj, struct buffer *buf) treesit_check_position (Lisp_Object obj, struct buffer *buf)
{ {
treesit_check_positive_integer (obj); ptrdiff_t pos = fix_position (obj);
ptrdiff_t pos = XFIXNUM (obj);
if (pos < BUF_BEGV (buf) || pos > BUF_ZV (buf)) if (pos < BUF_BEGV (buf) || pos > BUF_ZV (buf))
xsignal1 (Qargs_out_of_range, obj); xsignal1 (Qargs_out_of_range, obj);
} }
@@ -3350,7 +3339,7 @@ Note that this function returns an immediate child, not the smallest
treesit_check_position (pos, buf); treesit_check_position (pos, buf);
treesit_initialize (); treesit_initialize ();
ptrdiff_t byte_pos = buf_charpos_to_bytepos (buf, XFIXNUM (pos)); ptrdiff_t byte_pos = buf_charpos_to_bytepos (buf, fix_position (pos));
TSNode treesit_node = XTS_NODE (node)->node; TSNode treesit_node = XTS_NODE (node)->node;
TSTreeCursor cursor = ts_tree_cursor_new (treesit_node); TSTreeCursor cursor = ts_tree_cursor_new (treesit_node);
@@ -3388,8 +3377,8 @@ If NODE is nil, return nil. */)
treesit_initialize (); treesit_initialize ();
ptrdiff_t byte_beg = buf_charpos_to_bytepos (buf, XFIXNUM (beg)); ptrdiff_t byte_beg = buf_charpos_to_bytepos (buf, fix_position (beg));
ptrdiff_t byte_end = buf_charpos_to_bytepos (buf, XFIXNUM (end)); ptrdiff_t byte_end = buf_charpos_to_bytepos (buf, fix_position (end));
TSNode treesit_node = XTS_NODE (node)->node; TSNode treesit_node = XTS_NODE (node)->node;
TSNode child; TSNode child;
if (NILP (named)) if (NILP (named))
@@ -4079,8 +4068,8 @@ the query. */)
{ {
ptrdiff_t visible_beg ptrdiff_t visible_beg
= XTS_PARSER (XTS_NODE (lisp_node)->parser)->visible_beg; = XTS_PARSER (XTS_NODE (lisp_node)->parser)->visible_beg;
ptrdiff_t beg_byte = CHAR_TO_BYTE (XFIXNUM (beg)); ptrdiff_t beg_byte = CHAR_TO_BYTE (fix_position (beg));
ptrdiff_t end_byte = CHAR_TO_BYTE (XFIXNUM (end)); ptrdiff_t end_byte = CHAR_TO_BYTE (fix_position (end));
/* We never let tree-sitter run on buffers too large, so these /* We never let tree-sitter run on buffers too large, so these
assertion should never hit. */ assertion should never hit. */
eassert (beg_byte - visible_beg <= UINT32_MAX); eassert (beg_byte - visible_beg <= UINT32_MAX);
@@ -5169,7 +5158,7 @@ This is used for internal testing and debugging ONLY. */)
{ {
CHECK_NUMBER (pos); CHECK_NUMBER (pos);
struct ts_linecol pos_linecol struct ts_linecol pos_linecol
= treesit_linecol_of_pos (CHAR_TO_BYTE (XFIXNUM (pos)), = treesit_linecol_of_pos (CHAR_TO_BYTE (fix_position (pos)),
BUF_TS_LINECOL_POINT (current_buffer)); BUF_TS_LINECOL_POINT (current_buffer));
return Fcons (make_fixnum (pos_linecol.line), make_fixnum (pos_linecol.col)); return Fcons (make_fixnum (pos_linecol.line), make_fixnum (pos_linecol.col));
} }

View File

@@ -620,6 +620,22 @@ BODY is the test body."
;; First element of the match group should be a node. ;; First element of the match group should be a node.
(should (treesit-node-p (nth 0 (nth 0 res))))))) (should (treesit-node-p (nth 0 (nth 0 res)))))))
(ert-deftest treesit-query-marker-position ()
"Tests for query API."
(skip-unless (treesit-language-available-p 'json))
(with-temp-buffer
(insert "[1,2,{\"name\": \"Bob\"},3]")
(treesit-parser-create 'json)
;; Test marker.
(let* ((beg (point-min-marker))
(end (point-max-marker))
(res (treesit-query-capture 'json '((number) @num) beg end)))
(should (equal (length res) 3)))
;; Test out-of-range.
(should-error (treesit-query-capture 'json '((number) @num) -1 1))))
;;; Narrow ;;; Narrow
(ert-deftest treesit-narrow () (ert-deftest treesit-narrow ()