From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Dmitry Gutov Newsgroups: gmane.emacs.bugs Subject: bug#62717: 29.0.60; c-ts-mode does not indent the first line in a function after RET Date: Sun, 9 Apr 2023 03:20:23 +0300 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="40536"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.9.0 Cc: Theodor Thornhill , Yuan Fu , 62717@debbugs.gnu.org, =?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?= , Alan Mackenzie To: Daniel =?UTF-8?Q?Mart=C3=ADn?= Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Apr 09 06:12:29 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 1plMPk-000AJO-5i for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 09 Apr 2023 06:12:28 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1plMPP-0004bH-TE; Sun, 09 Apr 2023 00:12:07 -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 1plMPM-0004aT-Ik for bug-gnu-emacs@gnu.org; Sun, 09 Apr 2023 00:12:04 -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 1plMPM-0004Ah-6T for bug-gnu-emacs@gnu.org; Sun, 09 Apr 2023 00:12:04 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1plMPM-0004CX-23 for bug-gnu-emacs@gnu.org; Sun, 09 Apr 2023 00:12:04 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Dmitry Gutov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 09 Apr 2023 04:12:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 62717 X-GNU-PR-Package: emacs Original-Received: via spool by 62717-submit@debbugs.gnu.org id=B62717.168101349716086 (code B ref 62717); Sun, 09 Apr 2023 04:12:04 +0000 Original-Received: (at 62717) by debbugs.gnu.org; 9 Apr 2023 04:11:37 +0000 Original-Received: from localhost ([127.0.0.1]:60007 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1plMOu-0004BI-Uh for submit@debbugs.gnu.org; Sun, 09 Apr 2023 00:11:37 -0400 Original-Received: from wnew1-smtp.messagingengine.com ([64.147.123.26]:44311) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1plInK-00060K-6V for 62717@debbugs.gnu.org; Sat, 08 Apr 2023 20:20:35 -0400 Original-Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailnew.west.internal (Postfix) with ESMTP id 8A04F2B06841; Sat, 8 Apr 2023 20:20:27 -0400 (EDT) Original-Received: from mailfrontend2 ([10.202.2.163]) by compute1.internal (MEProxy); Sat, 08 Apr 2023 20:20:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gutov.dev; h=cc :cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to; s=fm1; t= 1680999627; x=1681003227; bh=oxlJmRKkPY4lNOteoCHDbyFGh+j//LIhqQ4 4gcUcDQc=; b=k2rQ17QTV9TrXrHjXUIVeNagFDydD3roT9qvZZbDzgyGrHikaCW REpFQ3fxWcTVOwWI3I9UgF+udpfJ8Futh/Osn2fjWAnqvhGA6rxG++7PaLjXfIQ7 +FHQpeLmzVT8aZ2NkQjlTyM8qwaIvj10PriCXZdasZdKJ1Lvz8y3wdVfLFNH+erF Bzz5mAVBJaoVWw0L1vRRRRfEqArR4emKdDq3CcAad5pKP/37F3l322NpzqPuo0d3 BxrzU7/y+jVJpGKifBPeQbKnD8ditqcGPgGO/HBftveFJQrS4XCHoTiib30md4jv 3lpL/8Kx5exfOR3p0krEjAbQo/ZpqoZyGRA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t= 1680999627; x=1681003227; bh=oxlJmRKkPY4lNOteoCHDbyFGh+j//LIhqQ4 4gcUcDQc=; b=fr4nY5ToI3H8hauCnv9YOBnfdliBcKTWvlR3j87ZkTPwDf2yPQq wbh//7VjBU7ReH4cQss40azrwhh54tt6NE7irGaEnHdnck0WIFE2XoXN4BdEgIS0 Y484YXfR1ihoKamAIYxKyrAOqH2xKs7imH7EBWl+XZkbyew7lhtseGNTKf7FcuFF i6l7oWZ1Zo/IsLI9WcDqykpSCvb5+48tMUwL9uYtYRERNq7GNTZMSYO+RiGjXbwM cyZvZSMlNyPgVe046gyvM98tPXj/IJGP8T3wkgPSriOCkJSrmm5YUrGJhshjoZ4V hGYDVD5CE/Y/WQ7o90SubWprMFyXQEgldsw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrvdejkedgfeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepkfffgggfuffvvehfhfgjtgfgsehtkeertddtfeejnecuhfhrohhmpeffmhhi thhrhicuifhuthhovhcuoegumhhithhrhiesghhuthhovhdruggvvheqnecuggftrfgrth htvghrnhepueffveeiffeugffgveejvdegteeuhfdugfehleelfeejtdelteethfdtieeg vddunecuffhomhgrihhnpehgihhthhhusgdrtghomhenucevlhhushhtvghrufhiiigvpe dtnecurfgrrhgrmhepmhgrihhlfhhrohhmpegumhhithhrhiesghhuthhovhdruggvvh X-ME-Proxy: Feedback-ID: i0e71465a:Fastmail Original-Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 8 Apr 2023 20:20:24 -0400 (EDT) Content-Language: en-US In-Reply-To: X-Mailman-Approved-At: Sun, 09 Apr 2023 00:11:32 -0400 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:259509 Archived-At: On 08/04/2023 21:37, Daniel Martín wrote: > Dmitry Gutov writes: > >> I've looked at what nvim-treesitter does for indentation, and at least >> one of the steps looks like this: >> >> https://github.com/nvim-treesitter/nvim-treesitter/blob/584ccea56e2d37b31ba292da2b539e1a4bb411ca/lua/nvim-treesitter/indent.lua#L129-L134 >> >> If the current line is empty, look at the end of the previous line and >> compute based on the node there. >> >> I'm not sure how this meshes with the fact that tree-sitter inserts a >> "virtual" closer node at the end of the previous line, but the >> approach is worth examining. >> >> Daniel, you posted about testing nvim-treesitter with several >> scenarios. Does it do the right thing with this one? > Yes, it works well in this scenario. Inserting a new line automatically > adds indentation. All right. From reading the code, it looks like a semi-coincidence that this example works fine: the algorithm is just different, looking for indent/dedent nodes, there is nothing similar to our logic in treesit--indent-1. Which can be good and bad, but it's likely that the grammar (and tree-sitter itself) co-evolved together with that approach, so it's no surprise the sharp edges match. In particular, the virtual closer node seems to be skipped because the search uses descendant_for_range, which seems to jump over zero-length nodes. We could try to hammer in that exception as a workaround, but the resulting PARENT won't contain BOL anyway, and it's not 100% clear how these fake nodes will look for other grammars. Indentation in ruby-ts-mode, for example, won't magically start working right away in the comparable situation (method definition without closer) because there is also a missing body_statement node, requiring further changes to indentation rules. What does this mean for us? Short of reimplementing nvim-treesitter's algorithm (and I haven't read Atom's or Zed's indentation code; anybody's welcome to chime in with a summary of either), we could just install the patch at the end of this message: it fixes this particular case, in a bit hackish way, but at least it doesn't affect other languages. Note that it still doesn't fix very similar cases, e.g. int main () { for (;;) { (we need additional rules looking for ERROR nodes, like in nvim's indent.scm), but in does fix int main () { for (;;) {} and int main () { int foo; I'm not sure, though, what is the big deal with adding the top-level function's closing curly first thing before writing the body (after that the parser starts working much better), so as far as I'm concerned this patch is very optional. It does add some complexity, after all. Adding Alan and Joao, who were interested in this scenario as well. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 981c7766375..9aaa8b32c73 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -859,6 +859,18 @@ c-ts-mode--defun-skipper (goto-char (match-end 0))) (treesit-default-defun-skipper)) +(defun c-ts-base--before-indent (args) + (pcase-let ((`(,node ,parent ,bol) args)) + (when (null node) + (let ((smallest-node (treesit-node-at (point)))) + ;; "Virtual" closer curly added by the + ;; parser's error recovery. + (when (and (equal (treesit-node-type smallest-node) "}") + (equal (treesit-node-end smallest-node) + (treesit-node-start smallest-node))) + (setq parent (treesit-node-parent smallest-node))))) + (list node parent bol))) + (defun c-ts-mode-indent-defun () "Indent the current top-level declaration syntactically. @@ -904,6 +916,8 @@ c-ts-base-mode ;; function_definitions, so we need to find the top-level node. (setq-local treesit-defun-prefer-top-level t) + (add-function :filter-args treesit-indent-function #'c-ts-base--before-indent) + ;; Indent. (when (eq c-ts-mode-indent-style 'linux) (setq-local indent-tabs-mode t))