Skip to content

Commit

Permalink
Clean up inlined stylelint-vscode implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
thibaudcolas committed Dec 8, 2019
1 parent e42de14 commit 72fcb11
Show file tree
Hide file tree
Showing 9 changed files with 454 additions and 300 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Expand Up @@ -11,6 +11,10 @@ jobs:
osx_image: xcode10.2
- os: windows
script: node lib/find-pkg-dir/test.js
- dist: xenial
script: node lib/stylelint-vscode/test/test.js
- os: windows
script: node lib\\stylelint-vscode\\test\\test.js

notifications:
email: false
8 changes: 0 additions & 8 deletions lib/stylelint-vscode/.travis.yml

This file was deleted.

74 changes: 37 additions & 37 deletions lib/stylelint-vscode/README.md
@@ -1,29 +1,37 @@
# stylelint-vscode

[![npm version](https://img.shields.io/npm/v/stylelint-vscode.svg)](https://www.npmjs.com/package/stylelint-vscode)
[![Build Status](https://travis-ci.com/shinnn/stylelint-vscode.svg?branch=master)](https://travis-ci.com/shinnn/stylelint-vscode)
[![codecov](https://codecov.io/gh/shinnn/stylelint-vscode/branch/master/graph/badge.svg)](https://codecov.io/gh/shinnn/stylelint-vscode)
> 🚧 Inlined dependency taken from [https://github.com/shinnn/stylelint-vscode](https://github.com/shinnn/stylelint-vscode).
---

A [stylelint](https://github.com/stylelint/stylelint) wrapper to easily integrate with [Visual Studio Code](https://code.visualstudio.com/) [language server](https://github.com/Microsoft/vscode-languageserver-node)

```javascript
const stylelintVSCode = require('stylelint-vscode');
const {TextDocument} = require('vscode-languageserver-types');
const { TextDocument } = require('vscode-languageserver-types');

(async () => {
await stylelintVSCode(TextDocument.create('file:///Users/me/0.css', 'css', 1, `
await stylelintVSCode(
TextDocument.create(
'file:///Users/me/0.css',
'css',
1,
`
p {
line-height: .8;
color: red;
}`), {
code,
config: {
rules: {
'number-leading-zero': 'always',
'color-named': ['never', {severity: 'warning'}]
}
}
}); /* => [{
}`,
),
{
code,
config: {
rules: {
'number-leading-zero': 'always',
'color-named': ['never', { severity: 'warning' }],
},
},
},
); /* => [{
range: {
start: {line: 2, character: 14},
end: {line: 2, character: 14}
Expand Down Expand Up @@ -59,26 +67,26 @@ npm install stylelint-vscode
const stylelintVSCode = require('stylelint-vscode');
```

### stylelintVSCode(*textDocument* [, *options*])
### stylelintVSCode(_textDocument_ [, *options*])

*textDocument*: [`TextDocument`](https://code.visualstudio.com/docs/extensionAPI/vscode-api#TextDocument)
*options*: `Object` (directly passed to [`stylelint.lint`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#the-stylelint-nodejs-api))
_textDocument_: [`TextDocument`](https://code.visualstudio.com/docs/extensionAPI/vscode-api#TextDocument)
_options_: `Object` (directly passed to [`stylelint.lint`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#the-stylelint-nodejs-api))
Return: `Promise<Array<Object>>`

It works like [`stylelint.lint()`](https://github.com/stylelint/stylelint/blob/10.0.1/lib/index.js#L31), except for:

* [`code`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#code) and [`codeFilename`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#codefilename) option values are derived from a `TextDocument` passed to the first argument.
* It will be resolved with an `Array` of [VS Code `Diagnostic`](https://github.com/Microsoft/vscode-languageserver-node/blob/release/types/3.14/types/src/main.ts#L508-L546) instances.
* It will be *rejected* (not resolved) when it takes invalid configs.
* In this case, it joins config errors into a single error object.
* It suppresses `No configuration found` error.
* Doing nothing when there is no configuration is a common behavior of editor plugins.
* [`files`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#files) and [`formatter`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#formatter) options are not supported.
- [`code`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#code) and [`codeFilename`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#codefilename) option values are derived from a `TextDocument` passed to the first argument.
- It will be resolved with an `Array` of [VS Code `Diagnostic`](https://github.com/Microsoft/vscode-languageserver-node/blob/release/types/3.14/types/src/main.ts#L508-L546) instances.
- It will be _rejected_ (not resolved) when it takes invalid configs.
- In this case, it joins config errors into a single error object.
- It suppresses `No configuration found` error.
- Doing nothing when there is no configuration is a common behavior of editor plugins.
- [`files`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#files) and [`formatter`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#formatter) options are not supported.

```javascript
const stylelintVSCode = require('stylelint-vscode');

(async () => {
async () => {
await stylelintVSCode(TextDocument.create('file:///Users/me/1.css', 'css', 1, '{foo}')); /*=> [{
range: {
start: {line: 0, character: 1},
Expand All @@ -89,7 +97,7 @@ const stylelintVSCode = require('stylelint-vscode');
code: 'CssSyntaxError',
source: 'stylelint'
}] */
});
};
```

```javascript
Expand All @@ -99,9 +107,9 @@ const stylelintVSCode = require('stylelint-vscode');
config: {
rules: {
indentation: 2,
'function-comma-space-before': 'foo'
}
}
'function-comma-space-before': 'foo',
},
},
});
} catch (err) {
err.name;
Expand All @@ -120,11 +128,3 @@ const stylelintVSCode = require('stylelint-vscode');
}
})();
```

## Related project

* [vscode-stylelint](https://github.com/shinnn/vscode-stylelint) — A VS Code extension powered by this module

## License

[ISC License](./LICENSE) © 2018 - 2019 Shinnosuke Watanabe
86 changes: 45 additions & 41 deletions lib/stylelint-vscode/index.js
@@ -1,12 +1,13 @@
'use strict';

const arrayToError = require('array-to-error');
const arrayToSentence = require('array-to-sentence');
const {at, has, intersection, isPlainObject, map, stubString} = require('lodash');
const {Files, TextDocument} = require('vscode-languageserver');
const inspectWithKind = require('inspect-with-kind');
const {lint} = require('stylelint');
const stylelintWarningToVscodeDiagnostic = require('stylelint-warning-to-vscode-diagnostic');
const { at, has, intersection, isPlainObject, map, stubString } = require('lodash');
const { Files, TextDocument } = require('vscode-languageserver');
const { lint } = require('stylelint');

const arrayToError = require('../array-to-error');
const arrayToSentence = require('../array-to-sentence');
const inspectWithKind = require('../inspect-with-kind');
const stylelintWarningToVscodeDiagnostic = require('../stylelint-warning-to-vscode-diagnostic');

// https://github.com/stylelint/stylelint/blob/10.0.1/lib/getPostcssResult.js#L69-L81
const SUPPORTED_SYNTAXES = new Set([
Expand All @@ -16,7 +17,7 @@ const SUPPORTED_SYNTAXES = new Set([
'markdown',
'sass',
'scss',
'sugarss'
'sugarss',
]);

const LANGUAGE_EXTENSION_EXCEPTION_PAIRS = new Map([
Expand All @@ -30,27 +31,22 @@ const LANGUAGE_EXTENSION_EXCEPTION_PAIRS = new Map([
['typescriptreact', 'css-in-js'],
['vue-html', 'html'],
['xml', 'html'],
['xsl', 'html']
['xsl', 'html'],
]);

const UNSUPPORTED_OPTIONS = [
'code',
'codeFilename',
'files',
'formatter'
];
const UNSUPPORTED_OPTIONS = ['code', 'codeFilename', 'files', 'formatter'];

function quote(str) {
return `\`${str}\``;
}

function processResults({results}) {
function processResults({ results }) {
// https://github.com/stylelint/stylelint/blob/10.0.1/lib/standalone.js#L114-L122
if (results.length === 0) {
return [];
}

const [{invalidOptionWarnings, warnings}] = results;
const [{ invalidOptionWarnings, warnings }] = results;

if (invalidOptionWarnings.length !== 0) {
throw arrayToError(map(invalidOptionWarnings, 'text'), SyntaxError);
Expand All @@ -63,40 +59,46 @@ module.exports = async function stylelintVSCode(...args) {
const argLen = args.length;

if (argLen !== 1 && argLen !== 2) {
throw new RangeError(`Expected 1 or 2 arguments (<TextDocument>[, <Object>]), but got ${
argLen === 0 ? 'no' : argLen
} arguments.`);
throw new RangeError(
`Expected 1 or 2 arguments (<TextDocument>[, <Object>]), but got ${
argLen === 0 ? 'no' : argLen
} arguments.`,
);
}

const [textDocument, options = {}] = args;

if (!TextDocument.is(textDocument)) {
throw new TypeError(`Expected a TextDocument https://code.visualstudio.com/docs/extensionAPI/vscode-api#TextDocument, but got ${
inspectWithKind(textDocument)
}.`);
throw new TypeError(
`Expected a TextDocument https://code.visualstudio.com/docs/extensionAPI/vscode-api#TextDocument, but got ${inspectWithKind(
textDocument,
)}.`,
);
}

if (argLen === 2) {
if (!isPlainObject(options)) {
throw new TypeError(`Expected an object containing stylelint API options, but got ${
inspectWithKind(options)
}.`);
throw new TypeError(
`Expected an object containing stylelint API options, but got ${inspectWithKind(options)}.`,
);
}

const providedUnsupportedOptions = intersection(Object.keys(options), UNSUPPORTED_OPTIONS);

if (providedUnsupportedOptions.length !== 0) {
throw new TypeError(`${
arrayToSentence(map(UNSUPPORTED_OPTIONS, quote))
} options are not supported because they will be derived from a document and there is no need to set them manually, but ${
arrayToSentence(map(providedUnsupportedOptions, quote))
} was provided.`);
throw new TypeError(
`${arrayToSentence(
map(UNSUPPORTED_OPTIONS, quote),
)} options are not supported because they will be derived from a document and there is no need to set them manually, but ${arrayToSentence(
map(providedUnsupportedOptions, quote),
)} was provided.`,
);
}
}

const priorOptions = {
code: textDocument.getText(),
formatter: stubString
formatter: stubString,
};
const codeFilename = Files.uriToFilePath(textDocument.uri);
let resultContainer;
Expand All @@ -117,25 +119,27 @@ module.exports = async function stylelintVSCode(...args) {
}

if (!at(options, 'config.rules')[0]) {
priorOptions.config = {rules: {}};
priorOptions.config = { rules: {} };
}
}

try {
resultContainer = await lint({...options, ...priorOptions});
resultContainer = await lint({ ...options, ...priorOptions });
} catch (err) {
if (
err.message.startsWith('No configuration provided for') ||
err.message.includes('No rules found within configuration')
) {
// Check only CSS syntax errors without applying any stylelint rules
return processResults(await lint({
...options,
...priorOptions,
config: {
rules: {}
}
}));
return processResults(
await lint({
...options,
...priorOptions,
config: {
rules: {},
},
}),
);
}

throw err;
Expand Down
57 changes: 0 additions & 57 deletions lib/stylelint-vscode/package.json

This file was deleted.

0 comments on commit 72fcb11

Please sign in to comment.