From 17a6e236f0f9dd288bbde5c514c91e6870489f34 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 20 Mar 2018 10:47:34 +0100 Subject: [PATCH] introduce simple widget editor. Use a command delegate so extensions do not intercept commands --- src/vs/editor/browser/codeEditor.ts | 2 +- src/vs/editor/browser/view/viewController.ts | 38 ++++++------ src/vs/editor/browser/view/viewImpl.ts | 7 +-- .../editor/browser/widget/codeEditorWidget.ts | 60 ++++++++++++++++++- src/vs/editor/common/commonCodeEditor.ts | 3 + .../contrib/suggest/test/suggestModel.test.ts | 2 +- src/vs/editor/test/browser/testCodeEditor.ts | 2 +- .../debug/electron-browser/replEditor.ts | 2 +- 8 files changed, 86 insertions(+), 30 deletions(-) diff --git a/src/vs/editor/browser/codeEditor.ts b/src/vs/editor/browser/codeEditor.ts index ba4ced1885d..1c5ed6d9b6b 100644 --- a/src/vs/editor/browser/codeEditor.ts +++ b/src/vs/editor/browser/codeEditor.ts @@ -24,7 +24,7 @@ export class CodeEditor extends CodeEditorWidget { @IContextKeyService contextKeyService: IContextKeyService, @IThemeService themeService: IThemeService ) { - super(domElement, options, instantiationService, codeEditorService, commandService, contextKeyService, themeService); + super(domElement, options, false, instantiationService, codeEditorService, commandService, contextKeyService, themeService); } protected _getContributions(): IEditorContributionCtor[] { diff --git a/src/vs/editor/browser/view/viewController.ts b/src/vs/editor/browser/view/viewController.ts index 30f1155a1a8..8dfebb34b87 100644 --- a/src/vs/editor/browser/view/viewController.ts +++ b/src/vs/editor/browser/view/viewController.ts @@ -7,9 +7,7 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { Position } from 'vs/editor/common/core/position'; import { Selection } from 'vs/editor/common/core/selection'; -import * as editorCommon from 'vs/editor/common/editorCommon'; import { IEditorMouseEvent } from 'vs/editor/browser/editorBrowser'; -import { ICommandService } from 'vs/platform/commands/common/commands'; import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; import { ViewOutgoingEvents } from 'vs/editor/browser/view/viewOutgoingEvents'; import { CoreNavigationCommands, CoreEditorCommand } from 'vs/editor/browser/controller/coreCommands'; @@ -35,26 +33,35 @@ export interface IMouseDispatchData { shiftKey: boolean; } +export interface ICommandDelegate { + paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]): void; + type(source: string, text: string): void; + replacePreviousChar(source: string, text: string, replaceCharCnt: number): void; + compositionStart(source: string): void; + compositionEnd(source: string): void; + cut(source: string): void; +} + export class ViewController { private readonly configuration: Configuration; private readonly viewModel: IViewModel; private readonly _execCoreEditorCommandFunc: ExecCoreEditorCommandFunc; private readonly outgoingEvents: ViewOutgoingEvents; - private readonly commandService: ICommandService; + private readonly commandDelegate: ICommandDelegate; constructor( configuration: Configuration, viewModel: IViewModel, execCommandFunc: ExecCoreEditorCommandFunc, outgoingEvents: ViewOutgoingEvents, - commandService: ICommandService + commandDelegate: ICommandDelegate ) { this.configuration = configuration; this.viewModel = viewModel; this._execCoreEditorCommandFunc = execCommandFunc; this.outgoingEvents = outgoingEvents; - this.commandService = commandService; + this.commandDelegate = commandDelegate; } private _execMouseCommand(editorCommand: CoreEditorCommand, args: any): void { @@ -63,36 +70,27 @@ export class ViewController { } public paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]): void { - this.commandService.executeCommand(editorCommon.Handler.Paste, { - text: text, - pasteOnNewLine: pasteOnNewLine, - multicursorText: multicursorText - }); + this.commandDelegate.paste(source, text, pasteOnNewLine, multicursorText); } public type(source: string, text: string): void { - this.commandService.executeCommand(editorCommon.Handler.Type, { - text: text - }); + this.commandDelegate.type(source, text); } public replacePreviousChar(source: string, text: string, replaceCharCnt: number): void { - this.commandService.executeCommand(editorCommon.Handler.ReplacePreviousChar, { - text: text, - replaceCharCnt: replaceCharCnt - }); + this.commandDelegate.replacePreviousChar(source, text, replaceCharCnt); } public compositionStart(source: string): void { - this.commandService.executeCommand(editorCommon.Handler.CompositionStart, {}); + this.commandDelegate.compositionStart(source); } public compositionEnd(source: string): void { - this.commandService.executeCommand(editorCommon.Handler.CompositionEnd, {}); + this.commandDelegate.compositionEnd(source); } public cut(source: string): void { - this.commandService.executeCommand(editorCommon.Handler.Cut, {}); + this.commandDelegate.cut(source); } public setSelection(source: string, modelSelection: Selection): void { diff --git a/src/vs/editor/browser/view/viewImpl.ts b/src/vs/editor/browser/view/viewImpl.ts index 54f9b156840..88fa7e2ed2d 100644 --- a/src/vs/editor/browser/view/viewImpl.ts +++ b/src/vs/editor/browser/view/viewImpl.ts @@ -8,14 +8,13 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { IDisposable } from 'vs/base/common/lifecycle'; import * as dom from 'vs/base/browser/dom'; import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode'; -import { ICommandService } from 'vs/platform/commands/common/commands'; import { Range } from 'vs/editor/common/core/range'; import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler'; import { Configuration } from 'vs/editor/browser/config/configuration'; import { TextAreaHandler, ITextAreaHandlerHelper } from 'vs/editor/browser/controller/textAreaHandler'; import { PointerHandler } from 'vs/editor/browser/controller/pointerHandler'; import * as editorBrowser from 'vs/editor/browser/editorBrowser'; -import { ViewController, ExecCoreEditorCommandFunc } from 'vs/editor/browser/view/viewController'; +import { ViewController, ExecCoreEditorCommandFunc, ICommandDelegate } from 'vs/editor/browser/view/viewController'; import { ViewEventDispatcher } from 'vs/editor/common/view/viewEventDispatcher'; import { ContentViewOverlays, MarginViewOverlays } from 'vs/editor/browser/view/viewOverlays'; import { ViewContentWidgets } from 'vs/editor/browser/viewParts/contentWidgets/contentWidgets'; @@ -93,7 +92,7 @@ export class View extends ViewEventHandler { private _renderAnimationFrame: IDisposable; constructor( - commandService: ICommandService, + commandDelegate: ICommandDelegate, configuration: Configuration, themeService: IThemeService, model: IViewModel, @@ -105,7 +104,7 @@ export class View extends ViewEventHandler { this._renderAnimationFrame = null; this.outgoingEvents = new ViewOutgoingEvents(model); - let viewController = new ViewController(configuration, model, execCoreEditorCommandFunc, this.outgoingEvents, commandService); + let viewController = new ViewController(configuration, model, execCoreEditorCommandFunc, this.outgoingEvents, commandDelegate); // The event dispatcher will always go through _renderOnce before dispatching any events this.eventDispatcher = new ViewEventDispatcher((callback: () => void) => this._renderOnce(callback)); diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 058cd4fcf12..934f72d63fa 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -33,6 +33,7 @@ import { Color } from 'vs/base/common/color'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { ClassName } from 'vs/editor/common/model/intervalTree'; import { ITextModel, IModelDecorationOptions } from 'vs/editor/common/model'; +import { ICommandDelegate } from '../view/viewController'; export abstract class CodeEditorWidget extends CommonCodeEditor implements editorBrowser.ICodeEditor { @@ -86,13 +87,14 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito constructor( domElement: HTMLElement, options: IEditorOptions, + isSimpleWidget: boolean, @IInstantiationService instantiationService: IInstantiationService, @ICodeEditorService codeEditorService: ICodeEditorService, @ICommandService commandService: ICommandService, @IContextKeyService contextKeyService: IContextKeyService, @IThemeService themeService: IThemeService ) { - super(domElement, options, instantiationService, contextKeyService); + super(domElement, options, isSimpleWidget, instantiationService, contextKeyService); this._codeEditorService = codeEditorService; this._commandService = commandService; this._themeService = themeService; @@ -358,8 +360,62 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito } protected _createView(): void { + let commandDelegate: ICommandDelegate; + if (this.isSimpleWidget) { + commandDelegate = { + paste: (source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]) => { + this.cursor.trigger(source, editorCommon.Handler.Paste, { text, pasteOnNewLine, multicursorText }); + }, + type: (source: string, text: string) => { + this.cursor.trigger(source, editorCommon.Handler.Type, { text }); + }, + replacePreviousChar: (source: string, text: string, replaceCharCnt: number) => { + this.cursor.trigger(source, editorCommon.Handler.ReplacePreviousChar, { text, replaceCharCnt }); + }, + compositionStart: (source: string) => { + this.cursor.trigger(source, editorCommon.Handler.CompositionStart, undefined); + }, + compositionEnd: (source: string) => { + this.cursor.trigger(source, editorCommon.Handler.CompositionEnd, undefined); + }, + cut: (source: string) => { + this.cursor.trigger(source, editorCommon.Handler.Cut, undefined); + } + }; + } else { + commandDelegate = { + paste: (source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[]) => { + this._commandService.executeCommand(editorCommon.Handler.Paste, { + text: text, + pasteOnNewLine: pasteOnNewLine, + multicursorText: multicursorText + }); + }, + type: (source: string, text: string) => { + this._commandService.executeCommand(editorCommon.Handler.Type, { + text: text + }); + }, + replacePreviousChar: (source: string, text: string, replaceCharCnt: number) => { + this._commandService.executeCommand(editorCommon.Handler.ReplacePreviousChar, { + text: text, + replaceCharCnt: replaceCharCnt + }); + }, + compositionStart: (source: string) => { + this._commandService.executeCommand(editorCommon.Handler.CompositionStart, {}); + }, + compositionEnd: (source: string) => { + this._commandService.executeCommand(editorCommon.Handler.CompositionEnd, {}); + }, + cut: (source: string) => { + this._commandService.executeCommand(editorCommon.Handler.Cut, {}); + } + }; + } + this._view = new View( - this._commandService, + commandDelegate, this._configuration, this._themeService, this.viewModel, diff --git a/src/vs/editor/common/commonCodeEditor.ts b/src/vs/editor/common/commonCodeEditor.ts index ccd5de9f045..1b659d0ae1c 100644 --- a/src/vs/editor/common/commonCodeEditor.ts +++ b/src/vs/editor/common/commonCodeEditor.ts @@ -93,6 +93,7 @@ export abstract class CommonCodeEditor extends Disposable { protected readonly domElement: IContextKeyServiceTarget; protected readonly id: number; protected readonly _configuration: CommonEditorConfiguration; + protected readonly isSimpleWidget: boolean; protected _contributions: { [key: string]: editorCommon.IEditorContribution; }; protected _actions: { [key: string]: editorCommon.IEditorAction; }; @@ -118,6 +119,7 @@ export abstract class CommonCodeEditor extends Disposable { constructor( domElement: IContextKeyServiceTarget, options: editorOptions.IEditorOptions, + isSimpleWidget: boolean, instantiationService: IInstantiationService, contextKeyService: IContextKeyService ) { @@ -126,6 +128,7 @@ export abstract class CommonCodeEditor extends Disposable { this.id = (++EDITOR_ID); this._decorationTypeKeysToIds = {}; this._decorationTypeSubtypes = {}; + this.isSimpleWidget = isSimpleWidget; options = options || {}; this._configuration = this._register(this._createConfiguration(options)); diff --git a/src/vs/editor/contrib/suggest/test/suggestModel.test.ts b/src/vs/editor/contrib/suggest/test/suggestModel.test.ts index 9c6152f2600..c4fcc5c7169 100644 --- a/src/vs/editor/contrib/suggest/test/suggestModel.test.ts +++ b/src/vs/editor/contrib/suggest/test/suggestModel.test.ts @@ -37,7 +37,7 @@ function createMockEditor(model: TextModel): TestCodeEditor { [IStorageService, NullStorageService] )); - const editor = new TestCodeEditor(new MockScopeLocation(), {}, instantiationService, contextKeyService); + const editor = new TestCodeEditor(new MockScopeLocation(), {}, false, instantiationService, contextKeyService); editor.setModel(model); return editor; } diff --git a/src/vs/editor/test/browser/testCodeEditor.ts b/src/vs/editor/test/browser/testCodeEditor.ts index 6661d013fd7..675277aed4d 100644 --- a/src/vs/editor/test/browser/testCodeEditor.ts +++ b/src/vs/editor/test/browser/testCodeEditor.ts @@ -173,7 +173,7 @@ function _createTestCodeEditor(options: TestCodeEditorCreationOptions): TestCode services.set(IContextKeyService, contextKeyService); let instantiationService = new InstantiationService(services); - let editor = new TestCodeEditor(new MockScopeLocation(), options, instantiationService, contextKeyService); + let editor = new TestCodeEditor(new MockScopeLocation(), options, false, instantiationService, contextKeyService); editor.setModel(options.model); return editor; } diff --git a/src/vs/workbench/parts/debug/electron-browser/replEditor.ts b/src/vs/workbench/parts/debug/electron-browser/replEditor.ts index e73098c24ad..177e5fae2ff 100644 --- a/src/vs/workbench/parts/debug/electron-browser/replEditor.ts +++ b/src/vs/workbench/parts/debug/electron-browser/replEditor.ts @@ -30,7 +30,7 @@ export class ReplInputEditor extends CodeEditorWidget { @IContextKeyService contextKeyService: IContextKeyService, @IThemeService themeService: IThemeService ) { - super(domElement, options, instantiationService, codeEditorService, commandService, contextKeyService, themeService); + super(domElement, options, true, instantiationService, codeEditorService, commandService, contextKeyService, themeService); } protected _getContributions(): IEditorContributionCtor[] { -- GitLab