diff --git a/CHANGELOG.md b/CHANGELOG.md index f9747106d7ab7..7ac8447d23556 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## v1.24.0 - 3/31/2022 + +[1.24.0 Milestone](https://github.com/eclipse-theia/theia/milestone/32) + +- [plugin] added support for `DocumentSymbolProviderMetadata` [#10811](https://github.com/eclipse-theia/theia/pull/10811) - Contributed on behalf of STMicroelectronics + ## v1.23.0 - 2/24/2022 [1.23.0 Milestone](https://github.com/eclipse-theia/theia/milestone/31) diff --git a/packages/debug/src/browser/debug-frontend-module.ts b/packages/debug/src/browser/debug-frontend-module.ts index b4eecd68b30e9..0cbbcf814b5b4 100644 --- a/packages/debug/src/browser/debug-frontend-module.ts +++ b/packages/debug/src/browser/debug-frontend-module.ts @@ -43,7 +43,6 @@ import { DebugViewOptions } from './view/debug-view-model'; import { DebugSessionWidget, DebugSessionWidgetFactory } from './view/debug-session-widget'; import { InDebugModeContext, BreakpointWidgetInputFocusContext, BreakpointWidgetInputStrictFocusContext } from './debug-keybinding-contexts'; import { DebugEditorModelFactory, DebugEditorModel } from './editor/debug-editor-model'; -import './debug-monaco-contribution'; import { bindDebugPreferences } from './debug-preferences'; import { DebugSchemaUpdater } from './debug-schema-updater'; import { DebugCallStackItemTypeKey } from './debug-call-stack-item-type-key'; diff --git a/packages/debug/src/browser/debug-monaco-contribution.ts b/packages/debug/src/browser/debug-monaco-contribution.ts deleted file mode 100644 index df820bb8516fa..0000000000000 --- a/packages/debug/src/browser/debug-monaco-contribution.ts +++ /dev/null @@ -1,89 +0,0 @@ -// ***************************************************************************** -// Copyright (C) 2018 TypeFox 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 WITH Classpath-exception-2.0 -// ***************************************************************************** -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. See License.txt in the project root for license information. -*--------------------------------------------------------------------------------------------*/ - -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import { visit } from 'jsonc-parser'; -import URI from '@theia/core/lib/common/uri'; - -monaco.languages.register({ - id: 'jsonc', - 'aliases': [ - 'JSON with Comments' - ], - 'filenames': [ - 'launch.json' - ] -}); - -monaco.languages.registerDocumentSymbolProvider('jsonc', { - provideDocumentSymbols(model: monaco.editor.ITextModel): monaco.languages.DocumentSymbol[] { - if (new URI(model.uri.toString()).path.base !== 'launch.json') { - return []; - } - const children: monaco.languages.DocumentSymbol[] = []; - const result: monaco.languages.DocumentSymbol = { - name: 'Launch Configurations', - detail: '', - kind: monaco.languages.SymbolKind.Object, - range: new monaco.Range(0, 0, 0, 0), - selectionRange: new monaco.Range(0, 0, 0, 0), - children, - tags: [] - }; - let name: string = ''; - let lastProperty = ''; - let startOffset = 0; - let depthInObjects = 0; - - visit(model.getValue(), { - onObjectProperty: (property, _offset, _length) => { - lastProperty = property; - }, - onLiteralValue: (value: any, _offset: number, _length: number) => { - if (lastProperty === 'name') { - name = value; - } - }, - onObjectBegin: (offset: number, _length: number) => { - depthInObjects++; - if (depthInObjects === 2) { - startOffset = offset; - } - }, - onObjectEnd: (offset: number, _length: number) => { - if (name && depthInObjects === 2) { - const range = monaco.Range.fromPositions(model.getPositionAt(startOffset), model.getPositionAt(offset)); - children.push({ - name, - detail: '', - kind: monaco.languages.SymbolKind.Object, - range, - selectionRange: range, - tags: [] - }); - } - depthInObjects--; - }, - }); - - return [result]; - } -}); diff --git a/packages/monaco/src/browser/monaco-outline-contribution.ts b/packages/monaco/src/browser/monaco-outline-contribution.ts index e55b1bf8150bd..cdae2c602f9a2 100644 --- a/packages/monaco/src/browser/monaco-outline-contribution.ts +++ b/packages/monaco/src/browser/monaco-outline-contribution.ts @@ -128,8 +128,7 @@ export class MonacoOutlineContribution implements FrontendApplicationContributio this.roots.forEach(resetSelection); } else { this.roots = []; - // eslint-disable-next-line @typescript-eslint/await-thenable - const providers = await DocumentSymbolProviderRegistry.all(model); + const providers = DocumentSymbolProviderRegistry.all(model); if (token.isCancellationRequested) { return []; } @@ -140,8 +139,14 @@ export class MonacoOutlineContribution implements FrontendApplicationContributio if (token.isCancellationRequested) { return []; } - const nodes = this.createNodes(uri, symbols || []); - this.roots.push(...nodes); + if (providers.length > 1 && provider.displayName) { + const nodes = this.createNodes(uri, symbols || []); + const providerRootNode = this.createProviderRootNode(uri, provider.displayName, nodes); + this.roots.push(providerRootNode); + } else { + const nodes = this.createNodes(uri, symbols || []); + this.roots.push(...nodes); + } } catch { /* collect symbols from other providers */ } @@ -151,6 +156,22 @@ export class MonacoOutlineContribution implements FrontendApplicationContributio return this.roots; } + protected createProviderRootNode(uri: URI, displayName: string, children: MonacoOutlineSymbolInformationNode[]): MonacoOutlineSymbolInformationNode { + const node: MonacoOutlineSymbolInformationNode = { + uri, + id: displayName, + name: displayName, + iconClass: '', + range: this.asRange(new monaco.Range(0, 0, 0, 0)), + fullRange: this.asRange(new monaco.Range(0, 0, 0, 0)), + children, + parent: undefined, + selected: false, + expanded: true + }; + return node; + } + protected createNodes(uri: URI, symbols: DocumentSymbol[]): MonacoOutlineSymbolInformationNode[] { let rangeBased = false; const ids = new Map(); diff --git a/packages/monaco/src/typings/monaco/index.d.ts b/packages/monaco/src/typings/monaco/index.d.ts index b3e2eb9807cc3..0799c0597ed45 100644 --- a/packages/monaco/src/typings/monaco/index.d.ts +++ b/packages/monaco/src/typings/monaco/index.d.ts @@ -2350,7 +2350,8 @@ declare module monaco.languages { export function registerRenameProvider(selector: monaco.modes.LanguageSelector, provider: RenameProvider): IDisposable; export function registerSignatureHelpProvider(selector: monaco.modes.LanguageSelector, provider: SignatureHelpProvider): IDisposable; export function registerHoverProvider(selector: monaco.modes.LanguageSelector, provider: HoverProvider): IDisposable; - export function registerDocumentSymbolProvider(selector: monaco.modes.LanguageSelector, provider: DocumentSymbolProvider): IDisposable; + export function registerDocumentSymbolProvider(selector: monaco.modes.LanguageSelector, provider: DocumentSymbolProvider, + metadata?: DocumentSymbolProviderMetadata): IDisposable; export function registerDocumentHighlightProvider(selector: monaco.modes.LanguageSelector, provider: DocumentHighlightProvider): IDisposable; export function registerDefinitionProvider(selector: monaco.modes.LanguageSelector, provider: DefinitionProvider): IDisposable; export function registerImplementationProvider(selector: monaco.modes.LanguageSelector, provider: ImplementationProvider): IDisposable; diff --git a/packages/plugin-ext/src/common/plugin-api-rpc.ts b/packages/plugin-ext/src/common/plugin-api-rpc.ts index da87d009f1c14..1dfdfb1972153 100644 --- a/packages/plugin-ext/src/common/plugin-api-rpc.ts +++ b/packages/plugin-ext/src/common/plugin-api-rpc.ts @@ -1402,6 +1402,7 @@ export interface ProcessTaskDto extends TaskDto, CommandProperties { export interface PluginInfo { id: string; name: string; + displayName?: string; } export interface LanguagesExt { @@ -1503,7 +1504,7 @@ export interface LanguagesMain { $registerDocumentLinkProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void; $registerCodeLensSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[], eventHandle?: number): void; $emitCodeLensEvent(eventHandle: number, event?: any): void; - $registerOutlineSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void; + $registerOutlineSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[], displayName?: string): void; $registerWorkspaceSymbolProvider(handle: number, pluginInfo: PluginInfo): void; $registerFoldingRangeProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void; $registerSelectionRangeProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void; diff --git a/packages/plugin-ext/src/main/browser/languages-main.ts b/packages/plugin-ext/src/main/browser/languages-main.ts index 100fabba060ff..bf23871325058 100644 --- a/packages/plugin-ext/src/main/browser/languages-main.ts +++ b/packages/plugin-ext/src/main/browser/languages-main.ts @@ -459,14 +459,15 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable { } } - $registerOutlineSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void { + $registerOutlineSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[], displayName?: string): void { const languageSelector = this.toLanguageSelector(selector); - const symbolProvider = this.createDocumentSymbolProvider(handle); + const symbolProvider = this.createDocumentSymbolProvider(handle, displayName); this.register(handle, monaco.modes.DocumentSymbolProviderRegistry.register(languageSelector, symbolProvider)); } - protected createDocumentSymbolProvider(handle: number): monaco.languages.DocumentSymbolProvider { + protected createDocumentSymbolProvider(handle: number, displayName?: string): monaco.languages.DocumentSymbolProvider { return { + displayName, provideDocumentSymbols: (model, token) => this.provideDocumentSymbols(handle, model, token) }; } diff --git a/packages/plugin-ext/src/plugin/languages.ts b/packages/plugin-ext/src/plugin/languages.ts index 6a1b656707e8c..ebb9b519f9847 100644 --- a/packages/plugin-ext/src/plugin/languages.ts +++ b/packages/plugin-ext/src/plugin/languages.ts @@ -531,9 +531,11 @@ export class LanguagesExtImpl implements LanguagesExt { // ### Code Reference Provider end // ### Document Symbol Provider begin - registerDocumentSymbolProvider(selector: theia.DocumentSelector, provider: theia.DocumentSymbolProvider, pluginInfo: PluginInfo): theia.Disposable { + registerDocumentSymbolProvider(selector: theia.DocumentSelector, provider: theia.DocumentSymbolProvider, pluginInfo: PluginInfo, + metadata?: theia.DocumentSymbolProviderMetadata): theia.Disposable { const callId = this.addNewAdapter(new OutlineAdapter(this.documents, provider)); - this.proxy.$registerOutlineSupport(callId, pluginInfo, this.transformDocumentSelector(selector)); + const displayName = (metadata && metadata.label) || getPluginLabel(pluginInfo); + this.proxy.$registerOutlineSupport(callId, pluginInfo, this.transformDocumentSelector(selector), displayName); return this.createDisposable(callId); } @@ -700,3 +702,7 @@ function serializeIndentation(indentationRules?: theia.IndentationRule): Seriali unIndentedLinePattern: serializeRegExp(indentationRules.unIndentedLinePattern) }; } + +function getPluginLabel(pluginInfo: PluginInfo): string { + return pluginInfo.displayName || pluginInfo.name; +} diff --git a/packages/plugin-ext/src/plugin/plugin-context.ts b/packages/plugin-ext/src/plugin/plugin-context.ts index d079bb9fb4b80..14446a1a39018 100644 --- a/packages/plugin-ext/src/plugin/plugin-context.ts +++ b/packages/plugin-ext/src/plugin/plugin-context.ts @@ -752,8 +752,9 @@ export function createAPIFactory( registerReferenceProvider(selector: theia.DocumentSelector, provider: theia.ReferenceProvider): theia.Disposable { return languagesExt.registerReferenceProvider(selector, provider, pluginToPluginInfo(plugin)); }, - registerDocumentSymbolProvider(selector: theia.DocumentSelector, provider: theia.DocumentSymbolProvider): theia.Disposable { - return languagesExt.registerDocumentSymbolProvider(selector, provider, pluginToPluginInfo(plugin)); + registerDocumentSymbolProvider(selector: theia.DocumentSelector, provider: theia.DocumentSymbolProvider, + metadata?: theia.DocumentSymbolProviderMetadata): theia.Disposable { + return languagesExt.registerDocumentSymbolProvider(selector, provider, pluginToPluginInfo(plugin), metadata); }, registerColorProvider(selector: theia.DocumentSelector, provider: theia.DocumentColorProvider): theia.Disposable { return languagesExt.registerColorProvider(selector, provider, pluginToPluginInfo(plugin)); diff --git a/packages/plugin-ext/src/plugin/type-converters.ts b/packages/plugin-ext/src/plugin/type-converters.ts index 6a44d7a82096a..dbf376be1f68c 100644 --- a/packages/plugin-ext/src/plugin/type-converters.ts +++ b/packages/plugin-ext/src/plugin/type-converters.ts @@ -1217,6 +1217,7 @@ export function pathOrURIToURI(value: string | URI): URI { export function pluginToPluginInfo(plugin: Plugin): rpc.PluginInfo { return { id: plugin.model.id, - name: plugin.model.name + name: plugin.model.name, + displayName: plugin.model.displayName }; } diff --git a/packages/plugin-metrics/src/browser/plugin-metrics-languages-main.ts b/packages/plugin-metrics/src/browser/plugin-metrics-languages-main.ts index db9f22af3516a..ff7c9903b17d4 100644 --- a/packages/plugin-metrics/src/browser/plugin-metrics-languages-main.ts +++ b/packages/plugin-metrics/src/browser/plugin-metrics-languages-main.ts @@ -273,9 +273,9 @@ export class LanguagesMainPluginMetrics extends LanguagesMainImpl { super.$registerCodeLensSupport(handle, pluginInfo, selector, eventHandle); } - override $registerOutlineSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void { + override $registerOutlineSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[], displayName?: string): void { this.registerPluginWithFeatureHandle(handle, pluginInfo.id); - super.$registerOutlineSupport(handle, pluginInfo, selector); + super.$registerOutlineSupport(handle, pluginInfo, selector, displayName); } override $registerDocumentFormattingSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void { diff --git a/packages/plugin/README.md b/packages/plugin/README.md index a54749dad2f8d..28f22f35e27c7 100644 --- a/packages/plugin/README.md +++ b/packages/plugin/README.md @@ -681,8 +681,9 @@ Example of code symbol provider registration: ```typescript const documentsSelector: theia.DocumentSelector = { scheme: 'file', language: 'typescript' }; const provider = { provideDocumentSymbols: provideSymbols }; +const metadata = { label: 'providerLabel' } -const disposable = theia.languages.registerDocumentSymbolProvider(documentsSelector, provider); +const disposable = theia.languages.registerDocumentSymbolProvider(documentsSelector, provider, metadata); ... diff --git a/packages/plugin/src/theia.d.ts b/packages/plugin/src/theia.d.ts index 07a4cb6492f9f..73af2d7699440 100644 --- a/packages/plugin/src/theia.d.ts +++ b/packages/plugin/src/theia.d.ts @@ -6952,6 +6952,16 @@ export module '@theia/plugin' { provideDocumentSymbols(document: TextDocument, token: CancellationToken): ProviderResult; } + /** + * Metadata about a {@link DocumentSymbolProvider}. + */ + export interface DocumentSymbolProviderMetadata { + /** + * A human-readable string that is shown when multiple outline trees show for one document. + */ + label?: string; + } + /** * Represents a color in RGBA space. */ @@ -8974,9 +8984,11 @@ export module '@theia/plugin' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A document symbol provider. - * @return A [disposable](#Disposable) that unregisters this provider when being disposed. + * @param metadata Optional metadata about the provider. + * @return A {@link Disposable disposable} that unregisters this provider when being disposed. */ - export function registerDocumentSymbolProvider(selector: DocumentSelector, provider: DocumentSymbolProvider): Disposable; + export function registerDocumentSymbolProvider(selector: DocumentSelector, provider: DocumentSymbolProvider, + metadata?: DocumentSymbolProviderMetadata): Disposable; /** * Register a color provider.