diff --git a/extensions/emmet/npm-shrinkwrap.json b/extensions/emmet/npm-shrinkwrap.json index f8d983ece7c..027ce671d95 100644 --- a/extensions/emmet/npm-shrinkwrap.json +++ b/extensions/emmet/npm-shrinkwrap.json @@ -118,9 +118,9 @@ "resolved": "https://registry.npmjs.org/@emmetio/variable-resolver/-/variable-resolver-0.2.1.tgz" }, "vscode-emmet-helper": { - "version": "0.0.11", - "from": "vscode-emmet-helper@0.0.11", - "resolved": "https://registry.npmjs.org/vscode-emmet-helper/-/vscode-emmet-helper-0.0.11.tgz" + "version": "0.0.14", + "from": "vscode-emmet-helper@0.0.14", + "resolved": "https://registry.npmjs.org/vscode-emmet-helper/-/vscode-emmet-helper-0.0.14.tgz" } } } diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json index ad756d157bf..0d865fc3a49 100644 --- a/extensions/emmet/package.json +++ b/extensions/emmet/package.json @@ -24,14 +24,19 @@ "title": "Emmet", "properties": { "emmet.showExpandedAbbreviation": { - "type": "boolean", - "default": true, - "description": "Shows expanded emmet abbreviations as suggestions" + "type": ["string"], + "enum": [ + "never", + "always", + "inDefaultEmmetModesOnly" + ], + "default": "inDefaultEmmetModesOnly", + "description": "Shows expanded emmet abbreviations as suggestions." }, "emmet.showAbbreviationSuggestions": { "type": "boolean", "default": true, - "description": "Shows possible emmet abbreviations as suggestions" + "description": "Shows possible emmet abbreviations as suggestions. Not applicable in stylesheets or when emmet.showExpandedAbbreviation is set to \"never\"." }, "emmet.includeLanguages": { "type": "object", @@ -68,6 +73,6 @@ "@emmetio/html-matcher": "^0.3.1", "@emmetio/css-parser": "^0.3.0", "@emmetio/math-expression": "^0.1.1", - "vscode-emmet-helper":"0.0.11" + "vscode-emmet-helper":"0.0.14" } } \ No newline at end of file diff --git a/extensions/emmet/src/abbreviationActions.ts b/extensions/emmet/src/abbreviationActions.ts index 8c270d2155f..cdc720e7dde 100644 --- a/extensions/emmet/src/abbreviationActions.ts +++ b/extensions/emmet/src/abbreviationActions.ts @@ -8,8 +8,8 @@ import { expand } from '@emmetio/expand-abbreviation'; import parseStylesheet from '@emmetio/css-parser'; import parse from '@emmetio/html-matcher'; import { Node, HtmlNode, Rule } from 'EmmetNode'; -import { getNode, getInnerRange, getMappedSyntax } from './util'; -import { getExpandOptions, extractAbbreviation, isStyleSheet, isAbbreviationValid } from 'vscode-emmet-helper'; +import { getNode, getInnerRange, getMappingForIncludedLanguages } from './util'; +import { getExpandOptions, extractAbbreviation, isStyleSheet, isAbbreviationValid, getEmmetMode } from 'vscode-emmet-helper'; import { DocumentStreamReader } from './bufferStream'; interface ExpandAbbreviationInput { @@ -208,10 +208,15 @@ function getSyntaxFromArgs(args: any): string { vscode.window.showInformationMessage('Cannot resolve language at cursor.'); return; } - let syntax = getMappedSyntax(args['language']); + + const mappedModes = getMappingForIncludedLanguages(); + let language: string = args['language']; + let parentMode: string = args['parentMode']; + + let syntax = getEmmetMode(mappedModes[language] ? mappedModes[language] : language); if (syntax) { return syntax; } - return getMappedSyntax(args['parentMode']); + return getEmmetMode(mappedModes[parentMode] ? mappedModes[parentMode] : parentMode); } \ No newline at end of file diff --git a/extensions/emmet/src/defaultCompletionProvider.ts b/extensions/emmet/src/defaultCompletionProvider.ts index b6edd606da3..76836ce8881 100644 --- a/extensions/emmet/src/defaultCompletionProvider.ts +++ b/extensions/emmet/src/defaultCompletionProvider.ts @@ -8,20 +8,25 @@ import parseStylesheet from '@emmetio/css-parser'; import parse from '@emmetio/html-matcher'; import { Node, HtmlNode } from 'EmmetNode'; import { DocumentStreamReader } from './bufferStream'; -import { EmmetCompletionItemProvider, isStyleSheet } from 'vscode-emmet-helper'; +import { EmmetCompletionItemProvider, isStyleSheet, getEmmetMode } from 'vscode-emmet-helper'; import { isValidLocationForEmmetAbbreviation } from './abbreviationActions'; -import { getSyntax, getNode, getInnerRange, getExcludedModes } from './util'; +import { getNode, getInnerRange, getMappingForIncludedLanguages } from './util'; export class DefaultCompletionItemProvider implements vscode.CompletionItemProvider { public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable { - let syntax = getSyntax(document); - if (getExcludedModes().indexOf(syntax) > -1) { - return; - } - syntax = this.syntaxHelper(syntax, document, position); + const mappedLanguages = getMappingForIncludedLanguages(); - if (!syntax) { + let isSyntaxMapped = mappedLanguages[document.languageId] ? true : false; + let syntax = getEmmetMode(isSyntaxMapped ? mappedLanguages[document.languageId] : document.languageId); + + if (document.languageId === 'html' || isStyleSheet(document.languageId)) { + // Document can be html/css parsed + // Use syntaxHelper to parse file, validate location and update sytnax if needed + syntax = this.syntaxHelper(syntax, document, position); + } + + if (!syntax || (isSyntaxMapped && vscode.workspace.getConfiguration('emmet')['showExpandedAbbreviation'] !== 'always')) { return; } @@ -30,12 +35,15 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi } /** - * Checks whether given position is valid for emmet abbreviation and returns appropriate syntax + * Parses given document to check whether given position is valid for emmet abbreviation and returns appropriate syntax * @param syntax string language mode of current document * @param document vscode.Textdocument * @param position vscode.Position position of the abbreviation that needs to be expanded */ private syntaxHelper(syntax: string, document: vscode.TextDocument, position: vscode.Position): string { + if (!syntax) { + return syntax; + } let parseContent = isStyleSheet(syntax) ? parseStylesheet : parse; let rootNode: Node = parseContent(new DocumentStreamReader(document)); let currentNode = getNode(rootNode, position); diff --git a/extensions/emmet/src/extension.ts b/extensions/emmet/src/extension.ts index e8ac1cbdf15..b7c1a9f36f1 100644 --- a/extensions/emmet/src/extension.ts +++ b/extensions/emmet/src/extension.ts @@ -17,19 +17,20 @@ import { fetchEditPoint } from './editPoint'; import { fetchSelectItem } from './selectItem'; import { evaluateMathExpression } from './evaluateMathExpression'; import { incrementDecrement } from './incrementDecrement'; -import { LANGUAGE_MODES, getExcludedModes } from './util'; +import { LANGUAGE_MODES, getMappingForIncludedLanguages } from './util'; import { updateExtensionsPath } from 'vscode-emmet-helper'; export function activate(context: vscode.ExtensionContext) { let completionProvider = new DefaultCompletionItemProvider(); - let excludedLanguages = getExcludedModes(); Object.keys(LANGUAGE_MODES).forEach(language => { - if (excludedLanguages.indexOf(language) > -1) { - return; - } const provider = vscode.languages.registerCompletionItemProvider(language, completionProvider, ...LANGUAGE_MODES[language]); context.subscriptions.push(provider); }); + let includedLanguages = getMappingForIncludedLanguages(); + Object.keys(includedLanguages).forEach(language => { + const provider = vscode.languages.registerCompletionItemProvider(language, completionProvider, ...LANGUAGE_MODES[includedLanguages[language]]); + context.subscriptions.push(provider); + }); context.subscriptions.push(vscode.commands.registerCommand('emmet.wrapWithAbbreviation', (args) => { wrapWithAbbreviation(args); diff --git a/extensions/emmet/src/util.ts b/extensions/emmet/src/util.ts index f3bdf3db7e9..f46a6150c96 100644 --- a/extensions/emmet/src/util.ts +++ b/extensions/emmet/src/util.ts @@ -46,7 +46,7 @@ export function getSyntax(document: vscode.TextDocument): string { return document.languageId; } -export function getIncludedModes(): any { +export function getMappingForIncludedLanguages(): any { let finalMappedModes = {}; let includeLanguagesConfig = vscode.workspace.getConfiguration('emmet')['includeLanguages']; let includeLanguages = Object.assign({}, MAPPED_MODES, includeLanguagesConfig ? includeLanguagesConfig : {}); @@ -58,29 +58,8 @@ export function getIncludedModes(): any { return finalMappedModes; } -export function getMappedSyntax(syntax: string): string { - if (!syntax) { - return; - } - if (/\b(typescriptreact|javascriptreact|jsx-tags|jsx)\b/.test(syntax)) { // treat tsx like jsx - return 'jsx'; - } - if (syntax === 'sass-indented') { // map sass-indented to sass - return 'sass'; - } - if (syntax === 'jade') { - return 'pug'; - } - if (Object.keys(LANGUAGE_MODES).indexOf(syntax) > -1) { - return syntax; - } - return getIncludedModes()[syntax]; -} -export function getExcludedModes(): string[] { - let excludedConfig = vscode.workspace.getConfiguration('emmet')['excludeLanguages']; - return Array.isArray(excludedConfig) ? excludedConfig : []; -} + /** * Returns node corresponding to given position in the given root node * @param root