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#73404: 30.0.50; [forward/kill/etc]-sexp commands do not behave as expected in tree-sitter modes Date: Tue, 10 Dec 2024 22:31:26 -0800 Message-ID: References: <87plox4mtp.fsf@masteringemacs.org> <87frpm20t7.fsf@masteringemacs.org> <8634lmbs8t.fsf@gnu.org> <87bk0a1u0o.fsf@masteringemacs.org> <86tte2a5o3.fsf@gnu.org> <877cay1lqt.fsf@masteringemacs.org> <86frpma06f.fsf@gnu.org> <86ikueiekp.fsf@mail.linkov.net> <86ed4zg1cc.fsf@mail.linkov.net> <87zflac68t.fsf@mail.linkov.net> <87jzcdlxdp.fsf@mail.linkov.net> <87o71jocgs.fsf@mail.linkov.net> Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3776.700.51\)) Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="20640"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Theodor Thornhill , Eli Zaretskii , Mickey Petersen , 73404@debbugs.gnu.org, Stefan Monnier To: Juri Linkov Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Wed Dec 11 07:39:28 2024 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 1tLGNb-0005EW-A5 for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 11 Dec 2024 07:39:27 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLGHZ-00080m-5H; Wed, 11 Dec 2024 01:33:13 -0500 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 1tLGHS-0007dK-LQ for bug-gnu-emacs@gnu.org; Wed, 11 Dec 2024 01:33:06 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tLGHS-0000B1-70 for bug-gnu-emacs@gnu.org; Wed, 11 Dec 2024 01:33:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=References:Date:In-Reply-To:From:Mime-Version:To:Subject; bh=KthLNndSnFM9j2SwKPlZ5N7rIaMVCa98IPmti5HnFP4=; b=esBGZgbpKrwUiFQpWEh1r0qcXws4R6I62IOtmr4lUqlun5YMSCmSALKpnX28nKFOI7gtu4aYCnRjqAbFCZa3dbEeMKWwCQZcocVEEFReVtt2RKz/BqxBkXAcmeNtYGwVity5L5ydabEfGyCs7rQlrhj0EHbbZDYGjq570Xxebqr5/aBIAUDX2tPF5psU/bLBxtnPUJn4kKaYI270cTJLqD5yuJVTeWoMBXgsK0p7opdgtIB5OdgsBwXCll6tCfWbm2pnP3ATL0uI+3QSCjVn5SRBF/zqNT3/QtKTArwnMo0fJLFqhHyq132bfuv6NESsU+yi09uIC8g+EOIChXlTbA==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tLGHO-0007Gp-In for bug-gnu-emacs@gnu.org; Wed, 11 Dec 2024 01:33:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Yuan Fu Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 11 Dec 2024 06:33:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 73404 X-GNU-PR-Package: emacs Original-Received: via spool by 73404-submit@debbugs.gnu.org id=B73404.173389877027924 (code B ref 73404); Wed, 11 Dec 2024 06:33:02 +0000 Original-Received: (at 73404) by debbugs.gnu.org; 11 Dec 2024 06:32:50 +0000 Original-Received: from localhost ([127.0.0.1]:60865 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tLGH8-0007GB-HX for submit@debbugs.gnu.org; Wed, 11 Dec 2024 01:32:50 -0500 Original-Received: from mail-pl1-f170.google.com ([209.85.214.170]:54479) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tLGH2-0007Fx-JW for 73404@debbugs.gnu.org; Wed, 11 Dec 2024 01:32:45 -0500 Original-Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-2163bd70069so33415205ad.0 for <73404@debbugs.gnu.org>; Tue, 10 Dec 2024 22:32:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1733898698; x=1734503498; darn=debbugs.gnu.org; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=KthLNndSnFM9j2SwKPlZ5N7rIaMVCa98IPmti5HnFP4=; b=ZVtHdjKWB6yJclQM5g5zIQ2nLyozrzu7N4vwGqqZkk/YWnMzMupsYczkclaki1MKLN zr4RjahbaJ1fksfp2eIH0CnXDJC9vhCc5RpO0SF71cIDdU982s8rAoYidl/VC3acufJX +U1k4mqVYapjXYUcKZzO2a9D4lSvCYfpFs4LLxZE6W9f949b1I5qM+lgxEh2sqyK/r5u gequ1AYAok7aDbZBxNdjIXDIzqm9YGwmxaDhOv4errcFf9sWu0MH6Rd58iKFdXcubVcY I5nwlX5WGnZ5xNihgmvCzjsj9opnU+nNXgQG9arIhWOf+1miXgt0KNOIEZwJy+/XgVx8 ERQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733898698; x=1734503498; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KthLNndSnFM9j2SwKPlZ5N7rIaMVCa98IPmti5HnFP4=; b=QpfX+ga3a5lkJlzNooshqEVIb/USHrHTl0t4TwA8t5mudQmKBokqCqfmQtCgghVNqF V2kg8GEhCVC4jAx+t7XSwWTNhJcrWSunkH3KkTMO4sPTa+0AL7DDBJ6TZJnV7RmqM4NY Zy9ovajN9aFPtX86YX21Vxov79X++vWYRCflGv4TUXqL2ncnF4bLsRUvSwLwHGhocXy0 WTiSA0uLJj09c8WZvBfQD5CIS8gHN6KL1WbOdalkrkz11g0+abLtPFApl+Y5LoBLVa5v 4SoDl2VEDZ1B0AQI6sq+hZFemw/oeqcZR/sIgfKt9kK+hm6/qMbMVQ3FXdyobIJOSoIn RekA== X-Forwarded-Encrypted: i=1; AJvYcCXGdRdZDnVYqx9hWhP7AGU0YrHH6uOdTDhYqRgmRB2LeJPrvx8xNzG35Cpiy+0ZChUVHFE1PQ==@debbugs.gnu.org X-Gm-Message-State: AOJu0YxowwA+6YsPbnRHhj93AXCY2yB+OXkjatqNkf5GDHqRbLYkdhxf nqBDDAObkuhPbLcUEnwWooyS44t46T0hvg+00o8UUB/GSVGXUdIt X-Gm-Gg: ASbGncvblgadAn1C7c6u7KV5GtP6IqgHdItc5RMBMSepOxewOh6oSIMQVuop29oD7Pk a/qaKw7zk3oIjPpF5u/ylQcWr/dkfqcaoXzRjsN/8yfgWY4gErVYDA+3OfzAftTXZev2ZRWJ6Wi YewqsAwQYwb9Wd3JMafelwnfUGCZkoac2F9NOeuAPIb8t5xr12+PxfP7Ox8av3jafGQlihUcGPW U8uoPdZs0akIZPjHTfCoiJU5DGXBeGNPQ8/P34MlS7yV2xop+fobMM+lZVvv1ejwSYl9xAYXTQD Rg== X-Google-Smtp-Source: AGHT+IHKszyUzGB0G8jGDuK4heO36K2xAh+fzTY8PWwBFKvxRhjisQYfUz6njTHYRxpbPC9Ct5qOSw== X-Received: by 2002:a17:903:945:b0:215:7fad:49ab with SMTP id d9443c01a7336-2177851f6a0mr32503325ad.10.1733898698497; Tue, 10 Dec 2024 22:31:38 -0800 (PST) Original-Received: from smtpclient.apple ([2601:646:8f81:6120:f90e:3b71:6ee2:6197]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21653b0d4f5sm42787205ad.70.2024.12.10.22.31.37 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Dec 2024 22:31:37 -0800 (PST) In-Reply-To: <87o71jocgs.fsf@mail.linkov.net> X-Mailer: Apple Mail (2.3776.700.51) 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:296802 Archived-At: > On Dec 10, 2024, at 9:20=E2=80=AFAM, Juri Linkov = wrote: >=20 >>> export const add =3D (a, b) -!- =3D> a + b; >>>=20 >>> typing 'C-M-f' should jump to the end of the next sexp >>> (to the end of whole "binary_expression"): >>>=20 >>> export const add =3D (a, b) =3D> a + b-!-; >>>=20 >>> since only tree-sitter knows about "binary_expression", >>> so 'forward-sexp-default-function' can't be used here. >>=20 >> Actually, I have one idea of possible heuristics: >>=20 >> 1. first try 'forward-sexp-default-function' >> 2. if it crosses the boundary of sexp defined by = 'treesit-thing-settings' >> then use 'treesit-end-of-thing' instead >>=20 >> This should work. Ok, will try. >=20 > This is implemented now in the attached patch, and it works nicely. >=20 > The main rule is the following: 'forward-sexp-default-function' > should not go out of the current thing, neither go inside a sibling. > So we use 'treesit-end-of-thing' in such cases. But when inside > a thing or outside a thing, use the default function. >=20 > This supposes that such things as "identifier" in js should be > removed from 'treesit-thing-settings' since identifiers should be > navigated the same way as such keywords as "export" and "const" > using 'forward-sexp-default-function'. >=20 > What should remain in 'treesit-thing-settings' are only grouping > constructs such as "parenthesized_expression" and "statement_block". Ah, this matches my idea of defining sexp in other languages as = =E2=80=9Crepeatable construct/list-like construct=E2=80=9D. We went with = =E2=80=9Cevery syntactic construct=E2=80=9D at the time, which I = didn=E2=80=99t object to, but I=E2=80=99m definitely happier with the = repeatable construct approach. Including Stefan and Theo since they were = part of the original sexp navigation discussion. My only concern is that would the result be a bit = unpredictable/confusing when we mix the result of two logic together in = such an involved way? We can push to master and try it out for a while. = I use tree-sitter sexp navigation for work every day, albeit strictly = for navigating list-like constructs=E2=80=94I use forward/backward-word = for smaller navigation. >=20 > Removing "identifier" from 'treesit-thing-settings' exposed a problem > in 'treesit-navigate-thing'. This line >=20 > ((and (null next) (null prev)) parent) >=20 > tries to go out of the current thing to its parent, > thus breaking the main principle that 'forward-sexp' > should move forward across siblings only. But removing > this line fixed the problem: Thanks, LGTM. >=20 > diff --git a/lisp/treesit.el b/lisp/treesit.el > index db8f7a7595d..4fcdbe7fc56 100644 > --- a/lisp/treesit.el > +++ b/lisp/treesit.el > @@ -2373,21 +2373,41 @@ treesit-forward-sexp > What constitutes as text and source code sexp is determined > by `text' and `sexp' in `treesit-thing-settings'." > (interactive "^p") > - (let ((arg (or arg 1)) > - (pred (or treesit-sexp-type-regexp 'sexp)) > - (node-at-point > - (treesit-node-at (point) (treesit-language-at (point))))) > - (or (when (and node-at-point > - ;; Make sure point is strictly inside node. > - (< (treesit-node-start node-at-point) > - (point) > - (treesit-node-end node-at-point)) > - (treesit-node-match-p node-at-point 'text t)) > - (forward-sexp-default-function arg) > - t) > - (if (> arg 0) > - (treesit-end-of-thing pred (abs arg) 'restricted) > - (treesit-beginning-of-thing pred (abs arg) 'restricted)) > + (let* ((arg (or arg 1)) > + (pred (or treesit-sexp-type-regexp 'sexp)) > + (current-thing (treesit-thing-at (point) pred t)) > + (default-pos > + (condition-case _ > + (save-excursion > + (forward-sexp-default-function arg) > + (point)) > + (scan-error nil))) > + (default-pos (unless (eq (point) default-pos) default-pos)) > + (sibling-pos > + (save-excursion > + (and (if (> arg 0) > + (treesit-end-of-thing pred (abs arg) = 'restricted) > + (treesit-beginning-of-thing pred (abs arg) = 'restricted)) > + (point)))) > + (sibling (when sibling-pos > + (if (> arg 0) > + (treesit-thing-prev sibling-pos pred) > + (treesit-thing-next sibling-pos pred))))) > + > + ;; 'forward-sexp-default-function' should not go out of the = current thing, > + ;; neither go inside the next thing, neither go over the next = thing > + (or (when (and default-pos > + (or (null current-thing) > + (if (> arg 0) > + (< default-pos (treesit-node-end = current-thing)) > + (> default-pos (treesit-node-start = current-thing)))) > + (or (null sibling) > + (if (> arg 0) > + (< default-pos (treesit-node-start = sibling)) > + (> default-pos (treesit-node-end = sibling))))) > + (goto-char default-pos)) > + (when sibling-pos > + (goto-char sibling-pos)) > ;; If we couldn't move, we should signal an error and report > ;; the obstacle, like `forward-sexp' does. If we couldn't > ;; find a parent, we simply return nil without moving point, > @@ -2849,8 +2869,7 @@ treesit-navigate-thing > (if (eq tactic 'restricted) > (setq pos (funcall > advance > - (cond ((and (null next) (null prev)) parent) > - ((> arg 0) next) > + (cond ((> arg 0) next) > (t prev)))) > ;; For `nested', it's a bit more work: > ;; Move...