> On Nov 27, 2024, at 11:30 PM, Eli Zaretskii wrote: > >> From: Björn Lindqvist >> 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? > >> 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. Everything is possible, it’s just elisp. The only problem is how generic you can make the rule. Here’s a POC that only works for this example; specifically, it only works for if statements and #ifdef directives. It should be extendable to for statement, while statement, etc, and maybe other directives too. Speaking of indent, we need to do something with c-ts-mode’s indentation rules. It’s getting too long and too complex. But I don’t have any great idea at this point. Maybe we can replace the rules with a hand-rolled function so it has more structure, or try nvim’s query approach. Yuan