From: Yuan Fu <casouri@gmail.com>
To: Filippo Argiolas <filippo.argiolas@gmail.com>
Cc: "Eli Zaretskii" <eliz@gnu.org>,
"Björn Lindqvist" <bjourne@gmail.com>,
emacs-devel@gnu.org
Subject: Re: How does c-ts-mode, tree-sitter indentation, and preprocessor directives work?
Date: Sat, 30 Nov 2024 22:18:36 -0800 [thread overview]
Message-ID: <52D99EBA-1DCB-4559-A645-A53E7CF82FED@gmail.com> (raw)
In-Reply-To: <m2ttbri52b.fsf@gmail.com>
> On Nov 28, 2024, at 10:30 AM, Filippo Argiolas <filippo.argiolas@gmail.com> wrote:
>
> Eli Zaretskii <eliz@gnu.org> writes:
>
>>> From: Björn Lindqvist <bjourne@gmail.com>
>>> Date: Thu, 28 Nov 2024 00:27:17 +0100
>>>
>>> I've been trying to get c-ts-mode to indent like I want, but I'm
>>> running into problems related to preprocessor directives.
>>
>> Preprocessor directives are difficult because the tree-sitter C/C++
>> grammars include only partial support for them.
>>
>>> For
>>> example, consider a type definition nested in two #ifdefs:
>>>
>>> #ifdef X
>>> #ifdef Y
>>> typedef int foo;
>>> #endif
>>> #endif
>>>
>>> Since both the parent and grand parent of the type_definition is a
>>> preproc_ifdef no rule matches.
>>
>> But if you go back (up) the parent-child hierarchy, you will
>> eventually find a node which is not a preproc_SOMETHING, and can go
>> from there, no?
>>
>
> I believe we might have a bug here, as far as I can tell it does not
> match
>
> ((n-p-gp nil "preproc" "translation_unit") column-0 0)
>
> Because both parent and grand parent are preproc. So it matches one of
> the `c-ts-mode--standalone-parent-skip-preproc' rules right after.
>
> After skipping preproc nodes parent is translation_unit and indents an offset
> from there. Guess this step could be made smarter to check for
> translation_unit and the rule above could be removed?
>
>>> Another issue is that I want my
>>> preprocessor directives kept at column 0, which unfortunately screws
>>> up all rules that refer to the parent. E.g.:
>>>
>>> ((parent-is "if_statement") standalone-parent 4)
>>>
>>> Doesn't work for
>>>
>>> int main() {
>>> if (true)
>>> #ifdef A
>>> prutt();
>>> #else
>>> fis();
>>> #endif
>>> }
>>>
>>> The rule I'd like to express is "take the indent of the closest
>>> *indenting* parent and add one indent". That rule would match whether
>>> that parent is a "while_statement", "if_statement", "for_statement",
>>> etc. You can't express such rules with tree-sitter, can you?
>>
>> Not sure, but Yuan will know.
>
> This can be worked around as Yuan showed, but isn't it a grammar bug?
> problem is with the #ifdef function and if statement become siblings, without
> preproc they have a child-parent relation.
>
> In my experience c-ts-mode is a bit fragile with preprocessor
> statements, probably because the grammar itself is fragile (see
> e.g. [1]) and the problem is an hard one.
Right.
> Yuan, do you think c-ts-mode could some way benefit from LSP knowledge
> about inactive preprocessor branches? Idea is that we would at least
> have a good syntax tree in the active branches while allowing some
> errors in the inactive ones.
Maybe. Technically you can create a parser and sets its range to only included the active branches. But for it to work end-to-end would require some major effort. I’m not sure if it’s worth it (in terms of code complexity and maintenance cost).
Yuan
next prev parent reply other threads:[~2024-12-01 6:18 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-27 23:27 How does c-ts-mode, tree-sitter indentation, and preprocessor directives work? Björn Lindqvist
2024-11-28 7:30 ` Eli Zaretskii
2024-11-28 10:03 ` Yuan Fu
2024-11-28 18:30 ` Filippo Argiolas
2024-12-01 6:18 ` Yuan Fu [this message]
2024-12-01 8:36 ` Filippo Argiolas
2024-12-01 9:32 ` Yuan Fu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52D99EBA-1DCB-4559-A645-A53E7CF82FED@gmail.com \
--to=casouri@gmail.com \
--cc=bjourne@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=filippo.argiolas@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).