css.experimental.customData
This commit is contained in:
parent
439e20c7b6
commit
f7894236ee
5 changed files with 80 additions and 7 deletions
2
extensions/css-language-features/.vscode/settings.json
vendored
Normal file
2
extensions/css-language-features/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
|
@ -9,7 +9,7 @@ import * as fs from 'fs';
|
|||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { languages, window, commands, ExtensionContext, Range, Position, CompletionItem, CompletionItemKind, TextEdit, SnippetString } from 'vscode';
|
||||
import { languages, window, commands, ExtensionContext, Range, Position, CompletionItem, CompletionItemKind, TextEdit, SnippetString, workspace } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, Disposable } from 'vscode-languageclient';
|
||||
|
||||
// this method is called when vs code is activated
|
||||
|
@ -30,6 +30,22 @@ export function activate(context: ExtensionContext) {
|
|||
|
||||
let documentSelector = ['css', 'scss', 'less'];
|
||||
|
||||
let dataPaths: string[] = workspace.getConfiguration('css').get('experimental.customData', []);
|
||||
if (dataPaths && dataPaths.length > 0) {
|
||||
if (!workspace.workspaceFolders) {
|
||||
dataPaths = [];
|
||||
} else {
|
||||
try {
|
||||
const workspaceRoot = workspace.workspaceFolders[0].uri.fsPath;
|
||||
dataPaths = dataPaths.map(d => {
|
||||
return path.resolve(workspaceRoot, d);
|
||||
});
|
||||
} catch (err) {
|
||||
dataPaths = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Options to control the language client
|
||||
let clientOptions: LanguageClientOptions = {
|
||||
documentSelector,
|
||||
|
@ -37,6 +53,7 @@ export function activate(context: ExtensionContext) {
|
|||
configurationSection: ['css', 'scss', 'less']
|
||||
},
|
||||
initializationOptions: {
|
||||
dataPaths
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
"id": "css",
|
||||
"title": "%css.title%",
|
||||
"properties": {
|
||||
"css.experimental.customData": {
|
||||
"type": "array",
|
||||
"description": "A list of JSON file paths that define custom CSS data that loads extra properties, at directives, pseudo classes / elements."
|
||||
},
|
||||
"css.validate": {
|
||||
"type": "boolean",
|
||||
"scope": "resource",
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, ServerCapabilities, ConfigurationRequest, WorkspaceFolder
|
||||
} from 'vscode-languageserver';
|
||||
import URI from 'vscode-uri';
|
||||
import * as fs from 'fs';
|
||||
import { TextDocument, CompletionList } from 'vscode-languageserver-types';
|
||||
|
||||
import { getCSSLanguageService, getSCSSLanguageService, getLESSLanguageService, LanguageSettings, LanguageService, Stylesheet } from 'vscode-css-languageservice';
|
||||
|
@ -14,6 +15,7 @@ import { getLanguageModelCache } from './languageModelCache';
|
|||
import { getPathCompletionParticipant } from './pathCompletion';
|
||||
import { formatError, runSafe } from './utils/runner';
|
||||
import { getDocumentContext } from './utils/documentContext';
|
||||
import { parseCSSData } from './languageFacts';
|
||||
|
||||
export interface Settings {
|
||||
css: LanguageSettings;
|
||||
|
@ -50,6 +52,8 @@ let scopedSettingsSupport = false;
|
|||
let foldingRangeLimit = Number.MAX_VALUE;
|
||||
let workspaceFolders: WorkspaceFolder[];
|
||||
|
||||
const languageServices: { [id: string]: LanguageService } = {};
|
||||
|
||||
// After the server has started the client sends an initialize request. The server receives
|
||||
// in the passed params the rootPath of the workspace plus the client capabilities.
|
||||
connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
|
@ -61,6 +65,33 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
|||
}
|
||||
}
|
||||
|
||||
const dataPaths: string[] = params.initializationOptions.dataPaths;
|
||||
|
||||
let customData = {
|
||||
customProperties: [],
|
||||
customAtDirectives: [],
|
||||
customPseudoElements: [],
|
||||
customPseudoClasses: []
|
||||
};
|
||||
|
||||
dataPaths.forEach(p => {
|
||||
if (fs.existsSync(p)) {
|
||||
const {
|
||||
properties,
|
||||
atDirectives,
|
||||
pseudoClasses,
|
||||
pseudoElements
|
||||
} = parseCSSData(fs.readFileSync(p, 'utf-8'));
|
||||
|
||||
customData.customProperties = customData.customProperties.concat(properties);
|
||||
customData.customAtDirectives = customData.customAtDirectives.concat(atDirectives);
|
||||
customData.customPseudoClasses = customData.customPseudoClasses.concat(pseudoClasses);
|
||||
customData.customPseudoElements = customData.customPseudoElements.concat(pseudoElements);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
function getClientCapability<T>(name: string, def: T) {
|
||||
const keys = name.split('.');
|
||||
let c: any = params.capabilities;
|
||||
|
@ -76,6 +107,10 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
|||
scopedSettingsSupport = !!getClientCapability('workspace.configuration', false);
|
||||
foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
|
||||
|
||||
languageServices.css = getCSSLanguageService(customData);
|
||||
languageServices.scss = getSCSSLanguageService(customData);
|
||||
languageServices.less = getLESSLanguageService(customData);
|
||||
|
||||
const capabilities: ServerCapabilities = {
|
||||
// Tell the client that the server works in FULL text document sync mode
|
||||
textDocumentSync: documents.syncKind,
|
||||
|
@ -96,12 +131,6 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
|||
return { capabilities };
|
||||
});
|
||||
|
||||
const languageServices: { [id: string]: LanguageService } = {
|
||||
css: getCSSLanguageService(),
|
||||
scss: getSCSSLanguageService(),
|
||||
less: getLESSLanguageService()
|
||||
};
|
||||
|
||||
function getLanguageService(document: TextDocument) {
|
||||
let service = languageServices[document.languageId];
|
||||
if (!service) {
|
||||
|
|
21
extensions/css-language-features/server/src/languageFacts.ts
Normal file
21
extensions/css-language-features/server/src/languageFacts.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export function parseCSSData(source: string) {
|
||||
let rawData: any;
|
||||
|
||||
try {
|
||||
rawData = JSON.parse(source);
|
||||
} catch (err) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
properties: rawData.properties || [],
|
||||
atDirectives: rawData.atdirectives || [],
|
||||
pseudoClasses: rawData.pseudoclasses || [],
|
||||
pseudoElements: rawData.pseudoelements || []
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue