unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Stylistic changes to tree-sitter code
       [not found] <87h6zp75nt.fsf.ref@yahoo.com>
@ 2022-10-27 13:33 ` Po Lu via Emacs development discussions.
  2022-10-27 13:56   ` Robert Pluim
  0 siblings, 1 reply; 15+ messages in thread
From: Po Lu via Emacs development discussions. @ 2022-10-27 13:33 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 785 bytes --]

I tried to fix much of the broken style in treesit.c, mainly instances
of:

  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 ()))

I also changed many places to use FOR_EACH_TAIL and handle circular
lists in user input correctly.

Unfortunately, I don't have tree-sitter installed, so would someone
please do a smoke test on the changes before I install them?

In addition, I tried to improve the wording of the comments.  But that's
not the important part.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Stylistic-changes-to-tree-sitter-code.patch --]
[-- Type: text/x-patch, Size: 32487 bytes --]

From f4464832179fcae4897097e3bb7431b342da39dd Mon Sep 17 00:00:00 2001
From: Po Lu <luangruo@yahoo.com>
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 | 383 ++++++++++++++++++++++++++++----------------------
 src/treesit.h |  14 +-
 2 files changed, 220 insertions(+), 177 deletions(-)

diff --git a/src/treesit.c b/src/treesit.c
index e4be065d94..7cff8046d7 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
+   :-) */
 
 \f
 /*** 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));
 	  CHECK_STRING (*name);
 	  *c_symbol = Fnth (make_fixnum (2), XCAR (list));
 	  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,11 @@ 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))
+  Lisp_Object tail;
+
+  tail = path_candidates;
+
+  FOR_EACH_TAIL (tail)
     {
       char *library_name = SSDATA (XCAR (tail));
       dynlib_error ();
@@ -547,6 +565,7 @@ treesit_load_language (Lisp_Object language_symbol,
       if (error == NULL)
 	break;
     }
+
   if (error != NULL)
     {
       *signal_symbol = Qtreesit_load_language_error;
@@ -587,8 +606,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 +686,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 +719,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 +741,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 +843,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 +930,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 +962,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 +978,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 +1201,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 +1222,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 +1248,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 +1305,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 +1322,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 +1420,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 +1442,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 +1499,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 +1520,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 +1647,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 +1731,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 +1938,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 +1975,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 +2000,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 +2057,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 +2078,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 +2104,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 +2119,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 +2160,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 +2271,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 +2308,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 +2364,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 +2376,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 +2397,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 +2498,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 +2704,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 +2830,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 +2935,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


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-27 13:33 ` Stylistic changes to tree-sitter code Po Lu via Emacs development discussions.
@ 2022-10-27 13:56   ` Robert Pluim
  2022-10-28  0:41     ` Po Lu via Emacs development discussions.
  0 siblings, 1 reply; 15+ messages in thread
From: Robert Pluim @ 2022-10-27 13:56 UTC (permalink / raw)
  To: Po Lu via Emacs development discussions.; +Cc: Po Lu

>>>>> On Thu, 27 Oct 2022 21:33:10 +0800, Po Lu via "Emacs development discussions." <emacs-devel@gnu.org> said:


    Po Lu> Unfortunately, I don't have tree-sitter installed, so would someone
    Po Lu> please do a smoke test on the changes before I install them?

I have it installed, but I donʼt use it yet, so all I can offer is a
compile test:

  CC       treesit.o
treesit.c: In function ‘treesit_find_override_name’:
treesit.c:467:41: error: ‘list’ undeclared (first use in this function); did you mean ‘listn’?
  467 |    *name = 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 ‘;’ before ‘return’
  476 |   CHECK_LIST_END (tem, Vtreesit_load_name_override_list)
      |                                                         ^
      |                                                         ;
  477 | 
  478 |   return false;
      |   ~~~~~~                                                 
treesit.c: In function ‘treesit_load_language’:
treesit.c:555:15: error: redeclaration of ‘tail’ with no linkage
  555 |   Lisp_Object tail;
      |               ^~~~
treesit.c:539:15: note: previous declaration of ‘tail’ was here
  539 |   Lisp_Object tail;
      |               ^~~~
treesit.c: In function ‘treesit_find_override_name’:
treesit.c:479:1: warning: control reaches end of non-void function [-Wreturn-type]
  479 | }
      | ^
make[2]: *** [Makefile:424: treesit.o] Error 1

Robert
-- 



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-27 13:56   ` Robert Pluim
@ 2022-10-28  0:41     ` Po Lu via Emacs development discussions.
  2022-10-28  4:14       ` Yuan Fu
  2022-10-28  7:03       ` Robert Pluim
  0 siblings, 2 replies; 15+ messages in thread
From: Po Lu via Emacs development discussions. @ 2022-10-28  0:41 UTC (permalink / raw)
  To: Robert Pluim; +Cc: Po Lu via Emacs development discussions.

Robert Pluim <rpluim@gmail.com> writes:

>>>>>> On Thu, 27 Oct 2022 21:33:10 +0800, Po Lu via "Emacs development discussions." <emacs-devel@gnu.org> said:
>
>
>     Po Lu> Unfortunately, I don't have tree-sitter installed, so would someone
>     Po Lu> please do a smoke test on the changes before I install them?
>
> I have it installed, but I donʼt use it yet, so all I can offer is a
> compile test:
>
>   CC       treesit.o
> treesit.c: In function ‘treesit_find_override_name’:
> treesit.c:467:41: error: ‘list’ undeclared (first use in this function); did you mean ‘listn’?
>   467 |    *name = 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 ‘;’ before ‘return’
>   476 |   CHECK_LIST_END (tem, Vtreesit_load_name_override_list)
>       |                                                         ^
>       |                                                         ;
>   477 | 
>   478 |   return false;
>       |   ~~~~~~                                                 
> treesit.c: In function ‘treesit_load_language’:
> treesit.c:555:15: error: redeclaration of ‘tail’ with no linkage
>   555 |   Lisp_Object tail;
>       |               ^~~~
> treesit.c:539:15: note: previous declaration of ‘tail’ was here
>   539 |   Lisp_Object tail;
>       |               ^~~~
> treesit.c: In function ‘treesit_find_override_name’:
> treesit.c:479:1: warning: control reaches end of non-void function [-Wreturn-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 <luangruo@yahoo.com>
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
+   :-) */
 
 \f
 /*** 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




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-28  0:41     ` Po Lu via Emacs development discussions.
@ 2022-10-28  4:14       ` Yuan Fu
  2022-10-28  7:03       ` Robert Pluim
  1 sibling, 0 replies; 15+ messages in thread
From: Yuan Fu @ 2022-10-28  4:14 UTC (permalink / raw)
  To: Po Lu; +Cc: Robert Pluim, Po Lu via Emacs development discussions.



> On Oct 27, 2022, at 5:41 PM, Po Lu via Emacs development discussions. <emacs-devel@gnu.org> wrote:
> 
> Robert Pluim <rpluim@gmail.com> writes:
> 
>>>>>>> On Thu, 27 Oct 2022 21:33:10 +0800, Po Lu via "Emacs development discussions." <emacs-devel@gnu.org> said:
>> 
>> 
>>    Po Lu> Unfortunately, I don't have tree-sitter installed, so would someone
>>    Po Lu> please do a smoke test on the changes before I install them?
>> 
>> I have it installed, but I donʼt use it yet, so all I can offer is a
>> compile test:
>> 
>>  CC       treesit.o
>> treesit.c: In function ‘treesit_find_override_name’:
>> treesit.c:467:41: error: ‘list’ undeclared (first use in this function); did you mean ‘listn’?
>>  467 |    *name = 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 ‘;’ before ‘return’
>>  476 |   CHECK_LIST_END (tem, Vtreesit_load_name_override_list)
>>      |                                                         ^
>>      |                                                         ;
>>  477 | 
>>  478 |   return false;
>>      |   ~~~~~~                                                 
>> treesit.c: In function ‘treesit_load_language’:
>> treesit.c:555:15: error: redeclaration of ‘tail’ with no linkage
>>  555 |   Lisp_Object tail;
>>      |               ^~~~
>> treesit.c:539:15: note: previous declaration of ‘tail’ was here
>>  539 |   Lisp_Object tail;
>>      |               ^~~~
>> treesit.c: In function ‘treesit_find_override_name’:
>> treesit.c:479:1: warning: control reaches end of non-void function [-Wreturn-type]
>>  479 | }
>>      | ^
>> make[2]: *** [Makefile:424: treesit.o] Error 1
>> 
>> Robert
> 
> Thanks.  What about this patch?

Thanks for your work! I don’t have opinions on stylistic changes :-)

Yuan


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-28  0:41     ` Po Lu via Emacs development discussions.
  2022-10-28  4:14       ` Yuan Fu
@ 2022-10-28  7:03       ` Robert Pluim
  2022-10-28  7:08         ` Po Lu
  1 sibling, 1 reply; 15+ messages in thread
From: Robert Pluim @ 2022-10-28  7:03 UTC (permalink / raw)
  To: Po Lu; +Cc: emacs-devel

>>>>> On Fri, 28 Oct 2022 08:41:32 +0800, Po Lu <luangruo@yahoo.com> said:
    Po Lu> Thanks.  What about this patch?

Yep, that compiles.

Robert
-- 



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-28  7:03       ` Robert Pluim
@ 2022-10-28  7:08         ` Po Lu
  2022-10-29  2:45           ` Po Lu via Emacs development discussions.
  0 siblings, 1 reply; 15+ messages in thread
From: Po Lu @ 2022-10-28  7:08 UTC (permalink / raw)
  To: Robert Pluim; +Cc: emacs-devel

Robert Pluim <rpluim@gmail.com> writes:

> Yep, that compiles.

Right.  Yuan Fu, can you see if it works or not?



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-28  7:08         ` Po Lu
@ 2022-10-29  2:45           ` Po Lu via Emacs development discussions.
  2022-10-29  4:19             ` Yuan Fu
  0 siblings, 1 reply; 15+ messages in thread
From: Po Lu via Emacs development discussions. @ 2022-10-29  2:45 UTC (permalink / raw)
  To: Robert Pluim; +Cc: emacs-devel, Yuan Fu

Po Lu <luangruo@yahoo.com> writes:

> Robert Pluim <rpluim@gmail.com> 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 <luangruo@yahoo.com>
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
+   :-) */
 
 \f
 /*** 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



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-29  2:45           ` Po Lu via Emacs development discussions.
@ 2022-10-29  4:19             ` Yuan Fu
  2022-10-29  5:44               ` Po Lu
                                 ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Yuan Fu @ 2022-10-29  4:19 UTC (permalink / raw)
  To: Po Lu; +Cc: Robert Pluim, emacs-devel

Ah, yes, the patch compiles fine, though there is a segfault: I believe you forgot to initialized the tem variable.

@@ -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;
 }
 
Also, out of curiosity, I thought active voice is good and passive voice is bad? Though the subject here doesn’t add any useful information, I recon.

-   - 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.


Yuan


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-29  4:19             ` Yuan Fu
@ 2022-10-29  5:44               ` Po Lu
  2022-10-29  7:01                 ` Eli Zaretskii
  2022-10-29  6:54               ` Eli Zaretskii
  2022-10-29  7:29               ` Stefan Kangas
  2 siblings, 1 reply; 15+ messages in thread
From: Po Lu @ 2022-10-29  5:44 UTC (permalink / raw)
  To: Yuan Fu; +Cc: Robert Pluim, emacs-devel

Yuan Fu <casouri@gmail.com> writes:

> Ah, yes, the patch compiles fine, though there is a segfault: I
> believe you forgot to initialized the tem variable.
>
> @@ -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;
>  }

Right, so if you add "tem = Vtreesit_load_name_override_list" above
"FOR_EACH_TAIL (tem)", does it work?

> Also, out of curiosity, I thought active voice is good and passive
> voice is bad? Though the subject here doesn’t add any useful
> information, I recon.

But not in comments and documentation.  IME, a very important point in
writing documentation and comments is to avoid the use of pronouns
unless absolutely necessary: "I", "you", "we", et cetera.  Especially
"we", which is also so hard to avoid even I make the mistake of using it
occasionally.

Thanks.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-29  4:19             ` Yuan Fu
  2022-10-29  5:44               ` Po Lu
@ 2022-10-29  6:54               ` Eli Zaretskii
  2022-10-29  7:29               ` Stefan Kangas
  2 siblings, 0 replies; 15+ messages in thread
From: Eli Zaretskii @ 2022-10-29  6:54 UTC (permalink / raw)
  To: Yuan Fu; +Cc: luangruo, rpluim, emacs-devel

> From: Yuan Fu <casouri@gmail.com>
> Date: Fri, 28 Oct 2022 21:19:19 -0700
> Cc: Robert Pluim <rpluim@gmail.com>,
>  emacs-devel@gnu.org
> 
> Also, out of curiosity, I thought active voice is good and passive voice is bad?

Yes.  So these particular changes are for the worse, IMO.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-29  5:44               ` Po Lu
@ 2022-10-29  7:01                 ` Eli Zaretskii
  2022-10-29  7:25                   ` Po Lu
  0 siblings, 1 reply; 15+ messages in thread
From: Eli Zaretskii @ 2022-10-29  7:01 UTC (permalink / raw)
  To: Po Lu; +Cc: casouri, rpluim, emacs-devel

> From: Po Lu <luangruo@yahoo.com>
> Cc: Robert Pluim <rpluim@gmail.com>,  emacs-devel@gnu.org
> Date: Sat, 29 Oct 2022 13:44:55 +0800
> 
> Yuan Fu <casouri@gmail.com> writes:
> 
> > Also, out of curiosity, I thought active voice is good and passive
> > voice is bad? Though the subject here doesn’t add any useful
> > information, I recon.
> 
> But not in comments and documentation.

Yes, in comments and documentation as well.

>                                      IME, a very important point in
> writing documentation and comments is to avoid the use of pronouns
> unless absolutely necessary: "I", "you", "we", et cetera.  Especially
> "we", which is also so hard to avoid even I make the mistake of using it
> occasionally.

That is correct, but your change removed only "we", and left "I"
intact.  In any case, rephrasing to avoid pronouns doesn't necessarily
force us to use passive voice.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-29  7:01                 ` Eli Zaretskii
@ 2022-10-29  7:25                   ` Po Lu
  2022-10-29  8:16                     ` Eli Zaretskii
  0 siblings, 1 reply; 15+ messages in thread
From: Po Lu @ 2022-10-29  7:25 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: casouri, rpluim, emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

> That is correct, but your change removed only "we", and left "I"
> intact.  In any case, rephrasing to avoid pronouns doesn't necessarily
> force us to use passive voice.

Well, if you can, please suggest some better ways to do that.  I tried
my best.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-29  4:19             ` Yuan Fu
  2022-10-29  5:44               ` Po Lu
  2022-10-29  6:54               ` Eli Zaretskii
@ 2022-10-29  7:29               ` Stefan Kangas
  2 siblings, 0 replies; 15+ messages in thread
From: Stefan Kangas @ 2022-10-29  7:29 UTC (permalink / raw)
  To: Yuan Fu, Po Lu; +Cc: Robert Pluim, emacs-devel

Yuan Fu <casouri@gmail.com> writes:

> Also, out of curiosity, I thought active voice is good and passive
> voice is bad? Though the subject here doesn’t add any useful
> information, I recon.

I don't have an opinion about this particular change, but I don't think
we apply that in such a blanket fashion (i.e. "passive voice = bad").

Richard gave this advice on 15 October:

> The proposed manual text includes several sentences which use passive
> voice and would be shorter in active voice.  Occasionally the use of
> passive voice is best approach, but usually not, so please try making
> them active and see if that makes the text more readable.

https://lists.gnu.org/archive/html/emacs-devel/2022-10/msg01276.html



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-29  7:25                   ` Po Lu
@ 2022-10-29  8:16                     ` Eli Zaretskii
  2022-10-29  8:34                       ` Po Lu
  0 siblings, 1 reply; 15+ messages in thread
From: Eli Zaretskii @ 2022-10-29  8:16 UTC (permalink / raw)
  To: Po Lu; +Cc: casouri, rpluim, emacs-devel

> From: Po Lu <luangruo@yahoo.com>
> Cc: casouri@gmail.com,  rpluim@gmail.com,  emacs-devel@gnu.org
> Date: Sat, 29 Oct 2022 15:25:13 +0800
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > That is correct, but your change removed only "we", and left "I"
> > intact.  In any case, rephrasing to avoid pronouns doesn't necessarily
> > force us to use passive voice.
> 
> Well, if you can, please suggest some better ways to do that.

Compliance!

> -   - 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.

Here I'd suggest

  It doesn't expose a syntax tree.  The syntax tree is part of the
  parser object, and updating the tree is handled on 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.

Here I'd suggest

  It doesn't expose the tree cursor, either.  Presumably, Lisp is slow
  enough to make insignificant any performance advantages from using
  the cursor.  Not exposing the cursor also minimizes the number of
  new types this adds to Emacs Lisp; currently, this adds only the
  parser and node types.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Stylistic changes to tree-sitter code
  2022-10-29  8:16                     ` Eli Zaretskii
@ 2022-10-29  8:34                       ` Po Lu
  0 siblings, 0 replies; 15+ messages in thread
From: Po Lu @ 2022-10-29  8:34 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: casouri, rpluim, emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Po Lu <luangruo@yahoo.com>
>> Cc: casouri@gmail.com,  rpluim@gmail.com,  emacs-devel@gnu.org
>> Date: Sat, 29 Oct 2022 15:25:13 +0800
>> 
>> Eli Zaretskii <eliz@gnu.org> writes:
>> 
>> > That is correct, but your change removed only "we", and left "I"
>> > intact.  In any case, rephrasing to avoid pronouns doesn't necessarily
>> > force us to use passive voice.
>> 
>> Well, if you can, please suggest some better ways to do that.
>
> Compliance!
>
>> -   - 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.
>
> Here I'd suggest
>
>   It doesn't expose a syntax tree.  The syntax tree is part of the
>   parser object, and updating the tree is handled on 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.
>
> Here I'd suggest
>
>   It doesn't expose the tree cursor, either.  Presumably, Lisp is slow
>   enough to make insignificant any performance advantages from using
>   the cursor.  Not exposing the cursor also minimizes the number of
>   new types this adds to Emacs Lisp; currently, this adds only the
>   parser and node types.

Thanks, I'll use that text instead.



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-10-29  8:34 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <87h6zp75nt.fsf.ref@yahoo.com>
2022-10-27 13:33 ` Stylistic changes to tree-sitter code Po Lu via Emacs development discussions.
2022-10-27 13:56   ` Robert Pluim
2022-10-28  0:41     ` Po Lu via Emacs development discussions.
2022-10-28  4:14       ` Yuan Fu
2022-10-28  7:03       ` Robert Pluim
2022-10-28  7:08         ` Po Lu
2022-10-29  2:45           ` Po Lu via Emacs development discussions.
2022-10-29  4:19             ` Yuan Fu
2022-10-29  5:44               ` Po Lu
2022-10-29  7:01                 ` Eli Zaretskii
2022-10-29  7:25                   ` Po Lu
2022-10-29  8:16                     ` Eli Zaretskii
2022-10-29  8:34                       ` Po Lu
2022-10-29  6:54               ` Eli Zaretskii
2022-10-29  7:29               ` Stefan Kangas

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).