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.bugs Subject: bug#62951: 29.0.90; c-ts-mode: Incorrect fontification due to FOR_EACH_TAIL_SAFE Date: Wed, 26 Apr 2023 20:14:45 -0700 Message-ID: <36F36D54-E56C-42C8-B686-448C8BF938EA@gmail.com> References: <82E7ADEC-25BC-475B-8EE0-839FE78FF2F4@gmail.com> <83fs8s2xnk.fsf@gnu.org> <2BDA88D0-A870-4FE3-BAF8-350FBAA943BF@gmail.com> <384f8110-eba6-8fb3-ef4e-56fa0721d85d@gutov.dev> <90E66143-A3E2-4B76-AC0A-01DC5E841AFE@gmail.com> Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3731.500.231\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_C19C1CC5-40F6-4BFB-B14A-97E439DD0C7D" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="4573"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Eli Zaretskii , 62951@debbugs.gnu.org To: Dmitry Gutov Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Apr 27 05:16:16 2023 Return-path: Envelope-to: geb-bug-gnu-emacs@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 1prs7D-00011u-59 for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 27 Apr 2023 05:16:15 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1prs73-0006qM-2a; Wed, 26 Apr 2023 23:16:05 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1prs71-0006qC-GV for bug-gnu-emacs@gnu.org; Wed, 26 Apr 2023 23:16:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1prs71-0000Nl-80 for bug-gnu-emacs@gnu.org; Wed, 26 Apr 2023 23:16:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1prs70-00031E-HG for bug-gnu-emacs@gnu.org; Wed, 26 Apr 2023 23:16:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Yuan Fu Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 27 Apr 2023 03:16:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 62951 X-GNU-PR-Package: emacs Original-Received: via spool by 62951-submit@debbugs.gnu.org id=B62951.168256530611518 (code B ref 62951); Thu, 27 Apr 2023 03:16:02 +0000 Original-Received: (at 62951) by debbugs.gnu.org; 27 Apr 2023 03:15:06 +0000 Original-Received: from localhost ([127.0.0.1]:57288 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1prs65-0002zi-VW for submit@debbugs.gnu.org; Wed, 26 Apr 2023 23:15:06 -0400 Original-Received: from mail-pl1-f172.google.com ([209.85.214.172]:50225) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1prs64-0002yt-1R for 62951@debbugs.gnu.org; Wed, 26 Apr 2023 23:15:05 -0400 Original-Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-1a66e7a52d3so60439015ad.0 for <62951@debbugs.gnu.org>; Wed, 26 Apr 2023 20:15:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682565298; x=1685157298; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:from:to:cc:subject:date:message-id:reply-to; bh=2OQYmPXwJWzFK3zfltXoHitr9TFSo5WL0jLOf+uBiD4=; b=FjQm3KLhT6PjzVtEGiu0PxknkddjxHBsVrSIFDsybHP2CJUIjWwjDBGx5mF7ZvG6pi qcQN6fER5r8nMvGExs+/NKXLlt6elKBkhU5/ecTzW1of9Bu7K2BQnC8p8oXSwVMfiLGm 0XbZodUKK7vYGCTZX7vXkxhvf82CNh98LutkSii8paSmZZo13Q19MOZQTdTUDykSOcrW IKIkV1s0NvSYl4mUTNdQq8Lj61lBUK6EXBwAVegGJQSiK9u07+2ZeZ8l4E5wliVtkG+E 3waAMk9Gol8IREbW4wzmQVtE1yjLsWRW8+MIRf6ML5PVjDuNjKzskvWpk3dmU/Ba4Po2 yKRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682565298; x=1685157298; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2OQYmPXwJWzFK3zfltXoHitr9TFSo5WL0jLOf+uBiD4=; b=jJocoXeZWuCIs1aU11GfLNs+fV3pFT/DnnKvvsB5EWBgZkJtQtPzRztbqGIFrqFMI1 cImywZjp9vwKWDFhSXwE5Ve6zsEwJ+JtAaGvIGMPLIAhktTEiTsiTdKdXQEI8bpDgSjt SBJSJK0+Id/qAjfsDST/hTpY8tr5JH3MTVfJgSzE3mxemVgBtwyeuJW/scCJXyrj6tV9 RfYHtuELt0E9belq2d88N4gJDDl6nXsypwRsTiGZPVIBXivsqAjn7MUJHuP+8gDkYRt9 JhSJ6//rY/E1yQTYQW8+QaDNZuJJnKaCYIpb3H37LBQjII1Ib0yD0KT2RR/ZusAiaUMX F6zg== X-Gm-Message-State: AC+VfDy4Sw+LcTs4g7w/AmZ2Qv5MflyGNlsPSwf9A67p1o5YzPifDPn3 zNgTH+UoUuTSoe3iF1WlL2o= X-Google-Smtp-Source: ACHHUZ4of0p+L8vJ61+u9Wr5FkD9MP+sqmebz8x0Zzl+HW6vj0Dkgs0W/wwuZ1GTgDLFFSxOX6RdSQ== X-Received: by 2002:a17:903:244e:b0:19e:6cb9:4c8f with SMTP id l14-20020a170903244e00b0019e6cb94c8fmr54731pls.41.1682565297684; Wed, 26 Apr 2023 20:14:57 -0700 (PDT) Original-Received: from smtpclient.apple (cpe-172-117-161-177.socal.res.rr.com. [172.117.161.177]) by smtp.gmail.com with ESMTPSA id w14-20020a1709029a8e00b00183c6784704sm10569400plp.291.2023.04.26.20.14.56 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Apr 2023 20:14:57 -0700 (PDT) In-Reply-To: <90E66143-A3E2-4B76-AC0A-01DC5E841AFE@gmail.com> X-Mailer: Apple Mail (2.3731.500.231) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:260694 Archived-At: --Apple-Mail=_C19C1CC5-40F6-4BFB-B14A-97E439DD0C7D Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 >=20 > My idea right now is to use the range feature in tree-sitter. Since = the =E2=80=9Cbody=E2=80=9D of FOR_EACH_TAIL is valid C, I can either set = the ranges for the parser so it ignores FOR_EACH_TAIL I end up going this route. > or I can add another parser that only parses the body of = FOR_EACH_TAIL. Ok, here=E2=80=99s the patch. Eli, would you give it a try? This is a = sizable patch so I=E2=80=99m not sure if you want it on emacs-29 or = master. Yuan --Apple-Mail=_C19C1CC5-40F6-4BFB-B14A-97E439DD0C7D Content-Disposition: attachment; filename=for-each-tail-fix.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="for-each-tail-fix.patch" Content-Transfer-Encoding: quoted-printable =46rom=206d9a9a4ce88f996d87fd121aaf6bfa21581fac30=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Yuan=20Fu=20=0ADate:=20Wed,=20= 26=20Apr=202023=2020:09:42=20-0700=0ASubject:=20[PATCH]=20Fix=20= FOR_EACH_TAIL=20in=20c-ts-mode=20(bug#62951)=0A=0A*=20= lisp/progmodes/c-ts-mode.el=0A(c-ts-mode--indent-styles):=20New=20indent=20= rule.=0A*=20lisp/progmodes/c-ts-mode.el=20= (c-ts-mode--for-each-tail-body-matcher):=0A= (c-ts-mode--emacs-c-range-query)=0A(c-ts-mode--for-each-tail-ranges)=0A= (c-ts-mode--reverse-ranges)=0A(c-ts-mode--emacs-set-ranges):=20New=20= functions=20and=20variables.=0A(c-ts-mode):=20Create=20a=20emacs-c=20= parser.=20=20More=20setup=20for=20Emacs=20source=0Asupport.=0A=0A*=20= lisp/treesit.el=20(treesit-query-range):=20Ignore=20underscore-prefixed=0A= capture=20names.=0A---=0A=20lisp/progmodes/c-ts-mode.el=20|=2092=20= ++++++++++++++++++++++++++++++++++++-=0A=20lisp/treesit.el=20=20=20=20=20= =20=20=20=20=20=20=20=20|=2017=20+++++--=0A=202=20files=20changed,=20103=20= insertions(+),=206=20deletions(-)=0A=0Adiff=20--git=20= a/lisp/progmodes/c-ts-mode.el=20b/lisp/progmodes/c-ts-mode.el=0Aindex=20= 6100f00e3ba..c4e1ba7a23a=20100644=0A---=20a/lisp/progmodes/c-ts-mode.el=0A= +++=20b/lisp/progmodes/c-ts-mode.el=0A@@=20-357,7=20+357,9=20@@=20= c-ts-mode--indent-styles=0A=20=20=20"Indent=20rules=20supported=20by=20= `c-ts-mode'.=0A=20MODE=20is=20either=20`c'=20or=20`cpp'."=0A=20=20=20= (let=20((common=0A-=20=20=20=20=20=20=20=20=20`(((parent-is=20= "translation_unit")=20column-0=200)=0A+=20=20=20=20=20=20=20=20=20= `((c-ts-mode--for-each-tail-body-matcher=20prev-line=20= c-ts-mode-indent-offset)=0A+=0A+=20=20=20=20=20=20=20=20=20=20=20= ((parent-is=20"translation_unit")=20column-0=200)=0A=20=20=20=20=20=20=20= =20=20=20=20=20((query=20"(ERROR=20(ERROR))=20@indent")=20column-0=200)=0A= =20=20=20=20=20=20=20=20=20=20=20=20((node-is=20")")=20parent=201)=0A=20=20= =20=20=20=20=20=20=20=20=20=20((node-is=20"]")=20parent-bol=200)=0A@@=20= -969,6=20+971,75=20@@=20c-ts-mode--emacs-current-defun-name=0A=20=20=20= (or=20(treesit-add-log-current-defun)=0A=20=20=20=20=20=20=20= (c-ts-mode--defun-name=20(c-ts-mode--emacs-defun-at-point))))=0A=20=0A= +;;;=20FOR_EACH_TAIL=20fix=0A+;;=0A+;;=20FOR_EACH_TAIL=20(and=20= FOR_EACH_TAIL_SAFE)=20followed=20by=20a=20unbracketed=0A+;;=20body=20= will=20mess=20up=20the=20parser,=20which=20parses=20the=20thing=20as=20a=20= function=0A+;;=20declaration.=20=20We=20"fix"=20it=20by=20adding=20a=20= shadow=20parser,=20emacs-c=20(which=0A+;;=20is=20just=20c=20but=20under=20= a=20different=20name).=20=20We=20use=20emacs-c=20to=20find=20each=0A+;;=20= FOR_EACH_TAIL=20with=20a=20unbracketed=20body,=20and=20set=20the=20= ranges=20of=20the=20C=0A+;;=20parser=20so=20that=20it=20skips=20those=20= FOR_EACH_TAIL's.=20=20Note=20that=20we=20only=0A+;;=20ignore=20= FOR_EACH_TAIL's=20with=20a=20unbracketed=20body.=20=20Those=20with=20a=0A= +;;=20bracketed=20body=20parses=20more=20or=20less=20fine.=0A+=0A+(defun=20= c-ts-mode--for-each-tail-body-matcher=20(_n=20_p=20bol=20&rest=20_)=0A+=20= =20"A=20matcher=20that=20matches=20the=20first=20line=20after=20a=20= FOR_EACH_TAIL.=0A+For=20BOL=20see=20`treesit-simple-indent-rules'."=0A+=20= =20(when=20c-ts-mode-emacs-sources-support=0A+=20=20=20=20= (save-excursion=0A+=20=20=20=20=20=20(goto-char=20bol)=0A+=20=20=20=20=20= =20(forward-line=20-1)=0A+=20=20=20=20=20=20(skip-chars-forward=20"=20= \t")=0A+=20=20=20=20=20=20(looking-at=20(rx=20"FOR_EACH_TAIL"=20(?=20(or=20= "_SAFE"=20"_ALIST_VALUE")))))))=0A+=0A+(defvar=20= c-ts-mode--emacs-c-range-query=0A+=20=20(treesit-query-compile=0A+=20=20=20= 'emacs-c=20`(((declaration=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20type:=20(macro_type_specifier=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20name:=20(identifier)=20@_name)=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20@for-each-tail)=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(:match=20,(rx=20"FOR_EACH_TAIL"=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(or=20"_SAFE"=20"_ALIST_VALUE")))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20@_name))))=0A+=20=20"Query=20that=20= finds=20the=20FOR_EACH_TAIL=20with=20a=20unbracketed=20body.")=0A+=0A= +(defvar-local=20c-ts-mode--for-each-tail-ranges=20nil=0A+=20=20"Ranges=20= covering=20all=20the=20FOR_EACH_TAIL's=20in=20the=20buffer.")=0A+=0A= +(defun=20c-ts-mode--reverse-ranges=20(ranges=20beg=20end)=0A+=20=20= "Reverse=20RANGES=20and=20return=20the=20new=20ranges=20between=20BEG=20= and=20END.=0A+Positions=20that=20were=20included=20RANGES=20are=20not=20= in=20the=20returned=0A+ranges,=20and=20vice=20versa.=0A+=0A+Return=20nil=20= if=20RANGES=20is=20nil.=20=20This=20way,=20passing=20the=20returned=0A= +ranges=20to=20`treesit-parser-set-included-ranges'=20will=20make=20the=0A= +parser=20parse=20the=20whole=20buffer."=0A+=20=20(if=20(null=20ranges)=0A= +=20=20=20=20=20=20nil=0A+=20=20=20=20(let=20((new-ranges=20nil)=0A+=20=20= =20=20=20=20=20=20=20=20(prev-end=20beg))=0A+=20=20=20=20=20=20(dolist=20= (range=20ranges)=0A+=20=20=20=20=20=20=20=20(push=20(cons=20prev-end=20= (car=20range))=20new-ranges)=0A+=20=20=20=20=20=20=20=20(setq=20prev-end=20= (cdr=20range)))=0A+=20=20=20=20=20=20(push=20(cons=20prev-end=20end)=20= new-ranges)=0A+=20=20=20=20=20=20(nreverse=20new-ranges))))=0A+=0A= +(defun=20c-ts-mode--emacs-set-ranges=20(beg=20end)=0A+=20=20"Set=20= ranges=20for=20the=20C=20parser=20to=20skip=20some=20FOR_EACH_TAIL's.=0A= +BEG=20and=20END=20are=20described=20in=20`treesit-range-rules'."=0A+=20=20= (let*=20((c-parser=20(treesit-parser-create=20'c))=0A+=20=20=20=20=20=20=20= =20=20(old-ranges=20c-ts-mode--for-each-tail-ranges)=0A+=20=20=20=20=20=20= =20=20=20(new-ranges=20(treesit-query-range=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20'emacs-c=20= c-ts-mode--emacs-c-range-query=20beg=20end))=0A+=20=20=20=20=20=20=20=20=20= (set-ranges=20(treesit--clip-ranges=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(treesit--merge-ranges=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20old-ranges=20= new-ranges=20beg=20end)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(point-min)=20(point-max)))=0A+=20=20=20=20=20=20=20=20= =20(reversed-ranges=20(c-ts-mode--reverse-ranges=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=20set-ranges=20= (point-min)=20(point-max))))=0A+=20=20=20=20(setq-local=20= c-ts-mode--for-each-tail-ranges=20set-ranges)=0A+=20=20=20=20= (treesit-parser-set-included-ranges=20c-parser=20reversed-ranges)))=0A+=0A= =20;;;=20Modes=0A=20=0A=20(defvar-keymap=20c-ts-base-mode-map=0A@@=20= -1072,6=20+1143,13=20@@=20c-ts-mode=0A=20=20=20:after-hook=20= (c-ts-mode-set-modeline)=0A=20=0A=20=20=20(when=20(treesit-ready-p=20'c)=0A= +=20=20=20=20;;=20If=20Emacs=20source=20support=20is=20enabled,=20make=20= sure=20emacs-c=20parser=20is=0A+=20=20=20=20;;=20after=20c=20parser=20in=20= the=20parser=20list.=20This=20way=20various=20tree-sitter=0A+=20=20=20=20= ;;=20functions=20will=20automatically=20use=20the=20c=20parser=20rather=20= than=20the=0A+=20=20=20=20;;=20emacs-c=20parser.=0A+=20=20=20=20(when=20= c-ts-mode-emacs-sources-support=0A+=20=20=20=20=20=20= (treesit-parser-create=20'emacs-c))=0A+=0A=20=20=20=20=20= (treesit-parser-create=20'c)=0A=20=20=20=20=20;;=20Comments.=0A=20=20=20=20= =20(setq-local=20comment-start=20"/*=20")=0A@@=20-1087,7=20+1165,17=20@@=20= c-ts-mode=0A=20=0A=20=20=20=20=20(when=20c-ts-mode-emacs-sources-support=0A= =20=20=20=20=20=20=20(setq-local=20add-log-current-defun-function=0A-=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= #'c-ts-mode--emacs-current-defun-name))))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20#'c-ts-mode--emacs-current-defun-name)=0A+=0A+=20= =20=20=20=20=20(setq-local=20treesit-range-settings=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(treesit-range-rules=20= 'c-ts-mode--emacs-set-ranges))=0A+=0A+=20=20=20=20=20=20(setq-local=20= treesit-language-at-point-function=20(lambda=20(_pos)=20'c))=0A+=0A+=20=20= =20=20=20=20;;=20Add=20a=20fake=20"emacs-c"=20language=20which=20is=20= just=20C.=20=20Used=20for=0A+=20=20=20=20=20=20;;=20skipping=20= FOR_EACH_TAIL,=20see=20`c-ts-mode--emacs-set-ranges'.=0A+=20=20=20=20=20=20= (setf=20(alist-get=20'emacs-c=20treesit-load-name-override-list)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20'("libtree-sitter-c"=20= "tree_sitter_c")))))=0A=20=0A=20;;;###autoload=0A=20(define-derived-mode=20= c++-ts-mode=20c-ts-base-mode=20"C++"=0Adiff=20--git=20a/lisp/treesit.el=20= b/lisp/treesit.el=0Aindex=20e718ea1a23a..1d4749c8cd2=20100644=0A---=20= a/lisp/treesit.el=0A+++=20b/lisp/treesit.el=0A@@=20-378,13=20+378,16=20= @@=20treesit-query-string=0A=20(defun=20treesit-query-range=20(node=20= query=20&optional=20beg=20end)=0A=20=20=20"Query=20the=20current=20= buffer=20and=20return=20ranges=20of=20captured=20nodes.=0A=20=0A-QUERY,=20= NODE,=20BEG,=20END=20are=20the=20same=20as=20in=0A= -`treesit-query-capture'.=20=20This=20function=20returns=20a=20list=0A= -of=20(START=20.=20END),=20where=20START=20and=20END=20specifics=20the=20= range=20of=20each=0A-captured=20node.=20=20Capture=20names=20don't=20= matter."=0A+QUERY,=20NODE,=20BEG,=20END=20are=20the=20same=20as=20in=20= `treesit-query-capture'.=0A+This=20function=20returns=20a=20list=20of=20= (START=20.=20END),=20where=20START=20and=0A+END=20specifics=20the=20= range=20of=20each=20captured=20node.=20=20Capture=20names=0A+generally=20= don't=20matter,=20but=20names=20that=20starts=20with=20an=20underscore=0A= +are=20ignored."=0A=20=20=20(cl-loop=20for=20capture=0A=20=20=20=20=20=20= =20=20=20=20=20=20in=20(treesit-query-capture=20node=20query=20beg=20= end)=0A+=20=20=20=20=20=20=20=20=20=20=20for=20name=20=3D=20(car=20= capture)=0A=20=20=20=20=20=20=20=20=20=20=20=20for=20node=20=3D=20(cdr=20= capture)=0A+=20=20=20=20=20=20=20=20=20=20=20if=20(not=20= (string-prefix-p=20"_"=20(symbol-name=20name)))=0A=20=20=20=20=20=20=20=20= =20=20=20=20collect=20(cons=20(treesit-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= (treesit-node-end=20node))))=0A=20=0A@@=20-399,6=20+402,9=20@@=20= treesit-range-settings=0A=20range=20to=20the=20range=20spanned=20by=20= captured=20nodes.=20=20QUERY=20must=20be=20a=0A=20compiled=20query.=0A=20= =0A+Capture=20names=20generally=20don't=20matter,=20but=20names=20that=20= starts=20with=0A+an=20underscore=20are=20ignored.=0A+=0A=20QUERY=20can=20= also=20be=20a=20function,=20in=20which=20case=20it=20is=20called=20with=20= 2=0A=20arguments,=20START=20and=20END.=20=20It=20should=20ensure=20= parsers'=20ranges=20are=0A=20correct=20in=20the=20region=20between=20= START=20and=20END.=0A@@=20-418,6=20+424,9=20@@=20treesit-range-rules=0A=20= Each=20QUERY=20is=20a=20tree-sitter=20query=20in=20either=20the=20= string,=0A=20s-expression=20or=20compiled=20form.=0A=20=0A+Capture=20= names=20generally=20don't=20matter,=20but=20names=20that=20starts=20with=0A= +an=20underscore=20are=20ignored.=0A+=0A=20For=20each=20QUERY,=20= :KEYWORD=20and=20VALUE=20pairs=20add=20meta=20information=20to=0A=20it.=20= =20For=20example,=0A=20=0A--=20=0A2.33.1=0A=0A= --Apple-Mail=_C19C1CC5-40F6-4BFB-B14A-97E439DD0C7D--