minor adjustment to readme
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / no-multi-spaces.js
1 /**
2  * @fileoverview Disallow use of multiple spaces.
3  * @author Nicholas C. Zakas
4  */
5
6 "use strict";
7
8 const astUtils = require("./utils/ast-utils");
9
10 //------------------------------------------------------------------------------
11 // Rule Definition
12 //------------------------------------------------------------------------------
13
14 module.exports = {
15     meta: {
16         type: "layout",
17
18         docs: {
19             description: "disallow multiple spaces",
20             category: "Best Practices",
21             recommended: false,
22             url: "https://eslint.org/docs/rules/no-multi-spaces"
23         },
24
25         fixable: "whitespace",
26
27         schema: [
28             {
29                 type: "object",
30                 properties: {
31                     exceptions: {
32                         type: "object",
33                         patternProperties: {
34                             "^([A-Z][a-z]*)+$": {
35                                 type: "boolean"
36                             }
37                         },
38                         additionalProperties: false
39                     },
40                     ignoreEOLComments: {
41                         type: "boolean",
42                         default: false
43                     }
44                 },
45                 additionalProperties: false
46             }
47         ]
48     },
49
50     create(context) {
51         const sourceCode = context.getSourceCode();
52         const options = context.options[0] || {};
53         const ignoreEOLComments = options.ignoreEOLComments;
54         const exceptions = Object.assign({ Property: true }, options.exceptions);
55         const hasExceptions = Object.keys(exceptions).filter(key => exceptions[key]).length > 0;
56
57         /**
58          * Formats value of given comment token for error message by truncating its length.
59          * @param {Token} token comment token
60          * @returns {string} formatted value
61          * @private
62          */
63         function formatReportedCommentValue(token) {
64             const valueLines = token.value.split("\n");
65             const value = valueLines[0];
66             const formattedValue = `${value.slice(0, 12)}...`;
67
68             return valueLines.length === 1 && value.length <= 12 ? value : formattedValue;
69         }
70
71         //--------------------------------------------------------------------------
72         // Public
73         //--------------------------------------------------------------------------
74
75         return {
76             Program() {
77                 sourceCode.tokensAndComments.forEach((leftToken, leftIndex, tokensAndComments) => {
78                     if (leftIndex === tokensAndComments.length - 1) {
79                         return;
80                     }
81                     const rightToken = tokensAndComments[leftIndex + 1];
82
83                     // Ignore tokens that don't have 2 spaces between them or are on different lines
84                     if (
85                         !sourceCode.text.slice(leftToken.range[1], rightToken.range[0]).includes("  ") ||
86                         leftToken.loc.end.line < rightToken.loc.start.line
87                     ) {
88                         return;
89                     }
90
91                     // Ignore comments that are the last token on their line if `ignoreEOLComments` is active.
92                     if (
93                         ignoreEOLComments &&
94                         astUtils.isCommentToken(rightToken) &&
95                         (
96                             leftIndex === tokensAndComments.length - 2 ||
97                             rightToken.loc.end.line < tokensAndComments[leftIndex + 2].loc.start.line
98                         )
99                     ) {
100                         return;
101                     }
102
103                     // Ignore tokens that are in a node in the "exceptions" object
104                     if (hasExceptions) {
105                         const parentNode = sourceCode.getNodeByRangeIndex(rightToken.range[0] - 1);
106
107                         if (parentNode && exceptions[parentNode.type]) {
108                             return;
109                         }
110                     }
111
112                     let displayValue;
113
114                     if (rightToken.type === "Block") {
115                         displayValue = `/*${formatReportedCommentValue(rightToken)}*/`;
116                     } else if (rightToken.type === "Line") {
117                         displayValue = `//${formatReportedCommentValue(rightToken)}`;
118                     } else {
119                         displayValue = rightToken.value;
120                     }
121
122                     context.report({
123                         node: rightToken,
124                         loc: { start: leftToken.loc.end, end: rightToken.loc.start },
125                         message: "Multiple spaces found before '{{displayValue}}'.",
126                         data: { displayValue },
127                         fix: fixer => fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " ")
128                     });
129                 });
130             }
131         };
132
133     }
134 };