// ***************************************************************************** // Copyright (C) 2018 Red Hat, Inc. and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: GNU General Public License, version 2 // with the GNU Classpath Exception which is available at // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** // copied from https://github.com/microsoft/vscode/blob/1.37.0/src/vs/workbench/api/common/extHostTypes.ts /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ /* eslint-disable no-null/no-null */ import { UUID } from '@theia/core/shared/@lumino/coreutils'; import { illegalArgument } from '../common/errors'; import type * as theia from '@theia/plugin'; import { URI as CodeURI } from '@theia/core/shared/vscode-uri'; import { UriComponents } from '../common/uri-components'; import { relative } from '../common/paths-util'; import { startsWithIgnoreCase } from '@theia/core/lib/common/strings'; import { SymbolKind } from '../common/plugin-api-rpc-model'; import { FileSystemProviderErrorCode, markAsFileSystemProviderError } from '@theia/filesystem/lib/common/files'; import * as paths from 'path'; import { es5ClassCompat } from '../common/types'; import { isObject, isStringArray } from '@theia/core/lib/common'; import { CellEditType, CellMetadataEdit, NotebookDocumentMetadataEdit } from '@theia/notebook/lib/common'; import { BinaryBuffer } from '@theia/core/lib/common/buffer'; /** * This is an implementation of #theia.Uri based on vscode-uri. * This is supposed to fix https://github.com/eclipse-theia/theia/issues/8752 * We cannot simply upgrade the dependency, because the current version 3.x * is not compatible with our current codebase */ @es5ClassCompat export class URI extends CodeURI implements theia.Uri { protected constructor(scheme: string, authority?: string, path?: string, query?: string, fragment?: string, _strict?: boolean); protected constructor(components: UriComponents); protected constructor(schemeOrData: string | UriComponents, authority?: string, path?: string, query?: string, fragment?: string, _strict: boolean = false) { if (typeof schemeOrData === 'string') { super(schemeOrData, authority, path, query, fragment, _strict); } else { super(schemeOrData); } } /** * Override to create the correct class. */ override with(change: { scheme?: string; authority?: string | null; path?: string | null; query?: string | null; fragment?: string | null; }): URI { return new URI(super.with(change)); } static joinPath(uri: URI, ...pathSegments: string[]): URI { if (!uri.path) { throw new Error('\'joinPath\' called on URI without path'); } const newPath = paths.posix.join(uri.path, ...pathSegments); return new URI(uri.scheme, uri.authority, newPath, uri.query, uri.fragment); } /** * Override to create the correct class. * @param data */ static override revive(data: UriComponents | CodeURI): URI; static override revive(data: UriComponents | CodeURI | null): URI | null; static override revive(data: UriComponents | CodeURI | undefined): URI | undefined; static override revive(data: UriComponents | CodeURI | undefined | null): URI | undefined | null { const uri = CodeURI.revive(data); return uri ? new URI(uri) : undefined; } static override parse(value: string, _strict?: boolean): URI { return new URI(CodeURI.parse(value, _strict)); } static override file(path: string): URI { return new URI(CodeURI.file(path)); } /** * There is quite some magic in to vscode URI class related to * transferring via JSON.stringify(). Making the CodeURI instance * makes sure we transfer this object as a vscode-uri URI. */ override toJSON(): UriComponents { return CodeURI.from(this).toJSON(); } } @es5ClassCompat export class Disposable { private disposable: undefined | (() => void); // eslint-disable-next-line @typescript-eslint/no-explicit-any static from(...disposables: { dispose(): any }[]): Disposable { return new Disposable(() => { if (disposables) { for (const disposable of disposables) { if (disposable && typeof disposable.dispose === 'function') { disposable.dispose(); } } } }); } constructor(func: () => void) { this.disposable = func; } /** * Dispose this object. */ dispose(): void { if (this.disposable) { this.disposable(); this.disposable = undefined; } } static create(func: () => void): Disposable { return new Disposable(func); } static NULL: Disposable; } export interface AccessibilityInformation { label: string; role?: string; } export enum StatusBarAlignment { Left = 1, Right = 2 } export enum TextEditorLineNumbersStyle { Off = 0, On = 1, Relative = 2, Interval = 3 } /** * Denotes a column in the editor window. * Columns are used to show editors side by side. */ export enum ViewColumn { Active = -1, Beside = -2, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9 } /** * Represents a color theme kind. */ export enum ColorThemeKind { Light = 1, Dark = 2, HighContrast = 3, HighContrastLight = 4 } export enum ExtensionMode { /** * The extension is installed normally (for example, from the marketplace * or VSIX) in the editor. */ Production = 1, /** * The extension is running from an `--extensionDevelopmentPath` provided * when launching the editor. */ Development = 2, /** * The extension is running from an `--extensionTestsPath` and * the extension host is running unit tests. */ Test = 3, } export enum ExtensionKind { UI = 1, Workspace = 2 } /** * Represents the validation type of the Source Control input. */ export enum SourceControlInputBoxValidationType { /** * Something not allowed by the rules of a language or other means. */ Error = 0, /** * Something suspicious but allowed. */ Warning = 1, /** * Something to inform about but not a problem. */ Information = 2 } export enum ExternalUriOpenerPriority { None = 0, Option = 1, Default = 2, Preferred = 3, } @es5ClassCompat export class ColorTheme implements theia.ColorTheme { constructor(public readonly kind: ColorThemeKind) { } } /** * Represents sources that can cause `window.onDidChangeEditorSelection` */ export enum TextEditorSelectionChangeKind { Keyboard = 1, Mouse = 2, Command = 3 } export namespace TextEditorSelectionChangeKind { export function fromValue(s: string | undefined): TextEditorSelectionChangeKind | undefined { switch (s) { case 'keyboard': return TextEditorSelectionChangeKind.Keyboard; case 'mouse': return TextEditorSelectionChangeKind.Mouse; case 'api': return TextEditorSelectionChangeKind.Command; } return undefined; } } export enum TextDocumentChangeReason { Undo = 1, Redo = 2, } @es5ClassCompat export class Position { private _line: number; private _character: number; constructor(line: number, char: number) { if (line < 0) { throw new Error('line number cannot be negative'); } if (char < 0) { throw new Error('char number cannot be negative'); } this._line = line; this._character = char; } get line(): number { return this._line; } get character(): number { return this._character; } isBefore(other: Position): boolean { if (this._line < other._line) { return true; } if (other._line < this._line) { return false; } return this._character < other._character; } isBeforeOrEqual(other: Position): boolean { if (this._line < other._line) { return true; } if (other._line < this._line) { return false; } return this._character <= other._character; } isAfter(other: Position): boolean { return !this.isBeforeOrEqual(other); } isAfterOrEqual(other: Position): boolean { return !this.isBefore(other); } isEqual(other: Position): boolean { return this._line === other._line && this._character === other._character; } compareTo(other: Position): number { if (this._line < other._line) { return -1; } else if (this._line > other.line) { return 1; } else { // equal line if (this._character < other._character) { return -1; } else if (this._character > other._character) { return 1; } else { // equal line and character return 0; } } } translate(change: { lineDelta?: number; characterDelta?: number; }): Position; translate(lineDelta?: number, characterDelta?: number): Position; translate(lineDeltaOrChange: number | { lineDelta?: number; characterDelta?: number; } | undefined, characterDelta: number = 0): Position { if (lineDeltaOrChange === null || characterDelta === null) { throw illegalArgument(); } let lineDelta: number; if (typeof lineDeltaOrChange === 'undefined') { lineDelta = 0; } else if (typeof lineDeltaOrChange === 'number') { lineDelta = lineDeltaOrChange; } else { lineDelta = typeof lineDeltaOrChange.lineDelta === 'number' ? lineDeltaOrChange.lineDelta : 0; characterDelta = typeof lineDeltaOrChange.characterDelta === 'number' ? lineDeltaOrChange.characterDelta : 0; } if (lineDelta === 0 && characterDelta === 0) { return this; } return new Position(this.line + lineDelta, this.character + characterDelta); } with(change: { line?: number; character?: number; }): Position; with(line?: number, character?: number): Position; with(lineOrChange: number | { line?: number; character?: number; } | undefined, character: number = this.character): Position { if (lineOrChange === null || character === null) { throw illegalArgument(); } let line: number; if (typeof lineOrChange === 'undefined') { line = this.line; } else if (typeof lineOrChange === 'number') { line = lineOrChange; } else { line = typeof lineOrChange.line === 'number' ? lineOrChange.line : this.line; character = typeof lineOrChange.character === 'number' ? lineOrChange.character : this.character; } if (line === this.line && character === this.character) { return this; } return new Position(line, character); } static Min(...positions: Position[]): Position { let result = positions.pop(); for (const p of positions) { if (p.isBefore(result!)) { result = p; } } return result!; } static Max(...positions: Position[]): Position { let result = positions.pop(); for (const p of positions) { if (p.isAfter(result!)) { result = p; } } return result!; } static isPosition(other: unknown): other is Position { if (!other) { return false; } if (typeof other !== 'object' || Array.isArray(other)) { return false; } if (other instanceof Position) { return true; } const { line, character } = other; if (typeof line === 'number' && typeof character === 'number') { return true; } return false; } toJSON(): unknown { return { line: this.line, character: this.character }; } } @es5ClassCompat export class Range { protected _start: Position; protected _end: Position; constructor(start: Position, end: Position); constructor(startLine: number, startColumn: number, endLine: number, endColumn: number); constructor(startLineOrStart: number | Position, startColumnOrEnd: number | Position, endLine?: number, endColumn?: number) { let start: Position | undefined = undefined; let end: Position | undefined = undefined; if (typeof startLineOrStart === 'number' && typeof startColumnOrEnd === 'number' && typeof endLine === 'number' && typeof endColumn === 'number') { start = new Position(startLineOrStart, startColumnOrEnd); end = new Position(endLine, endColumn); } else if (startLineOrStart instanceof Position && startColumnOrEnd instanceof Position) { start = startLineOrStart; end = startColumnOrEnd; } if (!start || !end) { throw new Error('Invalid arguments'); } if (start.isBefore(end)) { this._start = start; this._end = end; } else { this._start = end; this._end = start; } } get start(): Position { return this._start; } get end(): Position { return this._end; } contains(positionOrRange: Position | Range): boolean { if (positionOrRange instanceof Range) { return this.contains(positionOrRange._start) && this.contains(positionOrRange._end); } else if (positionOrRange instanceof Position) { if (positionOrRange.isBefore(this._start)) { return false; } if (this._end.isBefore(positionOrRange)) { return false; } return true; } return false; } isEqual(other: Range): boolean { return this._start.isEqual(other._start) && this._end.isEqual(other._end); } intersection(other: Range): Range | undefined { const start = Position.Max(other.start, this._start); const end = Position.Min(other.end, this._end); if (start.isAfter(end)) { // this happens when there is no overlap: // |-----| // |----| return undefined; } return new Range(start, end); } union(other: Range): Range { if (this.contains(other)) { return this; } else if (other.contains(this)) { return other; } const start = Position.Min(other.start, this._start); const end = Position.Max(other.end, this.end); return new Range(start, end); } get isEmpty(): boolean { return this._start.isEqual(this._end); } get isSingleLine(): boolean { return this._start.line === this._end.line; } with(change: { start?: Position, end?: Position }): Range; with(start?: Position, end?: Position): Range; with(startOrChange: Position | { start?: Position, end?: Position } | undefined, end: Position = this.end): Range { if (startOrChange === null || end === null) { throw illegalArgument(); } let start: Position; if (!startOrChange) { start = this.start; } else if (Position.isPosition(startOrChange)) { start = startOrChange; } else { start = startOrChange.start || this.start; end = startOrChange.end || this.end; } if (start.isEqual(this._start) && end.isEqual(this.end)) { return this; } return new Range(start, end); } static isRange(arg: unknown): arg is theia.Range { if (arg instanceof Range) { return true; } return isObject(arg) && Position.isPosition(arg.start) && Position.isPosition(arg.end); } toJSON(): unknown { return [this.start, this.end]; } } @es5ClassCompat export class Selection extends Range { private _anchor: Position; private _active: Position; constructor(anchor: Position, active: Position); constructor(anchorLine: number, anchorColumn: number, activeLine: number, activeColumn: number); constructor(anchorLineOrAnchor: number | Position, anchorColumnOrActive: number | Position, activeLine?: number, activeColumn?: number) { let anchor: Position | undefined = undefined; let active: Position | undefined = undefined; if (typeof anchorLineOrAnchor === 'number' && typeof anchorColumnOrActive === 'number' && typeof activeLine === 'number' && typeof activeColumn === 'number') { anchor = new Position(anchorLineOrAnchor, anchorColumnOrActive); active = new Position(activeLine, activeColumn); } else if (anchorLineOrAnchor instanceof Position && anchorColumnOrActive instanceof Position) { anchor = anchorLineOrAnchor; active = anchorColumnOrActive; } if (!anchor || !active) { throw new Error('Invalid arguments'); } super(anchor, active); this._anchor = anchor; this._active = active; } get active(): Position { return this._active; } get anchor(): Position { return this._anchor; } get isReversed(): boolean { return this._anchor === this._end; } } export namespace TextDocumentShowOptions { /** * @param candidate * @returns `true` if `candidate` is an instance of options that includes a selection. * This function should be used to determine whether TextDocumentOptions passed into commands by plugins * need to be translated to TextDocumentShowOptions in the style of the RPC model. Selection is the only field that requires translation. */ export function isTextDocumentShowOptions(candidate: unknown): candidate is theia.TextDocumentShowOptions { if (!candidate) { return false; } const options = candidate as theia.TextDocumentShowOptions; return Range.isRange(options.selection); } } export enum EndOfLine { LF = 1, CRLF = 2 } export enum EnvironmentVariableMutatorType { Replace = 1, Append = 2, Prepend = 3 } @es5ClassCompat export class SnippetString { static isSnippetString(thing: {}): thing is SnippetString { if (thing instanceof SnippetString) { return true; } if (!thing) { return false; } return typeof (thing).value === 'string'; } private static _escape(value: string): string { return value.replace(/\$|}|\\/g, '\\$&'); } private _tabstop: number = 1; value: string; constructor(value?: string) { this.value = value || ''; } appendText(string: string): SnippetString { this.value += SnippetString._escape(string); return this; } appendTabstop(number: number = this._tabstop++): SnippetString { this.value += '$'; this.value += number; return this; } appendPlaceholder(value: string | ((snippet: SnippetString) => void), number: number = this._tabstop++): SnippetString { if (typeof value === 'function') { const nested = new SnippetString(); nested._tabstop = this._tabstop; value(nested); this._tabstop = nested._tabstop; value = nested.value; } else { value = SnippetString._escape(value); } this.value += '${'; this.value += number; this.value += ':'; this.value += value; this.value += '}'; return this; } appendChoice(values: string[], number: number = this._tabstop++): SnippetString { const value = values.map(s => s.replace(/\$|}|\\|,/g, '\\$&')).join(','); this.value += `\$\{${number}|${value}|\}`; return this; } appendVariable(name: string, defaultValue?: string | ((snippet: SnippetString) => void)): SnippetString { if (typeof defaultValue === 'function') { const nested = new SnippetString(); nested._tabstop = this._tabstop; defaultValue(nested); this._tabstop = nested._tabstop; defaultValue = nested.value; } else if (typeof defaultValue === 'string') { defaultValue = defaultValue.replace(/\$|}/g, '\\$&'); } this.value += '${'; this.value += name; if (defaultValue) { this.value += ':'; this.value += defaultValue; } this.value += '}'; return this; } } @es5ClassCompat export class ThemeColor { constructor(public readonly id: string) { } } @es5ClassCompat export class ThemeIcon { static readonly File: ThemeIcon = new ThemeIcon('file'); static readonly Folder: ThemeIcon = new ThemeIcon('folder'); private constructor(public id: string, public color?: ThemeColor) { } } export namespace ThemeIcon { export function is(item: unknown): item is ThemeIcon { return isObject(item) && 'id' in item; } export function get(item: unknown): ThemeIcon | undefined { return is(item) ? item : undefined; } } export enum TextEditorRevealType { Default = 0, InCenter = 1, InCenterIfOutsideViewport = 2, AtTop = 3 } /** * These values match very carefully the values of `TrackedRangeStickiness` */ export enum DecorationRangeBehavior { /** * TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges */ OpenOpen = 0, /** * TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges */ ClosedClosed = 1, /** * TrackedRangeStickiness.GrowsOnlyWhenTypingBefore */ OpenClosed = 2, /** * TrackedRangeStickiness.GrowsOnlyWhenTypingAfter */ ClosedOpen = 3 } /** * Vertical Lane in the overview ruler of the editor. */ export enum OverviewRulerLane { Left = 1, Center = 2, Right = 4, Full = 7 } export enum ConfigurationTarget { Global = 1, Workspace, WorkspaceFolder, Default, Memory } @es5ClassCompat export class RelativePattern { private _base!: string; get base(): string { return this._base; } set base(base: string) { this._base = base; this._baseUri = URI.file(base); } private _baseUri!: URI; get baseUri(): URI { return this._baseUri; } set baseUri(baseUri: URI) { this._baseUri = baseUri; this.base = baseUri.fsPath; } constructor(base: theia.WorkspaceFolder | URI | string, public pattern: string) { if (typeof base !== 'string') { if (!base || !URI.isUri(base) && !URI.isUri(base.uri)) { throw illegalArgument('base'); } } if (typeof pattern !== 'string') { throw illegalArgument('pattern'); } if (typeof base === 'string') { this.baseUri = URI.file(base); } else if (URI.isUri(base)) { this.baseUri = base; } else { this.baseUri = base.uri; } } pathToRelative(from: string, to: string): string { return relative(from, to); } } export enum IndentAction { None = 0, Indent = 1, IndentOutdent = 2, Outdent = 3 } export namespace SyntaxTokenType { export function toString(v: SyntaxTokenType | unknown): 'other' | 'comment' | 'string' | 'regex' { switch (v) { case SyntaxTokenType.Other: return 'other'; case SyntaxTokenType.Comment: return 'comment'; case SyntaxTokenType.String: return 'string'; case SyntaxTokenType.RegEx: return 'regex'; } return 'other'; } } export enum SyntaxTokenType { /** * Everything except tokens that are part of comments, string literals and regular expressions. */ Other = 0, /** * A comment. */ Comment = 1, /** * A string literal. */ String = 2, /** * A regular expression. */ RegEx = 3 } @es5ClassCompat export class TextEdit { protected _range: Range; protected _newText: string; protected _newEol: EndOfLine | undefined; get range(): Range { return this._range; } set range(value: Range) { if (value && !Range.isRange(value)) { throw illegalArgument('range'); } this._range = value; } get newText(): string { return this._newText || ''; } set newText(value: string) { if (value && typeof value !== 'string') { throw illegalArgument('newText'); } this._newText = value; } get newEol(): EndOfLine | undefined { return this._newEol; } set newEol(value: EndOfLine) { if (value && typeof value !== 'number') { throw illegalArgument('newEol'); } this._newEol = value; } constructor(range: Range | undefined, newText: string | undefined) { this.range = range!; this.newText = newText!; } static isTextEdit(thing: {}): thing is TextEdit { if (thing instanceof TextEdit) { return true; } if (!thing) { return false; } return Range.isRange((thing).range) && typeof (thing).newText === 'string'; } static replace(range: Range, newText: string): TextEdit { return new TextEdit(range, newText); } static insert(position: Position, newText: string): TextEdit { return TextEdit.replace(new Range(position, position), newText); } static delete(range: Range): TextEdit { return TextEdit.replace(range, ''); } static setEndOfLine(eol: EndOfLine): TextEdit { const ret = new TextEdit(undefined, undefined); ret.newEol = eol; return ret; } } export enum CompletionTriggerKind { Invoke = 0, TriggerCharacter = 1, TriggerForIncompleteCompletions = 2 } export enum CompletionItemKind { Text = 0, Method = 1, Function = 2, Constructor = 3, Field = 4, Variable = 5, Class = 6, Interface = 7, Module = 8, Property = 9, Unit = 10, Value = 11, Enum = 12, Keyword = 13, Snippet = 14, Color = 15, // eslint-disable-line @typescript-eslint/no-shadow File = 16, Reference = 17, Folder = 18, EnumMember = 19, Constant = 20, Struct = 21, Event = 22, Operator = 23, TypeParameter = 24, User = 25, Issue = 26 } @es5ClassCompat export class CompletionItem implements theia.CompletionItem { label: string; kind?: CompletionItemKind; tags?: CompletionItemTag[]; detail: string; documentation: string | theia.MarkdownString; sortText: string; filterText: string; preselect: boolean; insertText: string | SnippetString; range: Range; textEdit: TextEdit; additionalTextEdits: TextEdit[]; command: theia.Command; constructor(label: string, kind?: CompletionItemKind) { this.label = label; this.kind = kind; } } @es5ClassCompat export class CompletionList { isIncomplete?: boolean; items: theia.CompletionItem[]; constructor(items: theia.CompletionItem[] = [], isIncomplete: boolean = false) { this.items = items; this.isIncomplete = isIncomplete; } } export enum InlineCompletionTriggerKind { Invoke = 0, Automatic = 1, } @es5ClassCompat export class InlineCompletionItem implements theia.InlineCompletionItem { filterText?: string; insertText: string; range?: Range; command?: theia.Command; constructor(insertText: string, range?: Range, command?: theia.Command) { this.insertText = insertText; this.range = range; this.command = command; } } @es5ClassCompat export class InlineCompletionList implements theia.InlineCompletionList { items: theia.InlineCompletionItem[]; commands: theia.Command[] | undefined = undefined; constructor(items: theia.InlineCompletionItem[]) { this.items = items; } } export enum DiagnosticSeverity { Error = 0, Warning = 1, Information = 2, Hint = 3 } export enum DebugConsoleMode { Separate = 0, MergeWithParent = 1 } @es5ClassCompat export class Location { uri: URI; range: Range; constructor(uri: URI, rangeOrPosition: Range | Position | undefined) { this.uri = uri; if (rangeOrPosition instanceof Range) { this.range = rangeOrPosition; } else if (rangeOrPosition instanceof Position) { this.range = new Range(rangeOrPosition, rangeOrPosition); } } static isLocation(thing: {}): thing is theia.Location { if (thing instanceof Location) { return true; } if (!thing) { return false; } return Range.isRange((thing).range) && URI.isUri((thing).uri); } } @es5ClassCompat export class DiagnosticRelatedInformation { location: Location; message: string; constructor(location: Location, message: string) { this.location = location; this.message = message; } } export enum DiagnosticTag { Unnecessary = 1, Deprecated = 2, } export enum CompletionItemTag { Deprecated = 1, } @es5ClassCompat export class Diagnostic { range: Range; message: string; severity: DiagnosticSeverity; source?: string; code?: string | number; relatedInformation?: DiagnosticRelatedInformation[]; tags?: DiagnosticTag[]; constructor(range: Range, message: string, severity: DiagnosticSeverity = DiagnosticSeverity.Error) { this.range = range; this.message = message; this.severity = severity; } } export enum MarkerSeverity { Hint = 1, Info = 2, Warning = 4, Error = 8, } export enum MarkerTag { Unnecessary = 1, Deprecated = 2, } export enum NotebookCellKind { Markup = 1, Code = 2 } export enum NotebookCellStatusBarAlignment { Left = 1, Right = 2 } export enum NotebookControllerAffinity { Default = 1, Preferred = 2 } export enum NotebookEditorRevealType { Default = 0, InCenter = 1, InCenterIfOutsideViewport = 2, AtTop = 3 } export enum NotebookCellExecutionState { /** * The cell is idle. */ Idle = 1, /** * Execution for the cell is pending. */ Pending = 2, /** * The cell is currently executing. */ Executing = 3, } export class NotebookKernelSourceAction { description?: string; detail?: string; command?: theia.Command; constructor( public label: string ) { } } @es5ClassCompat export class NotebookCellData implements theia.NotebookCellData { languageId: string; kind: NotebookCellKind; value: string; outputs?: theia.NotebookCellOutput[]; // eslint-disable-next-line @typescript-eslint/no-explicit-any metadata?: { [key: string]: any }; executionSummary?: theia.NotebookCellExecutionSummary; constructor(kind: NotebookCellKind, value: string, languageId: string, outputs?: theia.NotebookCellOutput[], metadata?: Record, executionSummary?: theia.NotebookCellExecutionSummary) { this.kind = kind; this.value = value; this.languageId = languageId; this.outputs = outputs ?? []; this.metadata = metadata; this.executionSummary = executionSummary; } } @es5ClassCompat export class NotebookCellOutput implements theia.NotebookCellOutput { outputId: string; items: theia.NotebookCellOutputItem[]; // eslint-disable-next-line @typescript-eslint/no-explicit-any metadata?: { [key: string]: any }; // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(items: theia.NotebookCellOutputItem[], idOrMetadata?: string | Record, metadata?: { [key: string]: any }) { this.items = items; if (typeof idOrMetadata === 'string') { this.outputId = idOrMetadata; this.metadata = metadata; } else { this.outputId = UUID.uuid4(); this.metadata = idOrMetadata ?? metadata; } } } export class NotebookCellOutputItem implements theia.NotebookCellOutputItem { mime: string; data: Uint8Array; static #encoder = new TextEncoder(); static text(value: string, mime?: string): NotebookCellOutputItem { const bytes = NotebookCellOutputItem.#encoder.encode(String(value)); return new NotebookCellOutputItem(bytes, mime || 'text/plain'); } // eslint-disable-next-line @typescript-eslint/no-explicit-any static json(value: any, mime?: string): NotebookCellOutputItem { const jsonStr = JSON.stringify(value, undefined, '\t'); return NotebookCellOutputItem.text(jsonStr, mime); } static stdout(value: string): NotebookCellOutputItem { return NotebookCellOutputItem.text(value, 'application/vnd.code.notebook.stdout'); } static stderr(value: string): NotebookCellOutputItem { return NotebookCellOutputItem.text(value, 'application/vnd.code.notebook.stderr'); } static error(value: Error): NotebookCellOutputItem { return NotebookCellOutputItem.json(value, 'application/vnd.code.notebook.error'); } constructor(data: Uint8Array, mime: string) { this.data = data; this.mime = mime; } } @es5ClassCompat export class NotebookCellStatusBarItem implements theia.NotebookCellStatusBarItem { text: string; alignment: NotebookCellStatusBarAlignment; command?: string | theia.Command; tooltip?: string; priority?: number; accessibilityInformation?: AccessibilityInformation; /** * Creates a new NotebookCellStatusBarItem. * @param text The text to show for the item. * @param alignment Whether the item is aligned to the left or right. * @stubbed */ constructor(text: string, alignment: NotebookCellStatusBarAlignment) { this.text = text; this.alignment = alignment; } } @es5ClassCompat export class NotebookData implements theia.NotebookData { cells: NotebookCellData[]; // eslint-disable-next-line @typescript-eslint/no-explicit-any metadata?: { [key: string]: any }; constructor(cells: NotebookCellData[]) { this.cells = cells; } } export class NotebookRange implements theia.NotebookRange { static isNotebookRange(thing: unknown): thing is theia.NotebookRange { if (thing instanceof NotebookRange) { return true; } if (!thing) { return false; } return typeof (thing).start === 'number' && typeof (thing).end === 'number'; } readonly start: number; readonly end: number; readonly isEmpty: boolean; with(change: { start?: number; end?: number }): NotebookRange { let newStart = this.start; let newEnd = this.end; if (change.start !== undefined) { newStart = change.start; } if (change.end !== undefined) { newEnd = change.end; } if (newStart === this.start && newEnd === this.end) { return this; } return new NotebookRange(newStart, newEnd); } constructor(start: number, end: number) { this.start = start; this.end = end; } } export class SnippetTextEdit implements theia.SnippetTextEdit { range: Range; snippet: SnippetString; keepWhitespace?: boolean; static isSnippetTextEdit(thing: unknown): thing is SnippetTextEdit { return thing instanceof SnippetTextEdit || isObject(thing) && Range.isRange((thing).range) && SnippetString.isSnippetString((thing).snippet); } static replace(range: Range, snippet: SnippetString): SnippetTextEdit { return new SnippetTextEdit(range, snippet); } static insert(position: Position, snippet: SnippetString): SnippetTextEdit { return SnippetTextEdit.replace(new Range(position, position), snippet); } constructor(range: Range, snippet: SnippetString) { this.range = range; this.snippet = snippet; } } @es5ClassCompat export class NotebookEdit implements theia.NotebookEdit { range: theia.NotebookRange; newCells: theia.NotebookCellData[]; // eslint-disable-next-line @typescript-eslint/no-explicit-any newCellMetadata?: { [key: string]: any; } | undefined; // eslint-disable-next-line @typescript-eslint/no-explicit-any newNotebookMetadata?: { [key: string]: any; } | undefined; static isNotebookCellEdit(thing: unknown): thing is NotebookEdit { if (thing instanceof NotebookEdit) { return true; } if (!thing) { return false; } return NotebookRange.isNotebookRange((thing)) && Array.isArray((thing).newCells); } static replaceCells(range: NotebookRange, newCells: NotebookCellData[]): NotebookEdit { return new NotebookEdit(range, newCells); } static insertCells(index: number, newCells: NotebookCellData[]): NotebookEdit { return new NotebookEdit(new NotebookRange(index, index), newCells); } static deleteCells(range: NotebookRange): NotebookEdit { return new NotebookEdit(range, []); } // eslint-disable-next-line @typescript-eslint/no-explicit-any static updateCellMetadata(index: number, newCellMetadata: { [key: string]: any }): NotebookEdit { return new NotebookEdit(new NotebookRange(index, index), [], newCellMetadata); } // eslint-disable-next-line @typescript-eslint/no-explicit-any static updateNotebookMetadata(newNotebookMetadata: { [key: string]: any }): NotebookEdit { return new NotebookEdit(new NotebookRange(0, 0), [], undefined, newNotebookMetadata); } constructor(range: NotebookRange, newCells: NotebookCellData[], newCellMetadata?: { [key: string]: unknown }, newNotebookMetadata?: { [key: string]: unknown }) { this.range = range; this.newCells = newCells; this.newCellMetadata = newCellMetadata; this.newNotebookMetadata = newNotebookMetadata; } } export class NotebookRendererScript implements theia.NotebookRendererScript { provides: readonly string[]; constructor( public uri: theia.Uri, provides?: string | readonly string[] ) { this.provides = Array.isArray(provides) ? provides : [provides]; }; } @es5ClassCompat export class ParameterInformation { label: string | [number, number]; documentation?: string | theia.MarkdownString; constructor(label: string | [number, number], documentation?: string | theia.MarkdownString) { this.label = label; this.documentation = documentation; } } @es5ClassCompat export class SignatureInformation { label: string; documentation?: string | theia.MarkdownString; parameters: ParameterInformation[]; activeParameter?: number; constructor(label: string, documentation?: string | theia.MarkdownString) { this.label = label; this.documentation = documentation; this.parameters = []; } } export enum SignatureHelpTriggerKind { Invoke = 1, TriggerCharacter = 2, ContentChange = 3, } @es5ClassCompat export class SignatureHelp { signatures: SignatureInformation[]; activeSignature: number; activeParameter: number; constructor() { this.signatures = []; } } @es5ClassCompat export class Hover { public contents: Array; public range?: Range; constructor( contents: theia.MarkdownString | theia.MarkedString | Array, range?: Range ) { if (!contents) { illegalArgument('contents must be defined'); } if (Array.isArray(contents)) { this.contents = contents; } else { this.contents = [contents]; } this.range = range; } } @es5ClassCompat export class VerboseHover extends Hover { public canIncreaseVerbosity: boolean | undefined; public canDecreaseVerbosity: boolean | undefined; constructor( contents: theia.MarkdownString | theia.MarkedString | (theia.MarkdownString | theia.MarkedString)[], range?: Range, canIncreaseVerbosity?: boolean, canDecreaseVerbosity?: boolean, ) { super(contents, range); this.canIncreaseVerbosity = canIncreaseVerbosity; this.canDecreaseVerbosity = canDecreaseVerbosity; } } export enum HoverVerbosityAction { Increase = 0, Decrease = 1 } @es5ClassCompat export class EvaluatableExpression { public range: Range; public expression?: string; constructor( range: Range, expression?: string ) { if (!range) { illegalArgument('range must be defined'); } this.range = range; this.expression = expression; } } @es5ClassCompat export class InlineValueContext implements theia.InlineValueContext { public frameId: number; public stoppedLocation: Range; constructor(frameId: number, stoppedLocation: Range) { if (!frameId) { illegalArgument('frameId must be defined'); } if (!stoppedLocation) { illegalArgument('stoppedLocation must be defined'); } this.frameId = frameId; this.stoppedLocation = stoppedLocation; } } @es5ClassCompat export class InlineValueText implements theia.InlineValueText { public type = 'text'; public range: Range; public text: string; constructor(range: Range, text: string) { if (!range) { illegalArgument('range must be defined'); } if (!text) { illegalArgument('text must be defined'); } this.range = range; this.text = text; } } @es5ClassCompat export class InlineValueVariableLookup implements theia.InlineValueVariableLookup { public type = 'variable'; public range: Range; public variableName?: string; public caseSensitiveLookup: boolean; constructor(range: Range, variableName?: string, caseSensitiveLookup?: boolean) { if (!range) { illegalArgument('range must be defined'); } this.range = range; this.caseSensitiveLookup = caseSensitiveLookup || true; this.variableName = variableName; } } @es5ClassCompat export class InlineValueEvaluatableExpression implements theia.InlineValueEvaluatableExpression { public type = 'expression'; public range: Range; public expression?: string; constructor(range: Range, expression?: string) { if (!range) { illegalArgument('range must be defined'); } this.range = range; this.expression = expression; } } export type InlineValue = InlineValueText | InlineValueVariableLookup | InlineValueEvaluatableExpression; export enum DocumentHighlightKind { Text = 0, Read = 1, Write = 2 } @es5ClassCompat export class DocumentHighlight { public range: Range; public kind?: DocumentHighlightKind; constructor( range: Range, kind?: DocumentHighlightKind ) { this.range = range; this.kind = kind; } } @es5ClassCompat export class MultiDocumentHighlight { /** * The URI of the document containing the highlights. */ uri: URI; /** * The highlights for the document. */ highlights: DocumentHighlight[]; /** * Creates a new instance of MultiDocumentHighlight. * @param uri The URI of the document containing the highlights. * @param highlights The highlights for the document. */ constructor(uri: URI, highlights: DocumentHighlight[]) { this.uri = uri; this.highlights = highlights; } } export type Definition = Location | Location[]; @es5ClassCompat export class DocumentLink { range: Range; target?: URI; tooltip?: string; constructor(range: Range, target: URI | undefined) { if (target && !(URI.isUri(target))) { throw illegalArgument('target'); } if (!Range.isRange(range) || range.isEmpty) { throw illegalArgument('range'); } this.range = range; this.target = target; } } @es5ClassCompat export class DocumentDropOrPasteEditKind { static readonly Empty: DocumentDropOrPasteEditKind = new DocumentDropOrPasteEditKind(''); static readonly Text: DocumentDropOrPasteEditKind = new DocumentDropOrPasteEditKind('text'); static readonly TextUpdateImports: DocumentDropOrPasteEditKind = new DocumentDropOrPasteEditKind('updateImports'); private static sep = '.'; constructor( public readonly value: string ) { } public append(...parts: string[]): DocumentDropOrPasteEditKind { return new DocumentDropOrPasteEditKind((this.value ? [this.value, ...parts] : parts).join(DocumentDropOrPasteEditKind.sep)); } public intersects(other: DocumentDropOrPasteEditKind): boolean { return this.contains(other) || other.contains(this); } public contains(other: DocumentDropOrPasteEditKind): boolean { return this.value === other.value || other.value.startsWith(this.value + DocumentDropOrPasteEditKind.sep); } } @es5ClassCompat export class DocumentDropEdit { title?: string; kind: DocumentDropOrPasteEditKind; handledMimeType?: string; yieldTo?: ReadonlyArray; insertText: string | SnippetString; additionalEdit?: WorkspaceEdit; constructor(insertText: string | SnippetString) { this.insertText = insertText; } } @es5ClassCompat export class CodeLens { range: Range; command?: theia.Command; get isResolved(): boolean { return !!this.command; } constructor(range: Range, command?: theia.Command) { this.range = range; this.command = command; } } export enum CodeActionTrigger { Automatic = 1, Manual = 2, } /** * The reason why code actions were requested. */ export enum CodeActionTriggerKind { /** * Code actions were explicitly requested by the user or by an extension. */ Invoke = 1, /** * Code actions were requested automatically. * * This typically happens when current selection in a file changes, but can * also be triggered when file content changes. */ Automatic = 2, } @es5ClassCompat export class CodeActionKind { private static readonly sep = '.'; public static readonly Empty = new CodeActionKind(''); public static readonly QuickFix = CodeActionKind.Empty.append('quickfix'); public static readonly Refactor = CodeActionKind.Empty.append('refactor'); public static readonly RefactorExtract = CodeActionKind.Refactor.append('extract'); public static readonly RefactorInline = CodeActionKind.Refactor.append('inline'); public static readonly RefactorMove = CodeActionKind.Refactor.append('move'); public static readonly RefactorRewrite = CodeActionKind.Refactor.append('rewrite'); public static readonly Source = CodeActionKind.Empty.append('source'); public static readonly SourceOrganizeImports = CodeActionKind.Source.append('organizeImports'); public static readonly SourceFixAll = CodeActionKind.Source.append('fixAll'); public static readonly Notebook = CodeActionKind.Empty.append('notebook'); constructor( public readonly value: string ) { } public append(parts: string): CodeActionKind { return new CodeActionKind(this.value ? this.value + CodeActionKind.sep + parts : parts); } public contains(other: CodeActionKind): boolean { return this.value === other.value || startsWithIgnoreCase(other.value, this.value + CodeActionKind.sep); } public intersects(other: CodeActionKind): boolean { return this.contains(other) || other.contains(this); } } export enum TextDocumentSaveReason { Manual = 1, AfterDelay = 2, FocusOut = 3 } @es5ClassCompat export class CodeAction { title: string; command?: theia.Command; edit?: WorkspaceEdit; diagnostics?: Diagnostic[]; kind?: CodeActionKind; disabled?: { reason: string }; isPreferred?: boolean; constructor(title: string, kind?: CodeActionKind) { this.title = title; this.kind = kind; } } export interface FileOperationOptions { overwrite?: boolean; ignoreIfExists?: boolean; ignoreIfNotExists?: boolean; recursive?: boolean; } // copied from https://github.com/microsoft/vscode/blob/b165e20587dd0797f37251515bc9e4dbe513ede8/src/vs/editor/common/modes.ts export interface WorkspaceEditMetadata { needsConfirmation: boolean; label: string; description?: string; iconPath?: { light: URI; dark: URI; } | ThemeIcon; } export const enum FileEditType { File = 1, Text = 2, // eslint-disable-next-line @typescript-eslint/no-shadow Cell = 3, CellReplace = 5, Snippet = 6, } export interface FileOperation { _type: FileEditType.File; from: URI | undefined; to: URI | undefined; options?: FileOperationOptions; metadata?: WorkspaceEditMetadata; } export interface FileTextEdit { _type: FileEditType.Text; uri: URI; edit: TextEdit; metadata?: WorkspaceEditMetadata; } export interface FileSnippetTextEdit { readonly _type: FileEditType.Snippet; readonly uri: URI; readonly range: Range; readonly edit: SnippetTextEdit; readonly metadata?: theia.WorkspaceEditEntryMetadata; } export interface FileCellEdit { readonly _type: FileEditType.Cell; readonly uri: URI; readonly edit?: CellMetadataEdit | NotebookDocumentMetadataEdit; readonly notebookMetadata?: Record; readonly metadata?: theia.WorkspaceEditEntryMetadata; } export interface CellEdit { readonly _type: FileEditType.CellReplace; readonly metadata?: theia.WorkspaceEditEntryMetadata; readonly uri: URI; readonly index: number; readonly count: number; readonly cells: theia.NotebookCellData[]; } type WorkspaceEditEntry = FileOperation | FileTextEdit | FileSnippetTextEdit | FileCellEdit | CellEdit | undefined; @es5ClassCompat export class WorkspaceEdit implements theia.WorkspaceEdit { private _edits = new Array(); renameFile(from: theia.Uri, to: theia.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }, metadata?: WorkspaceEditMetadata): void { this._edits.push({ _type: 1, from, to, options, metadata }); } createFile(uri: theia.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }, metadata?: WorkspaceEditMetadata): void { this._edits.push({ _type: 1, from: undefined, to: uri, options, metadata }); } deleteFile(uri: theia.Uri, options?: { recursive?: boolean, ignoreIfNotExists?: boolean }, metadata?: WorkspaceEditMetadata): void { this._edits.push({ _type: 1, from: uri, to: undefined, options, metadata }); } replace(uri: URI, range: Range, newText: string, metadata?: WorkspaceEditMetadata): void { this._edits.push({ _type: 2, uri, edit: new TextEdit(range, newText), metadata }); } insert(resource: URI, position: Position, newText: string, metadata?: WorkspaceEditMetadata): void { this.replace(resource, new Range(position, position), newText, metadata); } delete(resource: URI, range: Range, metadata?: WorkspaceEditMetadata): void { this.replace(resource, range, '', metadata); } has(uri: URI): boolean { for (const edit of this._edits) { if (edit && edit._type === 2 && edit.uri.toString() === uri.toString()) { return true; } } return false; } set(uri: URI, edits: ReadonlyArray): void; set(uri: URI, edits: ReadonlyArray<[TextEdit | SnippetTextEdit, theia.WorkspaceEditEntryMetadata | undefined]>): void; set(uri: URI, edits: ReadonlyArray): void; set(uri: URI, edits: ReadonlyArray<[NotebookEdit, theia.WorkspaceEditEntryMetadata | undefined]>): void; set(uri: URI, edits: ReadonlyArray): void { if (!edits) { // remove all text edits for `uri` for (let i = 0; i < this._edits.length; i++) { const element = this._edits[i]; if (element && (element._type === FileEditType.Text || element._type === FileEditType.Snippet) && element.uri.toString() === uri.toString()) { this._edits[i] = undefined; } } this._edits = this._edits.filter(e => !!e); } else { // append edit to the end for (const editOrTuple of edits) { if (!editOrTuple) { continue; } let edit: TextEdit | SnippetTextEdit | NotebookEdit; let metadata: theia.WorkspaceEditEntryMetadata | undefined; if (Array.isArray(editOrTuple)) { edit = editOrTuple[0]; metadata = editOrTuple[1]; } else { edit = editOrTuple; } if (NotebookEdit.isNotebookCellEdit(edit)) { if (edit.newCellMetadata) { this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Metadata, index: edit.range.start, metadata: edit.newCellMetadata } }); } else if (edit.newNotebookMetadata) { this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.DocumentMetadata, metadata: edit.newNotebookMetadata }, notebookMetadata: edit.newNotebookMetadata }); } else { const start = edit.range.start; const end = edit.range.end; if (start !== end || edit.newCells.length > 0) { this._edits.push({ _type: FileEditType.CellReplace, uri, index: start, count: end - start, cells: edit.newCells, metadata }); } } } else if (SnippetTextEdit.isSnippetTextEdit(edit)) { this._edits.push({ _type: FileEditType.Snippet, uri, range: edit.range, edit, metadata }); } else { this._edits.push({ _type: FileEditType.Text, uri, edit }); } } } } get(uri: URI): TextEdit[] { const res: TextEdit[] = []; for (const candidate of this._edits) { if (candidate && candidate._type === 2 && candidate.uri.toString() === uri.toString()) { res.push(candidate.edit); } } if (res.length === 0) { return undefined!; } return res; } entries(): [URI, TextEdit[]][] { const textEdits = new Map(); for (const candidate of this._edits) { if (candidate && candidate._type === FileEditType.Text) { let textEdit = textEdits.get(candidate.uri.toString()); if (!textEdit) { textEdit = [candidate.uri, []]; textEdits.set(candidate.uri.toString(), textEdit); } textEdit[1].push(candidate.edit); } } const result: [URI, TextEdit[]][] = []; textEdits.forEach(v => result.push(v)); return result; } // _allEntries(): ([URI, Array, theia.WorkspaceEditEntryMetadata] | [URI, URI, FileOperationOptions, WorkspaceEditMetadata])[] { // const res: ([URI, Array, theia.WorkspaceEditEntryMetadata] | [URI, URI, FileOperationOptions, WorkspaceEditMetadata])[] = []; // for (const edit of this._edits) { // if (!edit) { // continue; // } // if (edit._type === FileEditType.File) { // res.push([edit.from!, edit.to!, edit.options!, edit.metadata!]); // } else { // res.push([edit.uri, [edit.edit], edit.metadata!]); // } // } // return res; // } _allEntries(): ReadonlyArray { return this._edits; } get size(): number { return this.entries().length; } // eslint-disable-next-line @typescript-eslint/no-explicit-any toJSON(): any { return this.entries(); } } export class DataTransferItem { asString(): Thenable { return Promise.resolve(typeof this.value === 'string' ? this.value : JSON.stringify(this.value)); } asFile(): theia.DataTransferFile | undefined { return undefined; } // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(readonly value: any) { } } /** * A map containing a mapping of the mime type of the corresponding transferred data. * * Drag and drop controllers that implement {@link TreeDragAndDropController.handleDrag `handleDrag`} can add additional mime types to the * data transfer. These additional mime types will only be included in the `handleDrop` when the the drag was initiated from * an element in the same drag and drop controller. */ @es5ClassCompat export class DataTransfer implements Iterable<[mimeType: string, item: DataTransferItem]> { private items = new Map(); get(mimeType: string): DataTransferItem | undefined { return this.items.get(mimeType); } set(mimeType: string, value: DataTransferItem): void { this.items.set(mimeType, value); } has(mimeType: string): boolean { return this.items.has(mimeType); } // eslint-disable-next-line @typescript-eslint/no-explicit-any forEach(callbackfn: (item: DataTransferItem, mimeType: string, dataTransfer: DataTransfer) => void, thisArg?: any): void { this.items.forEach((item, mimetype) => { callbackfn.call(thisArg, item, mimetype, this); }); } [Symbol.iterator](): IterableIterator<[mimeType: string, item: DataTransferItem]> { return this.items[Symbol.iterator](); } clear(): void { this.items.clear(); } } @es5ClassCompat export class TreeItem { label?: string | theia.TreeItemLabel; id?: string; iconPath?: string | URI | { light: string | URI; dark: string | URI } | ThemeIcon; resourceUri?: URI; tooltip?: string | undefined; command?: theia.Command; contextValue?: string; checkboxState?: theia.TreeItemCheckboxState | { readonly state: theia.TreeItemCheckboxState; readonly tooltip?: string; readonly accessibilityInformation?: AccessibilityInformation }; constructor(label: string | theia.TreeItemLabel, collapsibleState?: theia.TreeItemCollapsibleState); constructor(resourceUri: URI, collapsibleState?: theia.TreeItemCollapsibleState); constructor(arg1: string | theia.TreeItemLabel | URI, public collapsibleState: theia.TreeItemCollapsibleState = TreeItemCollapsibleState.None) { if (arg1 instanceof URI) { this.resourceUri = arg1; } else { this.label = arg1; } } } export enum TreeItemCollapsibleState { None = 0, Collapsed = 1, Expanded = 2 } export enum TreeItemCheckboxState { Unchecked = 0, Checked = 1 } export enum SymbolTag { Deprecated = 1 } @es5ClassCompat export class SymbolInformation { static validate(candidate: SymbolInformation): void { if (!candidate.name) { throw new Error('Should provide a name inside candidate field'); } } name: string; location: Location; kind: SymbolKind; tags?: SymbolTag[]; containerName: undefined | string; constructor(name: string, kind: SymbolKind, containerName: string, location: Location); constructor(name: string, kind: SymbolKind, range: Range, uri?: URI, containerName?: string); constructor(name: string, kind: SymbolKind, rangeOrContainer: string | Range, locationOrUri?: Location | URI, containerName?: string) { this.name = name; this.kind = kind; this.containerName = containerName; if (typeof rangeOrContainer === 'string') { this.containerName = rangeOrContainer; } if (locationOrUri instanceof Location) { this.location = locationOrUri; } else if (rangeOrContainer instanceof Range) { this.location = new Location(locationOrUri!, rangeOrContainer); } SymbolInformation.validate(this); } // eslint-disable-next-line @typescript-eslint/no-explicit-any toJSON(): any { return { name: this.name, kind: SymbolKind[this.kind], location: this.location, containerName: this.containerName }; } } @es5ClassCompat export class DocumentSymbol { static validate(candidate: DocumentSymbol): void { if (!candidate.name) { throw new Error('Should provide a name inside candidate field'); } if (!candidate.range.contains(candidate.selectionRange)) { throw new Error('selectionRange must be contained in fullRange'); } if (candidate.children) { candidate.children.forEach(DocumentSymbol.validate); } } name: string; detail: string; kind: SymbolKind; tags?: SymbolTag[]; range: Range; selectionRange: Range; children: DocumentSymbol[]; constructor(name: string, detail: string, kind: SymbolKind, range: Range, selectionRange: Range) { this.name = name; this.detail = detail; this.kind = kind; this.range = range; this.selectionRange = selectionRange; this.children = []; DocumentSymbol.validate(this); } } export enum CommentThreadState { Unresolved = 0, Resolved = 1 } export enum CommentThreadCollapsibleState { Collapsed = 0, Expanded = 1 } export enum QuickInputButtonLocation { Title = 1, Inline = 2, Input = 3 } @es5ClassCompat export class QuickInputButtons { static readonly Back: theia.QuickInputButton = { iconPath: { id: 'Back', }, tooltip: 'Back' }; } @es5ClassCompat export class TerminalLink { static validate(candidate: TerminalLink): void { if (typeof candidate.startIndex !== 'number') { throw new Error('Should provide a startIndex inside candidate field'); } if (typeof candidate.length !== 'number') { throw new Error('Should provide a length inside candidate field'); } } startIndex: number; length: number; tooltip?: string; constructor(startIndex: number, length: number, tooltip?: string) { this.startIndex = startIndex; this.length = length; this.tooltip = tooltip; } } export enum TerminalLocation { Panel = 1, Editor = 2 } export enum TerminalOutputAnchor { Top = 0, Bottom = 1 } export class TerminalProfile { /** * Creates a new terminal profile. * @param options The options that the terminal will launch with. */ constructor(readonly options: theia.TerminalOptions | theia.ExtensionTerminalOptions) { } } export enum TerminalExitReason { Unknown = 0, Shutdown = 1, Process = 2, User = 3, Extension = 4, } @es5ClassCompat export class FileDecoration { static validate(d: FileDecoration): void { if (d.badge && d.badge.length !== 1 && d.badge.length !== 2) { throw new Error('The \'badge\'-property must be undefined or a short character'); } if (!d.color && !d.badge && !d.tooltip) { throw new Error('The decoration is empty'); } } badge?: string; tooltip?: string; color?: theia.ThemeColor; priority?: number; propagate?: boolean; constructor(badge?: string, tooltip?: string, color?: ThemeColor) { this.badge = badge; this.tooltip = tooltip; this.color = color; } } export enum CommentMode { Editing = 0, Preview = 1 } // #region file api export enum FileChangeType { Changed = 1, Created = 2, Deleted = 3, } @es5ClassCompat export class FileSystemError extends Error { static FileExists(messageOrUri?: string | URI): FileSystemError { return new FileSystemError(messageOrUri, FileSystemProviderErrorCode.FileExists, FileSystemError.FileExists); } static FileNotFound(messageOrUri?: string | URI): FileSystemError { return new FileSystemError(messageOrUri, FileSystemProviderErrorCode.FileNotFound, FileSystemError.FileNotFound); } static FileNotADirectory(messageOrUri?: string | URI): FileSystemError { return new FileSystemError(messageOrUri, FileSystemProviderErrorCode.FileNotADirectory, FileSystemError.FileNotADirectory); } static FileIsADirectory(messageOrUri?: string | URI): FileSystemError { return new FileSystemError(messageOrUri, FileSystemProviderErrorCode.FileIsADirectory, FileSystemError.FileIsADirectory); } static NoPermissions(messageOrUri?: string | URI): FileSystemError { return new FileSystemError(messageOrUri, FileSystemProviderErrorCode.NoPermissions, FileSystemError.NoPermissions); } static Unavailable(messageOrUri?: string | URI): FileSystemError { return new FileSystemError(messageOrUri, FileSystemProviderErrorCode.Unavailable, FileSystemError.Unavailable); } readonly code: string; constructor(uriOrMessage?: string | URI, code: FileSystemProviderErrorCode = FileSystemProviderErrorCode.Unknown, terminator?: Function) { super(URI.isUri(uriOrMessage) ? uriOrMessage.toString(true) : uriOrMessage); this.code = terminator?.name ?? 'Unknown'; // mark the error as file system provider error so that // we can extract the error code on the receiving side markAsFileSystemProviderError(this, code); // workaround when extending builtin objects and when compiling to ES5, see: // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work if (typeof Object.setPrototypeOf === 'function') { Object.setPrototypeOf(this, FileSystemError.prototype); } if (typeof Error.captureStackTrace === 'function' && typeof terminator === 'function') { // nice stack traces Error.captureStackTrace(this, terminator); } } } // #endregion export enum FileType { Unknown = 0, File = 1, Directory = 2, SymbolicLink = 64 } export interface FileStat { readonly type: FileType; readonly ctime: number; readonly mtime: number; readonly size: number; } @es5ClassCompat export class ProgressOptions { /** * The location at which progress should show. */ location: ProgressLocation; /** * A human-readable string which will be used to describe the * operation. */ title?: string; /** * Controls if a cancel button should show to allow the user to * cancel the long running operation. Note that currently only * `ProgressLocation.Notification` is supporting to show a cancel * button. */ cancellable?: boolean; constructor(location: ProgressLocation, title?: string, cancellable?: boolean) { this.location = location; } } @es5ClassCompat export class Progress { /** * Report a progress update. * @param value A progress item, like a message and/or an * report on how much work finished */ report(value: T): void { } } export enum ProgressLocation { /** * Show progress for the source control viewlet, as overlay for the icon and as progress bar * inside the viewlet (when visible). Neither supports cancellation nor discrete progress. */ SourceControl = 1, /** * Show progress in the status bar of the editor. Neither supports cancellation nor discrete progress. */ Window = 10, /** * Show progress as notification with an optional cancel button. Supports to show infinite and discrete progress. */ Notification = 15 } @es5ClassCompat export class ProcessExecution { private executionProcess: string; private arguments: string[]; private executionOptions: theia.ProcessExecutionOptions | undefined; constructor(process: string, options?: theia.ProcessExecutionOptions); constructor(process: string, args: string[], options?: theia.ProcessExecutionOptions); constructor(process: string, varg1?: string[] | theia.ProcessExecutionOptions, varg2?: theia.ProcessExecutionOptions) { if (typeof process !== 'string') { throw illegalArgument('process'); } this.executionProcess = process; if (varg1 !== undefined) { if (Array.isArray(varg1)) { this.arguments = varg1; this.executionOptions = varg2; } else { this.executionOptions = varg1; } } if (this.arguments === undefined) { this.arguments = []; } } get process(): string { return this.executionProcess; } set process(value: string) { if (typeof value !== 'string') { throw illegalArgument('process'); } this.executionProcess = value; } get args(): string[] { return this.arguments; } set args(value: string[]) { if (!Array.isArray(value)) { value = []; } this.arguments = value; } get options(): theia.ProcessExecutionOptions | undefined { return this.executionOptions; } set options(value: theia.ProcessExecutionOptions | undefined) { this.executionOptions = value; } public static is(value: theia.ShellExecution | theia.ProcessExecution | theia.CustomExecution): value is ProcessExecution { const candidate = value as ProcessExecution; return candidate && !!candidate.process; } } export enum QuickPickItemKind { Separator = -1, Default = 0, } export enum ShellQuoting { Escape = 1, Strong = 2, Weak = 3 } export enum TaskPanelKind { Shared = 1, Dedicated = 2, New = 3 } export enum TaskRevealKind { Always = 1, Silent = 2, Never = 3 } @es5ClassCompat export class ShellExecution { private shellCommandLine: string; private shellCommand: string | theia.ShellQuotedString; private arguments: (string | theia.ShellQuotedString)[]; private shellOptions: theia.ShellExecutionOptions | undefined; constructor(commandLine: string, options?: theia.ShellExecutionOptions); constructor(command: string | theia.ShellQuotedString, args: (string | theia.ShellQuotedString)[], options?: theia.ShellExecutionOptions); constructor(arg0: string | theia.ShellQuotedString, arg1?: theia.ShellExecutionOptions | (string | theia.ShellQuotedString)[], arg2?: theia.ShellExecutionOptions) { if (Array.isArray(arg1) || typeof arg1 === 'string') { if (!arg0) { throw illegalArgument('command can\'t be undefined or null'); } if (typeof arg0 !== 'string' && typeof arg0.value !== 'string') { throw illegalArgument('command'); } this.shellCommand = arg0; this.arguments = arg1 as (string | theia.ShellQuotedString)[]; this.shellOptions = arg2; } else { if (typeof arg0 !== 'string') { throw illegalArgument('commandLine'); } this.shellCommandLine = arg0; this.shellOptions = arg1; } } get commandLine(): string { return this.shellCommandLine; } set commandLine(value: string) { if (typeof value !== 'string') { throw illegalArgument('commandLine'); } this.shellCommandLine = value; } get command(): string | theia.ShellQuotedString { return this.shellCommand; } set command(value: string | theia.ShellQuotedString) { if (typeof value !== 'string' && typeof value.value !== 'string') { throw illegalArgument('command'); } this.shellCommand = value; } get args(): (string | theia.ShellQuotedString)[] { return this.arguments; } set args(value: (string | theia.ShellQuotedString)[]) { this.arguments = value || []; } get options(): theia.ShellExecutionOptions | undefined { return this.shellOptions; } set options(value: theia.ShellExecutionOptions | undefined) { this.shellOptions = value; } public static is(value: theia.ShellExecution | theia.ProcessExecution | theia.CustomExecution): value is ShellExecution { const candidate = value as ShellExecution; return candidate && (!!candidate.commandLine || !!candidate.command); } } @es5ClassCompat export class CustomExecution { private _callback: (resolvedDefinition: theia.TaskDefinition) => Thenable; constructor(callback: (resolvedDefinition: theia.TaskDefinition) => Thenable) { this._callback = callback; } public set callback(value: (resolvedDefinition: theia.TaskDefinition) => Thenable) { this._callback = value; } public get callback(): ((resolvedDefinition: theia.TaskDefinition) => Thenable) { return this._callback; } public static is(value: theia.ShellExecution | theia.ProcessExecution | theia.CustomExecution): value is CustomExecution { const candidate = value as CustomExecution; return candidate && (!!candidate._callback); } } @es5ClassCompat export class TaskGroup { public static Clean: TaskGroup = new TaskGroup('clean', 'Clean'); public static Build: TaskGroup = new TaskGroup('build', 'Build'); public static Rebuild: TaskGroup = new TaskGroup('rebuild', 'Rebuild'); public static Test: TaskGroup = new TaskGroup('test', 'Test'); public static from(value: string): TaskGroup | undefined { switch (value) { case 'clean': return TaskGroup.Clean; case 'build': return TaskGroup.Build; case 'rebuild': return TaskGroup.Rebuild; case 'test': return TaskGroup.Test; default: return undefined; } } constructor(id: 'clean' | 'build' | 'rebuild' | 'test', label: string); constructor(id: 'clean' | 'build' | 'rebuild' | 'test', label: string, isDefault?: boolean | undefined); constructor(readonly id: 'clean' | 'build' | 'rebuild' | 'test', label: string, isDefault?: boolean | undefined) { this.isDefault = !!isDefault; } readonly isDefault: boolean; } export enum TaskScope { Global = 1, Workspace = 2 } @es5ClassCompat export class Task { private taskDefinition: theia.TaskDefinition; private taskScope: theia.TaskScope.Global | theia.TaskScope.Workspace | theia.WorkspaceFolder | undefined; private taskName: string; private taskExecution: ProcessExecution | ShellExecution | CustomExecution | undefined; private taskProblemMatchers: string[]; private hasTaskProblemMatchers: boolean; private isTaskBackground: boolean; private taskSource: string; private taskGroup: TaskGroup | undefined; private taskPresentationOptions: theia.TaskPresentationOptions; private taskRunOptions: theia.RunOptions; constructor( taskDefinition: theia.TaskDefinition, scope: theia.WorkspaceFolder | theia.TaskScope.Global | theia.TaskScope.Workspace, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution, problemMatchers?: string | string[] ); // Deprecated constructor used by Jake vscode built-in constructor( taskDefinition: theia.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution, problemMatchers?: string | string[], ); // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(...args: any[]) { let taskDefinition: theia.TaskDefinition; let scope: theia.WorkspaceFolder | theia.TaskScope.Global | theia.TaskScope.Workspace | undefined; let name: string; let source: string; let execution: ProcessExecution | ShellExecution | CustomExecution | undefined; let problemMatchers: string | string[] | undefined; if (typeof args[1] === 'string') { [ taskDefinition, name, source, execution, problemMatchers, ] = args; } else { [ taskDefinition, scope, name, source, execution, problemMatchers, ] = args; } this.definition = taskDefinition; this.scope = scope; this.name = name; this.source = source; this.execution = execution; if (typeof problemMatchers === 'string') { this.taskProblemMatchers = [problemMatchers]; this.hasTaskProblemMatchers = true; } else if (Array.isArray(problemMatchers)) { this.taskProblemMatchers = problemMatchers; this.hasTaskProblemMatchers = true; } else { this.taskProblemMatchers = []; this.hasTaskProblemMatchers = false; } this.isTaskBackground = false; this.presentationOptions = Object.create(null); this.taskRunOptions = Object.create(null); } get definition(): theia.TaskDefinition { return this.taskDefinition; } set definition(value: theia.TaskDefinition) { if (value === undefined || value === null) { throw illegalArgument('Kind can\'t be undefined or null'); } this.taskDefinition = value; } get scope(): theia.TaskScope.Global | theia.TaskScope.Workspace | theia.WorkspaceFolder | undefined { return this.taskScope; } set scope(value: theia.TaskScope.Global | theia.TaskScope.Workspace | theia.WorkspaceFolder | undefined) { if (value === null) { value = undefined; } this.taskScope = value; } get name(): string { return this.taskName; } set name(value: string) { if (typeof value !== 'string') { throw illegalArgument('name'); } this.taskName = value; } get execution(): ProcessExecution | ShellExecution | CustomExecution | undefined { return this.taskExecution; } set execution(value: ProcessExecution | ShellExecution | CustomExecution | undefined) { if (value === null) { value = undefined; } this.taskExecution = value; } get problemMatchers(): string[] { return this.taskProblemMatchers; } set problemMatchers(value: string[]) { if (!Array.isArray(value)) { this.taskProblemMatchers = []; this.hasTaskProblemMatchers = false; return; } this.taskProblemMatchers = value; this.hasTaskProblemMatchers = true; } get hasProblemMatchers(): boolean { return this.hasTaskProblemMatchers; } get isBackground(): boolean { return this.isTaskBackground; } set isBackground(value: boolean) { if (value !== true && value !== false) { value = false; } this.isTaskBackground = value; } get source(): string { return this.taskSource; } set source(value: string) { if (typeof value !== 'string' || value.length === 0) { throw illegalArgument('source must be a string of length > 0'); } this.taskSource = value; } get group(): TaskGroup | undefined { return this.taskGroup; } set group(value: TaskGroup | undefined) { if (value === undefined || value === null) { this.taskGroup = undefined; return; } this.taskGroup = value; } get presentationOptions(): theia.TaskPresentationOptions { return this.taskPresentationOptions; } set presentationOptions(value: theia.TaskPresentationOptions) { if (value === null || value === undefined) { value = Object.create(null); } this.taskPresentationOptions = value; } get runOptions(): theia.RunOptions { return this.taskRunOptions; } set runOptions(value: theia.RunOptions) { if (value === null || value === undefined) { value = Object.create(null); } this.taskRunOptions = value; } } @es5ClassCompat export class Task2 extends Task { } @es5ClassCompat export class DebugAdapterExecutable { /** * The command or path of the debug adapter executable. * A command must be either an absolute path of an executable or the name of an command to be looked up via the PATH environment variable. * The special value 'node' will be mapped to VS Code's built-in Node.js runtime. */ readonly command: string; /** * The arguments passed to the debug adapter executable. Defaults to an empty array. */ readonly args?: string[]; /** * Optional options to be used when the debug adapter is started. * Defaults to undefined. */ readonly options?: theia.DebugAdapterExecutableOptions; /** * Creates a description for a debug adapter based on an executable program. * * @param command The command or executable path that implements the debug adapter. * @param args Optional arguments to be passed to the command or executable. * @param options Optional options to be used when starting the command or executable. */ constructor(command: string, args?: string[], options?: theia.DebugAdapterExecutableOptions) { this.command = command; this.args = args; this.options = options; } } export namespace DebugAdapterExecutable { export function is(adapter: theia.DebugAdapterDescriptor | undefined): adapter is theia.DebugAdapterExecutable { return !!adapter && 'command' in adapter; } } /** * Represents a debug adapter running as a socket based server. */ @es5ClassCompat export class DebugAdapterServer { /** * The port. */ readonly port: number; /** * The host. */ readonly host?: string; /** * Create a description for a debug adapter running as a socket based server. */ constructor(port: number, host?: string) { this.port = port; this.host = host; } } export namespace DebugAdapterServer { export function is(adapter: theia.DebugAdapterDescriptor | undefined): adapter is DebugAdapterServer { return !!adapter && 'port' in adapter; } } /** * Represents a debug adapter running as a Named Pipe (on Windows)/UNIX Domain Socket (on non-Windows) based server. */ @es5ClassCompat export class DebugAdapterNamedPipeServer { /** * Create a description for a debug adapter running as a Named Pipe (on Windows)/UNIX Domain Socket (on non-Windows) based server. */ constructor(readonly path: string) { } } export namespace DebugAdapterNamedPipeServer { export function is(adapter: theia.DebugAdapterDescriptor | undefined): adapter is DebugAdapterNamedPipeServer { return !!adapter && 'path' in adapter; } } /** * A debug adapter descriptor for an inline implementation. */ @es5ClassCompat export class DebugAdapterInlineImplementation { implementation: theia.DebugAdapter; /** * Create a descriptor for an inline implementation of a debug adapter. */ constructor(impl: theia.DebugAdapter) { this.implementation = impl; } } export namespace DebugAdapterInlineImplementation { export function is(adapter: theia.DebugAdapterDescriptor | undefined): adapter is DebugAdapterInlineImplementation { return !!adapter && 'implementation' in adapter; } } export type DebugAdapterDescriptor = DebugAdapterExecutable | DebugAdapterServer | DebugAdapterNamedPipeServer | DebugAdapterInlineImplementation; export enum LogLevel { Off = 0, Trace = 1, Debug = 2, Info = 3, Warning = 4, Error = 5 } /** * The base class of all breakpoint types. */ @es5ClassCompat export class Breakpoint { /** * Is breakpoint enabled. */ enabled: boolean; /** * An optional expression for conditional breakpoints. */ condition?: string; /** * An optional expression that controls how many hits of the breakpoint are ignored. */ hitCondition?: string; /** * An optional message that gets logged when this breakpoint is hit. Embedded expressions within {} are interpolated by the debug adapter. */ logMessage?: string; protected constructor(enabled?: boolean, condition?: string, hitCondition?: string, logMessage?: string, id?: string) { this.enabled = enabled || false; this.condition = condition; this.hitCondition = hitCondition; this.logMessage = logMessage; this._id = id; } private _id: string | undefined; /** * The unique ID of the breakpoint. */ get id(): string { if (!this._id) { this._id = UUID.uuid4(); } return this._id; } } /** * A breakpoint specified by a source location. */ @es5ClassCompat export class SourceBreakpoint extends Breakpoint { /** * The source and line position of this breakpoint. */ location: Location; /** * Create a new breakpoint for a source location. */ constructor(location: Location, enabled?: boolean, condition?: string, hitCondition?: string, logMessage?: string, id?: string) { super(enabled, condition, hitCondition, logMessage, id); this.location = location; } } /** * A breakpoint specified by a function name. */ @es5ClassCompat export class FunctionBreakpoint extends Breakpoint { /** * The name of the function to which this breakpoint is attached. */ functionName: string; /** * Create a new function breakpoint. */ constructor(functionName: string, enabled?: boolean, condition?: string, hitCondition?: string, logMessage?: string, id?: string) { super(enabled, condition, hitCondition, logMessage, id); this.functionName = functionName; } } export class DebugThread implements theia.DebugThread { constructor(readonly session: theia.DebugSession, readonly threadId: number) { } } export class DebugStackFrame implements theia.DebugStackFrame { constructor(readonly session: theia.DebugSession, readonly threadId: number, readonly frameId: number) { } } @es5ClassCompat export class Color { readonly red: number; readonly green: number; readonly blue: number; readonly alpha: number; constructor(red: number, green: number, blue: number, alpha: number) { this.red = red; this.green = green; this.blue = blue; this.alpha = alpha; } } @es5ClassCompat export class ColorInformation { range: Range; color: Color; constructor(range: Range, color: Color) { if (color && !(color instanceof Color)) { throw illegalArgument('color'); } if (!Range.isRange(range)) { throw illegalArgument('range'); } this.range = range; this.color = color; } } @es5ClassCompat export class ColorPresentation { label: string; textEdit?: TextEdit; additionalTextEdits?: TextEdit[]; constructor(label: string) { if (!label || typeof label !== 'string') { throw illegalArgument('label'); } this.label = label; } } export enum ColorFormat { RGB = 0, HEX = 1, HSL = 2 } @es5ClassCompat export class InlayHintLabelPart implements theia.InlayHintLabelPart { value: string; tooltip?: string | theia.MarkdownString | undefined; location?: Location | undefined; command?: theia.Command | undefined; constructor(value: string) { this.value = value; } } @es5ClassCompat export class InlayHint implements theia.InlayHint { position: theia.Position; label: string | InlayHintLabelPart[]; tooltip?: string | theia.MarkdownString | undefined; kind?: InlayHintKind; textEdits?: TextEdit[]; paddingLeft?: boolean; paddingRight?: boolean; constructor(position: theia.Position, label: string | InlayHintLabelPart[], kind?: InlayHintKind) { this.position = position; this.label = label; this.kind = kind; } } export enum InlayHintKind { Type = 1, Parameter = 2, } @es5ClassCompat export class FoldingRange { start: number; end: number; kind?: FoldingRangeKind; constructor(start: number, end: number, kind?: FoldingRangeKind) { this.start = start; this.end = end; this.kind = kind; } } export enum FoldingRangeKind { Comment = 1, Imports = 2, Region = 3 } @es5ClassCompat export class SelectionRange { range: Range; parent?: SelectionRange; constructor(range: Range, parent?: SelectionRange) { this.range = range; this.parent = parent; if (parent && !parent.range.contains(this.range)) { throw new Error('Invalid argument: parent must contain this range'); } } } /** * Enumeration of the supported operating systems. */ export enum OperatingSystem { Windows = 'Windows', Linux = 'Linux', OSX = 'OSX' } /** The areas of the application shell where webview panel can reside. */ export enum WebviewPanelTargetArea { Main = 'main', Left = 'left', Right = 'right', Bottom = 'bottom' } /** * Possible kinds of UI that can use extensions. */ export enum UIKind { /** * Extensions are accessed from a desktop application. */ Desktop = 1, /** * Extensions are accessed from a web browser. */ Web = 2 } @es5ClassCompat export class CallHierarchyItem { _sessionId?: string; _itemId?: string; kind: SymbolKind; name: string; detail?: string; uri: URI; range: Range; selectionRange: Range; tags?: readonly SymbolTag[]; constructor(kind: SymbolKind, name: string, detail: string, uri: URI, range: Range, selectionRange: Range) { this.kind = kind; this.name = name; this.detail = detail; this.uri = uri; this.range = range; this.selectionRange = selectionRange; } static isCallHierarchyItem(thing: {}): thing is CallHierarchyItem { if (thing instanceof CallHierarchyItem) { return true; } if (!thing) { return false; } return typeof (thing).kind === 'number' && typeof (thing).name === 'string' && URI.isUri((thing).uri) && Range.isRange((thing).range) && Range.isRange((thing).selectionRange); } } @es5ClassCompat export class CallHierarchyIncomingCall { from: theia.CallHierarchyItem; fromRanges: theia.Range[]; constructor(item: CallHierarchyItem, fromRanges: Range[]) { this.fromRanges = fromRanges; this.from = item; } } @es5ClassCompat export class CallHierarchyOutgoingCall { to: theia.CallHierarchyItem; fromRanges: theia.Range[]; constructor(item: CallHierarchyItem, fromRanges: Range[]) { this.fromRanges = fromRanges; this.to = item; } } @es5ClassCompat export class TypeHierarchyItem { _sessionId?: string; _itemId?: string; kind: SymbolKind; tags?: readonly SymbolTag[]; name: string; detail?: string; uri: URI; range: Range; selectionRange: Range; constructor(kind: SymbolKind, name: string, detail: string, uri: URI, range: Range, selectionRange: Range) { this.kind = kind; this.name = name; this.detail = detail; this.uri = uri; this.range = range; this.selectionRange = selectionRange; } static isTypeHierarchyItem(thing: {}): thing is TypeHierarchyItem { if (thing instanceof TypeHierarchyItem) { return true; } if (!thing) { return false; } return typeof (thing).kind === 'number' && typeof (thing).name === 'string' && URI.isUri((thing).uri) && Range.isRange((thing).range) && Range.isRange((thing).selectionRange); } } export enum LanguageStatusSeverity { Information = 0, Warning = 1, Error = 2 } @es5ClassCompat export class LinkedEditingRanges { ranges: theia.Range[]; wordPattern?: RegExp; constructor(ranges: Range[], wordPattern?: RegExp) { this.ranges = ranges; this.wordPattern = wordPattern; } } // Copied from https://github.com/microsoft/vscode/blob/1.72.2/src/vs/workbench/api/common/extHostTypes.ts export enum TestResultState { Queued = 1, Running = 2, Passed = 3, Failed = 4, Skipped = 5, Errored = 6 } export enum TestRunProfileKind { Run = 1, Debug = 2, Coverage = 3, } @es5ClassCompat export class TestTag implements theia.TestTag { constructor(public readonly id: string) { } } let nextTestRunId = 0; @es5ClassCompat export class TestRunRequest implements theia.TestRunRequest { testRunId: number = nextTestRunId++; constructor( public readonly include: theia.TestItem[] | undefined = undefined, public readonly exclude: theia.TestItem[] | undefined = undefined, public readonly profile: theia.TestRunProfile | undefined = undefined, public readonly continuous: boolean | undefined = undefined, public readonly preserveFocus: boolean = true ) { } } @es5ClassCompat export class TestMessage implements theia.TestMessage { public expectedOutput?: string; public actualOutput?: string; public location?: theia.Location; public contextValue?: string; public stackTrace?: theia.TestMessageStackFrame[] | undefined; public static diff(message: string | theia.MarkdownString, expected: string, actual: string): theia.TestMessage { const msg = new TestMessage(message); msg.expectedOutput = expected; msg.actualOutput = actual; return msg; } constructor(public message: string | theia.MarkdownString) { } } @es5ClassCompat export class TestCoverageCount { constructor(public covered: number, public total: number) { } } export class TestMessageStackFrame implements theia.TestMessageStackFrame { constructor( public label: string, public uri?: theia.Uri, public position?: Position ) { } } @es5ClassCompat export class FileCoverage { detailedCoverage?: theia.FileCoverageDetail[]; static fromDetails(uri: theia.Uri, details: theia.FileCoverageDetail[]): FileCoverage { const statements = new TestCoverageCount(0, 0); const branches = new TestCoverageCount(0, 0); const decl = new TestCoverageCount(0, 0); for (const detail of details) { if (detail instanceof StatementCoverage) { statements.total += 1; statements.covered += detail.executed ? 1 : 0; for (const branch of detail.branches) { branches.total += 1; branches.covered += branch.executed ? 1 : 0; } } else { decl.total += 1; decl.covered += detail.executed ? 1 : 0; } } const coverage = new FileCoverage( uri, statements, branches.total > 0 ? branches : undefined, decl.total > 0 ? decl : undefined, ); coverage.detailedCoverage = details; return coverage; } constructor( public uri: theia.Uri, public statementCoverage: TestCoverageCount, public branchCoverage?: TestCoverageCount, public declarationCoverage?: TestCoverageCount, public includesTests?: theia.TestItem[], ) { } } @es5ClassCompat export class StatementCoverage implements theia.StatementCoverage { constructor(public executed: number | boolean, public location: Position | Range, public branches: BranchCoverage[] = []) { } } export class BranchCoverage implements theia.BranchCoverage { constructor(public executed: number | boolean, public location?: Position | Range, public label?: string) { } } @es5ClassCompat export class DeclarationCoverage implements theia.DeclarationCoverage { constructor(public name: string, public executed: number | boolean, public location: Position | Range) { } } export type FileCoverageDetail = StatementCoverage | DeclarationCoverage; @es5ClassCompat export class TimelineItem { timestamp: number; label: string; id?: string; iconPath?: theia.Uri | { light: theia.Uri; dark: theia.Uri } | ThemeIcon; description?: string; tooltip?: string | theia.MarkdownString | undefined; command?: theia.Command; contextValue?: string; accessibilityInformation?: AccessibilityInformation; constructor(label: string, timestamp: number) { this.label = label; this.timestamp = timestamp; } } // #region Semantic Coloring @es5ClassCompat export class SemanticTokensLegend { public readonly tokenTypes: string[]; public readonly tokenModifiers: string[]; constructor(tokenTypes: string[], tokenModifiers: string[] = []) { this.tokenTypes = tokenTypes; this.tokenModifiers = tokenModifiers; } } function isStrArrayOrUndefined(arg: unknown): arg is string[] | undefined { return typeof arg === 'undefined' || isStringArray(arg); } @es5ClassCompat export class SemanticTokensBuilder { private _prevLine: number; private _prevChar: number; private _dataIsSortedAndDeltaEncoded: boolean; private _data: number[]; private _dataLen: number; private _tokenTypeStrToInt: Map; private _tokenModifierStrToInt: Map; private _hasLegend: boolean; constructor(legend?: SemanticTokensLegend) { this._prevLine = 0; this._prevChar = 0; this._dataIsSortedAndDeltaEncoded = true; this._data = []; this._dataLen = 0; this._tokenTypeStrToInt = new Map(); this._tokenModifierStrToInt = new Map(); this._hasLegend = false; if (legend) { this._hasLegend = true; for (let i = 0, len = legend.tokenTypes.length; i < len; i++) { this._tokenTypeStrToInt.set(legend.tokenTypes[i], i); } for (let i = 0, len = legend.tokenModifiers.length; i < len; i++) { this._tokenModifierStrToInt.set(legend.tokenModifiers[i], i); } } } public push(line: number, char: number, length: number, tokenType: number, tokenModifiers?: number): void; public push(range: Range, tokenType: string, tokenModifiers?: string[]): void; public push(arg0: number | Range, arg1: number | string, arg2?: number | string[], arg3?: number, arg4?: number): void { if (typeof arg0 === 'number' && typeof arg1 === 'number' && typeof arg2 === 'number' && typeof arg3 === 'number' && (typeof arg4 === 'number' || typeof arg4 === 'undefined')) { if (typeof arg4 === 'undefined') { arg4 = 0; } // 1st overload return this._pushEncoded(arg0, arg1, arg2, arg3, arg4); } if (Range.isRange(arg0) && typeof arg1 === 'string' && isStrArrayOrUndefined(arg2)) { // 2nd overload return this._push(arg0, arg1, arg2); } throw illegalArgument(); } private _push(range: theia.Range, tokenType: string, tokenModifiers?: string[]): void { if (!this._hasLegend) { throw new Error('Legend must be provided in constructor'); } if (range.start.line !== range.end.line) { throw new Error('`range` cannot span multiple lines'); } if (!this._tokenTypeStrToInt.has(tokenType)) { throw new Error('`tokenType` is not in the provided legend'); } const line = range.start.line; const char = range.start.character; const length = range.end.character - range.start.character; const nTokenType = this._tokenTypeStrToInt.get(tokenType)!; let nTokenModifiers = 0; if (tokenModifiers) { for (const tokenModifier of tokenModifiers) { if (!this._tokenModifierStrToInt.has(tokenModifier)) { throw new Error('`tokenModifier` is not in the provided legend'); } const nTokenModifier = this._tokenModifierStrToInt.get(tokenModifier)!; nTokenModifiers |= (1 << nTokenModifier) >>> 0; } } this._pushEncoded(line, char, length, nTokenType, nTokenModifiers); } private _pushEncoded(line: number, char: number, length: number, tokenType: number, tokenModifiers: number): void { if (this._dataIsSortedAndDeltaEncoded && (line < this._prevLine || (line === this._prevLine && char < this._prevChar))) { // push calls were ordered and are no longer ordered this._dataIsSortedAndDeltaEncoded = false; // Remove delta encoding from data const tokenCount = (this._data.length / 5) | 0; let prevLine = 0; let prevChar = 0; for (let i = 0; i < tokenCount; i++) { // eslint-disable-next-line @typescript-eslint/no-shadow let line = this._data[5 * i]; // eslint-disable-next-line @typescript-eslint/no-shadow let char = this._data[5 * i + 1]; if (line === 0) { // on the same line as previous token line = prevLine; char += prevChar; } else { // on a different line than previous token line += prevLine; } this._data[5 * i] = line; this._data[5 * i + 1] = char; prevLine = line; prevChar = char; } } let pushLine = line; let pushChar = char; if (this._dataIsSortedAndDeltaEncoded && this._dataLen > 0) { pushLine -= this._prevLine; if (pushLine === 0) { pushChar -= this._prevChar; } } this._data[this._dataLen++] = pushLine; this._data[this._dataLen++] = pushChar; this._data[this._dataLen++] = length; this._data[this._dataLen++] = tokenType; this._data[this._dataLen++] = tokenModifiers; this._prevLine = line; this._prevChar = char; } private static _sortAndDeltaEncode(data: number[]): Uint32Array { const pos: number[] = []; const tokenCount = (data.length / 5) | 0; for (let i = 0; i < tokenCount; i++) { pos[i] = i; } pos.sort((a, b) => { const aLine = data[5 * a]; const bLine = data[5 * b]; if (aLine === bLine) { const aChar = data[5 * a + 1]; const bChar = data[5 * b + 1]; return aChar - bChar; } return aLine - bLine; }); const result = new Uint32Array(data.length); let prevLine = 0; let prevChar = 0; for (let i = 0; i < tokenCount; i++) { const srcOffset = 5 * pos[i]; const line = data[srcOffset + 0]; const char = data[srcOffset + 1]; const length = data[srcOffset + 2]; const tokenType = data[srcOffset + 3]; const tokenModifiers = data[srcOffset + 4]; const pushLine = line - prevLine; const pushChar = (pushLine === 0 ? char - prevChar : char); const dstOffset = 5 * i; result[dstOffset + 0] = pushLine; result[dstOffset + 1] = pushChar; result[dstOffset + 2] = length; result[dstOffset + 3] = tokenType; result[dstOffset + 4] = tokenModifiers; prevLine = line; prevChar = char; } return result; } public build(resultId?: string): SemanticTokens { if (!this._dataIsSortedAndDeltaEncoded) { return new SemanticTokens(SemanticTokensBuilder._sortAndDeltaEncode(this._data), resultId); } return new SemanticTokens(new Uint32Array(this._data), resultId); } } @es5ClassCompat export class SemanticTokens { readonly resultId: string | undefined; readonly data: Uint32Array; constructor(data: Uint32Array, resultId?: string) { this.resultId = resultId; this.data = data; } } @es5ClassCompat export class SemanticTokensEdit { readonly start: number; readonly deleteCount: number; readonly data: Uint32Array | undefined; constructor(start: number, deleteCount: number, data?: Uint32Array) { this.start = start; this.deleteCount = deleteCount; this.data = data; } } @es5ClassCompat export class SemanticTokensEdits { readonly resultId: string | undefined; readonly edits: SemanticTokensEdit[]; constructor(edits: SemanticTokensEdit[], resultId?: string) { this.resultId = resultId; this.edits = edits; } } export enum InputBoxValidationSeverity { Info = 1, Warning = 2, Error = 3 } // #endregion // #region Tab Inputs export class TextTabInput { constructor(readonly uri: URI) { } } export class TextDiffTabInput { constructor(readonly original: URI, readonly modified: URI) { } } export class TextMergeTabInput { constructor(readonly base: URI, readonly input1: URI, readonly input2: URI, readonly result: URI) { } } export class CustomEditorTabInput { constructor(readonly uri: URI, readonly viewType: string) { } } export class WebviewEditorTabInput { constructor(readonly viewType: string) { } } export class TelemetryTrustedValue { readonly value: T; constructor(value: T) { this.value = value; } } export class TelemetryLogger { readonly onDidChangeEnableStates: theia.Event; readonly isUsageEnabled: boolean; readonly isErrorsEnabled: boolean; // eslint-disable-next-line @typescript-eslint/no-explicit-any logUsage(eventName: string, data?: Record>): void { } // eslint-disable-next-line @typescript-eslint/no-explicit-any logError(eventNameOrError: string | Error, data?: Record>): void { } dispose(): void { } constructor(readonly sender: TelemetrySender, readonly options?: TelemetryLoggerOptions) { } } export interface TelemetrySender { // eslint-disable-next-line @typescript-eslint/no-explicit-any sendEventData(eventName: string, data?: Record): void; // eslint-disable-next-line @typescript-eslint/no-explicit-any sendErrorData(error: Error, data?: Record): void; flush?(): void | Thenable; } export interface TelemetryLoggerOptions { /** * Whether or not you want to avoid having the built-in common properties such as os, extension name, etc injected into the data object. * Defaults to `false` if not defined. */ readonly ignoreBuiltInCommonProperties?: boolean; /** * Whether or not unhandled errors on the extension host caused by your extension should be logged to your sender. * Defaults to `false` if not defined. */ readonly ignoreUnhandledErrors?: boolean; /** * Any additional common properties which should be injected into the data object. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly additionalCommonProperties?: Record; } export class NotebookEditorTabInput { constructor(readonly uri: URI, readonly notebookType: string) { } } export class NotebookDiffEditorTabInput { constructor(readonly original: URI, readonly modified: URI, readonly notebookType: string) { } } export class TerminalEditorTabInput { constructor() { } } export class InteractiveWindowInput { constructor(readonly uri: URI, readonly inputBoxUri: URI) { } } // #endregion // #region DocumentPaste export class DocumentPasteEditKind { static Empty: DocumentPasteEditKind; static Text: DocumentPasteEditKind; static TextUpdateImports: DocumentPasteEditKind; constructor(public readonly value: string) { } /** @stubbed */ append(...parts: string[]): CodeActionKind { return CodeActionKind.Empty; }; /** @stubbed */ intersects(other: CodeActionKind): boolean { return false; } /** @stubbed */ contains(other: CodeActionKind): boolean { return false; } } DocumentPasteEditKind.Empty = new DocumentPasteEditKind(''); DocumentPasteEditKind.Text = new DocumentDropOrPasteEditKind('text'); DocumentPasteEditKind.TextUpdateImports = DocumentDropOrPasteEditKind.Text.append('updateImports'); @es5ClassCompat export class DocumentPasteEdit { constructor(insertText: string | SnippetString, title: string, kind: DocumentDropOrPasteEditKind) { this.insertText = insertText; this.title = title; this.kind = kind; } title: string; kind: DocumentDropOrPasteEditKind; insertText: string | SnippetString; additionalEdit?: WorkspaceEdit; yieldTo?: ReadonlyArray; } /** * The reason why paste edits were requested. */ export enum DocumentPasteTriggerKind { /** * Pasting was requested as part of a normal paste operation. */ Automatic = 0, /** * Pasting was requested by the user with the `paste as` command. */ PasteAs = 1, } // #endregion // #region DocumentPaste export enum EditSessionIdentityMatch { Complete = 100, Partial = 50, None = 0 } // #endregion // #region terminalCompletionProvider export class TerminalCompletionList { resourceOptions?: theia.TerminalCompletionResourceOptions; items: T[]; /** * Creates a new completion list. * * @param items The completion items. * @param resourceOptions Indicates which resources should be shown as completions for the cwd of the terminal. */ constructor(items: T[], resourceOptions?: theia.TerminalCompletionResourceOptions) { } } export class TerminalCompletionItem { label: string | theia.CompletionItemLabel; replacementRange: readonly [number, number]; detail?: string; documentation?: string | theia.MarkdownString; kind?: TerminalCompletionItemKind; /** * @stubbed */ constructor( label: string | theia.CompletionItemLabel, replacementRange: readonly [number, number], kind?: TerminalCompletionItemKind ) { } } export enum TerminalCompletionItemKind { File = 0, Folder = 1, Method = 2, Alias = 3, Argument = 4, Option = 5, OptionValue = 6, Flag = 7, SymbolicLinkFile = 8, SymbolicLinkFolder = 9, ScmCommit = 10, ScmBranch = 11, ScmTag = 12, ScmStash = 13, ScmRemote = 14, PullRequest = 15, PullRequestDone = 16, } // #endregion // #region terminalQuickFixProvider export class TerminalQuickFixTerminalCommand { /** * The terminal command to run */ terminalCommand: string; /** * Whether the command should be executed or just inserted (default) */ shouldExecute?: boolean; /** * @stubbed */ constructor(terminalCommand: string, shouldExecute?: boolean) { } } export class TerminalQuickFixOpener { /** * The uri to open */ uri: theia.Uri; /** * @stubbed */ constructor(uri: theia.Uri) { } } // #region Chat /** * @stubbed */ export class ChatRequestTurn { readonly prompt: string; readonly participant: string; readonly command?: string; readonly references: theia.ChatPromptReference[]; readonly toolReferences: readonly theia.ChatLanguageModelToolReference[]; private constructor(prompt: string, command: string | undefined, references: theia.ChatPromptReference[], participant: string, toolReferences: theia.ChatLanguageModelToolReference[]) { this.prompt = prompt; this.command = command; this.participant = participant; this.references = references; this.toolReferences = toolReferences; }; } /** * @stubbed */ export class ChatResponseTurn { readonly command?: string; private constructor(readonly response: ReadonlyArray, readonly result: theia.ChatResult, readonly participant: string) { } } /** * @stubbed */ export class ChatResponseAnchorPart { value: URI | Location; title?: string; constructor(value: URI | Location, title?: string) { } } /** * @stubbed */ export class ChatResponseProgressPart { value: string; constructor(value: string) { } } /** * @stubbed */ export class ChatResponseReferencePart { value: URI | Location; iconPath?: URI | ThemeIcon | { light: URI; dark: URI; }; constructor(value: URI | theia.Location, iconPath?: URI | ThemeIcon | { light: URI; dark: URI; }) { } } /** * @stubbed */ export class ChatResponseCommandButtonPart { value: theia.Command; constructor(value: theia.Command) { } } /** * @stubbed */ export class ChatResponseMarkdownPart { value: theia.MarkdownString; constructor(value: string | theia.MarkdownString) { } } /** * @stubbed */ export class ChatResponseFileTreePart { value: theia.ChatResponseFileTree[]; baseUri: URI; constructor(value: theia.ChatResponseFileTree[], baseUri: URI) { } } export type ChatResponsePart = ChatResponseMarkdownPart | ChatResponseFileTreePart | ChatResponseAnchorPart | ChatResponseProgressPart | ChatResponseReferencePart | ChatResponseCommandButtonPart; export enum ChatResultFeedbackKind { Unhelpful = 0, Helpful = 1, } export enum LanguageModelChatMessageRole { User = 1, Assistant = 2 } /** * @stubbed */ export class LanguageModelChatMessage { static User(content: string | Array, name?: string): LanguageModelChatMessage { return new LanguageModelChatMessage(LanguageModelChatMessageRole.User, content, name); } static Assistant(content: string | (LanguageModelTextPart | LanguageModelToolResultPart | LanguageModelDataPart)[], name?: string): LanguageModelChatMessage { return new LanguageModelChatMessage(LanguageModelChatMessageRole.Assistant, content, name); } constructor(public role: LanguageModelChatMessageRole, public content: string | LanguageModelInputPart[], public name?: string) { } } /** * The various message types which a {@linkcode LanguageModelChatProvider} can emit in the chat response stream */ export type LanguageModelResponsePart = LanguageModelTextPart | LanguageModelToolResultPart | LanguageModelToolCallPart | LanguageModelDataPart; /** * The various message types which can be sent via {@linkcode LanguageModelChat.sendRequest } and processed by a {@linkcode LanguageModelChatProvider} */ export type LanguageModelInputPart = LanguageModelTextPart | LanguageModelToolResultPart | LanguageModelToolCallPart | LanguageModelDataPart; export class LanguageModelError extends Error { static NoPermissions(message?: string): LanguageModelError { return new LanguageModelError(message, LanguageModelError.NoPermissions.name); } static Blocked(message?: string): LanguageModelError { return new LanguageModelError(message, LanguageModelError.Blocked.name); } static NotFound(message?: string): LanguageModelError { return new LanguageModelError(message, LanguageModelError.NotFound.name); } readonly code: string; constructor(message?: string, code?: string) { super(message); this.name = 'LanguageModelError'; this.code = code ?? ''; } } export enum LanguageModelChatToolMode { Auto = 1, Required = 2 } /** * @stubbed */ export class LanguageModelToolCallPart { callId: string; name: string; input: object; constructor(callId: string, name: string, input: object) { } } /** * @stubbed */ export class LanguageModelToolResultPart { callId: string; content: Array; constructor(callId: string, content: Array) { } } /** * @stubbed */ export class LanguageModelTextPart { value: string; constructor(value: string) { } } /** * @stubbed */ export class LanguageModelToolResult { content: Array; constructor(content: Array) { } } /** * @stubbed */ export class LanguageModelPromptTsxPart { value: unknown; constructor(value: unknown) { } } /** * @stubbed */ export class LanguageModelDataPart { static image(data: Uint8Array, mime: string): LanguageModelDataPart { return new LanguageModelDataPart(data, mime); } // eslint-disable-next-line @typescript-eslint/no-explicit-any static json(value: any, mime: string = 'text/x-json'): LanguageModelDataPart { const rawStr = JSON.stringify(value, undefined, '\t'); return new LanguageModelDataPart(BinaryBuffer.fromString(rawStr).buffer, mime); } static text(value: string, mime: string = 'text/plain'): LanguageModelDataPart { return new LanguageModelDataPart(BinaryBuffer.fromString(value).buffer, mime); } mimeType: string; data: Uint8Array; constructor(data: Uint8Array, mimeType: string) { } } /** * @stubbed */ export interface ProvideLanguageModelChatResponseOptions { // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly modelOptions?: { readonly [name: string]: any }; readonly tools?: readonly theia.LanguageModelChatTool[]; readonly toolMode: LanguageModelChatToolMode; } /** * @stubbed */ export interface LanguageModelChatInformation { readonly id: string; readonly name: string; readonly family: string; readonly tooltip?: string; readonly detail?: string; readonly version: string; readonly maxInputTokens: number; readonly maxOutputTokens: number; readonly capabilities: { readonly imageInput?: boolean; readonly toolCalling?: boolean | number; }; } /** * @stubbed */ export interface LanguageModelChatRequestMessage { readonly role: LanguageModelChatMessageRole; readonly content: ReadonlyArray; readonly name: string | undefined; } /** * @stubbed */ export interface LanguageModelChatProvider { readonly onDidChangeLanguageModelChatInformation?: theia.Event; provideLanguageModelChatInformation(options: PrepareLanguageModelChatModelOptions, token: theia.CancellationToken): theia.ProviderResult; provideLanguageModelChatResponse(model: T, messages: readonly theia.LanguageModelChatRequestMessage[], options: ProvideLanguageModelChatResponseOptions, progress: Progress, token: theia.CancellationToken): Thenable; provideTokenCount(model: T, text: string | LanguageModelChatRequestMessage, token: theia.CancellationToken): Thenable; } /** * @stubbed */ export interface PrepareLanguageModelChatModelOptions { readonly silent: boolean; } // #endregion // #region Port Attributes export enum PortAutoForwardAction { Notify = 1, OpenBrowser = 2, OpenPreview = 3, Silent = 4, Ignore = 5 } export class PortAttributes { constructor(public autoForwardAction: PortAutoForwardAction) { } } // #endregion // #region Debug Visualization export class DebugVisualization { iconPath?: URI | { light: URI; dark: URI } | ThemeIcon; visualization?: theia.Command | { treeId: string }; constructor(public name: string) { } } // #endregion // #region Terminal Shell Integration export enum TerminalShellExecutionCommandLineConfidence { Low = 0, Medium = 1, High = 2 } // #endregion /** * McpStdioServerDefinition represents an MCP server available by running * a local process and operating on its stdin and stdout streams. The process * will be spawned as a child process of the extension host and by default * will not run in a shell environment. */ export class McpStdioServerDefinition { /** * The human-readable name of the server. */ readonly label: string; /** * The working directory used to start the server. */ cwd?: URI; /** * The command used to start the server. Node.js-based servers may use * `process.execPath` to use the editor's version of Node.js to run the script. */ command: string; /** * Additional command-line arguments passed to the server. */ args?: string[]; /** * Optional additional environment information for the server. Variables * in this environment will overwrite or remove (if null) the default * environment variables of the editor's extension host. */ env?: Record; /** * Optional version identification for the server. If this changes, the * editor will indicate that tools have changed and prompt to refresh them. */ version?: string; /** * @param label The human-readable name of the server. * @param command The command used to start the server. * @param args Additional command-line arguments passed to the server. * @param env Optional additional environment information for the server. * @param version Optional version identification for the server. */ constructor(label: string, command: string, args?: string[], env?: Record, version?: string) { this.label = label; this.command = command; this.args = args; this.env = env; this.version = version; } } /** * McpHttpServerDefinition represents an MCP server available using the * Streamable HTTP transport. */ export class McpHttpServerDefinition { /** * The human-readable name of the server. */ readonly label: string; /** * The URI of the server. The editor will make a POST request to this URI * to begin each session. */ uri: URI; /** * Optional additional heads included with each request to the server. */ headers?: Record; /** * Optional version identification for the server. If this changes, the * editor will indicate that tools have changed and prompt to refresh them. */ version?: string; /** * @param label The human-readable name of the server. * @param uri The URI of the server. * @param headers Optional additional heads included with each request to the server. */ constructor(label: string, uri: URI, headers?: Record, version?: string) { this.label = label; this.uri = uri; this.headers = headers; this.version = version; }; } /** * Definitions that describe different types of Model Context Protocol servers, * which can be returned from the {@link McpServerDefinitionProvider}. */ export type McpServerDefinition = McpStdioServerDefinition | McpHttpServerDefinition; // #region textEditorDiffInformation export enum TextEditorChangeKind { Addition = 1, Deletion = 2, Modification = 3 } export interface TextEditorLineRange { readonly startLineNumber: number; readonly endLineNumberExclusive: number; } export interface TextEditorChange { readonly original: TextEditorLineRange; readonly modified: TextEditorLineRange; readonly kind: TextEditorChangeKind; } export interface TextEditorDiffInformation { readonly documentVersion: number; readonly original: theia.Uri | undefined; readonly modified: theia.Uri; readonly changes: readonly TextEditorChange[]; readonly isStale: boolean; } export interface TextEditorDiffInformationChangeEvent { readonly textEditor: TextEditor; readonly diffInformation: TextEditorDiffInformation[] | undefined; } export interface TextEditor { readonly diffInformation: TextEditorDiffInformation[] | undefined; } // #endregion