diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d6e3fb01217a..fae7bbad2ff0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ## v1.27.0 - Unreleased - [plugin] moved `WebviewViewResolveContext` from `window` to `root` namespace [#11216](https://github.com/eclipse-theia/theia/pull/11216) - Contributed on behalf of STMicroelectronics +- [plugin] Support `TextEditor#show()` and `TextEditor#hide()` [#11168](https://github.com/eclipse-theia/theia/pull/11168) - Contributed on behalf of STMicroelectronics [Breaking Changes:](#breaking_changes_1.27.0) diff --git a/packages/editor/src/browser/editor-manager.ts b/packages/editor/src/browser/editor-manager.ts index d8b00e01a5d54..09ce73385ccf7 100644 --- a/packages/editor/src/browser/editor-manager.ts +++ b/packages/editor/src/browser/editor-manager.ts @@ -187,6 +187,20 @@ export class EditorManager extends NavigatableWidgetOpenHandler { // This override only serves to inform external callers that they can use EditorOpenerOptions. override open(uri: URI, options?: EditorOpenerOptions): Promise { + + /* check whether we have a split request without a counter */ + if (options && options.counter === undefined && options.widgetOptions?.mode) { + switch (options.widgetOptions.mode) { + case 'split-right': + case 'split-bottom': + case 'split-top': + case 'split-left': + const counter = this.createCounterForUri(uri); + const splitOptions: EditorOpenerOptions = { counter, ...options }; + return super.open(uri, splitOptions); + } + } + return super.open(uri, options); } diff --git a/packages/plugin-ext/src/common/plugin-api-rpc.ts b/packages/plugin-ext/src/common/plugin-api-rpc.ts index abff12eabe343..2b26a92b2b59e 100644 --- a/packages/plugin-ext/src/common/plugin-api-rpc.ts +++ b/packages/plugin-ext/src/common/plugin-api-rpc.ts @@ -1161,11 +1161,10 @@ export interface DecorationOptions { } export interface TextEditorsMain { - // $tryShowTextDocument(resource: UriComponents, options: TextDocumentShowOptions): Promise; + $tryShowTextDocument(uri: UriComponents, options?: TextDocumentShowOptions): Promise; $registerTextEditorDecorationType(key: string, options: DecorationRenderOptions): void; $removeTextEditorDecorationType(key: string): void; - // $tryShowEditor(id: string, position: EditorPosition): Promise; - // $tryHideEditor(id: string): Promise; + $tryHideEditor(id: string): Promise; $trySetOptions(id: string, options: TextEditorConfigurationUpdate): Promise; $trySetDecorations(id: string, key: string, ranges: DecorationOptions[]): Promise; $trySetDecorationsFast(id: string, key: string, ranges: number[]): Promise; diff --git a/packages/plugin-ext/src/main/browser/editors-and-documents-main.ts b/packages/plugin-ext/src/main/browser/editors-and-documents-main.ts index 6d342661f5362..d2807b5f82ad6 100644 --- a/packages/plugin-ext/src/main/browser/editors-and-documents-main.ts +++ b/packages/plugin-ext/src/main/browser/editors-and-documents-main.ts @@ -41,6 +41,7 @@ export class EditorsAndDocumentsMain implements Disposable { private readonly textEditors = new Map(); private readonly modelService: EditorModelService; + private readonly editorService: EditorManager; private readonly onTextEditorAddEmitter = new Emitter(); private readonly onTextEditorRemoveEmitter = new Emitter(); @@ -59,10 +60,10 @@ export class EditorsAndDocumentsMain implements Disposable { constructor(rpc: RPCProtocol, container: interfaces.Container) { this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.EDITORS_AND_DOCUMENTS_EXT); - const editorService = container.get(EditorManager); + this.editorService = container.get(EditorManager); this.modelService = container.get(EditorModelService); - this.stateComputer = new EditorAndDocumentStateComputer(d => this.onDelta(d), editorService, this.modelService); + this.stateComputer = new EditorAndDocumentStateComputer(d => this.onDelta(d), this.editorService, this.modelService); this.toDispose.push(this.stateComputer); this.toDispose.push(this.onTextEditorAddEmitter); this.toDispose.push(this.onTextEditorRemoveEmitter); @@ -168,6 +169,19 @@ export class EditorsAndDocumentsMain implements Disposable { saveAll(includeUntitled?: boolean): Promise { return this.modelService.saveAll(includeUntitled); } + + hideEditor(id: string): Promise { + for (const editorWidget of this.editorService.all) { + const monacoEditor = MonacoEditor.get(editorWidget); + if (monacoEditor) { + if (id === new EditorSnapshot(monacoEditor).id) { + editorWidget.close(); + break; + } + } + } + return Promise.resolve(); + } } class EditorAndDocumentStateComputer implements Disposable { diff --git a/packages/plugin-ext/src/main/browser/main-context.ts b/packages/plugin-ext/src/main/browser/main-context.ts index 92cb03bc8ae23..4b9fa7d04d493 100644 --- a/packages/plugin-ext/src/main/browser/main-context.ts +++ b/packages/plugin-ext/src/main/browser/main-context.ts @@ -94,7 +94,7 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container const bulkEditService = container.get(MonacoBulkEditService); const monacoEditorService = container.get(MonacoEditorService); - const editorsMain = new TextEditorsMainImpl(editorsAndDocuments, rpc, bulkEditService, monacoEditorService); + const editorsMain = new TextEditorsMainImpl(editorsAndDocuments, documentsMain, rpc, bulkEditService, monacoEditorService); rpc.set(PLUGIN_RPC_CONTEXT.TEXT_EDITORS_MAIN, editorsMain); // start listening only after all clients are subscribed to events diff --git a/packages/plugin-ext/src/main/browser/text-editors-main.ts b/packages/plugin-ext/src/main/browser/text-editors-main.ts index 18a9230b8235f..9756262787654 100644 --- a/packages/plugin-ext/src/main/browser/text-editors-main.ts +++ b/packages/plugin-ext/src/main/browser/text-editors-main.ts @@ -28,9 +28,10 @@ import { DecorationRenderOptions, ThemeDecorationInstanceRenderOptions, DecorationOptions, - WorkspaceEditDto + WorkspaceEditDto, + DocumentsMain, } from '../../common/plugin-api-rpc'; -import { Range } from '../../common/plugin-api-rpc-model'; +import { Range, TextDocumentShowOptions } from '../../common/plugin-api-rpc-model'; import { EditorsAndDocumentsMain } from './editors-and-documents-main'; import { RPCProtocol } from '../../common/rpc-protocol'; import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable'; @@ -54,6 +55,7 @@ export class TextEditorsMainImpl implements TextEditorsMain, Disposable { constructor( private readonly editorsAndDocuments: EditorsAndDocumentsMain, + private readonly documents: DocumentsMain, rpc: RPCProtocol, private readonly bulkEditService: MonacoBulkEditService, private readonly monacoEditorService: MonacoEditorService, @@ -87,6 +89,10 @@ export class TextEditorsMainImpl implements TextEditorsMain, Disposable { } } + $tryShowTextDocument(uri: UriComponents, options?: TextDocumentShowOptions): Promise { + return this.documents.$tryShowDocument(uri, options); + } + $trySetOptions(id: string, options: TextEditorConfigurationUpdate): Promise { if (!this.editorsAndDocuments.getEditor(id)) { return Promise.reject(disposed(`TextEditor: ${id}`)); @@ -173,6 +179,10 @@ export class TextEditorsMainImpl implements TextEditorsMain, Disposable { this.monacoEditorService.removeDecorationType(key); } + $tryHideEditor(id: string): Promise { + return this.editorsAndDocuments.hideEditor(id); + } + $trySetDecorations(id: string, key: string, ranges: DecorationOptions[]): Promise { if (!this.editorsAndDocuments.getEditor(id)) { return Promise.reject(disposed(`TextEditor(${id})`)); diff --git a/packages/plugin-ext/src/plugin/text-editor.ts b/packages/plugin-ext/src/plugin/text-editor.ts index a27ff47bf7267..ac5af354e56fa 100644 --- a/packages/plugin-ext/src/plugin/text-editor.ts +++ b/packages/plugin-ext/src/plugin/text-editor.ts @@ -236,11 +236,11 @@ export class TextEditorExt implements theia.TextEditor { // prepare data for serialization const edits: SingleEditOperation[] = editData.edits.map(e => - ({ - range: Converter.fromRange(e.range)!, - text: e.text, - forceMoveMarkers: e.forceMoveMarkers - })); + ({ + range: Converter.fromRange(e.range)!, + text: e.text, + forceMoveMarkers: e.forceMoveMarkers + })); return this.proxy.$tryApplyEdits(this.id, editData.documentVersionId, edits, { setEndOfLine: editData.setEndOfLine, @@ -263,6 +263,17 @@ export class TextEditorExt implements theia.TextEditor { return undefined; }); } + + show(column?: theia.ViewColumn): void { + this.proxy.$tryShowTextDocument(this.document.uri, { + viewColumn: column, + preview: true, + }); + } + + hide(): void { + this.proxy.$tryHideEditor(this.id); + } } export class TextEditorOptionsExt implements theia.TextEditorOptions { diff --git a/packages/plugin/src/theia.d.ts b/packages/plugin/src/theia.d.ts index e6387aced88c4..0fedbf64739b3 100644 --- a/packages/plugin/src/theia.d.ts +++ b/packages/plugin/src/theia.d.ts @@ -1215,6 +1215,22 @@ export module '@theia/plugin' { * @param revealType The scrolling strategy for revealing `range`. */ revealRange(range: Range, revealType?: TextEditorRevealType): void; + + /** + * Shows this text editor. A [column](#ViewColumn) can be provided to control where the editor is being shown. Might change the [active editor](#window.activeTextEditor). + * + * @deprecated use [window.showTextDocument](#Window.showTextDocument) instead. + * + * @param column A [view column](#ViewColumn) in which this editor should be shown. + */ + show(column?: ViewColumn): void; + + /** + * Hides this text editor. + * + * @deprecated use 'workbench.action.closeActiveEditor' command instead. + */ + hide(): void; } /**