diff options
Diffstat (limited to 'tools/language-server/src/plugins/html/HTMLPlugin.ts')
-rw-r--r-- | tools/language-server/src/plugins/html/HTMLPlugin.ts | 142 |
1 files changed, 0 insertions, 142 deletions
diff --git a/tools/language-server/src/plugins/html/HTMLPlugin.ts b/tools/language-server/src/plugins/html/HTMLPlugin.ts deleted file mode 100644 index 49ca46b86..000000000 --- a/tools/language-server/src/plugins/html/HTMLPlugin.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { CompletionsProvider, FoldingRangeProvider } from '../interfaces'; -import { getEmmetCompletionParticipants, VSCodeEmmetConfig } from 'vscode-emmet-helper'; -import { getLanguageService, HTMLDocument, CompletionItem as HtmlCompletionItem, Node, FoldingRange } from 'vscode-html-languageservice'; -import { CompletionList, Position, CompletionItem, CompletionItemKind, TextEdit } from 'vscode-languageserver'; -import type { Document, DocumentManager } from '../../core/documents'; -import { isInsideExpression, isInsideFrontmatter } from '../../core/documents/utils'; -import type { ConfigManager } from '../../core/config'; - -export class HTMLPlugin implements CompletionsProvider, FoldingRangeProvider { - private lang = getLanguageService(); - private documents = new WeakMap<Document, HTMLDocument>(); - private styleScriptTemplate = new Set(['template', 'style', 'script']); - private configManager: ConfigManager; - public pluginName = 'HTML'; - - constructor(docManager: DocumentManager, configManager: ConfigManager) { - docManager.on('documentChange', (document) => { - this.documents.set(document, document.html); - }); - this.configManager = configManager; - } - - getCompletions(document: Document, position: Position): CompletionList | null { - const html = this.documents.get(document); - - if (!html) { - return null; - } - - if (this.isInsideFrontmatter(document, position) || this.isInsideExpression(html, document, position)) { - return null; - } - - const offset = document.offsetAt(position); - const node = html.findNodeAt(offset); - - if (this.isComponentTag(node)) { - return null; - } - - const emmetResults: CompletionList = { - isIncomplete: true, - items: [], - }; - this.lang.setCompletionParticipants([getEmmetCompletionParticipants(document, position, 'html', this.configManager.getEmmetConfig(), emmetResults)]); - - const results = this.lang.doComplete(document, position, html); - const items = this.toCompletionItems(results.items); - - return CompletionList.create( - [...this.toCompletionItems(items), ...this.getLangCompletions(items), ...emmetResults.items], - // Emmet completions change on every keystroke, so they are never complete - emmetResults.items.length > 0 - ); - } - - getFoldingRanges(document: Document): FoldingRange[] | null { - const html = this.documents.get(document); - if (!html) { - return null; - } - - return this.lang.getFoldingRanges(document); - } - - doTagComplete(document: Document, position: Position): string | null { - const html = this.documents.get(document); - if (!html) { - return null; - } - - if (this.isInsideFrontmatter(document, position) || this.isInsideExpression(html, document, position)) { - return null; - } - - return this.lang.doTagComplete(document, position, html); - } - - /** - * The HTML language service uses newer types which clash - * without the stable ones. Transform to the stable types. - */ - private toCompletionItems(items: HtmlCompletionItem[]): CompletionItem[] { - return items.map((item) => { - if (!item.textEdit || TextEdit.is(item.textEdit)) { - return item as CompletionItem; - } - return { - ...item, - textEdit: TextEdit.replace(item.textEdit.replace, item.textEdit.newText), - }; - }); - } - - private getLangCompletions(completions: CompletionItem[]): CompletionItem[] { - const styleScriptTemplateCompletions = completions.filter((completion) => completion.kind === CompletionItemKind.Property && this.styleScriptTemplate.has(completion.label)); - const langCompletions: CompletionItem[] = []; - addLangCompletion('style', ['scss', 'sass']); - return langCompletions; - - /** Add language completions */ - function addLangCompletion(tag: string, languages: string[]) { - const existingCompletion = styleScriptTemplateCompletions.find((completion) => completion.label === tag); - if (!existingCompletion) { - return; - } - - languages.forEach((lang) => - langCompletions.push({ - ...existingCompletion, - label: `${tag} (lang="${lang}")`, - insertText: existingCompletion.insertText && `${existingCompletion.insertText} lang="${lang}"`, - textEdit: - existingCompletion.textEdit && TextEdit.is(existingCompletion.textEdit) - ? { - range: existingCompletion.textEdit.range, - newText: `${existingCompletion.textEdit.newText} lang="${lang}"`, - } - : undefined, - }) - ); - } - } - - private isInsideExpression(html: HTMLDocument, document: Document, position: Position) { - const offset = document.offsetAt(position); - const node = html.findNodeAt(offset); - return isInsideExpression(document.getText(), node.start, offset); - } - - private isInsideFrontmatter(document: Document, position: Position) { - return isInsideFrontmatter(document.getText(), document.offsetAt(position)); - } - - private isComponentTag(node: Node): boolean { - if (!node.tag) { - return false; - } - const firstChar = node.tag[0]; - return /[A-Z]/.test(firstChar); - } -} |