diff --git a/.README/rules/check-line-alignment.md b/.README/rules/check-line-alignment.md
index 1ae10ba4b..87a807e8a 100644
--- a/.README/rules/check-line-alignment.md
+++ b/.README/rules/check-line-alignment.md
@@ -22,10 +22,21 @@ Use this to change the tags which are sought for alignment changes. *Currently*
*only works with the "never" option.* Defaults to an array of
`['param', 'arg', 'argument', 'property', 'prop', 'returns', 'return']`.
+##### `customSpacings`
+
+An object with any of the following keys set to an integer. Affects spacing:
+
+- `postDelimiter` - after the asterisk (e.g., `* @param`)
+- `postTag` - after the tag (e.g., `* @param `)
+- `postType` - after the type (e.g., `* @param {someType} `)
+- `postName` - after the name (e.g., `* @param {someType} name `)
+
+If a spacing is not defined, it defaults to one.
+
|||
|---|---|
|Context|everywhere|
-|Options|(a string matching `"always" or "never"` and optional object with `tags`)|
+|Options|(a string matching `"always" or "never"` and optional object with `tags` and `customSpacings`)|
|Tags|`param`, `property`, `returns` and others added by `tags`|
|Aliases|`arg`, `argument`, `prop`, `return`|
|Recommended|false|
diff --git a/README.md b/README.md
index 789da96f7..c7a3026f5 100644
--- a/README.md
+++ b/README.md
@@ -1944,10 +1944,22 @@ Use this to change the tags which are sought for alignment changes. *Currently*
*only works with the "never" option.* Defaults to an array of
`['param', 'arg', 'argument', 'property', 'prop', 'returns', 'return']`.
+
+##### customSpacings
+
+An object with any of the following keys set to an integer. Affects spacing:
+
+- `postDelimiter` - after the asterisk (e.g., `* @param`)
+- `postTag` - after the tag (e.g., `* @param `)
+- `postType` - after the type (e.g., `* @param {someType} `)
+- `postName` - after the name (e.g., `* @param {someType} name `)
+
+If a spacing is not defined, it defaults to one.
+
|||
|---|---|
|Context|everywhere|
-|Options|(a string matching `"always" or "never"` and optional object with `tags`)|
+|Options|(a string matching `"always" or "never"` and optional object with `tags` and `customSpacings`)|
|Tags|`param`, `property`, `returns` and others added by `tags`|
|Aliases|`arg`, `argument`, `prop`, `return`|
|Recommended|false|
@@ -2264,6 +2276,50 @@ function quux () {}
const fn = ( lorem, sit ) => {}
// "jsdoc/check-line-alignment": ["error"|"warn", "always"]
// Message: Expected JSDoc block lines to be aligned.
+
+/**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ *
+ * @return {string} Return description.
+ */
+const fn = ( lorem, sit ) => {}
+// "jsdoc/check-line-alignment": ["error"|"warn", "always",{"customSpacings":{"postDelimiter":2,"postTag":3,"postType":2}}]
+// Message: Expected JSDoc block lines to be aligned.
+
+/**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ *
+ * @return {string} Return description.
+ */
+const fn = ( lorem, sit ) => {}
+// "jsdoc/check-line-alignment": ["error"|"warn", "always",{"customSpacings":{"postName":3}}]
+// Message: Expected JSDoc block lines to be aligned.
+
+/**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ */
+const fn = ( lorem, sit ) => {}
+// "jsdoc/check-line-alignment": ["error"|"warn", "never",{"customSpacings":{"postDelimiter":2,"postTag":3,"postType":2}}]
+// Message: Expected JSDoc block lines to not be aligned.
+
+/**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ */
+const fn = ( lorem, sit ) => {}
+// "jsdoc/check-line-alignment": ["error"|"warn", "never",{"customSpacings":{"postName":3}}]
+// Message: Expected JSDoc block lines to not be aligned.
````
The following patterns are not considered problems:
@@ -2489,6 +2545,28 @@ function func(parameter){
*/
const fn = ( lorem, sit ) => {}
// "jsdoc/check-line-alignment": ["error"|"warn", "always",{"preserveMainDescriptionPostDelimiter":true}]
+
+/**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ *
+ * @return {string} Return description.
+ */
+const fn = ( lorem, sit ) => {}
+// "jsdoc/check-line-alignment": ["error"|"warn", "always",{"customSpacings":{"postDelimiter":2,"postTag":3,"postType":2}}]
+
+/**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ *
+ * @return {string} Return description.
+ */
+const fn = ( lorem, sit ) => {}
+// "jsdoc/check-line-alignment": ["error"|"warn", "never",{"customSpacings":{"postDelimiter":2,"postTag":3,"postType":2}}]
````
diff --git a/src/alignTransform.js b/src/alignTransform.js
index 8caf2e033..85962cdce 100644
--- a/src/alignTransform.js
+++ b/src/alignTransform.js
@@ -1,3 +1,9 @@
+/**
+ * Transform based on https://github.com/syavorsky/comment-parser/blob/master/src/transforms/align.ts
+ *
+ * It contains some customizations to align based on the tags, and some custom options.
+ */
+
import {
Markers,
} from 'comment-parser/lib/primitives';
@@ -58,7 +64,12 @@ const space = (len) => {
return ''.padStart(len, ' ');
};
-const alignTransform = (tags, indent, preserveMainDescriptionPostDelimiter) => {
+const alignTransform = ({
+ customSpacings,
+ tags,
+ indent,
+ preserveMainDescriptionPostDelimiter,
+}) => {
let intoTags = false;
let width;
@@ -90,17 +101,24 @@ const alignTransform = (tags, indent, preserveMainDescriptionPostDelimiter) => {
}
}
- tokens.postDelimiter = nothingAfter.delim ? '' : ' ';
+ const spacings = {
+ postDelimiter: customSpacings?.postDelimiter || 1,
+ postName: customSpacings?.postName || 1,
+ postTag: customSpacings?.postTag || 1,
+ postType: customSpacings?.postType || 1,
+ };
+
+ tokens.postDelimiter = nothingAfter.delim ? '' : space(spacings.postDelimiter);
if (!nothingAfter.tag) {
- tokens.postTag = space(width.tag - tokens.tag.length + 1);
+ tokens.postTag = space(width.tag - tokens.tag.length + spacings.postTag);
}
if (!nothingAfter.type) {
- tokens.postType = space(width.type - tokens.type.length + 1);
+ tokens.postType = space(width.type - tokens.type.length + spacings.postType);
}
if (!nothingAfter.name) {
// If post name is empty for all lines (name width 0), don't add post name spacing.
- tokens.postName = width.name === 0 ? '' : space(width.name - tokens.name.length + 1);
+ tokens.postName = width.name === 0 ? '' : space(width.name - tokens.name.length + spacings.postName);
}
return tokens;
diff --git a/src/rules/checkLineAlignment.js b/src/rules/checkLineAlignment.js
index 910ea525e..d7fccce22 100644
--- a/src/rules/checkLineAlignment.js
+++ b/src/rules/checkLineAlignment.js
@@ -8,7 +8,7 @@ const {
flow: commentFlow,
} = transforms;
-const checkNotAlignedPerTag = (utils, tag) => {
+const checkNotAlignedPerTag = (utils, tag, customSpacings) => {
/*
start +
delimiter +
@@ -61,11 +61,12 @@ const checkNotAlignedPerTag = (utils, tag) => {
const contentProp = contentProps[idx];
const contentPropVal = tokens[contentProp];
const spacerPropVal = tokens[spacerProp];
+ const spacing = customSpacings?.[spacerProp] || 1;
// There will be extra alignment if...
- // 1. There is extra whitespace within a single spacer segment OR
- return spacerPropVal.length > 1 ||
+ // 1. The spaces don't match the space it should have (1 or custom spacing) OR
+ return spacerPropVal.length !== spacing && spacerPropVal.length !== 0 ||
// 2. There is a (single) space, no immediate content, and yet another
// space is found subsequently (not separated by intervening content)
@@ -80,7 +81,8 @@ const checkNotAlignedPerTag = (utils, tag) => {
const contentPropVal = tokens[contentProp];
if (contentPropVal) {
- tokens[spacerProp] = ' ';
+ const spacing = customSpacings?.[spacerProp] || 1;
+ tokens[spacerProp] = ''.padStart(spacing, ' ');
followedBySpace(idx, (hasSpace, contentPrp) => {
if (hasSpace) {
tokens[contentPrp] = '';
@@ -97,6 +99,7 @@ const checkNotAlignedPerTag = (utils, tag) => {
};
const checkAlignment = ({
+ customSpacings,
indent,
jsdoc,
jsdocNode,
@@ -105,7 +108,14 @@ const checkAlignment = ({
tags,
utils,
}) => {
- const transform = commentFlow(alignTransform(tags, indent, preserveMainDescriptionPostDelimiter));
+ const transform = commentFlow(
+ alignTransform({
+ customSpacings,
+ indent,
+ preserveMainDescriptionPostDelimiter,
+ tags,
+ }),
+ );
const transformedJsdoc = transform(jsdoc);
const comment = '/*' + jsdocNode.value + '*/';
@@ -133,6 +143,7 @@ export default iterateJsdoc(({
const {
tags: applicableTags = ['param', 'arg', 'argument', 'property', 'prop', 'returns', 'return'],
preserveMainDescriptionPostDelimiter,
+ customSpacings,
} = context.options[1] || {};
if (context.options[0] === 'always') {
@@ -142,6 +153,7 @@ export default iterateJsdoc(({
}
checkAlignment({
+ customSpacings,
indent,
jsdoc,
jsdocNode,
@@ -156,7 +168,7 @@ export default iterateJsdoc(({
const foundTags = utils.getPresentTags(applicableTags);
foundTags.forEach((tag) => {
- checkNotAlignedPerTag(utils, tag);
+ checkNotAlignedPerTag(utils, tag, customSpacings);
});
}, {
iterateAllJsdocs: true,
@@ -174,6 +186,23 @@ export default iterateJsdoc(({
{
additionalProperties: false,
properties: {
+ customSpacings: {
+ additionalProperties: false,
+ properties: {
+ postDelimiter: {
+ type: 'integer',
+ },
+ postName: {
+ type: 'integer',
+ },
+ postTag: {
+ type: 'integer',
+ },
+ postType: {
+ type: 'integer',
+ },
+ },
+ },
preserveMainDescriptionPostDelimiter: {
default: false,
type: 'boolean',
diff --git a/test/rules/assertions/checkLineAlignment.js b/test/rules/assertions/checkLineAlignment.js
index 5849aa6b1..438d6f745 100644
--- a/test/rules/assertions/checkLineAlignment.js
+++ b/test/rules/assertions/checkLineAlignment.js
@@ -917,6 +917,146 @@ export default {
const fn = ( lorem, sit ) => {}
`,
},
+ {
+ code: `
+ /**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ *
+ * @return {string} Return description.
+ */
+ const fn = ( lorem, sit ) => {}
+ `,
+ errors: [
+ {
+ line: 2,
+ message: 'Expected JSDoc block lines to be aligned.',
+ type: 'Block',
+ },
+ ],
+ options: ['always', {
+ customSpacings: {
+ postDelimiter: 2,
+ postTag: 3,
+ postType: 2,
+ },
+ }],
+ output: `
+ /**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ *
+ * @return {string} Return description.
+ */
+ const fn = ( lorem, sit ) => {}
+ `,
+ },
+ {
+ code: `
+ /**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ *
+ * @return {string} Return description.
+ */
+ const fn = ( lorem, sit ) => {}
+ `,
+ errors: [
+ {
+ line: 2,
+ message: 'Expected JSDoc block lines to be aligned.',
+ type: 'Block',
+ },
+ ],
+ options: ['always', {
+ customSpacings: {
+ postName: 3,
+ },
+ }],
+ output: `
+ /**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ *
+ * @return {string} Return description.
+ */
+ const fn = ( lorem, sit ) => {}
+ `,
+ },
+ {
+ code: `
+ /**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ */
+ const fn = ( lorem, sit ) => {}
+ `,
+ errors: [
+ {
+ line: 6,
+ message: 'Expected JSDoc block lines to not be aligned.',
+ type: 'Block',
+ },
+ ],
+ options: ['never', {
+ customSpacings: {
+ postDelimiter: 2,
+ postTag: 3,
+ postType: 2,
+ },
+ }],
+ output: `
+ /**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ */
+ const fn = ( lorem, sit ) => {}
+ `,
+ },
+ {
+ code: `
+ /**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ */
+ const fn = ( lorem, sit ) => {}
+ `,
+ errors: [
+ {
+ line: 6,
+ message: 'Expected JSDoc block lines to not be aligned.',
+ type: 'Block',
+ },
+ ],
+ options: ['never', {
+ customSpacings: {
+ postName: 3,
+ },
+ }],
+ output: `
+ /**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ */
+ const fn = ( lorem, sit ) => {}
+ `,
+ },
],
valid: [
{
@@ -1255,5 +1395,45 @@ export default {
preserveMainDescriptionPostDelimiter: true,
}],
},
+ {
+ code: `
+ /**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ *
+ * @return {string} Return description.
+ */
+ const fn = ( lorem, sit ) => {}
+ `,
+ options: ['always', {
+ customSpacings: {
+ postDelimiter: 2,
+ postTag: 3,
+ postType: 2,
+ },
+ }],
+ },
+ {
+ code: `
+ /**
+ * Function description.
+ *
+ * @param {string} lorem Description.
+ * @param {int} sit Description multi words.
+ *
+ * @return {string} Return description.
+ */
+ const fn = ( lorem, sit ) => {}
+ `,
+ options: ['never', {
+ customSpacings: {
+ postDelimiter: 2,
+ postTag: 3,
+ postType: 2,
+ },
+ }],
+ },
],
};