From cedc0020142c5d2892c080bfb97e839550a5d693 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 1 Jun 2016 09:54:48 +0200 Subject: [PATCH] get rid of all text editor events emitted on global event bus --- .../browser/parts/editor/editorStatus.ts | 134 ++++++++++-------- .../browser/parts/editor/textEditor.ts | 32 +---- src/vs/workbench/common/events.ts | 39 ----- .../services/history/browser/history.ts | 44 +++--- 4 files changed, 94 insertions(+), 155 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 65dacba80c3..04e1aade822 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -21,15 +21,15 @@ import {language, LANGUAGE_DEFAULT} from 'vs/base/common/platform'; import {IMode} from 'vs/editor/common/modes'; import {UntitledEditorInput} from 'vs/workbench/common/editor/untitledEditorInput'; import {IFileEditorInput, EncodingMode, IEncodingSupport, asFileEditorInput, getUntitledOrFileResource} from 'vs/workbench/common/editor'; -import {IDisposable, combinedDisposable} from 'vs/base/common/lifecycle'; +import {IDisposable, combinedDisposable, dispose} from 'vs/base/common/lifecycle'; import {IMessageService, Severity} from 'vs/platform/message/common/message'; -import {ICommonCodeEditor} from 'vs/editor/common/editorCommon'; +import {ICommonCodeEditor, IConfigurationChangedEvent, IModelContentChangedEvent, IModelOptionsChangedEvent, IModelModeChangedEvent, ICursorPositionChangedEvent} from 'vs/editor/common/editorCommon'; import {OpenGlobalSettingsAction} from 'vs/workbench/browser/actions/openSettings'; import {ICodeEditor, IDiffEditor} from 'vs/editor/browser/editorBrowser'; import {TrimTrailingWhitespaceAction} from 'vs/editor/contrib/linesOperations/common/linesOperations'; import {EndOfLineSequence, ITokenizedModel, EditorType, ITextModel, IDiffEditorModel, IEditor} from 'vs/editor/common/editorCommon'; import {IndentUsingSpaces, IndentUsingTabs, DetectIndentation, IndentationToSpacesAction, IndentationToTabsAction} from 'vs/editor/contrib/indentation/common/indentation'; -import {EventType, ResourceEvent, EditorEvent, TextEditorSelectionEvent} from 'vs/workbench/common/events'; +import {EventType, ResourceEvent, EditorEvent} from 'vs/workbench/common/events'; import {BaseTextEditor} from 'vs/workbench/browser/parts/editor/textEditor'; import {IEditor as IBaseEditor} from 'vs/platform/editor/common/editor'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; @@ -42,16 +42,14 @@ import {IModeService} from 'vs/editor/common/services/modeService'; import {StyleMutator} from 'vs/base/browser/styleMutator'; import {Selection} from 'vs/editor/common/core/selection'; -function getCodeEditor(e: IBaseEditor): ICommonCodeEditor { - if (e instanceof BaseTextEditor) { - let editorWidget = e.getControl(); +function getCodeEditor(editorWidget: IEditor): ICommonCodeEditor { + if (editorWidget) { if (editorWidget.getEditorType() === EditorType.IDiffEditor) { return (editorWidget).getModifiedEditor(); } if (editorWidget.getEditorType() === EditorType.ICodeEditor) { return (editorWidget); } - return null; } return null; } @@ -231,6 +229,7 @@ export class EditorStatus implements IStatusbarItem { private eolElement: HTMLElement; private modeElement: HTMLElement; private toDispose: IDisposable[]; + private activeEditorListeners: IDisposable[]; private delayedRender: IDisposable; private toRender: StateChange; @@ -243,6 +242,7 @@ export class EditorStatus implements IStatusbarItem { @IConfigurationService private configurationService: IConfigurationService ) { this.toDispose = []; + this.activeEditorListeners = []; this.state = new State(); } @@ -292,13 +292,8 @@ export class EditorStatus implements IStatusbarItem { } } }, - this.eventService.addListener2(EventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChange(e.editor)), - this.eventService.addListener2(EventType.RESOURCE_ENCODING_CHANGED, (e: ResourceEvent) => this.onResourceEncodingChange(e.resource)), - this.eventService.addListener2(EventType.TEXT_EDITOR_SELECTION_CHANGED, (e: TextEditorSelectionEvent) => this.onSelectionChange(e.editor)), - this.eventService.addListener2(EventType.TEXT_EDITOR_MODE_CHANGED, (e: EditorEvent) => this.onModeChange(e.editor)), - this.eventService.addListener2(EventType.TEXT_EDITOR_CONTENT_CHANGED, (e: EditorEvent) => this.onEOLChange(e.editor)), - this.eventService.addListener2(EventType.TEXT_EDITOR_CONFIGURATION_CHANGED, (e: EditorEvent) => this.onTabFocusModeChange(e.editor)), - this.eventService.addListener2(EventType.TEXT_EDITOR_CONTENT_OPTIONS_CHANGED, (e: EditorEvent) => this.onIndentationChange(e.editor)) + this.eventService.addListener2(EventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChanged(e.editor)), + this.eventService.addListener2(EventType.RESOURCE_ENCODING_CHANGED, (e: ResourceEvent) => this.onResourceEncodingChange(e.resource)) ); return combinedDisposable(this.toDispose); @@ -437,25 +432,60 @@ export class EditorStatus implements IStatusbarItem { } } - private onEditorInputChange(e: IBaseEditor): void { - this.onSelectionChange(e); - this.onModeChange(e); - this.onEOLChange(e); + private onEditorInputChanged(e: IBaseEditor): void { + let control: IEditor; + const activeEditor = this.editorService.getActiveEditor(); + if (activeEditor instanceof BaseTextEditor) { + control = activeEditor.getControl(); + } + + // Update all states + this.onSelectionChange(control); + this.onModeChange(control); + this.onEOLChange(control); this.onEncodingChange(e); this.onTabFocusModeChange(e); - this.onIndentationChange(e); - } + this.onIndentationChange(control); - private onModeChange(e: IBaseEditor): void { - if (e && !this.isActiveEditor(e)) { - return; + // Dispose old active editor listeners + dispose(this.activeEditorListeners); + + // Attach new listeners to active editor + if (activeEditor instanceof BaseTextEditor) { + const control = activeEditor.getControl(); + + // Hook Listener for Selection changes + this.activeEditorListeners.push(control.onDidChangeCursorPosition((event: ICursorPositionChangedEvent) => { + this.onSelectionChange(control); + })); + + // Hook Listener for mode changes + this.activeEditorListeners.push(control.onDidChangeModelMode((event: IModelModeChangedEvent) => { + this.onModeChange(control); + })); + + // Hook Listener for content changes + this.activeEditorListeners.push(control.onDidChangeModelRawContent((event: IModelContentChangedEvent) => { + this.onEOLChange(control); + })); + + // Hook Listener for content options changes + this.activeEditorListeners.push(control.onDidChangeModelOptions((event: IModelOptionsChangedEvent) => { + this.onIndentationChange(control); + })); + + // Hook Listener for options changes + this.activeEditorListeners.push(control.onDidChangeConfiguration((event: IConfigurationChangedEvent) => { + this.onTabFocusModeChange(activeEditor); + })); } + } + private onModeChange(editorWidget?: IEditor): void { let info: StateDelta = { mode: null }; // We only support text based editors - if (e instanceof BaseTextEditor) { - let editorWidget = e.getControl(); + if (editorWidget) { let textModel = getTextModel(editorWidget); if (textModel) { // Compute mode @@ -471,45 +501,33 @@ export class EditorStatus implements IStatusbarItem { this.updateState(info); } - private onIndentationChange(e: IBaseEditor): void { - if (e && !this.isActiveEditor(e)) { - return; - } - + private onIndentationChange(editorWidget?: IEditor): void { const update: StateDelta = { indentation: null }; - if (e instanceof BaseTextEditor) { - let editorWidget = e.getControl(); - if (editorWidget) { - if (editorWidget.getEditorType() === EditorType.IDiffEditor) { - editorWidget = (editorWidget).getModifiedEditor(); - } + if (editorWidget) { + if (editorWidget.getEditorType() === EditorType.IDiffEditor) { + editorWidget = (editorWidget).getModifiedEditor(); + } - const model = (editorWidget).getModel(); - if (model) { - const modelOpts = model.getOptions(); - update.indentation = ( - modelOpts.insertSpaces - ? nls.localize('spacesSize', "Spaces: {0}", modelOpts.tabSize) - : nls.localize({ key: 'tabSize', comment: ['Tab corresponds to the tab key'] }, "Tab Size: {0}", modelOpts.tabSize) - ); - } + const model = (editorWidget).getModel(); + if (model) { + const modelOpts = model.getOptions(); + update.indentation = ( + modelOpts.insertSpaces + ? nls.localize('spacesSize', "Spaces: {0}", modelOpts.tabSize) + : nls.localize({ key: 'tabSize', comment: ['Tab corresponds to the tab key'] }, "Tab Size: {0}", modelOpts.tabSize) + ); } } this.updateState(update); } - private onSelectionChange(e: IBaseEditor): void { - if (e && !this.isActiveEditor(e)) { - return; - } - + private onSelectionChange(editorWidget?: IEditor): void { let info: IEditorSelectionStatus = {}; // We only support text based editors - if (e instanceof BaseTextEditor) { - let editorWidget = e.getControl(); + if (editorWidget) { // Compute selection(s) info.selections = editorWidget.getSelections() || []; @@ -537,14 +555,10 @@ export class EditorStatus implements IStatusbarItem { this.updateState({ selectionStatus: this.getSelectionLabel(info) }); } - private onEOLChange(e: IBaseEditor): void { - if (e && !this.isActiveEditor(e)) { - return; - } - + private onEOLChange(editorWidget?: IEditor): void { let info: StateDelta = { EOL: null }; - let codeEditor = getCodeEditor(e); + let codeEditor = getCodeEditor(editorWidget); if (codeEditor && !codeEditor.getConfiguration().readOnly) { let codeEditorModel = codeEditor.getModel(); if (codeEditorModel) { @@ -590,10 +604,6 @@ export class EditorStatus implements IStatusbarItem { } private onTabFocusModeChange(e: IBaseEditor): void { - if (e && !this.isActiveEditor(e)) { - return; - } - let info: StateDelta = { tabFocusMode: false }; // We only support text based editors diff --git a/src/vs/workbench/browser/parts/editor/textEditor.ts b/src/vs/workbench/browser/parts/editor/textEditor.ts index c310f252caa..73c2367aada 100644 --- a/src/vs/workbench/browser/parts/editor/textEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textEditor.ts @@ -10,12 +10,12 @@ import {Dimension, Builder} from 'vs/base/browser/builder'; import objects = require('vs/base/common/objects'); import {CodeEditorWidget} from 'vs/editor/browser/widget/codeEditorWidget'; import {IEditorViewState} from 'vs/editor/common/editorCommon'; -import {OptionsChangeEvent, EventType as WorkbenchEventType, EditorEvent, TextEditorSelectionEvent} from 'vs/workbench/common/events'; +import {OptionsChangeEvent, EventType as WorkbenchEventType} from 'vs/workbench/common/events'; import {Scope} from 'vs/workbench/common/memento'; import {EditorInput, EditorOptions} from 'vs/workbench/common/editor'; import {BaseEditor} from 'vs/workbench/browser/parts/editor/baseEditor'; import {EditorConfiguration} from 'vs/editor/common/config/commonEditorConfig'; -import {IEditor, EventType, IConfigurationChangedEvent, IModelContentChangedEvent, IModelOptionsChangedEvent, IModelModeChangedEvent, ICursorPositionChangedEvent, IEditorOptions} from 'vs/editor/common/editorCommon'; +import {IEditor, EventType, IEditorOptions} from 'vs/editor/common/editorCommon'; import {IWorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService'; import {IFilesConfiguration} from 'vs/platform/files/common/files'; import {Position} from 'vs/platform/editor/common/editor'; @@ -59,7 +59,7 @@ export abstract class BaseTextEditor extends BaseEditor { this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.applyConfiguration(e.config))); this.toUnbind.push(_themeService.onDidThemeChange(_ => this.onThemeChanged())); -} + } public get instantiationService(): IInstantiationService { return this._instantiationService; @@ -133,32 +133,6 @@ export abstract class BaseTextEditor extends BaseEditor { this._editorContainer = parent; this.editorControl = this.createEditorControl(parent); - // Hook Listener for Selection changes - this.toUnbind.push(this.editorControl.onDidChangeCursorPosition((event: ICursorPositionChangedEvent) => { - let selection = this.editorControl.getSelection(); - this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_SELECTION_CHANGED, new TextEditorSelectionEvent(selection, this, this.input, null, this.position, event)); - })); - - // Hook Listener for mode changes - this.toUnbind.push(this.editorControl.onDidChangeModelMode((event: IModelModeChangedEvent) => { - this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_MODE_CHANGED, new EditorEvent(this, this.input, null, this.position, event)); - })); - - // Hook Listener for content changes - this.toUnbind.push(this.editorControl.onDidChangeModelRawContent((event: IModelContentChangedEvent) => { - this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_CONTENT_CHANGED, new EditorEvent(this, this.input, null, this.position, event)); - })); - - // Hook Listener for content options changes - this.toUnbind.push(this.editorControl.onDidChangeModelOptions((event: IModelOptionsChangedEvent) => { - this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_CONTENT_OPTIONS_CHANGED, new EditorEvent(this, this.input, null, this.position, event)); - })); - - // Hook Listener for options changes - this.toUnbind.push(this.editorControl.onDidChangeConfiguration((event: IConfigurationChangedEvent) => { - this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_CONFIGURATION_CHANGED, new EditorEvent(this, this.input, null, this.position, event)); - })); - // Configuration this.applyConfiguration(this.configurationService.getConfiguration()); } diff --git a/src/vs/workbench/common/events.ts b/src/vs/workbench/common/events.ts index e31fb8d119d..250e9f2a7f3 100644 --- a/src/vs/workbench/common/events.ts +++ b/src/vs/workbench/common/events.ts @@ -9,7 +9,6 @@ import {Event} from 'vs/base/common/events'; import {IEditor, IEditorInput} from 'vs/platform/editor/common/editor'; import {EditorOptions} from 'vs/workbench/common/editor'; import {Position} from 'vs/platform/editor/common/editor'; -import {Selection} from 'vs/editor/common/core/selection'; /** * All workbench events are listed here. @@ -62,31 +61,6 @@ export class EventType { */ static EDITOR_POSITION_CHANGED = 'editorPositionChanged'; - /** - * An event type that fires when a text editor changes its selection. - */ - static TEXT_EDITOR_SELECTION_CHANGED = 'textEditorSelectionChanged'; - - /** - * An event type that fires when a text editor mode changes. - */ - static TEXT_EDITOR_MODE_CHANGED = 'textEditorModeChanged'; - - /** - * An event type that fires when a text editor content changes. - */ - static TEXT_EDITOR_CONTENT_CHANGED = 'textEditorContentChanged'; - - /** - * An event type that fires when a text editor content options changed. - */ - static TEXT_EDITOR_CONTENT_OPTIONS_CHANGED = 'textEditorContentOptionsChanged'; - - /** - * An event type that fires when a text editor's configuration changes. - */ - static TEXT_EDITOR_CONFIGURATION_CHANGED = 'textEditorOptionsChanged'; - /** * Event type for when a composite is about to open. */ @@ -155,19 +129,6 @@ export class EditorEvent extends Event { } } -/** - * A subclass of EditorEvent for text editor selection changes. - */ -export class TextEditorSelectionEvent extends EditorEvent { - public selection: Selection; - - constructor(selection: Selection, editor: IEditor, editorInput: IEditorInput, editorOptions: EditorOptions, position: Position, originalEvent?: any) { - super(editor, editorInput, editorOptions, position, originalEvent); - - this.selection = selection; - } -} - /** * Option change events are send when the options in the running instance change. */ diff --git a/src/vs/workbench/services/history/browser/history.ts b/src/vs/workbench/services/history/browser/history.ts index 3fa2bd872f5..837fde2012f 100644 --- a/src/vs/workbench/services/history/browser/history.ts +++ b/src/vs/workbench/services/history/browser/history.ts @@ -11,7 +11,7 @@ import {EventType} from 'vs/base/common/events'; import {IEditor as IBaseEditor} from 'vs/platform/editor/common/editor'; import {TextEditorOptions, EditorInput} from 'vs/workbench/common/editor'; import {BaseTextEditor} from 'vs/workbench/browser/parts/editor/textEditor'; -import {EditorEvent, TextEditorSelectionEvent, EventType as WorkbenchEventType} from 'vs/workbench/common/events'; +import {EditorEvent, EventType as WorkbenchEventType} from 'vs/workbench/common/events'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {IHistoryService} from 'vs/workbench/services/history/common/history'; import {Selection} from 'vs/editor/common/core/selection'; @@ -67,7 +67,7 @@ interface IInputWithPath { export abstract class BaseHistoryService { protected toUnbind: IDisposable[]; - private activeEditorUnbind: IDisposable; + private activeEditorListeners: IDisposable[]; constructor( private eventService: IEventService, @@ -75,28 +75,13 @@ export abstract class BaseHistoryService { protected contextService: IWorkspaceContextService ) { this.toUnbind = []; + this.activeEditorListeners = []; // Window Title window.document.title = this.getWindowTitle(null); // Editor Input Changes this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChanged(e))); - - // Text Editor Selection Changes - this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.TEXT_EDITOR_SELECTION_CHANGED, (event: TextEditorSelectionEvent) => this.onTextEditorSelectionChanged(event))); - } - - private onTextEditorSelectionChanged(event: TextEditorSelectionEvent): void { - - // If an active editor is set, but is different from the one from the event, prevent update because the editor is not active. - let editor = event.editor; - let activeEditor = this.editorService.getActiveEditor(); - if (activeEditor && editor && activeEditor !== editor) { - return; - } - - // Delegate to implementors - this.handleEditorSelectionChangeEvent(event.editor); } private onEditorInputChanged(event: EditorEvent): void { @@ -104,17 +89,26 @@ export abstract class BaseHistoryService { // Propagate to history this.onEditorEvent(event.editor); - // Stop old listener - if (this.activeEditorUnbind) { - this.activeEditorUnbind.dispose(); - } + // Dispose old listeners + dispose(this.activeEditorListeners); + this.activeEditorListeners = []; + + let activeEditor = this.editorService.getActiveEditor(); + let activeInput = activeEditor ? activeEditor.input : void 0; // Apply listener for dirty changes - let activeInput = this.editorService.getActiveEditorInput(); if (activeInput instanceof EditorInput) { - this.activeEditorUnbind = activeInput.onDidChangeDirty(() => { + this.activeEditorListeners.push(activeInput.onDidChangeDirty(() => { this.updateWindowTitle(activeInput); // Calculate New Window Title when dirty state changes - }); + })); + } + + // Apply listener for selection changes if this is a text editor + if (activeEditor instanceof BaseTextEditor) { + const control = activeEditor.getControl(); + this.activeEditorListeners.push(control.onDidChangeCursorPosition(event => { + this.handleEditorSelectionChangeEvent(activeEditor); + })); } } -- GitLab