Merge from vscode 7eaf220cafb9d9e901370ffce02229171cbf3ea6

This commit is contained in:
ADS Merger
2020-09-03 02:34:56 +00:00
committed by Anthony Dresser
parent 39d9eed585
commit a63578e6f7
519 changed files with 14338 additions and 6670 deletions

View File

@@ -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);

View File

@@ -103,6 +103,8 @@ export interface IKeybindingService {
registerSchemaContribution(contribution: KeybindingsSchemaContribution): void;
toggleLogging(): boolean;
_dumpDebugInfo(): string;
_dumpDebugInfoJSON(): string;
}

View File

@@ -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`;
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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
);
}

View File

@@ -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

View File

@@ -136,6 +136,10 @@ export class MockKeybindingService implements IKeybindingService {
return false;
}
public toggleLogging(): boolean {
return false;
}
public _dumpDebugInfo(): string {
return '';
}