Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple widget editor that is hidden from extensions #46169

Merged
merged 3 commits into from
Mar 20, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/vs/editor/browser/codeEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[] {
Expand Down
38 changes: 18 additions & 20 deletions src/vs/editor/browser/view/viewController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down
7 changes: 3 additions & 4 deletions src/vs/editor/browser/view/viewImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -93,7 +92,7 @@ export class View extends ViewEventHandler {
private _renderAnimationFrame: IDisposable;

constructor(
commandService: ICommandService,
commandDelegate: ICommandDelegate,
configuration: Configuration,
themeService: IThemeService,
model: IViewModel,
Expand All @@ -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));
Expand Down
60 changes: 58 additions & 2 deletions src/vs/editor/browser/widget/codeEditorWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolute imports


export abstract class CodeEditorWidget extends CommonCodeEditor implements editorBrowser.ICodeEditor {

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 8 additions & 2 deletions src/vs/editor/common/commonCodeEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export abstract class CommonCodeEditor extends Disposable {
private readonly _onDidPaste: Emitter<Range> = this._register(new Emitter<Range>());
public readonly onDidPaste = this._onDidPaste.event;

public readonly isSimpleWidget: boolean;

protected readonly domElement: IContextKeyServiceTarget;
protected readonly id: number;
Expand Down Expand Up @@ -118,6 +119,7 @@ export abstract class CommonCodeEditor extends Disposable {
constructor(
domElement: IContextKeyServiceTarget,
options: editorOptions.IEditorOptions,
isSimpleWidget: boolean,
instantiationService: IInstantiationService,
contextKeyService: IContextKeyService
) {
Expand All @@ -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));
Expand Down Expand Up @@ -1048,6 +1051,7 @@ class EditorContextKeysManager extends Disposable {

private _editor: CommonCodeEditor;
private _editorFocus: IContextKey<boolean>;
private _inputFocus: IContextKey<boolean>;
private _editorTextFocus: IContextKey<boolean>;
private _editorTabMovesFocus: IContextKey<boolean>;
private _editorReadonly: IContextKey<boolean>;
Expand All @@ -1064,6 +1068,7 @@ class EditorContextKeysManager extends Disposable {

contextKeyService.createKey('editorId', editor.getId());
this._editorFocus = EditorContextKeys.focus.bindTo(contextKeyService);
this._inputFocus = EditorContextKeys.inputFocus.bindTo(contextKeyService);
this._editorTextFocus = EditorContextKeys.textFocus.bindTo(contextKeyService);
this._editorTabMovesFocus = EditorContextKeys.tabMovesFocus.bindTo(contextKeyService);
this._editorReadonly = EditorContextKeys.readOnly.bindTo(contextKeyService);
Expand Down Expand Up @@ -1101,8 +1106,9 @@ class EditorContextKeysManager extends Disposable {
}

private _updateFromFocus(): void {
this._editorFocus.set(this._editor.hasWidgetFocus());
this._editorTextFocus.set(this._editor.isFocused());
this._editorFocus.set(this._editor.hasWidgetFocus() && !this._editor.isSimpleWidget);
this._editorTextFocus.set(this._editor.isFocused() && !this._editor.isSimpleWidget);
this._inputFocus.set(this._editor.isFocused());
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/vs/editor/common/editorContextKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export namespace EditorContextKeys {
*/
export const focus = new RawContextKey<boolean>('editorFocus', false);

/**
* A context key that is set when any editor input has focus (regular editor, repl input...).
*/
export const inputFocus = new RawContextKey<boolean>('inputFocus', false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's ask in the stand-up what would be a good name. Perhaps textInputFocus is better than inputFocus, as there might in the future be other types of inputs, like drop downs or radio buttons...


export const readOnly = new RawContextKey<boolean>('editorReadonly', false);
export const writable: ContextKeyExpr = readOnly.toNegated();
export const hasNonEmptySelection = new RawContextKey<boolean>('editorHasSelection', false);
Expand Down
2 changes: 1 addition & 1 deletion src/vs/editor/contrib/suggest/test/suggestModel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/vs/editor/test/browser/testCodeEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's postpone turning the flag to true here until we get the commands sorted out. Otherwise, I don't think cursor left/cursor right will work in the repl.

}

protected _getContributions(): IEditorContributionCtor[] {
Expand Down