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

Add consistent option to vue/padding-line-between-tags #1982

Merged
merged 5 commits into from Sep 30, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
155 changes: 93 additions & 62 deletions lib/rules/padding-line-between-tags.js
Expand Up @@ -24,44 +24,92 @@ function splitLines(text) {
* @param {RuleContext} context
* @param {VElement} tag
* @param {VElement} sibling
* @param {number} lineDifference
*/
function insertNewLine(context, tag, sibling) {
context.report({
messageId: 'always',
loc: sibling.loc,
// @ts-ignore
fix(fixer) {
return fixer.insertTextAfter(tag, '\n')
}
})
function insertNewLine(context, tag, sibling, lineDifference) {
const endTag = tag.endTag || tag.startTag

if (lineDifference === 1) {
context.report({
messageId: 'always',
loc: sibling.loc,
// @ts-ignore
fix(fixer) {
return fixer.insertTextAfter(tag, '\n')
}
})
} else if (lineDifference === 0) {
context.report({
messageId: 'always',
loc: sibling.loc,
// @ts-ignore
fix(fixer) {
const lastSpaces = /** @type {RegExpExecArray} */ (
/^\s*/.exec(context.getSourceCode().lines[endTag.loc.start.line - 1])
)[0]

return fixer.insertTextAfter(endTag, `\n\n${lastSpaces}`)
}
})
}
}

/**
* @param {RuleContext} context
* @param {VEndTag | VStartTag} endTag
* @param {VElement} sibling
* @param {number} lineDifference
*/
function removeExcessLines(context, endTag, sibling) {
context.report({
messageId: 'never',
loc: sibling.loc,
// @ts-ignore
fix(fixer) {
const start = endTag.range[1]
const end = sibling.range[0]
const paddingText = context.getSourceCode().text.slice(start, end)
const textBetween = splitLines(paddingText)
let newTextBetween = `\n${textBetween.pop()}`
for (let i = textBetween.length - 1; i >= 0; i--) {
if (!/^\s*$/.test(textBetween[i])) {
newTextBetween = `${i === 0 ? '' : '\n'}${
textBetween[i]
}${newTextBetween}`
function removeExcessLines(context, endTag, sibling, lineDifference) {
if (lineDifference > 1) {
let hasOnlyTextBetween = true
for (
let i = endTag.loc.start.line;
i < sibling.loc.start.line - 1 && hasOnlyTextBetween;
i++
) {
hasOnlyTextBetween = !/^\s*$/.test(context.getSourceCode().lines[i])
}
if (!hasOnlyTextBetween) {
context.report({
messageId: 'never',
loc: sibling.loc,
// @ts-ignore
fix(fixer) {
const start = endTag.range[1]
const end = sibling.range[0]
const paddingText = context.getSourceCode().text.slice(start, end)
const textBetween = splitLines(paddingText)
let newTextBetween = `\n${textBetween.pop()}`
for (let i = textBetween.length - 1; i >= 0; i--) {
if (!/^\s*$/.test(textBetween[i])) {
newTextBetween = `${i === 0 ? '' : '\n'}${
textBetween[i]
}${newTextBetween}`
}
}
return fixer.replaceTextRange([start, end], `${newTextBetween}`)
}
}
return fixer.replaceTextRange([start, end], `${newTextBetween}`)
})
}
})
}
}

/**
* @param {VElement} block
* @param {Array<{blankLine: "always" | "never" | "consistent", prev: string, next: string}>} configureList
*/
function hasConsistentConfiguration(block, configureList) {
for (let i = configureList.length - 1; i >= 0; --i) {
const configure = configureList[i]
if (
(configure.blankLine !== 'consistent' && configure.prev === '*') ||
configure.prev === block.name
) {
return false
}
}
return true
}

// ------------------------------------------------------------------------------
Expand All @@ -72,7 +120,7 @@ function removeExcessLines(context, endTag, sibling) {
* @param {RuleContext} context
*/
function checkNewline(context) {
/** @type {Array<{blankLine: "always" | "never", prev: string, next: string}>} */
/** @type {Array<{blankLine: "always" | "never" | "consistent", prev: string, next: string}>} */
const configureList = context.options[0] || [
{ blankLine: 'always', prev: '*', next: '*' }
]
Expand Down Expand Up @@ -109,40 +157,23 @@ function checkNewline(context) {
const lineDifference =
closestSibling.loc.start.line - endTag.loc.end.line
if (configure.blankLine === 'always') {
if (lineDifference === 1) {
insertNewLine(context, block, closestSibling)
} else if (lineDifference === 0) {
context.report({
messageId: 'always',
loc: closestSibling.loc,
// @ts-ignore
fix(fixer) {
const lastSpaces = /** @type {RegExpExecArray} */ (
/^\s*/.exec(
context.getSourceCode().lines[endTag.loc.start.line - 1]
)
)[0]

return fixer.insertTextAfter(endTag, `\n\n${lastSpaces}`)
}
})
insertNewLine(context, block, closestSibling, lineDifference)
} else if (configure.blankLine === 'consistent') {
dev1437 marked this conversation as resolved.
Show resolved Hide resolved
const siblingElements = block.parent.children.filter(
(element) =>
element.type === 'VElement' &&
hasConsistentConfiguration(element, configureList)
)

const siblingLineDifference =
siblingElements[1].loc.start.line - siblingElements[0].loc.end.line
if (siblingLineDifference > 1) {
insertNewLine(context, block, closestSibling, lineDifference)
} else {
removeExcessLines(context, endTag, closestSibling, lineDifference)
}
ota-meshi marked this conversation as resolved.
Show resolved Hide resolved
} else {
if (lineDifference > 1) {
let hasOnlyTextBetween = true
for (
let i = endTag.loc.start.line;
i < closestSibling.loc.start.line - 1 && hasOnlyTextBetween;
i++
) {
hasOnlyTextBetween = !/^\s*$/.test(
context.getSourceCode().lines[i]
)
}
if (!hasOnlyTextBetween) {
removeExcessLines(context, endTag, closestSibling)
}
}
removeExcessLines(context, endTag, closestSibling, lineDifference)
}
break
}
Expand All @@ -166,7 +197,7 @@ module.exports = {
items: {
type: 'object',
properties: {
blankLine: { enum: ['always', 'never'] },
blankLine: { enum: ['always', 'never', 'consistent'] },
prev: { type: 'string' },
next: { type: 'string' }
},
Expand Down