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

New Add vue/new-line-between-multiline-property rule #1080

Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
28ffe21
feat: init commit
IWANABETHATGUY Mar 18, 2020
dcce787
feat: add test, make rule configurable
IWANABETHATGUY Mar 18, 2020
df5a3f2
docs: update doc📖
IWANABETHATGUY Mar 18, 2020
fed017e
feat: merge from master
IWANABETHATGUY Mar 18, 2020
0441bb0
chore: update version
IWANABETHATGUY Mar 18, 2020
a63853d
ierge branch 'master' into feature/new-line-between-multi-line-property
IWANABETHATGUY Jun 27, 2020
d03dbda
lint fix
IWANABETHATGUY Jun 27, 2020
37654fc
test: 💍 add test case
IWANABETHATGUY Jul 26, 2020
154b00a
test: 💍 fix report when multi-line-property in callExpression
IWANABETHATGUY Jul 26, 2020
be657ee
Merge branch 'master' into feature/new-line-between-multi-line-property
IWANABETHATGUY Jul 27, 2020
f948a95
test: 💍 fix test in change request
IWANABETHATGUY Aug 4, 2020
bc6d9a5
Merge branch 'master' of github.com:IWANABETHATGUY/eslint-plugin-vue …
IWANABETHATGUY Aug 4, 2020
4b3d8c1
Merge branch 'feature/new-line-between-multi-line-property' of github…
IWANABETHATGUY Aug 4, 2020
719c920
test: 💍 js doc
IWANABETHATGUY Aug 5, 2020
f7a7980
Merge branch 'feature/new-line-between-multi-line-property' of github…
IWANABETHATGUY Aug 5, 2020
269a40e
test: 💍 Vue.component()
IWANABETHATGUY Aug 6, 2020
26e9d00
docs: ✏️ docs
IWANABETHATGUY Aug 6, 2020
12a9aaa
fix: 🐛 using sourceCode api
IWANABETHATGUY Aug 8, 2020
aa7d47a
fix: 🐛 using getTokenBewteen instead of getAlltoken
IWANABETHATGUY Aug 8, 2020
b556320
fix: 🐛 lint error
IWANABETHATGUY Aug 8, 2020
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
Binary file modified docs/.vuepress/public/favicon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/rules/README.md
Expand Up @@ -289,6 +289,7 @@ For example:
| [vue/html-comment-content-spacing](./html-comment-content-spacing.md) | enforce unified spacing in HTML comments | :wrench: |
| [vue/html-comment-indent](./html-comment-indent.md) | enforce consistent indentation in HTML comments | :wrench: |
| [vue/match-component-file-name](./match-component-file-name.md) | require component name property to match its file name | |
| [vue/new-line-between-multi-line-property](./new-line-between-multi-line-property.md) | enforce new lines between multi-line properties in Vue components | :wrench: |
| [vue/no-bare-strings-in-template](./no-bare-strings-in-template.md) | disallow the use of bare strings in `<template>` | |
| [vue/no-boolean-default](./no-boolean-default.md) | disallow boolean defaults | :wrench: |
| [vue/no-duplicate-attr-inheritance](./no-duplicate-attr-inheritance.md) | enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"` | |
Expand Down
93 changes: 93 additions & 0 deletions docs/rules/new-line-between-multi-line-property.md
@@ -0,0 +1,93 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/new-line-between-multi-line-property
description: enforce new lines between multi-line properties in Vue components
---
# vue/new-line-between-multi-line-property
> enforce new lines between multi-line properties in Vue components

- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.

## :book: Rule Details

This rule aims at enforcing new lines between multi-line properties in Vue components to help readability

Examples of **incorrect** code for this rule:

<eslint-code-block fix :rules="{'vue/new-line-between-multi-line-property': ['error']}">

```vue
<script>
export default {
props: {
value: {
type: String,
required: true
},
focused: {
type: Boolean,
default: false,
required: true
},

label: String,
icon: String
},
computed: {

}
}
</script>
```

</eslint-code-block>


Examples of **correct** code for this rule:

<eslint-code-block fix :rules="{'vue/new-line-between-multi-line-property': ['error']}">

```vue
<script>
export default {
props: {
value: {
type: String,
required: true
},

focused: {
type: Boolean,
default: false,
required: true
},

label: String,
icon: String
},

computed: {

}
}
</script>
```

</eslint-code-block>

## :wrench: Option
```json
{
"vue/new-line-between-multiline-property": ["error", {
"minLineOfMultilineProperty": 2
}]
}
```
- `minLineOfMultilineProperty` ... `type: number`, Define the minimum number of rows for a multi-line property .`type:` number, `default:` 2 , `min:`: 2
## :books: Further Reading
Nothing here
## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/new-line-between-multi-line-property.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/new-line-between-multi-line-property.js)
1 change: 1 addition & 0 deletions lib/configs/no-layout-rules.js
Expand Up @@ -28,6 +28,7 @@ module.exports = {
'vue/max-len': 'off',
'vue/multiline-html-element-content-newline': 'off',
'vue/mustache-interpolation-spacing': 'off',
'vue/new-line-between-multi-line-property': 'off',
'vue/no-extra-parens': 'off',
'vue/no-multi-spaces': 'off',
'vue/no-spaces-around-equal-signs-in-attribute': 'off',
Expand Down
1 change: 1 addition & 0 deletions lib/index.js
Expand Up @@ -44,6 +44,7 @@ module.exports = {
'multiline-html-element-content-newline': require('./rules/multiline-html-element-content-newline'),
'mustache-interpolation-spacing': require('./rules/mustache-interpolation-spacing'),
'name-property-casing': require('./rules/name-property-casing'),
'new-line-between-multi-line-property': require('./rules/new-line-between-multi-line-property'),
'no-arrow-functions-in-watch': require('./rules/no-arrow-functions-in-watch'),
'no-async-in-computed-properties': require('./rules/no-async-in-computed-properties'),
'no-bare-strings-in-template': require('./rules/no-bare-strings-in-template'),
Expand Down
140 changes: 140 additions & 0 deletions lib/rules/new-line-between-multi-line-property.js
@@ -0,0 +1,140 @@
/**
* @fileoverview Enforce new lines between multi-line properties in Vue components.
* @author IWANABETHATGUY
*/
'use strict'

const utils = require('../utils')
// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
// @ts-ignore
module.exports = {
meta: {
type: 'layout',
docs: {
description:
'enforce new lines between multi-line properties in Vue components',
categories: undefined,
url:
'https://eslint.vuejs.org/rules/new-line-between-multi-line-property.html'
},
fixable: 'whitespace', // or "code" or "whitespace"
schema: [
{
type: 'object',
properties: {
// number of line you want to insert after multi-line property
minLineOfMultilineProperty: {
type: 'number',
minimum: 2
}
}
}
]
},

/** @param {RuleContext} context */
create(context) {
// always insert one line
const insertLine = 1

let minLineOfMultilineProperty = 2
if (
context.options &&
context.options[0] &&
context.options[0].minLineOfMultilineProperty
) {
minLineOfMultilineProperty = context.options[0].minLineOfMultilineProperty
}

/** @type {any[]} */
const callStack = []
/** @type {any[]} */
let comments = []
return Object.assign(
{
/**
* @param {Program} node
*/
Program(node) {
comments = node.comments
IWANABETHATGUY marked this conversation as resolved.
Show resolved Hide resolved
}
},
utils.defineVueVisitor(context, {
CallExpression(node) {
callStack.push(node)
},
'CallExpression:exit'() {
callStack.pop()
},

/**
* @param {ObjectExpression} node
*/
ObjectExpression(node) {
if (callStack.length) {
return
}
const properties = node.properties
for (let i = 1; i < properties.length; i++) {
const cur = properties[i]
const pre = properties[i - 1]

/** @type {any[]} */
const leadingComments = []
// getFirstLeadingComments is enough , after that break the loop.
for (
let commentsIndex = 0;
commentsIndex < comments.length;
commentsIndex++
) {
const comment = comments[commentsIndex]
if (
comment.range[0] > pre.range[1] &&
comment.range[1] < cur.range[0]
) {
leadingComments.push(comments[commentsIndex])
IWANABETHATGUY marked this conversation as resolved.
Show resolved Hide resolved
break
}
}
const lineCountOfPreProperty =
pre.loc.end.line - pre.loc.start.line + 1
let curStartLine = cur.loc.start.line
if (leadingComments.length) {
curStartLine = leadingComments[0].loc.start.line
}
const lineCountBetweenCurAndPreProperty =
curStartLine - pre.loc.end.line - 1
if (
lineCountOfPreProperty >= minLineOfMultilineProperty &&
lineCountBetweenCurAndPreProperty < insertLine
) {
context.report({
node: pre,
loc: pre.loc,
message:
'Enforce new lines between multi-line properties in Vue components.',
// @ts-ignore
fix(fixer) {
let firstPositionOfLine = cur.range[0] - cur.loc.start.column
if (leadingComments.length) {
const firstComment = leadingComments[0]
firstPositionOfLine =
firstComment.range[0] - firstComment.loc.start.column
}
// this action equal to insert number of line before node
return fixer.insertTextAfterRange(
[firstPositionOfLine, firstPositionOfLine],
'\n'
// to avoid conflict with no-multiple-empty-lines, only insert one newline
)
}
})
}
}
}
})
)
}
}