unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Can this indentation be achieved with treesit-simple-indent-rules?
@ 2023-06-19 19:11 Nicolás Ojeda Bär
  2023-06-20  6:12 ` Yuan Fu
  2023-06-20 15:34 ` Dmitry Gutov
  0 siblings, 2 replies; 8+ messages in thread
From: Nicolás Ojeda Bär @ 2023-06-19 19:11 UTC (permalink / raw)
  To: emacs-devel

Hello,

I am trying my hand at writing a tree-sitter major mode. I am using
"treesit-simple-indent-rules" for indentation, but have not managed to
get the indentation style that I am looking for.

Suppose that the AST that you are trying to indent is (a (b c)) and
that you have
the indentation rules

    ((parent-is "a") parent-bol 2)
    ((parent-is "b") parent-bol 0)

Then the following is well-indented:

a
  b
  c

However, if "b" is in the same line as "a", then the result of indentation is:

a b
c

But I would like to have instead

a b
  c

That is, I would like "c" to be indented _as if_ "b" was on a separate
line. Is there a way to achieve this?

Thanks!

Cheers,
Nicolas



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can this indentation be achieved with treesit-simple-indent-rules?
  2023-06-19 19:11 Can this indentation be achieved with treesit-simple-indent-rules? Nicolás Ojeda Bär
@ 2023-06-20  6:12 ` Yuan Fu
  2023-06-20 10:16   ` Nicolás Ojeda Bär
  2023-06-20 15:34 ` Dmitry Gutov
  1 sibling, 1 reply; 8+ messages in thread
From: Yuan Fu @ 2023-06-20  6:12 UTC (permalink / raw)
  To: Nicolás Ojeda Bär; +Cc: emacs-devel



> On Jun 19, 2023, at 12:11 PM, Nicolás Ojeda Bär <n.oje.bar@gmail.com> wrote:
> 
> Hello,
> 
> I am trying my hand at writing a tree-sitter major mode. I am using
> "treesit-simple-indent-rules" for indentation, but have not managed to
> get the indentation style that I am looking for.
> 
> Suppose that the AST that you are trying to indent is (a (b c)) and
> that you have
> the indentation rules
> 
>    ((parent-is "a") parent-bol 2)
>    ((parent-is "b") parent-bol 0)
> 
> Then the following is well-indented:
> 
> a
>  b
>  c
> 
> However, if "b" is in the same line as "a", then the result of indentation is:
> 
> a b
> c
> 
> But I would like to have instead
> 
> a b
>  c
> 
> That is, I would like "c" to be indented _as if_ "b" was on a separate
> line. Is there a way to achieve this?

There are different approaches to this. Could you maybe explain why you want to indent it like this, so that I know what’s your intent? Maybe also give a concert example? I’m guessing something like a is special and you only want one level of indentation for the whole statement, even if it occupies multiple lines; or it could be that b and c are special and should align?

Yuan


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can this indentation be achieved with treesit-simple-indent-rules?
  2023-06-20  6:12 ` Yuan Fu
@ 2023-06-20 10:16   ` Nicolás Ojeda Bär
  0 siblings, 0 replies; 8+ messages in thread
From: Nicolás Ojeda Bär @ 2023-06-20 10:16 UTC (permalink / raw)
  To: Yuan Fu; +Cc: emacs-devel

Dear Yuan,

Thanks for your response. Let me give you a bit of context. I am
trying writing a major mode for OCaml. For indentation, I am trying to
replicate (as much as possible) the popular tool `ocp-indent`
(https://github.com/OCamlPro/ocp-indent). As far as I can see, this
tool tries to produce indentations which are "diff-friendly", that is,
such that breaking a line does not cause indentation to change in the
following lines. Concretely, consider the (indented) example
```
let x =
  match e with
  | Foo -> 0
```
If we move the `match` construct to the same line as `let`, I would
like the result to be indented as follows:
```
let x = match e with
  | Foo -> 0
```
and _not_
```
let x = match e with
| Foo -> 0
```
(in the context of my original message, "a" was the "let" expression,
"b", the "match" expression, and "c" the match clause "| Foo -> 0").

I hope that clarifies a bit my motivation. Do let me know if anything
is unclear.

Cheers,
Nicolas

On Tue, Jun 20, 2023 at 8:12 AM Yuan Fu <casouri@gmail.com> wrote:
>
>
>
> > On Jun 19, 2023, at 12:11 PM, Nicolás Ojeda Bär <n.oje.bar@gmail.com> wrote:
> >
> > Hello,
> >
> > I am trying my hand at writing a tree-sitter major mode. I am using
> > "treesit-simple-indent-rules" for indentation, but have not managed to
> > get the indentation style that I am looking for.
> >
> > Suppose that the AST that you are trying to indent is (a (b c)) and
> > that you have
> > the indentation rules
> >
> >    ((parent-is "a") parent-bol 2)
> >    ((parent-is "b") parent-bol 0)
> >
> > Then the following is well-indented:
> >
> > a
> >  b
> >  c
> >
> > However, if "b" is in the same line as "a", then the result of indentation is:
> >
> > a b
> > c
> >
> > But I would like to have instead
> >
> > a b
> >  c
> >
> > That is, I would like "c" to be indented _as if_ "b" was on a separate
> > line. Is there a way to achieve this?
>
> There are different approaches to this. Could you maybe explain why you want to indent it like this, so that I know what’s your intent? Maybe also give a concert example? I’m guessing something like a is special and you only want one level of indentation for the whole statement, even if it occupies multiple lines; or it could be that b and c are special and should align?
>
> Yuan



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can this indentation be achieved with treesit-simple-indent-rules?
  2023-06-19 19:11 Can this indentation be achieved with treesit-simple-indent-rules? Nicolás Ojeda Bär
  2023-06-20  6:12 ` Yuan Fu
@ 2023-06-20 15:34 ` Dmitry Gutov
  2023-06-20 16:16   ` Nicolás Ojeda Bär
  1 sibling, 1 reply; 8+ messages in thread
From: Dmitry Gutov @ 2023-06-20 15:34 UTC (permalink / raw)
  To: Nicolás Ojeda Bär, emacs-devel

On 19/06/2023 22:11, Nicolás Ojeda Bär wrote:
>      ((parent-is "b") parent-bol 0)

Try 'parent' instead of 'parent-bol'.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can this indentation be achieved with treesit-simple-indent-rules?
  2023-06-20 15:34 ` Dmitry Gutov
@ 2023-06-20 16:16   ` Nicolás Ojeda Bär
  2023-06-20 16:59     ` Dmitry Gutov
  2023-06-20 21:53     ` Yuan Fu
  0 siblings, 2 replies; 8+ messages in thread
From: Nicolás Ojeda Bär @ 2023-06-20 16:16 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: emacs-devel

On Tue, Jun 20, 2023 at 5:34 PM Dmitry Gutov <dmitry@gutov.dev> wrote:
>
> On 19/06/2023 22:11, Nicolás Ojeda Bär wrote:
> >      ((parent-is "b") parent-bol 0)
>
> Try 'parent' instead of 'parent-bol'.

Hello,

Thanks for the suggestion.

That would work in the "abstract" example because "a" is of width 1,
but would not work in general. You can see it clearly if we use "aaa",
"bbb" and "ccc" instead of "a", "b", "c": starting from the correctly
indented

aaa
  bbb
  ccc

if we put "bbb" in the same line as "aaa" we will get (using parent
instead of parent-bol)

aaa bbb
    ccc

but would like to get

aaa bbb
  ccc

In the concrete example in OCaml I mentioned in a previous reply, starting from

let x =
  match e with
  | Foo -> 0

if I put the "match" in the same line as the "let" (using parent
instead of parent-bol) I will get

let x = match e with
        | Foo -> 0

but would like to get instead

let x = match e with
  | Foo -> 0

Do let me know if anything is still unclear.

Cheers,
Nicolas



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can this indentation be achieved with treesit-simple-indent-rules?
  2023-06-20 16:16   ` Nicolás Ojeda Bär
@ 2023-06-20 16:59     ` Dmitry Gutov
  2023-06-20 18:45       ` Nicolás Ojeda Bär
  2023-06-20 21:53     ` Yuan Fu
  1 sibling, 1 reply; 8+ messages in thread
From: Dmitry Gutov @ 2023-06-20 16:59 UTC (permalink / raw)
  To: Nicolás Ojeda Bär; +Cc: emacs-devel

On 20/06/2023 19:16, Nicolás Ojeda Bär wrote:
> Thanks for the suggestion.
> 
> That would work in the "abstract" example because "a" is of width 1,
> but would not work in general. You can see it clearly if we use "aaa",
> "bbb" and "ccc" instead of "a", "b", "c": starting from the correctly
> indented
> 
> aaa
>    bbb
>    ccc
> 
> if we put "bbb" in the same line as "aaa" we will get (using parent
> instead of parent-bol)
> 
> aaa bbb
>      ccc
> 
> but would like to get
> 
> aaa bbb
>    ccc

Sounds like this could work, then:

     ((parent-is "a") parent-bol 2)
     ((parent-is "b") grand-parent 2)

If "a" might also reside not at indentation (with some tokens before 
it), you'll need to decide which indentation to have for that case. 
Maybe the above will be fine, or maybe you could use the 
'standalone-parent' anchor instead.

See treesit-simple-indent-presets for the full list of predefined ones. 
And if none fit exactly, you can define a custom function with the same 
signature (or several) which can do more advanced calculations, 
lookarounds, etc.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can this indentation be achieved with treesit-simple-indent-rules?
  2023-06-20 16:59     ` Dmitry Gutov
@ 2023-06-20 18:45       ` Nicolás Ojeda Bär
  0 siblings, 0 replies; 8+ messages in thread
From: Nicolás Ojeda Bär @ 2023-06-20 18:45 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: emacs-devel

On Tue, Jun 20, 2023 at 6:59 PM Dmitry Gutov <dmitry@gutov.dev> wrote:
>
> See treesit-simple-indent-presets for the full list of predefined ones.
> And if none fit exactly, you can define a custom function with the same
> signature (or several) which can do more advanced calculations,
> lookarounds, etc.

I did some experiments defining ac custom ANCHOR and indeed it looks
like I should be able to cobble something together to achieve what I
want.

Thanks for the pointer!

Cheers,
Nicolas



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can this indentation be achieved with treesit-simple-indent-rules?
  2023-06-20 16:16   ` Nicolás Ojeda Bär
  2023-06-20 16:59     ` Dmitry Gutov
@ 2023-06-20 21:53     ` Yuan Fu
  1 sibling, 0 replies; 8+ messages in thread
From: Yuan Fu @ 2023-06-20 21:53 UTC (permalink / raw)
  To: Nicolás Ojeda Bär; +Cc: Dmitry Gutov, emacs-devel



> On Jun 20, 2023, at 9:16 AM, Nicolás Ojeda Bär <n.oje.bar@gmail.com> wrote:
> 
> On Tue, Jun 20, 2023 at 5:34 PM Dmitry Gutov <dmitry@gutov.dev> wrote:
>> 
>> On 19/06/2023 22:11, Nicolás Ojeda Bär wrote:
>>>     ((parent-is "b") parent-bol 0)
>> 
>> Try 'parent' instead of 'parent-bol'.
> 
> Hello,
> 
> Thanks for the suggestion.
> 
> That would work in the "abstract" example because "a" is of width 1,
> but would not work in general. You can see it clearly if we use "aaa",
> "bbb" and "ccc" instead of "a", "b", "c": starting from the correctly
> indented
> 
> aaa
>  bbb
>  ccc
> 
> if we put "bbb" in the same line as "aaa" we will get (using parent
> instead of parent-bol)
> 
> aaa bbb
>    ccc
> 
> but would like to get
> 
> aaa bbb
>  ccc
> 
> In the concrete example in OCaml I mentioned in a previous reply, starting from
> 
> let x =
>  match e with
>  | Foo -> 0
> 
> if I put the "match" in the same line as the "let" (using parent
> instead of parent-bol) I will get
> 
> let x = match e with
>        | Foo -> 0
> 
> but would like to get instead
> 
> let x = match e with
>  | Foo -> 0
> 
> Do let me know if anything is still unclear.

Thanks for the context. So the logic is “the value of a let = VALUE should have a base indentation of +1 level”. Maybe you can add a rule that matches “the line below a let”, make it take precedence over other rules.

Come to think about it, the indent logic of OCaml seems to be determined by the previous line: let P be the node at the BOL of the previous line, and N be the node at the BOL of the current line, if P is some sort of a sibling of N, they indent the same amount; if P is some sort of (grand)parent of N, the current line indents one level more. Sans exceptions like the match arms and the body of a “let x = y in body”, IIRC.

Following this line of thought, maybe you can have rules for the exceptions, followed by two generic rules for the two cases, rather than writing explicit rules for every scenario?

Yuan


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-06-20 21:53 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-19 19:11 Can this indentation be achieved with treesit-simple-indent-rules? Nicolás Ojeda Bär
2023-06-20  6:12 ` Yuan Fu
2023-06-20 10:16   ` Nicolás Ojeda Bär
2023-06-20 15:34 ` Dmitry Gutov
2023-06-20 16:16   ` Nicolás Ojeda Bär
2023-06-20 16:59     ` Dmitry Gutov
2023-06-20 18:45       ` Nicolás Ojeda Bär
2023-06-20 21:53     ` Yuan Fu

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).