-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
[Fix] jsx-indent with tabs #1058
Conversation
1e7fbe5
to
d809e34
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
if (loc) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the ESLint docs, if loc
isn't provided, it defaults to node.loc
so I figured we could just do the same and save ourselves an if statement :)
|
||
var parentElementIndent = getNodeIndent(prevToken); | ||
if (prevToken.type === 'JSXElement') { | ||
parentElementIndent = getOpeningElementIndent(prevToken.openingElement); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note the recurssion here.
// as the baseline for the next two, instead of the realizing the entire three | ||
// lines are wrong together. See #608 | ||
/* output: [ | ||
output: [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woot! These changes fix this case and we can now auto-fix this!
@@ -212,17 +214,6 @@ ruleTester.run('jsx-indent', rule, { | |||
].join('\n'), | |||
parserOptions: parserOptions | |||
}, { | |||
// Literals indentation is not touched |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that Literal indentation should be touched as it doesn't make a difference in the resulting HTML (different for JSXExpressions, but that doesn't apply here).
tests/lib/rules/jsx-indent.js
Outdated
parserOptions: parserOptions | ||
// }, { | ||
// should we put effort in making this work? | ||
// who in their right mind would do this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question stands... It would require more logic in the fixer and I don't think it's worth the complexity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is worth supporting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, I went ahead and removed the commented-out code.
Pinging those who have touched this rule in one way or another: @yannickcr, @Jorundur, @eelyafi, @jayphelps, @petersendidit, @voxpelli Thanks friends! |
Don't merge this yet, just found a bug with the following code: <div>
{
foo &&
<div>
<div></div>
</div>
}
</div> We're getting a bad report on the middle-most |
Just noticed that this is actually by design (a few valid tests showing this). I'm going to add a config option to enable this style. |
a226f40
to
83396d3
Compare
Ok, I've updated the PR with documentation for the new configuration option |
Oh, and just an argument for the |
I published my branch as |
I've verified that this works on my work project 👍 |
Is this multiple fixes to separate indention cases? |
Originally, it was to fix a single issue with |
It's just a bit hard for me to follow with the various changes for separate things. I don't have enough cycles to fully understand it so I can't give a sign off, but it generally looks good. There were a couple changes you made that are opinionated--you called them out with comments. |
Understood @jayphelps, if others feel this way, then I'll split things up. |
Could you perhaps edit the original post to include a summary of the changed behaviors? |
parentElementIndent = getOpeningElementIndent(prevToken.openingElement); | ||
} | ||
|
||
if (isRightInLogicalExp(node) && indentLogicalExpressions) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only relevant bit for the indentLogicalExpressions
option.
* @param {ASTNode} node The JSXOpeningElement | ||
* @return {Number} the number of indentation characters it should have | ||
*/ | ||
function getOpeningElementIndent(node) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function came from the JSXOpeningElement
function below. I extracted it to make use of it else where. The only changes from what was there before is the two if statements before the var indent = (
assignment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for providing this context. This is helpful for reviewers.
Updated, let me know if more details would be helpful. Thanks @jayphelps! |
return { | ||
JSXOpeningElement: function(node) { | ||
var prevToken = sourceCode.getTokenBefore(node); | ||
if (!prevToken) { | ||
return; | ||
} | ||
// Use the parent in a list or an array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code was simply refactored to getOpeningElementIndent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great to me. Thanks for the contribution @kentcdodds.
@yannickcr it would be nice to get this in the next release.
@@ -165,8 +184,9 @@ module.exports = { | |||
} while (token.type === 'JSXText' && /^\s*$/.test(token.value)); | |||
var startLine = node.loc.start.line; | |||
var endLine = token ? token.loc.end.line : -1; | |||
var whitespaceOnly = token ? /\n\s*$/.test(token.value) : false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably doesn't matter, but I think this regex won't match the first line? Should it be /^\s*$/
instead? I'm also not sure what token.value
represents, so perhaps the \n
is necessary. (see also the regex on line 184)
If these end up being the same, it might not be a bad idea to move them to a constant at the module level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tried out changing it to ^
and it results in an additional extraneous error in one of the test cases. Specifically:
function MyComponent(props) {
return (
<div
className="foo-bar"
id="thing"
>
Hello world!
</div>
)
}
Because token.value
is actually everything between the >
and the </div>
(which includes a \n
)
* @param {ASTNode} node The JSXOpeningElement | ||
* @return {Number} the number of indentation characters it should have | ||
*/ | ||
function getOpeningElementIndent(node) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for providing this context. This is helpful for reviewers.
lib/rules/jsx-indent.js
Outdated
if (prevToken.type === 'JSXText' || prevToken.type === 'Punctuator' && prevToken.value === ',') { | ||
prevToken = sourceCode.getNodeByRangeIndex(prevToken.start); | ||
prevToken = prevToken.type === 'Literal' ? prevToken.parent : prevToken; | ||
// Use the first non-punctuator token in a conditional expression |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I find this style of commenting to be pretty awkward. I think this would be best if it was moved inside the conditional branch. Don't worry about this unless you end up touching this again, especially since you didn't write it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was in the area and updated the commenting style. I also find it confusing as it is.
tests/lib/rules/jsx-indent.js
Outdated
parserOptions: parserOptions | ||
// }, { | ||
// should we put effort in making this work? | ||
// who in their right mind would do this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is worth supporting.
95a5f8e
to
fe5c7e3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a few small (comments only) changes based on feedback.
@@ -165,8 +184,9 @@ module.exports = { | |||
} while (token.type === 'JSXText' && /^\s*$/.test(token.value)); | |||
var startLine = node.loc.start.line; | |||
var endLine = token ? token.loc.end.line : -1; | |||
var whitespaceOnly = token ? /\n\s*$/.test(token.value) : false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tried out changing it to ^
and it results in an additional extraneous error in one of the test cases. Specifically:
function MyComponent(props) {
return (
<div
className="foo-bar"
id="thing"
>
Hello world!
</div>
)
}
Because token.value
is actually everything between the >
and the </div>
(which includes a \n
)
lib/rules/jsx-indent.js
Outdated
if (prevToken.type === 'JSXText' || prevToken.type === 'Punctuator' && prevToken.value === ',') { | ||
prevToken = sourceCode.getNodeByRangeIndex(prevToken.start); | ||
prevToken = prevToken.type === 'Literal' ? prevToken.parent : prevToken; | ||
// Use the first non-punctuator token in a conditional expression |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was in the area and updated the commenting style. I also find it confusing as it is.
tests/lib/rules/jsx-indent.js
Outdated
parserOptions: parserOptions | ||
// }, { | ||
// should we put effort in making this work? | ||
// who in their right mind would do this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, I went ahead and removed the commented-out code.
fe5c7e3
to
6e5f688
Compare
This fixes the
--fix
forjsx-indent
. Specifically my issue was with tabs (Fixes #1057), but this fixes the same issues with spaces as well.Highlevel important bits:
>
) is on its own line. This will now lint and fix properly.indentLogicalExpressions
which will allow for indenting the right side of logical expressions (documented)