Skip to content

Commit a89ed2b

Browse files
committed
1 parent c677bf3 commit a89ed2b

2 files changed

Lines changed: 73 additions & 2 deletions

File tree

src/vs/platform/contextkey/common/contextkey.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66

77
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
88
import Event from 'vs/base/common/event';
9+
import { match } from 'vs/base/common/glob';
910

1011
export enum ContextKeyExprType {
1112
Defined = 1,
1213
Not = 2,
1314
Equals = 3,
1415
NotEquals = 4,
15-
And = 5
16+
And = 5,
17+
Glob = 6
1618
}
1719

1820
export abstract class ContextKeyExpr {
@@ -29,6 +31,10 @@ export abstract class ContextKeyExpr {
2931
return new ContextKeyNotEqualsExpr(key, value);
3032
}
3133

34+
public static glob(key: string, value: string): ContextKeyExpr {
35+
return new ContextKeyGlobExpr(key, value);
36+
}
37+
3238
public static not(key: string): ContextKeyExpr {
3339
return new ContextKeyNotExpr(key);
3440
}
@@ -60,6 +66,11 @@ export abstract class ContextKeyExpr {
6066
return new ContextKeyEqualsExpr(pieces[0].trim(), this._deserializeValue(pieces[1]));
6167
}
6268

69+
if (serializedOne.indexOf('=~') >= 0) {
70+
let pieces = serializedOne.split('=~');
71+
return new ContextKeyGlobExpr(pieces[0].trim(), this._deserializeValue(pieces[1]));
72+
}
73+
6374
if (/^\!\s*/.test(serializedOne)) {
6475
return new ContextKeyNotExpr(serializedOne.substr(1).trim());
6576
}
@@ -109,6 +120,8 @@ function cmp(a: ContextKeyExpr, b: ContextKeyExpr): number {
109120
return (<ContextKeyEqualsExpr>a).cmp(<ContextKeyEqualsExpr>b);
110121
case ContextKeyExprType.NotEquals:
111122
return (<ContextKeyNotEqualsExpr>a).cmp(<ContextKeyNotEqualsExpr>b);
123+
case ContextKeyExprType.Glob:
124+
return (<ContextKeyGlobExpr>a).cmp(<ContextKeyGlobExpr>b);
112125
default:
113126
throw new Error('Unknown ContextKeyExpr!');
114127
}
@@ -320,6 +333,55 @@ export class ContextKeyNotExpr implements ContextKeyExpr {
320333
}
321334
}
322335

336+
export class ContextKeyGlobExpr implements ContextKeyExpr {
337+
338+
constructor(private key: string, private value: any) {
339+
}
340+
341+
public getType(): ContextKeyExprType {
342+
return ContextKeyExprType.Glob;
343+
}
344+
345+
public cmp(other: ContextKeyGlobExpr): number {
346+
if (this.key < other.key) {
347+
return -1;
348+
}
349+
if (this.key > other.key) {
350+
return 1;
351+
}
352+
if (this.value < other.value) {
353+
return -1;
354+
}
355+
if (this.value > other.value) {
356+
return 1;
357+
}
358+
return 0;
359+
}
360+
361+
public equals(other: ContextKeyExpr): boolean {
362+
if (other instanceof ContextKeyGlobExpr) {
363+
return (this.key === other.key && this.value === other.value);
364+
}
365+
return false;
366+
}
367+
368+
public evaluate(context: IContext): boolean {
369+
return match(this.value, context.getValue(this.key))
370+
}
371+
372+
public normalize(): ContextKeyExpr {
373+
return this;
374+
}
375+
376+
public serialize(): string {
377+
return this.key + ' =~ \'' + this.value + '\'';
378+
}
379+
380+
public keys(): string[] {
381+
return [this.key];
382+
}
383+
}
384+
323385
export class ContextKeyAndExpr implements ContextKeyExpr {
324386
public readonly expr: ContextKeyExpr[];
325387

src/vs/platform/contextkey/test/common/contextkey.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import * as assert from 'assert';
88
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
9+
import { match } from 'vs/base/common/glob';
910

1011
function createContext(ctx: any) {
1112
return {
@@ -21,6 +22,8 @@ suite('ContextKeyExpr', () => {
2122
ContextKeyExpr.has('a1'),
2223
ContextKeyExpr.and(ContextKeyExpr.has('and.a')),
2324
ContextKeyExpr.has('a2'),
25+
ContextKeyExpr.glob('d3', '**/d*'),
26+
ContextKeyExpr.glob('d4', '**/3*'),
2427
ContextKeyExpr.equals('b1', 'bb1'),
2528
ContextKeyExpr.equals('b2', 'bb2'),
2629
ContextKeyExpr.notEquals('c1', 'cc1'),
@@ -32,9 +35,11 @@ suite('ContextKeyExpr', () => {
3235
ContextKeyExpr.equals('b2', 'bb2'),
3336
ContextKeyExpr.notEquals('c1', 'cc1'),
3437
ContextKeyExpr.not('d1'),
38+
ContextKeyExpr.glob('d4', '**/3*'),
3539
ContextKeyExpr.notEquals('c2', 'cc2'),
3640
ContextKeyExpr.has('a2'),
3741
ContextKeyExpr.equals('b1', 'bb1'),
42+
ContextKeyExpr.glob('d3', '**/d*'),
3843
ContextKeyExpr.has('a1'),
3944
ContextKeyExpr.and(ContextKeyExpr.equals('and.a', true)),
4045
ContextKeyExpr.not('d2')
@@ -59,9 +64,11 @@ suite('ContextKeyExpr', () => {
5964
let context = createContext({
6065
'a': true,
6166
'b': false,
62-
'c': '5'
67+
'c': '5',
68+
'd': 'd'
6369
});
6470
function testExpression(expr: string, expected: boolean): void {
71+
console.log(expr + ' ' + expected);
6572
let rules = ContextKeyExpr.deserialize(expr);
6673
assert.equal(rules.evaluate(context), expected, expr);
6774
}
@@ -74,11 +81,13 @@ suite('ContextKeyExpr', () => {
7481
testExpression(expr + ' == 5', value == <any>'5');
7582
testExpression(expr + ' != 5', value != <any>'5');
7683
testExpression('!' + expr, !value);
84+
testExpression(expr + ' =~ **/d*', match('**/d*', value));
7785
}
7886

7987
testBatch('a', true);
8088
testBatch('b', false);
8189
testBatch('c', '5');
90+
testBatch('d', 'd');
8291
testBatch('z', undefined);
8392

8493
testExpression('a && !b', true && !false);

0 commit comments

Comments
 (0)