From c314388da21720d893e7a36345e1cac36d1cfd5f Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Sun, 22 Apr 2018 12:29:13 -0700 Subject: [PATCH] Move emmet from html extenstion to emmet extension --- .../client/src/cssMain.ts | 2 +- .../emmet/src/defaultCompletionProvider.ts | 6 +- extensions/emmet/src/extension.ts | 3 +- extensions/emmet/src/util.ts | 1 + .../client/src/htmlMain.ts | 2 +- .../server/package.json | 1 - .../server/src/htmlServerMain.ts | 52 ++------------ .../server/src/modes/cssMode.ts | 22 +----- .../server/src/modes/htmlMode.ts | 7 +- .../server/src/modes/languageModes.ts | 3 +- .../server/src/test/emmet.test.ts | 72 ------------------- .../html-language-features/server/yarn.lock | 20 ------ 12 files changed, 17 insertions(+), 174 deletions(-) delete mode 100644 extensions/html-language-features/server/src/test/emmet.test.ts diff --git a/extensions/css-language-features/client/src/cssMain.ts b/extensions/css-language-features/client/src/cssMain.ts index c03c44b6cd6f6..a3474705b1675 100644 --- a/extensions/css-language-features/client/src/cssMain.ts +++ b/extensions/css-language-features/client/src/cssMain.ts @@ -33,7 +33,7 @@ export function activate(context: ExtensionContext) { let clientOptions: LanguageClientOptions = { documentSelector, synchronize: { - configurationSection: ['css', 'scss', 'less', 'emmet'] + configurationSection: ['css', 'scss', 'less'] }, initializationOptions: { } diff --git a/extensions/emmet/src/defaultCompletionProvider.ts b/extensions/emmet/src/defaultCompletionProvider.ts index 9e06041548dbf..fc7ac6d796ad4 100644 --- a/extensions/emmet/src/defaultCompletionProvider.ts +++ b/extensions/emmet/src/defaultCompletionProvider.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { Stylesheet } from 'EmmetNode'; +import { Node, Stylesheet } from 'EmmetNode'; import { isValidLocationForEmmetAbbreviation } from './abbreviationActions'; import { getEmmetHelper, getMappingForIncludedLanguages, parsePartialStylesheet, getEmmetConfiguration, getEmmetMode, isStyleSheet, parseDocument, } from './util'; @@ -34,7 +34,7 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi } let validateLocation = false; - let rootNode: Stylesheet | undefined = undefined; + let rootNode: Node | undefined = undefined; if (context.triggerKind !== vscode.CompletionTriggerKind.TriggerForIncompleteCompletions) { validateLocation = syntax === 'html' || syntax === 'jsx' || syntax === 'xml' || isStyleSheet(document.languageId); @@ -45,6 +45,8 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi if (!rootNode) { return; } + } else if (document.languageId === 'html') { + rootNode = parseDocument(document, false); } } diff --git a/extensions/emmet/src/extension.ts b/extensions/emmet/src/extension.ts index 3e0b46d979f3b..3079a1764fefb 100644 --- a/extensions/emmet/src/extension.ts +++ b/extensions/emmet/src/extension.ts @@ -142,7 +142,6 @@ export function activate(context: vscode.ExtensionContext) { */ const languageMappingForCompletionProviders: Map = new Map(); const completionProvidersMapping: Map = new Map(); -const languagesToSkipCompletionProviders = ['html']; function registerCompletionProviders(context: vscode.ExtensionContext) { let completionProvider = new DefaultCompletionItemProvider(); @@ -170,7 +169,7 @@ function registerCompletionProviders(context: vscode.ExtensionContext) { }); Object.keys(LANGUAGE_MODES).forEach(language => { - if (languagesToSkipCompletionProviders.indexOf(language) === -1 && !languageMappingForCompletionProviders.has(language)) { + if (!languageMappingForCompletionProviders.has(language)) { const provider = vscode.languages.registerCompletionItemProvider(language, completionProvider, ...LANGUAGE_MODES[language]); context.subscriptions.push(provider); diff --git a/extensions/emmet/src/util.ts b/extensions/emmet/src/util.ts index 3d0d8e2ac5d78..37820db427fe2 100644 --- a/extensions/emmet/src/util.ts +++ b/extensions/emmet/src/util.ts @@ -54,6 +54,7 @@ const emmetModes = ['html', 'pug', 'slim', 'haml', 'xml', 'xsl', 'jsx', 'css', ' // For other languages, users will have to use `emmet.includeLanguages` or // language specific extensions can provide emmet completion support export const MAPPED_MODES: Object = { + 'handlebars': 'html', 'php': 'html' }; diff --git a/extensions/html-language-features/client/src/htmlMain.ts b/extensions/html-language-features/client/src/htmlMain.ts index 6e25547a896cb..9d32be2861f8e 100644 --- a/extensions/html-language-features/client/src/htmlMain.ts +++ b/extensions/html-language-features/client/src/htmlMain.ts @@ -54,7 +54,7 @@ export function activate(context: ExtensionContext) { let clientOptions: LanguageClientOptions = { documentSelector, synchronize: { - configurationSection: ['html', 'css', 'javascript', 'emmet'], // the settings to synchronize + configurationSection: ['html', 'css', 'javascript'], // the settings to synchronize }, initializationOptions: { embeddedLanguages diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json index e2e1821512fef..70d664466d1ac 100644 --- a/extensions/html-language-features/server/package.json +++ b/extensions/html-language-features/server/package.json @@ -9,7 +9,6 @@ }, "dependencies": { "vscode-css-languageservice": "^3.0.9-next.10", - "vscode-emmet-helper": "1.2.6", "vscode-html-languageservice": "^2.1.3-next.3", "vscode-languageserver": "^4.0.0", "vscode-languageserver-protocol-foldingprovider": "^2.0.0-next.2", diff --git a/extensions/html-language-features/server/src/htmlServerMain.ts b/extensions/html-language-features/server/src/htmlServerMain.ts index c054ca83845ce..7e9253c83e60e 100644 --- a/extensions/html-language-features/server/src/htmlServerMain.ts +++ b/extensions/html-language-features/server/src/htmlServerMain.ts @@ -7,10 +7,10 @@ import { createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, RequestType, DocumentRangeFormattingRequest, Disposable, DocumentSelector, TextDocumentPositionParams, ServerCapabilities, - Position, CompletionTriggerKind, ConfigurationRequest, ConfigurationParams, DidChangeWorkspaceFoldersNotification, + Position, ConfigurationRequest, ConfigurationParams, DidChangeWorkspaceFoldersNotification, WorkspaceFolder, DocumentColorRequest, ColorInformation, ColorPresentationRequest } from 'vscode-languageserver'; -import { TextDocument, Diagnostic, DocumentLink, SymbolInformation, CompletionList } from 'vscode-languageserver-types'; +import { TextDocument, Diagnostic, DocumentLink, SymbolInformation } from 'vscode-languageserver-types'; import { getLanguageModes, LanguageModes, Settings } from './modes/languageModes'; import { format } from './modes/formatting'; @@ -18,7 +18,6 @@ import { pushAll } from './utils/arrays'; import { getDocumentContext } from './utils/documentContext'; import uri from 'vscode-uri'; import { formatError, runSafe, runSafeAsync } from './utils/runner'; -import { doComplete as emmetDoComplete, updateExtensionsPath as updateEmmetExtensionsPath, getEmmetCompletionParticipants } from 'vscode-emmet-helper'; import { FoldingRangeRequest, FoldingRangeServerCapabilities } from 'vscode-languageserver-protocol-foldingprovider'; import { getFoldingRanges } from './modes/htmlFolding'; @@ -78,10 +77,6 @@ function getDocumentSettings(textDocument: TextDocument, needsDocumentSettings: return Promise.resolve(void 0); } -let emmetSettings: any = {}; -let currentEmmetExtensionsPath: string; -const emmetTriggerCharacters = ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; - // 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 => { @@ -127,7 +122,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => { let capabilities: ServerCapabilities & FoldingRangeServerCapabilities = { // Tell the client that the server works in FULL text document sync mode textDocumentSync: documents.syncKind, - completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: [...emmetTriggerCharacters, '.', ':', '<', '"', '=', '/'] } : undefined, + completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: ['.', ':', '<', '"', '=', '/'] } : undefined, hoverProvider: true, documentHighlightProvider: true, documentRangeFormattingProvider: false, @@ -184,13 +179,6 @@ connection.onDidChangeConfiguration((change) => { formatterRegistration = null; } } - - emmetSettings = globalSettings.emmet || {}; - if (currentEmmetExtensionsPath !== emmetSettings['extensionsPath']) { - currentEmmetExtensionsPath = emmetSettings['extensionsPath']; - const workspaceUri = (workspaceFolders && workspaceFolders.length === 1) ? uri.parse(workspaceFolders[0].uri) : null; - updateEmmetExtensionsPath(currentEmmetExtensionsPath, workspaceUri ? workspaceUri.fsPath : undefined); - } }); const pendingValidationRequests: { [uri: string]: NodeJS.Timer } = {}; @@ -254,8 +242,6 @@ async function validateTextDocument(textDocument: TextDocument) { } } -let cachedCompletionList: CompletionList | null; -const hexColorRegex = /^#[\d,a-f,A-F]{1,6}$/; connection.onCompletion(async (textDocumentPosition, token) => { return runSafeAsync(async () => { const document = documents.get(textDocumentPosition.textDocument.uri); @@ -265,22 +251,6 @@ connection.onCompletion(async (textDocumentPosition, token) => { } const doComplete = mode.doComplete!; - if (cachedCompletionList - && !cachedCompletionList.isIncomplete - && (mode.getId() === 'html' || mode.getId() === 'css') - && textDocumentPosition.context - && textDocumentPosition.context.triggerKind === CompletionTriggerKind.TriggerForIncompleteCompletions - ) { - let result: CompletionList = emmetDoComplete(document, textDocumentPosition.position, mode.getId(), emmetSettings); - if (result && result.items) { - result.items.push(...cachedCompletionList.items); - } else { - result = cachedCompletionList; - cachedCompletionList = null; - } - return result; - } - if (mode.getId() !== 'html') { /* __GDPR__ "html.embbedded.complete" : { @@ -290,22 +260,8 @@ connection.onCompletion(async (textDocumentPosition, token) => { connection.telemetry.logEvent({ key: 'html.embbedded.complete', value: { languageId: mode.getId() } }); } - cachedCompletionList = null; - const emmetCompletionList = CompletionList.create([], false); - - const emmetCompletionParticipant = getEmmetCompletionParticipants(document, textDocumentPosition.position, mode.getId(), emmetSettings, emmetCompletionList); - const completionParticipants = [emmetCompletionParticipant]; - let settings = await getDocumentSettings(document, () => doComplete.length > 2); - let result = doComplete(document, textDocumentPosition.position, settings, completionParticipants); - if (emmetCompletionList.isIncomplete) { - emmetCompletionList.items = emmetCompletionList.items || []; - cachedCompletionList = result; - if (emmetCompletionList.items.length && hexColorRegex.test(emmetCompletionList.items[0].label) && result.items.some(x => x.label === emmetCompletionList.items[0].label)) { - emmetCompletionList.items.shift(); - } - return CompletionList.create([...emmetCompletionList.items, ...result.items], emmetCompletionList.isIncomplete || result.isIncomplete); - } + let result = doComplete(document, textDocumentPosition.position, settings); return result; }, null, `Error while computing completions for ${textDocumentPosition.textDocument.uri}`, token); diff --git a/extensions/html-language-features/server/src/modes/cssMode.ts b/extensions/html-language-features/server/src/modes/cssMode.ts index 1b40285ef0db3..2e8866428625f 100644 --- a/extensions/html-language-features/server/src/modes/cssMode.ts +++ b/extensions/html-language-features/server/src/modes/cssMode.ts @@ -6,11 +6,10 @@ import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache'; import { TextDocument, Position, Range, CompletionList } from 'vscode-languageserver-types'; -import { getCSSLanguageService, Stylesheet, ICompletionParticipant, FoldingRange } from 'vscode-css-languageservice'; +import { getCSSLanguageService, Stylesheet, FoldingRange } from 'vscode-css-languageservice'; import { LanguageMode, Workspace } from './languageModes'; import { HTMLDocumentRegions, CSS_STYLE_RULE } from './embeddedSupport'; import { Color } from 'vscode-languageserver'; -import { extractAbbreviation } from 'vscode-emmet-helper'; export function getCSSMode(documentRegions: LanguageModelCache, workspace: Workspace): LanguageMode { let cssLanguageService = getCSSLanguageService(); @@ -25,26 +24,9 @@ export function getCSSMode(documentRegions: LanguageModelCacheregisteredCompletionParticipants[i]).getId === 'function' && (registeredCompletionParticipants[i]).getId() === 'emmet') { - const extractedResults = extractAbbreviation(document, position, { lookAhead: false, syntax: 'css' }); - if (extractedResults && extractedResults.abbreviation) { - registeredCompletionParticipants[i].onCssProperty!({ propertyName: extractedResults.abbreviation, range: extractedResults.abbreviationRange }); - } - } else { - nonEmmetCompletionParticipants.push(registeredCompletionParticipants[i]); - } - } - } - cssLanguageService.setCompletionParticipants(nonEmmetCompletionParticipants); return cssLanguageService.doComplete(embedded, position, stylesheet) || CompletionList.create(); }, doHover(document: TextDocument, position: Position) { diff --git a/extensions/html-language-features/server/src/modes/htmlMode.ts b/extensions/html-language-features/server/src/modes/htmlMode.ts index d906ecde4ca83..cd3edbaed4bf5 100644 --- a/extensions/html-language-features/server/src/modes/htmlMode.ts +++ b/extensions/html-language-features/server/src/modes/htmlMode.ts @@ -5,7 +5,7 @@ 'use strict'; import { getLanguageModelCache } from '../languageModelCache'; -import { LanguageService as HTMLLanguageService, HTMLDocument, DocumentContext, FormattingOptions, HTMLFormatConfiguration, ICompletionParticipant } from 'vscode-html-languageservice'; +import { LanguageService as HTMLLanguageService, HTMLDocument, DocumentContext, FormattingOptions, HTMLFormatConfiguration } from 'vscode-html-languageservice'; import { TextDocument, Position, Range, CompletionItem } from 'vscode-languageserver-types'; import { LanguageMode, Workspace } from './languageModes'; @@ -18,7 +18,7 @@ export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace: getId() { return 'html'; }, - doComplete(document: TextDocument, position: Position, settings = workspace.settings, completionParticipants?: ICompletionParticipant[]) { + doComplete(document: TextDocument, position: Position, settings = workspace.settings) { let options = settings && settings.html && settings.html.suggest; let doAutoComplete = settings && settings.html && settings.html.autoClosingTags; if (doAutoComplete) { @@ -26,9 +26,6 @@ export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace: } let pathCompletionProposals: CompletionItem[] = []; let participants = [getPathCompletionParticipant(document, workspace.folders, pathCompletionProposals)]; - if (completionParticipants) { - participants.push(...completionParticipants); - } htmlLanguageService.setCompletionParticipants(participants); const htmlDocument = htmlDocuments.get(document); diff --git a/extensions/html-language-features/server/src/modes/languageModes.ts b/extensions/html-language-features/server/src/modes/languageModes.ts index 13242925d5a59..282c4f75ef443 100644 --- a/extensions/html-language-features/server/src/modes/languageModes.ts +++ b/extensions/html-language-features/server/src/modes/languageModes.ts @@ -24,7 +24,6 @@ export interface Settings { css?: any; html?: any; javascript?: any; - emmet?: { [key: string]: any }; } export interface Workspace { @@ -35,7 +34,7 @@ export interface Workspace { export interface LanguageMode { getId(): string; doValidation?: (document: TextDocument, settings?: Settings) => Diagnostic[]; - doComplete?: (document: TextDocument, position: Position, settings?: Settings, registeredCompletionParticipants?: any[]) => CompletionList; + doComplete?: (document: TextDocument, position: Position, settings?: Settings) => CompletionList; doResolve?: (document: TextDocument, item: CompletionItem) => CompletionItem; doHover?: (document: TextDocument, position: Position) => Hover | null; doSignatureHelp?: (document: TextDocument, position: Position) => SignatureHelp | null; diff --git a/extensions/html-language-features/server/src/test/emmet.test.ts b/extensions/html-language-features/server/src/test/emmet.test.ts deleted file mode 100644 index 15997dcf20da5..0000000000000 --- a/extensions/html-language-features/server/src/test/emmet.test.ts +++ /dev/null @@ -1,72 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -import 'mocha'; -import * as assert from 'assert'; -import { getHTMLMode } from '../modes/htmlMode'; -import { TextDocument, CompletionList } from 'vscode-languageserver-types'; -import { getLanguageModelCache } from '../languageModelCache'; - -import { getLanguageService } from 'vscode-html-languageservice'; -import * as embeddedSupport from '../modes/embeddedSupport'; -import { getEmmetCompletionParticipants } from 'vscode-emmet-helper'; -import { getCSSMode } from '../modes/cssMode'; - -suite('HTML Emmet Support', () => { - - const htmlLanguageService = getLanguageService(); - - function assertCompletions(syntax: string, value: string, expectedProposal: string | null, expectedProposalDoc: string | null): void { - const offset = value.indexOf('|'); - value = value.substr(0, offset) + value.substr(offset + 1); - - const workspace = { - settings: {}, - folders: [{ name: 'test', uri: 'test://test' }] - }; - - const document = TextDocument.create('test://test/test.' + syntax, syntax, 0, value); - const position = document.positionAt(offset); - const documentRegions = getLanguageModelCache(10, 60, document => embeddedSupport.getDocumentRegions(htmlLanguageService, document)); - const mode = syntax === 'html' ? getHTMLMode(htmlLanguageService, workspace) : getCSSMode(documentRegions, workspace); - - const emmetCompletionList = CompletionList.create([], false); - const emmetParticipant = getEmmetCompletionParticipants(document, position, document.languageId, {}, emmetCompletionList); - - const list = mode.doComplete!(document, position, {}, [emmetParticipant]); - assert.ok(list); - assert.ok(emmetCompletionList); - - let actualLabels = emmetCompletionList.items.map(c => c.label).sort(); - let actualDocs = emmetCompletionList.items.map(c => c.documentation).sort(); - if (expectedProposal && expectedProposalDoc) { - assert.ok(actualLabels.indexOf(expectedProposal) !== -1, value + ': Not found:' + expectedProposal + ' is ' + actualLabels.join(', ')); - assert.ok(actualDocs.indexOf(expectedProposalDoc) !== -1, value + ': Not found:' + expectedProposalDoc + ' is ' + actualDocs.join(', ')); - } else { - assert.ok(!emmetCompletionList.items.length && !emmetCompletionList.isIncomplete, value + ': No proposals expected, but was ' + actualLabels.join(', ')); - } - - } - - test('Html Emmet Completions', function (): any { - assertCompletions('html', 'ul|', 'ul', '
    |
'); - assertCompletions('html', 'ul|', 'ul', '
    |
'); - assertCompletions('html', '', null, null); - }); - - test('Css Emmet Completions', function (): any { - assertCompletions('css', '', 'margin: 10px;', 'margin: 10px;'); - assertCompletions('css', '', 'position: fixed;', 'position: fixed;'); - // assertCompletions('css', '', null, null); // disabled for #29113 - // assertCompletions('css', '', null, null); // disabled for #29113 - assertCompletions('css', '', null, null); - assertCompletions('css', '', null, null); - assertCompletions('css', '', null, null); - assertCompletions('css', '', 'margin: 10px;', '-moz-margin: 10px;\nmargin: 10px;'); - }); -}); \ No newline at end of file diff --git a/extensions/html-language-features/server/yarn.lock b/extensions/html-language-features/server/yarn.lock index f4da19b9c1dd2..0ef1e255f194c 100644 --- a/extensions/html-language-features/server/yarn.lock +++ b/extensions/html-language-features/server/yarn.lock @@ -2,10 +2,6 @@ # yarn lockfile v1 -"@emmetio/extract-abbreviation@0.1.6": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@emmetio/extract-abbreviation/-/extract-abbreviation-0.1.6.tgz#e4a9856c1057f0aff7d443b8536477c243abe28c" - "@types/mocha@2.2.33": version "2.2.33" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.33.tgz#d79a0061ec270379f4d9e225f4096fb436669def" @@ -14,10 +10,6 @@ version "7.0.43" resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" -jsonc-parser@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-1.0.0.tgz#ddcc864ae708e60a7a6dd36daea00172fa8d9272" - vscode-css-languageservice@^3.0.9-next.10: version "3.0.9-next.10" resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.9-next.10.tgz#be73d571221176b43d2c398a4a27f7d38206952d" @@ -25,14 +17,6 @@ vscode-css-languageservice@^3.0.9-next.10: vscode-languageserver-types "^3.6.1" vscode-nls "^3.2.1" -vscode-emmet-helper@1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.2.6.tgz#6cc7293765af7136d409d0d62ef17c66e8b9cf45" - dependencies: - "@emmetio/extract-abbreviation" "0.1.6" - jsonc-parser "^1.0.0" - vscode-languageserver-types "^3.6.0-next.1" - vscode-html-languageservice@^2.1.3-next.3: version "2.1.3-next.3" resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.1.3-next.3.tgz#20c4a0ae673815b598a7e132b5ef03a6920fa7af" @@ -63,10 +47,6 @@ vscode-languageserver-types@^3.6.0, vscode-languageserver-types@^3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.6.1.tgz#4bc06a48dff653495f12f94b8b1e228988a1748d" -vscode-languageserver-types@^3.6.0-next.1: - version "3.6.0-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.6.0-next.1.tgz#98e488d3f87b666b4ee1a3d89f0023e246d358f3" - vscode-languageserver@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-4.0.0.tgz#8b792f0d6d10acfe363d02371ed4ce53d08af88a"