Path: blob/main/extensions/extension-editing/src/packageDocumentHelper.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import * as vscode from 'vscode';6import { getLocation, Location } from 'jsonc-parser';7import { implicitActivationEvent, redundantImplicitActivationEvent } from './constants';8910export class PackageDocument {1112constructor(private document: vscode.TextDocument) { }1314public provideCompletionItems(position: vscode.Position, _token: vscode.CancellationToken): vscode.ProviderResult<vscode.CompletionItem[]> {15const location = getLocation(this.document.getText(), this.document.offsetAt(position));1617if (location.path.length >= 2 && location.path[1] === 'configurationDefaults') {18return this.provideLanguageOverridesCompletionItems(location, position);19}2021return undefined;22}2324public provideCodeActions(_range: vscode.Range, context: vscode.CodeActionContext, _token: vscode.CancellationToken): vscode.ProviderResult<vscode.CodeAction[]> {25const codeActions: vscode.CodeAction[] = [];26for (const diagnostic of context.diagnostics) {27if (diagnostic.message === implicitActivationEvent || diagnostic.message === redundantImplicitActivationEvent) {28const codeAction = new vscode.CodeAction(vscode.l10n.t("Remove activation event"), vscode.CodeActionKind.QuickFix);29codeAction.edit = new vscode.WorkspaceEdit();30const rangeForCharAfter = diagnostic.range.with(diagnostic.range.end, diagnostic.range.end.translate(0, 1));31if (this.document.getText(rangeForCharAfter) === ',') {32codeAction.edit.delete(this.document.uri, diagnostic.range.with(undefined, diagnostic.range.end.translate(0, 1)));33} else {34codeAction.edit.delete(this.document.uri, diagnostic.range);35}36codeActions.push(codeAction);37}38}39return codeActions;40}4142private provideLanguageOverridesCompletionItems(location: Location, position: vscode.Position): vscode.ProviderResult<vscode.CompletionItem[]> {43let range = this.getReplaceRange(location, position);44const text = this.document.getText(range);4546if (location.path.length === 2) {4748let snippet = '"[${1:language}]": {\n\t"$0"\n}';4950// Suggestion model word matching includes quotes,51// hence exclude the starting quote from the snippet and the range52// ending quote gets replaced53if (text && text.startsWith('"')) {54range = new vscode.Range(new vscode.Position(range.start.line, range.start.character + 1), range.end);55snippet = snippet.substring(1);56}5758return Promise.resolve([this.newSnippetCompletionItem({59label: vscode.l10n.t("Language specific editor settings"),60documentation: vscode.l10n.t("Override editor settings for language"),61snippet,62range63})]);64}6566if (location.path.length === 3 && location.previousNode && typeof location.previousNode.value === 'string' && location.previousNode.value.startsWith('[')) {6768// Suggestion model word matching includes starting quote and open sqaure bracket69// Hence exclude them from the proposal range70range = new vscode.Range(new vscode.Position(range.start.line, range.start.character + 2), range.end);7172return vscode.languages.getLanguages().then(languages => {73return languages.map(l => {7475// Suggestion model word matching includes closed sqaure bracket and ending quote76// Hence include them in the proposal to replace77return this.newSimpleCompletionItem(l, range, '', l + ']"');78});79});80}81return Promise.resolve([]);82}8384private getReplaceRange(location: Location, position: vscode.Position) {85const node = location.previousNode;86if (node) {87const nodeStart = this.document.positionAt(node.offset), nodeEnd = this.document.positionAt(node.offset + node.length);88if (nodeStart.isBeforeOrEqual(position) && nodeEnd.isAfterOrEqual(position)) {89return new vscode.Range(nodeStart, nodeEnd);90}91}92return new vscode.Range(position, position);93}9495private newSimpleCompletionItem(text: string, range: vscode.Range, description?: string, insertText?: string): vscode.CompletionItem {96const item = new vscode.CompletionItem(text);97item.kind = vscode.CompletionItemKind.Value;98item.detail = description;99item.insertText = insertText ? insertText : text;100item.range = range;101return item;102}103104private newSnippetCompletionItem(o: { label: string; documentation?: string; snippet: string; range: vscode.Range }): vscode.CompletionItem {105const item = new vscode.CompletionItem(o.label);106item.kind = vscode.CompletionItemKind.Value;107item.documentation = o.documentation;108item.insertText = new vscode.SnippetString(o.snippet);109item.range = o.range;110return item;111}112}113114115