- Currently working for Community Phone, and not looking for a job.
eslint-plugin-align-assignments's Introduction
eslint-plugin-align-assignments's People
eslint-plugin-align-assignments's Issues
PR, wrote you some code for better assignment.
Feel free to modify it as required.
const hasRequire= /require\(/u;
const spaceMatcher= /(?<n2>\s*)(?<n1>(?:\+|-|\*|\/|%|&|\^|\||<<|>>|\*\*|>>>)?=)/u;
const assignmentTokens= new Set ([
`>>>=`,
`<<=`,
`>>=`,
`**=`,
`&&=`,
`||=`,
`??=`,
`+=`,
`-=`,
`*=`,
`/=`,
`%=`,
`&=`,
`^=`,
`|=`,
`=`,
]);
module.exports= {
meta: {
fixable: `code`,
},
create: function (context) {
const {
options,
} = context;
const requiresOnly= Boolean (options) && options.length > 0 && options[0].requiresOnly;
const sourceCode= context.getSourceCode ();
const groups= [];
let previousNode;
return {
"VariableDeclaration": function (node) {
const source= sourceCode.getText (node);
if (Boolean (requiresOnly) && ! hasRequire.test (source)) {
return;
}
addNode (node, node);
},
"Program:exit": checkAll,
"ExpressionStatement": function (node) {
const hasAssignmentExpression= Object.is (`AssignmentExpression`, node.expression.type);
if (! hasAssignmentExpression) {
return;
}
addNode (node, node.expression);
},
};
function checkAll () {
groups.forEach (check);
}
function isAssignmentExpression (node) {
return Object.is (`AssignmentExpression`, node.type);
}
function addNode (groupNode, node) {
if (shouldStartNewGroup (groupNode)) {
groups.push ([
node,
]);
}
else {
getLast (groups).push (node);
}
previousNode= groupNode;
}
function shouldStartNewGroup (node) {
// first line of all
if (! previousNode) {
return true;
}
// switching parent nodes
if (! Object.is (previousNode.parent, node.parent)) {
return true;
}
// If previous node was a for and included the declarations, new group
if (Object.is (`ForStatement`, previousNode.parent.type) && previousNode.declarations) {
return true;
}
// previous line was blank.
const lineOfNode= sourceCode.getFirstToken (node).loc.start.line;
const lineOfPrev= sourceCode.getLastToken (previousNode).loc.start.line;
return ! Object.is (1, lineOfNode - lineOfPrev);
}
function check (group) {
const maxPos= maxPosition (group);
if (! areAligned (maxPos, group)) {
context.report ({
message: `This group of assignments is not aligned.`,
loc: {
start: group[0].loc.start,
end: getLast (group).loc.end,
},
fix: fixer=>{
const fixings= group.map (node=>{
const tokens= sourceCode.getTokens (node);
const firstToken= tokens[0];
const assignmentToken= tokens.find (token=>assignmentTokens.has (token.value));
const line= sourceCode.getText (node);
const lineIsAligned= ! Object.is (` `, line.charAt (maxPos+1)) && Object.is (` `, line.charAt (maxPos));
if (lineIsAligned || ! assignmentToken || isMultiline (firstToken, assignmentToken)) {
return fixer.replaceText (node, line);
}
// source line may include spaces, we need to accomodate for that.
const spacePrefix= firstToken.loc.start.column;
const startDelimiter= assignmentToken.loc.start.column - spacePrefix;
const endDelimiter= assignmentToken.loc.end.column - spacePrefix;
const start= line.slice (0, startDelimiter).replace (/\s+$/um, ``);
const ending= line.slice (endDelimiter).replace (/^\s+/um, ``);
const spacesRequired= maxPos - start.length - assignmentToken.value.length + 1;
const spaces= ` `.repeat (spacesRequired);
const fixedText= `${start}${assignmentToken.value}${spaces}${ending}`;
return fixer.replaceText (node, fixedText);
});
return fixings.filter (Boolean);
},
});
}
}
function isMultiline (firstToken, assignmentToken) {
return ! Object.is (firstToken.loc.start.line, assignmentToken.loc.start.line);
}
function findAssigment (node) {
const prefix= getPrefix (node);
const source= sourceCode.getText (node);
const match= source.slice (prefix).match (spaceMatcher);
const position= match ?
match.index + prefix + match[2].length :
null;
return position;
}
function getPrefix (node) {
const nodeBefore= isAssignmentExpression (node) ?
node.left:
node.declarations.find (dcl=>Object.is (`VariableDeclarator`, dcl.type)).id;
const prefix= nodeBefore.loc.end.column - nodeBefore.loc.start.column;
return prefix;
}
function areAligned (maxPos, nodes) {
return nodes
.filter (assignmentOnFirstLine)
.map (node=>sourceCode.getText (node))
.every (source=>{
return ! Object.is (` `, source.charAt (maxPos+1)) &&
Object.is (` `, source.charAt (maxPos+0));
});
}
function maxPosition (nodes) {
return nodes
.filter (assignmentOnFirstLine)
.map (findAssigment)
.reduce ((previous, current)=>{
return Math.max (previous, current);
}, 0);
}
function assignmentOnFirstLine (node) {
if (isAssignmentExpression (node)) {
const onFirstLine= Object.is (node.right.loc.start.line, node.left.loc.start.line);
return onFirstLine;
}
const source= sourceCode.getText (node);
const lines= source.split (`\n`);
return lines[0].includes (`=`);
}
function getLast (ary) {
return ary.at (- 1);
}
},
};
Cheers.
Support ESLint 6
Is ESlint 6 support expected?
Support all assignment operators
Operators like = += -= *= /= %= <<= >>= >>>= &= ^= \|=
should be valid assignment operators, and the plugin should be able to align them properly.
Suggestion of what would be valid.
a *= 3;
b >>= 3;
f >>>= 3;
Destructuring single-line assignments
First, very many thanks for writing this package. I have been looking for a way to enforce aligned assignment in eslint for over a year.
I am finding that supplying defaults for destructuring single-line assignments confuses this plugin, for example:
const { foo = [] } = bar;
reports 'This group of assignments is not aligned'. The 'fix' produces:
const { foo = [] } = bar;
which is not only worse but also does not stop the rule from complaining.
Types are ignored
No detection/alignment of:
type MyType = [number, string, string];
type MyOtherType = [string, number];
Logical assignments not supported
Logical assignment operators such as ||=
and &&=
are not supported
Adding the plugin to the plugins section makes eslint stop working
Edit: I also noticed it shows the error "Definition for rule 'align-assignments/align-assignments' was not found." with the plugin enabled.
In .eslintrc.json I have:
"plugins": [
***
"align-assignments",
***
],
Which breaks eslint as if there's a syntax or some other error in the configuration file.
Alignment of object properties after a function
It would seem that the function as an object property somehow resets the indentation level.
Expected look after auto-fix:
var obj = {
arr : [ 1, 2, 3 ],
obj_inner1 : { empty: true },
long_fun_name : function f() {
return 42;
},
obj_inner2 : { empty: true },
};
Current behavior:
var obj = {
arr : [ 1, 2, 3 ],
obj_inner1 : { empty: true },
long_fun_name : function f() {
return 42;
},
obj_inner2: { empty: true },
};
If I write the function in one line it's working as expected:
var obj = {
arr : [ 1, 2, 3 ],
obj_inner1 : { empty: true },
long_fun_name : function f() { return 42; },
obj_inner2 : { empty: true },
};
These are my rule settings:
rules: {
"key-spacing": ["error", {
"mode": "minimum",
"align": {
"beforeColon": true,
"afterColon": true,
"on": "colon"
}
}],
// PLUGIN rules
"align-assignments/align-assignments": [2, { "requiresOnly": false } ],
},
ESLint version: v5.16.0
Comments should not reset groups (Optional)
Let's say you have:
const hi = 1;
// Something nice about bye
const bye = 2;
This is valid.
Optionally, I could want to treat the whole thing as a group, making this valid instead.
const hi = 1;
// Something nice about bye
const bye = 2;
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.