diff --git a/docs/rules/no-multi-spaces.md b/docs/rules/no-multi-spaces.md
new file mode 100644
index 000000000..b93254dab
--- /dev/null
+++ b/docs/rules/no-multi-spaces.md
@@ -0,0 +1,31 @@
+# This rule warns about the usage of extra whitespaces between attributes (no-multi-spaces)
+
+The `--fix` option on the command line can automatically fix some of the problems reported by this rule.
+
+This rule aims to remove multiple spaces in a row between attributes witch are not used for indentation.
+
+## Rule Details
+
+Examples of **incorrect** code for this rule:
+
+```html
+
+
+
+
+```
+
+Examples of **correct** code for this rule:
+
+```html
+
+
+
+
+```
+
+### Options
+
+Nothing
diff --git a/lib/rules/no-multi-spaces.js b/lib/rules/no-multi-spaces.js
new file mode 100644
index 000000000..c9d6369f4
--- /dev/null
+++ b/lib/rules/no-multi-spaces.js
@@ -0,0 +1,66 @@
+/**
+ * @fileoverview This rule warns about the usage of extra whitespaces between attributes
+ * @author Armano
+ */
+'use strict'
+
+// ------------------------------------------------------------------------------
+// Rule Definition
+// ------------------------------------------------------------------------------
+
+module.exports = {
+ meta: {
+ docs: {
+ description: 'This rule warns about the usage of extra whitespaces between attributes',
+ category: 'Stylistic Issues',
+ recommended: false
+ },
+ fixable: 'whitespace', // or "code" or "whitespace"
+ schema: []
+ },
+
+ /**
+ * @param {RuleContext} context - The rule context.
+ * @returns {Object} AST event handlers.
+ */
+ create (context) {
+ // ----------------------------------------------------------------------
+ // Public
+ // ----------------------------------------------------------------------
+
+ return {
+ Program (node) {
+ if (context.parserServices.getTemplateBodyTokenStore == null) {
+ context.report({
+ loc: { line: 1, column: 0 },
+ message: 'Use the latest vue-eslint-parser. See also https://github.com/vuejs/eslint-plugin-vue#what-is-the-use-the-latest-vue-eslint-parser-error.'
+ })
+ return
+ }
+ const sourceCode = context.getSourceCode()
+ const tokenStore = context.parserServices.getTemplateBodyTokenStore()
+ const tokens = tokenStore.getTokens(node.templateBody, { includeComments: true })
+
+ let prevToken = tokens.shift()
+ for (const token of tokens) {
+ const spaces = token.range[0] - prevToken.range[1]
+ if (spaces > 1 && token.loc.start.line === prevToken.loc.start.line) {
+ context.report({
+ node: token,
+ loc: {
+ start: prevToken.loc.end,
+ end: token.loc.start
+ },
+ message: "Multiple spaces found before '{{displayValue}}'.",
+ fix: (fixer) => fixer.replaceTextRange([prevToken.range[1], token.range[0]], ' '),
+ data: {
+ displayValue: sourceCode.getText(token)
+ }
+ })
+ }
+ prevToken = token
+ }
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 6ebff6e25..e111a90cc 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
},
"dependencies": {
"requireindex": "^1.1.0",
- "vue-eslint-parser": "2.0.0-beta.6"
+ "vue-eslint-parser": "2.0.0-beta.7"
},
"devDependencies": {
"@types/node": "^4.2.16",
diff --git a/tests/lib/rules/no-multi-spaces.js b/tests/lib/rules/no-multi-spaces.js
new file mode 100644
index 000000000..afb93cf07
--- /dev/null
+++ b/tests/lib/rules/no-multi-spaces.js
@@ -0,0 +1,177 @@
+/**
+ * @fileoverview This rule warns about the usage of extra whitespaces between attributes
+ * @author Armano
+ */
+'use strict'
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+const rule = require('../../../lib/rules/no-multi-spaces')
+const RuleTester = require('eslint').RuleTester
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+const ruleTester = new RuleTester({
+ parser: 'vue-eslint-parser',
+ parserOptions: { ecmaVersion: 2015 }
+})
+
+ruleTester.run('no-multi-spaces', rule, {
+ valid: [
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ '{{ test }}
',
+ '{{test}}
',
+ '{{test}}
',
+ '{{test}}
',
+ '{{ i }}
',
+ '{{ i }}
',
+ ' {{ a }}
',
+ ' \n {{ a }}
'
+ ],
+ invalid: [
+ {
+ code: '',
+ output: '',
+ errors: [{
+ message: "Multiple spaces found before '/>'.",
+ type: 'HTMLSelfClosingTagClose'
+ }]
+ },
+ {
+ code: '',
+ output: '',
+ errors: [
+ {
+ message: "Multiple spaces found before 'class'.",
+ type: 'HTMLIdentifier'
+ },
+ {
+ message: "Multiple spaces found before '/>'.",
+ type: 'HTMLSelfClosingTagClose'
+ }
+ ]
+ },
+ {
+ code: '',
+ output: '',
+ errors: [
+ {
+ message: "Multiple spaces found before 'class'.",
+ type: 'HTMLIdentifier'
+ },
+ {
+ message: "Multiple spaces found before '/>'.",
+ type: 'HTMLSelfClosingTagClose'
+ }
+ ]
+ },
+ {
+ code: '',
+ output: '',
+ errors: [
+ {
+ message: "Multiple spaces found before ':class'.",
+ type: 'HTMLIdentifier'
+ },
+ {
+ message: "Multiple spaces found before '/>'.",
+ type: 'HTMLSelfClosingTagClose'
+ }
+ ]
+ },
+ {
+ code: '',
+ output: '',
+ errors: [{
+ message: "Multiple spaces found before '/>'.",
+ type: 'HTMLSelfClosingTagClose'
+ }]
+ },
+ {
+ code: '',
+ output: '',
+ errors: [{
+ message: "Multiple spaces found before '/>'.",
+ type: 'HTMLSelfClosingTagClose'
+ }]
+ },
+ {
+ code: '',
+ output: '',
+ errors: [{
+ message: "Multiple spaces found before '/>'.",
+ type: 'HTMLSelfClosingTagClose'
+ }]
+ },
+ {
+ code: '',
+ output: '',
+ errors: [
+ {
+ message: "Multiple spaces found before '/>'.",
+ type: 'HTMLSelfClosingTagClose'
+ }
+ ]
+ },
+ {
+ code: '{{ test }}
',
+ output: '{{ test }}
',
+ errors: [
+ {
+ message: "Multiple spaces found before 'test'.",
+ type: 'Identifier'
+ },
+ {
+ message: "Multiple spaces found before '}}'.",
+ type: 'VExpressionEnd'
+ }
+ ]
+ },
+ {
+ code: '',
+ output: '',
+ errors: [
+ {
+ message: "Multiple spaces found before '>'.",
+ type: 'HTMLTagClose'
+ }
+ ]
+ },
+ {
+ code: '{{ test }}
',
+ output: '{{ test }}
',
+ errors: [
+ {
+ message: "Multiple spaces found before 'i'.",
+ type: 'Identifier'
+ },
+ {
+ message: "Multiple spaces found before 'in'.",
+ type: 'Keyword'
+ },
+ {
+ message: "Multiple spaces found before 'b'.",
+ type: 'Identifier'
+ },
+ {
+ message: "Multiple spaces found before '\"'.",
+ type: 'Punctuator'
+ }
+ ]
+ }
+ ]
+})