Skip to content

Commit

Permalink
eclipse-theia#10026 Implement DocumentSymbolProviderMetadata
Browse files Browse the repository at this point in the history
- Introduce DocumentSymbolProviderMetadata interface in theia.d.ts
- Adapt register functions to pass on optional metadata
- Adapt the MonacoOutlineContribution and use metadata label or plugin's displayName as root node if multiple providers are registered (aligned to behavior in VSCode)
- Remove Theia's custom DocumentSymbolProvider for 'launch.json' files and reuse VSCode's provider (available via vscode-builtin-configuration-editing)

Contributed on behalf of STMicroelectronics

Signed-off-by: Nina Doschek <ndoschek@eclipsesource.com>

Fixes eclipse-theia#10026
  • Loading branch information
ndoschek committed Mar 1, 2022
1 parent 6b45b27 commit 50eda78
Show file tree
Hide file tree
Showing 13 changed files with 70 additions and 109 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
1 change: 0 additions & 1 deletion packages/debug/src/browser/debug-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
89 changes: 0 additions & 89 deletions packages/debug/src/browser/debug-monaco-contribution.ts

This file was deleted.

29 changes: 25 additions & 4 deletions packages/monaco/src/browser/monaco-outline-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 [];
}
Expand All @@ -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 */
}
Expand All @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion packages/monaco/src/typings/monaco/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion packages/plugin-ext/src/common/plugin-api-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,7 @@ export interface ProcessTaskDto extends TaskDto, CommandProperties {
export interface PluginInfo {
id: string;
name: string;
displayName?: string;
}

export interface LanguagesExt {
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions packages/plugin-ext/src/main/browser/languages-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
};
}
Expand Down
10 changes: 8 additions & 2 deletions packages/plugin-ext/src/plugin/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -700,3 +702,7 @@ function serializeIndentation(indentationRules?: theia.IndentationRule): Seriali
unIndentedLinePattern: serializeRegExp(indentationRules.unIndentedLinePattern)
};
}

function getPluginLabel(pluginInfo: PluginInfo): string {
return pluginInfo.displayName || pluginInfo.name;
}
5 changes: 3 additions & 2 deletions packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
3 changes: 2 additions & 1 deletion packages/plugin-ext/src/plugin/type-converters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 2 additions & 1 deletion packages/plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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);

...

Expand Down
16 changes: 14 additions & 2 deletions packages/plugin/src/theia.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6952,6 +6952,16 @@ export module '@theia/plugin' {
provideDocumentSymbols(document: TextDocument, token: CancellationToken): ProviderResult<SymbolInformation[] | DocumentSymbol[]>;
}

/**
* 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.
*/
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 50eda78

Please sign in to comment.