Received: (at 76398) by debbugs.gnu.org; 19 Feb 2025 07:47:07 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Wed Feb 19 02:47:07 2025 Received: from localhost ([127.0.0.1]:41309 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1tkenS-00007B-W9 for submit <at> debbugs.gnu.org; Wed, 19 Feb 2025 02:47:07 -0500 Received: from relay7-d.mail.gandi.net ([2001:4b98:dc4:8::227]:52679) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1tkenP-00005n-Tz for 76398 <at> debbugs.gnu.org; Wed, 19 Feb 2025 02:47:04 -0500 Received: by mail.gandi.net (Postfix) with ESMTPSA id 293EA441F0; Wed, 19 Feb 2025 07:46:53 +0000 (UTC) From: Juri Linkov <juri@HIDDEN> To: 76398 <at> debbugs.gnu.org Subject: Re: bug#76398: treesit-aggregated-outline-predicate In-Reply-To: <87tt8rrwnf.fsf@HIDDEN> Organization: LINKOV.NET References: <87tt8rrwnf.fsf@HIDDEN> Date: Wed, 19 Feb 2025 09:46:23 +0200 Message-ID: <87frkas7g0.fsf@HIDDEN> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/31.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain X-GND-State: clean X-GND-Score: 0 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdeifeeikecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfitefpfffkpdcuggftfghnshhusghstghrihgsvgenuceurghilhhouhhtmecufedtudenucenucfjughrpefhvfevufgjohhffffkfgggtgesthdtredttdertdenucfhrhhomheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqeenucggtffrrghtthgvrhhnpeffgeetfeevlefhleejfeeuheeiudeitdffhfdutdekfeffgffhveehteegueekheenucfkphepledurdduvdelrdelkedrheenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeeluddruddvledrleekrdehpdhhvghlohepmhgrihhlrdhgrghnughirdhnvghtpdhmrghilhhfrhhomhepjhhurhhisehlihhnkhhovhdrnhgvthdpnhgspghrtghpthhtohepfedprhgtphhtthhopehvrdhpuhhpihhllhhosehgmhgrihhlrdgtohhmpdhrtghpthhtoheptggrshhouhhrihesghhmrghilhdrtghomhdprhgtphhtthhopeejieefleekseguvggssghughhsrdhgnhhurdhorhhg X-GND-Sasl: juri@HIDDEN X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 76398 Cc: casouri@HIDDEN, v.pupillo@HIDDEN X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -1.0 (-) > So this patch helps 'treesit-outline-search' to get out of the local parser > to the primary parser to continue search for the next outline predicate. > > 'treesit-outline-level' should do the same, but currently I can't find > a suitable function to break out of embedded confinement > and get the host node that contains the guest ranges. > I mean that e.g. (treesit-parser-root-node (treesit-node-parser node)) > can get the root node of the local parser, but how to get its parent node > in the primary parser? It's understandable that treesit-node-parent > doesn't go out of its parser. But maybe there is another function? > If such function doesn't exist, this is fine, then could find that > node manually by calculating from treesit-parser-included-ranges. Maybe we need two new primitives: (treesit-next-parser-boundary POS) (treesit-prev-parser-boundary POS) and (treesit-upper-parser-node POS)
bug-gnu-emacs@HIDDEN
:bug#76398
; Package emacs
.
Full text available.Received: (at submit) by debbugs.gnu.org; 18 Feb 2025 17:35:13 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Tue Feb 18 12:35:13 2025 Received: from localhost ([127.0.0.1]:60578 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1tkRV2-0002Yk-FR for submit <at> debbugs.gnu.org; Tue, 18 Feb 2025 12:35:13 -0500 Received: from lists.gnu.org ([2001:470:142::17]:44942) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <juri@HIDDEN>) id 1tkRV0-0002T0-PA for submit <at> debbugs.gnu.org; Tue, 18 Feb 2025 12:35:11 -0500 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 <juri@HIDDEN>) id 1tkRUu-0001CB-QE for bug-gnu-emacs@HIDDEN; Tue, 18 Feb 2025 12:35:05 -0500 Received: from relay2-d.mail.gandi.net ([217.70.183.194]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <juri@HIDDEN>) id 1tkRUr-0001zy-QF for bug-gnu-emacs@HIDDEN; Tue, 18 Feb 2025 12:35:04 -0500 Received: by mail.gandi.net (Postfix) with ESMTPSA id C8BAB4418D for <bug-gnu-emacs@HIDDEN>; Tue, 18 Feb 2025 17:34:56 +0000 (UTC) From: Juri Linkov <juri@HIDDEN> To: bug-gnu-emacs@HIDDEN Subject: treesit-aggregated-outline-predicate Organization: LINKOV.NET X-Debbugs-Cc: casouri@HIDDEN, v.pupillo@HIDDEN Date: Tue, 18 Feb 2025 19:27:17 +0200 Message-ID: <87tt8rrwnf.fsf@HIDDEN> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/31.0.50 (x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-GND-State: clean X-GND-Score: 0 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdeiudelvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfitefpfffkpdcuggftfghnshhusghstghrihgsvgenuceurghilhhouhhtmecufedtudenucenucfjughrpefhvffuohffkfgfgggtsehmtderredtredtnecuhfhrohhmpefluhhrihcunfhinhhkohhvuceojhhurhhisehlihhnkhhovhdrnhgvtheqnecuggftrfgrthhtvghrnhepveetfeeiuefhtdeguedukefgjeejkedvvdevhfdvfedtieefkeevleeikefffedunecukfhppeeluddruddvledrleekrdehnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepledurdduvdelrdelkedrhedphhgvlhhopehmrghilhdrghgrnhguihdrnhgvthdpmhgrihhlfhhrohhmpehjuhhriheslhhinhhkohhvrdhnvghtpdhnsggprhgtphhtthhopedupdhrtghpthhtohepsghughdqghhnuhdqvghmrggtshesghhnuhdrohhrgh X-GND-Sasl: juri@HIDDEN Received-SPF: pass client-ip=217.70.183.194; envelope-from=juri@HIDDEN; helo=relay2-d.mail.gandi.net X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, TRACKER_ID=0.1 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: 0.8 (/) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -0.2 (/) --=-=-= Content-Type: text/plain As discussed in bug#74610, in multi-language modes treesit-outline-predicate ends abruptly after the first embedded range since it can't find more matches in its range, it can't go out back to the primary parser. So this patch helps 'treesit-outline-search' to get out of the local parser to the primary parser to continue search for the next outline predicate. 'treesit-outline-level' should do the same, but currently I can't find a suitable function to break out of embedded confinement and get the host node that contains the guest ranges. I mean that e.g. (treesit-parser-root-node (treesit-node-parser node)) can get the root node of the local parser, but how to get its parent node in the primary parser? It's understandable that treesit-node-parent doesn't go out of its parser. But maybe there is another function? If such function doesn't exist, this is fine, then could find that node manually by calculating from treesit-parser-included-ranges. --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=treesit-aggregated-outline-predicate.patch diff --git a/lisp/textmodes/mhtml-ts-mode.el b/lisp/textmodes/mhtml-ts-mode.el index 83f8879f427..7a481599310 100644 --- a/lisp/textmodes/mhtml-ts-mode.el +++ b/lisp/textmodes/mhtml-ts-mode.el @@ -580,7 +580,10 @@ mhtml-ts-mode (setq-local treesit-aggregated-simple-imenu-settings mhtml-ts-mode--treesit-aggregated-simple-imenu-settings) - ;; (setq-local treesit-outline-predicate nil) + (setq-local treesit-aggregated-outline-predicate + `((html . ,#'html-ts-mode--outline-predicate) + (javascript . "\\`function_declaration\\'") + (css . "\\`rule_set\\'"))) (treesit-major-mode-setup) diff --git a/lisp/treesit.el b/lisp/treesit.el index 30efd4d4599..ab9bfc33d3d 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -3601,6 +3601,16 @@ treesit-outline-predicate is constructed from the value of `treesit-simple-imenu-settings' when a major mode sets it.") +(defvar-local treesit-aggregated-outline-predicate nil + "Settings that configure `treesit-outline-search' for multi-language modes. + +The value should be an alist of (LANG . SETTINGS), where LANG is a +language symbol, and SETTINGS has the same form as +`treesit-outline-predicate'. + +When both this variable and `treesit-outline-predicate' are non-nil, +this variable takes priority.") + (defun treesit-outline-predicate--from-imenu (node) ;; Return an outline searching predicate created from Imenu. ;; Return the value suitable to set `treesit-outline-predicate'. @@ -3618,7 +3628,10 @@ treesit-outline-predicate--from-imenu (defun treesit-outline--at-point () "Return the outline heading node at the current line." - (let* ((pred treesit-outline-predicate) + (let* ((pred (if treesit-aggregated-outline-predicate + (alist-get (treesit-language-at (point)) + treesit-aggregated-outline-predicate) + treesit-outline-predicate)) (bol (pos-bol)) (eol (pos-eol)) (current (treesit-thing-at (point) pred)) @@ -3649,9 +3662,35 @@ treesit-outline-search (if (eq (point) (pos-bol)) (if (bobp) (point) (1- (point))) (pos-eol)))) + (pred (if treesit-aggregated-outline-predicate + (alist-get (treesit-language-at pos) + treesit-aggregated-outline-predicate) + treesit-outline-predicate)) (found (or bob-pos - (treesit-navigate-thing pos (if backward -1 1) 'beg - treesit-outline-predicate)))) + (treesit-navigate-thing pos (if backward -1 1) 'beg pred)))) + + ;; Handle multi-language modes + (when-let* ((ranges (mapcar #'treesit-parser-included-ranges + (treesit-parser-list))) + (ranges (delq nil (delete '((1 . 1)) ranges)))) + (if found + nil + ;; Possibly was inside the local range, and when can't find + ;; more matches inside the local range then need to go out + (when-let* ((bounds (seq-filter + (lambda (p) (if backward (< p pos) (> p pos))) + (flatten-list + (mapcar (lambda (rr) + (mapcar (if backward #'car #'cdr) rr)) + ranges)))) + (closest (when bounds (if backward (seq-max bounds) (seq-min bounds))))) + (setq found (treesit-navigate-thing + closest (if backward -1 1) 'beg + (if treesit-aggregated-outline-predicate + (alist-get (treesit-language-at closest) + treesit-aggregated-outline-predicate) + treesit-outline-predicate)))))) + (if found (if (or (not bound) (if backward (>= found bound) (<= found bound))) (progn @@ -3667,10 +3706,25 @@ treesit-outline-search (defun treesit-outline-level () "Return the depth of the current outline heading." (let* ((node (treesit-outline--at-point)) - (level 1)) - (while (setq node (treesit-parent-until node treesit-outline-predicate)) + (level 1) + (parser (when treesit-aggregated-outline-predicate + (treesit-node-parser node))) + (pred (if treesit-aggregated-outline-predicate + (alist-get (treesit-language-at (point)) + treesit-aggregated-outline-predicate) + treesit-outline-predicate))) + (while (setq node (treesit-parent-until node pred)) (setq level (1+ level))) - (if (zerop level) 1 level))) + (when-let* ((_ parser) + (host-lang (treesit-parser-language treesit-primary-parser)) + (_ (not (eq (treesit-language-at (point)) host-lang))) + (host-pred (alist-get host-lang treesit-aggregated-outline-predicate))) + ;; Now need to break out of embedded confinement + ;; and get the host node that contains the guest ranges + (setq node (treesit-parser-root-node parser)) + (while (setq node (treesit-parent-until node host-pred)) + (setq level (1+ level)))) + level)) ;;; Hideshow mode @@ -3955,11 +4009,14 @@ treesit-major-mode-setup #'treesit-simple-imenu)) ;; Outline minor mode. - (when (and (or treesit-outline-predicate treesit-simple-imenu-settings) + (when (and (or treesit-outline-predicate + treesit-aggregated-outline-predicate + treesit-simple-imenu-settings) (not (seq-some #'local-variable-p '(outline-search-function outline-regexp outline-level)))) - (unless treesit-outline-predicate + (unless (or treesit-outline-predicate + treesit-aggregated-outline-predicate) (setq treesit-outline-predicate #'treesit-outline-predicate--from-imenu)) (setq-local outline-search-function #'treesit-outline-search --=-=-=--
Juri Linkov <juri@HIDDEN>
:casouri@HIDDEN, v.pupillo@HIDDEN, bug-gnu-emacs@HIDDEN
.
Full text available.casouri@HIDDEN, v.pupillo@HIDDEN, bug-gnu-emacs@HIDDEN
:bug#76398
; Package emacs
.
Full text available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997 nCipher Corporation Ltd,
1994-97 Ian Jackson.