diff --git a/src/vs/editor/common/commonCodeEditor.ts b/src/vs/editor/common/commonCodeEditor.ts index f6752175ef623a07945c9897ea58fb49201af336..2ffeb9f41a8ee106ef17e10946e23f442a0a5be9 100644 --- a/src/vs/editor/common/commonCodeEditor.ts +++ b/src/vs/editor/common/commonCodeEditor.ts @@ -160,7 +160,14 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr this._editorTabMovesFocusKey.set(true); } this._editorReadonly.set(this._configuration.editor.readOnly); - this._lifetimeDispose.push(this._configuration.onDidChange((e) => this.emit(editorCommon.EventType.ConfigurationChanged, e))); + this._lifetimeDispose.push(this._configuration.onDidChange((e) => { + if (this._configuration.editor.tabFocusMode) { + this._editorTabMovesFocusKey.set(true); + } else { + this._editorTabMovesFocusKey.reset(); + } + this.emit(editorCommon.EventType.ConfigurationChanged, e); + })); this._telemetryService = telemetryService; this._instantiationService = instantiationService.createChild(new ServiceCollection([IKeybindingService, this._keybindingService])); @@ -215,11 +222,6 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr public updateOptions(newOptions:editorCommon.IEditorOptions): void { this._configuration.updateOptions(newOptions); - if (this._configuration.editor.tabFocusMode) { - this._editorTabMovesFocusKey.set(true); - } else { - this._editorTabMovesFocusKey.reset(); - } this._editorReadonly.set(this._configuration.editor.readOnly); } diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index fc95a843aec424e2c9ccddd0f31ceed0fc546ff4..aa386919c4b2830ce91268dbeef62502633bee9e 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -55,6 +55,38 @@ export const EditorZoom: IEditorZoom = new class { } }; +/** + * Control what pressing Tab does. + * If it is false, pressing Tab or Shift-Tab will be handled by the editor. + * If it is true, pressing Tab or Shift-Tab will move the browser focus. + * Defaults to false. + */ +export interface ITabFocus { + onDidChangeTabFocus:Event; + getTabFocusMode(): boolean; + setTabFocusMode(tabFocusMode:boolean): void; +} + +export const TabFocus: ITabFocus = new class { + private _tabFocus: boolean = false; + + private _onDidChangeTabFocus: Emitter = new Emitter(); + public onDidChangeTabFocus:Event = this._onDidChangeTabFocus.event; + + public getTabFocusMode(): boolean { + return this._tabFocus; + } + + public setTabFocusMode(tabFocusMode:boolean): void { + if (this._tabFocus === tabFocusMode) { + return; + } + + this._tabFocus = tabFocusMode; + this._onDidChangeTabFocus.fire(this._tabFocus); + } +}; + /** * Experimental screen reader support toggle */ @@ -188,7 +220,7 @@ class InternalEditorOptionsHelper { let readOnly = toBoolean(opts.readOnly); - let tabFocusMode = toBoolean(opts.tabFocusMode); + let tabFocusMode = TabFocus.getTabFocusMode(); if (readOnly) { tabFocusMode = true; } @@ -390,6 +422,7 @@ export abstract class CommonEditorConfiguration extends Disposable implements ed this.editor = this._computeInternalOptions(); this.editorClone = this.editor.clone(); this._register(EditorZoom.onDidChangeZoomLevel(_ => this._recomputeOptions())); + this._register(TabFocus.onDidChangeTabFocus(_ => this._recomputeOptions())); } public dispose(): void { diff --git a/src/vs/editor/common/config/defaultConfig.ts b/src/vs/editor/common/config/defaultConfig.ts index 6a074c4a8370dbfac6351f5ee06f0cff12242374..2c96b01efc002628a13c620388c92e5f8a4a1044 100644 --- a/src/vs/editor/common/config/defaultConfig.ts +++ b/src/vs/editor/common/config/defaultConfig.ts @@ -70,7 +70,6 @@ class ConfigClass implements IConfiguration { wordWrapBreakBeforeCharacters: '([{‘“〈《「『【〔([{「£¥$£¥++', wordWrapBreakAfterCharacters: ' \t})]?|&,;¢°′″‰℃、。。、¢,.:;?!%・・ゝゞヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻ァィゥェォャュョッー’”〉》」』】〕)]}」', wordWrapBreakObtrusiveCharacters: '.', - tabFocusMode: false, // Features hover: true, diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 0e12494196768d1b3bbaaa77b68b94124f058f93..cba6dda3700c950a6a91aea2def29ad128eeeccb 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -328,14 +328,6 @@ export interface IEditorOptions { */ wordWrapBreakObtrusiveCharacters?: string; - /** - * Control what pressing Tab does. - * If it is false, pressing Tab or Shift-Tab will be handled by the editor. - * If it is true, pressing Tab or Shift-Tab will move the browser focus. - * Defaults to false. - */ - tabFocusMode?:boolean; - /** * Performance guard: Stop rendering a line after x characters. * Defaults to 10000 if wrappingColumn is -1. Defaults to -1 if wrappingColumn is >= 0. diff --git a/src/vs/editor/contrib/toggleTabFocusMode/common/toggleTabFocusMode.ts b/src/vs/editor/contrib/toggleTabFocusMode/common/toggleTabFocusMode.ts index 2fb536209b425c4cb3080db20b8afab60c741e70..6e0aa974e2bed7e4dd32cb12bcb9054751be036b 100644 --- a/src/vs/editor/contrib/toggleTabFocusMode/common/toggleTabFocusMode.ts +++ b/src/vs/editor/contrib/toggleTabFocusMode/common/toggleTabFocusMode.ts @@ -10,7 +10,9 @@ import {TPromise} from 'vs/base/common/winjs.base'; import {EditorAction} from 'vs/editor/common/editorAction'; import {Behaviour} from 'vs/editor/common/editorActionEnablement'; import {ICommonCodeEditor, IEditorActionDescriptorData} from 'vs/editor/common/editorCommon'; -import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; +import {CommonEditorRegistry, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; +import {TabFocus} from 'vs/editor/common/config/commonEditorConfig'; +import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegistry'; export class ToggleTabFocusModeAction extends EditorAction { @@ -22,11 +24,8 @@ export class ToggleTabFocusModeAction extends EditorAction { public run():TPromise { - if(this.editor.getConfiguration().tabFocusMode) { - this.editor.updateOptions({tabFocusMode: false}); - } else { - this.editor.updateOptions({tabFocusMode: true}); - } + let oldValue = TabFocus.getTabFocusMode(); + TabFocus.setTabFocusMode(!oldValue); return TPromise.as(true); } @@ -34,7 +33,14 @@ export class ToggleTabFocusModeAction extends EditorAction { // register actions CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(ToggleTabFocusModeAction, ToggleTabFocusModeAction.ID, nls.localize('toggle.tabfocusmode', "Toggle Use of Tab Key for Setting Focus"), { - context: ContextKey.EditorTextFocus, + primary: null, + context: null +}, 'Toggle Use of Tab Key for Setting Focus')); + +KeybindingsRegistry.registerCommandRule({ + id: ToggleTabFocusModeAction.ID, + weight: KeybindingsRegistry.WEIGHT.editorContrib(), + when: null, primary: KeyMod.CtrlCmd | KeyCode.KEY_M, mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KEY_M } -}, 'Toggle Use of Tab Key for Setting Focus')); +}); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 2edae9c5e276407b7891393fdec30945ea67c9ae..68cb4d472baf14aba6814a8535011b4f5856fa8a 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1181,13 +1181,6 @@ declare module monaco.editor { * Defaults to '.'. */ wordWrapBreakObtrusiveCharacters?: string; - /** - * Control what pressing Tab does. - * If it is false, pressing Tab or Shift-Tab will be handled by the editor. - * If it is true, pressing Tab or Shift-Tab will move the browser focus. - * Defaults to false. - */ - tabFocusMode?: boolean; /** * Performance guard: Stop rendering a line after x characters. * Defaults to 10000 if wrappingColumn is -1. Defaults to -1 if wrappingColumn is >= 0. diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index c27414481ee2055afa713dbe829d2ccca1e868cf..f67a5e55181caa64586f780415df281cb1edad65 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -23,7 +23,7 @@ import {UntitledEditorInput} from 'vs/workbench/common/editor/untitledEditorInpu import {IFileEditorInput, EncodingMode, IEncodingSupport, asFileEditorInput, getUntitledOrFileResource} from 'vs/workbench/common/editor'; import {IDisposable, combinedDisposable, dispose} from 'vs/base/common/lifecycle'; import {IMessageService, Severity} from 'vs/platform/message/common/message'; -import {ICommonCodeEditor, IConfigurationChangedEvent, IModelContentChangedEvent, IModelOptionsChangedEvent, IModelModeChangedEvent, ICursorPositionChangedEvent} from 'vs/editor/common/editorCommon'; +import {ICommonCodeEditor, 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'; @@ -42,6 +42,7 @@ import {IModeService} from 'vs/editor/common/services/modeService'; import {StyleMutator} from 'vs/base/browser/styleMutator'; import {Selection} from 'vs/editor/common/core/selection'; import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService'; +import {TabFocus} from 'vs/editor/common/config/commonEditorConfig'; function getCodeEditor(editorWidget: IEditor): ICommonCodeEditor { if (editorWidget) { @@ -295,7 +296,8 @@ export class EditorStatus implements IStatusbarItem { } }, this.editorGroupService.onEditorsChanged(() => this.onEditorsChanged()), - this.eventService.addListener2(EventType.RESOURCE_ENCODING_CHANGED, (e: ResourceEvent) => this.onResourceEncodingChange(e.resource)) + this.eventService.addListener2(EventType.RESOURCE_ENCODING_CHANGED, (e: ResourceEvent) => this.onResourceEncodingChange(e.resource)), + TabFocus.onDidChangeTabFocus((e) => this.onTabFocusModeChange()) ); return combinedDisposable(this.toDispose); @@ -428,10 +430,7 @@ export class EditorStatus implements IStatusbarItem { } private onTabFocusModeClick(): void { - let activeEditor = this.editorService.getActiveEditor(); - if (activeEditor instanceof BaseTextEditor && isCodeEditorWithTabFocusMode(activeEditor)) { - (activeEditor.getControl()).updateOptions({ tabFocusMode: false }); - } + TabFocus.setTabFocusMode(false); } private onEditorsChanged(): void { @@ -446,7 +445,6 @@ export class EditorStatus implements IStatusbarItem { this.onModeChange(control); this.onEOLChange(control); this.onEncodingChange(activeEditor); - this.onTabFocusModeChange(activeEditor); this.onIndentationChange(control); // Dispose old active editor listeners @@ -475,11 +473,6 @@ export class EditorStatus implements IStatusbarItem { 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); - })); } } @@ -605,13 +598,8 @@ export class EditorStatus implements IStatusbarItem { } } - private onTabFocusModeChange(e: IBaseEditor): void { - let info: StateDelta = { tabFocusMode: false }; - - // We only support text based editors - if (e instanceof BaseTextEditor && isCodeEditorWithTabFocusMode(e)) { - info = { tabFocusMode: true }; - } + private onTabFocusModeChange(): void { + let info: StateDelta = { tabFocusMode: TabFocus.getTabFocusMode() }; this.updateState(info); } @@ -623,19 +611,6 @@ export class EditorStatus implements IStatusbarItem { } } -function isCodeEditorWithTabFocusMode(e: BaseTextEditor): boolean { - let editorWidget = e.getControl(); - if (editorWidget.getEditorType() === EditorType.IDiffEditor) { - editorWidget = (editorWidget).getModifiedEditor(); - } - if (editorWidget.getEditorType() !== EditorType.ICodeEditor) { - return false; - } - - let editorConfig = (editorWidget).getConfiguration(); - return editorConfig.tabFocusMode && !editorConfig.readOnly; -} - function isWritableCodeEditor(e: BaseTextEditor): boolean { let editorWidget = e.getControl(); if (editorWidget.getEditorType() === EditorType.IDiffEditor) {