提交 8f5fc228 编写于 作者: R Ramya Achutha Rao

Refactoring to support #28556 eventually

上级 bd74b632
......@@ -51,7 +51,13 @@ export function expandAbbreviation() {
mappedSyntax = true;
}
}
let output = expandAbbreviationHelper(syntax, editor.document, editor.selection, mappedSyntax);
if (!mappedSyntax) {
syntax = syntaxHelper(syntax, editor.document, editor.selection.end);
}
if (!syntax) {
return;
}
let output = expandAbbreviationHelper(syntax, editor.document, editor.selection);
if (output) {
editor.insertSnippet(new vscode.SnippetString(output.expandedText), output.abbreviationRange);
}
......@@ -69,21 +75,8 @@ export interface ExpandAbbreviationHelperOutput {
* @param syntax string syntax to be used for expanding abbreviations
* @param document vscode.TextDocument
* @param abbreviationRange vscode.Range range of the abbreviation that needs to be expanded
* @param mappedSyntax Boolean Pass true if given document language was mapped to given syntax to get emmet abbreviation expansions.
* */
export function expandAbbreviationHelper(syntax: string, document: vscode.TextDocument, abbreviationRange: vscode.Range, mappedSyntax: boolean): ExpandAbbreviationHelperOutput {
if (!mappedSyntax) {
let parseContent = isStyleSheet(syntax) ? parseStylesheet : parse;
let rootNode: Node = parseContent(new DocumentStreamReader(document));
let currentNode = getNode(rootNode, abbreviationRange.end);
if (forceCssSyntax(syntax, currentNode, abbreviationRange.end)) {
syntax = 'css';
} else if (!isValidLocationForEmmetAbbreviation(currentNode, syntax, abbreviationRange.end)) {
return;
}
}
export function expandAbbreviationHelper(syntax: string, document: vscode.TextDocument, abbreviationRange: vscode.Range): ExpandAbbreviationHelperOutput {
let abbreviation = document.getText(abbreviationRange);
if (abbreviationRange.isEmpty) {
[abbreviationRange, abbreviation] = extractAbbreviation(document, abbreviationRange.start);
......@@ -93,6 +86,24 @@ export function expandAbbreviationHelper(syntax: string, document: vscode.TextDo
return { expandedText, abbreviationRange, abbreviation, syntax };
}
/**
* Checks 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
*/
export function syntaxHelper(syntax: string, document: vscode.TextDocument, position: vscode.Position): string {
let parseContent = isStyleSheet(syntax) ? parseStylesheet : parse;
let rootNode: Node = parseContent(new DocumentStreamReader(document));
let currentNode = getNode(rootNode, position);
if (forceCssSyntax(syntax, currentNode, position)) {
return 'css';
} else if (!isValidLocationForEmmetAbbreviation(currentNode, syntax, position)) {
return;
}
}
/**
* Extracts abbreviation from the given position in the given document
*/
......@@ -141,7 +152,7 @@ function isValidLocationForEmmetAbbreviation(currentNode: Node, syntax: string,
return false;
}
function getExpandOptions(syntax: string, textToReplace?: string) {
export function getExpandOptions(syntax: string, textToReplace?: string) {
return {
field: field,
syntax: syntax,
......
......@@ -7,10 +7,9 @@
import * as vscode from 'vscode';
import { expand, createSnippetsRegistry } from '@emmetio/expand-abbreviation';
import { getSyntax, isStyleSheet } from './util';
import { expandAbbreviationHelper, ExpandAbbreviationHelperOutput } from './abbreviationActions';
import { syntaxHelper, expandAbbreviationHelper, ExpandAbbreviationHelperOutput, getExpandOptions } from './abbreviationActions';
const field = (index, placeholder) => `\${${index}${placeholder ? ':' + placeholder : ''}}`;
const snippetCompletionsCache = new Map<string, vscode.CompletionItem[]>();
const snippetKeyCache = new Map<string, string[]>();
export class EmmetCompletionItemProvider implements vscode.CompletionItemProvider {
private _mappedSyntax = false;
......@@ -21,64 +20,70 @@ export class EmmetCompletionItemProvider implements vscode.CompletionItemProvide
}
public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable<vscode.CompletionList> {
if (!vscode.workspace.getConfiguration('emmet')['useNewEmmet']) {
let emmetConfig = vscode.workspace.getConfiguration('emmet');
if (!emmetConfig['useNewEmmet'] || !emmetConfig['showExpandedAbbreviation']) {
return Promise.resolve(null);
}
let syntax = getSyntax(document);
let expandedAbbr: vscode.CompletionItem;
if (vscode.workspace.getConfiguration('emmet')['showExpandedAbbreviation']) {
let output: ExpandAbbreviationHelperOutput = expandAbbreviationHelper(syntax, document, new vscode.Range(position, position), this._mappedSyntax);
if (output) {
expandedAbbr = new vscode.CompletionItem(output.abbreviation);
expandedAbbr.insertText = new vscode.SnippetString(output.expandedText);
expandedAbbr.documentation = removeTabStops(output.expandedText);
expandedAbbr.range = output.abbreviationRange;
expandedAbbr.detail = 'Expand Emmet Abbreviation';
syntax = output.syntax;
}
let abbreviationRange = new vscode.Range(position, position);
if (!this._mappedSyntax) {
syntax = syntaxHelper(syntax, document, position);
}
let output: ExpandAbbreviationHelperOutput = expandAbbreviationHelper(syntax, document, abbreviationRange);
if (!output) {
return;
}
let expandedAbbr = new vscode.CompletionItem(output.abbreviation);
expandedAbbr.insertText = new vscode.SnippetString(output.expandedText);
expandedAbbr.documentation = removeTabStops(output.expandedText);
expandedAbbr.range = output.abbreviationRange;
expandedAbbr.detail = 'Expand Emmet Abbreviation';
syntax = output.syntax;
let completionItems: vscode.CompletionItem[] = expandedAbbr ? [expandedAbbr] : [];
if (!isStyleSheet(syntax)) {
if (expandedAbbr) {
// In non stylesheet like syntax, this extension returns expanded abbr plus posssible abbr completions
// To differentiate between the 2, the former is given CompletionItemKind.Value so that it gets a different icon
expandedAbbr.kind = vscode.CompletionItemKind.Value;
}
let currentWord = getCurrentWord(document, position);
let abbreviationSuggestions = this.getAbbreviationSuggestions(syntax, currentWord, (expandedAbbr && currentWord === expandedAbbr.label));
let abbreviationSuggestions = this.getAbbreviationSuggestions(syntax, currentWord, output.abbreviation, output.abbreviationRange);
completionItems = completionItems.concat(abbreviationSuggestions);
}
return Promise.resolve(new vscode.CompletionList(completionItems, true));
}
getAbbreviationSuggestions(syntax: string, prefix: string, skipExactMatch: boolean) {
if (!vscode.workspace.getConfiguration('emmet')['showAbbreviationSuggestions'] || !prefix) {
getAbbreviationSuggestions(syntax: string, prefix: string, abbreviation: string, abbreviationRange: vscode.Range): vscode.CompletionItem[] {
if (!vscode.workspace.getConfiguration('emmet')['showAbbreviationSuggestions'] || !prefix || !abbreviation) {
return [];
}
if (!snippetCompletionsCache.has(syntax)) {
if (!snippetKeyCache.has(syntax)) {
let registry = createSnippetsRegistry(syntax);
let completions: vscode.CompletionItem[] = registry.all({ type: 'string' }).map(snippet => {
let expandedWord = expand(snippet.value, {
field: field,
syntax: syntax
});
let item = new vscode.CompletionItem(snippet.key);
item.documentation = removeTabStops(expandedWord);
item.detail = 'Complete Emmet Abbreviation';
item.insertText = snippet.key;
return item;
let snippetKeys: string[] = registry.all({ type: 'string' }).map(snippet => {
return snippet.key;
});
snippetCompletionsCache.set(syntax, completions);
snippetKeyCache.set(syntax, snippetKeys);
}
let snippetCompletions = snippetCompletionsCache.get(syntax);
let skipExactMatch = prefix === abbreviation;
let snippetKeys = snippetKeyCache.get(syntax);
let snippetCompletions = [];
snippetKeys.forEach(snippetKey => {
if (!snippetKey.startsWith(prefix) || (snippetKey === prefix) || (skipExactMatch && snippetKey === prefix)) {
return;
}
let currentAbbr = snippetKey; // For #28556: abbreviation + snippetKey.substr(prefix.length);
let expandedAbbr = expand(currentAbbr, getExpandOptions(syntax));
let item = new vscode.CompletionItem(snippetKey);
item.documentation = removeTabStops(expandedAbbr);
item.detail = 'Complete Emmet Abbreviation';
item.insertText = snippetKey; // For #28556: new vscode.SnippetString(expandedAbbr);
snippetCompletions = snippetCompletions.filter(x => x.label.startsWith(prefix) && (!skipExactMatch || x.label !== prefix));
snippetCompletions.push(item);
});
return snippetCompletions;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册