From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Yuan Fu Newsgroups: gmane.emacs.devel Subject: Re: Tree-sitter api Date: Sat, 12 Mar 2022 22:25:11 -0800 Message-ID: <67183EAB-5D98-4211-B71B-4618D6266A15@gmail.com> References: <9C5A86D6-0E7D-4DDF-B211-278EF9AC7E01@gmail.com> <87a6gq5mxl.fsf@gmail.com> <877dbu5mgj.fsf@gmail.com> <0BB906F7-BD3A-41CC-9783-19AA16934497@gmail.com> <83pmplq9f3.fsf@gnu.org> <5B304D80-2969-4F59-9A90-412D0A284912@gmail.com> <83ilvbpsvl.fsf@gnu.org> <4A6F417A-EF74-40B6-9517-6C0947AB87A6@gmail.com> <83wnjmiork.fsf@gnu.org> <6D1CD758-2C6F-4843-9739-F2A5D5591648@gmail.com> Mime-Version: 1.0 (Mac OS X Mail 15.0 \(3693.60.0.1.1\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_D449D3E8-BB51-4338-8EC4-A25BC88AC0F7" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="40182"; mail-complaints-to="usenet@ciao.gmane.io" Cc: =?utf-8?Q?Cl=C3=A9ment_Pit-Claudel?= , Theodor Thornhill , ubolonton@gmail.com, Emacs developers , Philipp , Stefan Monnier , Yoav Marco , Stephen Leake , John Yates To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Mar 13 07:27:21 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nTHhI-000AL4-Jq for ged-emacs-devel@m.gmane-mx.org; Sun, 13 Mar 2022 07:27:21 +0100 Original-Received: from localhost ([::1]:54112 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nTHhH-00072D-2k for ged-emacs-devel@m.gmane-mx.org; Sun, 13 Mar 2022 01:27:19 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:55028) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nTHfM-0006EQ-31 for emacs-devel@gnu.org; Sun, 13 Mar 2022 01:25:21 -0500 Original-Received: from [2607:f8b0:4864:20::62e] (port=42886 helo=mail-pl1-x62e.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nTHfJ-0004mZ-D2; Sun, 13 Mar 2022 01:25:19 -0500 Original-Received: by mail-pl1-x62e.google.com with SMTP id p17so11039253plo.9; Sat, 12 Mar 2022 22:25:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:message-id:mime-version:subject:date:in-reply-to:cc:to :references; bh=4rgG6j7bwQOIR4prlIXbzfytHkco50HXt7mTKhp3rKo=; b=Cwa5V93DVz9AU8bhemy5ovU9L/gxzy8lP1BJIRd2yGRBItZOyVs7dWz7RSpfOlcf4f PXZM6lspOCImyVwO2BjheUTGMcblsUyIfSmh/mW0sC5GknIm2bVmF9iIuqUVekPlprIw mmKzCgCmjwNf2Kyo29pr5K6/cqyAPqmNEBianhQWvqIJzeaAcOoccybM65lJ1gunGUmc u9/yV2Oqmv6ilNGJi9jkwj8CFzpA5VuFj8GGk/WPep8B+viodQdNyUyPLVene22WIM1O QxTvUWWRbj6Gsm+eKGw8T8gZV/IXJTjxzMH2eV+OVfIpTEy+k1aPOflLbj/ePceayQrW /qhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:message-id:mime-version:subject:date :in-reply-to:cc:to:references; bh=4rgG6j7bwQOIR4prlIXbzfytHkco50HXt7mTKhp3rKo=; b=GqKK3EoilpRLdG0mLes8hMMUDQsi0Kd1UJZFPSqcpbQsbJ1FawkWj5on22fZmo2iWW rhQhulVki+9ieOsXJpuDTC0W930L5XDYRLIwX7Wwe3y5I4q+qpUoq8gr46CaO7JVES5o srMGPEvip56UtyznReuZj0h+je8HYOxeS6tcGZ5xWSsbw7pQhTd0gn1bIKTntMBr4MTn cik0NftJ/dfGHGzmmpWmIBm8p37RSs5jAkQ2PBVTsvN3xO20FfLupzrxDCZly5qUExAf n3agyorXiFUDOGqzscV4slQquh4KWCnTBG15FB1IkAAPYIif5UxEU+WpvpjJ9LMcD185 99dw== X-Gm-Message-State: AOAM533HwY6heDdRk7SL48YKBbHMs/UxUGAG5KITbeh3QPpzuEdiEDXe EtPG7hzKmSyeRpL+TXqDrCjgqJ+CrTNwDA== X-Google-Smtp-Source: ABdhPJy3PC3a2CQJBxqwMSe+vWlC6HI62llBhcVx/nQF1XAZQPsa/lNe6dh6Scp+k7oV3EOi1vr+VA== X-Received: by 2002:a17:902:b204:b0:14f:26a7:9f61 with SMTP id t4-20020a170902b20400b0014f26a79f61mr18162382plr.97.1647152713797; Sat, 12 Mar 2022 22:25:13 -0800 (PST) Original-Received: from smtpclient.apple ([2600:1700:2ec7:8c90:6914:28b0:4bab:77d7]) by smtp.gmail.com with ESMTPSA id q11-20020a63f94b000000b00373c5319642sm12688286pgk.93.2022.03.12.22.25.12 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 12 Mar 2022 22:25:13 -0800 (PST) In-Reply-To: <6D1CD758-2C6F-4843-9739-F2A5D5591648@gmail.com> X-Mailer: Apple Mail (2.3693.60.0.1.1) X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::62e (failed) Received-SPF: pass client-ip=2607:f8b0:4864:20::62e; envelope-from=casouri@gmail.com; helo=mail-pl1-x62e.google.com X-Spam_score_int: -6 X-Spam_score: -0.7 X-Spam_bar: / X-Spam_report: (-0.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, PDS_HP_HELO_NORDNS=0.659, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:287061 Archived-At: --Apple-Mail=_D449D3E8-BB51-4338-8EC4-A25BC88AC0F7 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii >=20 > It has been quite a while. I added some fixes to the patch and added = full changeling. Anyone would like to have a look at it? >=20 > Thanks, > Yuan Forgot to attach the patch, here it is: --Apple-Mail=_D449D3E8-BB51-4338-8EC4-A25BC88AC0F7 Content-Disposition: attachment; filename=tree-sitter.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="tree-sitter.patch" Content-Transfer-Encoding: quoted-printable =46rom=20a82dc29351dbb86fdd1c75b0ca570b7a133efc12=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Yuan=20Fu=20=0ADate:=20Sat,=20= 12=20Mar=202022=2022:10:06=20-0800=0ASubject:=20[PATCH]=20Merge=20= tree-sitter=20intergration=0A=0A*=20configure.ac=20(HAVE_TREE_SITTER,=20= TREE_SITTER_OBJ):=20New=20variables.=0A(DYNAMIC_LIB_SUFFIX):=20new=20= variable,=20I=20copied=20code=20from=20MODULES_SUFFIX=0Aso=20the=20diff=20= looks=20this=20way.=0A*=20doc/lispref/elisp.texi=20(Top):=20Add=20= tree-sitter=20manual.=0A*=20doc/lispref/modes.texi=20(Font=20Lock=20= Mode):=20mention=20tree-sitter.=0A(Parser-based=20Font=20Lock):=20New=20= section.=0A(Auto-Indentation):=20Mention=20tree-sitter.=0A(Parser-based=20= Indentation):=20New=20section.=0A*=20doc/lispref/parsing.texi=20(Parsing=20= Program=20Source):=20New=20chapter.=0A*=20= lisp/emacs-lisp/cl-preloaded.el=20(cl--typeof-types):=20Add=0A= tree-sitter-parser=20and=20tree-sitter-node=20type.=0A*=20= lisp/tree-sitter.el:=20New=20file.=0A*=20src/Makefile.in=20= (TREE_SITTER_LIBS,=20TREE_SITTER_FLAGS,=0ATREE_SITTER_OBJ):=20New=20= variables.=0A*=20src/alloc.c:=0A(cleanup_vector):=20Add=20cleanup=20code=20= for=20tree-sitter-parser=20and=0Atree-sitter-node.=0A*=20= src/casefiddle.c=20(casify_region):=20Notify=20tree-sitter=20parser=20of=0A= buffer=20change.=0A*=20src/data.c=20(Ftype_of):=20Add=20= tree-sitter-parser=20and=20tree-sitter-node=20type=0A= (Qtree_sitter_parser,=20Qtree_sitter_node):=20New=20symbol.=0A*=20= src/emacs.c=20(main):=20Add=20symbols=20in=20tree-sitter.c.=0A*=20= src/eval.c=20(define_error):=20Move=20the=20function=20to=20here.=0A*=20= src/insdel.c=20(insert_1_both,=20insert_from_string_1,=20= insert_from_gap,=0Ainsert_from_buffer_1,=20replace_range,=20= del_range_2):=20Notify=20tree-sitter=0Aparser=20of=20buffer=20change.=0A= *=20src/json.c=20(define_error):=20Move=20this=20function=20out.=0A*=20= src/lisp.h=20(DEFINE_GDB_SYMBOL_BEGIN):=20Add=20tree-sitter-parser=20and=0A= tree-sitter-node.=0A*=20src/lread.c=20(Vdynamic_library_suffixes):=20New=20= variable.=0A*=20src/print.c=20(print_vectorlike):=20Add=20code=20for=20= printing=0Atree-sitter-parser=20and=20tree-sitter-node.=0A*=20= src/tree-sitter.c:=20New=20file.=0A*=20src/tree-sitter.h:=20New=20file.=0A= *=20test/src/tree-sitter-tests.el:=20New=20file.=0A---=0A=20configure.ac=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20=20=2060=20= +-=0A=20doc/lispref/elisp.texi=20=20=20=20=20=20=20=20=20=20|=20=20=2012=20= +=0A=20doc/lispref/modes.texi=20=20=20=20=20=20=20=20=20=20|=20=20263=20= ++++-=0A=20doc/lispref/parsing.texi=20=20=20=20=20=20=20=20|=201416=20= +++++++++++++++++++++++++++=0A=20lisp/emacs-lisp/cl-preloaded.el=20|=20=20= =20=202=20+=0A=20lisp/tree-sitter.el=20=20=20=20=20=20=20=20=20=20=20=20=20= |=20=20844=20++++++++++++++++=0A=20src/Makefile.in=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20|=20=20=2010=20+-=0A=20src/alloc.c=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20=20=2013=20+=0A=20= src/casefiddle.c=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20=20=20= 12=20+=0A=20src/data.c=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20|=20=20=20=206=20+=0A=20src/emacs.c=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20|=20=20=20=204=20+=0A=20= src/eval.c=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20|=20=20=2013=20+=0A=20src/insdel.c=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20|=20=20=2047=20+-=0A=20src/json.c=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20=20=2016=20-=0A=20= src/lisp.h=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20|=20=20=20=209=20+=0A=20src/lread.c=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20|=20=20=20=208=20+=0A=20src/print.c=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20=20=2028=20+=0A=20= src/tree-sitter.c=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=201601=20= +++++++++++++++++++++++++++++++=0A=20src/tree-sitter.h=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20|=20=20139=20+++=0A=20= test/src/tree-sitter-tests.el=20=20=20|=20=20366=20+++++++=0A=2020=20= files=20changed,=204831=20insertions(+),=2038=20deletions(-)=0A=20create=20= mode=20100644=20doc/lispref/parsing.texi=0A=20create=20mode=20100644=20= lisp/tree-sitter.el=0A=20create=20mode=20100644=20src/tree-sitter.c=0A=20= create=20mode=20100644=20src/tree-sitter.h=0A=20create=20mode=20100644=20= test/src/tree-sitter-tests.el=0A=0Adiff=20--git=20a/configure.ac=20= b/configure.ac=0Aindex=20a315eeb6bd..db6b8a81fd=20100644=0A---=20= a/configure.ac=0A+++=20b/configure.ac=0A@@=20-457,6=20+457,7=20@@=20= AC_DEFUN=0A=20OPTION_DEFAULT_OFF([imagemagick],[compile=20with=20= ImageMagick=20image=20support])=0A=20= OPTION_DEFAULT_ON([native-image-api],=20[don't=20use=20native=20image=20= APIs=20(GDI+=20on=20Windows)])=0A=20OPTION_DEFAULT_IFAVAILABLE([json],=20= [compile=20with=20native=20JSON=20support])=0A= +OPTION_DEFAULT_IFAVAILABLE([tree-sitter],=20[compile=20with=20= tree-sitter])=0A=20=0A=20OPTION_DEFAULT_ON([xft],[don't=20use=20XFT=20= for=20anti=20aliased=20fonts])=0A=20OPTION_DEFAULT_ON([harfbuzz],[don't=20= use=20HarfBuzz=20for=20text=20shaping])=0A@@=20-3087,6=20+3088,23=20@@=20= AC_DEFUN=0A=20AC_SUBST(JSON_CFLAGS)=0A=20AC_SUBST(JSON_OBJ)=0A=20=0A= +HAVE_TREE_SITTER=3Dno=0A+TREE_SITTER_OBJ=3D=0A+=0A+if=20test=20= "${with_tree_sitter}"=20!=3D=20"no";=20then=0A+=20=20= EMACS_CHECK_MODULES([TREE_SITTER],=20[tree-sitter=20>=3D=200.0],=0A+=20=20= =20=20[HAVE_TREE_SITTER=3Dyes],=20[HAVE_TREE_SITTER=3Dno])=0A+=20=20if=20= test=20"${HAVE_TREE_SITTER}"=20=3D=20yes;=20then=0A+=20=20=20=20= AC_DEFINE(HAVE_TREE_SITTER,=201,=20[Define=20if=20using=20tree-sitter.])=0A= +=20=20=20=20TREE_SITTER_LIBS=3D-ltree-sitter=0A+=20=20=20=20= TREE_SITTER_OBJ=3D"tree-sitter.o"=0A+=20=20fi=0A+fi=0A+=0A= +AC_SUBST(TREE_SITTER_LIBS)=0A+AC_SUBST(TREE_SITTER_CFLAGS)=0A= +AC_SUBST(TREE_SITTER_OBJ)=0A+=0A=20NOTIFY_OBJ=3D=0A=20NOTIFY_SUMMARY=3Dno= =0A=20=0A@@=20-3926,20=20+3944,31=20@@=20AC_DEFUN=0A=20fi=0A=20= AC_SUBST(LIBZ)=0A=20=0A+###=20Dynamic=20library=20support=0A+case=20= $opsys=20in=0A+=20=20cygwin|mingw32)=20DYNAMIC_LIB_SUFFIX=3D".dll"=20;;=0A= +=20=20darwin)=20DYNAMIC_LIB_SUFFIX=3D".dylib"=20;;=0A+=20=20*)=20= DYNAMIC_LIB_SUFFIX=3D".so"=20;;=0A+esac=0A+case=20"${opsys}"=20in=0A+=20=20= darwin)=20DYNAMIC_LIB_SECONDARY_SUFFIX=3D'.so'=20;;=0A+=20=20*)=20= DYNAMIC_LIB_SECONDARY_SUFFIX=3D''=20;;=0A+esac=0A= +AC_DEFINE_UNQUOTED(DYNAMIC_LIB_SUFFIX,=20"$DYNAMIC_LIB_SUFFIX",=0A+=20=20= [System=20extension=20for=20dynamic=20libraries])=0A= +AC_DEFINE_UNQUOTED(DYNAMIC_LIB_SECONDARY_SUFFIX,=20= "$DYNAMIC_LIB_SECONDARY_SUFFIX",=0A+=20=20[Alternative=20system=20= extension=20for=20dynamic=20libraries.])=0A+=0A= +AC_SUBST(DYNAMIC_LIB_SUFFIX)=0A+AC_SUBST(DYNAMIC_LIB_SECONDARY_SUFFIX)=0A= +=0A=20###=20Dynamic=20modules=20support=0A=20LIBMODULES=3D=0A=20= HAVE_MODULES=3Dno=0A=20MODULES_OBJ=3D=0A=20NEED_DYNLIB=3Dno=0A-case=20= $opsys=20in=0A-=20=20cygwin|mingw32)=20MODULES_SUFFIX=3D".dll"=20;;=0A-=20= =20darwin)=20MODULES_SUFFIX=3D".dylib"=20;;=0A-=20=20*)=20= MODULES_SUFFIX=3D".so"=20;;=0A-esac=0A-case=20"${opsys}"=20in=0A-=20=20= darwin)=20MODULES_SECONDARY_SUFFIX=3D'.so'=20;;=0A-=20=20*)=20= MODULES_SECONDARY_SUFFIX=3D''=20;;=0A-esac=0A= +MODULES_SUFFIX=3D"${DYNAMIC_LIB_SUFFIX}"=0A= +MODULES_SECONDARY_SUFFIX=3D"${DYNAMIC_LIB_SECONDARY_SUFFIX}"=0A=20if=20= test=20"${with_modules}"=20!=3D=20"no";=20then=0A=20=20=20case=20$opsys=20= in=0A=20=20=20=20=20gnu|gnu-linux)=0A@@=20-3970,10=20+3999,10=20@@=20= AC_DEFUN=0A=20=20=20=20NEED_DYNLIB=3Dyes=0A=20=20=20=20= AC_DEFINE(HAVE_MODULES,=201,=20[Define=20to=201=20if=20dynamic=20modules=20= are=20enabled])=0A=20=20=20=20AC_DEFINE_UNQUOTED(MODULES_SUFFIX,=20= "$MODULES_SUFFIX",=0A-=20=20=20=20=20[System=20extension=20for=20dynamic=20= libraries])=0A+=20=20=20=20=20[System=20extension=20for=20dynamic=20= modules])=0A=20=20=20=20if=20test=20-n=20"${MODULES_SECONDARY_SUFFIX}";=20= then=0A=20=20=20=20=20=20AC_DEFINE_UNQUOTED(MODULES_SECONDARY_SUFFIX,=20= "$MODULES_SECONDARY_SUFFIX",=0A-=20=20=20=20=20=20=20[Alternative=20= system=20extension=20for=20dynamic=20libraries.])=0A+=20=20=20=20=20=20=20= [Alternative=20system=20extension=20for=20dynamic=20modules.])=0A=20=20=20= =20fi=0A=20fi=0A=20AC_SUBST(MODULES_OBJ)=0A@@=20-4333,6=20+4362,12=20@@=20= AC_DEFUN=0A=20=20=20*)=20MISSING=3D"$MISSING=20json"=0A=20=20=20=20=20=20= WITH_IFAVAILABLE=3D"$WITH_IFAVAILABLE=20--with-json=3Difavailable";;=0A=20= esac=0A+case=20$with_tree_sitter,$HAVE_TREE_SITTER=20in=0A+=20=20no,*=20= |=20ifavailable,*=20|=20*,yes)=20;;=0A+=20=20*)=20MISSING=3D"$MISSING=20= tree-sitter"=0A+=20=20=20=20=20WITH_IFAVAILABLE=3D"$WITH_IFAVAILABLE=20= --with-tree-sitter=3Difavailable";;=0A+esac=0A+=0A=20if=20test=20= "X${MISSING}"=20!=3D=20X;=20then=0A=20=20=20#=20If=20we=20have=20a=20= missing=20library,=20and=20we=20don't=20have=20pkg-config=20installed,=0A= =20=20=20#=20the=20missing=20pkg-config=20may=20be=20the=20reason.=20=20= Give=20the=20user=20a=20hint.=0A@@=20-6263,7=20+6298,7=20@@=20AC_DEFUN=0A= =20optsep=3D=0A=20emacs_config_features=3D=0A=20for=20opt=20in=20ACL=20= BE_APP=20CAIRO=20DBUS=20FREETYPE=20GCONF=20GIF=20GLIB=20GMP=20GNUTLS=20= GPM=20GSETTINGS=20\=0A-=20HARFBUZZ=20IMAGEMAGICK=20JPEG=20JSON=20LCMS2=20= LIBOTF=20LIBSELINUX=20LIBSYSTEMD=20LIBXML2=20\=0A+=20HARFBUZZ=20= IMAGEMAGICK=20JPEG=20JSON=20TREE-SITTER=20LCMS2=20LIBOTF=20LIBSELINUX=20= LIBSYSTEMD=20LIBXML2=20\=0A=20=20M17N_FLT=20MODULES=20NATIVE_COMP=20= NOTIFY=20NS=20OLDXMENU=20PDUMPER=20PGTK=20PNG=20RSVG=20SECCOMP=20\=0A=20=20= SOUND=20SQLITE3=20THREADS=20TIFF=20TOOLKIT_SCROLL_BARS=20\=0A=20=20= UNEXEC=20WEBP=20X11=20XAW3D=20XDBE=20XFT=20XIM=20XINPUT2=20XPM=20= XWIDGETS=20X_TOOLKIT=20\=0A@@=20-6334,6=20+6369,7=20@@=20AC_DEFUN=0A=20=20= =20Does=20Emacs=20use=20-lxft?=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20${HAVE_XFT}=0A= =20=20=20Does=20Emacs=20use=20-lsystemd?=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ${HAVE_LIBSYSTEMD}=0A=20=20=20Does=20Emacs=20use=20-ljansson?=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20${HAVE_JSON}=0A+=20=20Does=20Emacs=20use=20-ltree-sitter?=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ${HAVE_TREE_SITTER}=0A=20=20=20Does=20Emacs=20use=20the=20GMP=20library?=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ${HAVE_GMP}=0A=20=20=20Does=20Emacs=20directly=20use=20zlib?=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ${HAVE_ZLIB}=0A=20=20=20Does=20Emacs=20have=20dynamic=20modules=20= support?=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20${HAVE_MODULES}=0A= diff=20--git=20a/doc/lispref/elisp.texi=20b/doc/lispref/elisp.texi=0A= index=20426bb6d017..7390352016=20100644=0A---=20a/doc/lispref/elisp.texi=0A= +++=20b/doc/lispref/elisp.texi=0A@@=20-222,6=20+222,7=20@@=20Top=0A=20*=20= Non-ASCII=20Characters::=20=20=20=20Non-ASCII=20text=20in=20buffers=20= and=20strings.=0A=20*=20Searching=20and=20Matching::=20=20Searching=20= buffers=20for=20strings=20or=20regexps.=0A=20*=20Syntax=20Tables::=20=20=20= =20=20=20=20=20=20=20=20The=20syntax=20table=20controls=20word=20and=20= list=20parsing.=0A+*=20Parsing=20Program=20Source::=20=20Generate=20= syntax=20tree=20for=20program=20sources.=0A=20*=20Abbrevs::=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20How=20Abbrev=20mode=20works,=20and=20= its=20data=20structures.=0A=20=0A=20*=20Threads::=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20Concurrency=20in=20Emacs=20Lisp.=0A@@=20= -1357,6=20+1358,16=20@@=20Top=0A=20*=20Syntax=20Table=20Internals::=20=20= How=20syntax=20table=20information=20is=20stored.=0A=20*=20Categories::=20= =20=20=20=20=20=20=20=20=20=20=20=20=20Another=20way=20of=20classifying=20= character=20syntax.=0A=20=0A+Parsing=20Program=20Source=0A+=0A+*=20= Language=20Definitions::=20=20=20=20=20Loading=20tree-sitter=20language=20= definitions.=0A+*=20Using=20Parser::=20=20=20=20=20=20=20=20=20=20=20=20=20= Introduction=20to=20parsers.=0A+*=20Retrieving=20Node::=20=20=20=20=20=20= =20=20=20=20Retrieving=20node=20from=20syntax=20tree.=0A+*=20Accessing=20= Node::=20=20=20=20=20=20=20=20=20=20=20Accessing=20node=20information.=0A= +*=20Pattern=20Matching::=20=20=20=20=20=20=20=20=20Pattern=20matching=20= with=20query=20patterns.=0A+*=20Multiple=20Languages::=20=20=20=20=20=20=20= Parse=20text=20written=20in=20multiple=20languages.=0A+*=20Tree-sitter=20= C=20API::=20=20=20=20=20=20=20=20Compare=20the=20C=20API=20and=20the=20= ELisp=20API.=0A+=0A=20Syntax=20Descriptors=0A=20=0A=20*=20Syntax=20Class=20= Table::=20=20=20=20=20=20Table=20of=20syntax=20classes.=0A@@=20-1701,6=20= +1712,7=20@@=20Top=0A=20=0A=20@include=20searching.texi=0A=20@include=20= syntax.texi=0A+@include=20parsing.texi=0A=20@include=20abbrevs.texi=0A=20= @include=20threads.texi=0A=20@include=20processes.texi=0Adiff=20--git=20= a/doc/lispref/modes.texi=20b/doc/lispref/modes.texi=0Aindex=20= c29936d5ca..c38782752e=20100644=0A---=20a/doc/lispref/modes.texi=0A+++=20= b/doc/lispref/modes.texi=0A@@=20-2826,11=20+2826,13=20@@=20Font=20Lock=20= Mode=0A=20in=20which=20contexts.=20=20This=20section=20explains=20how=20= to=20customize=20Font=20Lock=20for=0A=20a=20particular=20major=20mode.=0A= =20=0A-=20=20Font=20Lock=20mode=20finds=20text=20to=20highlight=20in=20= two=20ways:=20through=0A-syntactic=20parsing=20based=20on=20the=20syntax=20= table,=20and=20through=20searching=0A-(usually=20for=20regular=20= expressions).=20=20Syntactic=20fontification=20happens=0A-first;=20it=20= finds=20comments=20and=20string=20constants=20and=20highlights=20them.=0A= -Search-based=20fontification=20happens=20second.=0A+=20=20Font=20Lock=20= mode=20finds=20text=20to=20highlight=20in=20three=20ways:=20through=0A= +syntactic=20parsing=20based=20on=20the=20syntax=20table,=20through=20= searching=0A+(usually=20for=20regular=20expressions),=20and=20through=20= parsing=20based=20on=20a=0A+full-blown=20parser.=20=20Syntactic=20= fontification=20happens=20first;=20it=20finds=0A+comments=20and=20string=20= constants=20and=20highlights=20them.=20=20Search-based=0A+fontification=20= happens=20second.=20=20Parser-based=20fontification=20can=20be=0A= +optionally=20enabled=20and=20it=20will=20precede=20the=20other=20two=20= fontifications.=0A=20=0A=20@menu=0A=20*=20Font=20Lock=20Basics::=20=20=20= =20=20=20=20=20=20=20=20=20Overview=20of=20customizing=20Font=20Lock.=0A= @@=20-2845,6=20+2847,7=20@@=20Font=20Lock=20Mode=0A=20*=20Syntactic=20= Font=20Lock::=20=20=20=20=20=20=20=20=20Fontification=20based=20on=20= syntax=20tables.=0A=20*=20Multiline=20Font=20Lock::=20=20=20=20=20=20=20=20= =20How=20to=20coerce=20Font=20Lock=20into=20properly=0A=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20highlighting=20multiline=20constructs.=0A+*=20Parser-based=20= Font=20Lock::=20=20=20=20=20=20Use=20a=20parser=20for=20fontification.=0A= =20@end=20menu=0A=20=0A=20@node=20Font=20Lock=20Basics=0A@@=20-3735,6=20= +3738,89=20@@=20Region=20to=20Refontify=0A=20reasonably=20fast.=0A=20= @end=20defvar=0A=20=0A+@node=20Parser-based=20Font=20Lock=0A+@subsection=20= Parser-based=20Font=20Lock=0A+=0A+@c=20This=20node=20is=20written=20when=20= the=20only=20parser=20Emacs=20has=20is=20tree-sitter,=0A+@c=20if=20in=20= the=20future=20more=20parser=20are=20supported,=20feel=20free=20to=20= reorganize=0A+@c=20and=20rewrite=20this=20node=20to=20describe=20= multiple=20parsers=20in=20parallel.=0A+=0A+Besides=20simple=20syntactic=20= font=20lock=20and=20search-based=20font=20lock,=20Emacs=0A+also=20= provides=20complete=20syntactic=20font=20lock=20with=20the=20help=20of=20= a=20parser,=0A+currently=20provided=20by=20the=20tree-sitter=20library=20= (@pxref{Parsing=20Program=0A+Source}).=20=20Because=20it=20is=20an=20= optional=20feature,=20parser-based=20font=20lock=0A+is=20less=20= integrated=20with=20Emacs.=20=20Most=20variables=20introduced=20in=20= previous=0A+sections=20only=20apply=20to=20search-based=20font=20lock,=20= except=20for=0A+@var{font-lock-maximum-decoration}.=0A+=0A+@defun=20= tree-sitter-font-lock-enable=0A+This=20function=20enables=20parser-based=20= font=20lock=20in=20the=20current=20buffer.=0A+@end=20defun=0A+=0A= +Parser-based=20font=20lock=20and=20other=20font=20lock=20mechanism=20= are=20not=20mutually=0A+exclusive.=20=20By=20default,=20if=20enabled,=20= parser-based=20font=20lock=20runs=20first,=0A+then=20the=20simple=20= syntactic=20font=20lock=20(if=20enabled),=20then=20search-based=0A+font=20= lock.=0A+=0A+Although=20parser-based=20font=20lock=20doesn't=20share=20= the=20same=20customization=0A+variables=20with=20search-based=20font=20= lock,=20parser-based=20font=20lock=20uses=0A+similar=20customization=20= schemes.=20=20Just=20like=20@var{font-lock-keywords}=20and=0A= +@var{font-lock-defaults},=20parser-based=20font=20lock=20has=0A= +@var{tree-sitter-font-lock-settings}=20and=0A= +@var{tree-sitter-font-lock-defaults}.=0A+=0A+@defvar=20= tree-sitter-font-lock-settings=0A+A=20list=20of=20@var{setting}s=20for=20= tree-sitter=20font=20lock.=0A+=0A+Each=20@var{setting}=20should=20look=20= like=0A+=0A+@example=0A+(@var{language}=20@var{query})=0A+@end=20example=0A= +=0A+Each=20@var{setting}=20controls=20one=20parser=20(often=20of=20= different=20language).=0A+And=20@var{language}=20is=20the=20language=20= symbol=20(@pxref{Language=0A+Definitions});=20@var{query}=20is=20either=20= a=20string=20query=20or=20a=20sexp=20query=0A+(@pxref{Pattern=20= Matching}).=0A+=0A+Capture=20names=20in=20@var{query}=20should=20be=20= face=20names=20like=0A+@code{font-lock-keyword-face}.=20=20The=20= captured=20node=20will=20be=20fontified=0A+with=20that=20face.=20=20= Capture=20names=20can=20also=20be=20function=20names,=20in=20which=0A= +case=20the=20function=20is=20called=20with=20(@var{start}=20@var{end}=20= @var{node}),=0A+where=20@var{start}=20and=20@var{end}=20are=20the=20= start=20and=20end=20position=20of=20the=0A+node=20in=20buffer,=20and=20= @var{node}=20is=20the=20tree-sitter=20node=20object.=20=20If=20a=0A= +capture=20name=20is=20both=20a=20face=20and=20a=20function,=20face=20= takes=20priority.=0A+=0A+Generally,=20major=20modes=20should=20set=20= @var{tree-sitter-font-lock-defaults},=0A+and=20let=20Emacs=20= automatically=20populate=20this=20variable.=0A+@end=20defvar=0A+=0A= +@defvar=20tree-sitter-font-lock-defaults=0A+This=20variable=20stores=20= defaults=20for=20tree-sitter=20font=20Lock.=20=20It=20is=20a=20list=0A= +of=0A+=0A+@example=0A+(@var{default}=20@var{:keyword}=20@var{value}...)=0A= +@end=20example=0A+=0A+A=20@var{default}=20may=20be=20a=20symbol=20or=20= a=20list=20of=20symbols=20(for=20different=0A+levels=20of=20= fontification).=20=20The=20symbol(s)=20can=20be=20a=20variable=20or=20a=0A= +function.=20=20If=20a=20symbol=20is=20both=20a=20variable=20and=20a=20= function,=20it=20is=20used=0A+as=20a=20function.=20=20Different=20levels=20= of=20fontification=20can=20be=20controlled=20by=0A= +@var{font-lock-maximum-decoration}.=0A+=0A+The=20symbol(s)=20in=20= @var{default}=20should=20contain=20or=20return=20a=0A+@var{setting}=20as=20= described=20in=20@var{tree-sitter-font-lock-settings}.=0A+=0A+The=20rest=20= @var{keyword}s=20and=20@var{value}s=20are=20additional=20settings=20that=0A= +could=20be=20used=20to=20alter=20the=20fontification=20behavior.=20=20= Currently=20there=0A+aren't=20any.=0A+@end=20defvar=0A+=0A= +Multi-language=20major=20modes=20should=20provide=20range=20functions=20= in=0A+@var{tree-sitter-range-functions},=20and=20Emacs=20will=20set=20= the=20ranges=0A+accordingly=20before=20fontifing=20a=20region=20= (@pxref{Multiple=20Languages}).=0A+=0A=20@node=20Auto-Indentation=0A=20= @section=20Automatic=20Indentation=20of=20code=0A=20=0A@@=20-3791,10=20= +3877,12=20@@=20Auto-Indentation=0A=20so=20if=20your=20language=20seems=20= somewhat=20similar=20to=20one=20of=20those=20languages,=0A=20you=20might=20= try=20to=20use=20that=20engine.=20=20@c=20FIXME:=20documentation?=0A=20= Another=20one=20is=20SMIE=20which=20takes=20an=20approach=20in=20the=20= spirit=0A-of=20Lisp=20sexps=20and=20adapts=20it=20to=20non-Lisp=20= languages.=0A+of=20Lisp=20sexps=20and=20adapts=20it=20to=20non-Lisp=20= languages.=20Yet=20another=20one=20is=0A+to=20rely=20on=20a=20full-blown=20= parser,=20for=20example,=20the=20tree-sitter=20library.=0A=20=0A=20@menu=0A= =20*=20SMIE::=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20A=20simple=20minded=20indentation=20engine.=0A+*=20= Parser-based=20indentation::=20=20=20=20Parser-based=20indentation=20= engine.=0A=20@end=20menu=0A=20=0A=20@node=20SMIE=0A@@=20-4454,6=20= +4542,169=20@@=20SMIE=20Customization=0A=20@code{eval:=20= (smie-config-local=20'(@var{rules}))}.=0A=20@end=20defun=0A=20=0A+@node=20= Parser-based=20Indentation=0A+@subsection=20Parser-based=20Indentation=0A= +=0A+@c=20This=20node=20is=20written=20when=20the=20only=20parser=20= Emacs=20has=20is=20tree-sitter,=0A+@c=20if=20in=20the=20future=20more=20= parser=20are=20supported,=20feel=20free=20to=20reorganize=0A+@c=20and=20= rewrite=20this=20node=20to=20describe=20multiple=20parsers=20in=20= parallel.=0A+=0A+When=20built=20with=20the=20tree-sitter=20library=20= (@pxref{Parsing=20Program=0A+Source}),=20Emacs=20could=20parse=20program=20= source=20and=20produce=20a=20syntax=20tree.=0A+And=20this=20syntax=20= tree=20can=20be=20used=20for=20indentation.=20=20For=20maximum=0A= +flexibility,=20we=20could=20write=20a=20custom=20indent=20function=20= that=20queries=20the=0A+syntax=20tree=20and=20indents=20accordingly=20= for=20each=20language,=20but=20that=20would=0A+be=20a=20lot=20of=20work.=20= =20It=20is=20more=20convenient=20to=20use=20the=20simple=20indentation=0A= +engine=20described=20below:=20we=20only=20need=20to=20write=20some=20= indentation=20rules=0A+and=20the=20engine=20takes=20care=20of=20the=20= rest.=0A+=0A+To=20enable=20the=20indentation=20engine,=20set=20the=20= value=20of=0A+@var{indent-line-function}=20to=20= @code{tree-sitter-indent}.=0A+=0A+@defvar=20tree-sitter-indent-function=0A= +This=20variable=20stores=20the=20actual=20function=20called=20by=0A= +@code{tree-sitter-indent}.=20=20By=20default,=20its=20value=20is=0A= +@code{tree-sitter-simple-indent}.=20=20In=20the=20future=20we=20might=20= add=20other=0A+more=20complex=20indentation=20engines,=20if=20= @code{tree-sitter-simple-indent}=0A+proves=20to=20be=20insufficient.=0A= +@end=20defvar=0A+=0A+@heading=20Writing=20indentation=20rules=0A+=0A= +@defvar=20tree-sitter-simple-indent-rules=0A+This=20local=20variable=20= stores=20indentation=20rules=20for=20every=20language.=20It=20is=0A+a=20= list=20of=0A+=0A+@example=0A+(@var{language}=20.=20@var{rules})=0A+@end=20= example=0A+=0A+where=20@var{language}=20is=20a=20language=20symbol,=20= @var{rules}=20is=20a=20list=20of=0A+=0A+@example=0A+(@var{matcher}=20= @var{anchor}=20@var{offset})=0A+@end=20example=0A+=0A+The=20= @var{matcher}=20determines=20whether=20this=20rule=20applies,=20= @var{anchor}=0A+and=20@var{offset}=20together=20determines=20which=20= column=20to=20indent=20to.=0A+=0A+A=20@var{matcher}=20is=20a=20function=20= that=20takes=20three=20arguments=20(@var{node}=0A+@var{parent}=20= @var{bol}).=20=20Argument=20@var{bol}=20is=20the=20point=20at=20where=20= we=0A+are=20indenting:=20the=20position=20of=20the=20first=20= non-whitespace=20character=20from=0A+the=20beginning=20of=20line;=20= @var{node}=20is=20the=20largest=20(highest-in-tree)=0A+node=20that=20= starts=20at=20that=20point;=20@var{parent}=20is=20the=20parent=20of=0A= +@var{node};=0A+=0A+If=20@var{matcher}=20returns=20non-nil,=20meaning=20= the=20rule=20matches,=20Emacs=20then=0A+uses=20@var{anchor}=20to=20find=20= an=20anchor,=20it=20should=20be=20a=20function=20that=0A+takes=20the=20= same=20argument=20(@var{node}=20@var{parent}=20@var{bol})=20and=0A= +returns=20a=20point.=0A+=0A+Finally=20Emacs=20computes=20the=20column=20= of=20that=20point=20returned=20by=0A+@var{anchor}=20and=20adds=20= @var{offset}=20to=20it,=20and=20indents=20to=20that=20column.=0A+=0A+For=20= @var{matcher}=20and=20@var{anchor},=20Emacs=20provides=20some=20= convenient=0A+presets=20to=20spare=20us=20from=20writing=20these=20= functions=20ourselves.=20They=20are=0A+stored=20in=20= @var{tree-sitter-simple-indent-presets},=20see=20below.=0A+@end=20defvar=0A= +=0A+@defvar=20tree-sitter-simple-indent-presets=0A+This=20is=20a=20list=20= of=20presets=20for=20@var{matcher}s=20and=20@var{anchor}s=20in=0A= +@var{tree-sitter-simple-indent-rules}.=20Each=20of=20them=20represent=20= a=0A+function=20that=20takes=20@var{node},=20@var{parent}=20and=20= @var{bol}=20as=0A+arguments.=0A+=0A+@example=0A+(match=20@var{node-type}=20= @var{parent-type}=0A+=20=20=20=20=20=20=20@var{node-field}=20= @var{node-index-min}=20@var{node-index-max})=0A+@end=20example=0A+=0A= +This=20matcher=20checks=20if=20@var{node}'s=20type=20is=20= @var{node-type},=0A+@var{parent}'s=20type=20is=20@var{parent-type},=20= @var{node}'s=20field=20name=20in=0A+@var{parent}=20is=20= @var{node-field},=20and=20@var{node}'s=20index=20among=20its=0A+siblings=20= is=20between=20@var{node-index-min}=20and=20@var{node-index-max}.=20=20= If=0A+the=20value=20of=20a=20constraint=20is=20nil,=20this=20matcher=20= doesn't=20check=20for=20that=0A+constraint.=20=20For=20example,=20to=20= match=20the=20first=20child=20where=20parent=20is=0A= +@code{argument_list},=20use=0A+=0A+@example=0A+(match=20nil=20= "argument_list"=20nil=20nil=200=200)=0A+@end=20example=0A+=0A+@example=0A= +no-node=0A+@end=20example=0A+=0A+This=20matcher=20matches=20the=20case=20= where=20@var{node}=20is=20nil,=20i.e.,=20there=20is=0A+no=20node=20that=20= starts=20at=20@var{bol}.=20=20This=20is=20the=20case=20when=20@var{bol}=20= is=0A+at=20an=20empty=20line=20or=20inside=20a=20multi-line=20string,=20= etc.=0A+=0A+@example=0A+(parent-is=20@var{type})=0A+@end=20example=0A+=0A= +This=20matcher=20matches=20if=20@var{parent}'s=20type=20is=20= @var{type}.=0A+=0A+@example=0A+(node-is=20@var{type})=0A+@end=20example=0A= +=0A+This=20matcher=20matches=20if=20@var{node}'s=20type=20is=20= @var{type}.=0A+=0A+@example=0A+(query=20@var{query})=0A+@end=20example=0A= +=0A+This=20matcher=20matches=20if=20querying=20@var{parent}=20with=20= @var{query}=0A+captures=20@var{node}.=20=20The=20capture=20name=20does=20= not=20matter.=0A+=0A+@example=0A+first-sibling=0A+@end=20example=0A+=0A= +This=20anchor=20returns=20the=20start=20of=20the=20first=20child=20of=20= @var{parent}.=0A+=0A+@example=0A+parent=0A+@end=20example=0A+=0A+This=20= anchor=20returns=20the=20start=20of=20@var{parent}.=0A+=0A+@example=0A= +prev-sibling=0A+@end=20example=0A+=0A+This=20anchor=20returns=20the=20= start=20of=20the=20previous=20sibling=20of=20@var{node}.=0A+=0A+@example=0A= +no-indent=0A+@end=20example=0A+=0A+This=20anchor=20returns=20the=20= start=20of=20@var{node},=20i.e.,=20do=20not=20indent.=0A+=0A+@example=0A= +prev-line=0A+@end=20example=0A+=0A+This=20anchor=20returns=20the=20= start=20of=20the=20first=20named=20node=20on=20the=20previous=0A+line.=20= =20This=20can=20be=20used=20for=20indenting=20an=20empty=20line.=0A+@end=20= defvar=0A+=0A+@heading=20Indentation=20utilities=0A+=0A+Here=20are=20= some=20utility=20functions=20that=20can=20help=20writing=20indentation=0A= +rules.=0A+=0A+@defun=20tree-sitter-check-indent=20mode=0A+This=20= function=20check=20current=20buffer's=20indentation=20against=20major=20= mode=0A+@var{mode}.=20=20It=20indents=20the=20current=20line=20in=20= @var{mode}=20and=20compares=0A+the=20indentation=20with=20the=20current=20= indentation.=20=20Then=20it=20pops=20up=20a=20diff=0A+buffer=20showing=20= the=20difference.=20=20Correct=20indentation=20(target)=20is=20in=0A= +green,=20current=20indentation=20is=20in=20red.=0A+@end=20defun=0A+=0A= +It=20is=20also=20helpful=20to=20use=20@code{tree-sitter-inspect-mode}=20= when=20writing=0A+indentation=20rules.=0A=20=0A=20@node=20Desktop=20Save=20= Mode=0A=20@section=20Desktop=20Save=20Mode=0Adiff=20--git=20= a/doc/lispref/parsing.texi=20b/doc/lispref/parsing.texi=0Anew=20file=20= mode=20100644=0Aindex=200000000000..4ebb13ac5e=0A---=20/dev/null=0A+++=20= b/doc/lispref/parsing.texi=0A@@=20-0,0=20+1,1416=20@@=0A+@c=20-*-=20= mode:=20texinfo;=20coding:=20utf-8=20-*-=0A+@c=20This=20is=20part=20of=20= the=20GNU=20Emacs=20Lisp=20Reference=20Manual.=0A+@c=20Copyright=20(C)=20= 2021=20Free=20Software=20Foundation,=20Inc.=0A+@c=20See=20the=20file=20= elisp.texi=20for=20copying=20conditions.=0A+@node=20Parsing=20Program=20= Source=0A+@chapter=20Parsing=20Program=20Source=0A+=0A+Emacs=20provides=20= various=20ways=20to=20parse=20program=20source=20text=20and=20produce=20= a=0A+@dfn{syntax=20tree}.=20=20In=20a=20syntax=20tree,=20text=20is=20no=20= longer=20a=0A+one-dimensional=20stream=20but=20a=20structured=20tree=20= of=20nodes,=20where=20each=20node=0A+representing=20a=20piece=20of=20= text.=20=20Thus=20a=20syntax=20tree=20can=20enable=0A+interesting=20= features=20like=20precise=20fontification,=20indentation,=0A+navigation,=20= structured=20editing,=20etc.=0A+=0A+Emacs=20has=20a=20simple=20facility=20= for=20parsing=20balanced=20expressions=0A+(@pxref{Parsing=20= Expressions}).=20=20There=20is=20also=20SMIE=20library=20for=20generic=0A= +navigation=20and=20indentation=20(@pxref{SMIE}).=0A+=0A+Emacs=20also=20= provides=20integration=20with=20tree-sitter=20library=0A= +(@uref{https://tree-sitter.github.io/tree-sitter})=20if=20compiled=20= with=0A+it.=20=20The=20tree-sitter=20library=20implements=20an=20= incremental=20parser=20and=20has=0A+support=20from=20a=20wide=20range=20= of=20programming=20languages.=0A+=0A+@defun=20tree-sitter-available-p=0A= +This=20function=20returns=20non-nil=20if=20tree-sitter=20features=20are=20= available=0A+for=20this=20Emacs=20instance.=0A+@end=20defun=0A+=0A+For=20= using=20tree-sitter=20features=20in=20font-lock=20and=20indentation,=0A= +@pxref{Parser-based=20Font=20Lock},=20@pxref{Parser-based=20= Indentation}.=0A+=0A+To=20access=20the=20syntax=20tree=20of=20the=20text=20= in=20a=20buffer,=20we=20need=20to=20first=0A+load=20a=20language=20= definition=20and=20create=20a=20parser=20with=20it.=20=20Next,=20we=20= can=0A+query=20the=20parser=20for=20specific=20nodes=20in=20the=20syntax=20= tree.=20=20Then,=20we=20can=0A+access=20various=20information=20about=20= the=20node,=20and=20we=20can=20pattern-match=20a=0A+node=20with=20a=20= powerful=20syntax.=20=20Finally,=20we=20explain=20how=20to=20work=20with=0A= +source=20files=20that=20mixes=20multiple=20languages.=20=20The=20= following=20sections=0A+explain=20how=20to=20do=20each=20of=20the=20= tasks=20in=20detail.=0A+=0A+@menu=0A+*=20Language=20Definitions::=20=20=20= =20=20Loading=20tree-sitter=20language=20definitions.=0A+*=20Using=20= Parser::=20=20=20=20=20=20=20=20=20=20=20=20=20Introduction=20to=20= parsers.=0A+*=20Retrieving=20Node::=20=20=20=20=20=20=20=20=20=20= Retrieving=20node=20from=20syntax=20tree.=0A+*=20Accessing=20Node::=20=20= =20=20=20=20=20=20=20=20=20Accessing=20node=20information.=0A+*=20= Pattern=20Matching::=20=20=20=20=20=20=20=20=20Pattern=20matching=20with=20= query=20patterns.=0A+*=20Multiple=20Languages::=20=20=20=20=20=20=20= Parse=20text=20written=20in=20multiple=20languages.=0A+*=20Tree-sitter=20= C=20API::=20=20=20=20=20=20=20=20Compare=20the=20C=20API=20and=20the=20= ELisp=20API.=0A+@end=20menu=0A+=0A+@node=20Language=20Definitions=0A= +@section=20Tree-sitter=20Language=20Definitions=0A+=0A+@heading=20= Loading=20a=20language=20definition=0A+=0A+Tree-sitter=20relies=20on=20= language=20definitions=20to=20parse=20text=20in=20that=0A+language.=20In=20= Emacs,=20A=20language=20definition=20is=20represented=20by=20a=20symbol=0A= +@code{tree-sitter-}.=20=20For=20example,=20C=20language=20= definition=20is=0A+represented=20as=20@code{tree-sitter-c},=20and=20= @code{tree-sitter-c}=20can=20be=0A+passed=20to=20tree-sitter=20functions=20= as=20the=20@var{language}=20argument.=0A+=0A+@vindex=20= tree-sitter-load-language-error=0A+Tree-sitter=20language=20definitions=20= are=20distributed=20as=20dynamic=0A+libraries.=20In=20order=20to=20use=20= a=20language=20definition=20in=20Emacs,=20you=20need=20to=0A+make=20sure=20= that=20the=20dynamic=20library=20is=20installed=20on=20the=20system,=20= either=0A+in=20standard=20locations=20or=20in=20@code{LD_LIBRARY_PATH}=20= (on=20some=20systems,=0A+it=20is=20@code{DYLD_LIBRARY_PATH}).=20=20If=20= Emacs=20cannot=20find=20the=20library=20or=0A+has=20problem=20loading=20= it,=20Emacs=20signals=0A+@var{tree-sitter-load-language-error}.=20=20The=20= signal=20data=20is=20a=20list=20of=0A+specific=20error=20messages.=0A+=0A= +@defun=20tree-sitter-language-available-p=20language=0A+This=20function=20= checks=20whether=20the=20dynamic=20library=20for=20@var{language}=20is=0A= +present=20on=20the=20system,=20and=20return=20non-nil=20if=20it=20is.=0A= +@end=20defun=0A+=0A+@vindex=20tree-sitter-load-name-override-list=0A+By=20= convention,=20the=20dynamic=20library=20for=20= @code{tree-sitter-}=0A+is=20= @code{libtree-sitter-.@var{ext}},=20where=20@var{ext}=20is=20= the=0A+system-specific=20extension=20for=20dynamic=20libraries.=20Also=20= by=20convention,=0A+the=20function=20provided=20by=20that=20library=20is=20= named=0A+@code{tree_sitter_}.=20=20If=20a=20language=20= definition=20doesn't=0A+follow=20this=20convention,=20you=20should=20add=20= an=20entry=0A+=0A+@example=0A+(@var{language-symbol}=20= @var{library-base-name}=20@var{function-name})=0A+@end=20example=0A+=0A= +to=20@var{tree-sitter-load-name-override-list},=20where=0A= +@var{library-base-name}=20is=20the=20base=20filename=20for=20the=20= dynamic=20library=0A+(conventionally=20= @code{libtree-sitter-}),=20and=0A+@var{function-name}=20is=20= the=20function=20provided=20by=20the=20library=0A+(conventionally=20= @code{tree_sitter_}).=20For=20example,=0A+=0A+@example=0A= +(tree-sitter-cool-lang=20"libtree-sitter-coool"=20"tree_sitter_coool")=0A= +@end=20example=0A+=0A+for=20a=20language=20too=20cool=20to=20abide=20by=20= the=20rules.=0A+=0A+@heading=20Concrete=20syntax=20tree=0A+=0A+A=20= syntax=20tree=20is=20what=20a=20language=20definition=20defines=20(more=20= or=20less)=20and=0A+what=20a=20parser=20generates.=20=20In=20a=20syntax=20= tree,=20each=20node=20represents=20a=0A+piece=20of=20text,=20and=20is=20= connected=20to=20each=20other=20by=20a=20parent-child=0A+relationship.=20= =20For=20example,=20if=20the=20source=20text=20is=0A+=0A+@example=0A+1=20= +=202=0A+@end=20example=0A+=0A+@noindent=0A+its=20syntax=20tree=20could=20= be=0A+=0A+@example=0A+@group=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20+--------------+=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20|=20root=20"1=20+=202"=20|=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20+--------------+=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20|=0A+=20=20=20=20=20=20=20=20= +--------------------------------+=0A+=20=20=20=20=20=20=20=20|=20=20=20=20= =20=20=20expression=20"1=20+=202"=20=20=20=20=20=20=20|=0A+=20=20=20=20=20= =20=20=20+--------------------------------+=0A+=20=20=20=20=20=20=20=20=20= =20=20|=20=20=20=20=20=20=20=20=20=20=20=20=20|=20=20=20=20=20=20=20=20=20= =20=20=20|=0A++------------+=20=20=20+--------------+=20=20=20= +------------+=0A+|=20number=20"1"=20|=20=20=20|=20operator=20"+"=20|=20=20= =20|=20number=20"2"=20|=0A++------------+=20=20=20+--------------+=20=20=20= +------------+=0A+@end=20group=0A+@end=20example=0A+=0A+We=20can=20also=20= represent=20it=20in=20s-expression:=0A+=0A+@example=0A+(root=20= (expression=20(number)=20(operator)=20(number)))=0A+@end=20example=0A+=0A= +@subheading=20Node=20types=0A+=0A+@cindex=20tree-sitter=20node=20type=0A= +@anchor{tree-sitter=20node=20type}=0A+@cindex=20tree-sitter=20named=20= node=0A+@anchor{tree-sitter=20named=20node}=0A+@cindex=20tree-sitter=20= anonymous=20node=0A+Names=20like=20@code{root},=20@code{expression},=20= @code{number},=0A+@code{operator}=20are=20nodes'=20@dfn{type}.=20=20= However,=20not=20all=20nodes=20in=20a=0A+syntax=20tree=20have=20a=20= type.=20=20Nodes=20that=20don't=20are=20@dfn{anonymous=20nodes},=0A+and=20= nodes=20with=20a=20type=20are=20@dfn{named=20nodes}.=20=20Anonymous=20= nodes=20are=0A+tokens=20with=20fixed=20spellings,=20including=20= punctuation=20characters=20like=0A+bracket=20@samp{]},=20and=20keywords=20= like=20@code{return}.=0A+=0A+@subheading=20Field=20names=0A+=0A+@cindex=20= tree-sitter=20node=20field=20name=0A+@anchor{tree-sitter=20node=20field=20= name}=20To=20make=20the=20syntax=20tree=20easier=20to=0A+analyze,=20many=20= language=20definitions=20assign=20@dfn{field=20names}=20to=20child=0A= +nodes.=20=20For=20example,=20a=20@code{function_definition}=20node=20= could=20have=20a=0A+@code{declarator}=20and=20a=20@code{body}:=0A+=0A= +@example=0A+@group=0A+(function_definition=0A+=20declarator:=20= (declaration)=0A+=20body:=20(compound_statement))=0A+@end=20group=0A= +@end=20example=0A+=0A+@deffn=20Command=20tree-sitter-inspect-mode=0A= +This=20minor=20mode=20displays=20the=20node=20that=20@emph{starts}=20at=20= point=20in=0A+mode-line.=20=20The=20mode-line=20will=20display=0A+=0A= +@example=0A+@var{parent}=20@var{field-name}:=20(@var{child}=20= (@var{grand-child}=20(...)))=0A+@end=20example=0A+=0A+@var{child},=20= @var{grand-child},=20and=20@var{grand-grand-child},=20etc,=20are=0A= +nodes=20that=20have=20their=20beginning=20at=20point.=20=20And=20= @var{parent}=20is=20the=0A+parent=20of=20@var{child}.=0A+=0A+If=20there=20= is=20no=20node=20that=20starts=20at=20point,=20i.e.,=20point=20is=20in=20= the=20middle=0A+of=20a=20node,=20then=20the=20mode-line=20only=20= displays=20the=20smallest=20node=20that=0A+spans=20point,=20and=20its=20= immediate=20parent.=0A+=0A+This=20minor=20mode=20doesn't=20create=20= parsers=20on=20its=20own.=20=20It=20simply=20uses=20the=0A+first=20= parser=20in=20@var{tree-sitter-parser-list}=20(@pxref{Using=20Parser}).=0A= +@end=20deffn=0A+=0A+@heading=20Reading=20the=20grammar=20definition=0A+=0A= +Authors=20of=20language=20definitions=20define=20the=20@dfn{grammar}=20= of=20a=0A+language,=20and=20this=20grammar=20determines=20how=20does=20a=20= parser=20construct=20a=0A+concrete=20syntax=20tree=20out=20of=20the=20= text.=20=20In=20order=20to=20used=20the=20syntax=0A+tree=20effectively,=20= we=20need=20to=20read=20the=20@dfn{grammar=20file}.=0A+=0A+The=20grammar=20= file=20is=20usually=20@code{grammar.js}=20in=20a=20language=0A= +definition=E2=80=99s=20project=20repository.=20=20The=20link=20to=20a=20= language=20definition=E2=80=99s=0A+home=20page=20can=20be=20found=20in=20= tree-sitter=E2=80=99s=20homepage=0A= +(@uref{https://tree-sitter.github.io/tree-sitter}).=0A+=0A+The=20= grammar=20is=20written=20in=20JavaScript=20syntax.=20=20For=20example,=20= the=20rule=0A+matching=20a=20@code{function_definition}=20node=20looks=20= like=0A+=0A+@example=0A+@group=0A+function_definition:=20$=20=3D>=20seq(=0A= +=20=20$.declaration_specifiers,=0A+=20=20field('declarator',=20= $.declaration),=0A+=20=20field('body',=20$.compound_statement)=0A+)=0A= +@end=20group=0A+@end=20example=0A+=0A+The=20rule=20is=20represented=20= by=20a=20function=20that=20takes=20a=20single=20argument=0A+@var{$},=20= representing=20the=20whole=20grammar.=20=20The=20function=20itself=20is=0A= +constructed=20by=20other=20functions:=20the=20@code{seq}=20function=20= puts=20together=20a=0A+sequence=20of=20children;=20the=20@code{field}=20= function=20annotates=20a=20child=20with=0A+a=20field=20name.=20=20If=20= we=20write=20the=20above=20definition=20in=20BNF=20syntax,=20it=0A+would=20= look=20like=0A+=0A+@example=0A+@group=0A+function_definition=20:=3D=0A+=20= =20=20=20=0A= +@end=20group=0A+@end=20example=0A+=0A+@noindent=0A+and=20the=20node=20= returned=20by=20the=20parser=20would=20look=20like=0A+=0A+@example=0A= +@group=0A+(function_definition=0A+=20=20(declaration_specifier)=0A+=20=20= declarator:=20(declaration)=0A+=20=20body:=20(compound_statement))=0A= +@end=20group=0A+@end=20example=0A+=0A+Below=20is=20a=20list=20of=20= functions=20that=20one=20will=20see=20in=20a=20grammar=0A+definition.=20=20= Each=20function=20takes=20other=20rules=20as=20arguments=20and=20returns=0A= +a=20new=20rule.=0A+=0A+@itemize=20@bullet=0A+@item=0A+@code{seq(rule1,=20= rule2,=20...)}=20matches=20each=20rule=20one=20after=20another.=0A+=0A= +@item=0A+@code{choice(rule1,=20rule2,=20...)}=20matches=20one=20of=20= the=20rules=20in=20its=0A+arguments.=0A+=0A+@item=0A+@code{repeat(rule)}=20= matches=20@var{rule}=20for=20@emph{zero=20or=20more}=20times.=0A+This=20= is=20like=20the=20@samp{*}=20operator=20in=20regular=20expressions.=0A+=0A= +@item=0A+@code{repeat1(rule)}=20matches=20@var{rule}=20for=20@emph{one=20= or=20more}=20times.=0A+This=20is=20like=20the=20@samp{+}=20operator=20in=20= regular=20expressions.=0A+=0A+@item=0A+@code{optional(rule)}=20matches=20= @var{rule}=20for=20@emph{zero=20or=20one}=20time.=0A+This=20is=20like=20= the=20@samp{?}=20operator=20in=20regular=20expressions.=0A+=0A+@item=0A= +@code{field(name,=20rule)}=20assigns=20field=20name=20@var{name}=20to=20= the=20child=0A+node=20matched=20by=20@var{rule}.=0A+=0A+@item=0A= +@code{alias(rule,=20alias)}=20makes=20nodes=20matched=20by=20@var{rule}=20= appear=20as=0A+@var{alias}=20in=20the=20syntax=20tree=20generated=20by=20= the=20parser.=20=20For=20example,=0A+=0A+@example=0A= +alias(preprocessor_call_exp,=20call_expression)=0A+@end=20example=0A+=0A= +makes=20any=20node=20matched=20by=20@code{preprocessor_call_exp}=20to=20= appear=20as=0A+@code{call_expression}.=0A+@end=20itemize=0A+=0A+Below=20= are=20grammar=20functions=20less=20interesting=20for=20a=20reader=20of=20= a=0A+language=20definition.=0A+=0A+@itemize=0A+@item=0A= +@code{token(rule)}=20marks=20@var{rule}=20to=20produce=20a=20single=20= leaf=20node.=0A+That=20is,=20instead=20of=20generating=20a=20parent=20= node=20with=20individual=20child=0A+nodes=20under=20it,=20everything=20= is=20combined=20into=20a=20single=20leaf=20node.=0A+=0A+@item=0A= +Normally,=20grammar=20rules=20ignore=20preceding=20whitespaces,=0A= +@code{token.immediate(rule)}=20changes=20@var{rule}=20to=20match=20only=20= when=0A+there=20is=20no=20preceding=20whitespaces.=0A+=0A+@item=0A= +@code{prec(n,=20rule)}=20gives=20@var{rule}=20a=20level=20@var{n}=20= precedence.=0A+=0A+@item=0A+@code{prec.left([n,]=20rule)}=20marks=20= @var{rule}=20as=20left-associative,=0A+optionally=20with=20level=20= @var{n}.=0A+=0A+@item=0A+@code{prec.right([n,]=20rule)}=20marks=20= @var{rule}=20as=20right-associative,=0A+optionally=20with=20level=20= @var{n}.=0A+=0A+@item=0A+@code{prec.dynamic(n,=20rule)}=20is=20like=20= @code{prec},=20but=20the=20precedence=0A+is=20applied=20at=20runtime=20= instead.=0A+@end=20itemize=0A+=0A+The=20tree-sitter=20project=20talks=20= about=20writing=20a=20grammar=20in=20more=20detail:=0A= +@uref{https://tree-sitter.github.io/tree-sitter/creating-parsers}.=0A= +Read=20especially=20``The=20Grammar=20DSL''=20section.=0A+=0A+@node=20= Using=20Parser=0A+@section=20Using=20Tree-sitter=20Parser=0A+@cindex=20= Tree-sitter=20parser=0A+=0A+This=20section=20described=20how=20to=20= create=20and=20configure=20a=20tree-sitter=0A+parser.=20=20In=20Emacs,=20= each=20tree-sitter=20parser=20is=20associated=20with=20a=0A+buffer.=20=20= As=20we=20edit=20the=20buffer,=20the=20associated=20parser=20is=20= automatically=0A+kept=20up-to-date.=0A+=0A+@defvar=20= tree-sitter-disabled-modes=0A+Before=20creating=20a=20parser,=20it=20is=20= perhaps=20good=20to=20check=20whether=20we=0A+should=20use=20tree-sitter=20= at=20all.=20=20Sometimes=20a=20user=20don't=20want=20to=20use=0A= +tree-sitter=20features=20for=20a=20major=20mode.=20=20To=20turn-off=20= tree-sitter=20for=20a=0A+mode,=20they=20add=20that=20mode=20to=20this=20= variable.=0A+@end=20defvar=0A+=0A+@defvar=20tree-sitter-maximum-size=0A= +If=20users=20want=20to=20turn=20off=20tree-sitter=20for=20buffers=20= larger=20than=20a=0A+particular=20size=20(because=20tree-sitter=20= consumes=20memory=20~10=20times=20the=0A+buffer=20size=20for=20storing=20= the=20syntax=20tree),=20they=20set=20this=20variable=20to=0A+that=20= size.=0A+@end=20defvar=0A+=0A+@defun=20tree-sitter-should-enable-p=20= &optional=20mode=0A+This=20function=20returns=20non-nil=20if=20= @var{mode}=20(default=20to=20the=20current=0A+major=20mode)=20should=20= activate=20tree-sitter=20features.=20=20The=20result=20depends=0A+on=20= the=20value=20of=20@var{tree-sitter-disabled-modes}=20and=0A= +@var{tree-sitter-maximum-size}=20described=20above.=20=20The=20result=20= also=0A+depends=20on,=20of=20course,=20the=20result=20of=20= @code{tree-sitter-avaliabe-p}.=0A+=0A+Writer=20of=20major=20modes=20or=20= other=20packages=20are=20responsible=20for=20calling=0A+this=20function=20= and=20determine=20whether=20to=20activate=20tree-sitter=20features.=0A= +@end=20defun=0A+=0A+=0A+@cindex=20Creating=20tree-sitter=20parsers=0A= +To=20create=20a=20parser,=20we=20provide=20a=20buffer=20to=20parse=20= and=20the=20language=20to=0A+use=20(@pxref{Language=20Definitions}).=20=20= Emacs=20provides=20several=20creation=0A+functions=20for=20different=20= use=20cases.=0A+=0A+@defun=20tree-sitter-get-parser-create=20language=0A= +This=20function=20is=20the=20most=20convenient=20one.=20=20It=20gives=20= you=20a=20parser=20that=0A+recognizes=20@var{language}=20for=20the=20= current=20buffer.=20=20The=20function=0A+checks=20if=20there=20already=20= exists=20a=20parser=20suiting=20the=20need,=20and=20only=0A+creates=20a=20= new=20one=20when=20it=20can't=20find=20one.=0A+=0A+@example=0A+@group=0A= +;;=20Create=20a=20parser=20for=20C=20programming=20language.=0A= +(tree-sitter-get-parser-create=20'tree-sitter-c)=0A+=20=20=20=20@c=20= @result{}=20#=0A= +@end=20group=0A+@end=20example=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-get-parser=20language=0A+This=20function=20is=20like=20= @code{tree-sitter-get-parser-create},=20but=20it=0A+always=20creates=20a=20= new=20parser.=0A+@end=20defun=0A+=0A+@defun=20tree-sitter-parser-create=20= buffer=20language=0A+This=20function=20is=20the=20most=20primitive,=20= requiring=20both=20the=20buffer=20to=0A+associate=20to,=20and=20the=20= language=20to=20use.=20=20If=20@var{buffer}=20is=20nil,=20the=0A+current=20= buffer=20is=20used.=0A+@end=20defun=0A+=0A+Given=20a=20parser,=20we=20= can=20query=20information=20about=20it:=0A+=0A+@defun=20= tree-sitter-parser-buffer=20parser=0A+Returns=20the=20buffer=20= associated=20with=20@var{parser}.=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-parser-language=20parser=0A+Returns=20the=20language=20that=20= @var{parser}=20uses.=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-parser-p=20object=0A+Checks=20if=20@var{object}=20is=20a=20= tree-sitter=20parser.=20Return=20non-nil=20if=20it=0A+is,=20return=20nil=20= otherwise.=0A+@end=20defun=0A+=0A+There=20is=20no=20need=20to=20= explicitly=20parse=20a=20buffer,=20because=20parsing=20is=20done=0A= +automatically=20and=20lazily.=20=20A=20parser=20only=20parses=20when=20= we=20query=20for=20a=0A+node=20in=20its=20syntax=20tree.=20=20Therefore,=20= when=20a=20parser=20is=20first=20created,=0A+it=20doesn't=20parse=20the=20= buffer;=20instead,=20it=20waits=20until=20we=20query=20for=20a=0A+node=20= for=20the=20first=20time.=20=20Similarly,=20when=20some=20change=20is=20= made=20in=20the=0A+buffer,=20a=20parser=20doesn't=20re-parse=20= immediately=20and=20only=20records=20some=0A+necessary=20information=20= to=20later=20re-parse=20when=20necessary.=0A+=0A+@vindex=20= tree-sitter-buffer-too-large=0A+When=20a=20parser=20do=20parse,=20it=20= checks=20for=20the=20size=20of=20the=20buffer.=0A+Tree-sitter=20can=20= only=20handle=20buffer=20no=20larger=20than=20about=204GB.=20=20If=20the=0A= +size=20exceeds=20that,=20Emacs=20signals=20= @var{tree-sitter-buffer-too-large}=0A+with=20signal=20data=20being=20the=20= buffer=20size.=0A+=0A+@vindex=20tree-sitter-parser-list=0A+Once=20a=20= parser=20is=20created,=20Emacs=20automatically=20adds=20it=20to=20the=0A= +buffer-local=20variable=20@var{tree-sitter-parser-list}.=20=20Every=20= time=20a=0A+change=20is=20made=20to=20the=20buffer,=20Emacs=20updates=20= parsers=20in=20this=20list=20so=0A+they=20can=20update=20their=20syntax=20= tree=20incrementally.=20=20Therefore,=20one=20must=0A+not=20remove=20= parsers=20from=20this=20list=20and=20put=20the=20parser=20back=20in:=20= if=20any=0A+change=20is=20made=20when=20that=20parser=20is=20absent,=20= the=20parser=20will=20be=0A+permanently=20out-of-sync=20with=20the=20= buffer=20content,=20and=20shouldn't=20be=20used=0A+anymore.=0A+=0A= +@cindex=20tree-sitter=20narrowing=0A+@anchor{tree-sitter=20narrowing}=20= Normally,=20a=20parser=20``sees''=20the=20whole=0A+buffer,=20but=20when=20= the=20buffer=20is=20narrowed=20(@pxref{Narrowing}),=20the=0A+parser=20= will=20only=20see=20the=20visible=20region.=20=20As=20far=20as=20the=20= parser=20can=0A+tell,=20the=20hidden=20region=20is=20deleted.=20=20And=20= when=20the=20buffer=20is=20later=0A+widened,=20the=20parser=20thinks=20= text=20is=20inserted=20in=20the=20beginning=20and=20in=0A+the=20end.=20=20= Although=20parsers=20respect=20narrowing,=20narrowing=20shouldn't=20be=0A= +the=20mean=20to=20handle=20a=20multi-language=20buffer;=20instead,=20= set=20the=20ranges=20in=0A+which=20a=20parser=20should=20operate=20in.=20= =20@xref{Multiple=20Languages}.=0A+=0A+Because=20a=20parser=20parses=20= lazily,=20when=20we=20narrow=20the=20buffer,=20the=20parser=0A+doesn't=20= act=20immediately;=20as=20long=20as=20we=20don't=20query=20for=20a=20= node=20while=0A+the=20buffer=20is=20narrowed,=20narrowing=20does=20not=20= affect=20the=20parser.=0A+=0A+@cindex=20tree-sitter=20parse=20string=0A= +@defun=20tree-sitter-parse-string=20string=20language=0A+Besides=20= creating=20a=20parser=20for=20a=20buffer,=20we=20can=20also=20just=20= parse=20a=0A+string.=20=20Unlike=20a=20buffer,=20parsing=20a=20string=20= is=20a=20one-time=20deal,=20and=0A+there=20is=20no=20way=20to=20update=20= the=20result.=0A+=0A+This=20function=20parses=20@var{string}=20with=20= @var{language},=20and=20returns=20the=0A+root=20node=20of=20the=20= generated=20syntax=20tree.=0A+@end=20defun=0A+=0A+@node=20Retrieving=20= Node=0A+@section=20Retrieving=20Node=0A+=0A+@cindex=20tree-sitter=20find=20= node=0A+@cindex=20tree-sitter=20get=20node=0A+There=20are=20two=20ways=20= to=20retrieve=20a=20node:=20directly=20from=20the=20syntax=20tree,=0A+or=20= by=20traveling=20from=20other=20nodes.=20=20But=20before=20we=20= continue,=20lets=20go=0A+over=20some=20conventions=20of=20tree-sitter=20= functions.=0A+=0A+We=20talk=20about=20a=20node=20being=20``smaller''=20= or=20``larger'',=20and=20``lower''=20or=0A+``higher''.=20=20A=20smaller=20= and=20lower=20node=20is=20lower=20in=20the=20syntax=20tree=20and=0A= +therefore=20spans=20a=20smaller=20piece=20of=20text;=20a=20larger=20and=20= higher=20node=20is=0A+higher=20up=20in=20the=20syntax=20tree,=20= containing=20many=20smaller=20nodes=20as=20its=0A+children,=20and=20= therefore=20spans=20a=20larger=20piece=20of=20text.=0A+=0A+When=20a=20= function=20cannot=20find=20a=20node,=20it=20returns=20nil.=20=20And=20= for=20the=0A+convenience=20for=20function=20chaining,=20all=20the=20= functions=20that=20take=20a=20node=0A+as=20argument=20and=20returns=20a=20= node=20accept=20the=20node=20to=20be=20nil;=20in=20that=0A+case,=20the=20= function=20just=20returns=20nil.=0A+=0A+@vindex=20= tree-sitter-node-outdated=0A+Nodes=20are=20not=20automatically=20updated=20= when=20the=20associated=20buffer=20is=0A+modified.=20=20In=20fact,=20= there=20is=20no=20way=20to=20update=20a=20node=20once=20it=20is=0A= +retrieved.=20=20It=20is=20best=20to=20use=20a=20node=20and=20throw=20it=20= away=20and=20not=20save=0A+it.=20=20A=20node=20is=20@dfn{outdated}=20if=20= the=20buffer=20has=20changed=20since=20the=20node=0A+is=20retrieved.=20=20= Using=20an=20outdated=20node=20throws=0A+@var{tree-sitter-node-outdated}=20= error.=0A+=0A+@heading=20Retrieving=20node=20from=20syntax=20tree=0A+=0A= +@defun=20tree-sitter-node-at=20beg=20&optional=20end=20parser-or-lang=20= named=0A+This=20function=20returns=20the=20@emph{smallest}=20node=20that=20= covers=20the=20span=0A+from=20@var{beg}=20to=20@var{end}.=20=20In=20= other=20words,=20the=20start=20of=20the=20node=0A+@code{<=3D}=20= @var{beg},=20and=20the=20end=20of=20the=20node=20@code{>=3D}=20= @var{end}.=20=20If=0A+@var{end}=20is=20omitted,=20it=20defaults=20to=20= the=20value=20of=20@var{beg}.=0A+=0A+When=20@var{parser-or-lang}=20is=20= nil,=20this=20function=20uses=20the=20first=20parser=0A+in=20= @var{tree-sitter-parser-list}=20in=20the=20current=20buffer.=20=20If=0A= +@var{parser-or-lang}=20is=20a=20parser=20object,=20it=20use=20that=20= parser;=20if=0A+@var{parser-or-lang}=20is=20a=20language,=20it=20finds=20= the=20first=20parser=20using=0A+that=20language=20in=20= @var{tree-sitter-parser-list}=20and=20use=20that.=0A+=0A+If=20= @var{named}=20is=20non-nil,=20this=20function=20looks=20for=20a=20named=20= node=0A+instead=20(@pxref{tree-sitter=20named=20node,=20named=20node}).=0A= +=0A+@example=0A+@group=0A+;;=20Find=20the=20node=20at=20point=20in=20a=20= C=20parser's=20syntax=20tree.=0A+(tree-sitter-node-at=20(point)=20= (point)=20'tree-sitter-c)=0A+=20=20=20=20@c=20@result{}=20= #=0A+@end=20group=0A= +@end=20example=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-parser-root-node=20parser=0A+This=20function=20returns=20the=20= root=20node=20of=20the=20syntax=20tree=20generated=20by=0A+@var{parser}.=0A= +@end=20defun=0A+=0A+@defun=20tree-sitter-buffer-root-node=20&optional=20= language=0A+This=20function=20finds=20the=20first=20parser=20that=20uses=20= @var{language}=20in=0A+@var{tree-sitter-parser-list}=20in=20the=20= current=20buffer,=20and=20returns=20the=0A+root=20node=20of=20that=20= buffer.=20=20If=20it=20cannot=20find=20an=20appropriate=20parser,=20it=0A= +returns=20nil.=0A+@end=20defun=0A+=0A+Once=20we=20have=20a=20node,=20we=20= can=20retrieve=20other=20nodes=20from=20it,=20or=20query=20for=0A= +information=20about=20this=20node.=0A+=0A+@heading=20Retrieving=20node=20= from=20other=20nodes=0A+=0A+@subheading=20By=20kinship=0A+=0A+@defun=20= tree-sitter-node-parent=20node=0A+This=20function=20returns=20the=20= immediate=20parent=20of=20@var{node}.=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-node-child=20node=20n=20&optional=20named=0A+This=20function=20= returns=20the=20@var{n}'th=20child=20of=20@var{node}.=20=20If=0A= +@var{named}=20is=20non-nil,=20then=20it=20only=20counts=20named=20nodes=0A= +(@pxref{tree-sitter=20named=20node,=20named=20node}).=20=20For=20= example,=20in=20a=20node=0A+that=20represents=20a=20string:=20= @code{"text"},=20there=20are=20three=20children=0A+nodes:=20the=20= opening=20quote=20@code{"},=20the=20string=20content=20@code{text},=20= and=0A+the=20enclosing=20quote=20@code{"}.=20=20Among=20these=20nodes,=20= the=20first=20child=20is=0A+the=20opening=20quote=20@code{"},=20the=20= first=20named=20child=20is=20the=20string=0A+content=20@code{text}.=0A= +@end=20defun=0A+=0A+@defun=20tree-sitter-node-children=20node=20= &optional=20named=0A+This=20function=20returns=20all=20of=20@var{node}'s=20= children=20in=20a=20list.=20=20If=0A+@var{named}=20is=20non-nil,=20then=20= it=20only=20retrieves=20named=20nodes=0A+(@pxref{tree-sitter=20named=20= node,=20named=20node}).=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-next-sibling=20node=20&optional=20named=0A+This=20function=20= finds=20the=20next=20sibling=20of=20@var{node}.=20=20If=20@var{named}=20= is=0A+non-nil,=20it=20finds=20the=20next=20named=20sibling=20= (@pxref{tree-sitter=20named=0A+node,=20named=20node}).=0A+@end=20defun=0A= +=0A+@defun=20tree-sitter-prev-sibling=20node=20&optional=20named=0A= +This=20function=20finds=20the=20previous=20sibling=20of=20@var{node}.=20= =20If=0A+@var{named}=20is=20non-nil,=20it=20finds=20the=20previous=20= named=20sibling=0A+(@pxref{tree-sitter=20named=20node,=20named=20node}).=0A= +@end=20defun=0A+=0A+@subheading=20By=20field=20name=0A+=0A+To=20make=20= the=20syntax=20tree=20easier=20to=20analyze,=20many=20language=20= definitions=0A+assign=20@dfn{field=20names}=20to=20child=20nodes=20= (@pxref{tree-sitter=20node=20field=0A+name,=20field=20name}).=20=20For=20= example,=20a=20@code{function_definition}=20node=0A+could=20have=20a=20= @code{declarator}=20and=20a=20@code{body}.=0A+=0A+@defun=20= tree-sitter-child-by-field-name=20node=20field-name=0A+This=20function=20= finds=20the=20child=20of=20@var{node}=20that=20has=20@var{field-name}=0A= +as=20its=20field=20name.=0A+=0A+@example=0A+@group=0A+;;=20Get=20the=20= child=20that=20has=20"body"=20as=20its=20field=20name.=0A= +(tree-sitter-child-by-field-name=20node=20"body")=0A+=20=20=20=20@c=20= @result{}=20#=0A= +@end=20group=0A+@end=20example=0A+@end=20defun=0A+=0A+@subheading=20By=20= position=0A+=0A+@defun=20tree-sitter-first-child-for-pos=20node=20pos=20= &optional=20named=0A+This=20function=20finds=20the=20first=20child=20of=20= @var{node}=20that=20extends=20beyond=0A+@var{pos}.=20=20``Extend=20= beyond''=20means=20the=20end=20of=20the=20child=20node=0A+@code{>=3D}=20= @var{pos}.=20=20This=20function=20only=20looks=20for=20immediate=20= children=20of=0A+@var{node},=20and=20doesn't=20look=20in=20its=20grand=20= children.=20=20If=20@var{named}=20is=0A+non-nil,=20it=20only=20looks=20= for=20named=20child=20(@pxref{tree-sitter=20named=20node,=0A+named=20= node}).=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-node-descendant-for-range=20node=20beg=20end=20&optional=20= named=0A+This=20function=20finds=20the=20@emph{smallest}=20(grand)child=20= of=20@var{node}=0A+that=20spans=20the=20range=20from=20@var{beg}=20to=20= @var{end}.=20=20It=20is=20similar=20to=0A+@code{tree-sitter-node-at}.=20=20= If=20@var{named}=20is=20non-nil,=20it=20only=20looks=0A+for=20named=20= child=20(@pxref{tree-sitter=20named=20node,=20named=20node}).=0A+@end=20= defun=0A+=0A+@heading=20More=20convenient=20functions=0A+=0A+@defun=20= tree-sitter-filter-child=20node=20pred=20&optional=20named=0A+This=20= function=20finds=20children=20of=20@var{node}=20that=20satisfies=20= @var{pred}.=0A+=0A+Function=20@var{pred}=20takes=20the=20child=20node=20= as=20the=20argument=20and=20should=0A+return=20non-nil=20to=20indicated=20= keeping=20the=20child.=20=20If=20@var{named}=0A+non-nil,=20this=20= function=20only=20searches=20for=20named=20nodes."=0A+@end=20defun=0A+=0A= +@defun=20tree-sitter-parent-until=20node=20pred=0A+This=20function=20= repeatedly=20finds=20the=20parent=20of=20@var{node},=20and=20returns=0A= +the=20parent=20if=20it=20satisfies=20@var{pred}=20(which=20takes=20the=20= parent=20as=20the=0A+argument).=20=20If=20no=20parent=20satisfies=20= @var{pred},=20this=20function=20returns=0A+nil.=0A+@end=20defun=0A+=0A= +@defun=20tree-sitter-parent-while=0A+This=20function=20repeatedly=20= finds=20the=20parent=20of=20@var{node},=20and=20keeps=0A+doing=20so=20as=20= long=20as=20the=20parent=20satisfies=20@var{pred}=20(which=20takes=20the=0A= +parent=20as=20the=20single=20argument).=20=20I.e.,=20this=20function=20= returns=20the=0A+farthest=20parent=20that=20still=20satisfies=20= @var{pred}.=0A+@end=20defun=0A+=0A+@node=20Accessing=20Node=0A+@section=20= Accessing=20Node=20Information=0A+=0A+Before=20going=20further,=20make=20= sure=20you=20have=20read=20the=20basic=20conventions=0A+about=20= tree-sitter=20nodes=20in=20the=20previous=20node.=0A+=0A+@heading=20= Basic=20information=0A+=0A+Every=20node=20is=20associated=20with=20a=20= parser,=20and=20that=20parser=20is=20associated=0A+with=20a=20buffer.=20=20= The=20following=20functions=20let=20you=20retrieve=20them.=0A+=0A+@defun=20= tree-sitter-node-parser=20node=0A+This=20function=20returns=20= @var{node}'s=20associated=20parser.=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-node-buffer=20node=0A+This=20function=20returns=20= @var{node}'s=20parser's=20associated=20buffer.=0A+@end=20defun=0A+=0A= +@defun=20tree-sitter-node-language=20node=0A+This=20function=20returns=20= @var{node}'s=20parser's=20associated=20language.=0A+@end=20defun=0A+=0A= +Each=20node=20represents=20a=20piece=20of=20text=20in=20the=20buffer.=20= =20Functions=20below=0A+finds=20relevant=20information=20about=20that=20= text.=0A+=0A+@defun=20tree-sitter-node-start=20node=0A+Return=20the=20= start=20position=20of=20@var{node}.=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-node-end=20node=0A+Return=20the=20end=20position=20of=20= @var{node}.=0A+@end=20defun=0A+=0A+@defun=20tree-sitter-node-text=20node=20= &optional=20object=0A+Returns=20the=20buffer=20text=20that=20@var{node}=20= represents.=20=20(If=20@var{node}=20is=0A+retrieved=20from=20parsing=20a=20= string,=20it=20will=20be=20the=20text=20from=20that=0A+string.)=0A+@end=20= defun=0A+=0A+Here=20are=20some=20basic=20checks=20on=20tree-sitter=20= nodes.=0A+=0A+@defun=20tree-sitter-node-p=20object=0A+Checks=20if=20= @var{object}=20is=20a=20tree-sitter=20syntax=20node.=0A+@end=20defun=0A+=0A= +@defun=20tree-sitter-node-eq=20node1=20node2=0A+Checks=20if=20= @var{node1}=20and=20@var{node2}=20are=20the=20same=20node=20in=20a=20= syntax=0A+tree.=0A+@end=20defun=0A+=0A+@heading=20Property=20information=0A= +=0A+In=20general,=20nodes=20in=20a=20concrete=20syntax=20tree=20fall=20= into=20two=20categories:=0A+@dfn{named=20nodes}=20and=20@dfn{anonymous=20= nodes}.=20=20Whether=20a=20node=20is=20named=0A+or=20anonymous=20is=20= determined=20by=20the=20language=20definition=0A+(@pxref{tree-sitter=20= named=20node,=20named=20node}).=0A+=0A+@cindex=20tree-sitter=20missing=20= node=0A+Apart=20from=20being=20named/anonymous,=20a=20node=20can=20have=20= other=20properties.=20=20A=0A+node=20can=20be=20``missing'':=20missing=20= nodes=20are=20inserted=20by=20the=20parser=20in=0A+order=20to=20recover=20= from=20certain=20kinds=20of=20syntax=20errors,=20i.e.,=20something=0A= +should=20probably=20be=20there=20according=20to=20the=20grammar,=20but=20= not=20there.=0A+=0A+@cindex=20tree-sitter=20extra=20node=0A+A=20node=20= can=20be=20``extra'':=20extra=20nodes=20represent=20things=20like=20= comments,=0A+which=20can=20appear=20anywhere=20in=20the=20text.=0A+=0A= +@cindex=20tree-sitter=20node=20that=20has=20changes=0A+A=20node=20``has=20= changes''=20if=20the=20buffer=20changed=20since=20when=20the=20node=20is=0A= +retrieved.=20=20In=20this=20case,=20the=20node's=20start=20and=20end=20= position=20would=20be=0A+off=20and=20we=20better=20throw=20it=20away=20= and=20retrieve=20a=20new=20one.=0A+=0A+@cindex=20tree-sitter=20node=20= that=20has=20error=0A+A=20node=20``has=20error''=20if=20the=20text=20it=20= spans=20contains=20a=20syntax=20error.=20=20It=0A+can=20be=20the=20node=20= itself=20has=20an=20error,=20or=20one=20of=20its=20(grand)children=20has=0A= +an=20error.=0A+=0A+@defun=20tree-sitter-node-check=20node=20property=0A= +This=20function=20checks=20if=20@var{node}=20has=20@var{property}.=20=20= @var{property}=0A+can=20be=20@code{'named},=20@code{'missing},=20= @code{'extra},=0A+@code{'has-changes},=20or=20@code{'has-error}.=0A+@end=20= defun=0A+=0A+Named=20nodes=20have=20``types''=20(@pxref{tree-sitter=20= node=20type,=20node=20type}).=0A+For=20example,=20a=20named=20node=20can=20= be=20a=20@code{string_literal}=20node,=20where=0A+@code{string_literal}=20= is=20its=20type.=0A+=0A+@defun=20tree-sitter-node-type=20node=0A+Return=20= @var{node}'s=20type=20as=20a=20string.=0A+@end=20defun=0A+=0A+@heading=20= Information=20as=20a=20child=20or=20parent=0A+=0A+@defun=20= tree-sitter-node-index=20node=20&optional=20named=0A+This=20function=20= returns=20the=20index=20of=20@var{node}=20as=20a=20child=20node=20of=20= its=0A+parent.=20=20If=20@var{named}=20is=20non-nil,=20it=20only=20count=20= named=20nodes=0A+(@pxref{tree-sitter=20named=20node,=20named=20node}).=0A= +@end=20defun=0A+=0A+@defun=20tree-sitter-node-field-name=20node=0A+A=20= child=20of=20a=20parent=20node=20could=20have=20a=20field=20name=20= (@pxref{tree-sitter=0A+node=20field=20name,=20field=20name}).=20=20This=20= function=20returns=20the=20field=20name=0A+of=20@var{node}=20as=20a=20= child=20of=20its=20parent.=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-node-field-name-for-child=20node=20n=0A+This=20is=20a=20more=20= primitive=20function=20that=20returns=20the=20field=20name=20of=20the=0A= +@var{n}'th=20child=20of=20@var{node}.=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-child-count=20node=20&optional=20named=0A+This=20function=20= finds=20the=20number=20of=20children=20of=20@var{node}.=20=20If=0A= +@var{named}=20is=20non-nil,=20it=20only=20counts=20named=20child=20= (@pxref{tree-sitter=0A+named=20node,=20named=20node}).=0A+@end=20defun=0A= +=0A+@node=20Pattern=20Matching=0A+@section=20Pattern=20Matching=20= Tree-sitter=20Nodes=0A+=0A+Tree-sitter=20let=20us=20pattern=20match=20= with=20a=20small=20declarative=20language.=0A+Pattern=20matching=20= consists=20of=20two=20steps:=20first=20tree-sitter=20matches=20a=0A= +@dfn{pattern}=20against=20nodes=20in=20the=20syntax=20tree,=20then=20it=20= @dfn{captures}=0A+specific=20nodes=20in=20that=20pattern=20and=20returns=20= the=20captured=20nodes.=0A+=0A+We=20describe=20first=20how=20to=20write=20= the=20most=20basic=20query=20pattern=20and=20how=20to=0A+capture=20nodes=20= in=20a=20pattern,=20then=20the=20pattern-match=20function,=20finally=0A= +more=20advanced=20pattern=20syntax.=0A+=0A+@heading=20Basic=20query=20= syntax=0A+=0A+@cindex=20Tree-sitter=20query=20syntax=0A+@cindex=20= Tree-sitter=20query=20pattern=0A+A=20@dfn{query}=20consists=20of=20= multiple=20@dfn{patterns},=20each=20pattern=20is=20an=0A+s-expression=20= that=20matches=20a=20certain=20node=20in=20the=20syntax=20node.=20=20A=0A= +pattern=20has=20the=20following=20shape:=0A+=0A+@example=0A+(@var{type}=20= @var{child}...)=0A+@end=20example=0A+=0A+@noindent=0A+For=20example,=20a=20= pattern=20that=20matches=20a=20@code{binary_expression}=20node=20that=0A= +contains=20@code{number_literal}=20child=20nodes=20would=20look=20like=0A= +=0A+@example=0A+(binary_expression=20(number_literal))=0A+@end=20= example=0A+=0A+To=20@dfn{capture}=20a=20node=20in=20the=20query=20= pattern=20above,=20append=0A+@code{@@capture-name}=20after=20the=20node=20= pattern=20you=20want=20to=20capture.=20=20For=0A+example,=0A+=0A= +@example=0A+(binary_expression=20(number_literal)=20@@number-in-exp)=0A= +@end=20example=0A+=0A+@noindent=0A+captures=20@code{number_literal}=20= nodes=20that=20are=20inside=20a=0A+@code{binary_expression}=20node=20= with=20capture=20name=20@code{number-in-exp}.=0A+=0A+We=20can=20capture=20= the=20@code{binary_expression}=20node=20too,=20with=20capture=0A+name=20= @code{biexp}:=0A+=0A+@example=0A+(binary_expression=0A+=20= (number_literal)=20@@number-in-exp)=20@@biexp=0A+@end=20example=0A+=0A= +@heading=20Query=20function=0A+=0A+Now=20we=20can=20introduce=20the=20= query=20functions.=0A+=0A+@defun=20tree-sitter-query-capture=20node=20= query=20&optional=20beg=20end=0A+This=20function=20matches=20patterns=20= in=20@var{query}=20in=20@var{node}.=0A+Argument=20@var{query}=20can=20be=20= a=20either=20string=20or=20a=20s-expression.=20=20For=0A+now,=20we=20= focus=20on=20the=20string=20syntax;=20s-expression=20syntax=20is=20= described=0A+at=20the=20end=20of=20the=20section.=0A+=0A+The=20function=20= returns=20all=20captured=20nodes=20in=20a=20list=20of=0A= +@code{(@var{capture_name}=20.=20@var{node})}.=20=20If=20@var{beg}=20and=20= @var{end}=0A+are=20both=20non-nil,=20it=20only=20pattern=20matches=20= nodes=20in=20that=20range.=0A+=0A+@vindex=20tree-sitter-query-error=0A= +This=20function=20raise=20a=20@var{tree-sitter-query-error}=20if=20= @var{query}=20is=0A+malformed.=20=20The=20signal=20data=20contains=20a=20= description=20of=20the=20specific=0A+error.=0A+@end=20defun=0A+=0A= +@defun=20tree-sitter-query-in=20source=20query=20&optional=20beg=20end=0A= +This=20function=20matches=20patterns=20in=20@var{query}=20in=20= @var{source},=20and=0A+returns=20all=20captured=20nodes=20in=20a=20list=20= of=20@code{(@var{capture_name}=0A+.=20@var{node})}.=20=20If=20@var{beg}=20= and=20@var{end}=20are=20both=20non-nil,=20it=20only=0A+pattern=20match=20= nodes=20in=20that=20range.=0A+=0A+Argument=20@var{source}=20designates=20= a=20node,=20it=20can=20be=20a=20language=20symbol,=0A+a=20parser,=20or=20= simply=20a=20node.=20=20If=20a=20language=20symbol,=20@var{source}=0A= +represents=20the=20root=20node=20of=20the=20first=20parser=20for=20that=20= language=20in=20the=0A+current=20buffer;=20if=20a=20parser,=20= @var{source}=20represents=20the=20root=20node=20of=0A+that=20parser.=0A+=0A= +This=20function=20also=20raises=20@var{tree-sitter-query-error}.=0A= +@end=20defun=0A+=0A+For=20example,=20suppose=20@var{node}'s=20content=20= is=20@code{1=20+=202},=20and=0A+@var{query}=20is=0A+=0A+@example=0A= +@group=0A+(setq=20query=0A+=20=20=20=20=20=20"(binary_expression=0A+=20=20= =20=20=20=20=20=20(number_literal)=20@@number-in-exp)=20@@biexp")=0A= +@end=20group=0A+@end=20example=0A+=0A+@noindent=0A+Querying=20that=20= query=20would=20return=0A+=0A+@example=0A+@group=0A= +(tree-sitter-query-capture=20node=20query)=0A+=20=20=20=20@result{}=20= ((biexp=20.=20@var{})=0A+=20=20=20=20=20=20=20= (number-in-exp=20.=20@var{})=0A+=20=20=20=20=20=20=20= (number-in-exp=20.=20@var{}))=0A+@end=20group=0A+@end=20= example=0A+=0A+As=20we=20mentioned=20earlier,=20a=20@var{query}=20could=20= contain=20multiple=0A+patterns.=20For=20example,=20it=20could=20have=20= two=20top-level=20patterns:=0A+=0A+@example=0A+@group=0A+(setq=20query=0A= +=20=20=20=20=20=20"(binary_expression)=20@@biexp=0A+=20=20=20=20=20=20=20= (number_literal)=20=20@@number=20@@biexp")=0A+@end=20group=0A+@end=20= example=0A+=0A+@defun=20tree-sitter-query-string=20string=20query=20= language=0A+This=20function=20parses=20@var{string}=20with=20= @var{language},=20pattern=20matches=0A+its=20root=20node=20with=20= @var{query},=20and=20returns=20the=20result.=0A+@end=20defun=0A+=0A= +@heading=20More=20query=20syntax=0A+=0A+Besides=20node=20type=20and=20= capture,=20tree-sitter's=20query=20syntax=20can=20express=0A+anonymous=20= node,=20field=20name,=20wildcard,=20quantification,=20grouping,=0A= +alternation,=20anchor,=20and=20predicate.=0A+=0A+@subheading=20= Anonymous=20node=0A+=0A+An=20anonymous=20node=20is=20written=20verbatim,=20= surrounded=20by=20quotes.=20=20A=0A+pattern=20matching=20(and=20= capturing)=20keyword=20@code{return}=20would=20be=0A+=0A+@example=0A= +"return"=20@@keyword=0A+@end=20example=0A+=0A+@subheading=20Wild=20card=0A= +=0A+In=20a=20query=20pattern,=20@samp{(_)}=20matches=20any=20named=20= node,=20and=20@samp{_}=0A+matches=20any=20named=20and=20anonymous=20= node.=20=20For=20example,=20to=20capture=20any=0A+named=20child=20of=20a=20= @code{binary_expression}=20node,=20the=20pattern=20would=20be=0A+=0A= +@example=0A+(binary_expression=20(_)=20@@in_biexp)=0A+@end=20example=0A= +=0A+@subheading=20Field=20name=0A+=0A+We=20can=20capture=20child=20= nodes=20that=20has=20specific=20field=20names:=0A+=0A+@example=0A+@group=0A= +(function_definition=0A+=20=20declarator:=20(_)=20@@func-declarator=0A+=20= =20body:=20(_)=20@@func-body)=0A+@end=20group=0A+@end=20example=0A+=0A= +We=20can=20also=20capture=20a=20node=20that=20doesn't=20have=20certain=20= field,=20say,=20a=0A+@code{function_definition}=20without=20a=20= @code{body}=20field.=0A+=0A+@example=0A+(function_definition=20!body)=20= @@func-no-body=0A+@end=20example=0A+=0A+@subheading=20Quantify=20node=0A= +=0A+Tree-sitter=20recognizes=20quantification=20operators=20@samp{*},=20= @samp{+}=20and=0A+@samp{?}.=20=20Their=20meanings=20are=20the=20same=20= as=20in=20regular=20expressions:=0A+@samp{*}=20matches=20the=20preceding=20= pattern=20zero=20or=20more=20times,=20@samp{+}=0A+matches=20one=20or=20= more=20times,=20and=20@samp{?}=20matches=20zero=20or=20one=20time.=0A+=0A= +For=20example,=20this=20pattern=20matches=20@code{type_declaration}=20= nodes=0A+that=20has=20@emph{zero=20or=20more}=20@code{long}=20keyword.=0A= +=0A+@example=0A+(type_declaration=20"long"*=20@@long-in-type)=0A+@end=20= example=0A+=0A+@noindent=0A+And=20this=20pattern=20matches=20a=20type=20= declaration=20that=20has=20zero=20or=20one=0A+@code{long}=20keyword:=0A+=0A= +@example=0A+(type_declaration=20"long"?)=20@@type-decl=0A+@end=20= example=0A+=0A+@subheading=20Grouping=0A+=0A+Similar=20to=20groups=20in=20= regular=20expression,=20we=20can=20bundle=20patterns=20into=20a=0A+group=20= and=20apply=20quantification=20operators=20to=20it.=20=20For=20example,=20= to=0A+express=20a=20comma=20separated=20list=20of=20identifiers,=20one=20= could=20write=0A+=0A+@example=0A+(identifier)=20(","=20(identifier))*=0A= +@end=20example=0A+=0A+@subheading=20Alternation=0A+=0A+Again,=20similar=20= to=20regular=20expressions,=20we=20can=20express=20``match=20anyone=0A= +from=20this=20group=20of=20patterns''=20in=20the=20query=20pattern.=20=20= The=20syntax=20is=20a=0A+list=20of=20patterns=20enclosed=20in=20square=20= brackets.=20=20For=20example,=20to=20capture=0A+some=20keywords=20in=20= C,=20the=20query=20pattern=20would=20be=0A+=0A+@example=0A+@group=0A+[=0A= +=20=20"return"=0A+=20=20"break"=0A+=20=20"if"=0A+=20=20"else"=0A+]=20= @@keyword=0A+@end=20group=0A+@end=20example=0A+=0A+@subheading=20Anchor=0A= +=0A+The=20anchor=20operator=20@samp{.}=20can=20be=20used=20to=20enforce=20= juxtaposition,=0A+i.e.,=20to=20enforce=20two=20things=20to=20be=20= directly=20next=20to=20each=20other.=20=20The=0A+two=20``things''=20can=20= be=20two=20nodes,=20or=20a=20child=20and=20the=20end=20of=20its=20= parent.=0A+For=20example,=20to=20capture=20the=20first=20child,=20the=20= last=20child,=20or=20two=0A+adjacent=20children:=0A+=0A+@example=0A= +@group=0A+;;=20Anchor=20the=20child=20with=20the=20end=20of=20its=20= parent.=0A+(compound_expression=20(_)=20@@last-child=20.)=0A+=0A+;;=20= Anchor=20the=20child=20with=20the=20beginning=20of=20its=20parent.=0A= +(compound_expression=20.=20(_)=20@@first-child)=0A+=0A+;;=20Anchor=20= two=20adjacent=20children.=0A+(compound_expression=0A+=20(_)=20= @@prev-child=0A+=20.=0A+=20(_)=20@@next-child)=0A+@end=20group=0A+@end=20= example=0A+=0A+Note=20that=20the=20enforcement=20of=20juxtaposition=20= ignores=20any=20anonymous=0A+nodes.=0A+=0A+@subheading=20Predicate=0A+=0A= +We=20can=20add=20predicate=20constraints=20to=20a=20pattern.=20=20For=20= example,=20if=20we=20use=0A+the=20following=20query=20pattern=0A+=0A= +@example=0A+@group=0A+(=0A+=20(array=20.=20(_)=20@@first=20(_)=20@@last=20= .)=0A+=20(#equal=20@@first=20@@last)=0A+)=0A+@end=20group=0A+@end=20= example=0A+=0A+Then=20tree-sitter=20only=20matches=20arrays=20where=20= the=20first=20element=20equals=20to=0A+the=20last=20element.=20=20To=20= attach=20a=20predicate=20to=20a=20pattern,=20we=20need=20to=0A+group=20= then=20together.=20=20A=20predicate=20always=20starts=20with=20a=20= @samp{#}.=0A+Currently=20there=20are=20two=20predicates,=20@code{#equal}=20= and=20@code{#match}.=0A+=0A+@deffn=20Predicate=20equal=20arg1=20arg2=0A= +Matches=20if=20@var{arg1}=20equals=20to=20@var{arg2}.=20=20Arguments=20= can=20be=20either=20a=0A+string=20or=20a=20capture=20name.=20=20Capture=20= names=20represent=20the=20text=20that=20the=0A+captured=20node=20spans=20= in=20the=20buffer.=0A+@end=20deffn=0A+=0A+@deffn=20Predicate=20match=20= regexp=20capture-name=0A+Matches=20if=20the=20text=20that=20= @var{capture-name}=E2=80=99s=20node=20spans=20in=20the=20buffer=0A= +matches=20regular=20expression=20@var{regexp}.=20=20Matching=20is=20= case-sensitive.=0A+@end=20deffn=0A+=0A+Note=20that=20a=20predicate=20can=20= only=20refer=20to=20capture=20names=20appeared=20in=20the=0A+same=20= pattern.=20=20Indeed,=20it=20makes=20little=20sense=20to=20refer=20to=20= capture=20names=0A+in=20other=20patterns=20anyway.=0A+=0A+@heading=20= S-expression=20patterns=0A+=0A+Besides=20strings,=20Emacs=20provides=20a=20= s-expression=20based=20syntax=20for=20query=0A+patterns.=20It=20largely=20= resembles=20the=20string-based=20syntax.=20=20For=20example,=0A+the=20= following=20pattern=0A+=0A+@example=0A+@group=0A= +(tree-sitter-query-capture=0A+=20node=20"(addition_expression=0A+=20=20=20= =20=20=20=20=20left:=20(_)=20@@left=0A+=20=20=20=20=20=20=20=20\"+\"=20= @@plus-sign=0A+=20=20=20=20=20=20=20=20right:=20(_)=20@@right)=20= @@addition=0A+=0A+=20=20=20=20=20=20=20=20[\"return\"=20\"break\"]=20= @@keyword")=0A+@end=20group=0A+@end=20example=0A+=0A+@noindent=0A+is=20= equivalent=20to=0A+=0A+@example=0A+@group=0A+(tree-sitter-query-capture=0A= +=20node=20'((addition_expression=0A+=20=20=20=20=20=20=20=20=20left:=20= (_)=20@@left=0A+=20=20=20=20=20=20=20=20=20"+"=20@@plus-sign=0A+=20=20=20= =20=20=20=20=20=20right:=20(_)=20@@right)=20@@addition=0A+=0A+=20=20=20=20= =20=20=20=20=20["return"=20"break"]=20@@keyword))=0A+@end=20group=0A= +@end=20example=0A+=0A+Most=20pattern=20syntax=20can=20be=20written=20= directly=20as=20strange=20but=0A+never-the-less=20valid=20s-expressions.=20= =20Only=20a=20few=20of=20them=20needs=0A+modification:=0A+=0A+@itemize=0A= +@item=0A+Anchor=20@samp{.}=20is=20written=20as=20@code{:anchor}.=0A= +@item=0A+@samp{?}=20is=20written=20as=20@samp{:?}.=0A+@item=0A+@samp{*}=20= is=20written=20as=20@samp{:*}.=0A+@item=0A+@samp{+}=20is=20written=20as=20= @samp{:+}.=0A+@item=0A+@code{#equal}=20is=20written=20as=20= @code{:equal}.=20=20In=20general,=20predicates=0A+change=20their=20= @samp{#}=20to=20@samp{:}.=0A+@end=20itemize=0A+=0A+For=20example,=0A+=0A= +@example=0A+@group=0A+"(=0A+=20=20(compound_expression=20.=20(_)=20= @@first=20(_)*=20@@rest)=0A+=20=20(#match=20\"love\"=20@@first)=0A+=20=20= )"=0A+@end=20group=0A+@end=20example=0A+=0A+is=20written=20in=20= s-expression=20as=0A+=0A+@example=0A+@group=0A+'((=0A+=20=20=20= (compound_expression=20:anchor=20(_)=20@@first=20(_)=20:*=20@@rest)=0A+=20= =20=20(:match=20"love"=20@@first)=0A+=20=20=20))=0A+@end=20group=0A+@end=20= example=0A+=0A+@defun=20tree-sitter-expand-query=20query=0A+This=20= function=20expands=20the=20s-expression=20@var{query}=20into=20a=20= string=0A+query.=20=20It=20is=20usually=20a=20good=20idea=20to=20expand=20= the=20s-expression=20patterns=0A+into=20strings=20for=20font-lock=20= queries=20since=20they=20are=20called=20repeatedly.=0A+@end=20defun=0A+=0A= +Tree-sitter=20project's=20documentation=20about=20pattern-matching=20= can=20be=0A+found=20at=0A= +@uref{https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-mat= ching-with-queries}.=0A+=0A+@node=20Multiple=20Languages=0A+@section=20= Parsing=20Text=20in=20Multiple=20Languages=0A+=0A+Sometimes,=20the=20= source=20of=20a=20programming=20language=20could=20contain=20sources=0A= +of=20other=20languages,=20HTML=20+=20CSS=20+=20JavaScript=20is=20one=20= example.=20=20In=20that=0A+case,=20we=20need=20to=20assign=20individual=20= parsers=20to=20text=20segments=20written=20in=0A+different=20languages.=20= =20Traditionally=20this=20is=20achieved=20by=20using=0A+narrowing.=20=20= While=20tree-sitter=20works=20with=20narrowing=20(@pxref{tree-sitter=0A= +narrowing,=20narrowing}),=20the=20recommended=20way=20is=20to=20set=20= ranges=20in=20which=0A+a=20parser=20will=20operate.=0A+=0A+@defun=20= tree-sitter-parser-set-included-ranges=20parser=20ranges=0A+This=20= function=20sets=20the=20range=20of=20@var{parser}=20to=20@var{ranges}.=20= =20Then=0A+@var{parser}=20will=20only=20read=20the=20text=20covered=20in=20= each=20range.=20=20Each=0A+range=20in=20@var{ranges}=20is=20a=20list=20= of=20cons=20@code{(@var{beg}=0A+.=20@var{end})}.=0A+=0A+Each=20range=20= in=20@var{ranges}=20must=20come=20in=20order=20and=20not=20overlap.=20=20= That=0A+is,=20in=20pseudo=20code:=0A+=0A+@example=0A+@group=0A+(cl-loop=20= for=20idx=20from=201=20to=20(1-=20(length=20ranges))=0A+=20=20=20=20=20=20= =20=20=20for=20prev=20=3D=20(nth=20(1-=20idx)=20ranges)=0A+=20=20=20=20=20= =20=20=20=20for=20next=20=3D=20(nth=20idx=20ranges)=0A+=20=20=20=20=20=20= =20=20=20should=20(<=3D=20(car=20prev)=20(cdr=20prev)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(car=20next)=20(cdr=20next)))=0A= +@end=20group=0A+@end=20example=0A+=0A+@vindex=20= tree-sitter-range-invalid=0A+If=20@var{ranges}=20violates=20this=20= constraint,=20or=20something=20else=20went=0A+wrong,=20this=20function=20= signals=20a=20@var{tree-sitter-range-invalid}.=20=20The=0A+signal=20data=20= contains=20a=20specific=20error=20message=20and=20the=20ranges=20we=20= are=0A+trying=20to=20set.=0A+=0A+This=20function=20can=20also=20be=20= used=20for=20disabling=20ranges.=20=20If=20@var{ranges}=0A+is=20nil,=20= the=20parser=20is=20set=20to=20parse=20the=20whole=20buffer.=0A+=0A= +Example:=0A+=0A+@example=0A+@group=0A= +(tree-sitter-parser-set-included-ranges=0A+=20parser=20'((1=20.=209)=20= (16=20.=2024)=20(24=20.=2025)))=0A+@end=20group=0A+@end=20example=0A= +@end=20defun=0A+=0A+@defun=20tree-sitter-parser-included-ranges=20= parser=0A+This=20function=20returns=20the=20ranges=20set=20for=20= @var{parser}.=20=20The=20return=0A+value=20is=20the=20same=20as=20the=20= @var{ranges}=20argument=20of=0A= +@code{tree-sitter-parser-included-ranges}:=20a=20list=20of=20cons=0A= +@code{(@var{beg}=20.=20@var{end})}.=20=20And=20if=20@var{parser}=20= doesn't=20have=20any=0A+ranges,=20the=20return=20value=20is=20nil.=0A+=0A= +@example=0A+@group=0A+(tree-sitter-parser-included-ranges=20parser)=0A+=20= =20=20=20@result{}=20((1=20.=209)=20(16=20.=2024)=20(24=20.=2025))=0A= +@end=20group=0A+@end=20example=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-set-ranges=20parser-or-lang=20ranges=0A+Like=20= @code{tree-sitter-parser-set-included-ranges},=20this=20function=20sets=0A= +the=20ranges=20of=20@var{parser-or-lang}=20to=20@var{ranges}.=20=20= Conveniently,=0A+@var{parser-or-lang}=20could=20be=20either=20a=20parser=20= or=20a=20language.=20=20If=20it=20is=0A+a=20language,=20this=20function=20= looks=20for=20the=20first=20parser=20in=0A+@var{tree-sitter-parser-list}=20= for=20that=20language=20in=20the=20current=20buffer,=0A+and=20set=20= range=20for=20it.=0A+@end=20defun=0A+=0A+@defun=20tree-sitter-get-ranges=20= parser-or-lang=0A+This=20function=20returns=20the=20ranges=20of=20= @var{parser-or-lang},=20like=0A= +@code{tree-sitter-parser-included-ranges}.=20=20And=20like=0A= +@code{tree-sitter-set-ranges},=20@var{parser-or-lang}=20can=20be=20a=20= parser=20or=0A+a=20language=20symbol.=0A+@end=20defun=0A+=0A+@defun=20= tree-sitter-query-range=20source=20pattern=20&optional=20beg=20end=0A= +This=20function=20matches=20@var{source}=20with=20@var{pattern}=20and=20= returns=20the=0A+ranges=20of=20captured=20nodes.=20=20The=20return=20= value=20has=20the=20same=20shape=20of=0A+other=20functions:=20a=20list=20= of=20@code{(@var{beg}=20.=20@var{end})}.=0A+=0A+For=20convenience,=20= @var{source}=20can=20be=20a=20language=20symbol,=20a=20parser,=20or=20a=0A= +node.=20=20If=20a=20language=20symbol,=20this=20function=20matches=20in=20= the=20root=20node=20of=0A+the=20first=20parser=20using=20that=20= language;=20if=20a=20parser,=20this=20function=0A+matches=20in=20the=20= root=20node=20of=20that=20parser;=20if=20a=20node,=20this=20function=0A= +matches=20in=20that=20node.=0A+=0A+Parameter=20@var{pattern}=20is=20the=20= query=20pattern=20used=20to=20capture=20nodes=0A+(@pxref{Pattern=20= Matching}).=20The=20capture=20names=20don't=20matter.=20=20Parameter=0A= +@var{beg}=20and=20@var{end},=20if=20both=20non-nil,=20limits=20the=20= range=20in=20which=0A+this=20function=20queries.=0A+=0A+Like=20other=20= query=20functions,=20this=20function=20raises=20an=0A= +@var{tree-sitter-query-error}=20if=20@var{pattern}=20is=20malformed.=0A= +@end=20defun=0A+=0A+@defun=20tree-sitter-language-at=20point=0A+This=20= function=20tries=20to=20figure=20out=20which=20language=20is=20= responsible=20for=0A+the=20text=20at=20@var{point}.=20=20It=20goes=20= over=20each=20parser=20in=0A+@var{tree-sitter-parser-list}=20and=20see=20= if=20that=20parser's=20range=20covers=0A+@var{point}.=0A+@end=20defun=0A= +=0A+@defvar=20tree-sitter-range-functions=0A+A=20list=20of=20range=20= functions.=20=20Font-locking=20and=20indenting=20code=20uses=0A= +functions=20in=20this=20alist=20to=20set=20correct=20ranges=20for=20a=20= language=20parser=0A+before=20using=20it.=0A+=0A+The=20signature=20of=20= each=20function=20should=20be=0A+=0A+@example=0A+(@var{start}=20= @var{end}=20&rest=20@var{_})=0A+@end=20example=0A+=0A+where=20= @var{start}=20and=20@var{end}=20marks=20the=20region=20that=20is=20about=20= to=20be=0A+used.=20=20A=20range=20function=20only=20need=20to=20(but=20= not=20limited=20to)=20update=0A+ranges=20in=20that=20region.=0A+=0A+Each=20= function=20in=20the=20list=20is=20called=20in-order.=0A+@end=20defvar=0A= +=0A+@defun=20tree-sitter-update-ranges=20&optional=20start=20end=0A= +This=20function=20is=20used=20by=20font-lock=20and=20indent=20to=20= update=20ranges=20before=0A+using=20any=20parser.=20=20Each=20range=20= function=20in=0A+@var{tree-sitter-range-functions}=20is=20called=20= in-order.=20=20Arguments=0A+@var{start}=20and=20@var{end}=20are=20passed=20= to=20each=20range=20function.=0A+@end=20defun=0A+=0A+@heading=20An=20= example=0A+=0A+Normally,=20in=20a=20set=20of=20languages=20that=20can=20= be=20mixed=20together,=20there=20is=20a=0A+major=20language=20and=20= several=20embedded=20languages.=20The=20major=20language=0A+parses=20the=20= whole=20document,=20and=20skips=20the=20embedded=20languages.=20Then=20= the=0A+parser=20for=20the=20major=20language=20knows=20the=20ranges=20of=20= the=20embedded=0A+languages.=20So=20we=20first=20parse=20the=20whole=20= document=20with=20the=20major=0A+language=E2=80=99s=20parser,=20set=20= ranges=20for=20the=20embedded=20languages,=20then=20parse=0A+the=20= embedded=20languages.=0A+=0A+Suppose=20we=20want=20to=20parse=20a=20very=20= simple=20document=20that=20mixes=20HTML,=20CSS=0A+and=20JavaScript:=0A+=0A= +@example=0A+@group=0A+=0A+=20=20=0A+=20=20= =0A+=0A+@end=20= group=0A+@end=20example=0A+=0A+We=20first=20parse=20with=20HTML,=20then=20= set=20ranges=20for=20CSS=20and=20JavaScript:=0A+=0A+@example=0A+@group=0A= +;;=20Create=20parsers.=0A+(setq=20html=20(tree-sitter-get-parser-create=20= 'tree-sitter-html))=0A+(setq=20css=20(tree-sitter-get-parser-create=20= 'tree-sitter-css))=0A+(setq=20js=20(tree-sitter-get-parser-create=20= 'tree-sitter-javascript))=0A+=0A+;;=20Set=20CSS=20ranges.=0A+(setq=20= css-range=0A+=20=20=20=20=20=20(tree-sitter-query-range=0A+=20=20=20=20=20= =20=20'tree-sitter-html=0A+=20=20=20=20=20=20=20"(style_element=20= (raw_text)=20@@capture)"))=0A+(tree-sitter-parser-set-included-ranges=20= css=20css-range)=0A+=0A+;;=20Set=20JavaScript=20ranges.=0A+(setq=20= js-range=0A+=20=20=20=20=20=20(tree-sitter-query-range=0A+=20=20=20=20=20= =20=20'tree-sitter-html=0A+=20=20=20=20=20=20=20"(script_element=20= (raw_text)=20@@capture)"))=0A+(tree-sitter-parser-set-included-ranges=20= js=20js-range)=0A+@end=20group=0A+@end=20example=0A+=0A+We=20use=20a=20= query=20pattern=20@code{(style_element=20(raw_text)=20@@capture)}=20to=0A= +find=20CSS=20nodes=20in=20the=20HTML=20parse=20tree.=20For=20how=20to=20= write=20query=0A+patterns,=20@pxref{Pattern=20Matching}.=0A+=0A+@node=20= Tree-sitter=20C=20API=0A+@section=20Tree-sitter=20C=20API=20= Correspondence=0A+=0A+Emacs'=20tree-sitter=20integration=20doesn't=20= expose=20every=20feature=0A+tree-sitter's=20C=20API=20provides.=20=20= Missing=20features=20include:=0A+=0A+@itemize=0A+@item=0A+Creating=20a=20= tree=20cursor=20and=20navigating=20the=20syntax=20tree=20with=20it.=0A= +@item=0A+Setting=20timeout=20and=20cancellation=20flag=20for=20a=20= parser.=0A+@item=0A+Setting=20the=20logger=20for=20a=20parser.=0A+@item=0A= +Printing=20a=20DOT=20graph=20of=20the=20syntax=20tree=20to=20a=20file.=0A= +@item=0A+Coping=20and=20modifying=20a=20syntax=20tree.=20=20(Emacs=20= doesn't=20expose=20a=20tree=0A+object.)=0A+@item=0A+Using=20(row,=20= column)=20coordinates=20as=20position.=0A+@item=0A+Updating=20a=20node=20= with=20changes.=20(In=20Emacs,=20retrieve=20a=20new=20node=20instead=0A= +of=20updating=20the=20existing=20one.)=0A+@item=0A+Querying=20statics=20= of=20a=20language=20definition.=0A+@end=20itemize=0A+=0A+In=20addition,=20= Emacs=20makes=20some=20changes=20to=20the=20C=20API=20to=20make=20the=20= API=20more=0A+convenient=20and=20idiomatic:=0A+=0A+@itemize=0A+@item=0A= +Instead=20of=20using=20byte=20positions,=20the=20ELisp=20API=20uses=20= character=0A+positions.=0A+@item=0A+Null=20nodes=20are=20converted=20to=20= nil.=0A+@end=20itemize=0A+=0A+Below=20is=20the=20correspondence=20= between=20all=20C=20API=20functions=20and=20their=0A+ELisp=20= counterparts.=20=20Sometimes=20one=20ELisp=20function=20corresponds=20to=0A= +multiple=20C=20functions,=20and=20many=20C=20functions=20don't=20have=20= an=20ELisp=0A+counterpart.=0A+=0A+@example=0A+ts_parser_new=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-parser-create=0A+ts_parser_delete=0A+ts_parser_set_language=0A= +ts_parser_language=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20tree-sitter-parser-language=0A+ts_parser_set_included_ranges=20= =20=20=20=20=20=20=20=20=20=20tree-sitter-parser-set-included-ranges=0A= +ts_parser_included_ranges=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-parser-included-ranges=0A+ts_parser_parse=0A= +ts_parser_parse_string=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20tree-sitter-parse-string=0A+ts_parser_parse_string_encoding=0A= +ts_parser_reset=0A+ts_parser_set_timeout_micros=0A= +ts_parser_timeout_micros=0A+ts_parser_set_cancellation_flag=0A= +ts_parser_cancellation_flag=0A+ts_parser_set_logger=0A+ts_parser_logger=0A= +ts_parser_print_dot_graphs=0A+ts_tree_copy=0A+ts_tree_delete=0A= +ts_tree_root_node=0A+ts_tree_language=0A+ts_tree_edit=0A= +ts_tree_get_changed_ranges=0A+ts_tree_print_dot_graph=0A+ts_node_type=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20tree-sitter-node-type=0A+ts_node_symbol=0A+ts_node_start_byte=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-node-start=0A+ts_node_start_point=0A+ts_node_end_byte=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-node-end=0A+ts_node_end_point=0A+ts_node_string=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-node-string=0A+ts_node_is_null=0A+ts_node_is_named=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-node-check=0A+ts_node_is_missing=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20tree-sitter-node-check=0A= +ts_node_is_extra=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20tree-sitter-node-check=0A+ts_node_has_changes=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20tree-sitter-node-check=0A= +ts_node_has_error=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20tree-sitter-node-check=0A+ts_node_parent=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-node-parent=0A+ts_node_child=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20tree-sitter-node-child=0A= +ts_node_field_name_for_child=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-node-field-name-for-child=0A+ts_node_child_count=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-node-child-count=0A+ts_node_named_child=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20tree-sitter-node-child=0A= +ts_node_named_child_count=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-node-child-count=0A+ts_node_child_by_field_name=20=20=20=20=20= =20=20=20=20=20=20=20=20tree-sitter-node-by-field-name=0A= +ts_node_child_by_field_id=0A+ts_node_next_sibling=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20tree-sitter-next-sibling=0A= +ts_node_prev_sibling=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20tree-sitter-prev-sibling=0A+ts_node_next_named_sibling=20=20=20=20=20= =20=20=20=20=20=20=20=20=20tree-sitter-next-sibling=0A= +ts_node_prev_named_sibling=20=20=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-prev-sibling=0A+ts_node_first_child_for_byte=20=20=20=20=20=20= =20=20=20=20=20=20tree-sitter-first-child-for-pos=0A= +ts_node_first_named_child_for_byte=20=20=20=20=20=20= tree-sitter-first-child-for-pos=0A+ts_node_descendant_for_byte_range=20=20= =20=20=20=20=20tree-sitter-descendant-for-range=0A= +ts_node_descendant_for_point_range=0A= +ts_node_named_descendant_for_byte_range=20= tree-sitter-descendant-for-range=0A= +ts_node_named_descendant_for_point_range=0A+ts_node_edit=0A+ts_node_eq=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20tree-sitter-node-eq=0A+ts_tree_cursor_new=0A= +ts_tree_cursor_delete=0A+ts_tree_cursor_reset=0A= +ts_tree_cursor_current_node=0A+ts_tree_cursor_current_field_name=0A= +ts_tree_cursor_current_field_id=0A+ts_tree_cursor_goto_parent=0A= +ts_tree_cursor_goto_next_sibling=0A+ts_tree_cursor_goto_first_child=0A= +ts_tree_cursor_goto_first_child_for_byte=0A= +ts_tree_cursor_goto_first_child_for_point=0A+ts_tree_cursor_copy=0A= +ts_query_new=0A+ts_query_delete=0A+ts_query_pattern_count=0A= +ts_query_capture_count=0A+ts_query_string_count=0A= +ts_query_start_byte_for_pattern=0A+ts_query_predicates_for_pattern=0A= +ts_query_step_is_definite=0A+ts_query_capture_name_for_id=0A= +ts_query_string_value_for_id=0A+ts_query_disable_capture=0A= +ts_query_disable_pattern=0A+ts_query_cursor_new=0A= +ts_query_cursor_delete=0A+ts_query_cursor_exec=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20tree-sitter-query-capture=0A= +ts_query_cursor_did_exceed_match_limit=0A+ts_query_cursor_match_limit=0A= +ts_query_cursor_set_match_limit=0A+ts_query_cursor_set_byte_range=0A= +ts_query_cursor_set_point_range=0A+ts_query_cursor_next_match=0A= +ts_query_cursor_remove_match=0A+ts_query_cursor_next_capture=0A= +ts_language_symbol_count=0A+ts_language_symbol_name=0A= +ts_language_symbol_for_name=0A+ts_language_field_count=0A= +ts_language_field_name_for_id=0A+ts_language_field_id_for_name=0A= +ts_language_symbol_type=0A+ts_language_version=0A+@end=20example=0Adiff=20= --git=20a/lisp/emacs-lisp/cl-preloaded.el=20= b/lisp/emacs-lisp/cl-preloaded.el=0Aindex=206aa45526d8..b4be54bbd6=20= 100644=0A---=20a/lisp/emacs-lisp/cl-preloaded.el=0A+++=20= b/lisp/emacs-lisp/cl-preloaded.el=0A@@=20-68,6=20+68,8=20@@=20= cl--typeof-types=0A=20=20=20=20=20(font-spec=20atom)=20(font-entity=20= atom)=20(font-object=20atom)=0A=20=20=20=20=20(vector=20array=20sequence=20= atom)=0A=20=20=20=20=20(user-ptr=20atom)=0A+=20=20=20=20= (tree-sitter-parser=20atom)=0A+=20=20=20=20(tree-sitter-node=20atom)=0A=20= =20=20=20=20;;=20Plus,=20really=20hand=20made:=0A=20=20=20=20=20(null=20= symbol=20list=20sequence=20atom))=0A=20=20=20"Alist=20of=20supertypes.=0A= diff=20--git=20a/lisp/tree-sitter.el=20b/lisp/tree-sitter.el=0Anew=20= file=20mode=20100644=0Aindex=200000000000..25886b393b=0A---=20/dev/null=0A= +++=20b/lisp/tree-sitter.el=0A@@=20-0,0=20+1,844=20@@=0A+;;;=20= tree-sitter.el=20---=20tree-sitter=20utilities=20-*-=20lexical-binding:=20= t=20-*-=0A+=0A+;;=20Copyright=20(C)=202021=20Free=20Software=20= Foundation,=20Inc.=0A+=0A+;;=20This=20file=20is=20part=20of=20GNU=20= Emacs.=0A+=0A+;;=20GNU=20Emacs=20is=20free=20software:=20you=20can=20= redistribute=20it=20and/or=20modify=0A+;;=20it=20under=20the=20terms=20= of=20the=20GNU=20General=20Public=20License=20as=20published=20by=0A+;;=20= the=20Free=20Software=20Foundation,=20either=20version=203=20of=20the=20= License,=20or=0A+;;=20(at=20your=20option)=20any=20later=20version.=0A+=0A= +;;=20GNU=20Emacs=20is=20distributed=20in=20the=20hope=20that=20it=20= will=20be=20useful,=0A+;;=20but=20WITHOUT=20ANY=20WARRANTY;=20without=20= even=20the=20implied=20warranty=20of=0A+;;=20MERCHANTABILITY=20or=20= FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20See=20the=0A+;;=20GNU=20= General=20Public=20License=20for=20more=20details.=0A+=0A+;;=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=0A+;;=20along=20with=20GNU=20Emacs.=20=20If=20not,=20see=20= .=0A+=0A+;;;=20Commentary:=0A+;;=0A+;;=20= Note=20to=20self:=20we=20don't=20create=20parsers=20automatically=20in=20= any=20provided=0A+;;=20functions.=0A+=0A+;;;=20Code:=0A+=0A= +(eval-when-compile=20(require=20'cl-lib))=0A+(require=20'cl-seq)=0A= +(require=20'font-lock)=0A+=0A+;;;=20Activating=20tree-sitter=0A+=0A= +(defgroup=20tree-sitter=0A+=20=20nil=0A+=20=20"Tree-sitter=20is=20an=20= incremental=20parser."=0A+=20=20:group=20'tools)=0A+=0A+(defcustom=20= tree-sitter-disabled-modes=20nil=0A+=20=20"A=20list=20of=20major-modes=20= for=20which=20tree-sitter=20support=20is=20disabled."=0A+=20=20:type=20= '(list=20symbol))=0A+=0A+(defcustom=20tree-sitter-maximum-size=20(*=204=20= 1024=201024)=0A+=20=20"Maximum=20buffer=20size=20for=20enabling=20= tree-sitter=20parsing."=0A+=20=20:type=20'integer)=0A+=0A+(defun=20= tree-sitter-available-p=20()=0A+=20=20"Return=20non-nil=20if=20= tree-sitter=20features=20are=20available."=0A+=20=20(fboundp=20= 'tree-sitter-parser-create))=0A+=0A+(defun=20tree-sitter-should-enable-p=20= (&optional=20mode)=0A+=20=20"Return=20non-nil=20if=20MODE=20should=20= activate=20tree-sitter=20support.=0A+MODE=20defaults=20to=20the=20value=20= of=20`major-mode'.=20=20The=20result=20depends=0A+on=20the=20value=20of=20= `tree-sitter-disabled-modes',=0A+`tree-sitter-maximum-size',=20and=20of=20= course,=20whether=20tree-sitter=20is=0A+available=20on=20the=20system=20= at=20all."=0A+=20=20(let*=20((mode=20(or=20mode=20major-mode))=0A+=20=20=20= =20=20=20=20=20=20(disabled=20(cl-loop=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20for=20disabled-mode=20in=20= tree-sitter-disabled-modes=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20if=20(provided-mode-derived-p=20mode=20disabled-mode)=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20return=20t=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20finally=20= return=20nil)))=0A+=20=20=20=20(and=20(tree-sitter-available-p)=0A+=20=20= =20=20=20=20=20=20=20(not=20disabled)=0A+=20=20=20=20=20=20=20=20=20(<=20= (buffer-size)=20tree-sitter-maximum-size))))=0A+=0A+;;;=20Parser=20API=20= supplement=0A+=0A+(defun=20tree-sitter-get-parser=20(language)=0A+=20=20= "Find=20the=20first=20parser=20using=20LANGUAGE=20in=20= `tree-sitter-parser-list'."=0A+=20=20(catch=20'found=0A+=20=20=20=20= (dolist=20(parser=20tree-sitter-parser-list)=0A+=20=20=20=20=20=20(when=20= (eq=20language=20(tree-sitter-parser-language=20parser))=0A+=20=20=20=20=20= =20=20=20(throw=20'found=20parser)))))=0A+=0A+(defun=20= tree-sitter-get-parser-create=20(language)=0A+=20=20"Find=20the=20first=20= parser=20using=20LANGUAGE=20in=20`tree-sitter-parser-list'.=0A+If=20none=20= exists,=20create=20one=20and=20return=20it."=0A+=20=20(or=20= (tree-sitter-get-parser=20language)=0A+=20=20=20=20=20=20= (tree-sitter-parser-create=0A+=20=20=20=20=20=20=20(current-buffer)=20= language)))=0A+=0A+(defun=20tree-sitter-parse-string=20(string=20= language)=0A+=20=20"Parse=20STRING=20using=20a=20parser=20for=20= LANGUAGE.=0A+Return=20the=20root=20node=20of=20the=20syntax=20tree."=0A+=20= =20(with-temp-buffer=0A+=20=20=20=20(insert=20string)=0A+=20=20=20=20= (tree-sitter-parser-root-node=0A+=20=20=20=20=20= (tree-sitter-parser-create=20(current-buffer)=20language))))=0A+=0A= +(defun=20tree-sitter-language-at=20(point)=0A+=20=20"Return=20the=20= language=20used=20at=20POINT."=0A+=20=20(cl-loop=20for=20parser=20in=20= tree-sitter-parser-list=0A+=20=20=20=20=20=20=20=20=20=20=20if=20= (tree-sitter-node-at=20point=20nil=20parser)=0A+=20=20=20=20=20=20=20=20=20= =20=20return=20(tree-sitter-parser-language=20parser)))=0A+=0A+(defun=20= tree-sitter-set-ranges=20(parser-or-lang=20ranges)=0A+=20=20"Set=20the=20= ranges=20of=20PARSER-OR-LANG=20to=20RANGES."=0A+=20=20= (tree-sitter-parser-set-included-ranges=0A+=20=20=20(cond=20((symbolp=20= parser-or-lang)=0A+=20=20=20=20=20=20=20=20=20=20(or=20= (tree-sitter-get-parser=20parser-or-lang)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(error=20"Cannot=20find=20a=20parser=20for=20%s"=20= parser-or-lang)))=0A+=20=20=20=20=20=20=20=20=20((tree-sitter-parser-p=20= parser-or-lang)=0A+=20=20=20=20=20=20=20=20=20=20parser-or-lang)=0A+=20=20= =20=20=20=20=20=20=20(t=20(error=20"Expecting=20a=20parser=20or=20= language,=20but=20got=20%s"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20parser-or-lang)))=0A+=20=20=20ranges))=0A+=0A+(defun=20= tree-sitter-get-ranges=20(parser-or-lang)=0A+=20=20"Get=20the=20ranges=20= of=20PARSER-OR-LANG."=0A+=20=20(tree-sitter-parser-included-ranges=0A+=20= =20=20(cond=20((symbolp=20parser-or-lang)=0A+=20=20=20=20=20=20=20=20=20=20= (or=20(tree-sitter-get-parser=20parser-or-lang)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(error=20"Cannot=20find=20a=20parser=20for=20%s"=20= parser-or-lang)))=0A+=20=20=20=20=20=20=20=20=20((tree-sitter-parser-p=20= parser-or-lang)=0A+=20=20=20=20=20=20=20=20=20=20parser-or-lang)=0A+=20=20= =20=20=20=20=20=20=20(t=20(error=20"Expecting=20a=20parser=20or=20= language,=20but=20got=20%s"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20parser-or-lang)))))=0A+=0A+;;;=20Node=20API=20supplement=0A= +=0A+(defun=20tree-sitter-node-buffer=20(node)=0A+=20=20"Return=20the=20= buffer=20in=20where=20NODE=20belongs."=0A+=20=20= (tree-sitter-parser-buffer=0A+=20=20=20(tree-sitter-node-parser=20= node)))=0A+=0A+(defun=20tree-sitter-node-language=20(node)=0A+=20=20= "Return=20the=20language=20symbol=20that=20NODE's=20parser=20uses."=0A+=20= =20(tree-sitter-parser-language=0A+=20=20=20(tree-sitter-node-parser=20= node)))=0A+=0A+(defun=20tree-sitter-node-at=20(beg=20&optional=20end=20= parser-or-lang=20named)=0A+=20=20"Return=20the=20smallest=20node=20= covering=20BEG=20to=20END.=0A+=0A+If=20omitted,=20END=20defaults=20to=20= BEG.=20=20Return=20nil=20if=20none=20find.=20=20If=0A+NAMED=20non-nil,=20= only=20look=20for=20named=20node.=20=20NAMED=20defaults=20to=20nil.=0A+=0A= +If=20PARSER-OR-LANG=20is=20nil,=20use=20the=20first=20parser=20in=0A= +`tree-sitter-parser-list';=20if=20PARSER-OR-LANG=20is=20a=20parser,=20= use=0A+that=20parser;=20if=20PARSER-OR-LANG=20is=20a=20language,=20find=20= a=20parser=20using=0A+that=20language=20in=20the=20current=20buffer,=20= and=20use=20that."=0A+=20=20(let=20((root=20(if=20(tree-sitter-parser-p=20= parser-or-lang)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-parser-root-node=20parser-or-lang)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(tree-sitter-buffer-root-node=20= parser-or-lang))))=0A+=20=20=20=20(tree-sitter-node-descendant-for-range=20= root=20beg=20(or=20end=20beg)=20named)))=0A+=0A+(defun=20= tree-sitter-buffer-root-node=20(&optional=20language)=0A+=20=20"Return=20= the=20root=20node=20of=20the=20current=20buffer.=0A+Use=20the=20first=20= parser=20in=20`tree-sitter-parser-list',=20if=20LANGUAGE=20is=0A= +non-nil,=20use=20the=20first=20parser=20for=20LANGUAGE."=0A+=20=20= (if-let=20((parser=0A+=20=20=20=20=20=20=20=20=20=20=20=20(or=20(if=20= language=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (or=20(tree-sitter-get-parser=20language)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(error=20"Cannot=20find=20a=20= parser=20for=20%s"=20language))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(or=20(car=20tree-sitter-parser-list)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(error=20"Buffer=20has=20= no=20parser"))))))=0A+=20=20=20=20=20=20(tree-sitter-parser-root-node=20= parser)))=0A+=0A+(defun=20tree-sitter-filter-child=20(node=20pred=20= &optional=20named)=0A+=20=20"Return=20children=20of=20NODE=20that=20= satisfies=20PRED.=0A+PRED=20is=20a=20function=20that=20takes=20one=20= argument,=20the=20child=20node.=20=20If=0A+NAMED=20non-nil,=20only=20= search=20for=20named=20node."=0A+=20=20(let=20((child=20= (tree-sitter-node-child=20node=200=20named))=0A+=20=20=20=20=20=20=20=20= result)=0A+=20=20=20=20(while=20child=0A+=20=20=20=20=20=20(when=20= (funcall=20pred=20child)=0A+=20=20=20=20=20=20=20=20(push=20child=20= result))=0A+=20=20=20=20=20=20(setq=20child=20= (tree-sitter-node-next-sibling=20child=20named)))=0A+=20=20=20=20= (reverse=20result)))=0A+=0A+(defun=20tree-sitter-node-text=20(node=20= &optional=20no-property)=0A+=20=20"Return=20the=20buffer=20(or=20string)=20= content=20corresponding=20to=20NODE.=0A+If=20NO-PROPERTY=20is=20non-nil,=20= remove=20text=20properties."=0A+=20=20(with-current-buffer=20= (tree-sitter-node-buffer=20node)=0A+=20=20=20=20(if=20no-property=0A+=20=20= =20=20=20=20=20=20(buffer-substring-no-properties=0A+=20=20=20=20=20=20=20= =20=20(tree-sitter-node-start=20node)=0A+=20=20=20=20=20=20=20=20=20= (tree-sitter-node-end=20node))=0A+=20=20=20=20=20=20(buffer-substring=0A= +=20=20=20=20=20=20=20(tree-sitter-node-start=20node)=0A+=20=20=20=20=20=20= =20(tree-sitter-node-end=20node)))))=0A+=0A+(defun=20= tree-sitter-parent-until=20(node=20pred)=0A+=20=20"Return=20the=20= closest=20parent=20of=20NODE=20that=20satisfies=20PRED.=0A+Return=20nil=20= if=20none=20found.=20=20PRED=20should=20be=20a=20function=20that=20takes=0A= +one=20argument,=20the=20parent=20node."=0A+=20=20(let=20((node=20= (tree-sitter-node-parent=20node)))=0A+=20=20=20=20(while=20(and=20node=20= (not=20(funcall=20pred=20node)))=0A+=20=20=20=20=20=20(setq=20node=20= (tree-sitter-node-parent=20node)))=0A+=20=20=20=20node))=0A+=0A+(defun=20= tree-sitter-parent-while=20(node=20pred)=0A+=20=20"Return=20the=20= furthest=20parent=20of=20NODE=20that=20satisfies=20PRED.=0A+Return=20nil=20= if=20none=20found.=20=20PRED=20should=20be=20a=20function=20that=20takes=0A= +one=20argument,=20the=20parent=20node."=0A+=20=20(let=20((last=20nil))=0A= +=20=20=20=20(while=20(and=20node=20(funcall=20pred=20node))=0A+=20=20=20= =20=20=20(setq=20last=20node=0A+=20=20=20=20=20=20=20=20=20=20=20=20node=20= (tree-sitter-node-parent=20node)))=0A+=20=20=20=20last))=0A+=0A+(defun=20= tree-sitter-node-children=20(node=20&optional=20named)=0A+=20=20"Return=20= a=20list=20of=20NODE's=20children.=0A+If=20NAMED=20is=20non-nil,=20= collect=20named=20child=20only."=0A+=20=20(mapcar=20(lambda=20(idx)=0A+=20= =20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-child=20node=20idx=20= named))=0A+=20=20=20=20=20=20=20=20=20=20(number-sequence=0A+=20=20=20=20= =20=20=20=20=20=20=200=20(1-=20(tree-sitter-node-child-count=20node=20= named)))))=0A+=0A+(defun=20tree-sitter-node-index=20(node=20&optional=20= named)=0A+=20=20"Return=20the=20index=20of=20NODE=20in=20its=20parent.=0A= +If=20NAMED=20is=20non-nil,=20count=20named=20child=20only."=0A+=20=20= (let=20((count=200))=0A+=20=20=20=20(while=20(setq=20node=20= (tree-sitter-node-prev-sibling=20node=20named))=0A+=20=20=20=20=20=20= (cl-incf=20count))=0A+=20=20=20=20count))=0A+=0A+(defun=20= tree-sitter-node-field-name=20(node)=0A+=20=20"Return=20the=20field=20= name=20of=20NODE=20as=20a=20child=20of=20its=20parent."=0A+=20=20= (when-let=20((parent=20(tree-sitter-node-parent=20node))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20(idx=20(tree-sitter-node-index=20node)))=0A+=20=20= =20=20(tree-sitter-node-field-name-for-child=20parent=20idx)))=0A+=0A= +;;;=20Query=20API=20supplement=0A+=0A+(defun=20tree-sitter-query-in=20= (source=20query=20&optional=20beg=20end)=0A+=20=20"Query=20the=20current=20= buffer=20with=20QUERY.=0A+=0A+SOURCE=20can=20be=20a=20language=20symbol,=20= a=20parser,=20or=20a=20node.=20=20If=20a=0A+language=20symbol,=20use=20= the=20root=20node=20of=20the=20first=20parser=20for=20that=0A+language;=20= if=20a=20parser,=20use=20the=20root=20node=20of=20that=20parser;=20if=20= a=0A+node,=20use=20that=20node.=0A+=0A+QUERY=20is=20either=20a=20string=20= query=20or=20a=20sexp=20query.=20=20See=20Info=20node=0A+`(elisp)Pattern=20= Matching'=20for=20how=20to=20write=20a=20query=20pattern=20in=20either=0A= +string=20or=20s-expression=20form.=0A+=0A+BEG=20and=20END,=20if=20= _both_=20non-nil,=20specifies=20the=20range=20in=20which=20the=20query=0A= +is=20executed.=0A+=0A+Raise=20an=20tree-sitter-query-error=20if=20QUERY=20= is=20malformed."=0A+=20=20(tree-sitter-query-capture=0A+=20=20=20(cond=20= ((symbolp=20source)=20(tree-sitter-buffer-root-node=20source))=0A+=20=20=20= =20=20=20=20=20=20((tree-sitter-parser-p=20source)=0A+=20=20=20=20=20=20=20= =20=20=20(tree-sitter-parser-root-node=20source))=0A+=20=20=20=20=20=20=20= =20=20((tree-sitter-node-p=20source)=20source))=0A+=20=20=20query=0A+=20=20= =20beg=20end))=0A+=0A+(defun=20tree-sitter-query-string=20(string=20= query=20language)=0A+=20=20"Query=20STRING=20with=20QUERY=20in=20= LANGUAGE.=0A+See=20`tree-sitter-query-capture'=20for=20QUERY."=0A+=20=20= (with-temp-buffer=0A+=20=20=20=20(insert=20string)=0A+=20=20=20=20(let=20= ((parser=20(tree-sitter-parser-create=20(current-buffer)=20language)))=0A= +=20=20=20=20=20=20(tree-sitter-query-capture=0A+=20=20=20=20=20=20=20= (tree-sitter-parser-root-node=20parser)=0A+=20=20=20=20=20=20=20= query))))=0A+=0A+(defun=20tree-sitter-query-range=20(source=20query=20= &optional=20beg=20end)=0A+=20=20"Query=20the=20current=20buffer=20and=20= return=20ranges=20of=20captured=20nodes.=0A+=0A+QUERY,=20SOURCE,=20BEG,=20= END=20are=20the=20same=20as=20in=0A+`tree-sitter-query-in'.=20=20This=20= function=20returns=20a=20list=0A+of=20(START=20.=20END),=20where=20START=20= and=20END=20specifics=20the=20range=20of=20each=0A+captured=20node.=20=20= Capture=20names=20don't=20matter."=0A+=20=20(cl-loop=20for=20capture=0A+=20= =20=20=20=20=20=20=20=20=20=20in=20(tree-sitter-query-in=20source=20= query=20beg=20end)=0A+=20=20=20=20=20=20=20=20=20=20=20for=20node=20=3D=20= (cdr=20capture)=0A+=20=20=20=20=20=20=20=20=20=20=20collect=20(cons=20= (tree-sitter-node-start=20node)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-end=20node))))=0A+=0A= +;;;=20Range=20API=20supplement=0A+=0A+(defvar-local=20= tree-sitter-range-functions=20nil=0A+=20=20"A=20list=20of=20range=20= functions.=0A+Font-locking=20and=20indenting=20code=20uses=20functions=20= in=20this=20alist=20to=0A+set=20correct=20ranges=20for=20a=20language=20= parser=20before=20using=20it.=0A+=0A+The=20signature=20of=20each=20= function=20should=20be=0A+=0A+=20=20=20=20(start=20end=20&rest=20_)=0A+=0A= +where=20START=20and=20END=20marks=20the=20region=20that=20is=20about=20= to=20be=20used.=20=20A=0A+range=20function=20only=20need=20to=20(but=20= not=20limited=20to)=20update=20ranges=20in=0A+that=20region.=0A+=0A+Each=20= function=20in=20the=20list=20is=20called=20in-order.")=0A+=0A+(defun=20= tree-sitter-update-ranges=20(&optional=20start=20end)=0A+=20=20"Update=20= the=20ranges=20for=20each=20language=20in=20the=20current=20buffer.=0A= +Calls=20each=20range=20functions=20in=20`tree-sitter-range-functions'=0A= +in-order.=20=20START=20and=20END=20are=20passed=20to=20each=20range=20= function."=0A+=20=20(dolist=20(range-fn=20tree-sitter-range-functions)=0A= +=20=20=20=20(funcall=20range-fn=20(or=20start=20(point-min))=20(or=20= end=20(point-max)))))=0A+=0A+;;;=20Font-lock=0A+=0A+(defvar-local=20= tree-sitter-font-lock-settings=20nil=0A+=20=20"A=20list=20of=20SETTINGs=20= for=20tree-sitter-based=20fontification.=0A+=0A+Each=20SETTING=20should=20= look=20like=0A+=0A+=20=20=20=20(LANGUAGE=20QUERY)=0A+=0A+Each=20SETTING=20= controls=20one=20parser=20(often=20of=20different=20language).=0A= +LANGUAGE=20is=20the=20language=20symbol.=20=20See=20Info=20node=20= `(elisp)Language=0A+Definitions'.=0A+=0A+QUERY=20is=20either=20a=20= string=20query=20or=20a=20sexp=20query.=0A+See=20Info=20node=20= `(elisp)Pattern=20Matching'=20for=20writing=20queries.=0A+=0A+Capture=20= names=20in=20QUERY=20should=20be=20face=20names=20like=0A= +`font-lock-keyword-face'.=20=20The=20captured=20node=20will=20be=20= fontified=0A+with=20that=20face.=20=20Capture=20names=20can=20also=20be=20= function=20names,=20in=0A+which=20case=20the=20function=20is=20called=20= with=20(START=20END=20NODE),=20where=0A+START=20and=20END=20are=20the=20= start=20and=20end=20position=20of=20the=20node=20in=0A+buffer,=20and=20= NODE=20is=20the=20tree-sitter=20node=20object.=20=20If=20a=20capture=0A= +name=20is=20both=20a=20face=20and=20a=20function,=20face=20takes=20= priority.=0A+=0A+Generally,=20major=20modes=20should=20set=0A= +`tree-sitter-font-lock-defaults',=20and=20let=20Emacs=20automatically=0A= +populate=20this=20variable.")=0A+=0A+(defvar-local=20= tree-sitter-font-lock-defaults=20nil=0A+=20=20"Defaults=20for=20= tree-sitter=20Font=20Lock=20specified=20by=20the=20major=20mode.=0A+=0A= +This=20variable=20should=20be=20a=20list=20of=0A+=0A+=20=20=20=20= (DEFAULT=20:KEYWORD=20VALUE...)=0A+=0A+A=20DEFAULT=20may=20be=20a=20= symbol=20or=20a=20list=20of=20symbols=20(specifying=0A+different=20= levels=20of=20fontification).=20=20The=20symbol(s)=20can=20be=20of=20a=0A= +variable=20or=20a=20function.=20=20If=20a=20symbol=20is=20both=20a=20= variable=20and=20a=0A+function,=20it=20is=20used=20as=20a=20function.=20=20= Different=20levels=20of=0A+fontification=20can=20be=20controlled=20by=0A= +`font-lock-maximum-decoration'.=0A+=0A+The=20symbol(s)=20in=20DEFAULT=20= should=20contain=20or=20return=20a=20SETTING=20as=0A+explained=20in=20= `tree-sitter-font-lock-settings',=20which=20looks=20like=0A+=0A+=20=20=20= =20(LANGUAGE=20QUERY)=0A+=0A+KEYWORD=20and=20VALUE=20are=20additional=20= settings=20could=20be=20used=20to=20alter=0A+fontification=20behavior.=20= =20Currently=20there=20aren't=20any.=0A+=0A+Multi-language=20major-modes=20= should=20provide=20a=20range=20function=20for=0A+eacn=20language=20it=20= supports=20in=20`tree-sitter-range-functions',=20and=0A+Emacs=20will=20= set=20the=20ranges=20accordingly=20before=20fontifing=20a=20region.=0A= +See=20Info=20node=20`(elisp)Multiple=20Languages'=20for=20what=20does=20= it=20mean=0A+to=20set=20ranges=20for=20a=20parser.")=0A+=0A+(defun=20= tree-sitter-font-lock-fontify-region=20(start=20end=20&optional=20= loudly)=0A+=20=20"Fontify=20the=20region=20between=20START=20and=20END.=0A= +If=20LOUDLY=20is=20non-nil,=20message=20some=20debugging=20= information."=0A+=20=20(tree-sitter-update-ranges=20start=20end)=0A+=20=20= (font-lock-unfontify-region=20start=20end)=0A+=20=20(dolist=20(setting=20= tree-sitter-font-lock-settings)=0A+=20=20=20=20(when-let*=20((language=20= (nth=200=20setting))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (match-pattern=20(nth=201=20setting))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(parser=20(tree-sitter-get-parser-create=20language)))=0A= +=20=20=20=20=20=20(when-let=20((node=20(tree-sitter-node-at=20start=20= end=20parser)))=0A+=20=20=20=20=20=20=20=20(let=20((captures=20= (tree-sitter-query-capture=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20node=20match-pattern=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20Specifying=20= the=20range=20is=20important.=20More=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20often=20than=20not,=20= NODE=20will=20be=20the=20root=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20;;=20node,=20and=20if=20we=20don't=20= specify=20the=20range,=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20;;=20we=20are=20basically=20querying=20the=20= whole=20file.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20start=20end)))=0A+=20=20=20=20=20=20=20=20=20=20= (with-silent-modifications=0A+=20=20=20=20=20=20=20=20=20=20=20=20= (dolist=20(capture=20captures)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(let*=20((face=20(car=20capture))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(node=20(cdr=20capture))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(start=20= (tree-sitter-node-start=20node))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(end=20(tree-sitter-node-end=20node)))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(cond=20((facep=20face)=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (put-text-property=20start=20end=20'face=20face))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((functionp=20face)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(funcall=20= face=20start=20end=20node))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(t=20(error=20"Capture=20name=20%s=20is=20= neither=20a=20face=20nor=20a=20function"=20face)))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(when=20loudly=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(message=20"Fontifying=20text=20from=20%d=20to=20= %d,=20Face:=20%s=20Language:=20%s"=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20start=20end=20face=20= language)))))))))=0A+=20=20;;=20Call=20regexp=20font-lock=20after=20= tree-sitter,=20as=20it=20is=20usually=20used=0A+=20=20;;=20for=20custom=20= fontification.=0A+=20=20(let=20((font-lock-unfontify-region-function=20= #'ignore))=0A+=20=20=20=20(funcall=20#'font-lock-default-fontify-region=20= start=20end=20loudly)))=0A+=0A+(defun=20tree-sitter-font-lock-enable=20= ()=0A+=20=20"Enable=20tree-sitter=20font-locking=20for=20the=20current=20= buffer."=0A+=20=20(let=20((default=20(car=20= tree-sitter-font-lock-defaults))=0A+=20=20=20=20=20=20=20=20(attributes=20= (cdr=20tree-sitter-font-lock-defaults)))=0A+=20=20=20=20(ignore=20= attributes)=0A+=20=20=20=20(setq-local=20tree-sitter-font-lock-settings=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (font-lock-eval-keywords=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(font-lock-choose-keywords=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20default=0A+=09=20=20=20=20=20=20=20=20=20=20= (font-lock-value-in-major-mode=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20font-lock-maximum-decoration)))))=0A+=20=20(setq-local=20= font-lock-fontify-region-function=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20#'tree-sitter-font-lock-fontify-region)=0A+=20=20;;=20If=20we=20= don't=20set=20`font-lock-defaults'=20to=20some=20non-nil=20value,=0A+=20=20= ;;=20font-lock=20doesn't=20enable=20properly=20(the=20= font-lock-mode-internal=0A+=20=20;;=20doesn't=20run).=20=20See=20= `font-lock-add-keywords'.=0A+=20=20(when=20(and=20font-lock-mode=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20(null=20font-lock-keywords)=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20(null=20font-lock-defaults))=0A+=20=20=20=20= (font-lock-mode=20-1)=0A+=20=20=20=20(setq-local=20font-lock-defaults=20= '(nil=20t))=0A+=20=20=20=20(font-lock-mode=201)))=0A+=0A+;;;=20Indent=0A= +=0A+(defvar=20tree-sitter--indent-verbose=20nil=0A+=20=20"If=20non-nil,=20= log=20progress=20when=20indenting.")=0A+=0A+;;=20This=20is=20not=20bound=20= locally=20like=20we=20normally=20do=20with=20major-mode=0A+;;=20stuff,=20= because=20for=20tree-sitter,=20a=20buffer=20could=20contain=20more=20= than=0A+;;=20one=20language.=0A+(defvar=20= tree-sitter-simple-indent-rules=20nil=0A+=20=20"A=20list=20of=20indent=20= rule=20settings.=0A+Each=20indent=20rule=20setting=20should=20be=20= (LANGUAGE=20.=20RULES),=0A+where=20LANGUAGE=20is=20a=20language=20= symbol,=20and=20RULES=20is=20a=20list=20of=0A+=0A+=20=20=20=20(MATCHER=20= ANCHOR=20OFFSET).=0A+=0A+MATCHER=20determines=20whether=20this=20rule=20= applies,=20ANCHOR=20and=20OFFSET=0A+together=20determines=20which=20= column=20to=20indent=20to.=0A+=0A+A=20MATCHER=20is=20a=20function=20that=20= takes=20three=20arguments=20(NODE=20PARENT=0A+BOL).=20=20BOL=20is=20the=20= point=20where=20we=20are=20indenting:=20the=20beginning=20of=0A+line=20= content,=20the=20position=20of=20the=20first=20non-whitespace=20= character.=0A+NODE=20is=20the=20largest=20(highest-in-tree)=20node=20= starting=20at=20that=0A+point.=20=20PARENT=20is=20the=20parent=20of=20= NODE.=0A+=0A+If=20MATCHER=20returns=20non-nil,=20meaning=20the=20rule=20= matches,=20Emacs=20then=0A+uses=20ANCHOR=20to=20find=20an=20anchor,=20it=20= should=20be=20a=20function=20that=20takes=0A+the=20same=20argument=20= (NODE=20PARENT=20BOL)=20and=20returns=20a=20point.=0A+=0A+Finally=20= Emacs=20computes=20the=20column=20of=20that=20point=20returned=20by=20= ANCHOR=0A+and=20adds=20OFFSET=20to=20it,=20and=20indents=20to=20that=20= column.=0A+=0A+For=20MATCHER=20and=20ANCHOR,=20Emacs=20provides=20some=20= convenient=20presets.=0A+See=20`tree-sitter-simple-indent-presets'.")=0A= +=0A+(defvar=20tree-sitter-simple-indent-presets=0A+=20=20'((match=20.=20= (lambda=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(&optional=20= node-type=20parent-type=20node-field=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20node-index-min=20= node-index-max)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20`(lambda=20= (node=20parent=20bol=20&rest=20_)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(and=20(or=20(null=20,node-type)=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(equal=20= (tree-sitter-node-type=20node)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ,node-type))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(or=20(null=20,parent-type)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(equal=20= (tree-sitter-node-type=20parent)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ,parent-type))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(or=20(null=20,node-field)=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(equal=20= (tree-sitter-node-field-name=20node)=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ,node-field))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(or=20(null=20,node-index-min)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(>=3D=20= (tree-sitter-node-index=20node=20t)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ,node-index-min))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(or=20(null=20,node-index-max)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(<=3D=20= (tree-sitter-node-index=20node=20t)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ,node-index-max))))))=0A+=20=20=20=20(no-node=20.=20(lambda=20(node=20= parent=20bol=20&rest=20_)=20(null=20node)))=0A+=20=20=20=20(parent-is=20= .=20(lambda=20(type)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20`(lambda=20(node=20parent=20bol=20&rest=20_)=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(equal=20,type=20= (tree-sitter-node-type=20parent)))))=0A+=0A+=20=20=20=20(node-is=20.=20= (lambda=20(type)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= `(lambda=20(node=20parent=20bol=20&rest=20_)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(equal=20,type=20(tree-sitter-node-type=20= node)))))=0A+=0A+=20=20=20=20(query=20.=20(lambda=20(pattern)=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20`(lambda=20(node=20parent=20bol=20= &rest=20_)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (cl-loop=20for=20capture=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20in=20(tree-sitter-query-capture=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20parent=20,pattern)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20if=20(tree-sitter-node-eq=20= node=20(cdr=20capture))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20return=20t=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20finally=20return=20= nil))))=0A+=20=20=20=20(first-sibling=20.=20(lambda=20(node=20parent=20= bol=20&rest=20_)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(tree-sitter-node-start=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-child=20parent=20= 0=20t))))=0A+=0A+=20=20=20=20(parent=20.=20(lambda=20(node=20parent=20= bol=20&rest=20_)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-start=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(tree-sitter-node-parent=20node))))=0A+=20=20=20=20(prev-sibling=20.=20= (lambda=20(node=20parent=20bol=20&rest=20_)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-start=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-prev-sibling=20node))))=0A+=20=20=20=20(no-indent=20.=20= (lambda=20(node=20parent=20bol=20&rest=20_)=20bol))=0A+=20=20=20=20= (prev-line=20.=20(lambda=20(node=20parent=20bol=20&rest=20_)=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(save-excursion=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(goto-char=20= bol)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (forward-line=20-1)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(skip-chars-forward=20"=20\t")=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-start=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-at=20(point)=20nil=20nil=20t))))))=0A+=20=20"A=20list=20= of=20presets.=0A+These=20presets=20that=20can=20be=20used=20as=20MATHER=20= and=20ANCHOR=20in=0A+`tree-sitter-simple-indent-rules'.=0A+=0A+MATCHER:=0A= +=0A+\(match=20NODE-TYPE=20PARENT-TYPE=20NODE-FIELD=20NODE-INDEX-MIN=20= NODE-INDEX-MAX)=0A+=0A+=20=20=20=20NODE-TYPE=20checks=20for=20node's=20= type,=20PARENT-TYPE=20checks=20for=0A+=20=20=20=20parent's=20type,=20= NODE-FIELD=20checks=20for=20the=20filed=20name=20of=20node=0A+=20=20=20=20= in=20the=20parent,=20NODE-INDEX-MIN=20and=20NODE-INDEX-MAX=20checks=20= for=0A+=20=20=20=20the=20node's=20index=20in=20the=20parent.=20=20= Therefore,=20to=20match=20the=0A+=20=20=20=20first=20child=20where=20= parent=20is=20\"argument_list\",=20use=0A+=0A+=20=20=20=20=20=20=20=20= (match=20nil=20\"argument_list\"=20nil=20nil=200=200).=0A+=0A+no-node=0A= +=0A+=20=20=20=20Matches=20the=20case=20where=20node=20is=20nil,=20i.e.,=20= there=20is=20no=20node=0A+=20=20=20=20that=20starts=20at=20point.=20=20= This=20is=20the=20case=20when=20indenting=20an=0A+=20=20=20=20empty=20= line.=0A+=0A+\(parent-is=20TYPE)=0A+=0A+=20=20=20=20Check=20that=20the=20= parent=20has=20type=20TYPE.=0A+=0A+\(node-is=20TYPE)=0A+=0A+=20=20=20=20= Checks=20that=20the=20node=20has=20type=20TYPE.=0A+=0A+\(query=20QUERY)=0A= +=0A+=20=20=20=20Queries=20the=20parent=20node=20with=20QUERY,=20and=20= checks=20if=20the=20node=0A+=20=20=20=20is=20captured=20(by=20any=20= capture=20name).=0A+=0A+ANCHOR:=0A+=0A+first-sibling=0A+=0A+=20=20=20=20= Find=20the=20first=20child=20of=20the=20parent.=0A+=0A+parent=0A+=0A+=20=20= =20=20Find=20the=20parent.=0A+=0A+prev-sibling=0A+=0A+=20=20=20=20Find=20= node's=20previous=20sibling.=0A+=0A+no-indent=0A+=0A+=20=20=20=20Do=20= nothing.=0A+=0A+prev-line=0A+=0A+=20=20=20=20Find=20the=20named=20node=20= on=20the=20previous=20line.=20=20This=20can=20be=20used=20when=0A+=20=20=20= =20indenting=20an=20empty=20line:=20just=20indent=20like=20the=20= previous=20node.")=0A+=0A+(defun=20tree-sitter--simple-apply=20(fn=20= args)=0A+=20=20"Apply=20ARGS=20to=20FN.=0A+=0A+If=20FN=20is=20a=20key=20= in=20`tree-sitter-simple-indent-presets',=20use=20the=0A+corresponding=20= value=20as=20the=20function."=0A+=20=20;;=20We=20don't=20want=20to=20= match=20uncompiled=20lambdas,=20so=20make=20sure=20this=20cons=0A+=20=20= ;;=20is=20not=20a=20function.=20=20We=20could=20move=20the=20condition=20= functionp=0A+=20=20;;=20forward,=20but=20better=20be=20explicit.=0A+=20=20= (cond=20((and=20(consp=20fn)=20(not=20(functionp=20fn)))=0A+=20=20=20=20=20= =20=20=20=20(apply=20(tree-sitter--simple-apply=20(car=20fn)=20(cdr=20= fn))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20We=20don't=20= evaluate=20ARGS=20with=20`simple-apply',=20i.e.,=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20;;=20no=20composing,=20better=20keep=20it=20= simple.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20args))=0A+=20=20= =20=20=20=20=20=20((and=20(symbolp=20fn)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(alist-get=20fn=20tree-sitter-simple-indent-presets))=0A+=20=20= =20=20=20=20=20=20=20(apply=20(alist-get=20fn=20= tree-sitter-simple-indent-presets)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20args))=0A+=20=20=20=20=20=20=20=20((functionp=20fn)=20(apply=20= fn=20args))=0A+=20=20=20=20=20=20=20=20(t=20(error=20"Couldn't=20find=20= the=20function=20corresponding=20to=20%s"=20fn))))=0A+=0A+;;=20This=20= variable=20might=20seem=20unnecessary:=20why=20split=0A+;;=20= `tree-sitter-indent'=20and=20`tree-sitter-simple-indent'=20into=20two=0A= +;;=20functions?=20=20We=20add=20this=20variable=20in=20between=20= because=20later=20we=20might=0A+;;=20add=20more=20powerful=20indentation=20= engines,=20and=20that=20new=20engine=20can=0A+;;=20probably=20share=20= `tree-sitter-indent'.=20=20It=20is=20also=20useful,=20suggested=0A+;;=20= by=20Stefan=20M,=20to=20have=20a=20function=20that=20figures=20out=20how=20= much=20to=20indent=0A+;;=20but=20doesn't=20actually=20performs=20the=20= indentation,=20because=20we=20might=0A+;;=20want=20to=20know=20where=20= will=20a=20node=20indent=20to=20if=20we=20put=20it=20at=20some=20other=0A= +;;=20location,=20and=20use=20that=20information=20to=20calculate=20the=20= actual=0A+;;=20indentation.=20=20And=20`tree-sitter-simple-indent'=20is=20= that=20function.=20=20I=0A+;;=20forgot=20the=20example=20Stefan=20gave,=20= but=20it=20makes=20a=20lot=20of=20sense.=0A+(defvar=20= tree-sitter-indent-function=20#'tree-sitter-simple-indent=0A+=20=20= "Function=20used=20by=20`tree-sitter-indent'=20to=20do=20some=20of=20the=20= work.=0A+=0A+This=20function=20is=20called=20with=0A+=0A+=20=20=20=20= (NODE=20PARENT=20BOL=20&rest=20_)=0A+=0A+and=20returns=0A+=0A+=20=20=20=20= (ANCHOR=20.=20OFFSET).=0A+=0A+BOL=20is=20the=20position=20of=20the=20= beginning=20of=20the=20line;=20NODE=20is=20the=0A+\"largest\"=20node=20= that=20starts=20at=20BOL;=20PARENT=20is=20its=20parent;=20ANCHOR=0A+is=20= a=20point=20(not=20a=20node),=20and=20OFFSET=20is=20a=20number.=20=20= Emacs=20finds=20the=0A+column=20of=20ANCHOR=20and=20adds=20OFFSET=20to=20= it=20as=20the=20final=20indentation=0A+of=20the=20current=20line.")=0A+=0A= +(defun=20tree-sitter-indent=20()=0A+=20=20"Indent=20according=20to=20= the=20result=20of=20`tree-sitter-indent-function'."=0A+=20=20= (tree-sitter-update-ranges)=0A+=20=20(let*=20((orig-pos=20(point))=0A+=20= =20=20=20=20=20=20=20=20(bol=20(save-excursion=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(forward-line=200)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(skip-chars-forward=20"=20\t")=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(point)))=0A+=20=20=20=20=20=20=20=20=20= (smallest-node=0A+=20=20=20=20=20=20=20=20=20=20(cl-loop=20for=20parser=20= in=20tree-sitter-parser-list=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20for=20node=20=3D=20(tree-sitter-node-at=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20bol=20nil=20parser)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20if=20node=20return=20node))=0A+=20=20=20=20=20=20=20=20=20(node=20= (tree-sitter-parent-while=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20smallest-node=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (lambda=20(node)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(eq=20bol=20(tree-sitter-node-start=20node))))))=0A+=20=20=20=20= (pcase-let*=0A+=20=20=20=20=20=20=20=20((parser=20(if=20smallest-node=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-parser=20smallest-node)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20nil))=0A+=20=20=20=20=20=20=20=20=20;;=20NODE=20= would=20be=20nil=20if=20BOL=20is=20on=20a=20whitespace.=20=20In=20that=20= case=0A+=20=20=20=20=20=20=20=20=20;;=20we=20set=20PARENT=20to=20the=20= "node=20at=20point",=20which=20would=0A+=20=20=20=20=20=20=20=20=20;;=20= encompass=20the=20whitespace.=0A+=20=20=20=20=20=20=20=20=20(parent=20= (cond=20((and=20node=20parser)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-parent=20node))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (parser=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(tree-sitter-node-at=20bol=20nil=20parser))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(t=20nil)))=0A+=20=20=20= =20=20=20=20=20=20(`(,anchor=20.=20,offset)=0A+=20=20=20=20=20=20=20=20=20= =20(funcall=20tree-sitter-indent-function=20node=20parent=20bol)))=0A+=20= =20=20=20=20=20(if=20(null=20anchor)=0A+=20=20=20=20=20=20=20=20=20=20= (when=20tree-sitter--indent-verbose=0A+=20=20=20=20=20=20=20=20=20=20=20=20= (message=20"Failed=20to=20find=20the=20anchor"))=0A+=20=20=20=20=20=20=20= =20(let=20((col=20(+=20(save-excursion=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(goto-char=20anchor)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (current-column))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20offset)))=0A+=20=20=20=20=20=20=20=20=20=20(if=20(<=20bol=20= orig-pos)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20(save-excursion=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(indent-line-to=20col))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20(indent-line-to=20col)))))))=0A+=0A= +(defun=20tree-sitter-simple-indent=20(node=20parent=20bol)=0A+=20=20= "Calculate=20indentation=20according=20to=20= `tree-sitter-simple-indent-rules'.=0A+=0A+BOL=20is=20the=20position=20of=20= the=20first=20non-whitespace=20character=20on=20the=0A+current=20line.=20= =20NODE=20is=20the=20largest=20node=20that=20starts=20at=20BOL,=0A= +PARENT=20is=20NODE's=20parent.=0A+=0A+Return=20(ANCHOR=20.=20OFFSET)=20= where=20ANCHOR=20is=20a=20node,=20OFFSET=20is=20the=0A+indentation=20= offset,=20meaning=20indent=20to=20align=20with=20ANCHOR=20and=20add=0A= +OFFSET."=0A+=20=20(if=20(null=20parent)=0A+=20=20=20=20=20=20(when=20= tree-sitter--indent-verbose=0A+=20=20=20=20=20=20=20=20(message=20= "PARENT=20is=20nil,=20not=20indenting"))=0A+=20=20=20=20(let*=20= ((language=20(tree-sitter-node-language=20parent))=0A+=20=20=20=20=20=20=20= =20=20=20=20(rules=20(alist-get=20language=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= tree-sitter-simple-indent-rules)))=0A+=20=20=20=20=20=20(cl-loop=20for=20= rule=20in=20rules=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20for=20= pred=20=3D=20(nth=200=20rule)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20for=20anchor=20=3D=20(nth=201=20rule)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20for=20offset=20=3D=20(nth=202=20rule)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20if=20(tree-sitter--simple-apply=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20pred=20(list=20node=20= parent=20bol))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20do=20= (when=20tree-sitter--indent-verbose=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(message=20"Matched=20rule:=20%S"=20rule))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20and=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20return=20(cons=20(tree-sitter--simple-apply=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20anchor=20(list=20node=20parent=20bol))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20offset)))))=0A+=0A= +(defun=20tree-sitter-check-indent=20(mode)=0A+=20=20"Check=20current=20= buffer's=20indentation=20against=20a=20major=20mode=20MODE.=0A+=0A+Pop=20= up=20a=20diff=20buffer=20showing=20the=20difference.=20=20Correct=0A= +indentation=20(target)=20is=20in=20green,=20current=20indentation=20is=20= in=20red."=0A+=20=20(interactive=20"CTarget=20major=20mode:=20")=0A+=20=20= (let=20((source-buf=20(current-buffer)))=0A+=20=20=20=20= (with-temp-buffer=0A+=20=20=20=20=20=20(insert-buffer-substring=20= source-buf)=0A+=20=20=20=20=20=20(funcall=20mode)=0A+=20=20=20=20=20=20= (indent-region=20(point-min)=20(point-max))=0A+=20=20=20=20=20=20= (diff-buffers=20source-buf=20(current-buffer)))))=0A+=0A+;;;=20Debugging=0A= +=0A+(defvar-local=20tree-sitter--inspect-name=20nil=0A+=20=20= "Tree-sitter-inspect-mode=20uses=20this=20to=20show=20node=20name=20in=20= mode-line.")=0A+=0A+(defun=20tree-sitter-inspect-node-at-point=20= (&optional=20arg)=0A+=20=20"Show=20information=20of=20the=20node=20at=20= point.=0A+If=20called=20interactively,=20show=20in=20echo=20area,=20= otherwise=20set=0A+`tree-sitter--inspect-name'=20(which=20will=20appear=20= in=20the=20mode-line=0A+if=20`tree-sitter-inspect-mode'=20is=20enabled).=20= =20Uses=20the=20first=20parser=0A+in=20`tree-sitter-parser-list'."=0A+=20= =20(interactive=20"p")=0A+=20=20;;=20NODE-LIST=20contains=20all=20the=20= node=20that=20starts=20at=20point.=0A+=20=20(let*=20((node-list=0A+=20=20= =20=20=20=20=20=20=20=20(cl-loop=20for=20node=20=3D=20= (tree-sitter-node-at=20(point))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20then=20(tree-sitter-node-parent=20node)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20while=20node=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20if=20(eq=20= (tree-sitter-node-start=20node)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(point))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20collect=20node))=0A+=20=20=20=20=20=20=20= =20=20(largest-node=20(car=20(last=20node-list)))=0A+=20=20=20=20=20=20=20= =20=20(parent=20(tree-sitter-node-parent=20largest-node))=0A+=20=20=20=20= =20=20=20=20=20;;=20node-list-acending=20contains=20all=20the=20node=20= bottom-up,=20then=0A+=20=20=20=20=20=20=20=20=20;;=20the=20parent.=0A+=20= =20=20=20=20=20=20=20=20(node-list-acending=0A+=20=20=20=20=20=20=20=20=20= =20(if=20(null=20largest-node)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20;;=20If=20there=20are=20no=20nodes=20that=20start=20at=20point,=20= just=20show=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20;;=20the=20node=20= at=20point=20and=20its=20parent.=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(list=20(tree-sitter-node-at=20(point))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-parent=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-at=20= (point))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20(append=20node-list=20= (list=20parent))))=0A+=20=20=20=20=20=20=20=20=20(name=20""))=0A+=20=20=20= =20;;=20We=20draw=20nodes=20like=20(parent=20field-name:=20(node))=20= recursively,=0A+=20=20=20=20;;=20so=20it=20could=20be=20(node1=20= field-name:=20(node2=20field-name:=20(node3))).=0A+=20=20=20=20(dolist=20= (node=20node-list-acending)=0A+=20=20=20=20=20=20(setq=0A+=20=20=20=20=20= =20=20name=0A+=20=20=20=20=20=20=20(concat=0A+=20=20=20=20=20=20=20=20= (if=20(tree-sitter-node-field-name=20node)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20(format=20"=20%s:=20"=20(tree-sitter-node-field-name=20node))=0A= +=20=20=20=20=20=20=20=20=20=20"=20")=0A+=20=20=20=20=20=20=20=20(if=20= (tree-sitter-node-check=20node=20'named)=20"("=20"\"")=0A+=20=20=20=20=20= =20=20=20(or=20(tree-sitter-node-type=20node)=0A+=20=20=20=20=20=20=20=20= =20=20=20=20"N/A")=0A+=20=20=20=20=20=20=20=20name=0A+=20=20=20=20=20=20=20= =20(if=20(tree-sitter-node-check=20node=20'named)=20")"=20"\""))))=0A+=20= =20=20=20(setq=20tree-sitter--inspect-name=20name)=0A+=20=20=20=20= (force-mode-line-update)=0A+=20=20=20=20(when=20arg=0A+=20=20=20=20=20=20= (if=20node-list=0A+=20=20=20=20=20=20=20=20=20=20(message=20"%s"=20= tree-sitter--inspect-name)=0A+=20=20=20=20=20=20=20=20(message=20"No=20= node=20at=20point")))))=0A+=0A+(define-minor-mode=20= tree-sitter-inspect-mode=0A+=20=20"Shows=20the=20node=20that=20_starts_=20= at=20point=20in=20the=20mode-line.=0A+=0A+The=20mode-line=20displays=0A+=0A= +=20=20=20=20PARENT=20FIELD-NAME:=20(CHILD=20(GRAND-CHILD=20(...)))=0A+=0A= +CHILD,=20GRAND-CHILD,=20and=20GRAND-GRAND-CHILD,=20etc,=20are=20nodes=20= that=0A+have=20their=20beginning=20at=20point.=20=20And=20PARENT=20is=20= the=20parent=20of=0A+CHILD.=0A+=0A+If=20no=20node=20starts=20at=20point,=20= i.e.,=20point=20is=20in=20the=20middle=20of=20a=0A+node,=20then=20we=20= just=20display=20the=20smallest=20node=20that=20spans=20point=20and=0A= +its=20immediate=20parent.=0A+=0A+This=20minor=20mode=20doesn't=20create=20= parsers=20on=20its=20own.=20=20It=20simply=0A+uses=20the=20first=20= parser=20in=20`tree-sitter-parser-list'."=0A+=20=20:lighter=20nil=0A+=20=20= (if=20tree-sitter-inspect-mode=0A+=20=20=20=20=20=20(progn=0A+=20=20=20=20= =20=20=20=20(add-hook=20'post-command-hook=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20#'tree-sitter-inspect-node-at-point=200=20t)=0A= +=20=20=20=20=20=20=20=20(add-to-list=20'mode-line-misc-info=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'(:eval=20= tree-sitter--inspect-name)))=0A+=20=20=20=20(remove-hook=20= 'post-command-hook=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= #'tree-sitter-inspect-node-at-point=20t)=0A+=20=20=20=20(setq=20= mode-line-misc-info=0A+=20=20=20=20=20=20=20=20=20=20(remove=20'(:eval=20= tree-sitter--inspect-name)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20mode-line-misc-info))))=0A+=0A+(defun=20tree-sitter-check-query=20= (query=20language)=0A+=20=20"Check=20if=20QUERY=20is=20valid=20for=20= LANGUAGE.=0A+If=20QUERY=20is=20invalid,=20display=20the=20query=20in=20a=20= popup=20buffer,=20jumps=0A+to=20the=20offending=20pattern=20and=20= highlight=20the=20pattern."=0A+=20=20(let=20((buf=20(get-buffer-create=20= "*tree-sitter=20check=20query*")))=0A+=20=20=20=20(with-temp-buffer=0A+=20= =20=20=20=20=20(tree-sitter-get-parser-create=20language)=0A+=20=20=20=20= =20=20(condition-case=20err=0A+=20=20=20=20=20=20=20=20=20=20(progn=20= (tree-sitter-query-in=20language=20query)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(message=20"QUERY=20is=20valid"))=0A+=20=20=20=20=20= =20=20=20(tree-sitter-query-error=0A+=20=20=20=20=20=20=20=20=20= (with-current-buffer=20buf=0A+=20=20=20=20=20=20=20=20=20=20=20(let*=20= ((data=20(cdr=20err))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(message=20(nth=200=20data))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(start=20(nth=201=20data)))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20(erase-buffer)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= (insert=20query)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(goto-char=20= start)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(search-forward=20"=20"=20= nil=20t)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(put-text-property=20= start=20(point)=20'face=20'error)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20(message=20"%s"=20(buffer-substring=20start=20(point)))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20(goto-char=20(point-min))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20(insert=20(format=20"%s:=20%d\n"=20message=20= start))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20(forward-char=20= start)))=0A+=20=20=20=20=20=20=20=20=20(pop-to-buffer=20buf))))))=0A+=0A= +;;;=20Etc=0A+=0A+(declare-function=20find-library-name=20= "find-func.el")=0A+(defun=20tree-sitter--check-manual-covarage=20()=0A+=20= =20"Print=20tree-sitter=20functions=20missing=20from=20the=20manual=20in=20= message=20buffer."=0A+=20=20(interactive)=0A+=20=20(require=20= 'find-func)=0A+=20=20(let=20((functions-in-source=0A+=20=20=20=20=20=20=20= =20=20(with-temp-buffer=0A+=20=20=20=20=20=20=20=20=20=20=20= (insert-file-contents=20(find-library-name=20"tree-sitter"))=0A+=20=20=20= =20=20=20=20=20=20=20=20(cl-remove-if=0A+=20=20=20=20=20=20=20=20=20=20=20= =20(lambda=20(name)=20(string-match=20"tree-sitter--"=20name))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20(cl-sort=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20(save-excursion=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (goto-char=20(point-min))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (cl-loop=20while=20(re-search-forward=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"^(defun=20= \\([^=20]+\\)"=20nil=20t)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20collect=20(match-string-no-properties=201)))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20#'string<))))=0A+=20=20=20=20=20=20= =20=20(functions-in-manual=0A+=20=20=20=20=20=20=20=20=20= (with-temp-buffer=0A+=20=20=20=20=20=20=20=20=20=20=20= (insert-file-contents=20(expand-file-name=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "doc/lispref/parsing.texi"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= source-directory))=0A+=20=20=20=20=20=20=20=20=20=20=20= (insert-file-contents=20(expand-file-name=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "doc/lispref/modes.texi"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= source-directory))=0A+=20=20=20=20=20=20=20=20=20=20=20(cl-sort=0A+=20=20= =20=20=20=20=20=20=20=20=20=20(save-excursion=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(goto-char=20(point-min))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(cl-loop=20while=20(re-search-forward=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "^@defun=20\\([^=20]+\\)"=20nil=20t)=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20collect=20= (match-string-no-properties=201)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= #'string<))))=0A+=20=20=20=20(message=20"Missing:=20%s"=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20(string-join=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(cl-remove-if=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (lambda=20(name)=20(member=20name=20functions-in-manual))=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20functions-in-source)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20"\n"))))=0A+=0A+(provide=20'tree-sitter)=0A+=0A= +;;;=20tree-sitter.el=20ends=20here=0Adiff=20--git=20a/src/Makefile.in=20= b/src/Makefile.in=0Aindex=202b7c4bb316..6ae55b19e1=20100644=0A---=20= a/src/Makefile.in=0A+++=20b/src/Makefile.in=0A@@=20-337,6=20+337,10=20@@=20= JSON_LIBS=20=3D=0A=20JSON_CFLAGS=20=3D=20@JSON_CFLAGS@=0A=20JSON_OBJ=20=3D= =20@JSON_OBJ@=0A=20=0A+TREE_SITTER_LIBS=20=3D=20@TREE_SITTER_LIBS@=0A= +TREE_SITTER_FLAGS=20=3D=20@TREE_SITTER_FLAGS@=0A+TREE_SITTER_OBJ=20=3D=20= @TREE_SITTER_OBJ@=0A+=0A=20INTERVALS_H=20=3D=20dispextern.h=20= intervals.h=20composite.h=0A=20=0A=20GETLOADAVG_LIBS=20=3D=20= @GETLOADAVG_LIBS@=0A@@=20-400,7=20+404,7=20@@=20EMACS_CFLAGS=3D=0A=20=20=20= $(XINPUT_CFLAGS)=20$(WEBP_CFLAGS)=20$(WEBKIT_CFLAGS)=20$(LCMS2_CFLAGS)=20= \=0A=20=20=20$(SETTINGS_CFLAGS)=20$(FREETYPE_CFLAGS)=20= $(FONTCONFIG_CFLAGS)=20\=0A=20=20=20$(HARFBUZZ_CFLAGS)=20= $(LIBOTF_CFLAGS)=20$(M17N_FLT_CFLAGS)=20$(DEPFLAGS)=20\=0A-=20=20= $(LIBSYSTEMD_CFLAGS)=20$(JSON_CFLAGS)=20$(XSYNC_CFLAGS)=20\=0A+=20=20= $(LIBSYSTEMD_CFLAGS)=20$(JSON_CFLAGS)=20$(XSYNC_CFLAGS)=20= $(TREE_SITTER_CFLAGS)=20\=0A=20=20=20$(LIBGNUTLS_CFLAGS)=20= $(NOTIFY_CFLAGS)=20$(CAIRO_CFLAGS)=20\=0A=20=20=20$(WERROR_CFLAGS)=20= $(HAIKU_CFLAGS)=0A=20ALL_CFLAGS=20=3D=20$(EMACS_CFLAGS)=20$(WARN_CFLAGS)=20= $(CFLAGS)=0A@@=20-439,7=20+443,7=20@@=20base_obj=20=3D=0A=20=09$(if=20= $(HYBRID_MALLOC),sheap.o)=20\=0A=20=09$(MSDOS_OBJ)=20$(MSDOS_X_OBJ)=20= $(NS_OBJ)=20$(CYGWIN_OBJ)=20$(FONT_OBJ)=20\=0A=20=09$(W32_OBJ)=20= $(WINDOW_SYSTEM_OBJ)=20$(XGSELOBJ)=20$(JSON_OBJ)=20\=0A-=09$(HAIKU_OBJ)=20= $(PGTK_OBJ)=0A+=09$(TREE_SITTER_OBJ)=20$(HAIKU_OBJ)=20$(PGTK_OBJ)=0A=20= doc_obj=20=3D=20$(base_obj)=20$(NS_OBJC_OBJ)=0A=20obj=20=3D=20$(doc_obj)=20= $(HAIKU_CXX_OBJ)=0A=20=0A@@=20-559,7=20+563,7=20@@=20LIBES=20=3D=0A=20=20= =20=20$(LIBGNUTLS_LIBS)=20$(LIB_PTHREAD)=20$(GETADDRINFO_A_LIBS)=20= $(LCMS2_LIBS)=20\=0A=20=20=20=20$(NOTIFY_LIBS)=20$(LIB_MATH)=20$(LIBZ)=20= $(LIBMODULES)=20$(LIBSYSTEMD_LIBS)=20\=0A=20=20=20=20$(JSON_LIBS)=20= $(LIBGMP)=20$(LIBGCCJIT_LIBS)=20$(XINPUT_LIBS)=20$(HAIKU_LIBS)=20\=0A-=20= =20=20$(SQLITE3_LIBS)=0A+=20=20=20$(TREE_SITTER_LIBS)=20$(SQLITE3_LIBS)=0A= =20=0A=20##=20FORCE=20it=20so=20that=20admin/unidata=20can=20decide=20= whether=20this=20file=20is=0A=20##=20up-to-date.=20=20Although=20since=20= charprop=20depends=20on=20bootstrap-emacs,=0Adiff=20--git=20= a/src/alloc.c=20b/src/alloc.c=0Aindex=209ed94dc8a1..d4209bb3b9=20100644=0A= ---=20a/src/alloc.c=0A+++=20b/src/alloc.c=0A@@=20-50,6=20+50,10=20@@=20= Copyright=20(C)=201985-1986,=201988,=201993-1995,=201997-2022=20Free=20= Software=0A=20#include=20TERM_HEADER=0A=20#endif=20/*=20= HAVE_WINDOW_SYSTEM=20*/=0A=20=0A+#ifdef=20HAVE_TREE_SITTER=0A+#include=20= "tree-sitter.h"=0A+#endif=0A+=0A=20#include=20=0A=20= #include=20=0A=20#include=20=20=20=20=20=20=20=20=20= =20=20=20/*=20For=20backtrace.=20=20*/=0A@@=20-3177,6=20+3181,15=20@@=20= cleanup_vector=20(struct=20Lisp_Vector=20*vector)=0A=20=20=20=20=20=20=20= if=20(uptr->finalizer)=0A=20=09uptr->finalizer=20(uptr->p);=0A=20=20=20=20= =20}=0A+#ifdef=20HAVE_TREE_SITTER=0A+=20=20else=20if=20= (PSEUDOVECTOR_TYPEP=20(&vector->header,=20PVEC_TS_PARSER))=0A+=20=20=20=20= {=0A+=20=20=20=20=20=20struct=20Lisp_TS_Parser=20*lisp_parser=0A+=09=3D=20= PSEUDOVEC_STRUCT=20(vector,=20Lisp_TS_Parser);=0A+=20=20=20=20=20=20= ts_tree_delete(lisp_parser->tree);=0A+=20=20=20=20=20=20= ts_parser_delete(lisp_parser->parser);=0A+=20=20=20=20}=0A+#endif=0A=20= #ifdef=20HAVE_MODULES=0A=20=20=20else=20if=20(PSEUDOVECTOR_TYPEP=20= (&vector->header,=20PVEC_MODULE_FUNCTION))=0A=20=20=20=20=20{=0Adiff=20= --git=20a/src/casefiddle.c=20b/src/casefiddle.c=0Aindex=20= 2ea5f09b4c..ac9e73be0c=20100644=0A---=20a/src/casefiddle.c=0A+++=20= b/src/casefiddle.c=0A@@=20-30,6=20+30,10=20@@=20Copyright=20(C)=201985,=20= 1994,=201997-1999,=202001-2022=20Free=20Software=20Foundation,=0A=20= #include=20"composite.h"=0A=20#include=20"keymap.h"=0A=20=0A+#ifdef=20= HAVE_TREE_SITTER=0A+#include=20"tree-sitter.h"=0A+#endif=0A+=0A=20enum=20= case_action=20{CASE_UP,=20CASE_DOWN,=20CASE_CAPITALIZE,=20= CASE_CAPITALIZE_UP};=0A=20=0A=20/*=20State=20for=20casing=20individual=20= characters.=20=20*/=0A@@=20-530,6=20+534,11=20@@=20casify_region=20(enum=20= case_action=20flag,=20Lisp_Object=20b,=20Lisp_Object=20e)=0A=20=20=20= modify_text=20(start,=20end);=0A=20=20=20prepare_casing_context=20(&ctx,=20= flag,=20true);=0A=20=0A+#ifdef=20HAVE_TREE_SITTER=0A+=20=20ptrdiff_t=20= start_byte=20=3D=20CHAR_TO_BYTE=20(start);=0A+=20=20ptrdiff_t=20= old_end_byte=20=3D=20CHAR_TO_BYTE=20(end);=0A+#endif=0A+=0A=20=20=20= ptrdiff_t=20orig_end=20=3D=20end;=0A=20=20=20record_delete=20(start,=20= make_buffer_string=20(start,=20end,=20true),=20false);=0A=20=20=20if=20= (NILP=20(BVAR=20(current_buffer,=20enable_multibyte_characters)))=0A@@=20= -548,6=20+557,9=20@@=20casify_region=20(enum=20case_action=20flag,=20= Lisp_Object=20b,=20Lisp_Object=20e)=0A=20=20=20=20=20{=0A=20=20=20=20=20=20= =20signal_after_change=20(start,=20end=20-=20start=20-=20added,=20end=20= -=20start);=0A=20=20=20=20=20=20=20update_compositions=20(start,=20end,=20= CHECK_ALL);=0A+#ifdef=20HAVE_TREE_SITTER=0A+=20=20=20=20=20=20= ts_record_change=20(start_byte,=20old_end_byte,=20CHAR_TO_BYTE=20(end));=0A= +#endif=0A=20=20=20=20=20}=0A=20=0A=20=20=20return=20orig_end=20+=20= added;=0Adiff=20--git=20a/src/data.c=20b/src/data.c=0Aindex=20= 1526cc0c73..64095b3bb9=20100644=0A---=20a/src/data.c=0A+++=20= b/src/data.c=0A@@=20-260,6=20+260,10=20@@=20DEFUN=20("type-of",=20= Ftype_of,=20Stype_of,=201,=201,=200,=0A=20=20=20=20=20=20=20=20=20=20=20= return=20Qxwidget;=0A=20=20=20=20=20=20=20=20=20case=20= PVEC_XWIDGET_VIEW:=0A=20=20=20=20=20=20=20=20=20=20=20return=20= Qxwidget_view;=0A+=09case=20PVEC_TS_PARSER:=0A+=09=20=20return=20= Qtree_sitter_parser;=0A+=09case=20PVEC_TS_NODE:=0A+=09=20=20return=20= Qtree_sitter_node;=0A=20=20=20=20=20=20=20=20=20case=20PVEC_SQLITE:=0A=20= =20=20=20=20=20=20=20=20=20=20return=20Qsqlite;=0A=20=20=20=20=20=20=20=20= =20/*=20"Impossible"=20cases.=20=20*/=0A@@=20-4203,6=20+4207,8=20@@=20= #define=20PUT_ERROR(sym,=20tail,=20msg)=09=09=09\=0A=20=20=20DEFSYM=20= (Qterminal,=20"terminal");=0A=20=20=20DEFSYM=20(Qxwidget,=20"xwidget");=0A= =20=20=20DEFSYM=20(Qxwidget_view,=20"xwidget-view");=0A+=20=20DEFSYM=20= (Qtree_sitter_parser,=20"tree-sitter-parser");=0A+=20=20DEFSYM=20= (Qtree_sitter_node,=20"tree-sitter-node");=0A=20=0A=20=20=20DEFSYM=20= (Qdefun,=20"defun");=0A=20=0Adiff=20--git=20a/src/emacs.c=20= b/src/emacs.c=0Aindex=20d1060bca0b..703b8785c8=20100644=0A---=20= a/src/emacs.c=0A+++=20b/src/emacs.c=0A@@=20-85,6=20+85,7=20@@=20#define=20= MAIN_PROGRAM=0A=20#include=20"intervals.h"=0A=20#include=20"character.h"=0A= =20#include=20"buffer.h"=0A+#include=20"tree-sitter.h"=0A=20#include=20= "window.h"=0A=20#include=20"xwidget.h"=0A=20#include=20"atimer.h"=0A@@=20= -2147,6=20+2148,9=20@@=20main=20(int=20argc,=20char=20**argv)=0A=20=20=20= =20=20=20=20syms_of_floatfns=20();=0A=20=0A=20=20=20=20=20=20=20= syms_of_buffer=20();=0A+=20=20=20=20=20=20#ifdef=20HAVE_TREE_SITTER=0A+=20= =20=20=20=20=20syms_of_tree_sitter=20();=0A+=20=20=20=20=20=20#endif=0A=20= =20=20=20=20=20=20syms_of_bytecode=20();=0A=20=20=20=20=20=20=20= syms_of_callint=20();=0A=20=20=20=20=20=20=20syms_of_casefiddle=20();=0A= diff=20--git=20a/src/eval.c=20b/src/eval.c=0Aindex=20= 294d79e67a..ecf57efb92=20100644=0A---=20a/src/eval.c=0A+++=20= b/src/eval.c=0A@@=20-1915,6=20+1915,19=20@@=20signal_error=20(const=20= char=20*s,=20Lisp_Object=20arg)=0A=20=20=20xsignal=20(Qerror,=20Fcons=20= (build_string=20(s),=20arg));=0A=20}=0A=20=0A+void=0A+define_error=20= (Lisp_Object=20name,=20const=20char=20*message,=20Lisp_Object=20parent)=0A= +{=0A+=20=20eassert=20(SYMBOLP=20(name));=0A+=20=20eassert=20(SYMBOLP=20= (parent));=0A+=20=20Lisp_Object=20parent_conditions=20=3D=20Fget=20= (parent,=20Qerror_conditions);=0A+=20=20eassert=20(CONSP=20= (parent_conditions));=0A+=20=20eassert=20(!NILP=20(Fmemq=20(parent,=20= parent_conditions)));=0A+=20=20eassert=20(NILP=20(Fmemq=20(name,=20= parent_conditions)));=0A+=20=20Fput=20(name,=20Qerror_conditions,=20= pure_cons=20(name,=20parent_conditions));=0A+=20=20Fput=20(name,=20= Qerror_message,=20build_pure_c_string=20(message));=0A+}=0A+=0A=20/*=20= Use=20this=20for=20arithmetic=20overflow,=20e.g.,=20when=20an=20integer=20= result=20is=0A=20=20=20=20too=20large=20even=20for=20a=20bignum.=20=20*/=0A= =20void=0Adiff=20--git=20a/src/insdel.c=20b/src/insdel.c=0Aindex=20= 6f180ac580..72b6a8ad1b=20100644=0A---=20a/src/insdel.c=0A+++=20= b/src/insdel.c=0A@@=20-31,6=20+31,10=20@@=0A=20#include=20= "region-cache.h"=0A=20#include=20"pdumper.h"=0A=20=0A+#ifdef=20= HAVE_TREE_SITTER=0A+#include=20"tree-sitter.h"=0A+#endif=0A+=0A=20static=20= void=20insert_from_string_1=20(Lisp_Object,=20ptrdiff_t,=20ptrdiff_t,=20= ptrdiff_t,=0A=20=09=09=09=09=20=20ptrdiff_t,=20bool,=20bool);=0A=20= static=20void=20insert_from_buffer_1=20(struct=20buffer=20*,=20= ptrdiff_t,=20ptrdiff_t,=20bool);=0A@@=20-940,6=20+944,12=20@@=20= insert_1_both=20(const=20char=20*string,=0A=20=20=20=20=20= set_text_properties=20(make_fixnum=20(PT),=20make_fixnum=20(PT=20+=20= nchars),=0A=20=09=09=09=20Qnil,=20Qnil,=20Qnil);=0A=20=0A+#ifdef=20= HAVE_TREE_SITTER=0A+=20=20eassert=20(nbytes=20>=3D=200);=0A+=20=20= eassert=20(PT_BYTE=20>=3D=200);=0A+=20=20ts_record_change=20(PT_BYTE,=20= PT_BYTE,=20PT_BYTE=20+=20nbytes);=0A+#endif=0A+=0A=20=20=20adjust_point=20= (nchars,=20nbytes);=0A=20=0A=20=20=20check_markers=20();=0A@@=20-1071,6=20= +1081,12=20@@=20insert_from_string_1=20(Lisp_Object=20string,=20= ptrdiff_t=20pos,=20ptrdiff_t=20pos_byte,=0A=20=20=20= graft_intervals_into_buffer=20(intervals,=20PT,=20nchars,=0A=20=09=09=09=20= =20=20=20=20=20=20current_buffer,=20inherit);=0A=20=0A+#ifdef=20= HAVE_TREE_SITTER=0A+=20=20eassert=20(nbytes=20>=3D=200);=0A+=20=20= eassert=20(PT_BYTE=20>=3D=200);=0A+=20=20ts_record_change=20(PT_BYTE,=20= PT_BYTE,=20PT_BYTE=20+=20nbytes);=0A+#endif=0A+=0A=20=20=20adjust_point=20= (nchars,=20outgoing_nbytes);=0A=20=0A=20=20=20check_markers=20();=0A@@=20= -1137,6=20+1153,12=20@@=20insert_from_gap=20(ptrdiff_t=20nchars,=20= ptrdiff_t=20nbytes,=20bool=20text_at_gap_tail)=0A=20=09=09=09=09=20=20=20= current_buffer,=200);=0A=20=20=20=20=20}=0A=20=0A+#ifdef=20= HAVE_TREE_SITTER=0A+=20=20eassert=20(nbytes=20>=3D=200);=0A+=20=20= eassert=20(ins_bytepos=20>=3D=200);=0A+=20=20ts_record_change=20= (ins_bytepos,=20ins_bytepos,=20ins_bytepos=20+=20nbytes);=0A+#endif=0A+=0A= =20=20=20if=20(ins_charpos=20<=20PT)=0A=20=20=20=20=20adjust_point=20= (nchars,=20nbytes);=0A=20=0A@@=20-1287,6=20+1309,12=20@@=20= insert_from_buffer_1=20(struct=20buffer=20*buf,=0A=20=20=20/*=20Insert=20= those=20intervals.=20=20*/=0A=20=20=20graft_intervals_into_buffer=20= (intervals,=20PT,=20nchars,=20current_buffer,=20inherit);=0A=20=0A= +#ifdef=20HAVE_TREE_SITTER=0A+=20=20eassert=20(outgoing_nbytes=20>=3D=20= 0);=0A+=20=20eassert=20(PT_BYTE=20>=3D=200);=0A+=20=20ts_record_change=20= (PT_BYTE,=20PT_BYTE,=20PT_BYTE=20+=20outgoing_nbytes);=0A+#endif=0A+=0A=20= =20=20adjust_point=20(nchars,=20outgoing_nbytes);=0A=20}=0A=20=0C=0A@@=20= -1535,6=20+1563,13=20@@=20replace_range=20(ptrdiff_t=20from,=20ptrdiff_t=20= to,=20Lisp_Object=20new,=0A=20=20=20graft_intervals_into_buffer=20= (intervals,=20from,=20inschars,=0A=20=09=09=09=20=20=20=20=20=20=20= current_buffer,=20inherit);=0A=20=0A+#ifdef=20HAVE_TREE_SITTER=0A+=20=20= eassert=20(to_byte=20>=3D=20from_byte);=0A+=20=20eassert=20= (outgoing_insbytes=20>=3D=200);=0A+=20=20eassert=20(from_byte=20>=3D=20= 0);=0A+=20=20ts_record_change=20(from_byte,=20to_byte,=20from_byte=20+=20= outgoing_insbytes);=0A+#endif=0A+=0A=20=20=20/*=20Relocate=20point=20as=20= if=20it=20were=20a=20marker.=20=20*/=0A=20=20=20if=20(from=20<=20PT)=0A=20= =20=20=20=20adjust_point=20((from=20+=20inschars=20-=20(PT=20<=20to=20?=20= PT=20:=20to)),=0A@@=20-1569,7=20+1604,11=20@@=20replace_range=20= (ptrdiff_t=20from,=20ptrdiff_t=20to,=20Lisp_Object=20new,=0A=20=20=20=20= If=20MARKERS,=20relocate=20markers.=0A=20=0A=20=20=20=20Unlike=20most=20= functions=20at=20this=20level,=20never=20call=0A-=20=20=20= prepare_to_modify_buffer=20and=20never=20call=20signal_after_change.=20=20= */=0A+=20=20=20prepare_to_modify_buffer=20and=20never=20call=20= signal_after_change.=0A+=20=20=20Because=20this=20function=20is=20called=20= in=20a=20loop,=20one=20character=20at=20a=20time.=0A+=20=20=20The=20= caller=20of=20'replace_range_2'=20calls=20these=20hooks=20for=20the=20= entire=0A+=20=20=20region=20once.=20=20Apart=20from=20= signal_after_change,=20any=20caller=20of=20this=0A+=20=20=20function=20= should=20also=20call=20ts_record_change.=20=20*/=0A=20=0A=20void=0A=20= replace_range_2=20(ptrdiff_t=20from,=20ptrdiff_t=20from_byte,=0A@@=20= -1892,6=20+1931,12=20@@=20del_range_2=20(ptrdiff_t=20from,=20ptrdiff_t=20= from_byte,=0A=20=0A=20=20=20evaporate_overlays=20(from);=0A=20=0A+#ifdef=20= HAVE_TREE_SITTER=0A+=20=20eassert=20(from_byte=20<=3D=20to_byte);=0A+=20=20= eassert=20(from_byte=20>=3D=200);=0A+=20=20ts_record_change=20= (from_byte,=20to_byte,=20from_byte);=0A+#endif=0A+=0A=20=20=20return=20= deletion;=0A=20}=0A=20=0Adiff=20--git=20a/src/json.c=20b/src/json.c=0A= index=20db1be07f19..957f91b46b=20100644=0A---=20a/src/json.c=0A+++=20= b/src/json.c=0A@@=20-1090,22=20+1090,6=20@@=20DEFUN=20= ("json-parse-buffer",=20Fjson_parse_buffer,=20Sjson_parse_buffer,=0A=20=20= =20return=20unbind_to=20(count,=20lisp);=0A=20}=0A=20=0A-/*=20Simplified=20= version=20of=20'define-error'=20that=20works=20with=20pure=0A-=20=20=20= objects.=20=20*/=0A-=0A-static=20void=0A-define_error=20(Lisp_Object=20= name,=20const=20char=20*message,=20Lisp_Object=20parent)=0A-{=0A-=20=20= eassert=20(SYMBOLP=20(name));=0A-=20=20eassert=20(SYMBOLP=20(parent));=0A= -=20=20Lisp_Object=20parent_conditions=20=3D=20Fget=20(parent,=20= Qerror_conditions);=0A-=20=20eassert=20(CONSP=20(parent_conditions));=0A= -=20=20eassert=20(!NILP=20(Fmemq=20(parent,=20parent_conditions)));=0A-=20= =20eassert=20(NILP=20(Fmemq=20(name,=20parent_conditions)));=0A-=20=20= Fput=20(name,=20Qerror_conditions,=20pure_cons=20(name,=20= parent_conditions));=0A-=20=20Fput=20(name,=20Qerror_message,=20= build_pure_c_string=20(message));=0A-}=0A-=0A=20void=0A=20syms_of_json=20= (void)=0A=20{=0Adiff=20--git=20a/src/lisp.h=20b/src/lisp.h=0Aindex=20= 778bd1bfa5..aecbfed7fa=20100644=0A---=20a/src/lisp.h=0A+++=20= b/src/lisp.h=0A@@=20-575,6=20+575,8=20@@=20#define=20ENUM_BF(TYPE)=20= enum=20TYPE=0A=20=20=20=20your=20object=20--=20this=20way,=20the=20same=20= object=20could=20be=20used=20to=20represent=0A=20=20=20=20several=20= disparate=20C=20structures.=0A=20=0A+=20=20=20In=20addition,=20you=20= need=20to=20add=20switch=20branches=20in=20data.c=20for=20Ftype_of.=0A+=0A= =20=20=20=20You=20also=20need=20to=20add=20the=20new=20type=20to=20the=20= constant=0A=20=20=20=20`cl--typeof-types'=20in=20= lisp/emacs-lisp/cl-preloaded.el.=20=20*/=0A=20=0A@@=20-1053,6=20+1055,8=20= @@=20DEFINE_GDB_SYMBOL_END=20(PSEUDOVECTOR_FLAG)=0A=20=20=20= PVEC_CONDVAR,=0A=20=20=20PVEC_MODULE_FUNCTION,=0A=20=20=20= PVEC_NATIVE_COMP_UNIT,=0A+=20=20PVEC_TS_PARSER,=0A+=20=20PVEC_TS_NODE,=0A= =20=20=20PVEC_SQLITE,=0A=20=0A=20=20=20/*=20These=20should=20be=20last,=20= for=20internal_equal=20and=20sxhash_obj.=20=20*/=0A@@=20-5407,6=20= +5411,11=20@@=20maybe_gc=20(void)=0A=20=20=20=20=20maybe_garbage_collect=20= ();=0A=20}=0A=20=0A+/*=20Simplified=20version=20of=20'define-error'=20= that=20works=20with=20pure=0A+=20=20=20objects.=20=20*/=0A+void=0A= +define_error=20(Lisp_Object=20name,=20const=20char=20*message,=20= Lisp_Object=20parent);=0A+=0A=20INLINE_HEADER_END=0A=20=0A=20#endif=20/*=20= EMACS_LISP_H=20*/=0Adiff=20--git=20a/src/lread.c=20b/src/lread.c=0Aindex=20= 0486a98883..8989e2d12d=20100644=0A---=20a/src/lread.c=0A+++=20= b/src/lread.c=0A@@=20-5196,6=20+5196,14=20@@=20syms_of_lread=20(void)=0A=20= =20=20=20=20Fcons=20(build_pure_c_string=20(MODULES_SECONDARY_SUFFIX),=20= Vload_suffixes);=0A=20#endif=0A=20=0A+=20=20DEFVAR_LISP=20= ("dynamic-library-suffixes",=20Vdynamic_library_suffixes,=0A+=09=20=20=20= =20=20=20=20doc:=20/*=20A=20list=20of=20suffixes=20for=20loadable=20= dynamic=20libraries.=20=20*/);=0A+=20=20Vdynamic_library_suffixes=20=3D=0A= +=20=20=20=20Fcons=20(build_pure_c_string=20= (DYNAMIC_LIB_SECONDARY_SUFFIX),=20Qnil);=0A+=20=20= Vdynamic_library_suffixes=20=3D=0A+=20=20=20=20Fcons=20= (build_pure_c_string=20(DYNAMIC_LIB_SUFFIX),=0A+=09=20=20=20= Vdynamic_library_suffixes);=0A+=0A=20#endif=0A=20=20=20DEFVAR_LISP=20= ("module-file-suffix",=20Vmodule_file_suffix,=0A=20=09=20=20=20=20=20=20=20= doc:=20/*=20Suffix=20of=20loadable=20module=20file,=20or=20nil=20if=20= modules=20are=20not=20supported.=20=20*/);=0Adiff=20--git=20= a/src/print.c=20b/src/print.c=0Aindex=208cce8a1ad8..b55b0d2e39=20100644=0A= ---=20a/src/print.c=0A+++=20b/src/print.c=0A@@=20-48,6=20+48,10=20@@=20= Copyright=20(C)=201985-1986,=201988,=201993-1995,=201997-2022=20Free=20= Software=0A=20#=20include=20=20/*=20for=20F_DUPFD_CLOEXEC=20= */=0A=20#endif=0A=20=0A+#ifdef=20HAVE_TREE_SITTER=0A+#include=20= "tree-sitter.h"=0A+#endif=0A+=0A=20struct=20terminal;=0A=20=0A=20/*=20= Avoid=20actual=20stack=20overflow=20in=20print.=20=20*/=0A@@=20-1936,6=20= +1940,30=20@@=20print_vectorlike=20(Lisp_Object=20obj,=20Lisp_Object=20= printcharfun,=20bool=20escapeflag,=0A=20=20=20=20=20=20=20}=0A=20=20=20=20= =20=20=20break;=0A=20#endif=0A+=0A+#ifdef=20HAVE_TREE_SITTER=0A+=20=20=20= =20case=20PVEC_TS_PARSER:=0A+=20=20=20=20=20=20print_c_string=20= ("#language_symbol;=0A+=20= =20=20=20=20=20print_string=20(Fsymbol_name=20(language),=20= printcharfun);=0A+=20=20=20=20=20=20print_c_string=20("=20in=20",=20= printcharfun);=0A+=20=20=20=20=20=20print_object=20(XTS_PARSER=20= (obj)->buffer,=20printcharfun,=20escapeflag);=0A+=20=20=20=20=20=20= printchar=20('>',=20printcharfun);=0A+=20=20=20=20=20=20break;=0A+=20=20=20= =20case=20PVEC_TS_NODE:=0A+=20=20=20=20=20=20print_c_string=20= ("#parser)->buffer,=0A+=09=09=20=20=20=20printcharfun,=20= escapeflag);=0A+=20=20=20=20=20=20printchar=20('>',=20printcharfun);=0A+=20= =20=20=20=20=20break;=0A+#endif=0A+=0A=20=20=20=20=20case=20PVEC_SQLITE:=0A= =20=20=20=20=20=20=20{=0A=20=09print_c_string=20("#.=20=20*/=0A+=0A+#include=20= =0A+=0A+#include=20"lisp.h"=0A+#include=20"buffer.h"=0A= +#include=20"tree-sitter.h"=0A+=0A+/*=20Commentary=0A+=0A+=20=20=20The=20= Emacs=20wrapper=20of=20tree-sitter=20does=20not=20expose=20everything=20= the=20C=0A+=20=20=20API=20provides,=20most=20notably:=0A+=0A+=20=20=20-=20= It=20doesn't=20expose=20a=20syntax=20tree,=20we=20put=20the=20syntax=20= tree=20in=20the=0A+=20=20=20=20=20parser=20object,=20and=20updating=20= the=20tree=20is=20handled=20in=20the=20C=20level.=0A+=0A+=20=20=20-=20We=20= don't=20expose=20tree=20cursor=20either.=20=20I=20think=20Lisp=20is=20= slow=20enough=0A+=20=20=20=20=20to=20nullify=20any=20performance=20= advantage=20of=20using=20a=20cursor,=20though=20I=0A+=20=20=20=20=20= don't=20have=20evidence.=0A+=0A+=20=20=20-=20Because=20updating=20the=20= change=20is=20handled=20in=20the=20C=20level=20as=20each=0A+=20=20=20=20=20= change=20is=20made=20in=20the=20buffer,=20there=20is=20no=20way=20for=20= Lisp=20to=20update=0A+=20=20=20=20=20a=20node.=20=20But=20since=20we=20= can=20just=20retrieve=20a=20new=20node,=20it=20shouldn't=0A+=20=20=20=20=20= be=20a=20limitation.=0A+=0A+=20=20=20-=20I=20didn't=20expose=20setting=20= timeout=20and=20cancellation=20flag=20for=20a=0A+=20=20=20=20=20parser,=20= mainly=20because=20I=20don't=20think=20they=20are=20really=20necessary=0A= +=20=20=20=20=20in=20Emacs'=20use=20cases.=0A+=0A+=20=20=20-=20Many=20= tree-sitter=20functions=20asks=20for=20a=20TSPoint,=20basically=20a=20= (row,=0A+=20=20=20=20=20column)=20location.=20=20Emacs=20uses=20a=20gap=20= buffer=20and=20keeps=20no=0A+=20=20=20=20=20information=20about=20row=20= and=20column=20position.=20=20According=20to=20the=0A+=20=20=20=20=20= author=20of=20tree-sitter,=20tree-sitter=20only=20asks=20for=20(row,=20= column)=0A+=20=20=20=20=20position=20to=20carry=20it=20around=20and=20= return=20back=20to=20the=20user=20later;=0A+=20=20=20=20=20and=20the=20= real=20position=20used=20is=20the=20byte=20position.=20=20He=20also=20= said=0A+=20=20=20=20=20that=20he=20_think_=20that=20it=20will=20work=20= to=20use=20byte=20position=20only.=0A+=20=20=20=20=20That's=20why=20= whenever=20a=20TSPoint=20is=20asked,=20we=20pass=20a=20dummy=20one=20to=0A= +=20=20=20=20=20it.=20=20Judging=20by=20the=20nature=20of=20parsing=20= algorithms,=20I=20think=20it=20is=0A+=20=20=20=20=20safe=20to=20use=20= only=20byte=20position,=20and=20I=20don't=20think=20this=20will=0A+=20=20= =20=20=20change=20in=20the=20future.=0A+=0A+=20=20=20=20=20REF:=20= https://github.com/tree-sitter/tree-sitter/issues/445=0A+=0A+=20=20=20= tree-sitter.h=20has=20some=20commentary=20on=20the=20two=20main=20data=20= structure=0A+=20=20=20for=20the=20parser=20and=20node.=20=20= ts_ensure_position_synced=20has=20some=0A+=20=20=20commentary=20on=20how=20= do=20we=20make=20tree-sitter=20play=20well=20with=20narrowing=0A+=20=20=20= (tree-sitter=20parser=20only=20sees=20the=20visible=20region,=20so=20we=20= need=20to=0A+=20=20=20translate=20positions=20back=20and=20forth).=20=20= Most=20action=20happens=20in=0A+=20=20=20ts_ensure_parsed,=20= ts_read_buffer=20and=20ts_record_change.=0A+=0A+=20=20=20A=20complete=20= correspondence=20list=20between=20tree-sitter=20functions=20and=0A+=20=20= =20exposed=20Lisp=20functions=20can=20be=20found=20in=20the=20manual=20= (elisp)API=0A+=20=20=20Correspondence.=0A+=0A+=20=20=20Placement=20of=20= CHECK_xxx=20functions:=20call=20CHECK_xxx=20before=20using=20any=0A+=20=20= =20unchecked=20Lisp=20values;=20these=20include=20argument=20of=20Lisp=20= functions,=0A+=20=20=20return=20value=20of=20Fsymbol_value,=20car=20of=20= a=20cons.=0A+=0A+=20=20=20Initializing=20tree-sitter:=20there=20are=20= two=20entry=20points=20to=20tree-sitter=0A+=20=20=20functions:=20= 'tree-sitter-parser-create'=20and=0A+=20=20=20= 'tree-sitter-language-available-p'.=20=20Therefore=20we=20only=20need=20= to=20call=0A+=20=20=20initialization=20function=20in=20those=20two=20= functions.=0A+=0A+=20=20=20Tree-sitter=20offset=20(0-based)=20and=20= buffer=20position=20(1-based):=0A+=20=20=20=20=20tree-sitter=20offset=20= +=20buffer=20position=20=3D=20buffer=20position=0A+=20=20=20=20=20buffer=20= position=20-=20buffer=20position=20=3D=20tree-sitter=20offset=0A+=20*/=0A= +=0A+/***=20Initialization=20*/=0A+=0A+bool=20ts_initialized=20=3D=20= false;=0A+=0A+static=20void=20*=0A+ts_calloc_wrapper=20(size_t=20n,=20= size_t=20size)=0A+{=0A+=20=20return=20xzalloc=20(n=20*=20size);=0A+}=0A+=0A= +void=0A+ts_initialize=20()=0A+{=0A+=20=20if=20(!ts_initialized)=0A+=20=20= =20=20{=0A+=20=20=20=20=20=20ts_set_allocator=20(xmalloc,=20= ts_calloc_wrapper,=20xrealloc,=20xfree);=0A+=20=20=20=20=20=20= ts_initialized=20=3D=20true;=0A+=20=20=20=20}=0A+}=0A+=0A+/***=20Loading=20= language=20library=20*/=0A+=0A+/*=20Translates=20a=20symbol=20= tree-sitter-=20to=20a=20C=20name=0A+=20=20=20tree_sitter_.=20= =20*/=0A+void=0A+ts_symbol_to_c_name=20(char=20*symbol_name)=0A+{=0A+=20=20= for=20(int=20idx=3D0;=20idx=20<=20strlen=20(symbol_name);=20idx++)=0A+=20= =20=20=20{=0A+=20=20=20=20=20=20if=20(symbol_name[idx]=20=3D=3D=20'-')=0A= +=09symbol_name[idx]=20=3D=20'_';=0A+=20=20=20=20}=0A+}=0A+=0A+bool=0A= +ts_find_override_name=0A+(Lisp_Object=20language_symbol,=20Lisp_Object=20= *name,=20Lisp_Object=20*c_symbol)=0A+{=0A+=20=20for=20(Lisp_Object=20= list=20=3D=20Vtree_sitter_load_name_override_list;=0A+=20=20=20=20=20=20=20= !NILP=20(list);=20list=20=3D=20XCDR=20(list))=0A+=20=20=20=20{=0A+=20=20=20= =20=20=20Lisp_Object=20lang=20=3D=20XCAR=20(XCAR=20(list));=0A+=20=20=20=20= =20=20CHECK_SYMBOL=20(lang);=0A+=20=20=20=20=20=20if=20(EQ=20(lang,=20= language_symbol))=0A+=09{=0A+=09=20=20*name=20=3D=20Fnth=20(make_fixnum=20= (1),=20XCAR=20(list));=0A+=09=20=20CHECK_STRING=20(*name);=0A+=09=20=20= *c_symbol=20=3D=20Fnth=20(make_fixnum=20(2),=20XCAR=20(list));=0A+=09=20=20= CHECK_STRING=20(*c_symbol);=0A+=09=20=20return=20true;=0A+=09}=0A+=20=20=20= =20}=0A+=20=20return=20false;=0A+}=0A+=0A+/*=20Load=20the=20dynamic=20= library=20of=20LANGUAGE_SYMBOL=20and=20return=20the=20pointer=0A+=20=20=20= to=20the=20language=20definition.=20=20Signals=0A+=20=20=20= Qtree_sitter_load_language_error=20if=20something=20goes=20wrong.=0A+=20=20= =20Qtree_sitter_load_language_error=20carries=20the=20error=20message=20= from=0A+=20=20=20trying=20to=20load=20the=20library=20with=20each=20= extension.=0A+=0A+=20=20=20If=20SIGNAL=20is=20true,=20signal=20an=20= error=20when=20failed=20to=20load=20LANGUAGE;=20if=0A+=20=20=20false,=20= return=20NULL=20when=20failed.=20=20*/=0A+TSLanguage=20*=0A= +ts_load_language=20(Lisp_Object=20language_symbol,=20bool=20signal)=0A= +{=0A+=20=20Lisp_Object=20symbol_name=20=3D=20Fsymbol_name=20= (language_symbol);=0A+=0A+=20=20/*=20Figure=20out=20the=20library=20name=20= and=20C=20name.=20=20*/=0A+=20=20Lisp_Object=20lib_base_name=20=3D=0A+=20= =20=20=20(concat2=20(build_pure_c_string=20("lib"),=20symbol_name));=0A+=20= =20char=20*c_name=20=3D=20strdup=20(SSDATA=20(symbol_name));=0A+=20=20= ts_symbol_to_c_name=20(c_name);=0A+=0A+=20=20/*=20Override=20the=20= library=20name=20and=20C=20name,=20if=20appropriate.=20=20*/=0A+=20=20= Lisp_Object=20override_name;=0A+=20=20Lisp_Object=20override_c_name;=0A+=20= =20bool=20found_override=20=3D=20ts_find_override_name=0A+=20=20=20=20= (language_symbol,=20&override_name,=20&override_c_name);=0A+=20=20if=20= (found_override)=0A+=20=20=20=20{=0A+=20=20=20=20=20=20lib_base_name=20=3D= =20override_name;=0A+=20=20=20=20=20=20c_name=20=3D=20SSDATA=20= (override_c_name);=0A+=20=20=20=20}=0A+=0A+=20=20dynlib_handle_ptr=20= handle;=0A+=20=20char=20const=20*error;=0A+=20=20Lisp_Object=20= error_list=20=3D=20Qnil;=0A+=20=20/*=20Try=20loading=20dynamic=20library=20= with=20each=20extension=20in=0A+=20=20=20=20=20= 'tree-sitter-load-suffixes'.=20=20Stop=20when=20succeed,=20record=20= error=0A+=20=20=20=20=20message=20and=20try=20the=20next=20one=20when=20= fail.=20=20*/=0A+=20=20for=20(Lisp_Object=20suffixes=20=3D=20= Vdynamic_library_suffixes;=0A+=20=20=20=20=20=20=20!NILP=20(suffixes);=20= suffixes=20=3D=20XCDR=20(suffixes))=0A+=20=20=20=20{=0A+=20=20=20=20=20=20= char=20*library_name=20=3D=0A+=09SSDATA=20(concat2=20(lib_base_name,=20= XCAR=20(suffixes)));=0A+=20=20=20=20=20=20dynlib_error=20();=0A+=20=20=20= =20=20=20handle=20=3D=20dynlib_open=20(library_name);=0A+=20=20=20=20=20=20= error=20=3D=20dynlib_error=20();=0A+=20=20=20=20=20=20if=20(error=20=3D=3D= =20NULL)=0A+=09break;=0A+=20=20=20=20=20=20else=0A+=09error_list=20=3D=20= Fcons=20(build_string=20(error),=20error_list);=0A+=20=20=20=20}=0A+=20=20= if=20(error=20!=3D=20NULL)=0A+=20=20=20=20{=0A+=20=20=20=20=20=20if=20= (signal)=0A+=09xsignal2=20(Qtree_sitter_load_language_error,=0A+=09=09=20= =20symbol_name,=20Fnreverse=20(error_list));=0A+=20=20=20=20=20=20else=0A= +=09return=20NULL;=0A+=20=20=20=20}=0A+=0A+=20=20/*=20Load=20TSLanguage.=20= =20*/=0A+=20=20dynlib_error=20();=0A+=20=20TSLanguage=20*(*langfn)=20();=0A= +=20=20langfn=20=3D=20dynlib_sym=20(handle,=20c_name);=0A+=20=20error=20= =3D=20dynlib_error=20();=0A+=20=20if=20(error=20!=3D=20NULL)=0A+=20=20=20= =20{=0A+=20=20=20=20=20=20if=20(signal)=0A+=09xsignal1=20= (Qtree_sitter_load_language_error,=0A+=09=09=20=20build_string=20= (error));=0A+=20=20=20=20=20=20else=0A+=09return=20NULL;=0A+=20=20=20=20= }=0A+=20=20TSLanguage=20*lang=20=3D=20(*langfn)=20();=0A+=0A+=20=20/*=20= Check=20if=20language=20version=20matches=20tree-sitter=20version.=20=20= */=0A+=20=20TSParser=20*parser=20=3D=20ts_parser_new=20();=0A+=20=20bool=20= success=20=3D=20ts_parser_set_language=20(parser,=20lang);=0A+=20=20= ts_parser_delete=20(parser);=0A+=20=20if=20(!success)=0A+=20=20=20=20{=0A= +=20=20=20=20=20=20if=20(signal)=0A+=09xsignal2=20= (Qtree_sitter_load_language_error,=0A+=09=09=20=20build_pure_c_string=20= ("Language=20version=20doesn't=20match=20tree-sitter=20version,=20= language=20version:"),=0A+=09=09=20=20make_fixnum=20(ts_language_version=20= (lang)));=0A+=20=20=20=20=20=20else=0A+=09return=20NULL;=0A+=20=20=20=20= }=0A+=20=20return=20lang;=0A+}=0A+=0A+DEFUN=20= ("tree-sitter-language-available-p",=0A+=20=20=20=20=20=20=20= Ftree_sitter_langauge_available_p,=0A+=20=20=20=20=20=20=20= Stree_sitter_language_available_p,=0A+=20=20=20=20=20=20=201,=201,=200,=0A= +=20=20=20=20=20=20=20doc:=20/*=20Return=20non-nil=20if=20LANGUAGE=20= exists=20and=20is=20loadable.=20=20*/)=0A+=20=20(Lisp_Object=20language)=0A= +{=0A+=20=20CHECK_SYMBOL=20(language);=0A+=20=20ts_initialize=20();=0A+=20= =20if=20(ts_load_language(language,=20false)=20=3D=3D=20NULL)=0A+=20=20=20= =20return=20Qnil;=0A+=20=20else=0A+=20=20=20=20return=20Qt;=0A+}=0A+=0A= +/***=20Parsing=20functions=20*/=0A+=0A+/*=20An=20auxiliary=20function=20= that=20saves=20a=20few=20lines=20of=20code.=20=20Assumes=20TREE=0A+=20=20= =20is=20not=20NULL.=20=20*/=0A+static=20inline=20void=0A+ts_tree_edit_1=20= (TSTree=20*tree,=20ptrdiff_t=20start_byte,=0A+=09=09ptrdiff_t=20= old_end_byte,=20ptrdiff_t=20new_end_byte)=0A+{=0A+=20=20TSPoint=20= dummy_point=20=3D=20{0,=200};=0A+=20=20TSInputEdit=20edit=20=3D=20= {(uint32_t)=20start_byte,=0A+=09=09=20=20=20=20=20=20(uint32_t)=20= old_end_byte,=0A+=09=09=20=20=20=20=20=20(uint32_t)=20new_end_byte,=0A+=09= =09=20=20=20=20=20=20dummy_point,=20dummy_point,=20dummy_point};=0A+=20=20= ts_tree_edit=20(tree,=20&edit);=0A+}=0A+=0A+/*=20Update=20each=20= parser's=20tree=20after=20the=20user=20made=20an=20edit.=20=20This=0A= +function=20does=20not=20parse=20the=20buffer=20and=20only=20updates=20= the=20tree.=20(So=20it=0A+should=20be=20very=20fast.)=20=20*/=0A+void=0A= +ts_record_change=20(ptrdiff_t=20start_byte,=20ptrdiff_t=20old_end_byte,=0A= +=09=09=20=20ptrdiff_t=20new_end_byte)=0A+{=0A+=20=20for=20(Lisp_Object=20= parser_list=20=3D=0A+=09=20Fsymbol_value=20(Qtree_sitter_parser_list);=0A= +=20=20=20=20=20=20=20!NILP=20(parser_list);=0A+=20=20=20=20=20=20=20= parser_list=20=3D=20XCDR=20(parser_list))=0A+=20=20=20=20{=0A+=20=20=20=20= =20=20CHECK_CONS=20(parser_list);=0A+=20=20=20=20=20=20Lisp_Object=20= lisp_parser=20=3D=20XCAR=20(parser_list);=0A+=20=20=20=20=20=20= CHECK_TS_PARSER=20(lisp_parser);=0A+=20=20=20=20=20=20TSTree=20*tree=20=3D= =20XTS_PARSER=20(lisp_parser)->tree;=0A+=20=20=20=20=20=20if=20(tree=20= !=3D=20NULL)=0A+=09{=0A+=09=20=20eassert=20(start_byte=20<=3D=20= old_end_byte);=0A+=09=20=20eassert=20(start_byte=20<=3D=20new_end_byte);=0A= +=09=20=20/*=20Think=20the=20recorded=20change=20as=20a=20delete=20= followed=20by=20an=0A+=09=20=20=20=20=20insert,=20and=20think=20of=20= them=20as=20moving=20unchanged=20text=20back=0A+=09=20=20=20=20=20and=20= forth.=20=20After=20all,=20the=20whole=20point=20of=20updating=20the=0A+=09= =20=20=20=20=20tree=20is=20to=20update=20the=20position=20of=20unchanged=20= text.=20=20*/=0A+=09=20=20ptrdiff_t=20bytes_del=20=3D=20old_end_byte=20-=20= start_byte;=0A+=09=20=20ptrdiff_t=20bytes_ins=20=3D=20new_end_byte=20-=20= start_byte;=0A+=0A+=09=20=20ptrdiff_t=20visible_beg=20=3D=20XTS_PARSER=20= (lisp_parser)->visible_beg;=0A+=09=20=20ptrdiff_t=20visible_end=20=3D=20= XTS_PARSER=20(lisp_parser)->visible_end;=0A+=0A+=09=20=20ptrdiff_t=20= affected_start=20=3D=0A+=09=20=20=20=20max=20(visible_beg,=20start_byte)=20= -=20visible_beg;=0A+=09=20=20ptrdiff_t=20affected_old_end=20=3D=0A+=09=20= =20=20=20min=20(visible_end,=20affected_start=20+=20bytes_del);=0A+=09=20= =20ptrdiff_t=20affected_new_end=20=3D=0A+=09=20=20=20=20affected_start=20= +=20bytes_ins;=0A+=0A+=09=20=20ts_tree_edit_1=20(tree,=20affected_start,=20= affected_old_end,=0A+=09=09=09=20=20affected_new_end);=0A+=09=20=20= XTS_PARSER=20(lisp_parser)->visible_end=20=3D=20affected_new_end;=0A+=09=20= =20XTS_PARSER=20(lisp_parser)->need_reparse=20=3D=20true;=0A+=09=20=20= XTS_PARSER=20(lisp_parser)->timestamp++;=0A+=09}=0A+=20=20=20=20}=0A+}=0A= +=0A+void=0A+ts_ensure_position_synced=20(Lisp_Object=20parser)=0A+{=0A+=20= =20TSParser=20*ts_parser=20=3D=20XTS_PARSER=20(parser)->parser;=0A+=20=20= TSTree=20*tree=20=3D=20XTS_PARSER=20(parser)->tree;=0A+=0A+=20=20if=20= (tree=20=3D=3D=20NULL)=0A+=20=20=20=20return;=0A+=0A+=20=20struct=20= buffer=20*buffer=20=3D=20XBUFFER=20(XTS_PARSER=20(parser)->buffer);=0A+=20= =20ptrdiff_t=20visible_beg=20=3D=20XTS_PARSER=20(parser)->visible_beg;=0A= +=20=20ptrdiff_t=20visible_end=20=3D=20XTS_PARSER=20= (parser)->visible_end;=0A+=20=20/*=20Before=20we=20parse=20or=20set=20= ranges,=20catch=20up=20with=20the=20narrowing=0A+=20=20=20=20=20= situation.=20=20We=20change=20visible_beg=20and=20visible_end=20to=20= match=0A+=20=20=20=20=20BUF_BEGV_BYTE=20and=20BUF_ZV_BYTE,=20and=20= inform=20tree-sitter=20of=20the=0A+=20=20=20=20=20change.=20=20We=20want=20= to=20move=20the=20visible=20range=20of=20tree-sitter=20to=0A+=20=20=20=20= =20match=20the=20narrowed=20range.=20For=20example,=0A+=20=20=20=20=20= from=20________|xxxx|__=0A+=20=20=20=20=20to=20=20=20|xxxx|__________=20= */=0A+=0A+=20=20/*=201.=20Make=20sure=20visible_beg=20<=3D=20= BUF_BEGV_BYTE.=20=20*/=0A+=20=20if=20(visible_beg=20>=20BUF_BEGV_BYTE=20= (buffer))=0A+=20=20=20=20{=0A+=20=20=20=20=20=20/*=20Tree-sitter=20sees:=20= insert=20at=20the=20beginning.=20*/=0A+=20=20=20=20=20=20ts_tree_edit_1=20= (tree,=200,=200,=20visible_beg=20-=20BUF_BEGV_BYTE=20(buffer));=0A+=20=20= =20=20=20=20visible_beg=20=3D=20BUF_BEGV_BYTE=20(buffer);=0A+=20=20=20=20= }=0A+=20=20/*=202.=20Make=20sure=20visible_end=20=3D=20BUF_ZV_BYTE.=20=20= */=0A+=20=20if=20(visible_end=20<=20BUF_ZV_BYTE=20(buffer))=0A+=20=20=20=20= {=0A+=20=20=20=20=20=20/*=20Tree-sitter=20sees:=20insert=20at=20the=20= end.=20=20*/=0A+=20=20=20=20=20=20ts_tree_edit_1=20(tree,=20visible_end=20= -=20visible_beg,=0A+=09=09=20=20=20=20=20=20visible_end=20-=20= visible_beg,=0A+=09=09=20=20=20=20=20=20BUF_ZV_BYTE=20(buffer)=20-=20= visible_beg);=0A+=20=20=20=20=20=20visible_end=20=3D=20BUF_ZV_BYTE=20= (buffer);=0A+=20=20=20=20}=0A+=20=20else=20if=20(visible_end=20>=20= BUF_ZV_BYTE=20(buffer))=0A+=20=20=20=20{=0A+=20=20=20=20=20=20/*=20= Tree-sitter=20sees:=20delete=20at=20the=20end.=20=20*/=0A+=20=20=20=20=20= =20ts_tree_edit_1=20(tree,=20BUF_ZV_BYTE=20(buffer)=20-=20visible_beg,=0A= +=09=09=20=20=20=20=20=20visible_end=20-=20visible_beg,=0A+=09=09=20=20=20= =20=20=20BUF_ZV_BYTE=20(buffer)=20-=20visible_beg);=0A+=20=20=20=20=20=20= visible_end=20=3D=20BUF_ZV_BYTE=20(buffer);=0A+=20=20=20=20}=0A+=20=20/*=20= 3.=20Make=20sure=20visible_beg=20=3D=20BUF_BEGV_BYTE.=20=20*/=0A+=20=20= if=20(visible_beg=20<=20BUF_BEGV_BYTE=20(buffer))=0A+=20=20=20=20{=0A+=20= =20=20=20=20=20/*=20Tree-sitter=20sees:=20delete=20at=20the=20beginning.=20= =20*/=0A+=20=20=20=20=20=20ts_tree_edit_1=20(tree,=200,=20BUF_BEGV_BYTE=20= (buffer)=20-=20visible_beg,=200);=0A+=20=20=20=20=20=20visible_beg=20=3D=20= BUF_BEGV_BYTE=20(buffer);=0A+=20=20=20=20}=0A+=20=20eassert=20(0=20<=3D=20= visible_beg);=0A+=20=20eassert=20(visible_beg=20<=3D=20visible_end);=0A+=0A= +=20=20XTS_PARSER=20(parser)->visible_beg=20=3D=20visible_beg;=0A+=20=20= XTS_PARSER=20(parser)->visible_end=20=3D=20visible_end;=0A+}=0A+=0A+void=0A= +ts_check_buffer_size=20(struct=20buffer=20*buffer)=0A+{=0A+=20=20= ptrdiff_t=20buffer_size=20=3D=0A+=20=20=20=20(BUF_Z=20(buffer)=20-=20= BUF_BEG=20(buffer));=0A+=20=20if=20(buffer_size=20>=20UINT32_MAX)=0A+=20=20= =20=20xsignal2=20(Qtree_sitter_buffer_too_large,=0A+=09=20=20=20=20=20=20= build_pure_c_string=20("Buffer=20size=20too=20large,=20size:"),=0A+=09=20= =20=20=20=20=20make_fixnum=20(buffer_size));=0A+}=0A+=0A+/*=20Parse=20= the=20buffer.=20=20We=20don't=20parse=20until=20we=20have=20to.=20When=20= we=20have=0A+to,=20we=20call=20this=20function=20to=20parse=20and=20= update=20the=20tree.=20=20*/=0A+void=0A+ts_ensure_parsed=20(Lisp_Object=20= parser)=0A+{=0A+=20=20if=20(!XTS_PARSER=20(parser)->need_reparse)=0A+=20=20= =20=20return;=0A+=20=20TSParser=20*ts_parser=20=3D=20XTS_PARSER=20= (parser)->parser;=0A+=20=20TSTree=20*tree=20=3D=20= XTS_PARSER(parser)->tree;=0A+=20=20TSInput=20input=20=3D=20XTS_PARSER=20= (parser)->input;=0A+=20=20struct=20buffer=20*buffer=20=3D=20XBUFFER=20= (XTS_PARSER=20(parser)->buffer);=0A+=20=20ts_check_buffer_size=20= (buffer);=0A+=0A+=20=20/*=20Before=20we=20parse,=20catch=20up=20with=20= the=20narrowing=20situation.=20=20*/=0A+=20=20ts_ensure_position_synced=20= (parser);=0A+=0A+=20=20TSTree=20*new_tree=20=3D=20= ts_parser_parse(ts_parser,=20tree,=20input);=0A+=20=20/*=20This=20should=20= be=20very=20rare=20(impossible,=20really):=20it=20only=20happens=0A+=20=20= =20=20=20when=201)=20language=20is=20not=20set=20(impossible=20in=20= Emacs=20because=20the=20user=0A+=20=20=20=20=20has=20to=20supply=20a=20= language=20to=20create=20a=20parser),=202)=20parse=20canceled=0A+=20=20=20= =20=20due=20to=20timeout=20(impossible=20because=20we=20don't=20set=20a=20= timeout),=203)=0A+=20=20=20=20=20parse=20canceled=20due=20to=20= cancellation=20flag=20(impossible=20because=20we=0A+=20=20=20=20=20don't=20= set=20the=20flag).=20=20(See=20comments=20for=20ts_parser_parse=20in=0A+=20= =20=20=20=20tree_sitter/api.h.)=20=20*/=0A+=20=20if=20(new_tree=20=3D=3D=20= NULL)=0A+=20=20=20=20{=0A+=20=20=20=20=20=20Lisp_Object=20buf;=0A+=20=20=20= =20=20=20XSETBUFFER=20(buf,=20buffer);=0A+=20=20=20=20=20=20xsignal1=20= (Qtree_sitter_parse_error,=20buf);=0A+=20=20=20=20}=0A+=0A+=20=20= ts_tree_delete=20(tree);=0A+=20=20XTS_PARSER=20(parser)->tree=20=3D=20= new_tree;=0A+=20=20XTS_PARSER=20(parser)->need_reparse=20=3D=20false;=0A= +}=0A+=0A+/*=20This=20is=20the=20read=20function=20provided=20to=20= tree-sitter=20to=20read=20from=20a=0A+=20=20=20buffer.=20=20It=20reads=20= one=20character=20at=20a=20time=20and=20automatically=20skips=0A+=20=20=20= the=20gap.=20=20*/=0A+const=20char*=0A+ts_read_buffer=20(void=20*parser,=20= uint32_t=20byte_index,=0A+=09=09TSPoint=20position,=20uint32_t=20= *bytes_read)=0A+{=0A+=20=20struct=20buffer=20*buffer=20=3D=0A+=20=20=20=20= XBUFFER=20(((struct=20Lisp_TS_Parser=20*)=20parser)->buffer);=0A+=20=20= ptrdiff_t=20visible_beg=20=3D=20((struct=20Lisp_TS_Parser=20*)=20= parser)->visible_beg;=0A+=20=20ptrdiff_t=20visible_end=20=3D=20((struct=20= Lisp_TS_Parser=20*)=20parser)->visible_end;=0A+=20=20ptrdiff_t=20= byte_pos=20=3D=20byte_index=20+=20visible_beg;=0A+=20=20/*=20We=20will=20= make=20sure=20visible_beg=20=3D=20BUF_BEGV_BYTE=20before=20re-parse=20= (in=0A+=20=20=20=20=20ts_ensure_parsed),=20so=20byte_pos=20will=20never=20= be=20smaller=20than=0A+=20=20=20=20=20BUF_BEG_BYTE.=20=20*/=0A+=20=20= eassert=20(visible_beg=20=3D=20BUF_BEGV_BYTE=20(buffer));=0A+=20=20= eassert=20(visible_end=20=3D=20BUF_ZV_BYTE=20(buffer));=0A+=0A+=20=20/*=20= Read=20one=20character.=20=20Tree-sitter=20wants=20us=20to=20set=20= bytes_read=20to=200=0A+=20=20=20=20=20if=20it=20reads=20to=20the=20end=20= of=20buffer.=20=20It=20doesn't=20say=20what=20it=20wants=0A+=20=20=20=20=20= for=20the=20return=20value=20in=20that=20case,=20so=20we=20just=20give=20= it=20an=20empty=0A+=20=20=20=20=20string.=20=20*/=0A+=20=20char=20*beg;=0A= +=20=20int=20len;=0A+=20=20/*=20This=20function=20could=20run=20from=20a=20= user=20command,=20so=20it=20is=20better=20to=0A+=20=20=20=20=20do=20= nothing=20instead=20of=20raising=20an=20error.=20(It=20was=20a=20pain=20= in=20the=20a**=0A+=20=20=20=20=20to=20decrypt=20mega-if-conditions=20in=20= Emacs=20source,=20so=20I=20wrote=20the=20two=0A+=20=20=20=20=20branches=20= separately.)=20=20*/=0A+=20=20if=20(!BUFFER_LIVE_P=20(buffer))=0A+=20=20=20= =20{=0A+=20=20=20=20=20=20beg=20=3D=20NULL;=0A+=20=20=20=20=20=20len=20=3D= =200;=0A+=20=20=20=20}=0A+=20=20/*=20Reached=20visible=20end-of-buffer,=20= tell=20tree-sitter=20to=20read=20no=20more.=20=20*/=0A+=20=20else=20if=20= (byte_pos=20>=3D=20visible_end)=0A+=20=20=20=20{=0A+=20=20=20=20=20=20= beg=20=3D=20NULL;=0A+=20=20=20=20=20=20len=20=3D=200;=0A+=20=20=20=20}=0A= +=20=20/*=20Normal=20case,=20read=20a=20character.=20=20*/=0A+=20=20else=0A= +=20=20=20=20{=0A+=20=20=20=20=20=20beg=20=3D=20(char=20*)=20= BUF_BYTE_ADDRESS=20(buffer,=20byte_pos);=0A+=20=20=20=20=20=20len=20=3D=20= BYTES_BY_CHAR_HEAD=20((int)=20*beg);=0A+=20=20=20=20}=0A+=20=20= *bytes_read=20=3D=20(uint32_t)=20len;=0A+=20=20return=20beg;=0A+}=0A+=0A= +/***=20Functions=20for=20parser=20and=20node=20object*/=0A+=0A+/*=20= Wrap=20the=20parser=20in=20a=20Lisp_Object=20to=20be=20used=20in=20the=20= Lisp=20machine.=20=20*/=0A+Lisp_Object=0A+make_ts_parser=20(Lisp_Object=20= buffer,=20TSParser=20*parser,=0A+=09=09TSTree=20*tree,=20Lisp_Object=20= language_symbol)=0A+{=0A+=20=20struct=20Lisp_TS_Parser=20*lisp_parser=0A= +=20=20=20=20=3D=20ALLOCATE_PSEUDOVECTOR=0A+=20=20=20=20(struct=20= Lisp_TS_Parser,=20buffer,=20PVEC_TS_PARSER);=0A+=0A+=20=20= lisp_parser->language_symbol=20=3D=20language_symbol;=0A+=20=20= lisp_parser->buffer=20=3D=20buffer;=0A+=20=20lisp_parser->parser=20=3D=20= parser;=0A+=20=20lisp_parser->tree=20=3D=20tree;=0A+=20=20TSInput=20= input=20=3D=20{lisp_parser,=20ts_read_buffer,=20TSInputEncodingUTF8};=0A= +=20=20lisp_parser->input=20=3D=20input;=0A+=20=20= lisp_parser->need_reparse=20=3D=20true;=0A+=20=20= lisp_parser->visible_beg=20=3D=20BUF_BEGV=20(XBUFFER=20(buffer));=0A+=20=20= lisp_parser->visible_end=20=3D=20BUF_ZV=20(XBUFFER=20(buffer));=0A+=20=20= return=20make_lisp_ptr=20(lisp_parser,=20Lisp_Vectorlike);=0A+}=0A+=0A= +/*=20Wrap=20the=20node=20in=20a=20Lisp_Object=20to=20be=20used=20in=20= the=20Lisp=20machine.=20=20*/=0A+Lisp_Object=0A+make_ts_node=20= (Lisp_Object=20parser,=20TSNode=20node)=0A+{=0A+=20=20struct=20= Lisp_TS_Node=20*lisp_node=0A+=20=20=20=20=3D=20ALLOCATE_PSEUDOVECTOR=20= (struct=20Lisp_TS_Node,=20parser,=20PVEC_TS_NODE);=0A+=20=20= lisp_node->parser=20=3D=20parser;=0A+=20=20lisp_node->node=20=3D=20node;=0A= +=20=20lisp_node->timestamp=20=3D=20XTS_PARSER=20(parser)->timestamp;=0A= +=20=20return=20make_lisp_ptr=20(lisp_node,=20Lisp_Vectorlike);=0A+}=0A+=0A= +DEFUN=20("tree-sitter-parser-p",=0A+=20=20=20=20=20=20=20= Ftree_sitter_parser_p,=20Stree_sitter_parser_p,=201,=201,=200,=0A+=20=20=20= =20=20=20=20doc:=20/*=20Return=20t=20if=20OBJECT=20is=20a=20tree-sitter=20= parser.=20=20*/)=0A+=20=20(Lisp_Object=20object)=0A+{=0A+=20=20if=20= (TS_PARSERP=20(object))=0A+=20=20=20=20return=20Qt;=0A+=20=20else=0A+=20=20= =20=20return=20Qnil;=0A+}=0A+=0A+DEFUN=20("tree-sitter-node-p",=0A+=20=20= =20=20=20=20=20Ftree_sitter_node_p,=20Stree_sitter_node_p,=201,=201,=20= 0,=0A+=20=20=20=20=20=20=20doc:=20/*=20Return=20t=20if=20OBJECT=20is=20a=20= tree-sitter=20node.=20=20*/)=0A+=20=20(Lisp_Object=20object)=0A+{=0A+=20=20= if=20(TS_NODEP=20(object))=0A+=20=20=20=20return=20Qt;=0A+=20=20else=0A+=20= =20=20=20return=20Qnil;=0A+}=0A+=0A+DEFUN=20("tree-sitter-node-parser",=0A= +=20=20=20=20=20=20=20Ftree_sitter_node_parser,=20= Stree_sitter_node_parser,=0A+=20=20=20=20=20=20=201,=201,=200,=0A+=20=20=20= =20=20=20=20doc:=20/*=20Return=20the=20parser=20to=20which=20NODE=20= belongs.=20=20*/)=0A+=20=20(Lisp_Object=20node)=0A+{=0A+=20=20= CHECK_TS_NODE=20(node);=0A+=20=20return=20XTS_NODE=20(node)->parser;=0A= +}=0A+=0A+DEFUN=20("tree-sitter-parser-create",=0A+=20=20=20=20=20=20=20= Ftree_sitter_parser_create,=20Stree_sitter_parser_create,=0A+=20=20=20=20= =20=20=202,=202,=200,=0A+=20=20=20=20=20=20=20doc:=20/*=20Create=20and=20= return=20a=20parser=20in=20BUFFER=20for=20LANGUAGE.=0A+=0A+The=20parser=20= is=20automatically=20added=20to=20BUFFER's=0A+`tree-sitter-parser-list'.=20= =20LANGUAGE=20should=20be=20the=20symbol=20of=20a=0A+function=20provided=20= by=20a=20tree-sitter=20language=20dynamic=20module,=20e.g.,=0A= +'tree-sitter-json.=20=20If=20BUFFER=20is=20nil,=20use=20the=20current=20= buffer.=20=20*/)=0A+=20=20(Lisp_Object=20buffer,=20Lisp_Object=20= language)=0A+{=0A+=20=20if=20(NILP=20(buffer))=0A+=20=20=20=20buffer=20=3D= =20Fcurrent_buffer=20();=0A+=0A+=20=20CHECK_BUFFER=20(buffer);=0A+=20=20= CHECK_SYMBOL=20(language);=0A+=20=20ts_check_buffer_size=20(XBUFFER=20= (buffer));=0A+=0A+=20=20ts_initialize=20();=0A+=0A+=20=20TSParser=20= *parser=20=3D=20ts_parser_new=20();=0A+=20=20TSLanguage=20*lang=20=3D=20= ts_load_language=20(language,=20true);=0A+=20=20/*=20We=20check=20= language=20version=20when=20loading=20a=20language,=20so=20this=20should=0A= +=20=20=20=20=20always=20succeed.=20=20*/=0A+=20=20= ts_parser_set_language=20(parser,=20lang);=0A+=0A+=20=20Lisp_Object=20= lisp_parser=0A+=20=20=20=20=3D=20make_ts_parser=20(buffer,=20parser,=20= NULL,=20language);=0A+=0A+=20=20struct=20buffer=20*old_buffer=20=3D=20= current_buffer;=0A+=20=20set_buffer_internal=20(XBUFFER=20(buffer));=0A+=0A= +=20=20Fset=20(Qtree_sitter_parser_list,=0A+=09Fcons=20(lisp_parser,=20= Fsymbol_value=20(Qtree_sitter_parser_list)));=0A+=0A+=20=20= set_buffer_internal=20(old_buffer);=0A+=20=20return=20lisp_parser;=0A+}=0A= +=0A+DEFUN=20("tree-sitter-parser-buffer",=0A+=20=20=20=20=20=20=20= Ftree_sitter_parser_buffer,=20Stree_sitter_parser_buffer,=0A+=20=20=20=20= =20=20=201,=201,=200,=0A+=20=20=20=20=20=20=20doc:=20/*=20Return=20the=20= buffer=20of=20PARSER.=20=20*/)=0A+=20=20(Lisp_Object=20parser)=0A+{=0A+=20= =20CHECK_TS_PARSER=20(parser);=0A+=20=20Lisp_Object=20buf;=0A+=20=20= XSETBUFFER=20(buf,=20XBUFFER=20(XTS_PARSER=20(parser)->buffer));=0A+=20=20= return=20buf;=0A+}=0A+=0A+DEFUN=20("tree-sitter-parser-language",=0A+=20=20= =20=20=20=20=20Ftree_sitter_parser_language,=20= Stree_sitter_parser_language,=0A+=20=20=20=20=20=20=201,=201,=200,=0A+=20= =20=20=20=20=20=20doc:=20/*=20Return=20parser's=20language=20symbol.=0A= +This=20symbol=20is=20the=20one=20used=20to=20create=20the=20parser.=20=20= */)=0A+=20=20(Lisp_Object=20parser)=0A+{=0A+=20=20CHECK_TS_PARSER=20= (parser);=0A+=20=20return=20XTS_PARSER=20(parser)->language_symbol;=0A+}=0A= +=0A+/***=20Parser=20API=20*/=0A+=0A+DEFUN=20= ("tree-sitter-parser-root-node",=0A+=20=20=20=20=20=20=20= Ftree_sitter_parser_root_node,=20Stree_sitter_parser_root_node,=0A+=20=20= =20=20=20=20=201,=201,=200,=0A+=20=20=20=20=20=20=20doc:=20/*=20Return=20= the=20root=20node=20of=20PARSER.=20=20*/)=0A+=20=20(Lisp_Object=20= parser)=0A+{=0A+=20=20CHECK_TS_PARSER=20(parser);=0A+=20=20= ts_ensure_parsed=20(parser);=0A+=20=20TSNode=20root_node=20=3D=20= ts_tree_root_node=20(XTS_PARSER=20(parser)->tree);=0A+=20=20return=20= make_ts_node=20(parser,=20root_node);=0A+}=0A+=0A+/*=20Checks=20that=20= the=20RANGES=20argument=20of=0A+=20=20=20= tree-sitter-parser-set-included-ranges=20is=20valid.=20=20*/=0A+void=0A= +ts_check_range_argument=20(Lisp_Object=20ranges)=0A+{=0A+=20=20= EMACS_INT=20last_point=20=3D=201;=0A+=20=20for=20(Lisp_Object=20tail=20=3D= =20ranges;=0A+=20=20=20=20=20=20=20!NILP=20(tail);=20tail=20=3D=20XCDR=20= (tail))=0A+=20=20=20=20{=0A+=20=20=20=20=20=20CHECK_CONS=20(tail);=0A+=20= =20=20=20=20=20Lisp_Object=20range=20=3D=20XCAR=20(tail);=0A+=20=20=20=20= =20=20CHECK_CONS=20(range);=0A+=20=20=20=20=20=20CHECK_FIXNUM=20(XCAR=20= (range));=0A+=20=20=20=20=20=20CHECK_FIXNUM=20(XCDR=20(range));=0A+=20=20= =20=20=20=20EMACS_INT=20beg=20=3D=20XFIXNUM=20(XCAR=20(range));=0A+=20=20= =20=20=20=20EMACS_INT=20end=20=3D=20XFIXNUM=20(XCDR=20(range));=0A+=20=20= =20=20=20=20/*=20TODO:=20Maybe=20we=20should=20check=20for=20= point-min/max,=20too?=20=20*/=0A+=20=20=20=20=20=20if=20(!(last_point=20= <=3D=20beg=20&&=20beg=20<=3D=20end))=0A+=09xsignal2=20= (Qtree_sitter_range_invalid,=0A+=09=09=20=20build_pure_c_string=0A+=09=09= =20=20("RANGE=20is=20either=20overlapping=20or=20out-of-order"),=0A+=09=09= =20=20ranges);=0A+=20=20=20=20=20=20last_point=20=3D=20end;=0A+=20=20=20=20= }=0A+}=0A+=0A+DEFUN=20("tree-sitter-parser-set-included-ranges",=0A+=20=20= =20=20=20=20=20Ftree_sitter_parser_set_included_ranges,=0A+=20=20=20=20=20= =20=20Stree_sitter_parser_set_included_ranges,=0A+=20=20=20=20=20=20=20= 2,=202,=200,=0A+=20=20=20=20=20=20=20doc:=20/*=20Limit=20PARSER=20to=20= RANGES.=0A+=0A+RANGES=20is=20a=20list=20of=20(BEG=20.=20END),=20each=20= (BEG=20.=20END)=20confines=20a=20range=20in=0A+which=20the=20parser=20= should=20operate=20in.=20=20Each=20range=20must=20not=20overlap,=20and=0A= +each=20range=20should=20come=20in=20order.=20=20Signal=20= `tree-sitter-set-range-error'=0A+if=20the=20argument=20is=20invalid,=20= or=20something=20else=20went=20wrong.=20=20If=20RANGES=0A+is=20nil,=20= set=20PARSER=20to=20parse=20the=20whole=20buffer.=20=20*/)=0A+=20=20= (Lisp_Object=20parser,=20Lisp_Object=20ranges)=0A+{=0A+=20=20= CHECK_TS_PARSER=20(parser);=0A+=20=20CHECK_CONS=20(ranges);=0A+=20=20= ts_check_range_argument=20(ranges);=0A+=0A+=20=20/*=20Before=20we=20= parse,=20catch=20up=20with=20narrowing/widening.=20=20*/=0A+=20=20= ts_ensure_position_synced=20(parser);=0A+=0A+=20=20bool=20success;=0A+=20= =20if=20(NILP=20(ranges))=0A+=20=20=20=20{=0A+=20=20=20=20=20=20/*=20If=20= RANGES=20is=20nil,=20make=20parser=20to=20parse=20the=20whole=20= document.=0A+=09=20To=20do=20that=20we=20give=20tree-sitter=20a=200=20= length,=20the=20range=20is=20a=0A+=09=20dummy.=20=20*/=0A+=20=20=20=20=20= =20TSRange=20ts_range=20=3D=20{0,=200,=200,=200};=0A+=20=20=20=20=20=20= success=20=3D=20ts_parser_set_included_ranges=0A+=09(XTS_PARSER=20= (parser)->parser,=20&ts_range=20,=200);=0A+=20=20=20=20}=0A+=20=20else=0A= +=20=20=20=20{=0A+=20=20=20=20=20=20/*=20Set=20ranges=20for=20PARSER.=20=20= */=0A+=20=20=20=20=20=20ptrdiff_t=20len=20=3D=20list_length=20(ranges);=0A= +=20=20=20=20=20=20TSRange=20*ts_ranges=20=3D=20malloc=20= (sizeof(TSRange)=20*=20len);=0A+=20=20=20=20=20=20struct=20buffer=20= *buffer=20=3D=20XBUFFER=20(XTS_PARSER=20(parser)->buffer);=0A+=0A+=20=20=20= =20=20=20for=20(int=20idx=3D0;=20!NILP=20(ranges);=20idx++,=20ranges=20=3D= =20XCDR=20(ranges))=0A+=09{=0A+=09=20=20Lisp_Object=20range=20=3D=20XCAR=20= (ranges);=0A+=09=20=20struct=20buffer=20*buffer=20=3D=20XBUFFER=20= (XTS_PARSER=20(parser)->buffer);=0A+=0A+=09=20=20EMACS_INT=20beg_byte=20= =3D=20buf_charpos_to_bytepos=0A+=09=20=20=20=20(buffer,=20XFIXNUM=20= (XCAR=20(range)));=0A+=09=20=20EMACS_INT=20end_byte=20=3D=20= buf_charpos_to_bytepos=0A+=09=20=20=20=20(buffer,=20XFIXNUM=20(XCDR=20= (range)));=0A+=09=20=20/*=20We=20don't=20care=20about=20start=20and=20= end=20points,=20put=20in=20dummy=0A+=09=20=20=20=20=20value.=20=20*/=0A+=09= =20=20TSRange=20rg=20=3D=20{{0,0},=20{0,0},=0A+=09=09=09(uint32_t)=20= beg_byte=20-=20BUF_BEGV_BYTE=20(buffer),=0A+=09=09=09(uint32_t)=20= end_byte=20-=20BUF_BEGV_BYTE=20(buffer)};=0A+=09=20=20ts_ranges[idx]=20=3D= =20rg;=0A+=09}=0A+=20=20=20=20=20=20success=20=3D=20= ts_parser_set_included_ranges=0A+=09(XTS_PARSER=20(parser)->parser,=20= ts_ranges,=20(uint32_t)=20len);=0A+=20=20=20=20=20=20/*=20Although=20= XFIXNUM=20could=20signal,=20it=20should=20be=20impossible=0A+=09=20= because=20we=20have=20checked=20the=20input=20by=20= ts_check_range_argument.=0A+=09=20So=20there=20is=20no=20need=20for=20= unwind-protect.=20=20*/=0A+=20=20=20=20=20=20free=20(ts_ranges);=0A+=20=20= =20=20}=0A+=0A+=20=20if=20(!success)=0A+=20=20=20=20xsignal2=20= (Qtree_sitter_range_invalid,=0A+=09=20=20=20=20=20=20build_pure_c_string=0A= +=09=20=20=20=20=20=20("Something=20went=20wrong=20when=20setting=20= ranges"),=0A+=09=20=20=20=20=20=20ranges);=0A+=0A+=20=20XTS_PARSER=20= (parser)->need_reparse=20=3D=20true;=0A+=20=20return=20Qnil;=0A+}=0A+=0A= +DEFUN=20("tree-sitter-parser-included-ranges",=0A+=20=20=20=20=20=20=20= Ftree_sitter_parser_included_ranges,=0A+=20=20=20=20=20=20=20= Stree_sitter_parser_included_ranges,=0A+=20=20=20=20=20=20=201,=201,=20= 0,=0A+=20=20=20=20=20=20=20doc:=20/*=20Return=20the=20ranges=20set=20for=20= PARSER.=0A+See=20`tree-sitter-parser-set-ranges'.=20=20If=20no=20range=20= is=20set,=20return=0A+nil.=20=20*/)=0A+=20=20(Lisp_Object=20parser)=0A+{=0A= +=20=20CHECK_TS_PARSER=20(parser);=0A+=20=20uint32_t=20len;=0A+=20=20= const=20TSRange=20*ranges=20=3D=20ts_parser_included_ranges=0A+=20=20=20=20= (XTS_PARSER=20(parser)->parser,=20&len);=0A+=20=20if=20(len=20=3D=3D=20= 0)=0A+=20=20=20=20return=20Qnil;=0A+=20=20struct=20buffer=20*buffer=20=3D=20= XBUFFER=20(XTS_PARSER=20(parser)->buffer);=0A+=0A+=20=20Lisp_Object=20= list=20=3D=20Qnil;=0A+=20=20for=20(int=20idx=3D0;=20idx=20<=20len;=20= idx++)=0A+=20=20=20=20{=0A+=20=20=20=20=20=20TSRange=20range=20=3D=20= ranges[idx];=0A+=20=20=20=20=20=20uint32_t=20beg_byte=20=3D=20= range.start_byte=20+=20BUF_BEGV_BYTE=20(buffer);=0A+=20=20=20=20=20=20= uint32_t=20end_byte=20=3D=20range.end_byte=20+=20BUF_BEGV_BYTE=20= (buffer);=0A+=0A+=20=20=20=20=20=20Lisp_Object=20lisp_range=20=3D=0A+=09= Fcons=20(make_fixnum=20(buf_bytepos_to_charpos=20(buffer,=20beg_byte))=20= ,=0A+=09=20=20=20=20=20=20=20make_fixnum=20(buf_bytepos_to_charpos=20= (buffer,=20end_byte)));=0A+=20=20=20=20=20=20list=20=3D=20Fcons=20= (lisp_range,=20list);=0A+=20=20=20=20}=0A+=20=20return=20Fnreverse=20= (list);=0A+}=0A+=0A+/***=20Node=20API=20=20*/=0A+=0A+/*=20Check=20that=20= OBJ=20is=20a=20positive=20integer=20and=20signal=20an=20error=20if=0A+=20= =20=20otherwise.=20*/=0A+static=20void=0A+ts_check_positive_integer=20= (Lisp_Object=20obj)=0A+{=0A+=20=20CHECK_INTEGER=20(obj);=0A+=20=20if=20= (XFIXNUM=20(obj)=20<=200)=0A+=20=20=20=20xsignal1=20(Qargs_out_of_range,=20= obj);=0A+}=0A+=0A+static=20void=0A+ts_check_node=20(Lisp_Object=20obj)=0A= +{=0A+=20=20CHECK_TS_NODE=20(obj);=0A+=20=20Lisp_Object=20lisp_parser=20= =3D=20XTS_NODE=20(obj)->parser;=0A+=20=20if=20(XTS_NODE=20= (obj)->timestamp=20!=3D=0A+=20=20=20=20=20=20XTS_PARSER=20= (lisp_parser)->timestamp)=0A+=20=20=20=20xsignal1=20= (Qtree_sitter_node_outdated,=20obj);=0A+}=0A+=0A+DEFUN=20= ("tree-sitter-node-type",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_type,=20Stree_sitter_node_type,=201,=201,=200,=0A+=20=20= =20=20=20=20=20doc:=20/*=20Return=20the=20NODE's=20type=20as=20a=20= string.=0A+If=20NODE=20is=20nil,=20return=20nil.=20=20*/)=0A+=20=20= (Lisp_Object=20node)=0A+{=0A+=20=20if=20(NILP=20(node))=20return=20Qnil;=0A= +=20=20ts_check_node=20(node);=0A+=20=20TSNode=20ts_node=20=3D=20= XTS_NODE=20(node)->node;=0A+=20=20const=20char=20*type=20=3D=20= ts_node_type=20(ts_node);=0A+=20=20return=20build_string=20(type);=0A+}=0A= +=0A+DEFUN=20("tree-sitter-node-start",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_start,=20Stree_sitter_node_start,=201,=201,=200,=0A+=20= =20=20=20=20=20=20doc:=20/*=20Return=20the=20NODE's=20start=20position.=0A= +If=20NODE=20is=20nil,=20return=20nil.=20=20*/)=0A+=20=20(Lisp_Object=20= node)=0A+{=0A+=20=20if=20(NILP=20(node))=20return=20Qnil;=0A+=20=20= ts_check_node=20(node);=0A+=20=20TSNode=20ts_node=20=3D=20XTS_NODE=20= (node)->node;=0A+=20=20ptrdiff_t=20visible_beg=20=3D=0A+=20=20=20=20= XTS_PARSER=20(XTS_NODE=20(node)->parser)->visible_beg;=0A+=20=20uint32_t=20= start_byte_offset=20=3D=20ts_node_start_byte=20(ts_node);=0A+=20=20= struct=20buffer=20*buffer=20=3D=0A+=20=20=20=20XBUFFER=20(XTS_PARSER=20= (XTS_NODE=20(node)->parser)->buffer);=0A+=20=20ptrdiff_t=20start_pos=20=3D= =20buf_bytepos_to_charpos=0A+=20=20=20=20(buffer,=20start_byte_offset=20= +=20visible_beg);=0A+=20=20return=20make_fixnum=20(start_pos);=0A+}=0A+=0A= +DEFUN=20("tree-sitter-node-end",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_end,=20Stree_sitter_node_end,=201,=201,=200,=0A+=20=20=20= =20=20=20=20doc:=20/*=20Return=20the=20NODE's=20end=20position.=0A+If=20= NODE=20is=20nil,=20return=20nil.=20=20*/)=0A+=20=20(Lisp_Object=20node)=0A= +{=0A+=20=20if=20(NILP=20(node))=20return=20Qnil;=0A+=20=20ts_check_node=20= (node);=0A+=20=20TSNode=20ts_node=20=3D=20XTS_NODE=20(node)->node;=0A+=20= =20ptrdiff_t=20visible_beg=20=3D=0A+=20=20=20=20XTS_PARSER=20(XTS_NODE=20= (node)->parser)->visible_beg;=0A+=20=20uint32_t=20end_byte_offset=20=3D=20= ts_node_end_byte=20(ts_node);=0A+=20=20struct=20buffer=20*buffer=20=3D=0A= +=20=20=20=20XBUFFER=20(XTS_PARSER=20(XTS_NODE=20= (node)->parser)->buffer);=0A+=20=20ptrdiff_t=20end_pos=20=3D=20= buf_bytepos_to_charpos=0A+=20=20=20=20(buffer,=20end_byte_offset=20+=20= visible_beg);=0A+=20=20return=20make_fixnum=20(end_pos);=0A+}=0A+=0A= +DEFUN=20("tree-sitter-node-string",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_string,=20Stree_sitter_node_string,=201,=201,=200,=0A+=20= =20=20=20=20=20=20doc:=20/*=20Return=20the=20string=20representation=20= of=20NODE.=0A+If=20NODE=20is=20nil,=20return=20nil.=20=20*/)=0A+=20=20= (Lisp_Object=20node)=0A+{=0A+=20=20if=20(NILP=20(node))=20return=20Qnil;=0A= +=20=20ts_check_node=20(node);=0A+=20=20TSNode=20ts_node=20=3D=20= XTS_NODE=20(node)->node;=0A+=20=20char=20*string=20=3D=20ts_node_string=20= (ts_node);=0A+=20=20return=20make_string=20(string,=20strlen=20= (string));=0A+}=0A+=0A+DEFUN=20("tree-sitter-node-parent",=0A+=20=20=20=20= =20=20=20Ftree_sitter_node_parent,=20Stree_sitter_node_parent,=201,=201,=20= 0,=0A+=20=20=20=20=20=20=20doc:=20/*=20Return=20the=20immediate=20parent=20= of=20NODE.=0A+Return=20nil=20if=20there=20isn't=20any.=20=20If=20NODE=20= is=20nil,=20return=20nil.=20=20*/)=0A+=20=20(Lisp_Object=20node)=0A+{=0A= +=20=20if=20(NILP=20(node))=20return=20Qnil;=0A+=20=20ts_check_node=20= (node);=0A+=20=20TSNode=20ts_node=20=3D=20XTS_NODE=20(node)->node;=0A+=20= =20TSNode=20parent=20=3D=20ts_node_parent=20(ts_node);=0A+=0A+=20=20if=20= (ts_node_is_null=20(parent))=0A+=20=20=20=20return=20Qnil;=0A+=0A+=20=20= return=20make_ts_node=20(XTS_NODE=20(node)->parser,=20parent);=0A+}=0A+=0A= +DEFUN=20("tree-sitter-node-child",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_child,=20Stree_sitter_node_child,=202,=203,=200,=0A+=20= =20=20=20=20=20=20doc:=20/*=20Return=20the=20Nth=20child=20of=20NODE.=0A= +=0A+Return=20nil=20if=20there=20isn't=20any.=20=20If=20NAMED=20is=20= non-nil,=20look=20for=20named=0A+child=20only.=20=20NAMED=20defaults=20= to=20nil.=20=20If=20NODE=20is=20nil,=20return=20nil.=20=20*/)=0A+=20=20= (Lisp_Object=20node,=20Lisp_Object=20n,=20Lisp_Object=20named)=0A+{=0A+=20= =20if=20(NILP=20(node))=20return=20Qnil;=0A+=20=20ts_check_node=20= (node);=0A+=20=20ts_check_positive_integer=20(n);=0A+=20=20EMACS_INT=20= idx=20=3D=20XFIXNUM=20(n);=0A+=20=20if=20(idx=20>=20UINT32_MAX)=20= xsignal1=20(Qargs_out_of_range,=20n);=0A+=20=20TSNode=20ts_node=20=3D=20= XTS_NODE=20(node)->node;=0A+=20=20TSNode=20child;=0A+=20=20if=20(NILP=20= (named))=0A+=20=20=20=20child=20=3D=20ts_node_child=20(ts_node,=20= (uint32_t)=20idx);=0A+=20=20else=0A+=20=20=20=20child=20=3D=20= ts_node_named_child=20(ts_node,=20(uint32_t)=20idx);=0A+=0A+=20=20if=20= (ts_node_is_null=20(child))=0A+=20=20=20=20return=20Qnil;=0A+=0A+=20=20= return=20make_ts_node=20(XTS_NODE=20(node)->parser,=20child);=0A+}=0A+=0A= +DEFUN=20("tree-sitter-node-check",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_check,=20Stree_sitter_node_check,=202,=202,=200,=0A+=20= =20=20=20=20=20=20doc:=20/*=20Return=20non-nil=20if=20NODE=20has=20= PROPERTY,=20nil=20otherwise.=0A+=0A+PROPERTY=20could=20be=20'named,=20= 'missing,=20'extra,=20'has-changes,=20'has-error.=0A+Named=20nodes=20= correspond=20to=20named=20rules=20in=20the=20language=20definition,=0A= +whereas=20"anonymous"=20nodes=20correspond=20to=20string=20literals=20= in=20the=0A+language=20definition.=0A+=0A+Missing=20nodes=20are=20= inserted=20by=20the=20parser=20in=20order=20to=20recover=20from=0A= +certain=20kinds=20of=20syntax=20errors,=20i.e.,=20should=20be=20there=20= but=20not=20there.=0A+=0A+Extra=20nodes=20represent=20things=20like=20= comments,=20which=20are=20not=20required=20the=0A+language=20definition,=20= but=20can=20appear=20anywhere.=0A+=0A+A=20node=20"has=20changes"=20if=20= the=20buffer=20changed=20since=20the=20node=20is=0A+created.=20(Don't=20= forget=20the=20"s"=20at=20the=20end=20of=20'has-changes.)=0A+=0A+A=20= node=20"has=20error"=20if=20itself=20is=20a=20syntax=20error=20or=20= contains=20any=20syntax=0A+errors.=20=20*/)=0A+=20=20(Lisp_Object=20= node,=20Lisp_Object=20property)=0A+{=0A+=20=20if=20(NILP=20(node))=20= return=20Qnil;=0A+=20=20ts_check_node=20(node);=0A+=20=20CHECK_SYMBOL=20= (property);=0A+=20=20TSNode=20ts_node=20=3D=20XTS_NODE=20(node)->node;=0A= +=20=20bool=20result;=0A+=20=20if=20(EQ=20(property,=20Qnamed))=0A+=20=20= =20=20result=20=3D=20ts_node_is_named=20(ts_node);=0A+=20=20else=20if=20= (EQ=20(property,=20Qmissing))=0A+=20=20=20=20result=20=3D=20= ts_node_is_missing=20(ts_node);=0A+=20=20else=20if=20(EQ=20(property,=20= Qextra))=0A+=20=20=20=20result=20=3D=20ts_node_is_extra=20(ts_node);=0A+=20= =20else=20if=20(EQ=20(property,=20Qhas_error))=0A+=20=20=20=20result=20=3D= =20ts_node_has_error=20(ts_node);=0A+=20=20else=20if=20(EQ=20(property,=20= Qhas_changes))=0A+=20=20=20=20result=20=3D=20ts_node_has_changes=20= (ts_node);=0A+=20=20else=0A+=20=20=20=20signal_error=20("Expecting=20= 'named,=20'missing,=20'extra,=20'has-changes=20or=20'has-error,=20got",=0A= +=09=09=20=20property);=0A+=20=20return=20result=20?=20Qt=20:=20Qnil;=0A= +}=0A+=0A+DEFUN=20("tree-sitter-node-field-name-for-child",=0A+=20=20=20=20= =20=20=20Ftree_sitter_node_field_name_for_child,=0A+=20=20=20=20=20=20=20= Stree_sitter_node_field_name_for_child,=202,=202,=200,=0A+=20=20=20=20=20= =20=20doc:=20/*=20Return=20the=20field=20name=20of=20the=20Nth=20child=20= of=20NODE.=0A+=0A+Return=20nil=20if=20there=20isn't=20any=20child=20or=20= no=20field=20is=20found.=0A+If=20NODE=20is=20nil,=20return=20nil.=20=20= */)=0A+=20=20(Lisp_Object=20node,=20Lisp_Object=20n)=0A+{=0A+=20=20if=20= (NILP=20(node))=20return=20Qnil;=0A+=20=20ts_check_node=20(node);=0A+=20=20= ts_check_positive_integer=20(n);=0A+=20=20EMACS_INT=20idx=20=3D=20= XFIXNUM=20(n);=0A+=20=20if=20(idx=20>=20UINT32_MAX)=20xsignal1=20= (Qargs_out_of_range,=20n);=0A+=20=20TSNode=20ts_node=20=3D=20XTS_NODE=20= (node)->node;=0A+=20=20const=20char=20*name=0A+=20=20=20=20=3D=20= ts_node_field_name_for_child=20(ts_node,=20(uint32_t)=20idx);=0A+=0A+=20=20= if=20(name=20=3D=3D=20NULL)=0A+=20=20=20=20return=20Qnil;=0A+=0A+=20=20= return=20make_string=20(name,=20strlen=20(name));=0A+}=0A+=0A+DEFUN=20= ("tree-sitter-node-child-count",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_child_count,=0A+=20=20=20=20=20=20=20= Stree_sitter_node_child_count,=201,=202,=200,=0A+=20=20=20=20=20=20=20= doc:=20/*=20Return=20the=20number=20of=20children=20of=20NODE.=0A+=0A+If=20= NAMED=20is=20non-nil,=20count=20named=20child=20only.=20=20NAMED=20= defaults=20to=0A+nil.=20=20If=20NODE=20is=20nil,=20return=20nil.=20=20= */)=0A+=20=20(Lisp_Object=20node,=20Lisp_Object=20named)=0A+{=0A+=20=20= if=20(NILP=20(node))=20return=20Qnil;=0A+=20=20ts_check_node=20(node);=0A= +=20=20TSNode=20ts_node=20=3D=20XTS_NODE=20(node)->node;=0A+=20=20= uint32_t=20count;=0A+=20=20if=20(NILP=20(named))=0A+=20=20=20=20count=20= =3D=20ts_node_child_count=20(ts_node);=0A+=20=20else=0A+=20=20=20=20= count=20=3D=20ts_node_named_child_count=20(ts_node);=0A+=20=20return=20= make_fixnum=20(count);=0A+}=0A+=0A+DEFUN=20= ("tree-sitter-node-child-by-field-name",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_child_by_field_name,=0A+=20=20=20=20=20=20=20= Stree_sitter_node_child_by_field_name,=202,=202,=200,=0A+=20=20=20=20=20=20= =20doc:=20/*=20Return=20the=20child=20of=20NODE=20with=20FIELD-NAME.=0A= +Return=20nil=20if=20there=20isn't=20any.=20=20If=20NODE=20is=20nil,=20= return=20nil.=20=20*/)=0A+=20=20(Lisp_Object=20node,=20Lisp_Object=20= field_name)=0A+{=0A+=20=20if=20(NILP=20(node))=20return=20Qnil;=0A+=20=20= ts_check_node=20(node);=0A+=20=20CHECK_STRING=20(field_name);=0A+=20=20= char=20*name_str=20=3D=20SSDATA=20(field_name);=0A+=20=20TSNode=20= ts_node=20=3D=20XTS_NODE=20(node)->node;=0A+=20=20TSNode=20child=0A+=20=20= =20=20=3D=20ts_node_child_by_field_name=20(ts_node,=20name_str,=20strlen=20= (name_str));=0A+=0A+=20=20if=20(ts_node_is_null(child))=0A+=20=20=20=20= return=20Qnil;=0A+=0A+=20=20return=20make_ts_node(XTS_NODE=20= (node)->parser,=20child);=0A+}=0A+=0A+DEFUN=20= ("tree-sitter-node-next-sibling",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_next_sibling,=0A+=20=20=20=20=20=20=20= Stree_sitter_node_next_sibling,=201,=202,=200,=0A+=20=20=20=20=20=20=20= doc:=20/*=20Return=20the=20next=20sibling=20of=20NODE.=0A+=0A+Return=20= nil=20if=20there=20isn't=20any.=20=20If=20NAMED=20is=20non-nil,=20look=20= for=20named=0A+child=20only.=20=20NAMED=20defaults=20to=20nil.=20=20If=20= NODE=20is=20nil,=20return=20nil.=20=20*/)=0A+=20=20(Lisp_Object=20node,=20= Lisp_Object=20named)=0A+{=0A+=20=20if=20(NILP=20(node))=20return=20Qnil;=0A= +=20=20ts_check_node=20(node);=0A+=20=20TSNode=20ts_node=20=3D=20= XTS_NODE=20(node)->node;=0A+=20=20TSNode=20sibling;=0A+=20=20if=20(NILP=20= (named))=0A+=20=20=20=20sibling=20=3D=20ts_node_next_sibling=20= (ts_node);=0A+=20=20else=0A+=20=20=20=20sibling=20=3D=20= ts_node_next_named_sibling=20(ts_node);=0A+=0A+=20=20if=20= (ts_node_is_null(sibling))=0A+=20=20=20=20return=20Qnil;=0A+=0A+=20=20= return=20make_ts_node(XTS_NODE=20(node)->parser,=20sibling);=0A+}=0A+=0A= +DEFUN=20("tree-sitter-node-prev-sibling",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_prev_sibling,=0A+=20=20=20=20=20=20=20= Stree_sitter_node_prev_sibling,=201,=202,=200,=0A+=20=20=20=20=20=20=20= doc:=20/*=20Return=20the=20previous=20sibling=20of=20NODE.=0A+=0A+Return=20= nil=20if=20there=20isn't=20any.=20=20If=20NAMED=20is=20non-nil,=20look=20= for=20named=0A+child=20only.=20=20NAMED=20defaults=20to=20nil.=20=20If=20= NODE=20is=20nil,=20return=20nil.=20=20*/)=0A+=20=20(Lisp_Object=20node,=20= Lisp_Object=20named)=0A+{=0A+=20=20if=20(NILP=20(node))=20return=20Qnil;=0A= +=20=20ts_check_node=20(node);=0A+=20=20TSNode=20ts_node=20=3D=20= XTS_NODE=20(node)->node;=0A+=20=20TSNode=20sibling;=0A+=0A+=20=20if=20= (NILP=20(named))=0A+=20=20=20=20sibling=20=3D=20ts_node_prev_sibling=20= (ts_node);=0A+=20=20else=0A+=20=20=20=20sibling=20=3D=20= ts_node_prev_named_sibling=20(ts_node);=0A+=0A+=20=20if=20= (ts_node_is_null(sibling))=0A+=20=20=20=20return=20Qnil;=0A+=0A+=20=20= return=20make_ts_node(XTS_NODE=20(node)->parser,=20sibling);=0A+}=0A+=0A= +DEFUN=20("tree-sitter-node-first-child-for-pos",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_first_child_for_pos,=0A+=20=20=20=20=20=20=20= Stree_sitter_node_first_child_for_pos,=202,=203,=200,=0A+=20=20=20=20=20=20= =20doc:=20/*=20Return=20the=20first=20child=20of=20NODE=20on=20POS.=0A+=0A= +Specifically,=20return=20the=20first=20child=20that=20extends=20beyond=20= POS.=20=20POS=20is=0A+a=20position=20in=20the=20buffer.=20=20Return=20= nil=20if=20there=20isn't=20any.=20=20If=20NAMED=20is=0A+non-nil,=20look=20= for=20named=20child=20only.=20=20NAMED=20defaults=20to=20nil.=20=20Note=20= that=0A+this=20function=20returns=20an=20immediate=20child,=20not=20the=20= smallest=0A+(grand)child.=20=20If=20NODE=20is=20nil,=20return=20nil.=20=20= */)=0A+=20=20(Lisp_Object=20node,=20Lisp_Object=20pos,=20Lisp_Object=20= named)=0A+{=0A+=20=20if=20(NILP=20(node))=20return=20Qnil;=0A+=20=20= ts_check_node=20(node);=0A+=20=20ts_check_positive_integer=20(pos);=0A+=0A= +=20=20struct=20buffer=20*buf=20=3D=0A+=20=20=20=20XBUFFER=20(XTS_PARSER=20= (XTS_NODE=20(node)->parser)->buffer);=0A+=20=20ptrdiff_t=20visible_beg=20= =3D=0A+=20=20=20=20XTS_PARSER=20(XTS_NODE=20= (node)->parser)->visible_beg;=0A+=20=20ptrdiff_t=20byte_pos=20=3D=20= buf_charpos_to_bytepos=20(buf,=20XFIXNUM=20(pos));=0A+=0A+=20=20if=20= (byte_pos=20<=20BUF_BEGV_BYTE=20(buf)=20||=20byte_pos=20>=20BUF_ZV_BYTE=20= (buf))=0A+=20=20=20=20xsignal1=20(Qargs_out_of_range,=20pos);=0A+=0A+=20=20= TSNode=20ts_node=20=3D=20XTS_NODE=20(node)->node;=0A+=20=20TSNode=20= child;=0A+=20=20if=20(NILP=20(named))=0A+=20=20=20=20child=20=3D=20= ts_node_first_child_for_byte=0A+=20=20=20=20=20=20(ts_node,=20byte_pos=20= -=20visible_beg);=0A+=20=20else=0A+=20=20=20=20child=20=3D=20= ts_node_first_named_child_for_byte=0A+=20=20=20=20=20=20(ts_node,=20= byte_pos=20-=20visible_beg);=0A+=0A+=20=20if=20(ts_node_is_null=20= (child))=0A+=20=20=20=20return=20Qnil;=0A+=0A+=20=20return=20= make_ts_node=20(XTS_NODE=20(node)->parser,=20child);=0A+}=0A+=0A+DEFUN=20= ("tree-sitter-node-descendant-for-range",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_descendant_for_range,=0A+=20=20=20=20=20=20=20= Stree_sitter_node_descendant_for_range,=203,=204,=200,=0A+=20=20=20=20=20= =20=20doc:=20/*=20Return=20the=20smallest=20node=20that=20covers=20BEG=20= to=20END.=0A+=0A+The=20returned=20node=20is=20a=20descendant=20of=20= NODE.=20=20POS=20is=20a=20position.=20=20Return=0A+nil=20if=20there=20= isn't=20any.=20=20If=20NAMED=20is=20non-nil,=20look=20for=20named=20= child=0A+only.=20=20NAMED=20defaults=20to=20nil.=20=20If=20NODE=20is=20= nil,=20return=20nil.=20=20*/)=0A+=20=20(Lisp_Object=20node,=20= Lisp_Object=20beg,=20Lisp_Object=20end,=20Lisp_Object=20named)=0A+{=0A+=20= =20if=20(NILP=20(node))=20return=20Qnil;=0A+=20=20ts_check_node=20= (node);=0A+=20=20CHECK_INTEGER=20(beg);=0A+=20=20CHECK_INTEGER=20(end);=0A= +=0A+=20=20struct=20buffer=20*buf=20=3D=0A+=20=20=20=20XBUFFER=20= (XTS_PARSER=20(XTS_NODE=20(node)->parser)->buffer);=0A+=20=20ptrdiff_t=20= visible_beg=20=3D=0A+=20=20=20=20XTS_PARSER=20(XTS_NODE=20= (node)->parser)->visible_beg;=0A+=20=20ptrdiff_t=20byte_beg=20=3D=20= buf_charpos_to_bytepos=20(buf,=20XFIXNUM=20(beg));=0A+=20=20ptrdiff_t=20= byte_end=20=3D=20buf_charpos_to_bytepos=20(buf,=20XFIXNUM=20(end));=0A+=0A= +=20=20/*=20Checks=20for=20BUFFER_BEG=20<=3D=20BEG=20<=3D=20END=20<=3D=20= BUFFER_END.=20=20*/=0A+=20=20if=20(!(BUF_BEGV_BYTE=20(buf)=20<=3D=20= byte_beg=0A+=09&&=20byte_beg=20<=3D=20byte_end=0A+=09&&=20byte_end=20<=3D=20= BUF_ZV_BYTE=20(buf)))=0A+=20=20=20=20xsignal2=20(Qargs_out_of_range,=20= beg,=20end);=0A+=0A+=20=20TSNode=20ts_node=20=3D=20XTS_NODE=20= (node)->node;=0A+=20=20TSNode=20child;=0A+=20=20if=20(NILP=20(named))=0A= +=20=20=20=20child=20=3D=20ts_node_descendant_for_byte_range=0A+=20=20=20= =20=20=20(ts_node,=20byte_beg=20-=20visible_beg=20,=20byte_end=20-=20= visible_beg);=0A+=20=20else=0A+=20=20=20=20child=20=3D=20= ts_node_named_descendant_for_byte_range=0A+=20=20=20=20=20=20(ts_node,=20= byte_beg=20-=20visible_beg,=20byte_end=20-=20visible_beg);=0A+=0A+=20=20= if=20(ts_node_is_null=20(child))=0A+=20=20=20=20return=20Qnil;=0A+=0A+=20= =20return=20make_ts_node=20(XTS_NODE=20(node)->parser,=20child);=0A+}=0A= +=0A+DEFUN=20("tree-sitter-node-eq",=0A+=20=20=20=20=20=20=20= Ftree_sitter_node_eq,=0A+=20=20=20=20=20=20=20Stree_sitter_node_eq,=202,=20= 2,=200,=0A+=20=20=20=20=20=20=20doc:=20/*=20Return=20non-nil=20if=20= NODE1=20and=20NODE2=20are=20the=20same=20node.=0A+If=20any=20one=20of=20= NODE1=20and=20NODE2=20is=20nil,=20return=20nil.=20=20*/)=0A+=20=20= (Lisp_Object=20node1,=20Lisp_Object=20node2)=0A+{=0A+=20=20if=20(NILP=20= (node1)=20||=20NILP=20(node2))=0A+=20=20=20=20return=20Qnil;=0A+=20=20= CHECK_TS_NODE=20(node1);=0A+=20=20CHECK_TS_NODE=20(node2);=0A+=0A+=20=20= TSNode=20ts_node_1=20=3D=20XTS_NODE=20(node1)->node;=0A+=20=20TSNode=20= ts_node_2=20=3D=20XTS_NODE=20(node2)->node;=0A+=0A+=20=20bool=20= same_node=20=3D=20ts_node_eq=20(ts_node_1,=20ts_node_2);=0A+=20=20return=20= same_node=20?=20Qt=20:=20Qnil;=0A+}=0A+=0A+/***=20Query=20functions=20*/=0A= +=0A+/*=20If=20we=20decide=20to=20pre-load=20tree-sitter.el,=20maybe=20= we=20can=20implement=0A+=20=20=20this=20function=20in=20Lisp.=20=20*/=0A= +DEFUN=20("tree-sitter-expand-pattern",=0A+=20=20=20=20=20=20=20= Ftree_sitter_expand_pattern,=0A+=20=20=20=20=20=20=20= Stree_sitter_expand_pattern,=201,=201,=200,=0A+=20=20=20=20=20=20=20doc:=20= /*=20Expand=20PATTERN=20to=20its=20string=20form.=0A+=0A+PATTERN=20can=20= be=0A+=0A+=20=20=20=20:anchor=0A+=20=20=20=20:?=0A+=20=20=20=20:*=0A+=20=20= =20=20:+=0A+=20=20=20=20:equal=0A+=20=20=20=20:match=0A+=20=20=20=20= (TYPE=20PATTERN...)=0A+=20=20=20=20[PATTERN...]=0A+=20=20=20=20= FIELD-NAME:=0A+=20=20=20=20@CAPTURE-NAME=0A+=20=20=20=20(_)=0A+=20=20=20=20= _=0A+=20=20=20=20\"TYPE\"=0A+=0A+Consult=20Info=20node=20`(elisp)Pattern=20= Matching'=20form=20detailed=0A+explanation.=20=20*/)=0A+=20=20= (Lisp_Object=20pattern)=0A+{=0A+=20=20if=20(EQ=20(pattern,=20= intern_c_string=20(":anchor")))=0A+=20=20=20=20return=20= build_pure_c_string(".");=0A+=20=20if=20(EQ=20(pattern,=20= intern_c_string=20(":?")))=0A+=20=20=20=20return=20= build_pure_c_string("?");=0A+=20=20if=20(EQ=20(pattern,=20= intern_c_string=20(":*")))=0A+=20=20=20=20return=20= build_pure_c_string("*");=0A+=20=20if=20(EQ=20(pattern,=20= intern_c_string=20(":+")))=0A+=20=20=20=20return=20= build_pure_c_string("+");=0A+=20=20if=20(EQ=20(pattern,=20= intern_c_string=20(":equal")))=0A+=20=20=20=20return=20= build_pure_c_string("#equal");=0A+=20=20if=20(EQ=20(pattern,=20= intern_c_string=20(":match")))=0A+=20=20=20=20return=20= build_pure_c_string("#match");=0A+=20=20Lisp_Object=20opening_delimeter=20= =3D=0A+=20=20=20=20build_pure_c_string=20(VECTORP=20(pattern)=20?=20"["=20= :=20"(");=0A+=20=20Lisp_Object=20closing_delimiter=20=3D=0A+=20=20=20=20= build_pure_c_string=20(VECTORP=20(pattern)=20?=20"]"=20:=20")");=0A+=20=20= if=20(VECTORP=20(pattern)=20||=20CONSP=20(pattern))=0A+=20=20=20=20= return=20concat3=20(opening_delimeter,=0A+=09=09=20=20=20=20Fmapconcat=20= (intern_c_string=0A+=09=09=09=09("tree-sitter-expand-pattern"),=0A+=09=09= =09=09pattern,=0A+=09=09=09=09build_pure_c_string=20("=20")),=0A+=09=09=20= =20=20=20closing_delimiter);=0A+=20=20return=20CALLN=20(Fformat,=20= build_pure_c_string("%S"),=20pattern);=0A+}=0A+=0A+DEFUN=20= ("tree-sitter-expand-query",=0A+=20=20=20=20=20=20=20= Ftree_sitter_expand_query,=0A+=20=20=20=20=20=20=20= Stree_sitter_expand_query,=201,=201,=200,=0A+=20=20=20=20=20=20=20doc:=20= /*=20Expand=20sexp=20QUERY=20to=20its=20string=20form.=0A+=0A+A=20= PATTERN=20in=20QUERY=20can=20be=0A+=0A+=20=20=20=20:anchor=0A+=20=20=20=20= :?=0A+=20=20=20=20:*=0A+=20=20=20=20:+=0A+=20=20=20=20:equal=0A+=20=20=20= =20:match=0A+=20=20=20=20(TYPE=20PATTERN...)=0A+=20=20=20=20[PATTERN...]=0A= +=20=20=20=20FIELD-NAME:=0A+=20=20=20=20@CAPTURE-NAME=0A+=20=20=20=20(_)=0A= +=20=20=20=20_=0A+=20=20=20=20\"TYPE\"=0A+=0A+Consult=20Info=20node=20= `(elisp)Pattern=20Matching'=20form=20detailed=0A+explanation.=20=20*/)=0A= +=20=20(Lisp_Object=20query)=0A+{=0A+=20=20return=20Fmapconcat=20= (intern_c_string=20("tree-sitter-expand-pattern"),=0A+=09=09=20=20=20=20=20= query,=20build_pure_c_string=20("=20"));=0A+}=0A+=0A+char*=0A= +ts_query_error_to_string=20(TSQueryError=20error)=0A+{=0A+=20=20switch=20= (error)=0A+=20=20=20=20{=0A+=20=20=20=20case=20TSQueryErrorNone:=0A+=20=20= =20=20=20=20return=20"None";=0A+=20=20=20=20case=20TSQueryErrorSyntax:=0A= +=20=20=20=20=20=20return=20"Syntax=20error=20at";=0A+=20=20=20=20case=20= TSQueryErrorNodeType:=0A+=20=20=20=20=20=20return=20"Node=20type=20error=20= at";=0A+=20=20=20=20case=20TSQueryErrorField:=0A+=20=20=20=20=20=20= return=20"Field=20error=20at";=0A+=20=20=20=20case=20= TSQueryErrorCapture:=0A+=20=20=20=20=20=20return=20"Capture=20error=20= at";=0A+=20=20=20=20case=20TSQueryErrorStructure:=0A+=20=20=20=20=20=20= return=20"Structure=20error=20at";=0A+=20=20=20=20default:=0A+=20=20=20=20= =20=20return=20"Unknown=20error";=0A+=20=20=20=20}=0A+}=0A+=0A+/*=20= Collect=20predicates=20for=20this=20match=20and=20return=20them=20in=20a=20= list.=20=20Each=0A+=20=20=20predicate=20is=20a=20list=20of=20strings=20= and=20symbols.=20=20*/=0A+Lisp_Object=0A+ts_predicates_for_pattern=0A= +(TSQuery=20*query,=20uint32_t=20pattern_index)=0A+{=0A+=20=20uint32_t=20= len;=0A+=20=20const=20TSQueryPredicateStep=20*predicate_list=20=3D=0A+=20= =20=20=20ts_query_predicates_for_pattern=20(query,=20pattern_index,=20= &len);=0A+=20=20Lisp_Object=20result=20=3D=20Qnil;=0A+=20=20Lisp_Object=20= predicate=20=3D=20Qnil;=0A+=20=20for=20(int=20idx=3D0;=20idx=20<=20len;=20= idx++)=0A+=20=20=20=20{=0A+=20=20=20=20=20=20TSQueryPredicateStep=20step=20= =3D=20predicate_list[idx];=0A+=20=20=20=20=20=20switch=20(step.type)=0A+=09= {=0A+=09case=20TSQueryPredicateStepTypeCapture:=0A+=09=20=20{=0A+=09=20=20= =20=20uint32_t=20str_len;=0A+=09=20=20=20=20const=20char=20*str=20=3D=20= ts_query_capture_name_for_id=0A+=09=20=20=20=20=20=20(query,=20= step.value_id,=20&str_len);=0A+=09=20=20=20=20predicate=20=3D=20Fcons=20= (intern_c_string_1=20(str,=20str_len),=0A+=09=09=09=20=20=20=20=20=20=20= predicate);=0A+=09=20=20=20=20break;=0A+=09=20=20}=0A+=09case=20= TSQueryPredicateStepTypeString:=0A+=09=20=20{=0A+=09=20=20=20=20uint32_t=20= str_len;=0A+=09=20=20=20=20const=20char=20*str=20=3D=20= ts_query_string_value_for_id=0A+=09=20=20=20=20=20=20(query,=20= step.value_id,=20&str_len);=0A+=09=20=20=20=20predicate=20=3D=20Fcons=20= (make_string=20(str,=20str_len),=20predicate);=0A+=09=20=20=20=20break;=0A= +=09=20=20}=0A+=09case=20TSQueryPredicateStepTypeDone:=0A+=09=20=20= result=20=3D=20Fcons=20(Fnreverse=20(predicate),=20result);=0A+=09=20=20= predicate=20=3D=20Qnil;=0A+=09=20=20break;=0A+=09}=0A+=20=20=20=20}=0A+=20= =20return=20Fnreverse=20(result);=0A+}=0A+=0A+/*=20Translate=20a=20= capture=20NAME=20(symbol)=20to=20the=20text=20of=20the=20captured=20= node.=0A+=20=20=20Signals=20tree-sitter-query-error=20if=20such=20node=20= is=20not=20captured.=20=20*/=0A+Lisp_Object=0A= +ts_predicate_capture_name_to_text=20(Lisp_Object=20name,=20Lisp_Object=20= captures)=0A+{=0A+=20=20Lisp_Object=20node=20=3D=20Qnil;=0A+=20=20for=20= (Lisp_Object=20tail=20=3D=20captures;=20!NILP=20(tail);=20tail=20=3D=20= XCDR=20(tail))=0A+=20=20=20=20{=0A+=20=20=20=20=20=20if=20(EQ=20(XCAR=20= (XCAR=20(tail)),=20name))=0A+=09{=0A+=09=20=20node=20=3D=20XCDR=20(XCAR=20= (tail));=0A+=09=20=20break;=0A+=09}=0A+=20=20=20=20}=0A+=0A+=20=20if=20= (NILP=20(node))=0A+=20=20=20=20xsignal3=20(Qtree_sitter_query_error,=0A+=09= =20=20=20=20=20=20build_pure_c_string=20("Cannot=20find=20captured=20= node"),=0A+=09=20=20=20=20=20=20name,=20build_pure_c_string=20("A=20= predicate=20can=20only=20refer=20to=20captured=20nodes=20in=20the=20same=20= pattern"));=0A+=0A+=20=20struct=20buffer=20*old_buffer=20=3D=20= current_buffer;=0A+=20=20set_buffer_internal=0A+=20=20=20=20(XBUFFER=20= (XTS_PARSER=20(XTS_NODE=20(node)->parser)->buffer));=0A+=20=20= Lisp_Object=20text=20=3D=20Fbuffer_substring=0A+=20=20=20=20= (Ftree_sitter_node_start=20(node),=20Ftree_sitter_node_end=20(node));=0A= +=20=20set_buffer_internal=20(old_buffer);=0A+=20=20return=20text;=0A+}=0A= +=0A+/*=20Handles=20predicate=20(#equal=20A=20B).=20=20Return=20true=20= if=20A=20equals=20B;=20return=0A+=20=20=20false=20otherwise.=20A=20and=20= B=20can=20be=20either=20string,=20or=20a=20capture=20name.=0A+=20=20=20= The=20capture=20name=20evaluates=20to=20the=20text=20its=20captured=20= node=20spans=20in=0A+=20=20=20the=20buffer.=20=20*/=0A+bool=0A= +ts_predicate_equal=20(Lisp_Object=20args,=20Lisp_Object=20captures)=0A= +{=0A+=20=20if=20(XFIXNUM=20(Flength=20(args))=20!=3D=202)=0A+=20=20=20=20= xsignal2=20(Qtree_sitter_query_error,=20build_pure_c_string=20= ("Predicate=20`equal'=20requires=20two=20arguments=20but=20only=20= given"),=20Flength=20(args));=0A+=0A+=20=20Lisp_Object=20arg1=20=3D=20= XCAR=20(args);=0A+=20=20Lisp_Object=20arg2=20=3D=20XCAR=20(XCDR=20= (args));=0A+=20=20Lisp_Object=20tail=20=3D=20captures;=0A+=20=20= Lisp_Object=20text1=20=3D=20STRINGP=20(arg1)=20?=20arg1=20:=0A+=20=20=20=20= ts_predicate_capture_name_to_text=20(arg1,=20captures);=0A+=20=20= Lisp_Object=20text2=20=3D=20STRINGP=20(arg2)=20?=20arg2=20:=0A+=20=20=20=20= ts_predicate_capture_name_to_text=20(arg2,=20captures);=0A+=0A+=20=20if=20= (NILP=20(Fstring_equal=20(text1,=20text2)))=0A+=20=20=20=20return=20= false;=0A+=20=20else=0A+=20=20=20=20return=20true;=0A+}=0A+=0A+/*=20= Handles=20predicate=20(#match=20"regexp"=20@node).=20=20Return=20true=20= if=20"regexp"=0A+=20=20=20matches=20the=20text=20spanned=20by=20@node;=20= return=20false=20otherwise.=20=20Matching=0A+=20=20=20is=20= case-sensitive.=20=20*/=0A+bool=0A+ts_predicate_match=20(Lisp_Object=20= args,=20Lisp_Object=20captures)=0A+{=0A+=20=20if=20(XFIXNUM=20(Flength=20= (args))=20!=3D=202)=0A+=20=20=20=20xsignal2=20(Qtree_sitter_query_error,=20= build_pure_c_string=20("Predicate=20`equal'=20requires=20two=20arguments=20= but=20only=20given"),=20Flength=20(args));=0A+=0A+=20=20Lisp_Object=20= regexp=20=3D=20XCAR=20(args);=0A+=20=20Lisp_Object=20capture_name=20=3D=20= XCAR=20(XCDR=20(args));=0A+=20=20Lisp_Object=20tail=20=3D=20captures;=0A= +=20=20Lisp_Object=20text=20=3D=20ts_predicate_capture_name_to_text=0A+=20= =20=20=20(capture_name,=20captures);=0A+=0A+=20=20/*=20It's=20probably=20= common=20to=20get=20the=20argument=20order=20backwards.=20=20Catch=0A+=20= =20=20=20=20this=20mistake=20early=20and=20show=20helpful=20explanation,=20= because=20Emacs=0A+=20=20=20=20=20loves=20you.=20=20(We=20put=20the=20= regexp=20first=20because=20that's=20what=0A+=20=20=20=20=20string-match=20= does.)=20=20*/=0A+=20=20if=20(!STRINGP=20(regexp))=0A+=20=20=20=20= xsignal1=20(Qtree_sitter_query_error,=20build_pure_c_string=20("The=20= first=20argument=20to=20`match'=20should=20be=20a=20regexp=20string,=20= not=20a=20capture=20name"));=0A+=20=20if=20(!SYMBOLP=20(capture_name))=0A= +=20=20=20=20xsignal1=20(Qtree_sitter_query_error,=20build_pure_c_string=20= ("The=20second=20argument=20to=20`match'=20should=20be=20a=20capture=20= name,=20not=20a=20string"));=0A+=0A+=20=20if=20(fast_string_match=20= (regexp,=20text)=20>=3D=200)=0A+=20=20=20=20return=20true;=0A+=20=20else=0A= +=20=20=20=20return=20false;=0A+}=0A+=0A+/*=20About=20predicates:=20I=20= decide=20to=20hard-code=20predicates=20in=20C=20instead=20of=0A+=20=20=20= implementing=20an=20extensible=20system=20where=20predicates=20are=20= translated=0A+=20=20=20to=20Lisp=20functions,=20and=20new=20predicates=20= can=20be=20added=20by=20extending=20a=0A+=20=20=20list=20of=20functions,=20= because=20I=20really=20couldn't=20imagine=20any=20useful=0A+=20=20=20= predicates=20besides=20equal=20and=20match.=20=20If=20we=20later=20found=20= out=20that=0A+=20=20=20such=20system=20is=20indeed=20useful=20and=20= necessary,=20it=20can=20be=20easily=0A+=20=20=20added.=20=20*/=0A+=0A+/*=20= If=20all=20predicates=20in=20PREDICATES=20passes,=20return=20true;=20= otherwise=0A+=20=20=20return=20false.=20=20*/=0A+bool=0A= +ts_eval_predicates=20(Lisp_Object=20captures,=20Lisp_Object=20= predicates)=0A+{=0A+=20=20bool=20pass=20=3D=20true;=0A+=20=20/*=20= Evaluate=20each=20predicates.=20=20*/=0A+=20=20for=20(Lisp_Object=20tail=20= =3D=20predicates;=0A+=20=20=20=20=20=20=20!NILP=20(tail);=20tail=20=3D=20= XCDR=20(tail))=0A+=20=20=20=20{=0A+=20=20=20=20=20=20Lisp_Object=20= predicate=20=3D=20XCAR=20(tail);=0A+=20=20=20=20=20=20Lisp_Object=20fn=20= =3D=20XCAR=20(predicate);=0A+=20=20=20=20=20=20Lisp_Object=20args=20=3D=20= XCDR=20(predicate);=0A+=20=20=20=20=20=20if=20(!NILP=20(Fstring_equal=20= (fn,=20build_pure_c_string("equal"))))=0A+=09pass=20=3D=20= ts_predicate_equal=20(args,=20captures);=0A+=20=20=20=20=20=20else=20if=20= (!NILP=20(Fstring_equal=0A+=09=09=20=20=20=20=20=20(fn,=20= build_pure_c_string("match"))))=0A+=09pass=20=3D=20ts_predicate_match=20= (args,=20captures);=0A+=20=20=20=20=20=20else=0A+=09xsignal3=20= (Qtree_sitter_query_error,=0A+=09=09=20=20build_pure_c_string=20= ("Invalid=20predicate"),=0A+=09=09=20=20fn,=20build_pure_c_string=20= ("Currently=20Emacs=20only=20supports=20equal=20and=20match=20= predicate"));=0A+=20=20=20=20}=0A+=20=20/*=20If=20all=20predicates=20= passed,=20add=20captures=20to=20result=20list.=20=20*/=0A+=20=20return=20= pass;=0A+}=0A+=0A+DEFUN=20("tree-sitter-query-capture",=0A+=20=20=20=20=20= =20=20Ftree_sitter_query_capture,=0A+=20=20=20=20=20=20=20= Stree_sitter_query_capture,=202,=204,=200,=0A+=20=20=20=20=20=20=20doc:=20= /*=20Query=20NODE=20with=20patterns=20in=20QUERY.=0A+=0A+Return=20a=20= list=20of=20(CAPTURE_NAME=20.=20NODE).=20=20CAPTURE_NAME=20is=20the=20= name=0A+assigned=20to=20the=20node=20in=20PATTERN.=20=20NODE=20is=20the=20= captured=20node.=0A+=0A+QUERY=20is=20either=20a=20string=20query=20or=20= a=20sexp=20query.=20=20See=20Info=20node=0A+`(elisp)Pattern=20Matching'=20= for=20how=20to=20write=20a=20query=20in=20either=20string=20or=0A= +s-expression=20form.=0A+=0A+BEG=20and=20END,=20if=20both=20non-nil,=20= specifies=20the=20range=20in=20which=20the=20query=0A+is=20executed.=0A+=0A= +Raise=20an=20tree-sitter-query-error=20if=20QUERY=20is=20malformed,=20= or=20something=0A+else=20goes=20wrong.=20=20*/)=0A+=20=20(Lisp_Object=20= node,=20Lisp_Object=20query,=0A+=20=20=20Lisp_Object=20beg,=20= Lisp_Object=20end)=0A+{=0A+=20=20ts_check_node=20(node);=0A+=20=20if=20= (!NILP=20(beg))=0A+=20=20=20=20CHECK_INTEGER=20(beg);=0A+=20=20if=20= (!NILP=20(end))=0A+=20=20=20=20CHECK_INTEGER=20(end);=0A+=0A+=20=20if=20= (CONSP=20(query))=0A+=20=20=20=20query=20=3D=20Ftree_sitter_expand_query=20= (query);=0A+=20=20else=0A+=20=20=20=20CHECK_STRING=20(query);=0A+=0A+=20=20= /*=20Extract=20C=20values=20from=20Lisp=20objects.=20=20*/=0A+=20=20= TSNode=20ts_node=20=3D=20XTS_NODE=20(node)->node;=0A+=20=20Lisp_Object=20= lisp_parser=20=3D=20XTS_NODE=20(node)->parser;=0A+=20=20ptrdiff_t=20= visible_beg=20=3D=0A+=20=20=20=20XTS_PARSER=20(XTS_NODE=20= (node)->parser)->visible_beg;=0A+=20=20const=20TSLanguage=20*lang=20=3D=20= ts_parser_language=0A+=20=20=20=20(XTS_PARSER=20(lisp_parser)->parser);=0A= +=20=20char=20*source=20=3D=20SSDATA=20(query);=0A+=0A+=20=20/*=20= Initialize=20query=20objects,=20and=20execute=20query.=20=20*/=0A+=20=20= uint32_t=20error_offset;=0A+=20=20TSQueryError=20error_type;=0A+=20=20/*=20= TODO:=20We=20could=20cache=20the=20query=20object,=20so=20that=20= repeatedly=0A+=20=20=20=20=20querying=20with=20the=20same=20query=20can=20= reuse=20the=20query=20object.=20=20It=20also=0A+=20=20=20=20=20saves=20= us=20from=20expanding=20the=20sexp=20query=20into=20a=20string.=20=20I=20= don't=0A+=20=20=20=20=20know=20how=20much=20time=20that=20could=20save=20= though.=20=20*/=0A+=20=20TSQuery=20*ts_query=20=3D=20ts_query_new=20= (lang,=20source,=20strlen=20(source),=0A+=09=09=09=09=20=20=20=20= &error_offset,=20&error_type);=0A+=20=20TSQueryCursor=20*cursor=20=3D=20= ts_query_cursor_new=20();=0A+=0A+=20=20if=20(ts_query=20=3D=3D=20NULL)=0A= +=20=20=20=20{=0A+=20=20=20=20=20=20xsignal2=20= (Qtree_sitter_query_error,=0A+=09=09build_string=20= (ts_query_error_to_string=20(error_type)),=0A+=09=09make_fixnum=20= (error_offset=20+=201));=0A+=20=20=20=20}=0A+=20=20if=20(!NILP=20(beg)=20= &&=20!NILP=20(end))=0A+=20=20=20=20{=0A+=20=20=20=20=20=20EMACS_INT=20= beg_byte=20=3D=20XFIXNUM=20(beg);=0A+=20=20=20=20=20=20EMACS_INT=20= end_byte=20=3D=20XFIXNUM=20(end);=0A+=20=20=20=20=20=20= ts_query_cursor_set_byte_range=0A+=09(cursor,=20(uint32_t)=20beg_byte=20= -=20visible_beg,=0A+=09=20(uint32_t)=20end_byte=20-=20visible_beg);=0A+=20= =20=20=20}=0A+=0A+=20=20ts_query_cursor_exec=20(cursor,=20ts_query,=20= ts_node);=0A+=20=20TSQueryMatch=20match;=0A+=0A+=20=20/*=20Go=20over=20= each=20match,=20collect=20captures=20and=20predicates.=20=20Include=20= the=0A+=20=20=20=20=20captures=20in=20the=20return=20list=20if=20all=20= predicates=20in=20that=20match=0A+=20=20=20=20=20passes.=20=20*/=0A+=20=20= Lisp_Object=20result=20=3D=20Qnil;=0A+=20=20while=20= (ts_query_cursor_next_match=20(cursor,=20&match))=0A+=20=20=20=20{=0A+=20= =20=20=20=20=20/*=20Get=20captured=20nodes.=20=20*/=0A+=20=20=20=20=20=20= Lisp_Object=20captures_lisp=20=3D=20Qnil;=0A+=20=20=20=20=20=20const=20= TSQueryCapture=20*captures=20=3D=20match.captures;=0A+=20=20=20=20=20=20= for=20(int=20idx=3D0;=20idx=20<=20match.capture_count;=20idx++)=0A+=09{=0A= +=09=20=20uint32_t=20capture_name_len;=0A+=09=20=20TSQueryCapture=20= capture=20=3D=20captures[idx];=0A+=09=20=20Lisp_Object=20captured_node=20= =3D=0A+=09=20=20=20=20make_ts_node(lisp_parser,=20capture.node);=0A+=09=20= =20const=20char=20*capture_name=20=3D=20ts_query_capture_name_for_id=0A+=09= =20=20=20=20(ts_query,=20capture.index,=20&capture_name_len);=0A+=09=20=20= Lisp_Object=20cap=20=3D=0A+=09=20=20=20=20Fcons=20(intern_c_string_1=20= (capture_name,=20capture_name_len),=0A+=09=09=20=20=20captured_node);=0A= +=09=20=20captures_lisp=20=3D=20Fcons=20(cap,=20captures_lisp);=0A+=09}=0A= +=20=20=20=20=20=20/*=20Get=20predicates.=20=20*/=0A+=20=20=20=20=20=20= Lisp_Object=20predicates=20=3D=0A+=09ts_predicates_for_pattern=20= (ts_query,=20match.pattern_index);=0A+=0A+=20=20=20=20=20=20= captures_lisp=20=3D=20Fnreverse=20(captures_lisp);=0A+=20=20=20=20=20=20= if=20(ts_eval_predicates=20(captures_lisp,=20predicates))=0A+=09{=0A+=09=20= =20result=20=3D=20CALLN=20(Fnconc,=20result,=20captures_lisp);=0A+=09}=0A= +=20=20=20=20}=0A+=20=20ts_query_delete=20(ts_query);=0A+=20=20= ts_query_cursor_delete=20(cursor);=0A+=20=20return=20result;=0A+}=0A+=0A= +/***=20Initialization=20*/=0A+=0A+/*=20Initialize=20the=20tree-sitter=20= routines.=20=20*/=0A+void=0A+syms_of_tree_sitter=20(void)=0A+{=0A+=20=20= DEFSYM=20(Qtree_sitter_parser_p,=20"tree-sitter-parser-p");=0A+=20=20= DEFSYM=20(Qtree_sitter_node_p,=20"tree-sitter-node-p");=0A+=20=20DEFSYM=20= (Qnamed,=20"named");=0A+=20=20DEFSYM=20(Qmissing,=20"missing");=0A+=20=20= DEFSYM=20(Qextra,=20"extra");=0A+=20=20DEFSYM=20(Qhas_changes,=20= "has-changes");=0A+=20=20DEFSYM=20(Qhas_error,=20"has-error");=0A+=0A+=20= =20DEFSYM=20(Qtree_sitter_error,=20"tree-sitter-error");=0A+=20=20DEFSYM=20= (Qtree_sitter_query_error,=20"tree-sitter-query-error");=0A+=20=20DEFSYM=20= (Qtree_sitter_parse_error,=20"tree-sitter-parse-error");=0A+=20=20DEFSYM=20= (Qtree_sitter_range_invalid,=20"tree-sitter-range-invalid");=0A+=20=20= DEFSYM=20(Qtree_sitter_buffer_too_large,=0A+=09=20=20= "tree-sitter-buffer-too-large");=0A+=20=20DEFSYM=20= (Qtree_sitter_load_language_error,=0A+=09=20=20= "tree-sitter-load-language-error");=0A+=20=20DEFSYM=20= (Qtree_sitter_node_outdated,=0A+=09=20=20"tree-sitter-node-outdated");=0A= +=0A+=20=20define_error=20(Qtree_sitter_error,=20"Generic=20tree-sitter=20= error",=20Qerror);=0A+=20=20define_error=20(Qtree_sitter_query_error,=20= "Query=20pattern=20is=20malformed",=0A+=09=09Qtree_sitter_error);=0A+=20=20= /*=20Should=20be=20impossible,=20no=20need=20to=20document=20this=20= error.=20=20*/=0A+=20=20define_error=20(Qtree_sitter_parse_error,=20= "Parse=20failed",=0A+=09=09Qtree_sitter_error);=0A+=20=20define_error=20= (Qtree_sitter_range_invalid,=0A+=09=09"RANGES=20are=20invalid,=20they=20= have=20to=20be=20ordered=20and=20not=20overlapping",=0A+=09=09= Qtree_sitter_error);=0A+=20=20define_error=20= (Qtree_sitter_buffer_too_large,=20"Buffer=20too=20large=20(>=204GB)",=0A= +=09=09Qtree_sitter_error);=0A+=20=20define_error=20= (Qtree_sitter_load_language_error,=0A+=09=09"Cannot=20load=20language=20= definition",=0A+=09=09Qtree_sitter_error);=0A+=20=20define_error=20= (Qtree_sitter_node_outdated,=0A+=09=09"This=20node=20is=20outdated,=20= please=20retrieve=20a=20new=20one",=0A+=09=09Qtree_sitter_error);=0A+=0A= +=20=20DEFSYM=20(Qtree_sitter_parser_list,=20"tree-sitter-parser-list");=0A= +=20=20DEFVAR_LISP=20("tree-sitter-parser-list",=20= Vtree_sitter_parser_list,=0A+=09=20=20=20=20=20=20=20doc:=20/*=20A=20= list=20of=20tree-sitter=20parsers.=0A+=0A+If=20you=20removed=20a=20= parser=20from=20this=20list,=20do=20not=20put=20it=20back=20in.=20=20= Emacs=0A+keeps=20the=20parser=20in=20this=20list=20updated=20with=20any=20= change=20in=20the=20buffer.=0A+If=20removed=20and=20put=20back=20in,=20= there=20is=20no=20guarantee=20that=20the=20parser=20is=20in=0A+sync=20= with=20the=20buffer's=20content.=20=20*/);=0A+=20=20= Vtree_sitter_parser_list=20=3D=20Qnil;=0A+=20=20= Fmake_variable_buffer_local=20(Qtree_sitter_parser_list);=0A+=0A+=20=20= DEFVAR_LISP=20("tree-sitter-load-name-override-list",=0A+=09=20=20=20=20=20= =20=20Vtree_sitter_load_name_override_list,=0A+=09=20=20=20=20=20=20=20= doc:=0A+=09=20=20=20=20=20=20=20/*=20An=20override=20alist=20for=20= irregular=20tree-sitter=20libraries.=0A+=0A+By=20default,=20Emacs=20= assumes=20the=20dynamic=20library=20for=20tree-sitter-=0A+is=20= libtree-sitter-.,=20where=20=20is=20the=20OS=20specific=0A= +extension=20for=20dynamic=20libraries.=20=20Emacs=20also=20assumes=20= that=20the=20name=20of=0A+the=20C=20function=20the=20library=20provides=20= is=20tree_sitter_.=20If=20that=20is=0A+not=20the=20case,=20add=20= an=20entry=0A+=0A+=20=20=20=20(LANGUAGE-SYMBOL=20LIBRARY-BASE-NAME=20= FUNCTION-NAME)=0A+=0A+to=20this=20alist,=20where=20LIBRARY-BASE-NAME=20= is=20the=20filename=20of=20the=20dynamic=0A+library=20without=20= extension,=20FUNCTION-NAME=20is=20the=20function=20provided=20by=0A+the=20= library.=20=20*/);=0A+=20=20Vtree_sitter_load_name_override_list=20=3D=20= Qnil;=0A+=0A+=20=20defsubr=20(&Stree_sitter_language_available_p);=0A+=0A= +=20=20defsubr=20(&Stree_sitter_parser_p);=0A+=20=20defsubr=20= (&Stree_sitter_node_p);=0A+=0A+=20=20defsubr=20= (&Stree_sitter_node_parser);=0A+=0A+=20=20defsubr=20= (&Stree_sitter_parser_create);=0A+=20=20defsubr=20= (&Stree_sitter_parser_buffer);=0A+=20=20defsubr=20= (&Stree_sitter_parser_language);=0A+=0A+=20=20defsubr=20= (&Stree_sitter_parser_root_node);=0A+=20=20/*=20defsubr=20= (&Stree_sitter_parse_string);=20*/=0A+=0A+=20=20defsubr=20= (&Stree_sitter_parser_set_included_ranges);=0A+=20=20defsubr=20= (&Stree_sitter_parser_included_ranges);=0A+=0A+=20=20defsubr=20= (&Stree_sitter_node_type);=0A+=20=20defsubr=20= (&Stree_sitter_node_start);=0A+=20=20defsubr=20(&Stree_sitter_node_end);=0A= +=20=20defsubr=20(&Stree_sitter_node_string);=0A+=20=20defsubr=20= (&Stree_sitter_node_parent);=0A+=20=20defsubr=20= (&Stree_sitter_node_child);=0A+=20=20defsubr=20= (&Stree_sitter_node_check);=0A+=20=20defsubr=20= (&Stree_sitter_node_field_name_for_child);=0A+=20=20defsubr=20= (&Stree_sitter_node_child_count);=0A+=20=20defsubr=20= (&Stree_sitter_node_child_by_field_name);=0A+=20=20defsubr=20= (&Stree_sitter_node_next_sibling);=0A+=20=20defsubr=20= (&Stree_sitter_node_prev_sibling);=0A+=20=20defsubr=20= (&Stree_sitter_node_first_child_for_pos);=0A+=20=20defsubr=20= (&Stree_sitter_node_descendant_for_range);=0A+=20=20defsubr=20= (&Stree_sitter_node_eq);=0A+=0A+=20=20defsubr=20= (&Stree_sitter_expand_pattern);=0A+=20=20defsubr=20= (&Stree_sitter_expand_query);=0A+=20=20defsubr=20= (&Stree_sitter_query_capture);=0A+}=0Adiff=20--git=20a/src/tree-sitter.h=20= b/src/tree-sitter.h=0Anew=20file=20mode=20100644=0Aindex=20= 0000000000..05d8e14fe6=0A---=20/dev/null=0A+++=20b/src/tree-sitter.h=0A= @@=20-0,0=20+1,139=20@@=0A+/*=20Header=20file=20for=20the=20tree-sitter=20= integration.=0A+=0A+Copyright=20(C)=202021=20Free=20Software=20= Foundation,=20Inc.=0A+=0A+This=20file=20is=20part=20of=20GNU=20Emacs.=0A= +=0A+GNU=20Emacs=20is=20free=20software:=20you=20can=20redistribute=20it=20= and/or=20modify=0A+it=20under=20the=20terms=20of=20the=20GNU=20General=20= Public=20License=20as=20published=20by=0A+the=20Free=20Software=20= Foundation,=20either=20version=203=20of=20the=20License,=20or=20(at=0A= +your=20option)=20any=20later=20version.=0A+=0A+GNU=20Emacs=20is=20= distributed=20in=20the=20hope=20that=20it=20will=20be=20useful,=0A+but=20= WITHOUT=20ANY=20WARRANTY;=20without=20even=20the=20implied=20warranty=20= of=0A+MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20= =20See=20the=0A+GNU=20General=20Public=20License=20for=20more=20details.=0A= +=0A+You=20should=20have=20received=20a=20copy=20of=20the=20GNU=20= General=20Public=20License=0A+along=20with=20GNU=20Emacs.=20=20If=20not,=20= see=20.=20=20*/=0A+=0A+#ifndef=20= EMACS_TREE_SITTER_H=0A+#define=20EMACS_TREE_SITTER_H=0A+=0A+#include=20= =0A+#include=20"lisp.h"=0A+=0A+#include=20=0A= +=0A+INLINE_HEADER_BEGIN=0A+=0A+/*=20A=20wrapper=20for=20a=20tree-sitter=20= parser,=20but=20also=20contains=20a=20parse=20tree=0A+=20=20=20and=20= other=20goodies=20for=20convenience.=20=20*/=0A+struct=20Lisp_TS_Parser=0A= +{=0A+=20=20union=20vectorlike_header=20header;=0A+=20=20/*=20A=20symbol=20= represents=20the=20language=20this=20parser=20uses.=20=20See=20the=0A+=20= =20=20=20=20manual=20for=20more=20explanation.=20=20*/=0A+=20=20= Lisp_Object=20language_symbol;=0A+=20=20/*=20The=20buffer=20associated=20= with=20this=20parser.=20=20*/=0A+=20=20Lisp_Object=20buffer;=0A+=20=20/*=20= The=20pointer=20to=20the=20tree-sitter=20parser.=20=20Never=20NULL.=20=20= */=0A+=20=20TSParser=20*parser;=0A+=20=20/*=20Pointer=20to=20the=20= syntax=20tree.=20=20Initially=20is=20NULL,=20so=20check=20for=20NULL=0A+=20= =20=20=20=20before=20use.=20=20*/=0A+=20=20TSTree=20*tree;=0A+=20=20/*=20= Teaches=20tree-sitter=20how=20to=20read=20an=20Emacs=20buffer.=20=20*/=0A= +=20=20TSInput=20input;=0A+=20=20/*=20Re-parsing=20an=20unchanged=20= buffer=20is=20not=20free=20for=20tree-sitter,=20so=20we=0A+=20=20=20=20=20= only=20make=20it=20re-parse=20when=20need_reparse=20=3D=3D=20true.=20=20= That=20usually=0A+=20=20=20=20=20means=20some=20change=20is=20made=20in=20= the=20buffer.=20=20But=20others=20could=20set=0A+=20=20=20=20=20this=20= field=20to=20true=20to=20force=20tree-sitter=20to=20re-parse.=20=20*/=0A= +=20=20bool=20need_reparse;=0A+=20=20/*=20These=20two=20positions=20= record=20the=20buffer=20byte=20position=20(1-based)=20of=0A+=20=20=20=20=20= the=20"visible=20region"=20that=20tree-sitter=20sees.=20=20Unlike=20= markers,=0A+=20=20=20=20=20These=20two=20positions=20do=20not=20change=20= as=20the=20user=20inserts=20and=20deletes=0A+=20=20=20=20=20text=20= around=20them.=20Before=20re-parse,=20we=20move=20these=20positions=20to=0A= +=20=20=20=20=20match=20BUF_BEGV_BYTE=20and=20BUF_ZV_BYTE.=20=20Note=20= that=20we=20don't=20need=20to=0A+=20=20=20=20=20synchronize=20these=20= positions=20when=20retrieving=20them=20in=20a=20function=0A+=20=20=20=20=20= that=20involves=20a=20node:=20if=20the=20node=20is=20not=20outdated,=20= these=0A+=20=20=20=20=20positions=20are=20synchronized.=20=20*/=0A+=20=20= ptrdiff_t=20visible_beg;=0A+=20=20ptrdiff_t=20visible_end;=0A+=20=20/*=20= This=20counter=20is=20incremented=20every=20time=20a=20change=20is=20= made=20to=20the=0A+=20=20=20=20=20buffer=20in=20ts_record_change.=20=20= The=20node=20retrieved=20from=20this=20parser=0A+=20=20=20=20=20inherits=20= this=20timestamp.=20=20This=20way=20we=20can=20make=20sure=20the=20node=20= is=0A+=20=20=20=20=20not=20outdated=20when=20we=20access=20its=20= information.=20=20*/=0A+=20=20ptrdiff_t=20timestamp;=0A+};=0A+=0A+/*=20A=20= wrapper=20around=20a=20tree-sitter=20node.=20=20*/=0A+struct=20= Lisp_TS_Node=0A+{=0A+=20=20union=20vectorlike_header=20header;=0A+=20=20= /*=20This=20prevents=20gc=20from=20collecting=20the=20tree=20before=20= the=20node=20is=20done=0A+=20=20=20=20=20with=20it.=20=20TSNode=20= contains=20a=20pointer=20to=20the=20tree=20it=20belongs=20to,=0A+=20=20=20= =20=20and=20the=20parser=20object,=20when=20collected=20by=20gc,=20will=20= free=20that=0A+=20=20=20=20=20tree.=20*/=0A+=20=20Lisp_Object=20parser;=0A= +=20=20TSNode=20node;=0A+=20=20/*=20A=20node=20inherits=20its=20parser's=20= timestamp=20at=20creation=20time.=20=20The=0A+=20=20=20=20=20parser's=20= timestamp=20increments=20as=20the=20buffer=20changes.=20=20This=20way=20= we=0A+=20=20=20=20=20can=20make=20sure=20the=20node=20is=20not=20= outdated=20when=20we=20access=20its=0A+=20=20=20=20=20information.=20=20= */=0A+=20=20ptrdiff_t=20timestamp;=0A+};=0A+=0A+INLINE=20bool=0A= +TS_PARSERP=20(Lisp_Object=20x)=0A+{=0A+=20=20return=20PSEUDOVECTORP=20= (x,=20PVEC_TS_PARSER);=0A+}=0A+=0A+INLINE=20struct=20Lisp_TS_Parser=20*=0A= +XTS_PARSER=20(Lisp_Object=20a)=0A+{=0A+=20=20eassert=20(TS_PARSERP=20= (a));=0A+=20=20return=20XUNTAG=20(a,=20Lisp_Vectorlike,=20struct=20= Lisp_TS_Parser);=0A+}=0A+=0A+INLINE=20bool=0A+TS_NODEP=20(Lisp_Object=20= x)=0A+{=0A+=20=20return=20PSEUDOVECTORP=20(x,=20PVEC_TS_NODE);=0A+}=0A+=0A= +INLINE=20struct=20Lisp_TS_Node=20*=0A+XTS_NODE=20(Lisp_Object=20a)=0A+{=0A= +=20=20eassert=20(TS_NODEP=20(a));=0A+=20=20return=20XUNTAG=20(a,=20= Lisp_Vectorlike,=20struct=20Lisp_TS_Node);=0A+}=0A+=0A+INLINE=20void=0A= +CHECK_TS_PARSER=20(Lisp_Object=20parser)=0A+{=0A+=20=20CHECK_TYPE=20= (TS_PARSERP=20(parser),=20Qtree_sitter_parser_p,=20parser);=0A+}=0A+=0A= +INLINE=20void=0A+CHECK_TS_NODE=20(Lisp_Object=20node)=0A+{=0A+=20=20= CHECK_TYPE=20(TS_NODEP=20(node),=20Qtree_sitter_node_p,=20node);=0A+}=0A= +=0A+void=0A+ts_record_change=20(ptrdiff_t=20start_byte,=20ptrdiff_t=20= old_end_byte,=0A+=09=09=20=20ptrdiff_t=20new_end_byte);=0A+=0A= +Lisp_Object=0A+make_ts_parser=20(Lisp_Object=20buffer,=20TSParser=20= *parser,=0A+=09=09TSTree=20*tree,=20Lisp_Object=20language_symbol);=0A+=0A= +Lisp_Object=0A+make_ts_node=20(Lisp_Object=20parser,=20TSNode=20node);=0A= +=0A+extern=20void=20syms_of_tree_sitter=20(void);=0A+=0A= +INLINE_HEADER_END=0A+=0A+#endif=20/*=20EMACS_TREE_SITTER_H=20*/=0Adiff=20= --git=20a/test/src/tree-sitter-tests.el=20= b/test/src/tree-sitter-tests.el=0Anew=20file=20mode=20100644=0Aindex=20= 0000000000..46e6e692eb=0A---=20/dev/null=0A+++=20= b/test/src/tree-sitter-tests.el=0A@@=20-0,0=20+1,366=20@@=0A+;;;=20= tree-sitter-tests.el=20---=20tests=20for=20src/tree-sitter.c=20=20=20=20=20= =20=20=20=20-*-=20lexical-binding:=20t;=20-*-=0A+=0A+;;=20Copyright=20= (C)=202021=20Free=20Software=20Foundation,=20Inc.=0A+=0A+;;=20This=20= file=20is=20part=20of=20GNU=20Emacs.=0A+=0A+;;=20GNU=20Emacs=20is=20free=20= software:=20you=20can=20redistribute=20it=20and/or=20modify=0A+;;=20it=20= under=20the=20terms=20of=20the=20GNU=20General=20Public=20License=20as=20= published=20by=0A+;;=20the=20Free=20Software=20Foundation,=20either=20= version=203=20of=20the=20License,=20or=0A+;;=20(at=20your=20option)=20= any=20later=20version.=0A+=0A+;;=20GNU=20Emacs=20is=20distributed=20in=20= the=20hope=20that=20it=20will=20be=20useful,=0A+;;=20but=20WITHOUT=20ANY=20= WARRANTY;=20without=20even=20the=20implied=20warranty=20of=0A+;;=20= MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20= See=20the=0A+;;=20GNU=20General=20Public=20License=20for=20more=20= details.=0A+=0A+;;=20You=20should=20have=20received=20a=20copy=20of=20= the=20GNU=20General=20Public=20License=0A+;;=20along=20with=20GNU=20= Emacs.=20=20If=20not,=20see=20.=0A+=0A= +;;;=20Code:=0A+=0A+(require=20'ert)=0A+(require=20'tree-sitter)=0A+=0A= +(ert-deftest=20tree-sitter-basic-parsing=20()=0A+=20=20"Test=20basic=20= parsing=20routines."=0A+=20=20(with-temp-buffer=0A+=20=20=20=20(let=20= ((parser=20(tree-sitter-parser-create=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(current-buffer)=20'tree-sitter-json)))=0A+=20=20= =20=20=20=20(should=0A+=20=20=20=20=20=20=20(eq=20parser=20(car=20= tree-sitter-parser-list)))=0A+=20=20=20=20=20=20(should=0A+=20=20=20=20=20= =20=20(equal=20(tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(tree-sitter-parser-root-node=20parser))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20"(ERROR)"))=0A+=0A+=20=20=20=20=20=20(insert=20= "[1,2,3]")=0A+=20=20=20=20=20=20(should=0A+=20=20=20=20=20=20=20(equal=20= (tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-parser-root-node=20parser))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20"(document=20(array=20(number)=20(number)=20(number)))"))=0A= +=0A+=20=20=20=20=20=20(goto-char=20(point-min))=0A+=20=20=20=20=20=20= (forward-char=203)=0A+=20=20=20=20=20=20(insert=20"{\"name\":=20= \"Bob\"},")=0A+=20=20=20=20=20=20(should=0A+=20=20=20=20=20=20=20(equal=0A= +=20=20=20=20=20=20=20=20(tree-sitter-node-string=0A+=20=20=20=20=20=20=20= =20=20(tree-sitter-parser-root-node=20parser))=0A+=20=20=20=20=20=20=20=20= "(document=20(array=20(number)=20(object=20(pair=20key:=20(string=20= (string_content))=20value:=20(string=20(string_content))))=20(number)=20= (number)))")))))=0A+=0A+(ert-deftest=20tree-sitter-node-api=20()=0A+=20=20= "Tests=20for=20node=20API."=0A+=20=20(with-temp-buffer=0A+=20=20=20=20= (let=20(parser=20root-node=20doc-node=20object-node=20pair-node)=0A+=20=20= =20=20=20=20(progn=0A+=20=20=20=20=20=20=20=20(insert=20"[1,2,{\"name\":=20= \"Bob\"},3]")=0A+=20=20=20=20=20=20=20=20(setq=20parser=20= (tree-sitter-parser-create=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(current-buffer)=20'tree-sitter-json))=0A+=20=20=20=20= =20=20=20=20(setq=20root-node=20(tree-sitter-parser-root-node=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= parser)))=0A+=20=20=20=20=20=20;;=20`tree-sitter-node-type'.=0A+=20=20=20= =20=20=20(should=20(equal=20"document"=20(tree-sitter-node-type=20= root-node)))=0A+=20=20=20=20=20=20;;=20`tree-sitter-node-check'.=0A+=20=20= =20=20=20=20(should=20(eq=20t=20(tree-sitter-node-check=20root-node=20= 'named)))=0A+=20=20=20=20=20=20(should=20(eq=20nil=20= (tree-sitter-node-check=20root-node=20'missing)))=0A+=20=20=20=20=20=20= (should=20(eq=20nil=20(tree-sitter-node-check=20root-node=20'extra)))=0A= +=20=20=20=20=20=20(should=20(eq=20nil=20(tree-sitter-node-check=20= root-node=20'has-error)))=0A+=20=20=20=20=20=20;;=20= `tree-sitter-node-child'.=0A+=20=20=20=20=20=20(setq=20doc-node=20= (tree-sitter-node-child=20root-node=200))=0A+=20=20=20=20=20=20(should=20= (equal=20"array"=20(tree-sitter-node-type=20doc-node)))=0A+=20=20=20=20=20= =20(should=20(equal=20(tree-sitter-node-string=20doc-node)=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"(array=20(number)=20= (number)=20(object=20(pair=20key:=20(string=20(string_content))=20value:=20= (string=20(string_content))))=20(number))"))=0A+=20=20=20=20=20=20;;=20= `tree-sitter-node-child-count'.=0A+=20=20=20=20=20=20(should=20(eql=209=20= (tree-sitter-node-child-count=20doc-node)))=0A+=20=20=20=20=20=20(should=20= (eql=204=20(tree-sitter-node-child-count=20doc-node=20t)))=0A+=20=20=20=20= =20=20;;=20`tree-sitter-node-field-name-for-child'.=0A+=20=20=20=20=20=20= (setq=20object-node=20(tree-sitter-node-child=20doc-node=202=20t))=0A+=20= =20=20=20=20=20(setq=20pair-node=20(tree-sitter-node-child=20object-node=20= 0=20t))=0A+=20=20=20=20=20=20(should=20(equal=20"object"=20= (tree-sitter-node-type=20object-node)))=0A+=20=20=20=20=20=20(should=20= (equal=20"pair"=20(tree-sitter-node-type=20pair-node)))=0A+=20=20=20=20=20= =20(should=20(equal=20"key"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(tree-sitter-node-field-name-for-child=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20pair-node=200)))=0A= +=20=20=20=20=20=20;;=20`tree-sitter-node-child-by-field-name'.=0A+=20=20= =20=20=20=20(should=20(equal=20"(string=20(string_content))"=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(tree-sitter-node-child-by-field-name=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20pair-node=20= "key"))))=0A+=20=20=20=20=20=20;;=20`tree-sitter-node-next-sibling'.=0A+=20= =20=20=20=20=20(should=20(equal=20"(number)"=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-string=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-next-sibling=20object-node=20t))))=0A+=20=20=20=20=20=20= (should=20(equal=20"(\",\")"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-next-sibling=20= object-node))))=0A+=20=20=20=20=20=20;;=20= `tree-sitter-node-prev-sibling'.=0A+=20=20=20=20=20=20(should=20(equal=20= "(number)"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(tree-sitter-node-prev-sibling=20object-node=20= t))))=0A+=20=20=20=20=20=20(should=20(equal=20"(\",\")"=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-string=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-prev-sibling=20object-node))))=0A+=20=20=20=20=20=20;;=20= `tree-sitter-node-first-child-for-pos'.=0A+=20=20=20=20=20=20(should=20= (equal=20"(number)"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-first-child-for-pos=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= doc-node=203=20t))))=0A+=20=20=20=20=20=20(should=20(equal=20"(\",\")"=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(tree-sitter-node-first-child-for-pos=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20doc-node=20= 3))))=0A+=20=20=20=20=20=20;;=20`tree-sitter-node-descendant-for-range'.=0A= +=20=20=20=20=20=20(should=20(equal=20"(\"{\")"=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-string=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-descendant-for-range=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20root-node=206=207))))=0A+=20=20=20=20= =20=20(should=20(equal=20"(object=20(pair=20key:=20(string=20= (string_content))=20value:=20(string=20(string_content))))"=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(tree-sitter-node-descendant-for-range=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20root-node=206=20= 7=20t))))=0A+=20=20=20=20=20=20;;=20`tree-sitter-node-eq'.=0A+=20=20=20=20= =20=20(should=20(tree-sitter-node-eq=20root-node=20root-node))=0A+=20=20=20= =20=20=20(should=20(not=20(tree-sitter-node-eq=20root-node=20= doc-node))))))=0A+=0A+(ert-deftest=20tree-sitter-query-api=20()=0A+=20=20= "Tests=20for=20query=20API."=0A+=20=20(with-temp-buffer=0A+=20=20=20=20= (let=20(parser=20root-node=20pattern=20doc-node=20object-node=20= pair-node)=0A+=20=20=20=20=20=20(progn=0A+=20=20=20=20=20=20=20=20= (insert=20"[1,2,{\"name\":=20\"Bob\"},3]")=0A+=20=20=20=20=20=20=20=20= (setq=20parser=20(tree-sitter-parser-create=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(current-buffer)=20= 'tree-sitter-json))=0A+=20=20=20=20=20=20=20=20(setq=20root-node=20= (tree-sitter-parser-root-node=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20parser)))=0A+=0A+=20=20=20=20=20=20= (dolist=20(pattern=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= '("(string)=20@string=0A+(pair=20key:=20(_)=20@keyword)=0A+((_)=20@bob=20= (#match=20\"^B.b$\"=20@bob))=0A+(number)=20@number=0A+((number)=20@n3=20= (#equal=20\"3\"=20@n3))=20"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20((string)=20@string=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(pair=20key:=20(_)=20@keyword)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20((_)=20@bob=20(:match=20"^B.b$"=20@bob))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(number)=20@number=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((number)=20@n3=20= (:equal=20"3"=20@n3)))))=0A+=20=20=20=20=20=20=20=20(should=0A+=20=20=20=20= =20=20=20=20=20(equal=0A+=20=20=20=20=20=20=20=20=20=20'((number=20.=20= "1")=20(number=20.=20"2")=0A+=20=20=20=20=20=20=20=20=20=20=20=20= (keyword=20.=20"\"name\"")=0A+=20=20=20=20=20=20=20=20=20=20=20=20= (string=20.=20"\"name\"")=0A+=20=20=20=20=20=20=20=20=20=20=20=20(string=20= .=20"\"Bob\"")=0A+=20=20=20=20=20=20=20=20=20=20=20=20(bob=20.=20"Bob")=0A= +=20=20=20=20=20=20=20=20=20=20=20=20(number=20.=20"3")=0A+=20=20=20=20=20= =20=20=20=20=20=20=20(n3=20.=20"3"))=0A+=20=20=20=20=20=20=20=20=20=20= (mapcar=20(lambda=20(entry)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(cons=20(car=20entry)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(tree-sitter-node-text=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(cdr=20entry))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(tree-sitter-query-capture=20root-node=20pattern))))=0A+=20=20=20= =20=20=20=20=20(should=0A+=20=20=20=20=20=20=20=20=20(equal=0A+=20=20=20=20= =20=20=20=20=20=20"(type=20field:=20(_)=20@capture=20.)=20?=20*=20+=20= \"return\""=0A+=20=20=20=20=20=20=20=20=20=20(tree-sitter-expand-query=0A= +=20=20=20=20=20=20=20=20=20=20=20'((type=20field:=20(_)=20@capture=20= :anchor)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20:?=20:*=20:+=20= "return"))))))))=0A+=0A+(ert-deftest=20tree-sitter-narrow=20()=0A+=20=20= "Tests=20if=20narrowing=20works."=0A+=20=20(with-temp-buffer=0A+=20=20=20= =20(let=20(parser=20root-node=20pattern=20doc-node=20object-node=20= pair-node)=0A+=20=20=20=20=20=20(progn=0A+=20=20=20=20=20=20=20=20= (insert=20"xxx[1,{\"name\":=20\"Bob\"},2,3]xxx")=0A+=20=20=20=20=20=20=20= =20(narrow-to-region=20(+=20(point-min)=203)=20(-=20(point-max)=203))=0A= +=20=20=20=20=20=20=20=20(setq=20parser=20(tree-sitter-parser-create=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (current-buffer)=20'tree-sitter-json))=0A+=20=20=20=20=20=20=20=20(setq=20= root-node=20(tree-sitter-parser-root-node=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20parser)))=0A+=20=20=20=20=20= =20;;=20This=20test=20is=20from=20the=20basic=20test.=0A+=20=20=20=20=20=20= (should=0A+=20=20=20=20=20=20=20(equal=0A+=20=20=20=20=20=20=20=20= (tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20= (tree-sitter-parser-root-node=20parser))=0A+=20=20=20=20=20=20=20=20= "(document=20(array=20(number)=20(object=20(pair=20key:=20(string=20= (string_content))=20value:=20(string=20(string_content))))=20(number)=20= (number)))"))=0A+=0A+=20=20=20=20=20=20(widen)=0A+=20=20=20=20=20=20= (goto-char=20(point-min))=0A+=20=20=20=20=20=20(insert=20"ooo")=0A+=20=20= =20=20=20=20(should=20(equal=20"oooxxx[1,{\"name\":=20\"Bob\"},2,3]xxx"=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (buffer-string)))=0A+=20=20=20=20=20=20(delete-region=2010=2026)=0A+=20=20= =20=20=20=20(should=20(equal=20"oooxxx[1,2,3]xxx"=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(buffer-string)))=0A+=20=20=20=20= =20=20(narrow-to-region=20(+=20(point-min)=206)=20(-=20(point-max)=203))=0A= +=20=20=20=20=20=20;;=20This=20test=20is=20also=20from=20the=20basic=20= test.=0A+=20=20=20=20=20=20(should=0A+=20=20=20=20=20=20=20(equal=20= (tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-parser-root-node=20parser))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20"(document=20(array=20(number)=20(number)=20(number)))"))=0A= +=20=20=20=20=20=20(widen)=0A+=20=20=20=20=20=20(goto-char=20= (point-max))=0A+=20=20=20=20=20=20(insert=20"[1,2]")=0A+=20=20=20=20=20=20= (should=20(equal=20"oooxxx[1,2,3]xxx[1,2]"=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(buffer-string)))=0A+=20=20=20=20=20=20= (narrow-to-region=20(-=20(point-max)=205)=20(point-max))=0A+=20=20=20=20=20= =20(should=0A+=20=20=20=20=20=20=20(equal=20(tree-sitter-node-string=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(tree-sitter-parser-root-node=20= parser))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20"(document=20= (array=20(number)=20(number)))"))=0A+=20=20=20=20=20=20(widen)=0A+=20=20=20= =20=20=20(goto-char=20(point-min))=0A+=20=20=20=20=20=20(insert=20"[1]")=0A= +=20=20=20=20=20=20(should=20(equal=20"[1]oooxxx[1,2,3]xxx[1,2]"=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (buffer-string)))=0A+=20=20=20=20=20=20(narrow-to-region=20(point-min)=20= (+=20(point-min)=203))=0A+=20=20=20=20=20=20(should=0A+=20=20=20=20=20=20= =20(equal=20(tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(tree-sitter-parser-root-node=20parser))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20"(document=20(array=20(number)))")))))=0A+=0A= +(ert-deftest=20tree-sitter-range=20()=0A+=20=20"Tests=20if=20range=20= works."=0A+=20=20(with-temp-buffer=0A+=20=20=20=20(let=20(parser=20= root-node=20pattern=20doc-node=20object-node=20pair-node)=0A+=20=20=20=20= =20=20(progn=0A+=20=20=20=20=20=20=20=20(insert=20= "[[1],oooxxx[1,2,3],xxx[1,2]]")=0A+=20=20=20=20=20=20=20=20(setq=20= parser=20(tree-sitter-parser-create=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(current-buffer)=20'tree-sitter-json))=0A+=20= =20=20=20=20=20=20=20(setq=20root-node=20(tree-sitter-parser-root-node=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20parser)))=0A+=20=20=20=20=20=20(should-error=0A+=20=20=20=20=20=20=20= (tree-sitter-parser-set-included-ranges=0A+=20=20=20=20=20=20=20=20= parser=20'((1=20.=206)=20(5=20.=2020)))=0A+=20=20=20=20=20=20=20:type=20= '(tree-sitter-range-invalid))=0A+=0A+=20=20=20=20=20=20= (tree-sitter-parser-set-included-ranges=0A+=20=20=20=20=20=20=20parser=20= '((1=20.=206)=20(12=20.=2020)=20(23=20.=2029)))=0A+=20=20=20=20=20=20= (should=20(equal=20'((1=20.=206)=20(12=20.=2020)=20(23=20.=2029))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-parser-included-ranges=20parser)))=0A+=20=20=20=20=20=20= (should=20(equal=20"(document=20(array=20(array=20(number))=20(array=20= (number)=20(number)=20(number))=20(array=20(number)=20(number))))"=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(tree-sitter-parser-root-node=20parser))))=0A+=20=20= =20=20=20=20;;=20TODO:=20More=20tests.=0A+=20=20=20=20=20=20)))=0A+=0A= +(ert-deftest=20tree-sitter-multi-lang=20()=0A+=20=20"Tests=20if=20= parsing=20multiple=20language=20works."=0A+=20=20(with-temp-buffer=0A+=20= =20=20=20(let=20(html=20css=20js=20html-range=20css-range=20js-range)=0A= +=20=20=20=20=20=20(progn=0A+=20=20=20=20=20=20=20=20(insert=20= "")=0A+=20=20=20=20= =20=20=20=20(setq=20html=20(tree-sitter-get-parser-create=20= 'tree-sitter-html))=0A+=20=20=20=20=20=20=20=20(setq=20css=20= (tree-sitter-get-parser-create=20'tree-sitter-css))=0A+=20=20=20=20=20=20= =20=20(setq=20js=20(tree-sitter-get-parser-create=20= 'tree-sitter-javascript)))=0A+=20=20=20=20=20=20;;=20JavaScript.=0A+=20=20= =20=20=20=20(setq=20js-range=0A+=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-query-range=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= 'tree-sitter-html=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= '((script_element=20(raw_text)=20@capture))))=0A+=20=20=20=20=20=20= (should=20(equal=20'((15=20.=2016))=20js-range))=0A+=20=20=20=20=20=20= (tree-sitter-parser-set-included-ranges=20js=20js-range)=0A+=20=20=20=20=20= =20(should=20(equal=20"(program=20(expression_statement=20(number)))"=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(tree-sitter-parser-root-node=20js))))=0A+=20=20=20=20= =20=20;;=20CSS.=0A+=20=20=20=20=20=20(setq=20css-range=0A+=20=20=20=20=20= =20=20=20=20=20=20=20(tree-sitter-query-range=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20'tree-sitter-html=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= '((style_element=20(raw_text)=20@capture))))=0A+=20=20=20=20=20=20= (should=20(equal=20'((32=20.=2039))=20css-range))=0A+=20=20=20=20=20=20= (tree-sitter-parser-set-included-ranges=20css=20css-range)=0A+=20=20=20=20= =20=20(should=0A+=20=20=20=20=20=20=20(equal=20"(stylesheet=20(rule_set=20= (selectors=20(tag_name))=20(block)))"=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(tree-sitter-parser-root-node=20css))))=0A+=20=20=20=20=20=20;;=20= TODO:=20More=20tests.=0A+=20=20=20=20=20=20)))=0A+=0A+(ert-deftest=20= tree-sitter-parser-supplemental=20()=0A+=20=20"Supplemental=20node=20= functions."=0A+=20=20;;=20`tree-sitter-get-parser'.=0A+=20=20= (with-temp-buffer=0A+=20=20=20=20(should=20(equal=20= (tree-sitter-get-parser=20'tree-sitter-json)=20nil)))=0A+=20=20;;=20= `tree-sitter-get-parser-create'.=0A+=20=20(with-temp-buffer=0A+=20=20=20=20= (should=20(not=20(equal=20(tree-sitter-get-parser-create=20= 'tree-sitter-json)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20nil))))=0A+=20=20;;=20`tree-sitter-parse-string'.=0A= +=20=20(should=20(equal=20(tree-sitter-node-string=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(tree-sitter-parse-string=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"[1,2,{\"name\":=20= \"Bob\"},3]"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= 'tree-sitter-json))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "(document=20(array=20(number)=20(number)=20(object=20(pair=20key:=20= (string=20(string_content))=20value:=20(string=20(string_content))))=20= (number)))"))=0A+=20=20(with-temp-buffer=0A+=20=20=20=20(let=20(parser=20= root-node=20doc-node=20object-node=20pair-node)=0A+=20=20=20=20=20=20= (progn=0A+=20=20=20=20=20=20=20=20(insert=20"[1,2,{\"name\":=20= \"Bob\"},3]")=0A+=20=20=20=20=20=20=20=20(setq=20parser=20= (tree-sitter-parser-create=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(current-buffer)=20'tree-sitter-json))=0A+=20=20=20=20= =20=20=20=20(setq=20root-node=20(tree-sitter-parser-root-node=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= parser))=0A+=20=20=20=20=20=20=20=20(setq=20doc-node=20= (tree-sitter-node-child=20root-node=200)))=0A+=20=20=20=20=20=20;;=20= `tree-sitter-get-parser'.=0A+=20=20=20=20=20=20(should=20(not=20(equal=20= (tree-sitter-get-parser=20'tree-sitter-json)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20nil)))=0A+=20=20=20=20= =20=20;;=20`tree-sitter-language-at'.=0A+=20=20=20=20=20=20(should=20= (equal=20(tree-sitter-language-at=20(point))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20'tree-sitter-json))=0A+=20=20=20=20=20= =20;;=20`tree-sitter-set-ranges',=20`tree-sitter-get-ranges'.=0A+=20=20=20= =20=20=20(tree-sitter-set-ranges=20'tree-sitter-json=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= '((1=20.=202)))=0A+=20=20=20=20=20=20(should=20(equal=20= (tree-sitter-get-ranges=20'tree-sitter-json)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20'((1=20.=202)))))))=0A+=0A= +(ert-deftest=20tree-sitter-node-supplemental=20()=0A+=20=20= "Supplemental=20node=20functions."=0A+=20=20(let=20(parser=20root-node=20= doc-node=20array-node)=0A+=20=20=20=20(progn=0A+=20=20=20=20=20=20= (insert=20"[1,2,{\"name\":=20\"Bob\"},3]")=0A+=20=20=20=20=20=20(setq=20= parser=20(tree-sitter-parser-create=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(current-buffer)=20'tree-sitter-json))=0A+=20=20=20= =20=20=20(setq=20root-node=20(tree-sitter-parser-root-node=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20parser))=0A+=20=20= =20=20=20=20(setq=20doc-node=20(tree-sitter-node-child=20root-node=20= 0)))=0A+=20=20=20=20;;=20`tree-sitter-node-buffer'.=0A+=20=20=20=20= (should=20(equal=20(tree-sitter-node-buffer=20root-node)=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(current-buffer)))=0A+=20=20=20= =20;;=20`tree-sitter-node-language'.=0A+=20=20=20=20(should=20(eq=20= (tree-sitter-node-language=20root-node)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20'tree-sitter-json))=0A+=20=20=20=20;;=20= `tree-sitter-node-at'.=0A+=20=20=20=20(should=20(equal=20= (tree-sitter-node-string=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(tree-sitter-node-at=201=202=20'tree-sitter-json))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"(\"[\")"))=0A+=20=20=20= =20;;=20`tree-sitter-buffer-root-node'.=0A+=20=20=20=20(should=20= (tree-sitter-node-eq=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= (tree-sitter-buffer-root-node=20'tree-sitter-json)=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20root-node))=0A+=20=20=20=20;;=20= `tree-sitter-filter-child'.=0A+=20=20=20=20(should=20(equal=20(mapcar=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20= (node)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(tree-sitter-node-type=20node))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(tree-sitter-filter-child=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20doc-node=20(lambda=20(node)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(tree-sitter-node-check=20node=20'named))))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'("number"=20= "number"=20"object"=20"number")))=0A+=20=20=20=20;;=20= `tree-sitter-node-text'.=0A+=20=20=20=20(should=20(equal=20= (tree-sitter-node-text=20doc-node)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20"[1,2,{\"name\":=20\"Bob\"},3]"))=0A+=20=20=20=20;;=20= `tree-sitter-node-index'.=0A+=20=20=20=20(should=20(eq=20= (tree-sitter-node-index=20doc-node)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=200))=0A+=20=20=20=20;;=20TODO:=0A+=20=20=20=20;;=20= `tree-sitter-parent-until'=0A+=20=20=20=20;;=20= `tree-sitter-parent-while'=0A+=20=20=20=20;;=20= `tree-sitter-node-children'=0A+=20=20=20=20;;=20= `tree-sitter-node-field-name'=0A+=20=20=20=20))=0A+=0A+;;=20TODO=0A+;;=20= -=20Functions=20in=20tree-sitter.el=0A+;;=20-=20= tree-sitter-load-name-override-list=0A+=0A+(provide=20= 'tree-sitter-tests)=0A+;;;=20tree-sitter-tests.el=20ends=20here=0A--=20=0A= 2.33.1=0A=0A= --Apple-Mail=_D449D3E8-BB51-4338-8EC4-A25BC88AC0F7--