From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Po Lu via "Emacs development discussions." Newsgroups: gmane.emacs.devel Subject: Re: Stylistic changes to tree-sitter code Date: Fri, 28 Oct 2022 08:41:32 +0800 Message-ID: <87y1t06apv.fsf@yahoo.com> References: <87h6zp75nt.fsf.ref@yahoo.com> <87h6zp75nt.fsf@yahoo.com> <87h6zptloj.fsf@gmail.com> Reply-To: Po Lu Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="14109"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: Po Lu via "Emacs development discussions." To: Robert Pluim Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Oct 28 02:42:54 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ooDSW-0003Xs-47 for ged-emacs-devel@m.gmane-mx.org; Fri, 28 Oct 2022 02:42:52 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ooDRW-0001Nt-6C; Thu, 27 Oct 2022 20:41:50 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ooDRS-0001Mb-K5 for emacs-devel@gnu.org; Thu, 27 Oct 2022 20:41:46 -0400 Original-Received: from sonic307-10.consmr.mail.ne1.yahoo.com ([66.163.190.33]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1ooDRP-0008UW-3V for emacs-devel@gnu.org; Thu, 27 Oct 2022 20:41:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1666917701; bh=fjVUSrVV0w4G+H5t9BuMQe499AaWW54jcYGOp5A+3Lc=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From:Subject:Reply-To; b=YGpiW6xFSeCVTqr7c6dxDea9ipZ1oc5ThwhXJKW+tOftc8fOEGib3uLo4111/ez65vDYsEa0ijnFkNz15xxQrT/+d3NTfgX0bDDogNofpAyYNZfULJ0TTWXt6Yjn89W7w+dJqujDVjJVJtQ7K25CqFXmFQE8t5+4fx3MbcQyE+ReM6ydKYtDxLIKSd7bbYlo8hGh7bshxROJHpjUi8bBQ/tjuVgtn9J59WT8sO2Hq8tAFZwWiP1WcuZrulqzSjftVTzF7u/PfrZiFo7n6uAfZvijgqfiIvYREF/+m/Lgn6S3j4w9uOzXaJu+Znlwq7VCh4lHwxKUoNz2rhSqXXdTrQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1666917701; bh=9VIOAJjqhlJabQhA5M0o2l89LnzM3wAXF/tFC7rQW7D=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=FCA3XO4F/m1z7TWlsd+MC3EwtmmYQyiBDKggd5p/bm83kXL/R2a/TlmpzV9PnGBcfaFCfik6PUnfk45BLVPrb2H+SwVhr2CXJzmpLffw2FG17r3tfjWhpJobIKICRpS87M7syRXf04ntxLeQVGKWYw8UA+NiHRVSULKJODMPGxus1kFt5TsjMpdjZHBWQWhz0XPa1h1O47C3ofqc3k42YLUdXAUwf2JSeRWuYtjyIgdcNwqtUNwtbwFn3lwc9+nqRJ49WFTTrXDIa6KziBJBscfPeq5dpC1JYbq0NYQgjKIm8ShaeuZm+CY4JzGjMZLR/1gUOOiOdfMa+2ib3HoJEA== X-YMail-OSG: 6CZy4dUVM1lw_5O6VyGi3TffzL5Vqv55zSSA6pCGPxe2Q3OPqGo.N6X4VHdIRLG ygEnp_IZINprmojA6NOL3ptxiRNlHAMA4Hb4PtV1.G59xGMgSwPgr.R6Bbu2UhgCTWPHSVj29Cb8 dgzLiMA397lGts_DCrTj6wrL1HF.e6bVOUw9WJT6afDFZAW1IOSxSDNoeHhG9W5F9JhRWy8cqZ9t DiOy_P6UvqrGUuuaDNgRUPhf3Nms37Pem75AkZeUT6pyDDGGEwwxViOvQqrx_RUopeoF7Pe9xMy4 ABsupBQNocYxVtuZfxlL3BzJ_KxrtaHua0nSsMIvTAAJrDf_NJmeBljkiPHgaXv2ZSOSHswE0CPm 0XYZDyPjqT5cgjP2cUII3OfkpsKgAif2va0BytG2HgDv7y5abcZtm_Mr3Rm8wf1zXWsSxDKjM3Kb HGg8sXi4fC3c37.rKtXEG_tc1Q7xNlbnzNMzpB85kIXmaHnpzbdQgM6mrW5aT_pFkXdtIWOvXjK8 FFJlm4q4AJ1WYAwwUxsIUDbugXsFeUR5NpJ8iVHEI.EAdqkxePKcRBFdBEcx2skT1ONcaaBQnh3n oUXe_o50jRhPyETELIw5pF2ka.Jw2HlsY4iWmgiDkbU64FmWWLc129o69d8U6xR_t5nc9pWcgMp8 dEOPxccBp0MqkzL9EbPlo5iB7X5i_5krE2eRRKy0_ACSaUhT1wQR3iz2VEwSQPjR6p2sFPhw6Big cWnH5vJYm3n4XSTfKO4M3NoStN2IYEU9S3mQU5trkyISijlKVsTR3GVgwHaL0SG6er8wdgyr1RcC K1ZN0ng6GGFx3e5RaTR9UZjuzsX7kzxArmnEyfkGAm X-Sonic-MF: Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.ne1.yahoo.com with HTTP; Fri, 28 Oct 2022 00:41:41 +0000 Original-Received: by hermes--production-sg3-74fb94585-w75tz (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 81f9c0104dbe50062a6f1fc90a2005cc; Fri, 28 Oct 2022 00:41:37 +0000 (UTC) In-Reply-To: <87h6zptloj.fsf@gmail.com> (Robert Pluim's message of "Thu, 27 Oct 2022 15:56:12 +0200") X-Mailer: WebService/1.1.20783 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Received-SPF: pass client-ip=66.163.190.33; envelope-from=luangruo@yahoo.com; helo=sonic307-10.consmr.mail.ne1.yahoo.com X-Spam_score_int: -7 X-Spam_score: -0.8 X-Spam_bar: / X-Spam_report: (-0.8 / 5.0 requ) BAYES_00=-1.9, DKIM_ADSP_CUSTOM_MED=0.001, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, FREEMAIL_FROM=0.001, NML_ADSP_CUSTOM_MED=0.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: "Emacs-devel" Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:298649 Archived-At: Robert Pluim writes: >>>>>> On Thu, 27 Oct 2022 21:33:10 +0800, Po Lu via "Emacs development dis= cussions." said: > > > Po Lu> Unfortunately, I don't have tree-sitter installed, so would so= meone > Po Lu> please do a smoke test on the changes before I install them? > > I have it installed, but I don=CA=BCt use it yet, so all I can offer is a > compile test: > > CC treesit.o > treesit.c: In function =E2=80=98treesit_find_override_name=E2=80=99: > treesit.c:467:41: error: =E2=80=98list=E2=80=99 undeclared (first use in = this function); did you mean =E2=80=98listn=E2=80=99? > 467 | *name =3D Fnth (make_fixnum (1), XCAR (list)); > | ^~~~ > | listn > treesit.c:467:41: note: each undeclared identifier is reported only once = for each function it appears in > treesit.c:476:57: error: expected =E2=80=98;=E2=80=99 before =E2=80=98ret= urn=E2=80=99 > 476 | CHECK_LIST_END (tem, Vtreesit_load_name_override_list) > | ^ > | ; > 477 |=20 > 478 | return false; > | ~~~~~~=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20 > treesit.c: In function =E2=80=98treesit_load_language=E2=80=99: > treesit.c:555:15: error: redeclaration of =E2=80=98tail=E2=80=99 with no = linkage > 555 | Lisp_Object tail; > | ^~~~ > treesit.c:539:15: note: previous declaration of =E2=80=98tail=E2=80=99 wa= s here > 539 | Lisp_Object tail; > | ^~~~ > treesit.c: In function =E2=80=98treesit_find_override_name=E2=80=99: > treesit.c:479:1: warning: control reaches end of non-void function [-Wret= urn-type] > 479 | } > | ^ > make[2]: *** [Makefile:424: treesit.o] Error 1 > > Robert Thanks. What about this patch? >From 2c556471b7738c821ef4af8236c9a89159dfe0fb Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 27 Oct 2022 21:30:23 +0800 Subject: [PATCH] Stylistic changes to tree-sitter code * src/treesit.c (treesit_find_override_name) (treesit_load_language_push_for_each_suffix, treesit_load_language) (Ftreesit_langauge_available_p, treesit_record_change) (make_treesit_parser, make_treesit_node, make_treesit_query) (Ftreesit_parser_create, Ftreesit_parser_delete, Ftreesit_parser_list) (treesit_check_range_argument, Ftreesit_parser_included_ranges) (Ftreesit_node_start, Ftreesit_node_end, Ftreesit_node_check) (Ftreesit_node_child_by_field_name, Ftreesit_pattern_expand) (Ftreesit_query_expand, treesit_predicates_for_pattern) (treesit_predicate_capture_name_to_text, treesit_predicate_equal) (treesit_predicate_match, treesit_eval_predicates) (Ftreesit_query_capture, treesit_search_dfs, treesit_build_sparse_tree) (syms_of_treesit): Use FOR_EACH_TAIL (or FOR_EACH_TAIL_SAFE where not obviously safe), and check list heads and tails correctly; fix coding style of various constructs, especially: variable =3D mumble (frob (bar), (foo () + bar ()) + (baz () + quux ())) which should actually be variable =3D mumble (frob (bar), (foo () + bar ()) + (baz () + quux ())) and foo =3D mumble (frob (bar), 0) + (foo () + bar ()) + (baz () + quux ()) which should actually be foo =3D (mumble (frob (bar), 0) + (foo () + bar ()) + (baz () + quux ())) * src/treesit.h: Make declaration coding style consistent. --- src/treesit.c | 386 ++++++++++++++++++++++++++++---------------------- src/treesit.h | 14 +- 2 files changed, 221 insertions(+), 179 deletions(-) diff --git a/src/treesit.c b/src/treesit.c index e4be065d94..210b335c52 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -280,13 +280,15 @@ #define ts_tree_root_node fn_ts_tree_root_node The Emacs wrapper of tree-sitter does not expose everything the C API provides, most notably: =20 - - It doesn't expose a syntax tree. We put the syntax tree in the - parser object, and updating the tree is handled on the C level. + - It doesn't expose a syntax tree. The syntax tree is placed in + the parser object, and updating the tree is handled at the C + level. =20 - - We don't expose tree cursor either. I think Lisp is slow enough - to nullify any performance advantage of using a cursor, though I - don't have evidence. Also I want to minimize the number of new - types we introduce. Currently we only add parser and node type. + - The tree cursor is not exposed either. I think Lisp is slow + enough to nullify any performance advantage of using a cursor, + though I don't have evidence. Also I want to minimize the number + of new types we introduce. Currently we only add parser and node + type. =20 - Because updating the change is handled on the C level as each change is made in the buffer, there is no way for Lisp to update @@ -295,36 +297,38 @@ #define ts_tree_root_node fn_ts_tree_root_node =20 - I didn't expose setting timeout and cancellation flag for a parser, mainly because I don't think they are really necessary - in Emacs' use cases. - - - Many tree-sitter functions asks for a TSPoint, basically a (row, - column) location. Emacs uses a gap buffer and keeps no - information about row and column position. According to the - author of tree-sitter, tree-sitter only asks for (row, column) - position to carry it around and return back to the user later; - and the real position used is the byte position. He also said - that he _think_ that it will work to use byte position only. - That's why whenever a TSPoint is asked, we pass a dummy one to - it. Judging by the nature of parsing algorithms, I think it is - safe to use only byte position, and I don't think this will - change in the future. - - REF: https://github.com/tree-sitter/tree-sitter/issues/445 - - treesit.h has some commentary on the two main data structure - for the parser and node. treesit_ensure_position_synced has some - commentary on how do we make tree-sitter play well with narrowing - (tree-sitter parser only sees the visible region, so we need to + in Emacs's use cases. + + - Many tree-sitter functions take a TSPoint, which is basically a + row and column. Emacs uses a gap buffer and does not keep + information about the row and column position of a buffer. + According to the author of tree-sitter, those functions only take + a TSPoint so that it can be moved alongside the byte position and + returned to the caller afterwards, and the position actually used + is the specified byte position. He also said that he _thinks_ + that just passing a byte position will also work. As a result, a + dummy value is used in place of each TSPoint. Judging by the + nature of parsing algorithms, I think it is safe to use only the + byte position, and I don't think this will change in the future. + + See: https://github.com/tree-sitter/tree-sitter/issues/445 + + treesit.h has some commentary on the two main data structure for + the parser and node. treesit_ensure_position_synced has some + commentary on how we make tree-sitter play well with narrowing (the + tree-sitter parser only sees the visible region, so we need to translate positions back and forth). Most action happens in - treesit_ensure_parsed, treesit_read_buffer and treesit_record_change. + treesit_ensure_parsed, treesit_read_buffer and + treesit_record_change. =20 A complete correspondence list between tree-sitter functions and - exposed Lisp functions can be found in the manual (elisp)API + exposed Lisp functions can be found in the manual node (elisp)API Correspondence. =20 Placement of CHECK_xxx functions: call CHECK_xxx before using any - unchecked Lisp values; these include argument of Lisp functions, - return value of Fsymbol_value, car of a cons. + unchecked Lisp values; these include arguments of Lisp functions, + the return value of Fsymbol_value, and that of Fcar or Fcdr on + user-specified conses. =20 Initializing tree-sitter: there are two entry points to tree-sitter functions: 'treesit-parser-create' and @@ -378,8 +382,8 @@ #define ts_tree_root_node fn_ts_tree_root_node up and the query doesn't EQ to the cache anymore, the performance mysteriously drops. 3) what if a user uses so many stuff that the default cache size (20) is not enough and we end up thrashing? - These are all imagined scenarios but they are not impossible :-) - */ + These are all imaginary scenarios but they are not impossible + :-) */ =20 /*** Initialization */ @@ -449,21 +453,28 @@ treesit_symbol_to_c_name (char *symbol_name) treesit_find_override_name (Lisp_Object language_symbol, Lisp_Object *name, Lisp_Object *c_symbol) { + Lisp_Object tem; + CHECK_LIST (Vtreesit_load_name_override_list); - for (Lisp_Object list =3D Vtreesit_load_name_override_list; - !NILP (list); list =3D XCDR (list)) + + FOR_EACH_TAIL (tem) { - Lisp_Object lang =3D XCAR (XCAR (list)); + Lisp_Object lang =3D XCAR (XCAR (tem)); CHECK_SYMBOL (lang); + if (EQ (lang, language_symbol)) { - *name =3D Fnth (make_fixnum (1), XCAR (list)); + *name =3D Fnth (make_fixnum (1), XCAR (tem)); CHECK_STRING (*name); - *c_symbol =3D Fnth (make_fixnum (2), XCAR (list)); + *c_symbol =3D Fnth (make_fixnum (2), XCAR (tem)); CHECK_STRING (*c_symbol); + return true; } } + + CHECK_LIST_END (tem, Vtreesit_load_name_override_list); + return false; } =20 @@ -475,12 +486,13 @@ treesit_find_override_name (Lisp_Object language_symb= ol, Lisp_Object *name, treesit_load_language_push_for_each_suffix (Lisp_Object lib_base_name, Lisp_Object *path_candidates) { - for (Lisp_Object suffixes =3D Vdynamic_library_suffixes; - !NILP (suffixes); suffixes =3D XCDR (suffixes)) - { - *path_candidates =3D Fcons (concat2 (lib_base_name, XCAR (suffixes)), - *path_candidates); - } + Lisp_Object suffixes; + + suffixes =3D Vdynamic_library_suffixes; + + FOR_EACH_TAIL (suffixes) + *path_candidates =3D Fcons (concat2 (lib_base_name, XCAR (suffixes)), + *path_candidates); } =20 /* Load the dynamic library of LANGUAGE_SYMBOL and return the pointer @@ -497,10 +509,10 @@ treesit_load_language (Lisp_Object language_symbol, CHECK_LIST (Vtreesit_extra_load_path); =20 /* Figure out the library name and C name. */ - Lisp_Object lib_base_name =3D - concat2 (build_pure_c_string ("libtree-sitter-"), symbol_name); - Lisp_Object base_name =3D - concat2 (build_pure_c_string ("tree-sitter-"), symbol_name); + Lisp_Object lib_base_name + =3D concat2 (build_pure_c_string ("libtree-sitter-"), symbol_name); + Lisp_Object base_name + =3D concat2 (build_pure_c_string ("tree-sitter-"), symbol_name); =20 /* Override the library name and C name, if appropriate. */ Lisp_Object override_name; @@ -509,7 +521,7 @@ treesit_load_language (Lisp_Object language_symbol, &override_name, &override_c_name); if (found_override) - lib_base_name =3D override_name; + lib_base_name =3D override_name; =20 /* Now we generate a list of possible library paths. */ Lisp_Object path_candidates =3D Qnil; @@ -519,13 +531,16 @@ treesit_load_language (Lisp_Object language_symbol, /* This is used for reporting errors (i.e., just filenames). */ Lisp_Object base_candidates =3D path_candidates; /* Then push ~/.emacs.d/tree-sitter paths. */ - Lisp_Object lib_name =3D - Fexpand_file_name (concat2 (build_string ("tree-sitter/"), lib_base_na= me), - Fsymbol_value (Quser_emacs_directory)); + Lisp_Object lib_name + =3D Fexpand_file_name (concat2 (build_string ("tree-sitter/"), lib_bas= e_name), + Fsymbol_value (Quser_emacs_directory)); treesit_load_language_push_for_each_suffix (lib_name, &path_candidates); /* Then push paths from treesit-extra-load-path. */ - for (Lisp_Object tail =3D Freverse (Vtreesit_extra_load_path); - !NILP (tail); tail =3D XCDR (tail)) + Lisp_Object tail; + + tail =3D Freverse (Vtreesit_extra_load_path); + + FOR_EACH_TAIL (tail) { Lisp_Object expanded_lib =3D Fexpand_file_name (lib_base_name, XCAR = (tail)); treesit_load_language_push_for_each_suffix (expanded_lib, @@ -537,8 +552,10 @@ treesit_load_language (Lisp_Object language_symbol, fail. */ dynlib_handle_ptr handle; char const *error; - for (Lisp_Object tail =3D path_candidates; - !NILP (tail); tail =3D XCDR (tail)) + + tail =3D path_candidates; + + FOR_EACH_TAIL (tail) { char *library_name =3D SSDATA (XCAR (tail)); dynlib_error (); @@ -547,6 +564,7 @@ treesit_load_language (Lisp_Object language_symbol, if (error =3D=3D NULL) break; } + if (error !=3D NULL) { *signal_symbol =3D Qtreesit_load_language_error; @@ -587,8 +605,7 @@ treesit_load_language (Lisp_Object language_symbol, return lang; } =20 -DEFUN ("treesit-language-available-p", - Ftreesit_langauge_available_p, +DEFUN ("treesit-language-available-p", Ftreesit_langauge_available_p, Streesit_language_available_p, 1, 2, 0, doc: /* Return non-nil if LANGUAGE exists and is loadable. @@ -668,15 +685,17 @@ treesit_tree_edit_1 (TSTree *tree, ptrdiff_t start_by= te, } =20 /* Update each parser's tree after the user made an edit. This -function does not parse the buffer and only updates the tree. (So it -should be very fast.) */ + function does not parse the buffer and only updates the tree, so it + should be very fast. */ void treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, ptrdiff_t new_end_byte) { - for (Lisp_Object parser_list =3D BVAR (current_buffer, ts_parser_list); - !NILP (parser_list); - parser_list =3D XCDR (parser_list)) + Lisp_Object parser_list; + + parser_list =3D BVAR (current_buffer, ts_parser_list); + + FOR_EACH_TAIL_SAFE (parser_list) { CHECK_CONS (parser_list); Lisp_Object lisp_parser =3D XCAR (parser_list); @@ -699,15 +718,15 @@ treesit_record_change (ptrdiff_t start_byte, ptrdiff_= t old_end_byte, VISIBLE_BEG. min(visi_end, max(visi_beg, value)) clips value into [visi_beg, visi_end], and subtracting visi_beg gives the offset from visi_beg. */ - ptrdiff_t start_offset =3D - min (visible_end, - max (visible_beg, start_byte)) - visible_beg; - ptrdiff_t old_end_offset =3D - min (visible_end, - max (visible_beg, old_end_byte)) - visible_beg; - ptrdiff_t new_end_offset =3D - min (visible_end, - max (visible_beg, new_end_byte)) - visible_beg; + ptrdiff_t start_offset =3D (min (visible_end, + max (visible_beg, start_byte)) + - visible_beg); + ptrdiff_t old_end_offset =3D (min (visible_end, + max (visible_beg, old_end_byte)) + - visible_beg); + ptrdiff_t new_end_offset =3D (min (visible_end, + max (visible_beg, new_end_byte)) + - visible_beg); eassert (start_offset <=3D old_end_offset); eassert (start_offset <=3D new_end_offset); =20 @@ -721,21 +740,18 @@ treesit_record_change (ptrdiff_t start_byte, ptrdiff_= t old_end_byte, view changes. */ ptrdiff_t visi_beg_delta; if (old_end_byte > new_end_byte) - { - /* Move backward. */ - visi_beg_delta =3D - min (visible_beg, new_end_byte) - - min (visible_beg, old_end_byte); - } + /* Move backward. */ + visi_beg_delta =3D (min (visible_beg, new_end_byte) + - min (visible_beg, old_end_byte)); else - { - /* Move forward. */ - visi_beg_delta =3D - old_end_byte < visible_beg ? new_end_byte - old_end_byte : 0; - } + /* Move forward. */ + visi_beg_delta =3D (old_end_byte < visible_beg + ? new_end_byte - old_end_byte : 0); XTS_PARSER (lisp_parser)->visible_beg =3D visible_beg + visi_beg_delta; - XTS_PARSER (lisp_parser)->visible_end - =3D visible_end + visi_beg_delta + (new_end_offset - old_end_offset); + XTS_PARSER (lisp_parser)->visible_end =3D (visible_end + + visi_beg_delta + + (new_end_offset + - old_end_offset)); eassert (XTS_PARSER (lisp_parser)->visible_beg >=3D 0); eassert (XTS_PARSER (lisp_parser)->visible_beg <=3D XTS_PARSER (lisp_parser)->visible_end); @@ -826,7 +842,7 @@ treesit_check_buffer_size (struct buffer *buffer) } =20 /* Parse the buffer. We don't parse until we have to. When we have -to, we call this function to parse and update the tree. */ + to, we call this function to parse and update the tree. */ static void treesit_ensure_parsed (Lisp_Object parser) { @@ -913,15 +929,18 @@ treesit_read_buffer (void *parser, uint32_t byte_inde= x, return beg; } =20 -/*** Functions for parser and node object*/ +/*** Functions for parser and node object */ =20 -/* Wrap the parser in a Lisp_Object to be used in the Lisp machine. */ +/* Wrap the parser in a Lisp_Object to be used in the Lisp + machine. */ Lisp_Object make_treesit_parser (Lisp_Object buffer, TSParser *parser, TSTree *tree, Lisp_Object language_symbol) { - struct Lisp_TS_Parser *lisp_parser =3D - ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Parser, buffer, PVEC_TS_PARSER); + struct Lisp_TS_Parser *lisp_parser; + + lisp_parser =3D ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Parser, + buffer, PVEC_TS_PARSER); =20 lisp_parser->language_symbol =3D language_symbol; lisp_parser->buffer =3D buffer; @@ -942,8 +961,10 @@ make_treesit_parser (Lisp_Object buffer, TSParser *par= ser, Lisp_Object make_treesit_node (Lisp_Object parser, TSNode node) { - struct Lisp_TS_Node *lisp_node =3D - ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Node, parser, PVEC_TS_NODE); + struct Lisp_TS_Node *lisp_node; + + lisp_node =3D ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Node, + parser, PVEC_TS_NODE); lisp_node->parser =3D parser; lisp_node->node =3D node; lisp_node->timestamp =3D XTS_PARSER (parser)->timestamp; @@ -956,9 +977,10 @@ make_treesit_node (Lisp_Object parser, TSNode node) make_treesit_query (Lisp_Object query, Lisp_Object language) { TSQueryCursor *treesit_cursor =3D ts_query_cursor_new (); - struct Lisp_TS_Query *lisp_query =3D - ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Query, source, - PVEC_TS_COMPILED_QUERY); + struct Lisp_TS_Query *lisp_query; + + lisp_query =3D ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Query, + source, PVEC_TS_COMPILED_QUERY); =20 lisp_query->language =3D language; lisp_query->source =3D query; @@ -1178,8 +1200,9 @@ DEFUN ("treesit-parser-create", ts_parser_set_language (parser, lang); =20 /* Create parser. */ - Lisp_Object lisp_parser - =3D make_treesit_parser (Fcurrent_buffer (), parser, NULL, language); + Lisp_Object lisp_parser =3D make_treesit_parser (Fcurrent_buffer (), + parser, NULL, + language); =20 /* Update parser-list. */ BVAR (buf, ts_parser_list) =3D Fcons (lisp_parser, BVAR (buf, ts_parser_= list)); @@ -1198,7 +1221,9 @@ DEFUN ("treesit-parser-delete", =20 Lisp_Object buffer =3D XTS_PARSER (parser)->buffer; struct buffer *buf =3D XBUFFER (buffer); - BVAR (buf, ts_parser_list) =3D Fdelete (parser, BVAR (buf, ts_parser_lis= t)); + + BVAR (buf, ts_parser_list) + =3D Fdelete (parser, BVAR (buf, ts_parser_list)); =20 XTS_PARSER (parser)->deleted =3D true; return Qnil; @@ -1222,12 +1247,13 @@ DEFUN ("treesit-parser-list", /* Return a fresh list so messing with that list doesn't affect our internal data. */ Lisp_Object return_list =3D Qnil; - for (Lisp_Object tail =3D BVAR (buf, ts_parser_list); - !NILP (tail); - tail =3D XCDR (tail)) - { - return_list =3D Fcons (XCAR (tail), return_list); - } + Lisp_Object tail; + + tail =3D BVAR (buf, ts_parser_list); + + FOR_EACH_TAIL (tail) + return_list =3D Fcons (XCAR (tail), return_list); + return Freverse (return_list); } =20 @@ -1278,8 +1304,13 @@ treesit_check_range_argument (Lisp_Object ranges) ptrdiff_t point_min =3D BUF_BEGV (buffer); ptrdiff_t point_max =3D BUF_ZV (buffer); EMACS_INT last_point =3D point_min; + Lisp_Object tail; + + tail =3D ranges; =20 - for (Lisp_Object tail =3D ranges; !NILP (tail); tail =3D XCDR (tail)) + CHECK_LIST (tail); + + FOR_EACH_TAIL (tail) { CHECK_CONS (tail); Lisp_Object range =3D XCAR (tail); @@ -1290,10 +1321,13 @@ treesit_check_range_argument (Lisp_Object ranges) EMACS_INT end =3D XFIXNUM (XCDR (range)); if (!(last_point <=3D beg && beg <=3D end && end <=3D point_max)) xsignal2 (Qtreesit_range_invalid, - build_pure_c_string ("RANGE is either overlapping or out-of-order or o= ut-of-range"), + build_pure_c_string ("RANGE is either overlapping," + " out-of-order or out-of-range"), ranges); last_point =3D end; } + + CHECK_LIST_END (tail, ranges); } =20 DEFUN ("treesit-parser-set-included-ranges", @@ -1385,8 +1419,8 @@ DEFUN ("treesit-parser-included-ranges", treesit_check_parser (parser); treesit_initialize (); uint32_t len; - const TSRange *ranges =3D - ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len); + const TSRange *ranges + =3D ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len); if (len =3D=3D 0) return Qnil; =20 @@ -1407,9 +1441,9 @@ DEFUN ("treesit-parser-included-ranges", eassert (beg_byte <=3D end_byte); eassert (end_byte <=3D BUF_ZV_BYTE (buffer)); =20 - Lisp_Object lisp_range =3D - Fcons (make_fixnum (buf_bytepos_to_charpos (buffer, beg_byte)) , - make_fixnum (buf_bytepos_to_charpos (buffer, end_byte))); + Lisp_Object lisp_range + =3D Fcons (make_fixnum (buf_bytepos_to_charpos (buffer, beg_byte)), + make_fixnum (buf_bytepos_to_charpos (buffer, end_byte))); list =3D Fcons (lisp_range, list); } return Fnreverse (list); @@ -1464,10 +1498,11 @@ DEFUN ("treesit-node-start", TSNode treesit_node =3D XTS_NODE (node)->node; ptrdiff_t visible_beg =3D XTS_PARSER (XTS_NODE (node)->parser)->visible_= beg; uint32_t start_byte_offset =3D ts_node_start_byte (treesit_node); - struct buffer *buffer =3D - XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); - ptrdiff_t start_pos =3D - buf_bytepos_to_charpos (buffer, start_byte_offset + visible_beg); + struct buffer *buffer + =3D XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); + ptrdiff_t start_pos + =3D buf_bytepos_to_charpos (buffer, + start_byte_offset + visible_beg); return make_fixnum (start_pos); } =20 @@ -1484,10 +1519,10 @@ DEFUN ("treesit-node-end", TSNode treesit_node =3D XTS_NODE (node)->node; ptrdiff_t visible_beg =3D XTS_PARSER (XTS_NODE (node)->parser)->visible_= beg; uint32_t end_byte_offset =3D ts_node_end_byte (treesit_node); - struct buffer *buffer =3D - XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); - ptrdiff_t end_pos =3D - buf_bytepos_to_charpos (buffer, end_byte_offset + visible_beg); + struct buffer *buffer + =3D XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); + ptrdiff_t end_pos + =3D buf_bytepos_to_charpos (buffer, end_byte_offset + visible_beg); return make_fixnum (end_pos); } =20 @@ -1611,7 +1646,8 @@ DEFUN ("treesit-node-check", else if (EQ (property, Qhas_changes)) result =3D ts_node_has_changes (treesit_node); else - signal_error ("Expecting `named', `missing', `extra', `has-changes' or= `has-error', but got", + signal_error ("Expecting `named', `missing', `extra', " + "`has-changes' or `has-error', but got", property); return result ? Qt : Qnil; } @@ -1694,7 +1730,8 @@ DEFUN ("treesit-node-child-by-field-name", char *name_str =3D SSDATA (field_name); TSNode treesit_node =3D XTS_NODE (node)->node; TSNode child - =3D ts_node_child_by_field_name (treesit_node, name_str, strlen (name_= str)); + =3D ts_node_child_by_field_name (treesit_node, name_str, + strlen (name_str)); =20 if (ts_node_is_null (child)) return Qnil; @@ -1900,10 +1937,10 @@ DEFUN ("treesit-pattern-expand", return build_pure_c_string ("#equal"); if (EQ (pattern, intern_c_string (":match"))) return build_pure_c_string ("#match"); - Lisp_Object opening_delimeter =3D - build_pure_c_string (VECTORP (pattern) ? "[" : "("); - Lisp_Object closing_delimiter =3D - build_pure_c_string (VECTORP (pattern) ? "]" : ")"); + Lisp_Object opening_delimeter + =3D build_pure_c_string (VECTORP (pattern) ? "[" : "("); + Lisp_Object closing_delimiter + =3D build_pure_c_string (VECTORP (pattern) ? "]" : ")"); if (VECTORP (pattern) || CONSP (pattern)) return concat3 (opening_delimeter, Fmapconcat (intern_c_string ("treesit-pattern-expand"), @@ -1937,8 +1974,8 @@ DEFUN ("treesit-query-expand", See Info node `(elisp)Pattern Matching' for detailed explanation. */) (Lisp_Object query) { - return Fmapconcat (intern_c_string ("treesit-pattern-expand"), - query, build_pure_c_string (" ")); + return Fmapconcat (Qtreesit_pattern_expand, + query, empty_unibyte_string); } =20 /* This struct is used for passing captures to be check against @@ -1962,8 +1999,8 @@ DEFUN ("treesit-query-expand", treesit_predicates_for_pattern (TSQuery *query, uint32_t pattern_index) { uint32_t len; - const TSQueryPredicateStep *predicate_list =3D - ts_query_predicates_for_pattern (query, pattern_index, &len); + const TSQueryPredicateStep *predicate_list + =3D ts_query_predicates_for_pattern (query, pattern_index, &len); Lisp_Object result =3D Qnil; Lisp_Object predicate =3D Qnil; for (int idx =3D 0; idx < len; idx++) @@ -2019,7 +2056,9 @@ treesit_predicate_capture_name_to_text (Lisp_Object n= ame, if (NILP (node)) xsignal3 (Qtreesit_query_error, build_pure_c_string ("Cannot find captured node"), - name, build_pure_c_string ("A predicate can only refer to captured = nodes in the same pattern")); + name, build_pure_c_string ("A predicate can only refer" + " to captured nodes in the " + "same pattern")); =20 struct buffer *old_buffer =3D current_buffer; set_buffer_internal (XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buff= er)); @@ -2038,17 +2077,20 @@ treesit_predicate_equal (Lisp_Object args, struct c= apture_range captures) { if (XFIXNUM (Flength (args)) !=3D 2) xsignal2 (Qtreesit_query_error, - build_pure_c_string ("Predicate `equal' requires two arguments but = only given"), + build_pure_c_string ("Predicate `equal' requires " + "two arguments but only given"), Flength (args)); =20 Lisp_Object arg1 =3D XCAR (args); Lisp_Object arg2 =3D XCAR (XCDR (args)); - Lisp_Object text1 =3D - STRINGP (arg1) ? arg1 : treesit_predicate_capture_name_to_text (arg1, - captures); - Lisp_Object text2 =3D - STRINGP (arg2) ? arg2 : treesit_predicate_capture_name_to_text (arg2, - captures); + Lisp_Object text1 =3D (STRINGP (arg1) + ? arg1 + : treesit_predicate_capture_name_to_text (arg1, + captures)); + Lisp_Object text2 =3D (STRINGP (arg2) + ? arg2 + : treesit_predicate_capture_name_to_text (arg2, + captures)); =20 return !NILP (Fstring_equal (text1, text2)); } @@ -2061,7 +2103,8 @@ treesit_predicate_match (Lisp_Object args, struct cap= ture_range captures) { if (XFIXNUM (Flength (args)) !=3D 2) xsignal2 (Qtreesit_query_error, - build_pure_c_string ("Predicate `equal' requires two arguments but = only given"), + build_pure_c_string ("Predicate `equal' requires two " + "arguments but only given"), Flength (args)); =20 Lisp_Object regexp =3D XCAR (args); @@ -2075,10 +2118,12 @@ treesit_predicate_match (Lisp_Object args, struct c= apture_range captures) string-match does.) */ if (!STRINGP (regexp)) xsignal1 (Qtreesit_query_error, - build_pure_c_string ("The first argument to `match' should be a reg= exp string, not a capture name")); + build_pure_c_string ("The first argument to `match' should " + "be a regexp string, not a capture name")); if (!SYMBOLP (capture_name)) xsignal1 (Qtreesit_query_error, - build_pure_c_string ("The second argument to `match' should be a ca= pture name, not a string")); + build_pure_c_string ("The second argument to `match' should " + "be a capture name, not a string")); =20 if (fast_string_match (regexp, text) >=3D 0) return true; @@ -2114,7 +2159,8 @@ treesit_eval_predicates (struct capture_range capture= s, Lisp_Object predicates) else xsignal3 (Qtreesit_query_error, build_pure_c_string ("Invalid predicate"), - fn, build_pure_c_string ("Currently Emacs only supports equal and matc= h predicate")); + fn, build_pure_c_string ("Currently Emacs only supports" + " equal and match predicate")); } /* If all predicates passed, add captures to result list. */ return pass; @@ -2224,12 +2270,14 @@ DEFUN ("treesit-query-capture", treesit_initialize (); =20 /* Extract C values from Lisp objects. */ - TSNode treesit_node =3D XTS_NODE (lisp_node)->node; - Lisp_Object lisp_parser =3D XTS_NODE (lisp_node)->parser; - ptrdiff_t visible_beg =3D - XTS_PARSER (XTS_NODE (lisp_node)->parser)->visible_beg; - const TSLanguage *lang =3D - ts_parser_language (XTS_PARSER (lisp_parser)->parser); + TSNode treesit_node + =3D XTS_NODE (lisp_node)->node; + Lisp_Object lisp_parser + =3D XTS_NODE (lisp_node)->parser; + ptrdiff_t visible_beg + =3D XTS_PARSER (XTS_NODE (lisp_node)->parser)->visible_beg; + const TSLanguage *lang + =3D ts_parser_language (XTS_PARSER (lisp_parser)->parser); =20 /* Initialize query objects. At the end of this block, we should have a working TSQuery and a TSQueryCursor. */ @@ -2259,10 +2307,11 @@ DEFUN ("treesit-query-capture", uint32_t error_offset; TSQueryError error_type; treesit_query =3D ts_query_new (lang, query_string, strlen (query_st= ring), - &error_offset, &error_type); + &error_offset, &error_type); if (treesit_query =3D=3D NULL) xsignal (Qtreesit_query_error, - treesit_compose_query_signal_data (error_offset, error_type)); + treesit_compose_query_signal_data (error_offset, + error_type)); cursor =3D ts_query_cursor_new (); needs_to_free_query_and_cursor =3D true; } @@ -2314,9 +2363,9 @@ DEFUN ("treesit-query-capture", Lisp_Object cap; if (NILP (node_only)) { - const char *capture_name =3D - ts_query_capture_name_for_id (treesit_query, capture.index, - &capture_name_len); + const char *capture_name + =3D ts_query_capture_name_for_id (treesit_query, capture.index, + &capture_name_len); cap =3D Fcons (intern_c_string_1 (capture_name, capture_name_len), captured_node); } @@ -2326,16 +2375,15 @@ DEFUN ("treesit-query-capture", result =3D Fcons (cap, result); } /* Get predicates. */ - Lisp_Object predicates =3D - treesit_predicates_for_pattern (treesit_query, match.pattern_index); + Lisp_Object predicates + =3D treesit_predicates_for_pattern (treesit_query, + match.pattern_index); =20 /* captures_lisp =3D Fnreverse (captures_lisp); */ struct capture_range captures_range =3D { result, prev_result }; if (!treesit_eval_predicates (captures_range, predicates)) - { - /* Predicates didn't pass, roll back. */ - result =3D prev_result; - } + /* Predicates didn't pass, roll back. */ + result =3D prev_result; } if (needs_to_free_query_and_cursor) { @@ -2348,8 +2396,7 @@ DEFUN ("treesit-query-capture", /*** Navigation */ =20 /* Return the next/previous named/unnamed sibling of NODE. FORWARD - controls the direction and NAMED controls the nameness. - */ + controls the direction and NAMED controls the nameness. */ static TSNode treesit_traverse_sibling_helper (TSNode node, bool forward, bool named) { @@ -2450,13 +2497,15 @@ treesit_search_dfs (TSNode *root, Lisp_Object pred,= Lisp_Object parser, return false; else { - int count =3D - named ? ts_node_named_child_count (node) : ts_node_child_count (node); + int count =3D (named + ? ts_node_named_child_count (node) + : ts_node_child_count (node)); for (int offset =3D 0; offset < count; offset++) { uint32_t idx =3D forward ? offset : count - offset - 1; - TSNode child =3D - named ? ts_node_named_child (node, idx) : ts_node_child (node, idx); + TSNode child =3D (named + ? ts_node_named_child (node, idx) + : ts_node_child (node, idx)); =20 if (!ts_node_is_null (child) && treesit_search_dfs (&child, pred, parser, named, @@ -2654,11 +2703,9 @@ treesit_build_sparse_tree (TSTreeCursor *cursor, Lis= p_Object parent, } /* Before we go, reverse children in the sparse tree. */ if (match) - { - /* When match =3D=3D true, "parent" is actually the node we added in - this layer (parent =3D this). */ - Fsetcdr (parent, Fnreverse (Fcdr (parent))); - } + /* When match =3D=3D true, "parent" is actually the node we added in + this layer (parent =3D this). */ + Fsetcdr (parent, Fnreverse (Fcdr (parent))); } =20 DEFUN ("treesit-induce-sparse-tree", @@ -2782,6 +2829,7 @@ syms_of_treesit (void) DEFSYM (Quser_emacs_directory, "user-emacs-directory"); DEFSYM (Qtreesit_parser_deleted, "treesit-parser-deleted"); + DEFSYM (Qtreesit_pattern_expand, "treesit-pattern-expand"); =20 DEFSYM (Qor, "or"); =20 @@ -2886,6 +2934,6 @@ syms_of_treesit (void) defsubr (&Streesit_search_subtree); defsubr (&Streesit_search_forward); defsubr (&Streesit_induce_sparse_tree); -#endif /* HAVE_TREE_SITTER */ +#endif /* HAVE_TREE_SITTER */ defsubr (&Streesit_available_p); } diff --git a/src/treesit.h b/src/treesit.h index 60f1a0ceaf..1538995671 100644 --- a/src/treesit.h +++ b/src/treesit.h @@ -169,16 +169,10 @@ CHECK_TS_COMPILED_QUERY (Lisp_Object query) Qtreesit_compiled_query_p, query); } =20 -void -treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, - ptrdiff_t new_end_byte); - -Lisp_Object -make_treesit_parser (Lisp_Object buffer, TSParser *parser, - TSTree *tree, Lisp_Object language_symbol); - -Lisp_Object -make_treesit_node (Lisp_Object parser, TSNode node); +extern void treesit_record_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); +extern Lisp_Object make_treesit_parser (Lisp_Object, TSParser *, TSTree *, + Lisp_Object); +extern Lisp_Object make_treesit_node (Lisp_Object, TSNode); =20 extern void treesit_delete_parser (struct Lisp_TS_Parser *); extern void treesit_delete_query (struct Lisp_TS_Query *); --=20 2.37.3