mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-07 01:25:38 -05:00
Merge from vscode 7eaf220cafb9d9e901370ffce02229171cbf3ea6
This commit is contained in:
committed by
Anthony Dresser
parent
39d9eed585
commit
a63578e6f7
@@ -17,6 +17,7 @@ import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKe
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
interface CurrentChord {
|
||||
keypress: string;
|
||||
@@ -34,6 +35,7 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
|
||||
private _currentChord: CurrentChord | null;
|
||||
private _currentChordChecker: IntervalTimer;
|
||||
private _currentChordStatusMessage: IDisposable | null;
|
||||
protected _logging: boolean;
|
||||
|
||||
public get inChordMode(): boolean {
|
||||
return !!this._currentChord;
|
||||
@@ -44,12 +46,14 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
|
||||
protected _commandService: ICommandService,
|
||||
protected _telemetryService: ITelemetryService,
|
||||
private _notificationService: INotificationService,
|
||||
protected _logService: ILogService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this._currentChord = null;
|
||||
this._currentChordChecker = new IntervalTimer();
|
||||
this._currentChordStatusMessage = null;
|
||||
this._logging = false;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
@@ -69,6 +73,19 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
|
||||
return '';
|
||||
}
|
||||
|
||||
public toggleLogging(): boolean {
|
||||
this._logging = !this._logging;
|
||||
return this._logging;
|
||||
}
|
||||
|
||||
protected _log(str: string): void {
|
||||
if (this._logging) {
|
||||
this._logService.info(`[KeybindingService]: ${str}`);
|
||||
} else {
|
||||
this._logService.trace(`[KeybindingService]: ${str}`);
|
||||
}
|
||||
}
|
||||
|
||||
public getDefaultKeybindings(): readonly ResolvedKeybindingItem[] {
|
||||
return this._getResolver().getDefaultKeybindings();
|
||||
}
|
||||
@@ -168,6 +185,7 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
|
||||
}
|
||||
const [firstPart,] = keybinding.getDispatchParts();
|
||||
if (firstPart === null) {
|
||||
this._log(`\\ Keyboard event cannot be dispatched.`);
|
||||
// cannot be dispatched, probably only modifier keys
|
||||
return shouldPreventDefault;
|
||||
}
|
||||
@@ -177,6 +195,8 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
|
||||
const keypressLabel = keybinding.getLabel();
|
||||
const resolveResult = this._getResolver().resolve(contextValue, currentChord, firstPart);
|
||||
|
||||
this._logService.trace('KeybindingService#dispatch', keypressLabel, resolveResult?.commandId);
|
||||
|
||||
if (resolveResult && resolveResult.enterChord) {
|
||||
shouldPreventDefault = true;
|
||||
this._enterChordMode(firstPart, keypressLabel);
|
||||
|
||||
@@ -103,6 +103,8 @@ export interface IKeybindingService {
|
||||
|
||||
registerSchemaContribution(contribution: KeybindingsSchemaContribution): void;
|
||||
|
||||
toggleLogging(): boolean;
|
||||
|
||||
_dumpDebugInfo(): string;
|
||||
_dumpDebugInfoJSON(): string;
|
||||
}
|
||||
|
||||
@@ -20,13 +20,19 @@ export interface IResolveResult {
|
||||
}
|
||||
|
||||
export class KeybindingResolver {
|
||||
private readonly _log: (str: string) => void;
|
||||
private readonly _defaultKeybindings: ResolvedKeybindingItem[];
|
||||
private readonly _keybindings: ResolvedKeybindingItem[];
|
||||
private readonly _defaultBoundCommands: Map<string, boolean>;
|
||||
private readonly _map: Map<string, ResolvedKeybindingItem[]>;
|
||||
private readonly _lookupMap: Map<string, ResolvedKeybindingItem[]>;
|
||||
|
||||
constructor(defaultKeybindings: ResolvedKeybindingItem[], overrides: ResolvedKeybindingItem[]) {
|
||||
constructor(
|
||||
defaultKeybindings: ResolvedKeybindingItem[],
|
||||
overrides: ResolvedKeybindingItem[],
|
||||
log: (str: string) => void
|
||||
) {
|
||||
this._log = log;
|
||||
this._defaultKeybindings = defaultKeybindings;
|
||||
|
||||
this._defaultBoundCommands = new Map<string, boolean>();
|
||||
@@ -254,6 +260,7 @@ export class KeybindingResolver {
|
||||
}
|
||||
|
||||
public resolve(context: IContext, currentChord: string | null, keypress: string): IResolveResult | null {
|
||||
this._log(`| Resolving ${keypress}${currentChord ? ` chorded from ${currentChord}` : ``}`);
|
||||
let lookupMap: ResolvedKeybindingItem[] | null = null;
|
||||
|
||||
if (currentChord !== null) {
|
||||
@@ -262,6 +269,7 @@ export class KeybindingResolver {
|
||||
const candidates = this._map.get(currentChord);
|
||||
if (typeof candidates === 'undefined') {
|
||||
// No chords starting with `currentChord`
|
||||
this._log(`\\ No keybinding entries.`);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -277,6 +285,7 @@ export class KeybindingResolver {
|
||||
const candidates = this._map.get(keypress);
|
||||
if (typeof candidates === 'undefined') {
|
||||
// No bindings with `keypress`
|
||||
this._log(`\\ No keybinding entries.`);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -285,11 +294,13 @@ export class KeybindingResolver {
|
||||
|
||||
let result = this._findCommand(context, lookupMap);
|
||||
if (!result) {
|
||||
this._log(`\\ From ${lookupMap.length} keybinding entries, no when clauses matched the context.`);
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO@chords
|
||||
if (currentChord === null && result.keypressParts.length > 1 && result.keypressParts[1] !== null) {
|
||||
this._log(`\\ From ${lookupMap.length} keybinding entries, matched chord, when: ${printWhenExplanation(result.when)}, source: ${printSourceExplanation(result)}.`);
|
||||
return {
|
||||
enterChord: true,
|
||||
leaveChord: false,
|
||||
@@ -299,6 +310,7 @@ export class KeybindingResolver {
|
||||
};
|
||||
}
|
||||
|
||||
this._log(`\\ From ${lookupMap.length} keybinding entries, matched ${result.command}, when: ${printWhenExplanation(result.when)}, source: ${printSourceExplanation(result)}.`);
|
||||
return {
|
||||
enterChord: false,
|
||||
leaveChord: result.keypressParts.length > 1,
|
||||
@@ -362,3 +374,23 @@ export class KeybindingResolver {
|
||||
return unboundCommands;
|
||||
}
|
||||
}
|
||||
|
||||
function printWhenExplanation(when: ContextKeyExpression | undefined): string {
|
||||
if (!when) {
|
||||
return `no when condition`;
|
||||
}
|
||||
return `${when.serialize()}`;
|
||||
}
|
||||
|
||||
function printSourceExplanation(kb: ResolvedKeybindingItem): string {
|
||||
if (kb.isDefault) {
|
||||
if (kb.extensionId) {
|
||||
return `built-in extension ${kb.extensionId}`;
|
||||
}
|
||||
return `built-in`;
|
||||
}
|
||||
if (kb.extensionId) {
|
||||
return `user extension ${kb.extensionId}`;
|
||||
}
|
||||
return `user`;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface IKeybindingItem {
|
||||
when: ContextKeyExpression | null | undefined;
|
||||
weight1: number;
|
||||
weight2: number;
|
||||
extensionId: string | null;
|
||||
}
|
||||
|
||||
export interface IKeybindings {
|
||||
@@ -51,6 +52,7 @@ export interface IKeybindingRule2 {
|
||||
args?: any;
|
||||
weight: number;
|
||||
when: ContextKeyExpression | undefined;
|
||||
extensionId?: string;
|
||||
}
|
||||
|
||||
export const enum KeybindingWeight {
|
||||
@@ -161,7 +163,8 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
|
||||
commandArgs: rule.args,
|
||||
when: rule.when,
|
||||
weight1: rule.weight,
|
||||
weight2: 0
|
||||
weight2: 0,
|
||||
extensionId: rule.extensionId || null
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -219,7 +222,8 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
|
||||
commandArgs: commandArgs,
|
||||
when: when,
|
||||
weight1: weight1,
|
||||
weight2: weight2
|
||||
weight2: weight2,
|
||||
extensionId: null
|
||||
});
|
||||
this._cachedMergedKeybindings = null;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,9 @@ export class ResolvedKeybindingItem {
|
||||
public readonly commandArgs: any;
|
||||
public readonly when: ContextKeyExpression | undefined;
|
||||
public readonly isDefault: boolean;
|
||||
public readonly extensionId: string | null;
|
||||
|
||||
constructor(resolvedKeybinding: ResolvedKeybinding | undefined, command: string | null, commandArgs: any, when: ContextKeyExpression | undefined, isDefault: boolean) {
|
||||
constructor(resolvedKeybinding: ResolvedKeybinding | undefined, command: string | null, commandArgs: any, when: ContextKeyExpression | undefined, isDefault: boolean, extensionId: string | null) {
|
||||
this.resolvedKeybinding = resolvedKeybinding;
|
||||
this.keypressParts = resolvedKeybinding ? removeElementsAfterNulls(resolvedKeybinding.getDispatchParts()) : [];
|
||||
this.bubble = (command ? command.charCodeAt(0) === CharCode.Caret : false);
|
||||
@@ -26,6 +27,7 @@ export class ResolvedKeybindingItem {
|
||||
this.commandArgs = commandArgs;
|
||||
this.when = when;
|
||||
this.isDefault = isDefault;
|
||||
this.extensionId = extensionId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayo
|
||||
import { INotification, INotificationService, IPromptChoice, IPromptOptions, NoOpNotification, IStatusMessageOptions } from 'vs/platform/notification/common/notification';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
|
||||
function createContext(ctx: any) {
|
||||
return {
|
||||
@@ -36,7 +37,7 @@ suite('AbstractKeybindingService', () => {
|
||||
commandService: ICommandService,
|
||||
notificationService: INotificationService
|
||||
) {
|
||||
super(contextKeyService, commandService, NullTelemetryService, notificationService);
|
||||
super(contextKeyService, commandService, NullTelemetryService, notificationService, new NullLogService());
|
||||
this._resolver = resolver;
|
||||
}
|
||||
|
||||
@@ -167,7 +168,7 @@ suite('AbstractKeybindingService', () => {
|
||||
setFilter() { }
|
||||
};
|
||||
|
||||
let resolver = new KeybindingResolver(items, []);
|
||||
let resolver = new KeybindingResolver(items, [], () => { });
|
||||
|
||||
return new TestKeybindingService(resolver, contextKeyService, commandService, notificationService);
|
||||
};
|
||||
@@ -189,7 +190,8 @@ suite('AbstractKeybindingService', () => {
|
||||
command,
|
||||
null,
|
||||
when,
|
||||
true
|
||||
true,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ suite('KeybindingResolver', () => {
|
||||
command,
|
||||
commandArgs,
|
||||
when,
|
||||
isDefault
|
||||
isDefault,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,7 +45,7 @@ suite('KeybindingResolver', () => {
|
||||
assert.equal(KeybindingResolver.contextMatchesRules(createContext({ bar: 'baz' }), contextRules), true);
|
||||
assert.equal(KeybindingResolver.contextMatchesRules(createContext({ bar: 'bz' }), contextRules), false);
|
||||
|
||||
let resolver = new KeybindingResolver([keybindingItem], []);
|
||||
let resolver = new KeybindingResolver([keybindingItem], [], () => { });
|
||||
assert.equal(resolver.resolve(createContext({ bar: 'baz' }), null, getDispatchStr(runtimeKeybinding))!.commandId, 'yes');
|
||||
assert.equal(resolver.resolve(createContext({ bar: 'bz' }), null, getDispatchStr(runtimeKeybinding)), null);
|
||||
});
|
||||
@@ -56,7 +57,7 @@ suite('KeybindingResolver', () => {
|
||||
let contextRules = ContextKeyExpr.equals('bar', 'baz');
|
||||
let keybindingItem = kbItem(keybinding, 'yes', commandArgs, contextRules, true);
|
||||
|
||||
let resolver = new KeybindingResolver([keybindingItem], []);
|
||||
let resolver = new KeybindingResolver([keybindingItem], [], () => { });
|
||||
assert.equal(resolver.resolve(createContext({ bar: 'baz' }), null, getDispatchStr(runtimeKeybinding))!.commandArgs, commandArgs);
|
||||
});
|
||||
|
||||
@@ -307,7 +308,7 @@ suite('KeybindingResolver', () => {
|
||||
)
|
||||
];
|
||||
|
||||
let resolver = new KeybindingResolver(items, []);
|
||||
let resolver = new KeybindingResolver(items, [], () => { });
|
||||
|
||||
let testKey = (commandId: string, expectedKeys: number[]) => {
|
||||
// Test lookup
|
||||
|
||||
@@ -136,6 +136,10 @@ export class MockKeybindingService implements IKeybindingService {
|
||||
return false;
|
||||
}
|
||||
|
||||
public toggleLogging(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
public _dumpDebugInfo(): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user