From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Theodor Thornhill via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#60623: 30.0.50; Add forward-sentence with tree sitter support Date: Sun, 08 Jan 2023 14:29:08 +0100 Message-ID: <87bkn9tasb.fsf@thornhill.no> References: <87o7ratva2.fsf@thornhill.no> Reply-To: Theodor Thornhill Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="4326"; mail-complaints-to="usenet@ciao.gmane.io" Cc: juri@linkov.net, eliz@gnu.org, casouri@gmail.com, monnier@iro.umontreal.ca To: mardani29@yahoo.es, 60623@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Jan 08 14:30:17 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 1pEVkf-0000uj-F4 for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 08 Jan 2023 14:30:17 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pEVkV-00082b-Mz; Sun, 08 Jan 2023 08:30:07 -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 1pEVkR-00081W-Gz for bug-gnu-emacs@gnu.org; Sun, 08 Jan 2023 08:30:03 -0500 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 1pEVkR-0001mR-2O for bug-gnu-emacs@gnu.org; Sun, 08 Jan 2023 08:30:03 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1pEVkQ-0002j0-Sx for bug-gnu-emacs@gnu.org; Sun, 08 Jan 2023 08:30:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Theodor Thornhill Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 08 Jan 2023 13:30:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 60623 X-GNU-PR-Package: emacs X-Debbugs-Original-To: Daniel =?UTF-8?Q?Mart=C3=ADn?= , "Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors" X-Debbugs-Original-Cc: 60623@debbugs.gnu.org, Juri Linkov , eliz@gnu.org, casouri@gmail.com, monnier@iro.umontreal.ca Original-Received: via spool by 60623-submit@debbugs.gnu.org id=B60623.167318456110374 (code B ref 60623); Sun, 08 Jan 2023 13:30:02 +0000 Original-Received: (at 60623) by debbugs.gnu.org; 8 Jan 2023 13:29:21 +0000 Original-Received: from localhost ([127.0.0.1]:60165 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pEVjk-0002hG-EX for submit@debbugs.gnu.org; Sun, 08 Jan 2023 08:29:21 -0500 Original-Received: from out-169.mta0.migadu.com ([91.218.175.169]:33382) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pEVjf-0002h3-6c for 60623@debbugs.gnu.org; Sun, 08 Jan 2023 08:29:18 -0500 X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=thornhill.no; s=key1; t=1673184551; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Lp8ykaFXYWu8wZubiihEG3kFHW4R0zwR2rZQumYrvx4=; b=N/MpNEvbxy+ZgCjJ3BeopeQbUZwWmW4D56sVbuLSRE8DmADt1W20dcPhPgaFWdMbiVuGKJ b19futOCtREEITzXFcZ/iDSZz2AJpvlWa4oKeDvT5hZk7RVElvEWrXlgECa5lhd5fuh3ds r2XsKubCTHl41rivWjO2rarJkPvT0mFZU1iXpq/ExcR3cbPEGms80EpkRVVBLQaI2yIFE7 aJH4ZXw9D7d9ryVG05qOUkZ5+E2MBCOkZvCabfyI+nBXIqlnaExcqkCnlbL+CZmBbl6A/8 cS0W6cTDRlyl8yTph9e1Z/YGW7mlO5de5z3mHTdmscZYXa6eIuLkrSzkmk74Ow== In-Reply-To: X-Migadu-Flow: FLOW_OUT 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:252923 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Daniel Mart=C3=ADn writes: > Theodor Thornhill via "Bug reports for GNU Emacs, the Swiss army knife > of text editors" writes: > >> Hi all! >> >> This patch tweaks the forward-sentence function to be usable with >> tree-sitter. >> >> It follows the same style as the recent change in transpose-sexps, so I >> hope it isn't too controversial. > > Thanks. > >> >> What exact node types do you consider useful for sentence movement? >> > > I haven't thought much about your proposed nodes, I initially thought > that sentences in a programming language are just "statements". They aren't really proper propsals. Mostly some example values to show that the code works. The problem with just stating "statements" is that the names are different across parsers. So in java one would call ``` void foo() { var foo =3D 5; // <-- This thing } ``` A "local_variable_declaration" or something like that. But it would make sense for M-e to move across that whole line. So this is language dependent, I believe. > > As a suggestion, treesit-forward-sentence could navigate by textual > sentences when point is inside comments or strings. > Yeah, this is a good idea - added in following patch. >> +** New defvar-local forward-sentence-function. >> +The previous implementation of 'forward-sentence' is moved into this >> +variable, which can be set to customize the sentece movement behavior. > ^^^^^^^ > sentence > Thanks - fixed. > Also, this feature probably needs an update to the Info documentation to > mention that Tree-sitter can specialize sentence commands in programming > modes. Yes, likely. I will add this a bit later, when we agree on its behavior fully :) @Eli, what doc changes do you see as needed here? @Juri: I added a change with how I understood what you meant. Is that in your line of reasoning? Theo --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Add-forward-sentence-with-tree-sitter-support-bug-60.patch >From 62d6f162ba7646783675dc87199ca31691164bf4 Mon Sep 17 00:00:00 2001 From: Theodor Thornhill Date: Sat, 7 Jan 2023 12:44:14 +0100 Subject: [PATCH] Add forward-sentence with tree sitter support (bug#60623) * etc/NEWS: Mention the new changes. * lisp/progmodes/c-ts-mode.el (c-ts-base-mode): Set the variable. * lisp/progmodes/java-ts-mode.el (java-ts-mode): Set the variable. * lisp/textmodes/paragraphs.el (forward-sentence-default-function): Move old implementation to its own function. (forward-sentence-function): New defvar defaulting to old behavior. (forward-sentence): Use the variable in this function unconditionally. * lisp/treesit.el (treesit-sentence-type-regexp): New defvar. (treesit-forward-sentence): New defun. (treesit-major-mode-setup): Conditionally set forward-sentence-function. --- etc/NEWS | 13 +++++++++++++ lisp/progmodes/c-ts-mode.el | 8 ++++++++ lisp/progmodes/java-ts-mode.el | 6 ++++++ lisp/textmodes/paragraphs.el | 16 +++++++++++++--- lisp/treesit.el | 28 ++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 3 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 690e9c3faa9..98f5d71cc90 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -57,6 +57,19 @@ treesit.el now unconditionally sets 'transpose-sexps-function' for all Tree-sitter modes. This functionality utilizes the new 'transpose-sexps-function'. +** New defvar-local forward-sentence-function. +The previous implementation of 'forward-sentence' is moved into this +variable, which can be set to customize the sentence movement +behavior. + +** New defvar-local 'treesit-sentence-type-regexp. +Similarly to 'treesit-defun-type-regexp', this variable is used to +navigate sentences in Tree-sitter enabled modes. + +** New function 'treesit-forward-sentence'. +treesit.el now conditionally sets 'forward-sentence-function' for all +Tree-sitter modes that sets 'treesit-sentence-type-regexp'. + * Changes in Specialized Modes and Packages in Emacs 30.1 --- diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index a22f1f3c44f..dec866f762f 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -736,6 +736,14 @@ c-ts-base-mode :syntax-table c-ts-mode--syntax-table ;; Navigation. + (setq-local treesit-sentence-type-regexp + (regexp-opt '("statement" + "expression" + "definition" + "specifier" + "declaration" + "comment" + "preproc"))) (setq-local treesit-defun-type-regexp (cons (regexp-opt '("function_definition" "type_definition" diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el index 87a4e2b90f8..0e3381e219a 100644 --- a/lisp/progmodes/java-ts-mode.el +++ b/lisp/progmodes/java-ts-mode.el @@ -296,6 +296,12 @@ java-ts-mode (append "{}():;," electric-indent-chars)) ;; Navigation. + (setq-local treesit-sentence-type-regexp + (regexp-opt '("statement" + "expression" + "parameters" + "list" + "comment"))) (setq-local treesit-defun-type-regexp (regexp-opt '("method_declaration" "class_declaration" diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el index 73abb155aaa..4580be3450d 100644 --- a/lisp/textmodes/paragraphs.el +++ b/lisp/textmodes/paragraphs.el @@ -441,14 +441,12 @@ end-of-paragraph-text (if (< (point) (point-max)) (end-of-paragraph-text)))))) -(defun forward-sentence (&optional arg) +(defun forward-sentence-default-function (&optional arg) "Move forward to next end of sentence. With argument, repeat. When ARG is negative, move backward repeatedly to start of sentence. The variable `sentence-end' is a regular expression that matches ends of sentences. Also, every paragraph boundary terminates sentences as well." - (interactive "^p") - (or arg (setq arg 1)) (let ((opoint (point)) (sentence-end (sentence-end))) (while (< arg 0) @@ -480,6 +478,18 @@ forward-sentence (let ((npoint (constrain-to-field nil opoint t))) (not (= npoint opoint))))) +(defvar forward-sentence-function #'forward-sentence-default-function + "Function to be used to calculate sentence movements. +See `forward-sentence-default-function' for behavior description.") + +(defun forward-sentence (&optional arg) + "Move forward to next end of sentence. With argument, repeat. +When ARG is negative, move backward repeatedly to start of sentence. +Delegates its work to `forward-sentence-function'." + (interactive "^p") + (or arg (setq arg 1)) + (funcall forward-sentence-function arg)) + (defun count-sentences (start end) "Count sentences in current buffer from START to END." (let ((sentences 0) diff --git a/lisp/treesit.el b/lisp/treesit.el index a7f453a8899..0681e758b37 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -1783,6 +1783,32 @@ treesit-end-of-defun (when treesit-defun-skipper (funcall treesit-defun-skipper)))) +(defvar-local treesit-sentence-type-regexp "" + "A regexp that matches the node type of sentence nodes. + +A sentence node is a node that is bigger than a sexp, and +delimits larger statements in the source code. It is, however, +smaller in scope than defuns. This is used by +`treesit-forward-sentence' and friends.") + +(defun treesit-forward-sentence (&optional arg) + "Tree-sitter `forward-sentence-function' function. + +ARG is the same as in `forward-sentence-function'. + +If inside comment or other nodes described in +`treesit-sentence-type-regexp', use +`forward-sentence-default-function', else move across nodes as +described by `treesit-sentence-type-regexp'." + + (if (string-match-p + treesit-text-type-regexp + (treesit-node-type (treesit-node-at (point)))) + (funcall #'forward-sentence-default-function arg) + (funcall + (if (> arg 0) #'treesit-end-of-thing #'treesit-beginning-of-thing) + treesit-sentence-type-regexp (abs arg)))) + (defvar-local treesit-text-type-regexp "\\`comment\\'" "A regexp that matches the node type of textual nodes. @@ -2256,6 +2282,8 @@ treesit-major-mode-setup #'treesit-add-log-current-defun)) (setq-local transpose-sexps-function #'treesit-transpose-sexps) + (when treesit-sentence-type-regexp + (setq-local forward-sentence-function #'treesit-forward-sentence)) ;; Imenu. (when treesit-simple-imenu-settings -- 2.34.1 --=-=-=--