mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-27 12:04:04 +01:00
Emmet suggestions in non markup/stylesheet languages #29532
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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<vscode.CompletionList> {
|
||||
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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user