Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto indentation of blocks #17

Open
hexaeder opened this issue Oct 13, 2023 · 5 comments
Open

Auto indentation of blocks #17

hexaeder opened this issue Oct 13, 2023 · 5 comments

Comments

@hexaeder
Copy link

Hello,

I just switched from julia-mode to julia-ts-mode on emacs 29.1. One thing I noticed is that my editor does not indent correctly anymore. I.e., when typing

function foo()<ret>

the point gets placed at column 0 in the next row rather than column 4. This works "correctly" when I switch back to julia-mode.

Is this a problem with julia-ts-mode? Might be related to something else in my config, so feel free to close if this feature has nothing to do with julia-ts-mode, my emacs knowledge is rather limited and I am never quite certain which mode provides which feature anyway 🙃

@ggebbie
Copy link

ggebbie commented Oct 13, 2023

Discussion of the issue here:

https://discourse.julialang.org/t/help-testing-julia-tree-sitter-mode-in-emacs/92819/29?page=2

My understanding: it is a tree-sitter issue. If you have the enclosing end block then the indenting should work.

@ronisbr
Copy link
Collaborator

ronisbr commented Oct 13, 2023

Yes, exactly like @ggebbie said. Before adding end, tree-sitter does not create a new node. Hence, emacs cannot know that it must apply indentation.

@hexaeder
Copy link
Author

hexaeder commented Oct 13, 2023

Thanks for the link! However, M-x indent-according-to-mode works as expected, even without the end keyword:

function foo()
bar <M-x indent-according-to-mode>
#noend

EDIT: does not work at the end of file 🤔

On the other hand

function foo() <ret>
end

will put the point at column 0 within the function body, even with end keyword.

This feels inconsistent with the explanation about treesitter nodes...

@ronisbr
Copy link
Collaborator

ronisbr commented Oct 13, 2023

will put the point at column 0 within the function body, even with end keyword.

If you have no text at all, it also does not create a node. That's why you do not see the indentation. Take a look at the explorer information:

function teste()

end
(function_definition function name: (identifier)
 (parameter_list ( ))
 \n end)

Notice that we do not have a "function body".

Thanks for the link! However, M-x indent-according-to-mode works as expected, even without the end keyword:

It does not work here. You probably are seeing some strange indentation due to the previous text in the file. I tested with this snippet:

function foo()
bar

function teste()
end

This feels inconsistent with the explanation about treesitter nodes...

No. Check the explorer when you partially define a function:

function teste()
a = 2
(ERROR function (identifier)
 (parameter_list ( ))
 \n
 (assignment (identifier) (operator) (integer_literal))
 \n)

It marks as an error. That's why the indentation cannot work.

@natrys
Copy link

natrys commented Sep 20, 2024

If you have no text at all, it also does not create a node. That's why you do not see the indentation.

I think that's only partially true. Whether or not there is a node at point shouldn't materially affect our indentation condition since in this case it only relies on parent (e.g. (parent_is "_definition")).

The first two parameters of treesit-simple-indent function is node and parent. Given our particular condition here, so long as the parent is function_definition, we should indent regardless of whether node is nil or something valid. If you trace that function, then I think the problem becomes apparent. At this position if you press tab:

function test()
|
end

The trace-output gives you:

======================================================================
1 -> (treesit-simple-indent nil #<treesit-node "
" in 20-22> 21)
1 <- treesit-simple-indent: (1 . 0)

So here Emacs considers us to be inside the anonymous newline node, and therefore considers that to be the parent. I am not sure why Emacs can't consider node to be newline, I think that's because the start of the newline happened before the bol of current line. That would make sense, if the reason writing something else suddenly makes it work is because then that newline node terminates and becomes a sibling node, and the new node is actually considered a node because it started after the bol of current line, which means function_definition finally becomes parent:

======================================================================
1 -> (treesit-simple-indent #<treesit-node assignment in 23-37> #<treesit-node function_definition in 1-41> 23)
1 <- treesit-simple-indent: (1 . 2)

What I am getting to is that it might be possible to fix the problem here if we make our indentation rules that newline aware. However that might be very tricky to do, it might be worthwhile asking upstream to simply remove the newlines from showing up in the syntax tree, then the rules here will work as is (without needing to create a new node).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants