You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While programming in javascript/typescript, I have noticed many problems with function call argument indentation. I finally decided to look into why I'm having problems, and discovered three different, but related problems with ecma indents that all result in over-indentation.
I've decided not to make any pull requests as javascript and typescript are some of the most used languages today, and changing the way that they are indented could potentially effect thousands of people.
First, the bug that made me look into this. The following is code indented by nvim-treesitter:
console.log({key: "value"},{key: "value"});
The reason the code is indented like this is because the children of arguments nodes are indented, but also the children of array, object and parenthesized_expression nodes:
The first object is not indented because part of the object node (the opening {) starts on the same line as the arguments node. Subsequent nodes, though, are indented once because they are a child of the arguments node, and then again their contents are indented as they should be.
We can see the reasoning for these all being indented if we format the code in the way that it expects:
console.log({key: "value"},{key: "value"});
The problem is that tree-sitter doesn't know that the only reason the children of the arguments node are on a new line is because the nodes themselves are multi-line. How to solve this (or if it even is possible to solve), I'm not sure. But while exploring the ecma indents, I discovered another related issue which causes multiple indents. The following is code indented by nvim-treesitter:
console.log({key: "value"},{key: "value"});
There are two reasons the code appears this way. First, all arguments nodes which have an object node as a child will branch their indentation:
I cannot think of any reason why this would be the case. This statement was included in the original commit of the ecma indents file, and seems to have been kept around because no one knows what it does. Removing it makes the code indent like this:
console.log({key: "value"},{key: "value"});
This looks better, but still has a problem in my eyes: The arguments node (the parentheses and everything inside) is indented when not on the same line as the function identifier (as can be seen above). This doesn't look bad, but isn't in line with how indenting traditionally works. Usually, an indent occurs when a block (or other multi-line expression) starts, but does not end on the same line. In the above code, there is no block that starts in the first line that isn't continued that would create need for an indent. (Note: Not necessarily an authority, but code formatters like eslint/stylistic and prettier suggest that there should be no indentation for arguments on a new line, as I have suggested.)
This could easily be solved by removing these queries: (added in this commit)
tree-sitter indents all children of the arguments node, even though we don't intend for them to be "multi-line" arguments (in the sense that each argument goes on its own line). I have no idea how this could be solved
arguments nodes that include an object are branched for seemingly no reason. This can easily be solved.
arguments nodes that are on a separate line than their function identifier are indented. This could be easily fixed, but it could be argued that this is a matter of personal preference, and it appears that this functionality was added on purpose.
I would appreciate opinions/insight on the things I have brought up. Thanks.
The text was updated successfully, but these errors were encountered:
While programming in javascript/typescript, I have noticed many problems with function call argument indentation. I finally decided to look into why I'm having problems, and discovered three different, but related problems with ecma indents that all result in over-indentation.
I've decided not to make any pull requests as javascript and typescript are some of the most used languages today, and changing the way that they are indented could potentially effect thousands of people.
First, the bug that made me look into this. The following is code indented by nvim-treesitter:
The reason the code is indented like this is because the children of
arguments
nodes are indented, but also the children ofarray
,object
andparenthesized_expression
nodes:nvim-treesitter/queries/ecma/indents.scm
Lines 1 to 19 in e7ea07e
The first object is not indented because part of the object node (the opening
{
) starts on the same line as thearguments
node. Subsequent nodes, though, are indented once because they are a child of thearguments
node, and then again their contents are indented as they should be.We can see the reasoning for these all being indented if we format the code in the way that it expects:
The problem is that tree-sitter doesn't know that the only reason the children of the
arguments
node are on a new line is because the nodes themselves are multi-line. How to solve this (or if it even is possible to solve), I'm not sure. But while exploring the ecma indents, I discovered another related issue which causes multiple indents. The following is code indented by nvim-treesitter:There are two reasons the code appears this way. First, all
arguments
nodes which have anobject
node as a child will branch their indentation:nvim-treesitter/queries/ecma/indents.scm
Lines 51 to 57 in e7ea07e
I cannot think of any reason why this would be the case. This statement was included in the original commit of the ecma indents file, and seems to have been kept around because no one knows what it does. Removing it makes the code indent like this:
This looks better, but still has a problem in my eyes: The
arguments
node (the parentheses and everything inside) is indented when not on the same line as the function identifier (as can be seen above). This doesn't look bad, but isn't in line with how indenting traditionally works. Usually, an indent occurs when a block (or other multi-line expression) starts, but does not end on the same line. In the above code, there is no block that starts in the first line that isn't continued that would create need for an indent. (Note: Not necessarily an authority, but code formatters like eslint/stylistic and prettier suggest that there should be no indentation for arguments on a new line, as I have suggested.)This could easily be solved by removing these queries: (added in this commit)
nvim-treesitter/queries/ecma/indents.scm
Lines 21 to 28 in e7ea07e
Removing them makes indentation look like this:
In my mind, this is correct.
In summary, there are three issues:
arguments
node, even though we don't intend for them to be "multi-line" arguments (in the sense that each argument goes on its own line). I have no idea how this could be solvedarguments
nodes that include an object are branched for seemingly no reason. This can easily be solved.arguments
nodes that are on a separate line than their function identifier are indented. This could be easily fixed, but it could be argued that this is a matter of personal preference, and it appears that this functionality was added on purpose.I would appreciate opinions/insight on the things I have brought up. Thanks.
The text was updated successfully, but these errors were encountered: