mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-19 06:39:55 +01:00
Merge pull request #41646 from Microsoft/chrisdias/contextkeyglobexpr
Chrisdias/contextkeyglobexpr
This commit is contained in:
@@ -6,13 +6,15 @@
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import Event from 'vs/base/common/event';
|
||||
import { match } from 'vs/base/common/glob';
|
||||
|
||||
export enum ContextKeyExprType {
|
||||
Defined = 1,
|
||||
Not = 2,
|
||||
Equals = 3,
|
||||
NotEquals = 4,
|
||||
And = 5
|
||||
And = 5,
|
||||
Glob = 6
|
||||
}
|
||||
|
||||
export abstract class ContextKeyExpr {
|
||||
@@ -29,6 +31,10 @@ export abstract class ContextKeyExpr {
|
||||
return new ContextKeyNotEqualsExpr(key, value);
|
||||
}
|
||||
|
||||
public static glob(key: string, value: string): ContextKeyExpr {
|
||||
return new ContextKeyGlobExpr(key, value);
|
||||
}
|
||||
|
||||
public static not(key: string): ContextKeyExpr {
|
||||
return new ContextKeyNotExpr(key);
|
||||
}
|
||||
@@ -60,6 +66,11 @@ export abstract class ContextKeyExpr {
|
||||
return new ContextKeyEqualsExpr(pieces[0].trim(), this._deserializeValue(pieces[1]));
|
||||
}
|
||||
|
||||
if (serializedOne.indexOf('=~') >= 0) {
|
||||
let pieces = serializedOne.split('=~');
|
||||
return new ContextKeyGlobExpr(pieces[0].trim(), this._deserializeValue(pieces[1]));
|
||||
}
|
||||
|
||||
if (/^\!\s*/.test(serializedOne)) {
|
||||
return new ContextKeyNotExpr(serializedOne.substr(1).trim());
|
||||
}
|
||||
@@ -109,6 +120,8 @@ function cmp(a: ContextKeyExpr, b: ContextKeyExpr): number {
|
||||
return (<ContextKeyEqualsExpr>a).cmp(<ContextKeyEqualsExpr>b);
|
||||
case ContextKeyExprType.NotEquals:
|
||||
return (<ContextKeyNotEqualsExpr>a).cmp(<ContextKeyNotEqualsExpr>b);
|
||||
case ContextKeyExprType.Glob:
|
||||
return (<ContextKeyGlobExpr>a).cmp(<ContextKeyGlobExpr>b);
|
||||
default:
|
||||
throw new Error('Unknown ContextKeyExpr!');
|
||||
}
|
||||
@@ -320,6 +333,55 @@ export class ContextKeyNotExpr implements ContextKeyExpr {
|
||||
}
|
||||
}
|
||||
|
||||
export class ContextKeyGlobExpr implements ContextKeyExpr {
|
||||
|
||||
constructor(private key: string, private value: any) {
|
||||
}
|
||||
|
||||
public getType(): ContextKeyExprType {
|
||||
return ContextKeyExprType.Glob;
|
||||
}
|
||||
|
||||
public cmp(other: ContextKeyGlobExpr): number {
|
||||
if (this.key < other.key) {
|
||||
return -1;
|
||||
}
|
||||
if (this.key > other.key) {
|
||||
return 1;
|
||||
}
|
||||
if (this.value < other.value) {
|
||||
return -1;
|
||||
}
|
||||
if (this.value > other.value) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpr): boolean {
|
||||
if (other instanceof ContextKeyGlobExpr) {
|
||||
return (this.key === other.key && this.value === other.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public evaluate(context: IContext): boolean {
|
||||
return match(this.value, context.getValue(this.key));
|
||||
}
|
||||
|
||||
public normalize(): ContextKeyExpr {
|
||||
return this;
|
||||
}
|
||||
|
||||
public serialize(): string {
|
||||
return this.key + ' =~ \'' + this.value + '\'';
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
return [this.key];
|
||||
}
|
||||
}
|
||||
|
||||
export class ContextKeyAndExpr implements ContextKeyExpr {
|
||||
public readonly expr: ContextKeyExpr[];
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { match } from 'vs/base/common/glob';
|
||||
|
||||
function createContext(ctx: any) {
|
||||
return {
|
||||
@@ -21,6 +22,8 @@ suite('ContextKeyExpr', () => {
|
||||
ContextKeyExpr.has('a1'),
|
||||
ContextKeyExpr.and(ContextKeyExpr.has('and.a')),
|
||||
ContextKeyExpr.has('a2'),
|
||||
ContextKeyExpr.glob('d3', '**/d*'),
|
||||
ContextKeyExpr.glob('d4', '**/3*'),
|
||||
ContextKeyExpr.equals('b1', 'bb1'),
|
||||
ContextKeyExpr.equals('b2', 'bb2'),
|
||||
ContextKeyExpr.notEquals('c1', 'cc1'),
|
||||
@@ -32,9 +35,11 @@ suite('ContextKeyExpr', () => {
|
||||
ContextKeyExpr.equals('b2', 'bb2'),
|
||||
ContextKeyExpr.notEquals('c1', 'cc1'),
|
||||
ContextKeyExpr.not('d1'),
|
||||
ContextKeyExpr.glob('d4', '**/3*'),
|
||||
ContextKeyExpr.notEquals('c2', 'cc2'),
|
||||
ContextKeyExpr.has('a2'),
|
||||
ContextKeyExpr.equals('b1', 'bb1'),
|
||||
ContextKeyExpr.glob('d3', '**/d*'),
|
||||
ContextKeyExpr.has('a1'),
|
||||
ContextKeyExpr.and(ContextKeyExpr.equals('and.a', true)),
|
||||
ContextKeyExpr.not('d2')
|
||||
@@ -59,9 +64,11 @@ suite('ContextKeyExpr', () => {
|
||||
let context = createContext({
|
||||
'a': true,
|
||||
'b': false,
|
||||
'c': '5'
|
||||
'c': '5',
|
||||
'd': 'd'
|
||||
});
|
||||
function testExpression(expr: string, expected: boolean): void {
|
||||
console.log(expr + ' ' + expected);
|
||||
let rules = ContextKeyExpr.deserialize(expr);
|
||||
assert.equal(rules.evaluate(context), expected, expr);
|
||||
}
|
||||
@@ -74,11 +81,13 @@ suite('ContextKeyExpr', () => {
|
||||
testExpression(expr + ' == 5', value == <any>'5');
|
||||
testExpression(expr + ' != 5', value != <any>'5');
|
||||
testExpression('!' + expr, !value);
|
||||
testExpression(expr + ' =~ **/d*', match('**/d*', value));
|
||||
}
|
||||
|
||||
testBatch('a', true);
|
||||
testBatch('b', false);
|
||||
testBatch('c', '5');
|
||||
testBatch('d', 'd');
|
||||
testBatch('z', undefined);
|
||||
|
||||
testExpression('a && !b', true && !false);
|
||||
|
||||
Reference in New Issue
Block a user