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: Sat, 29 Oct 2022 10:45:47 +0800 Message-ID: <875yg34aas.fsf@yahoo.com> References: <87h6zp75nt.fsf.ref@yahoo.com> <87h6zp75nt.fsf@yahoo.com> <87h6zptloj.fsf@gmail.com> <87y1t06apv.fsf@yahoo.com> <87k04ksa4f.fsf@gmail.com> <87k04k5stm.fsf@yahoo.com> Reply-To: Po Lu Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="5325"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: , Yuan Fu To: Robert Pluim Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Oct 29 04:47:25 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 1oobsb-0001Cw-1w for ged-emacs-devel@m.gmane-mx.org; Sat, 29 Oct 2022 04:47:25 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oobrd-0002tg-5p; Fri, 28 Oct 2022 22:46:25 -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 1oobrJ-0002t4-Qo for emacs-devel@gnu.org; Fri, 28 Oct 2022 22:46:10 -0400 Original-Received: from sonic303-20.consmr.mail.ne1.yahoo.com ([66.163.188.146]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oobrF-00018y-Eh for emacs-devel@gnu.org; Fri, 28 Oct 2022 22:46:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1667011557; bh=x/aeDpZNI2y/0KVnHjyNM08VqWWI+rOpqvLgm2zcpWM=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From:Subject:Reply-To; b=ZJ5w3Ha1L4O7eNEus6iftjIhkN1ZpzkUlr/deCe+i491o3k49xUKStYA6j/urcYVuo8WfQUCZLbtICu8HCTVQ8264jzdWhnW7zCdFr3nMIwAu8j1TiI4IwX9OnuQkA+RaiOZ6DFn05+WuvFSHThsvlbiKUPHIVuPeGT71931zcr0d95Yb2slDeczDZ3ENiF0xoJXCAt+wrfuHhTDwsRbOAVrFEmUsB1kdeoA0Hez77bGwFoKXoap2k+Zj+pEJlo/mjO/QdilUpQgTQRfnKeMA8Jq+Xwy+00t1/G14vKIC5utVqbGfpoAWOCGp6V+rGS/o0w9qdRmO9m62OFjFnFdVQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1667011557; bh=2iRyqcHZvo1BjfSNaFZ147nMFEFt+UWe6xoSb9kxgWw=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=tm8e+NgFMP76bCCzNxu4rVBqa1JR/DLyTRFvH6U2wD29wHhdcaFrnqH35hdslocQUSi3BltSHLu+uliw671NxEfx3HkApqEktZrIUW/IQ918ILSE4c8udnr9jUX9c85toU2mQWqLTzJx4lADC47HwqlZf635uXExQ3HlYPtbQbdZbYT1hDIx8gWQXDCMzgR2atNFUfK0IHg7fBV8Fel18Dw75RpjEGOGFeMXN5SRUXnZpY9S3xmfIvugYl4oeBN2wiEp7qNSxo2V8s7ERkYEou1y1T9SPPyxKasYoXFdL/kHoY/KoHz9HK2eG/X448MGSoWL76aN3vzNfLupjOaI2g== X-YMail-OSG: ZMbMCJsVM1m7zXeVz5C5jZYZBEdEQZNAGWnIRi_Kdw52btVHqlfpLmQpZWscPwU BpxR3avfcwOMbNwCjBgyObhXoKWHPp_UOgVWhQgMqOLW0jbJtCRbl4a7NUATfzT90HI1ha3zwFay GgkyBYACS38kEowNrjBrxFqn3_n4aR70h91eA2_rKSuhZPQLwJRoIcTNGesCIYR1sT8QuvvToI6. E65E3zUuVZZNLz.tXMMkM.IPVxTY8H4hbanah8k2kEXdcWXPG320osgYCTIAE1XrV7XnlWePQNXP yEtBd63Dzgkc2aYGgKqISjwoBu8LY8HxPyZsqZI7pk.XIE1rKiPyLB2Y.A_XGEhJjXhvdg.H5Koh 5SmzrWc7lHxWB9Z3rW0_iBPzG5CLbxLc4fYPs1zJIXT2Psa3TFWkH8xc5TCPPqGiJeQ6Xwu_fVrf qKQ6oCYJ_W.5zfM6hIwDZKoIaxnWWHaUF0Enpq7CacmVBpyPTfwZfVDjOyBHgQnOdn46iHZ3dZeh 3glAieCyZxytxRtRrcGbWVm2mi9LGQ8DMusnGCh6ptYOgPq8nPBDgRb3nkOcLj3zdWZK0FczVmua Lbwmnfv0FNSUP0zSw1z3PFH7bwrOGUUU7qbrYrEklgObXIPupEyH0qgR2gu_QFdb_otVc0.1.AfG q8HtinK.C66VSSOb.qxw8xFxed7GbPFtjnJ9fgXoJo.MmvOW2Ysns1XiknzSEKiqXdd3C90nolH7 0nEPBry4HgNrKgdGEVQ_IEXAacmmM6JChPliBKT8.0anN8PUQaaOFkl0s5TwCJBr7BlRQx3Bn4pR vE42hbQM4dJtzgxCJ6I8u0_9tr462D.Y.ZaH3dP6og X-Sonic-MF: Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic303.consmr.mail.ne1.yahoo.com with HTTP; Sat, 29 Oct 2022 02:45:57 +0000 Original-Received: by hermes--production-sg3-74fb94585-wlrr8 (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 2dc5b2d0d23a4971c0f13c857fdd6f12; Sat, 29 Oct 2022 02:45:52 +0000 (UTC) In-Reply-To: <87k04k5stm.fsf@yahoo.com> (Po Lu's message of "Fri, 28 Oct 2022 15:08:05 +0800") 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.188.146; envelope-from=luangruo@yahoo.com; helo=sonic303-20.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:298708 Archived-At: Po Lu writes: > Robert Pluim writes: > >> Yep, that compiles. > > Right. Yuan Fu, can you see if it works or not? Oops, looks like I forgot to copy him in. Yuan, could you please see if the following patch works or not? >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 = mumble (frob (bar), (foo () + bar ()) + (baz () + quux ())) which should actually be variable = mumble (frob (bar), (foo () + bar ()) + (baz () + quux ())) and foo = mumble (frob (bar), 0) + (foo () + bar ()) + (baz () + quux ()) which should actually be foo = (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: - - 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. - - 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. - 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 - 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. 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. 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. 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 + :-) */ /*** 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 = Vtreesit_load_name_override_list; - !NILP (list); list = XCDR (list)) + + FOR_EACH_TAIL (tem) { - Lisp_Object lang = XCAR (XCAR (list)); + Lisp_Object lang = XCAR (XCAR (tem)); CHECK_SYMBOL (lang); + if (EQ (lang, language_symbol)) { - *name = Fnth (make_fixnum (1), XCAR (list)); + *name = Fnth (make_fixnum (1), XCAR (tem)); CHECK_STRING (*name); - *c_symbol = Fnth (make_fixnum (2), XCAR (list)); + *c_symbol = Fnth (make_fixnum (2), XCAR (tem)); CHECK_STRING (*c_symbol); + return true; } } + + CHECK_LIST_END (tem, Vtreesit_load_name_override_list); + return false; } @@ -475,12 +486,13 @@ treesit_find_override_name (Lisp_Object language_symbol, Lisp_Object *name, treesit_load_language_push_for_each_suffix (Lisp_Object lib_base_name, Lisp_Object *path_candidates) { - for (Lisp_Object suffixes = Vdynamic_library_suffixes; - !NILP (suffixes); suffixes = XCDR (suffixes)) - { - *path_candidates = Fcons (concat2 (lib_base_name, XCAR (suffixes)), - *path_candidates); - } + Lisp_Object suffixes; + + suffixes = Vdynamic_library_suffixes; + + FOR_EACH_TAIL (suffixes) + *path_candidates = Fcons (concat2 (lib_base_name, XCAR (suffixes)), + *path_candidates); } /* 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); /* Figure out the library name and C name. */ - Lisp_Object lib_base_name = - concat2 (build_pure_c_string ("libtree-sitter-"), symbol_name); - Lisp_Object base_name = - concat2 (build_pure_c_string ("tree-sitter-"), symbol_name); + Lisp_Object lib_base_name + = concat2 (build_pure_c_string ("libtree-sitter-"), symbol_name); + Lisp_Object base_name + = concat2 (build_pure_c_string ("tree-sitter-"), symbol_name); /* 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 = override_name; + lib_base_name = override_name; /* Now we generate a list of possible library paths. */ Lisp_Object path_candidates = 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 = path_candidates; /* Then push ~/.emacs.d/tree-sitter paths. */ - Lisp_Object lib_name = - Fexpand_file_name (concat2 (build_string ("tree-sitter/"), lib_base_name), - Fsymbol_value (Quser_emacs_directory)); + Lisp_Object lib_name + = Fexpand_file_name (concat2 (build_string ("tree-sitter/"), lib_base_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 = Freverse (Vtreesit_extra_load_path); - !NILP (tail); tail = XCDR (tail)) + Lisp_Object tail; + + tail = Freverse (Vtreesit_extra_load_path); + + FOR_EACH_TAIL (tail) { Lisp_Object expanded_lib = 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 = path_candidates; - !NILP (tail); tail = XCDR (tail)) + + tail = path_candidates; + + FOR_EACH_TAIL (tail) { char *library_name = SSDATA (XCAR (tail)); dynlib_error (); @@ -547,6 +564,7 @@ treesit_load_language (Lisp_Object language_symbol, if (error == NULL) break; } + if (error != NULL) { *signal_symbol = Qtreesit_load_language_error; @@ -587,8 +605,7 @@ treesit_load_language (Lisp_Object language_symbol, return lang; } -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_byte, } /* 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 = BVAR (current_buffer, ts_parser_list); - !NILP (parser_list); - parser_list = XCDR (parser_list)) + Lisp_Object parser_list; + + parser_list = BVAR (current_buffer, ts_parser_list); + + FOR_EACH_TAIL_SAFE (parser_list) { CHECK_CONS (parser_list); Lisp_Object lisp_parser = 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 = - min (visible_end, - max (visible_beg, start_byte)) - visible_beg; - ptrdiff_t old_end_offset = - min (visible_end, - max (visible_beg, old_end_byte)) - visible_beg; - ptrdiff_t new_end_offset = - min (visible_end, - max (visible_beg, new_end_byte)) - visible_beg; + ptrdiff_t start_offset = (min (visible_end, + max (visible_beg, start_byte)) + - visible_beg); + ptrdiff_t old_end_offset = (min (visible_end, + max (visible_beg, old_end_byte)) + - visible_beg); + ptrdiff_t new_end_offset = (min (visible_end, + max (visible_beg, new_end_byte)) + - visible_beg); eassert (start_offset <= old_end_offset); eassert (start_offset <= new_end_offset); @@ -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 = - min (visible_beg, new_end_byte) - - min (visible_beg, old_end_byte); - } + /* Move backward. */ + visi_beg_delta = (min (visible_beg, new_end_byte) + - min (visible_beg, old_end_byte)); else - { - /* Move forward. */ - visi_beg_delta = - old_end_byte < visible_beg ? new_end_byte - old_end_byte : 0; - } + /* Move forward. */ + visi_beg_delta = (old_end_byte < visible_beg + ? new_end_byte - old_end_byte : 0); XTS_PARSER (lisp_parser)->visible_beg = visible_beg + visi_beg_delta; - XTS_PARSER (lisp_parser)->visible_end - = visible_end + visi_beg_delta + (new_end_offset - old_end_offset); + XTS_PARSER (lisp_parser)->visible_end = (visible_end + + visi_beg_delta + + (new_end_offset + - old_end_offset)); eassert (XTS_PARSER (lisp_parser)->visible_beg >= 0); eassert (XTS_PARSER (lisp_parser)->visible_beg <= XTS_PARSER (lisp_parser)->visible_end); @@ -826,7 +842,7 @@ treesit_check_buffer_size (struct buffer *buffer) } /* 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_index, return beg; } -/*** Functions for parser and node object*/ +/*** Functions for parser and node object */ -/* 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 = - ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Parser, buffer, PVEC_TS_PARSER); + struct Lisp_TS_Parser *lisp_parser; + + lisp_parser = ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Parser, + buffer, PVEC_TS_PARSER); lisp_parser->language_symbol = language_symbol; lisp_parser->buffer = buffer; @@ -942,8 +961,10 @@ make_treesit_parser (Lisp_Object buffer, TSParser *parser, Lisp_Object make_treesit_node (Lisp_Object parser, TSNode node) { - struct Lisp_TS_Node *lisp_node = - ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Node, parser, PVEC_TS_NODE); + struct Lisp_TS_Node *lisp_node; + + lisp_node = ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Node, + parser, PVEC_TS_NODE); lisp_node->parser = parser; lisp_node->node = node; lisp_node->timestamp = 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 = ts_query_cursor_new (); - struct Lisp_TS_Query *lisp_query = - ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Query, source, - PVEC_TS_COMPILED_QUERY); + struct Lisp_TS_Query *lisp_query; + + lisp_query = ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Query, + source, PVEC_TS_COMPILED_QUERY); lisp_query->language = language; lisp_query->source = query; @@ -1178,8 +1200,9 @@ DEFUN ("treesit-parser-create", ts_parser_set_language (parser, lang); /* Create parser. */ - Lisp_Object lisp_parser - = make_treesit_parser (Fcurrent_buffer (), parser, NULL, language); + Lisp_Object lisp_parser = make_treesit_parser (Fcurrent_buffer (), + parser, NULL, + language); /* Update parser-list. */ BVAR (buf, ts_parser_list) = Fcons (lisp_parser, BVAR (buf, ts_parser_list)); @@ -1198,7 +1221,9 @@ DEFUN ("treesit-parser-delete", Lisp_Object buffer = XTS_PARSER (parser)->buffer; struct buffer *buf = XBUFFER (buffer); - BVAR (buf, ts_parser_list) = Fdelete (parser, BVAR (buf, ts_parser_list)); + + BVAR (buf, ts_parser_list) + = Fdelete (parser, BVAR (buf, ts_parser_list)); XTS_PARSER (parser)->deleted = 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 = Qnil; - for (Lisp_Object tail = BVAR (buf, ts_parser_list); - !NILP (tail); - tail = XCDR (tail)) - { - return_list = Fcons (XCAR (tail), return_list); - } + Lisp_Object tail; + + tail = BVAR (buf, ts_parser_list); + + FOR_EACH_TAIL (tail) + return_list = Fcons (XCAR (tail), return_list); + return Freverse (return_list); } @@ -1278,8 +1304,13 @@ treesit_check_range_argument (Lisp_Object ranges) ptrdiff_t point_min = BUF_BEGV (buffer); ptrdiff_t point_max = BUF_ZV (buffer); EMACS_INT last_point = point_min; + Lisp_Object tail; + + tail = ranges; - for (Lisp_Object tail = ranges; !NILP (tail); tail = XCDR (tail)) + CHECK_LIST (tail); + + FOR_EACH_TAIL (tail) { CHECK_CONS (tail); Lisp_Object range = XCAR (tail); @@ -1290,10 +1321,13 @@ treesit_check_range_argument (Lisp_Object ranges) EMACS_INT end = XFIXNUM (XCDR (range)); if (!(last_point <= beg && beg <= end && end <= point_max)) xsignal2 (Qtreesit_range_invalid, - build_pure_c_string ("RANGE is either overlapping or out-of-order or out-of-range"), + build_pure_c_string ("RANGE is either overlapping," + " out-of-order or out-of-range"), ranges); last_point = end; } + + CHECK_LIST_END (tail, ranges); } 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 = - ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len); + const TSRange *ranges + = ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len); if (len == 0) return Qnil; @@ -1407,9 +1441,9 @@ DEFUN ("treesit-parser-included-ranges", eassert (beg_byte <= end_byte); eassert (end_byte <= BUF_ZV_BYTE (buffer)); - Lisp_Object lisp_range = - Fcons (make_fixnum (buf_bytepos_to_charpos (buffer, beg_byte)) , - make_fixnum (buf_bytepos_to_charpos (buffer, end_byte))); + Lisp_Object lisp_range + = Fcons (make_fixnum (buf_bytepos_to_charpos (buffer, beg_byte)), + make_fixnum (buf_bytepos_to_charpos (buffer, end_byte))); list = Fcons (lisp_range, list); } return Fnreverse (list); @@ -1464,10 +1498,11 @@ DEFUN ("treesit-node-start", TSNode treesit_node = XTS_NODE (node)->node; ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; uint32_t start_byte_offset = ts_node_start_byte (treesit_node); - struct buffer *buffer = - XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); - ptrdiff_t start_pos = - buf_bytepos_to_charpos (buffer, start_byte_offset + visible_beg); + struct buffer *buffer + = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); + ptrdiff_t start_pos + = buf_bytepos_to_charpos (buffer, + start_byte_offset + visible_beg); return make_fixnum (start_pos); } @@ -1484,10 +1519,10 @@ DEFUN ("treesit-node-end", TSNode treesit_node = XTS_NODE (node)->node; ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; uint32_t end_byte_offset = ts_node_end_byte (treesit_node); - struct buffer *buffer = - XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); - ptrdiff_t end_pos = - buf_bytepos_to_charpos (buffer, end_byte_offset + visible_beg); + struct buffer *buffer + = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); + ptrdiff_t end_pos + = buf_bytepos_to_charpos (buffer, end_byte_offset + visible_beg); return make_fixnum (end_pos); } @@ -1611,7 +1646,8 @@ DEFUN ("treesit-node-check", else if (EQ (property, Qhas_changes)) result = 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 = SSDATA (field_name); TSNode treesit_node = XTS_NODE (node)->node; TSNode child - = ts_node_child_by_field_name (treesit_node, name_str, strlen (name_str)); + = ts_node_child_by_field_name (treesit_node, name_str, + strlen (name_str)); 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 = - build_pure_c_string (VECTORP (pattern) ? "[" : "("); - Lisp_Object closing_delimiter = - build_pure_c_string (VECTORP (pattern) ? "]" : ")"); + Lisp_Object opening_delimeter + = build_pure_c_string (VECTORP (pattern) ? "[" : "("); + Lisp_Object closing_delimiter + = 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); } /* 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 = - ts_query_predicates_for_pattern (query, pattern_index, &len); + const TSQueryPredicateStep *predicate_list + = ts_query_predicates_for_pattern (query, pattern_index, &len); Lisp_Object result = Qnil; Lisp_Object predicate = Qnil; for (int idx = 0; idx < len; idx++) @@ -2019,7 +2056,9 @@ treesit_predicate_capture_name_to_text (Lisp_Object name, 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")); struct buffer *old_buffer = current_buffer; set_buffer_internal (XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer)); @@ -2038,17 +2077,20 @@ treesit_predicate_equal (Lisp_Object args, struct capture_range captures) { if (XFIXNUM (Flength (args)) != 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)); Lisp_Object arg1 = XCAR (args); Lisp_Object arg2 = XCAR (XCDR (args)); - Lisp_Object text1 = - STRINGP (arg1) ? arg1 : treesit_predicate_capture_name_to_text (arg1, - captures); - Lisp_Object text2 = - STRINGP (arg2) ? arg2 : treesit_predicate_capture_name_to_text (arg2, - captures); + Lisp_Object text1 = (STRINGP (arg1) + ? arg1 + : treesit_predicate_capture_name_to_text (arg1, + captures)); + Lisp_Object text2 = (STRINGP (arg2) + ? arg2 + : treesit_predicate_capture_name_to_text (arg2, + captures)); return !NILP (Fstring_equal (text1, text2)); } @@ -2061,7 +2103,8 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures) { if (XFIXNUM (Flength (args)) != 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)); Lisp_Object regexp = XCAR (args); @@ -2075,10 +2118,12 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures) string-match does.) */ if (!STRINGP (regexp)) xsignal1 (Qtreesit_query_error, - build_pure_c_string ("The first argument to `match' should be a regexp 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 capture name, not a string")); + build_pure_c_string ("The second argument to `match' should " + "be a capture name, not a string")); if (fast_string_match (regexp, text) >= 0) return true; @@ -2114,7 +2159,8 @@ treesit_eval_predicates (struct capture_range captures, 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 match 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 (); /* Extract C values from Lisp objects. */ - TSNode treesit_node = XTS_NODE (lisp_node)->node; - Lisp_Object lisp_parser = XTS_NODE (lisp_node)->parser; - ptrdiff_t visible_beg = - XTS_PARSER (XTS_NODE (lisp_node)->parser)->visible_beg; - const TSLanguage *lang = - ts_parser_language (XTS_PARSER (lisp_parser)->parser); + TSNode treesit_node + = XTS_NODE (lisp_node)->node; + Lisp_Object lisp_parser + = XTS_NODE (lisp_node)->parser; + ptrdiff_t visible_beg + = XTS_PARSER (XTS_NODE (lisp_node)->parser)->visible_beg; + const TSLanguage *lang + = ts_parser_language (XTS_PARSER (lisp_parser)->parser); /* 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 = ts_query_new (lang, query_string, strlen (query_string), - &error_offset, &error_type); + &error_offset, &error_type); if (treesit_query == NULL) xsignal (Qtreesit_query_error, - treesit_compose_query_signal_data (error_offset, error_type)); + treesit_compose_query_signal_data (error_offset, + error_type)); cursor = ts_query_cursor_new (); needs_to_free_query_and_cursor = true; } @@ -2314,9 +2363,9 @@ DEFUN ("treesit-query-capture", Lisp_Object cap; if (NILP (node_only)) { - const char *capture_name = - ts_query_capture_name_for_id (treesit_query, capture.index, - &capture_name_len); + const char *capture_name + = ts_query_capture_name_for_id (treesit_query, capture.index, + &capture_name_len); cap = Fcons (intern_c_string_1 (capture_name, capture_name_len), captured_node); } @@ -2326,16 +2375,15 @@ DEFUN ("treesit-query-capture", result = Fcons (cap, result); } /* Get predicates. */ - Lisp_Object predicates = - treesit_predicates_for_pattern (treesit_query, match.pattern_index); + Lisp_Object predicates + = treesit_predicates_for_pattern (treesit_query, + match.pattern_index); /* captures_lisp = Fnreverse (captures_lisp); */ struct capture_range captures_range = { result, prev_result }; if (!treesit_eval_predicates (captures_range, predicates)) - { - /* Predicates didn't pass, roll back. */ - result = prev_result; - } + /* Predicates didn't pass, roll back. */ + result = prev_result; } if (needs_to_free_query_and_cursor) { @@ -2348,8 +2396,7 @@ DEFUN ("treesit-query-capture", /*** Navigation */ /* 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 = - named ? ts_node_named_child_count (node) : ts_node_child_count (node); + int count = (named + ? ts_node_named_child_count (node) + : ts_node_child_count (node)); for (int offset = 0; offset < count; offset++) { uint32_t idx = forward ? offset : count - offset - 1; - TSNode child = - named ? ts_node_named_child (node, idx) : ts_node_child (node, idx); + TSNode child = (named + ? ts_node_named_child (node, idx) + : ts_node_child (node, idx)); if (!ts_node_is_null (child) && treesit_search_dfs (&child, pred, parser, named, @@ -2654,11 +2703,9 @@ treesit_build_sparse_tree (TSTreeCursor *cursor, Lisp_Object parent, } /* Before we go, reverse children in the sparse tree. */ if (match) - { - /* When match == true, "parent" is actually the node we added in - this layer (parent = this). */ - Fsetcdr (parent, Fnreverse (Fcdr (parent))); - } + /* When match == true, "parent" is actually the node we added in + this layer (parent = this). */ + Fsetcdr (parent, Fnreverse (Fcdr (parent))); } 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"); DEFSYM (Qor, "or"); @@ -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); } -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); extern void treesit_delete_parser (struct Lisp_TS_Parser *); extern void treesit_delete_query (struct Lisp_TS_Query *); -- 2.37.3