提交 dde41be0 编写于 作者: A Alex Dima

Adopt more of `EditorAction._precondition`

上级 c54515ad
......@@ -89,7 +89,6 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
private accumulatedModelEvents: EmitterEvent[];
private _renderAnimationFrame: IDisposable;
private _keybindingService: IKeybindingService;
private _editorTextFocusContextKey: IKeybindingContextKey<boolean>;
constructor(
......@@ -175,8 +174,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
private createTextArea(keybindingService: IKeybindingService): void {
// Text Area (The focus will always be in the textarea when the cursor is blinking)
this.textArea = <HTMLTextAreaElement>document.createElement('textarea');
this._keybindingService = keybindingService.createScoped(this.textArea);
this._editorTextFocusContextKey = EditorContextKeys.TextFocus.bindTo(this._keybindingService);
this._editorTextFocusContextKey = EditorContextKeys.TextFocus.bindTo(keybindingService);
this.textArea.className = editorBrowser.ClassNames.TEXTAREA;
this.textArea.setAttribute('wrap', 'off');
this.textArea.setAttribute('autocorrect', 'off');
......@@ -508,7 +506,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp
this.viewParts = [];
this.layoutProvider.dispose();
this._keybindingService.dispose();
this._editorTextFocusContextKey.reset();
}
// --- begin Code Editor APIs
......
......@@ -581,7 +581,8 @@ export abstract class CommonCodeEditor extends EventEmitter implements editorCom
public getSupportedActions(): editorCommon.IEditorAction[] {
let result = this.getActions();
result = result.filter(action => action.isSupported());
result = result.filter(action => action.isSupported(true));
return result;
}
......
......@@ -41,9 +41,9 @@ export class InternalEditorAction extends AbstractInternalEditorAction implement
});
}
public isSupported():boolean {
public isSupported(forceEditorTextFocus:boolean):boolean {
return this._instantiationService.invokeFunction((accessor) => {
return this._actual.supported(accessor, this._editor);
return this._actual.supported(accessor, this._editor, forceEditorTextFocus);
});
}
......@@ -68,7 +68,7 @@ export class DynamicEditorAction extends AbstractInternalEditorAction implements
return true;
}
public isSupported():boolean {
public isSupported(forceEditorTextFocus:boolean):boolean {
return true;
}
......
......@@ -3025,12 +3025,12 @@ export namespace EditorContextKeys {
* A context key that is set when the editor's text has focus (cursor is blinking).
* @internal
*/
export const TextFocus = new KbCtxKey<boolean>('editorTextFocus', undefined);
export const TextFocus = new KbCtxKey<boolean>('editorTextFocus', false);
/**
* A context key that is set when the editor's text or an editor's widget has focus.
* @internal
*/
export const Focus = new KbCtxKey<boolean>('editorFocus', undefined);
export const Focus = new KbCtxKey<boolean>('editorFocus', false);
/**
* A context key that is set when the editor's text is readonly.
......@@ -3482,7 +3482,7 @@ export interface IEditorAction {
label: string;
alias: string;
enabled: boolean;
isSupported():boolean;
isSupported(forceEditorTextFocus:boolean):boolean;
run(): TPromise<void>;
}
......
......@@ -8,7 +8,7 @@ import {illegalArgument} from 'vs/base/common/errors';
import URI from 'vs/base/common/uri';
import {TPromise} from 'vs/base/common/winjs.base';
import {ServicesAccessor, IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {KbExpr} from 'vs/platform/keybinding/common/keybinding';
import {KbExpr, IKeybindingService} from 'vs/platform/keybinding/common/keybinding';
import {CommandsRegistry} from 'vs/platform/commands/common/commands';
import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegistry';
import {Registry} from 'vs/platform/platform';
......@@ -33,13 +33,46 @@ export interface IEditorCommandMenuOptions {
// --- Editor Actions
// let recorded: EditorAction[] = [];
function record(desc:EditorAction) {
return;
// let stack = new Error().stack;
// desc.callsite = stack.split('\n')[3];
// recorded.push(desc);
}
function analyze() {
return;
// recorded.sort((a, b) => a.id < b.id ? -1 : (a.id > b.id ? 1 : 0));
// recorded.forEach((desc) => {
// let rightpad = (str:string, cnt:number) => {
// while (str.length < cnt) {
// str = str + ' ';
// }
// return str;
// };
// if (typeof desc._precondition === 'undefined') {
// console.warn('MISSING PRECONDITION FOR ' + desc.id + desc.callsite);
// } else {
// let prec = desc._precondition ? desc._precondition.serialize() : 'null';
// if (desc._needsWritableEditor && prec.indexOf('!editorReadonly') === -1) {
// console.warn('BELOW COMMAND DOES NOT PRECONDITION CORRECTLY WRITABLE!');
// }
// console.log(rightpad(desc.id, 50) + '' + desc._needsWritableEditor + '\t\t' + rightpad(prec, 50) + '\t\t' + desc.callsite);
// }
// });
// recorded = [];
}
export module CommonEditorRegistry {
export function registerEditorAction(desc:EditorAction) {
record(desc);
(<EditorContributionRegistry>Registry.as(Extensions.EditorCommonContributions)).registerEditorAction(desc);
}
export function getEditorActions(): EditorAction[] {
analyze();
return (<EditorContributionRegistry>Registry.as(Extensions.EditorCommonContributions)).getEditorActions();
}
......@@ -152,6 +185,8 @@ export abstract class EditorAction extends ConfigEditorCommand {
public alias: string;
public menuOpts: IEditorCommandMenuOptions;
public _precondition: KbExpr;
constructor(id:string, label:string, alias:string, needsWritableEditor:boolean) {
super(id);
this.label = label;
......@@ -170,17 +205,26 @@ export abstract class EditorAction extends ConfigEditorCommand {
}
public enabled(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): boolean {
if (!this.supported(accessor, editor, false)) {
return false;
}
if (this._needsWritableEditor) {
return !editor.getConfiguration().readOnly;
}
return true;
}
public supported(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): boolean {
if (this._needsWritableEditor) {
return !editor.getConfiguration().readOnly;
public supported(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor, forceEditorTextFocus:boolean): boolean {
const kbService = accessor.get(IKeybindingService);
let override = null;
if (forceEditorTextFocus) {
override = {
editorTextFocus: true
};
}
return true;
return kbService.contextMatchesRules(this._precondition, override);
}
public abstract run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void | TPromise<void>;
......
......@@ -61,20 +61,6 @@ abstract class ClipboardWritingAction extends ExecCommandAction {
}
}
function editorCursorIsInEditableRange(editor:editorCommon.ICommonCodeEditor): boolean {
let model = editor.getModel();
if (!model) {
return false;
}
let hasEditableRange = model.hasEditableRange();
if (!hasEditableRange) {
return true;
}
let editableRange = model.getEditableRange();
let editorPosition = editor.getPosition();
return editableRange.containsPosition(editorPosition);
}
class ExecCommandCutAction extends ClipboardWritingAction {
constructor() {
......@@ -101,13 +87,6 @@ class ExecCommandCutAction extends ClipboardWritingAction {
order: 1
};
}
public enabled(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): boolean {
if (!super.enabled(accessor, editor)) {
return false;
}
return editorCursorIsInEditableRange(editor);
}
}
class ExecCommandCopyAction extends ClipboardWritingAction {
......@@ -164,13 +143,6 @@ class ExecCommandPasteAction extends ExecCommandAction {
order: 3
};
}
public enabled(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): boolean {
if (!super.enabled(accessor, editor)) {
return false;
}
return editorCursorIsInEditableRange(editor);
}
}
if (browser.supportsExecCommand('cut')) {
......
......@@ -29,8 +29,7 @@ import {getDeclarationsAtPosition} from 'vs/editor/contrib/goToDeclaration/commo
import {ReferencesController} from 'vs/editor/contrib/referenceSearch/browser/referencesController';
import {ReferencesModel} from 'vs/editor/contrib/referenceSearch/browser/referencesModel';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import {IPeekViewService} from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget';
import {optional} from 'vs/platform/instantiation/common/instantiation';
import {PeekContext} from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget';
import {KbExpr} from 'vs/platform/keybinding/common/keybinding';
import ModeContextKeys = editorCommon.ModeContextKeys;
......@@ -196,7 +195,6 @@ export class OpenDefinitionToSideAction extends DefinitionAction {
}
export class PeekDefinitionAction extends DefinitionAction {
constructor() {
super(
'editor.action.previewDeclaration',
......@@ -205,7 +203,7 @@ export class PeekDefinitionAction extends DefinitionAction {
new DefinitionActionConfig(void 0, true, false)
);
this._precondition = KbExpr.and(EditorContextKeys.TextFocus, ModeContextKeys.hasDefinitionProvider);
this._precondition = KbExpr.and(EditorContextKeys.TextFocus, ModeContextKeys.hasDefinitionProvider, PeekContext.notInPeekEditor);
this.kbOpts = {
kbExpr: EditorContextKeys.TextFocus,
......@@ -219,15 +217,6 @@ export class PeekDefinitionAction extends DefinitionAction {
kbExpr: ModeContextKeys.hasDefinitionProvider
};
}
public enabled(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): boolean {
if (!super.enabled(accessor, editor)) {
return false;
}
const peekViewService = accessor.get(IPeekViewService, optional);
return (!peekViewService || !peekViewService.isActive);
}
}
// --- Editor Contribution to goto definition using the mouse and a modifier key
......
......@@ -17,10 +17,9 @@ import {Position} from 'vs/editor/common/core/position';
import {Range} from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {ServicesAccessor, EditorAction, CommonEditorRegistry} from 'vs/editor/common/editorCommonExtensions';
import {Location, ReferenceProviderRegistry} from 'vs/editor/common/modes';
import {IPeekViewService, getOuterEditor} from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget';
import {Location} from 'vs/editor/common/modes';
import {IPeekViewService, PeekContext, getOuterEditor} from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget';
import {provideReferences} from '../common/referenceSearch';
import {ReferenceWidget} from './referencesWidget';
import {ReferencesController, RequestOptions, ctxReferenceSearchVisible} from './referencesController';
import {ReferencesModel} from './referencesModel';
......@@ -43,7 +42,7 @@ export class ReferenceController implements editorCommon.IEditorContribution {
@optional(IPeekViewService) peekViewService: IPeekViewService
) {
if (peekViewService) {
peekViewService.contextKey.bindTo(keybindingService);
PeekContext.inPeekEditor.bindTo(keybindingService);
}
}
......@@ -65,7 +64,7 @@ export class ReferenceAction extends EditorAction {
false
);
this._precondition = KbExpr.and(EditorContextKeys.TextFocus, ModeContextKeys.hasReferenceProvider);
this._precondition = KbExpr.and(EditorContextKeys.TextFocus, ModeContextKeys.hasReferenceProvider, PeekContext.notInPeekEditor);
this.kbOpts = {
kbExpr: EditorContextKeys.TextFocus,
......@@ -79,18 +78,6 @@ export class ReferenceAction extends EditorAction {
};
}
public enabled(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): boolean {
if (!super.enabled(accessor, editor)) {
return false;
}
const peekViewService = accessor.get(IPeekViewService, optional);
if (peekViewService && peekViewService.isActive) {
return false;
}
return ReferenceProviderRegistry.has(editor.getModel());
}
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
let range = editor.getSelection();
let model = editor.getModel();
......@@ -187,6 +174,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
weight: CommonEditorRegistry.commandWeight(-101),
primary: KeyCode.Escape,
secondary: [KeyMod.Shift | KeyCode.Escape],
when: KbExpr.and(ReferenceWidget.INNER_EDITOR_CONTEXT_KEY, KbExpr.not('config.editor.stablePeek')),
when: KbExpr.and(PeekContext.inPeekEditor, KbExpr.not('config.editor.stablePeek')),
handler: closeActiveReferenceSearch
});
......@@ -38,7 +38,6 @@ import {ICodeEditor} from 'vs/editor/browser/editorBrowser';
import {EmbeddedCodeEditorWidget} from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
import {PeekViewWidget, IPeekViewService} from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget';
import {FileReferences, OneReference, ReferencesModel} from './referencesModel';
import {KbCtxKey} from 'vs/platform/keybinding/common/keybinding';
class DecorationsManager implements IDisposable {
......@@ -485,8 +484,6 @@ export interface SelectionEvent {
*/
export class ReferenceWidget extends PeekViewWidget {
public static INNER_EDITOR_CONTEXT_KEY = new KbCtxKey<boolean>('inReferenceSearchEditor', true);
private _model: ReferencesModel;
private _decorationsManager: DecorationsManager;
......@@ -508,7 +505,7 @@ export class ReferenceWidget extends PeekViewWidget {
private _contextService: IWorkspaceContextService,
private _instantiationService: IInstantiationService
) {
super(editor, ReferenceWidget.INNER_EDITOR_CONTEXT_KEY, { frameColor: '#007ACC', showFrame: false, showArrow: true, isResizeable: true });
super(editor, { frameColor: '#007ACC', showFrame: false, showArrow: true, isResizeable: true });
this._instantiationService = this._instantiationService.createChild(new ServiceCollection([IPeekViewService, this]));
this.create();
......
......@@ -19,7 +19,6 @@ import {ServicesAccessor, EditorAction, EditorCommand, CommonEditorRegistry} fro
import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions';
import {IRange, ICommonCodeEditor, EditorContextKeys, ModeContextKeys, IEditorContribution} from 'vs/editor/common/editorCommon';
import {BulkEdit, createBulkEdit} from 'vs/editor/common/services/bulkEdit';
import {RenameProviderRegistry} from 'vs/editor/common/modes';
import {ICodeEditor} from 'vs/editor/browser/editorBrowser';
import {rename} from '../common/rename';
import RenameInputField from './renameInputField';
......@@ -170,13 +169,6 @@ export class RenameAction extends EditorAction {
};
}
public enabled(accessor:ServicesAccessor, editor:ICommonCodeEditor): boolean {
if (!super.enabled(accessor, editor)) {
return false;
}
return RenameProviderRegistry.has(editor.getModel());
}
public run(accessor:ServicesAccessor, editor:ICommonCodeEditor): TPromise<void> {
return RenameController.get(editor).run();
}
......
......@@ -19,14 +19,20 @@ import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService';
import {ICodeEditor} from 'vs/editor/browser/editorBrowser';
import {IOptions, ZoneWidget} from './zoneWidget';
import {EmbeddedCodeEditorWidget} from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
import {KbCtxKey} from 'vs/platform/keybinding/common/keybinding';
import {KbExpr, KbCtxKey} from 'vs/platform/keybinding/common/keybinding';
export var IPeekViewService = createDecorator<IPeekViewService>('peekViewService');
export namespace PeekContext {
export const inPeekEditor = new KbCtxKey<boolean>('inReferenceSearchEditor', true);
export const notInPeekEditor:KbExpr = inPeekEditor.toNegated();
}
export const NOT_INNER_EDITOR_CONTEXT_KEY = new KbCtxKey<boolean>('inReferenceSearchEditor', true);
export interface IPeekViewService {
_serviceBrand: any;
isActive: boolean;
contextKey: KbCtxKey<boolean>;
}
export function getOuterEditor(accessor: ServicesAccessor, args: any): ICommonCodeEditor {
......@@ -37,10 +43,9 @@ export function getOuterEditor(accessor: ServicesAccessor, args: any): ICommonCo
return editor;
}
export class PeekViewWidget extends ZoneWidget implements IPeekViewService {
export abstract class PeekViewWidget extends ZoneWidget implements IPeekViewService {
public _serviceBrand: any;
public contextKey: KbCtxKey<boolean>;
private _onDidClose = new Emitter<PeekViewWidget>();
private _isActive = false;
......@@ -52,9 +57,8 @@ export class PeekViewWidget extends ZoneWidget implements IPeekViewService {
protected _actionbarWidget: ActionBar;
protected _bodyElement: HTMLDivElement;
constructor(editor: ICodeEditor, contextKey: KbCtxKey<boolean>, options: IOptions = {}) {
constructor(editor: ICodeEditor, options: IOptions = {}) {
super(editor, options);
this.contextKey = contextKey;
}
public dispose(): void {
......
......@@ -2759,7 +2759,7 @@ declare module monaco.editor {
label: string;
alias: string;
enabled: boolean;
isSupported(): boolean;
isSupported(forceEditorTextFocus: boolean): boolean;
run(): Promise<void>;
}
......
......@@ -186,9 +186,14 @@ export abstract class AbstractKeybindingService {
return new ScopedKeybindingService(this, this._onDidChangeContextKey, domNode);
}
public contextMatchesRules(rules: KbExpr): boolean {
public contextMatchesRules(rules: KbExpr, overrideKeys?:any): boolean {
const ctx = Object.create(null);
this.getContext(this._myContextId).fillInContext(ctx);
if (overrideKeys) {
for (let key in overrideKeys) {
ctx[key] = overrideKeys[key];
}
}
const result = KeybindingResolver.contextMatchesRules(ctx, rules);
// console.group(rules.serialize() + ' -> ' + result);
// rules.keys().forEach(key => { console.log(key, ctx[key]); });
......@@ -257,6 +262,17 @@ export abstract class KeybindingService extends AbstractKeybindingService implem
this._commandService = commandService;
this._statusService = statusService;
this._messageService = messageService;
// Uncomment this to see the contexts continuously logged
// let lastLoggedValue: string = null;
// setInterval(() => {
// let values = Object.keys(this._contexts).map((key) => this._contexts[key]);
// let logValue = values.map(v => JSON.stringify(v._value, null, '\t')).join('\n');
// if (lastLoggedValue !== logValue) {
// lastLoggedValue = logValue;
// console.log(lastLoggedValue);
// }
// }, 2000);
}
protected _beginListening(domNode: HTMLElement): void {
......
......@@ -478,7 +478,7 @@ export interface IKeybindingService {
onDidChangeContext: Event<string[]>;
createKey<T>(key: string, defaultValue: T): IKeybindingContextKey<T>;
contextMatchesRules(rules: KbExpr): boolean;
contextMatchesRules(rules: KbExpr, overrideKeys?:any): boolean;
getContextValue<T>(key: string): T;
createScoped(domNode: IKeybindingScopeLocation): IKeybindingService;
......
......@@ -19,7 +19,7 @@ import {SyncActionDescriptor, ExecuteCommandAction, IMenuService} from 'vs/platf
import {IWorkbenchActionRegistry, Extensions as ActionExtensions} from 'vs/workbench/common/actionRegistry';
import {Registry} from 'vs/platform/platform';
import {QuickOpenHandler, QuickOpenAction} from 'vs/workbench/browser/quickopen';
import {IEditorAction} from 'vs/editor/common/editorCommon';
import {IEditorAction, IEditor} from 'vs/editor/common/editorCommon';
import {matchesWords, matchesPrefix, matchesContiguousSubString, or} from 'vs/base/common/filters';
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
......@@ -268,8 +268,11 @@ export class CommandsHandler extends QuickOpenHandler {
let activeEditorControl = <any>(activeEditor ? activeEditor.getControl() : null);
let editorActions: IEditorAction[] = [];
if (activeEditorControl && types.isFunction(activeEditorControl.getSupportedActions)) {
editorActions = activeEditorControl.getSupportedActions();
if (activeEditorControl) {
let editor = <IEditor>activeEditorControl;
if (types.isFunction(editor.getSupportedActions)) {
editorActions = editor.getSupportedActions();
}
}
let editorEntries = this.editorActionsToEntries(editorActions, searchValue);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册