Separate Completion Provider for Emmet Css
This commit is contained in:
parent
fed8544b4f
commit
6ff1da8d30
|
@ -6,12 +6,12 @@
|
|||
|
||||
import * as vscode from 'vscode';
|
||||
import { expand, createSnippetsRegistry } from '@emmetio/expand-abbreviation';
|
||||
import { getSyntax, isStyleSheet, getProfile, extractAbbreviation } from './util';
|
||||
import { getSyntax, getProfile, extractAbbreviation } from './util';
|
||||
|
||||
const field = (index, placeholder) => `\${${index}${placeholder ? ':' + placeholder : ''}}`;
|
||||
const snippetCompletionsCache = new Map<string, vscode.CompletionItem[]>();
|
||||
|
||||
export class EmmetCompletionItemProvider implements vscode.CompletionItemProvider {
|
||||
abstract class EmmetCompletionItemProviderBase implements vscode.CompletionItemProvider {
|
||||
|
||||
public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable<vscode.CompletionList> {
|
||||
|
||||
|
@ -20,42 +20,97 @@ export class EmmetCompletionItemProvider implements vscode.CompletionItemProvide
|
|||
}
|
||||
|
||||
let currentWord = getCurrentWord(document, position);
|
||||
let expandedAbbr = getExpandedAbbreviation(document, position);
|
||||
let abbreviationSuggestions = getAbbreviationSuggestions(getSyntax(document), currentWord, (expandedAbbr && currentWord === expandedAbbr.label));
|
||||
let expandedAbbr = this.getExpandedAbbreviation(document, position);
|
||||
let abbreviationSuggestions = this.getAbbreviationSuggestions(getSyntax(document), currentWord, (expandedAbbr && currentWord === expandedAbbr.label));
|
||||
let completionItems = expandedAbbr ? [expandedAbbr, ...abbreviationSuggestions] : abbreviationSuggestions;
|
||||
|
||||
return Promise.resolve(new vscode.CompletionList(completionItems, true));
|
||||
}
|
||||
|
||||
protected getExpandedAbbreviation(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem {
|
||||
if (!vscode.workspace.getConfiguration('emmet')['showExpandedAbbreviation']) {
|
||||
return;
|
||||
}
|
||||
let [rangeToReplace, wordToExpand] = extractAbbreviation(position);
|
||||
if (!rangeToReplace || !wordToExpand) {
|
||||
return;
|
||||
}
|
||||
let syntax = getSyntax(document);
|
||||
let expandedWord = expand(wordToExpand, {
|
||||
field: field,
|
||||
syntax: syntax,
|
||||
profile: getProfile(syntax),
|
||||
addons: syntax === 'jsx' ? { 'jsx': true } : null
|
||||
});
|
||||
|
||||
let completionitem = new vscode.CompletionItem(wordToExpand);
|
||||
completionitem.insertText = new vscode.SnippetString(expandedWord);
|
||||
completionitem.documentation = removeTabStops(expandedWord);
|
||||
completionitem.range = rangeToReplace;
|
||||
completionitem.detail = 'Expand Emmet Abbreviation';
|
||||
|
||||
|
||||
return completionitem;
|
||||
}
|
||||
|
||||
abstract getAbbreviationSuggestions(syntax: string, prefix: string, skipExactMatch: boolean): vscode.CompletionItem[];
|
||||
|
||||
}
|
||||
|
||||
function getExpandedAbbreviation(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem {
|
||||
if (!vscode.workspace.getConfiguration('emmet')['showExpandedAbbreviation']) {
|
||||
return;
|
||||
}
|
||||
let [rangeToReplace, wordToExpand] = extractAbbreviation(position);
|
||||
if (!rangeToReplace || !wordToExpand) {
|
||||
return;
|
||||
}
|
||||
let syntax = getSyntax(document);
|
||||
let expandedWord = expand(wordToExpand, {
|
||||
field: field,
|
||||
syntax: syntax,
|
||||
profile: getProfile(syntax),
|
||||
addons: syntax === 'jsx' ? { 'jsx': true } : null
|
||||
});
|
||||
export class EmmetCompletionItemProviderHtml extends EmmetCompletionItemProviderBase {
|
||||
|
||||
let completionitem = new vscode.CompletionItem(wordToExpand);
|
||||
completionitem.insertText = new vscode.SnippetString(expandedWord);
|
||||
completionitem.documentation = removeTabStops(expandedWord);
|
||||
completionitem.range = rangeToReplace;
|
||||
completionitem.detail = 'Expand Emmet Abbreviation';
|
||||
protected getExpandedAbbreviation(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem {
|
||||
let completionItem = super.getExpandedAbbreviation(document, position);
|
||||
|
||||
// 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
|
||||
if (!isStyleSheet(syntax)) {
|
||||
completionitem.kind = vscode.CompletionItemKind.Value;
|
||||
// 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
|
||||
completionItem.kind = vscode.CompletionItemKind.Value;
|
||||
|
||||
return completionItem;
|
||||
}
|
||||
return completionitem;
|
||||
|
||||
getAbbreviationSuggestions(syntax: string, prefix: string, skipExactMatch: boolean) {
|
||||
if (!vscode.workspace.getConfiguration('emmet')['showAbbreviationSuggestions'] || !prefix) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!snippetCompletionsCache.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;
|
||||
});
|
||||
snippetCompletionsCache.set(syntax, completions);
|
||||
}
|
||||
|
||||
let snippetCompletions = snippetCompletionsCache.get(syntax);
|
||||
|
||||
snippetCompletions = snippetCompletions.filter(x => x.label.startsWith(prefix) && (!skipExactMatch || x.label !== prefix));
|
||||
|
||||
return snippetCompletions;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export class EmmetCompletionItemProviderCss extends EmmetCompletionItemProviderBase {
|
||||
public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable<vscode.CompletionList> {
|
||||
return super.provideCompletionItems(document, position, token);
|
||||
}
|
||||
|
||||
getAbbreviationSuggestions(syntax: string, prefix: string, skipExactMatch: boolean) {
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getCurrentWord(document: vscode.TextDocument, position: vscode.Position): string {
|
||||
|
@ -72,35 +127,7 @@ function getCurrentWord(document: vscode.TextDocument, position: vscode.Position
|
|||
function removeTabStops(expandedWord: string): string {
|
||||
return expandedWord.replace(/\$\{\d+\}/g, '').replace(/\$\{\d+:([^\}]+)\}/g, '$1');
|
||||
}
|
||||
function getAbbreviationSuggestions(syntax: string, prefix: string, skipExactMatch: boolean) {
|
||||
if (!vscode.workspace.getConfiguration('emmet')['showAbbreviationSuggestions'] || !prefix || isStyleSheet(syntax)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!snippetCompletionsCache.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;
|
||||
});
|
||||
snippetCompletionsCache.set(syntax, completions);
|
||||
}
|
||||
|
||||
let snippetCompletions = snippetCompletionsCache.get(syntax);
|
||||
|
||||
snippetCompletions = snippetCompletions.filter(x => x.label.startsWith(prefix) && (!skipExactMatch || x.label !== prefix));
|
||||
|
||||
return snippetCompletions;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { EmmetCompletionItemProvider } from './emmetCompletionProvider';
|
||||
import { EmmetCompletionItemProviderHtml, EmmetCompletionItemProviderCss } from './emmetCompletionProvider';
|
||||
import { expandAbbreviation, wrapWithAbbreviation } from './abbreviationActions';
|
||||
import { removeTag } from './removeTag';
|
||||
import { updateTag } from './updateTag';
|
||||
|
@ -21,7 +21,7 @@ interface ISupportedLanguageMode {
|
|||
triggerCharacters: string[];
|
||||
}
|
||||
|
||||
const SUPPORTED_LANGUAGE_MODES: ISupportedLanguageMode[] = [
|
||||
const HTML_LANGUAGE_MODES: ISupportedLanguageMode[] = [
|
||||
{ id: 'html', triggerCharacters: ['!', '.', '}'] },
|
||||
{ id: 'jade', triggerCharacters: ['!', '.', '}'] },
|
||||
{ id: 'slim', triggerCharacters: ['!', '.', '}'] },
|
||||
|
@ -29,23 +29,29 @@ const SUPPORTED_LANGUAGE_MODES: ISupportedLanguageMode[] = [
|
|||
{ id: 'xml', triggerCharacters: ['.', '}'] },
|
||||
{ id: 'xsl', triggerCharacters: ['.', '}'] },
|
||||
|
||||
{ id: 'css', triggerCharacters: [':'] },
|
||||
{ id: 'scss', triggerCharacters: [':'] },
|
||||
{ id: 'sass', triggerCharacters: [':'] },
|
||||
{ id: 'less', triggerCharacters: [':'] },
|
||||
{ id: 'stylus', triggerCharacters: [':'] },
|
||||
|
||||
{ id: 'javascriptreact', triggerCharacters: ['.'] },
|
||||
{ id: 'typescriptreact', triggerCharacters: ['.'] }
|
||||
];
|
||||
|
||||
const CSS_LANGUAGE_MODES: ISupportedLanguageMode[] = [
|
||||
{ id: 'css', triggerCharacters: [':'] },
|
||||
{ id: 'scss', triggerCharacters: [':'] },
|
||||
{ id: 'sass', triggerCharacters: [':'] },
|
||||
{ id: 'less', triggerCharacters: [':'] },
|
||||
{ id: 'stylus', triggerCharacters: [':'] }
|
||||
];
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
let completionProvider = new EmmetCompletionItemProvider();
|
||||
let completionProviderHtml = new EmmetCompletionItemProviderHtml();
|
||||
let completionProviderCss = new EmmetCompletionItemProviderCss();
|
||||
|
||||
for (let language of SUPPORTED_LANGUAGE_MODES) {
|
||||
const selector: vscode.DocumentFilter = { language: language.id };
|
||||
const provider = vscode.languages.registerCompletionItemProvider(selector, completionProvider, ...language.triggerCharacters);
|
||||
for (let language of HTML_LANGUAGE_MODES) {
|
||||
const provider = vscode.languages.registerCompletionItemProvider({ language: language.id }, completionProviderHtml, ...language.triggerCharacters);
|
||||
context.subscriptions.push(provider);
|
||||
}
|
||||
|
||||
for (let language of CSS_LANGUAGE_MODES) {
|
||||
const provider = vscode.languages.registerCompletionItemProvider({ language: language.id }, completionProviderCss, ...language.triggerCharacters);
|
||||
context.subscriptions.push(provider);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue