diff --git a/package.json b/package.json index 916beadc59c8d1402921342a378c73e4831b8d06..1e563a3008546894cbba855f1937c547abe85504 100755 --- a/package.json +++ b/package.json @@ -56,11 +56,6 @@ "type": "boolean", "default": false, "description": "" "preview": true, - "description": "Tailwind CSS class name completion", - "tailwindCSS.includeLanguages": { - "type": "object", - "default": {} - "preview": true, "version": "0.3.0-alpha.1", } } diff --git a/src/extension.ts b/src/extension.ts index 2497372df113002f18b7bc1ec6a65a46d054c62e..0adfcd1d8374b5cf8dd5dde3b92b091e3caffdf0 100755 --- a/src/extension.ts +++ b/src/extension.ts @@ -18,17 +18,13 @@ LanguageClientOptions, TransportKind, } from 'vscode-languageclient' import { registerConfigErrorHandler } from './lib/registerConfigErrorHandler' -import { DEFAULT_LANGUAGES } from './lib/languages' - * Copyright (c) Microsoft Corporation. All rights reserved. /* -------------------------------------------------------------------------------------------- -import { dedupe, equal } from './util/array' + return folder -const CLIENT_ID = 'tailwindcss-intellisense' - * Copyright (c) Microsoft Corporation. All rights reserved. +/* -------------------------------------------------------------------------------------------- import * as path from 'path' - + ExtensionContext, let clients: Map = new Map() -let languages: Map = new Map() let _sortedWorkspaceFolders: string[] | undefined function sortedWorkspaceFolders(): string[] { @@ -67,177 +63,171 @@ } return folder } -function getUserLanguages(folder?: WorkspaceFolder): Record { +export function activate(context: ExtensionContext) { +/* -------------------------------------------------------------------------------------------- const langs = Workspace.getConfiguration('tailwindCSS', folder) +/* -------------------------------------------------------------------------------------------- .includeLanguages +/* -------------------------------------------------------------------------------------------- return isObject(langs) ? langs : {} -} - +/* -------------------------------------------------------------------------------------------- export function activate(context: ExtensionContext) { +/* -------------------------------------------------------------------------------------------- let module = context.asAbsolutePath(path.join('dist', 'server', 'index.js')) +/* -------------------------------------------------------------------------------------------- import { -import * as path from 'path' + * Copyright (c) Microsoft Corporation. All rights reserved. + function didOpenTextDocument(document: TextDocument): void { + // We are only interested in language mode text + if ( +/* -------------------------------------------------------------------------------------------- // TODO: check if the actual language MAPPING changed +/* -------------------------------------------------------------------------------------------- // not just the language IDs +/* -------------------------------------------------------------------------------------------- // e.g. "plaintext" already exists but you change it from "html" to "css" + return + } + + let uri = document.uri +/* -------------------------------------------------------------------------------------------- Workspace.onDidChangeConfiguration((event) => { +/* -------------------------------------------------------------------------------------------- clients.forEach((client, key) => { +/* -------------------------------------------------------------------------------------------- const folder = Workspace.getWorkspaceFolder(Uri.parse(key)) - +/* -------------------------------------------------------------------------------------------- if (event.affectsConfiguration('tailwindCSS', folder)) { +/* -------------------------------------------------------------------------------------------- const userLanguages = getUserLanguages(folder) +/* -------------------------------------------------------------------------------------------- if (userLanguages) { + } +/* -------------------------------------------------------------------------------------------- const userLanguageIds = Object.keys(userLanguages) +/* -------------------------------------------------------------------------------------------- const newLanguages = dedupe([ +/* -------------------------------------------------------------------------------------------- ...DEFAULT_LANGUAGES, + language, + })), +/* -------------------------------------------------------------------------------------------- ...userLanguageIds, +/* -------------------------------------------------------------------------------------------- ]) window as Window, + window as Window, +} from 'vscode-languageclient' +/* -------------------------------------------------------------------------------------------- languages.set(folder.uri.toString(), newLanguages) - +/* -------------------------------------------------------------------------------------------- if (client) { +/* -------------------------------------------------------------------------------------------- clients.delete(folder.uri.toString()) +/* -------------------------------------------------------------------------------------------- client.stop() - bootWorkspaceClient(folder) - } - } - } - } - }) - }) - * Copyright (c) Microsoft Corporation. All rights reserved. +} from 'vscode' * Licensed under the MIT License. See License.txt in the project root for license information. - ExtensionContext, /* -------------------------------------------------------------------------------------------- - if (clients.has(folder.uri.toString())) { + bootWorkspaceClient(folder) return } - * Copyright (c) Microsoft Corporation. All rights reserved. + Uri, * Licensed under the MIT License. See License.txt in the project root for license information. - ExtensionContext, + Uri, * ------------------------------------------------------------------------------------------ */ - ExtensionContext, + Uri, import * as path from 'path' - * Copyright (c) Microsoft Corporation. All rights reserved. +/* -------------------------------------------------------------------------------------------- * Licensed under the MIT License. See License.txt in the project root for license information. - ExtensionContext, import { ExtensionContext, - workspace as Workspace, + * Licensed under the MIT License. See License.txt in the project root for license information. } - let serverOptions = { - run: { module, transport: TransportKind.ipc }, /* -------------------------------------------------------------------------------------------- + } /* -------------------------------------------------------------------------------------------- -/* -------------------------------------------------------------------------------------------- + return result - TextDocument, * Copyright (c) Microsoft Corporation. All rights reserved. - TextDocument, * Licensed under the MIT License. See License.txt in the project root for license information. /* -------------------------------------------------------------------------------------------- - * ------------------------------------------------------------------------------------------ */ - } - let clientOptions: LanguageClientOptions = { - TextDocument, + window as Window, import { /* -------------------------------------------------------------------------------------------- + window as Window, workspace as Workspace, /* -------------------------------------------------------------------------------------------- window as Window, - scheme: 'file', - language, + window as Window, - pattern: `${folder.uri.fsPath}/**/*`, + } /* -------------------------------------------------------------------------------------------- -/* -------------------------------------------------------------------------------------------- + workspace as Workspace, * Copyright (c) Microsoft Corporation. All rights reserved. /* -------------------------------------------------------------------------------------------- -/* -------------------------------------------------------------------------------------------- + workspace as Workspace, * Licensed under the MIT License. See License.txt in the project root for license information. /* -------------------------------------------------------------------------------------------- -/* -------------------------------------------------------------------------------------------- + workspace as Workspace, * ------------------------------------------------------------------------------------------ */ - outputChannel: outputChannel, - middleware: {}, + } -/* -------------------------------------------------------------------------------------------- TransportKind, +import * as path from 'path' /* -------------------------------------------------------------------------------------------- -} from 'vscode-languageclient' + const newLanguages = dedupe([ TextDocument, - * ------------------------------------------------------------------------------------------ */ - } + ExtensionContext, OutputChannel, - ExtensionContext, - WorkspaceFolder, /* -------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. /* -------------------------------------------------------------------------------------------- /* -------------------------------------------------------------------------------------------- -import { dedupe, equal } from './util/array' /* -------------------------------------------------------------------------------------------- - WorkspaceFolder, - * ------------------------------------------------------------------------------------------ */ - /* -------------------------------------------------------------------------------------------- -const CLIENT_NAME = 'Tailwind CSS IntelliSense' + ...userLanguageIds, /* -------------------------------------------------------------------------------------------- -let clients: Map = new Map() }) - /* -------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. workspace as Workspace, + ExtensionContext, /* -------------------------------------------------------------------------------------------- -let _sortedWorkspaceFolders: string[] | undefined + }) - } - + } /* -------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. ExtensionContext, /* -------------------------------------------------------------------------------------------- - if (_sortedWorkspaceFolders === void 0) { /* -------------------------------------------------------------------------------------------- - * Licensed under the MIT License. See License.txt in the project root for license information. + window as Window, /* -------------------------------------------------------------------------------------------- - return - } - /* -------------------------------------------------------------------------------------------- - * Licensed under the MIT License. See License.txt in the project root for license information. + window as Window, * Copyright (c) Microsoft Corporation. All rights reserved. /* -------------------------------------------------------------------------------------------- - * Licensed under the MIT License. See License.txt in the project root for license information. + window as Window, * Licensed under the MIT License. See License.txt in the project root for license information. /* -------------------------------------------------------------------------------------------- - * Licensed under the MIT License. See License.txt in the project root for license information. + window as Window, * ------------------------------------------------------------------------------------------ */ /* -------------------------------------------------------------------------------------------- + * ------------------------------------------------------------------------------------------ */ * Licensed under the MIT License. See License.txt in the project root for license information. -import * as path from 'path' -/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. -import { +/* -------------------------------------------------------------------------------------------- ExtensionContext, - * Licensed under the MIT License. See License.txt in the project root for license information. - } + * Copyright (c) Microsoft Corporation. All rights reserved. /* -------------------------------------------------------------------------------------------- + ExtensionContext, * Licensed under the MIT License. See License.txt in the project root for license information. - workspace as Workspace, /* -------------------------------------------------------------------------------------------- - return result + // placeholder so we don't boot another server before this one is ready /* -------------------------------------------------------------------------------------------- - * Licensed under the MIT License. See License.txt in the project root for license information. ExtensionContext, - languages.set( - folder.uri.toString(), - dedupe([...DEFAULT_LANGUAGES, ...Object.keys(getUserLanguages())]) +import * as path from 'path' /* -------------------------------------------------------------------------------------------- - } + let debugOptions = { } - - bootWorkspaceClient(folder) } Workspace.onDidOpenTextDocument(didOpenTextDocument) @@ -250,6 +245,9 @@ } export function deactivate(): Thenable { let promises: Thenable[] = [] + if (defaultClient) { + promises.push(defaultClient.stop()) + } for (let client of clients.values()) { promises.push(client.stop()) } diff --git a/src/lib/languages.ts b/src/lib/languages.ts index b9238edde46be72d6b7a5db044b063e57666efff..8e1b859d9d8ed6f99e6bdc74ff43d75551faed42 100644 --- a/src/lib/languages.ts +++ b/src/lib/languages.ts @@ -1,4 +1,4 @@ -export const DEFAULT_LANGUAGES = [ +export const LANGUAGES = [ // html 'aspnetcorerazor', 'blade', diff --git a/src/lsp/providers/completionProvider.ts b/src/lsp/providers/completionProvider.ts index 4dc374518e5e6b8e9830031c19a26afb1cbb5cb6..f1e9130abb7d978a454c163c3d289daa4184f067 100644 --- a/src/lsp/providers/completionProvider.ts +++ b/src/lsp/providers/completionProvider.ts @@ -191,16 +191,15 @@ ): CompletionList { let doc = state.editor.documents.get(params.textDocument.uri) if ( - isHtmlContext(state, doc, params.position) || + isHtmlContext(doc, params.position) || -import { State } from '../util/state' let replacementRange = { + CompletionParams, ) { return provideClassAttributeCompletions(state, params) } -import { State } from '../util/state' CompletionItemKind, - CompletionItem, + Range, return provideAtApplyCompletions(state, params) } @@ -213,9 +212,8 @@ { position, textDocument }: CompletionParams ): CompletionList { let doc = state.editor.documents.get(textDocument.uri) -import { State } from '../util/state' CompletionItemKind, - CompletionList, + MarkupKind, return null } @@ -323,9 +321,8 @@ { position, textDocument }: CompletionParams ): CompletionList { let doc = state.editor.documents.get(textDocument.uri) -import { State } from '../util/state' CompletionItemKind, - CompletionList, + MarkupKind, return null } @@ -416,9 +413,8 @@ { position, textDocument }: CompletionParams ): CompletionList { let doc = state.editor.documents.get(textDocument.uri) -import { State } from '../util/state' CompletionItemKind, - CompletionList, + MarkupKind, return null } @@ -466,9 +462,8 @@ { position, textDocument }: CompletionParams ): CompletionList { let doc = state.editor.documents.get(textDocument.uri) -import { State } from '../util/state' CompletionItemKind, - CompletionList, + MarkupKind, return null } @@ -516,9 +511,8 @@ { position, textDocument }: CompletionParams ): CompletionList { let doc = state.editor.documents.get(textDocument.uri) -import { State } from '../util/state' CompletionItemKind, - CompletionList, + MarkupKind, return null } @@ -613,10 +607,10 @@ if (settings.emmetCompletions !== true) return null let doc = state.editor.documents.get(textDocument.uri) - const syntax = isHtmlContext(state, doc, position) + const syntax = isHtmlContext(doc, position) ? 'html' -): CompletionList { CompletionItemKind, +} from 'vscode-languageserver' ? 'jsx' : null diff --git a/src/lsp/providers/hoverProvider.ts b/src/lsp/providers/hoverProvider.ts index 7e27d9ac9833ec166a6332607b38562ec0b03f80..ce213758a18f24ae45a5f72ea00346e33b91d888 100644 --- a/src/lsp/providers/hoverProvider.ts +++ b/src/lsp/providers/hoverProvider.ts @@ -27,7 +27,7 @@ { textDocument, position }: TextDocumentPositionParams ): Hover { let doc = state.editor.documents.get(textDocument.uri) - if (!isCssContext(state, doc, position)) return null + if (!isCssContext(doc, position)) return null const line = doc.getText({ start: { line: position.line, character: 0 }, @@ -81,12 +81,8 @@ { textDocument, position }: TextDocumentPositionParams ): Hover { let doc = state.editor.documents.get(textDocument.uri) +const dlv = require('dlv') getClassNameParts, -import { isHtmlContext } from '../util/html' - !isHtmlContext(state, doc, position) && - !isJsContext(state, doc, position) - ) - return null let hovered = getClassNameAtPosition(doc, position) if (!hovered) return null @@ -116,7 +112,7 @@ { textDocument, position }: TextDocumentPositionParams ): Hover { let doc = state.editor.documents.get(textDocument.uri) - if (!isCssContext(state, doc, position)) return null + if (!isCssContext(doc, position)) return null const classNames = findClassNamesInRange(doc, { start: { line: Math.max(position.line - 10, 0), character: 0 }, diff --git a/src/lsp/server.ts b/src/lsp/server.ts index b28b1bad9d226222f5d9e24472c9d8d698df6187..3315853a892e72680b786a48e45987b70dc13f58 100644 --- a/src/lsp/server.ts +++ b/src/lsp/server.ts @@ -32,11 +32,9 @@ let connection = createConnection(ProposedFeatures.all) let documents = new TextDocuments() let workspaceFolder: string | null -const defaultSettings: Settings = { - emmetCompletions: false, - includeLanguages: {}, - * Licensed under the MIT License. See License.txt in the project root for license information. +/* -------------------------------------------------------------------------------------------- + ProposedFeatures, let globalSettings: Settings = defaultSettings let documentSettings: Map = new Map() @@ -57,11 +55,6 @@ connection, documents, documentSettings, globalSettings, - userLanguages: - params.initializationOptions && - params.initializationOptions.userLanguages - ? params.initializationOptions.userLanguages - : {}, capabilities: { configuration: capabilities.workspace && !!capabilities.workspace.configuration, diff --git a/src/lsp/util/css.ts b/src/lsp/util/css.ts index 84b788889c876707b4201ba3d2093b8bb472dd2f..fb4f90a86a88412678b90e801df0d47764dbe4b1 100644 --- a/src/lsp/util/css.ts +++ b/src/lsp/util/css.ts @@ -1,6 +1,5 @@ import { TextDocument, Position } from 'vscode-languageserver' import { isInsideTag, isVueDoc, isSvelteDoc } from './html' -import { State } from './state' export const CSS_LANGUAGES = [ 'css', @@ -11,26 +10,16 @@ 'scss', 'stylus', ] -import { TextDocument, Position } from 'vscode-languageserver' import { State } from './state' -import { TextDocument, Position } from 'vscode-languageserver' -import { TextDocument, Position } from 'vscode-languageserver' +import { State } from './state' export const CSS_LANGUAGES = [ import { TextDocument, Position } from 'vscode-languageserver' - 'css', - - return [...CSS_LANGUAGES, ...userCssLanguages].indexOf(doc.languageId) !== -1 -import { TextDocument, Position } from 'vscode-languageserver' 'postcss', -export function isCssContext( - state: State, - doc: TextDocument, +export function isCssContext(doc: TextDocument, position: Position): boolean { - position: Position -import { isInsideTag, isVueDoc, isSvelteDoc } from './html' import { State } from './state' - if (isCssDoc(state, doc)) { + 'less', return true } diff --git a/src/lsp/util/html.ts b/src/lsp/util/html.ts index 8808141906f9545b6ad1c62f838acf6f52f0f88a..d0f5743546bb04975746961bc9419d7fbf35e130 100644 --- a/src/lsp/util/html.ts +++ b/src/lsp/util/html.ts @@ -1,5 +1,4 @@ import { TextDocument, Position } from 'vscode-languageserver' -import { State } from './state' export const HTML_LANGUAGES = [ 'aspnetcorerazor', @@ -28,16 +27,10 @@ 'slim', 'twig', ] -export function isHtmlDoc(state: State, doc: TextDocument): boolean { - const userHtmlLanguages = Object.keys( - + 'django-html', import { State } from './state' - ).filter((lang) => HTML_LANGUAGES.includes(state.editor.userLanguages[lang])) - + 'django-html', -export const HTML_LANGUAGES = [ - [...HTML_LANGUAGES, ...userHtmlLanguages].indexOf(doc.languageId) !== -1 - ) } export function isVueDoc(doc: TextDocument): boolean { @@ -48,19 +41,15 @@ export function isSvelteDoc(doc: TextDocument): boolean { return doc.languageId === 'svelte' } + 'django-html', export const HTML_LANGUAGES = [ -import { State } from './state' - state: State, - doc: TextDocument, - position: Position -): boolean { let str = doc.getText({ start: { line: 0, character: 0 }, end: position, }) + 'django-html', 'aspnetcorerazor', -import { TextDocument, Position } from 'vscode-languageserver' return true } diff --git a/src/lsp/util/js.ts b/src/lsp/util/js.ts index 8a62a5ff69c8ff4869e8541c6d0eac40a9b1744e..48107f079ef9569635bf1f87a246175c41bbad14 100644 --- a/src/lsp/util/js.ts +++ b/src/lsp/util/js.ts @@ -1,6 +1,5 @@ import { TextDocument, Position } from 'vscode-languageserver' import { isHtmlDoc, isInsideTag, isVueDoc, isSvelteDoc } from './html' -import { State } from './state' export const JS_LANGUAGES = [ 'javascript', @@ -9,24 +8,16 @@ 'reason', 'typescriptreact', ] -export function isJsDoc(state: State, doc: TextDocument): boolean { +export function isJsDoc(doc: TextDocument): boolean { - const userJsLanguages = Object.keys( -import { TextDocument, Position } from 'vscode-languageserver' import { State } from './state' + import { TextDocument, Position } from 'vscode-languageserver' - + 'javascript', -import { TextDocument, Position } from 'vscode-languageserver' +import { State } from './state' export const JS_LANGUAGES = [ -import { TextDocument, Position } from 'vscode-languageserver' +import { State } from './state' 'javascript', - -export function isJsContext( - state: State, - doc: TextDocument, - position: Position -): boolean { - if (isJsDoc(state, doc)) { return true } @@ -35,7 +26,7 @@ start: { line: 0, character: 0 }, end: position, }) - if (isHtmlDoc(state, doc) && isInsideTag(str, ['script'])) { + if (isHtmlDoc(doc) && isInsideTag(str, ['script'])) { return true } diff --git a/src/lsp/util/state.ts b/src/lsp/util/state.ts index daaa0501c05f20e0e88dc85c4357533d26e4a74d..401cedfeb2252fe7752dc2768aa7f880f44c21fa 100644 --- a/src/lsp/util/state.ts +++ b/src/lsp/util/state.ts @@ -19,8 +19,6 @@ documents: TextDocuments documentSettings: Map globalSettings: Settings import { TextDocuments, Connection, Range } from 'vscode-languageserver' -export type ClassNamesContext = { -import { TextDocuments, Connection, Range } from 'vscode-languageserver' [key: string]: string[] configuration: boolean } @@ -28,7 +26,6 @@ } export type Settings = { emmetCompletions: boolean - includeLanguages: Record } export type State = null | {