diff --git a/demo/src/features/customView.ts b/demo/src/features/customView.ts
index ae439b53..6bd872ea 100644
--- a/demo/src/features/customView.ts
+++ b/demo/src/features/customView.ts
@@ -1,4 +1,4 @@
-import { IDialogService } from 'vscode/services'
+import { IDialogService, EditorInput } from 'vscode/services'
import { registerCustomView, registerEditorPane, ViewContainerLocation } from '@codingame/monaco-vscode-views-service-override'
import * as monaco from 'monaco-editor'
import iconUrl from '../Visual_Studio_Code_1.35_icon.svg?url'
@@ -54,8 +54,19 @@ const { CustomEditorInput } = registerEditorPane({
return {
dispose () {
+ },
+
+ async setInput (input: EditorInput) {
+ if (input.resource != null) {
+ container.innerHTML = 'Opened file: ' + input.resource.path
+ } else {
+ container.innerHTML = 'This is a custom editor pane
You can render anything you want here'
+ }
}
}
+ },
+ registerEditorOptions: {
+ globPattern: '*.customeditor'
}
})
diff --git a/demo/src/features/filesystem.ts b/demo/src/features/filesystem.ts
index 5993d5ba..22974d98 100644
--- a/demo/src/features/filesystem.ts
+++ b/demo/src/features/filesystem.ts
@@ -49,6 +49,10 @@ $$
$$`
))
+fileSystemProvider.registerFile(new RegisteredMemoryFile(vscode.Uri.file('/tmp/test.customeditor'), `
+Custom Editor!`
+))
+
fileSystemProvider.registerFile(new RegisteredMemoryFile(vscode.Uri.file('/tmp/test.css'), `
h1 {
color: DeepSkyBlue;
diff --git a/src/service-override/views.ts b/src/service-override/views.ts
index dadf19b9..97d04a9a 100644
--- a/src/service-override/views.ts
+++ b/src/service-override/views.ts
@@ -43,19 +43,19 @@ import 'vs/workbench/contrib/languageDetection/browser/languageDetection.contrib
import 'vs/workbench/contrib/files/browser/files.contribution.js?include=registerConfiguration'
import 'vs/workbench/contrib/files/browser/files.contribution.js?exclude=registerConfiguration'
import { Codicon } from 'vs/base/common/codicons'
-import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'
+import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'
import { IEditorDropService } from 'vs/workbench/services/editor/browser/editorDropService'
import { IEditorDropTargetDelegate } from 'vs/workbench/browser/parts/editor/editorDropTarget'
import { IEditorService } from 'vs/workbench/services/editor/common/editorService'
-import { IEditorResolverService } from 'vs/workbench/services/editor/common/editorResolverService'
+import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'
import { EditorResolverService } from 'vs/workbench/services/editor/browser/editorResolverService'
import { BreadcrumbsService, IBreadcrumbsService } from 'vs/workbench/browser/parts/editor/breadcrumbs'
import { IContextViewService } from 'vs/platform/contextview/browser/contextView'
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'
import { EditorInput, IEditorCloseHandler } from 'vs/workbench/common/editor/editorInput'
-import { EditorExtensions, Verbosity } from 'vs/workbench/common/editor'
-import { IEditorOptions } from 'vs/platform/editor/common/editor'
+import { EditorExtensions, IEditorOpenContext, Verbosity } from 'vs/workbench/common/editor'
+import { IEditorOptions, IResourceEditorInput, ITextResourceEditorInput } from 'vs/platform/editor/common/editor'
import { IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'
import { ITextEditorService, TextEditorService } from 'vs/workbench/services/textfile/common/textEditorService'
import { CodeEditorService } from 'vs/workbench/services/editor/browser/codeEditorService'
@@ -87,6 +87,7 @@ import { ConfirmResult } from 'vs/platform/dialogs/common/dialogs'
import { ILayoutService } from 'vs/platform/layout/browser/layoutService'
import { IBannerService } from 'vs/workbench/services/banner/browser/bannerService'
import { ITitleService } from 'vs/workbench/services/title/common/titleService'
+import { CancellationToken } from 'vs/base/common/cancellation'
import { MonacoDelegateEditorGroupsService, MonacoEditorService, OpenEditor } from './tools/editor'
import getBulkEditServiceOverride from './bulkEdit'
import getLayoutServiceOverride, { LayoutService } from './layout'
@@ -95,6 +96,7 @@ import getKeybindingsOverride from './keybindings'
import { changeUrlDomain } from './tools/url'
import { registerAssets } from '../assets'
import { registerServiceInitializePostParticipant } from '../lifecycle'
+import { getService } from '../services'
function createPart (id: string, role: string, classes: string[]): HTMLElement {
const part = document.createElement(role === 'status' ? 'footer' /* Use footer element for status bar #98376 */ : 'div')
@@ -189,6 +191,10 @@ function renderStatusBarPart (container: HTMLElement): IDisposable {
return attachPart(Parts.STATUSBAR_PART, container)
}
+interface BodyRenderer extends IDisposable {
+ setInput? (input: EditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise
+}
+
type Label = string | {
short: string
medium: string
@@ -197,7 +203,21 @@ type Label = string | {
interface EditorPanelOption {
readonly id: string
name: string
- renderBody (container: HTMLElement): IDisposable
+ renderBody (container: HTMLElement): BodyRenderer
+
+ /**
+ * By setting these options, this editor will be opened by default for
+ * certain file types.
+ */
+ registerEditorOptions?: {
+ /**
+ * Which files to open it for
+ *
+ * @example '*.md'
+ */
+ globPattern: string
+ priority?: RegisteredEditorPriority
+ }
}
interface SimpleEditorInput extends EditorInput {
@@ -207,9 +227,10 @@ interface SimpleEditorInput extends EditorInput {
setDirty (dirty: boolean): void
}
-function registerEditorPane (options: EditorPanelOption): { disposable: IDisposable, CustomEditorInput: new (closeHandler?: IEditorCloseHandler) => SimpleEditorInput } {
+function registerEditorPane (options: EditorPanelOption): { disposable: IDisposable, CustomEditorInput: new (closeHandler?: IEditorCloseHandler, baseInput?: IResourceEditorInput | ITextResourceEditorInput) => SimpleEditorInput } {
class CustomEditorPane extends EditorPane {
private content?: HTMLElement
+ private bodyRenderer?: BodyRenderer
constructor (
@ITelemetryService telemetryService: ITelemetryService,
@IThemeService themeService: IThemeService,
@@ -223,13 +244,22 @@ function registerEditorPane (options: EditorPanelOption): { disposable: IDisposa
this.content.style.display = 'flex'
this.content.style.alignItems = 'stretch'
append(parent, this.content)
- this._register(options.renderBody(this.content))
+ this.bodyRenderer = options.renderBody(this.content)
+ this._register(this.bodyRenderer)
}
override layout (dimension: Dimension): void {
this.content!.style.height = `${dimension.height}px`
this.content!.style.width = `${dimension.width}px`
}
+
+ override async setInput (input: EditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise {
+ if (this.bodyRenderer != null && this.bodyRenderer.setInput != null) {
+ await this.bodyRenderer.setInput(input, options, context, token)
+ }
+
+ return super.setInput(input, options, context, token)
+ }
}
class CustomEditorInput extends EditorInput implements SimpleEditorInput {
@@ -240,7 +270,7 @@ function registerEditorPane (options: EditorPanelOption): { disposable: IDisposa
private description: Label = options.name
private dirty: boolean = false
- constructor (public override readonly closeHandler?: IEditorCloseHandler) {
+ constructor (public override readonly closeHandler?: IEditorCloseHandler, public baseInput?: IResourceEditorInput | ITextResourceEditorInput) {
super()
}
@@ -249,7 +279,7 @@ function registerEditorPane (options: EditorPanelOption): { disposable: IDisposa
}
override get resource (): URI | undefined {
- return undefined
+ return this.baseInput?.resource
}
public setName (name: string) {
@@ -304,16 +334,45 @@ function registerEditorPane (options: EditorPanelOption): { disposable: IDisposa
}
}
- const disposable = Registry.as(EditorExtensions.EditorPane).registerEditorPane(
+ const disposableStore = new DisposableStore()
+
+ disposableStore.add(Registry.as(EditorExtensions.EditorPane).registerEditorPane(
EditorPaneDescriptor.create(
CustomEditorPane,
options.id,
options.name
),
- [new SyncDescriptor(CustomEditorInput)])
+ [new SyncDescriptor(CustomEditorInput)]))
+
+ const registerEditorOptions = options.registerEditorOptions
+ if (registerEditorOptions != null) {
+ getService(IEditorResolverService).then(editorResolverService => {
+ if (disposableStore.isDisposed) {
+ return
+ }
+
+ disposableStore.add(editorResolverService.registerEditor(
+ registerEditorOptions.globPattern,
+ {
+ id: CustomEditorInput.ID,
+ label: options.name,
+ priority: registerEditorOptions.priority ?? RegisteredEditorPriority.default
+ },
+ {},
+ {
+ createEditorInput (editorInput: IResourceEditorInput | ITextResourceEditorInput, _group: IEditorGroup) {
+ return {
+ options: {},
+ editor: new CustomEditorInput(undefined, editorInput)
+ }
+ }
+ }
+ ))
+ }).catch(console.error)
+ }
return {
- disposable,
+ disposable: disposableStore,
CustomEditorInput
}
}
@@ -676,5 +735,7 @@ export {
SidebarPart,
ActivitybarPart,
PanelPart,
- Parts
+ Parts,
+
+ BodyRenderer
}