Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/common/languageSelector.ts
3292 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { IRelativePattern, match as matchGlobPattern } from '../../base/common/glob.js';
7
import { URI } from '../../base/common/uri.js';
8
import { normalize } from '../../base/common/path.js';
9
10
export interface LanguageFilter {
11
readonly language?: string;
12
readonly scheme?: string;
13
readonly pattern?: string | IRelativePattern;
14
readonly notebookType?: string;
15
/**
16
* This provider is implemented in the UI thread.
17
*/
18
readonly hasAccessToAllModels?: boolean;
19
readonly exclusive?: boolean;
20
21
/**
22
* This provider comes from a builtin extension.
23
*/
24
readonly isBuiltin?: boolean;
25
}
26
27
export type LanguageSelector = string | LanguageFilter | ReadonlyArray<string | LanguageFilter>;
28
29
export function score(selector: LanguageSelector | undefined, candidateUri: URI, candidateLanguage: string, candidateIsSynchronized: boolean, candidateNotebookUri: URI | undefined, candidateNotebookType: string | undefined): number {
30
31
if (Array.isArray(selector)) {
32
// array -> take max individual value
33
let ret = 0;
34
for (const filter of selector) {
35
const value = score(filter, candidateUri, candidateLanguage, candidateIsSynchronized, candidateNotebookUri, candidateNotebookType);
36
if (value === 10) {
37
return value; // already at the highest
38
}
39
if (value > ret) {
40
ret = value;
41
}
42
}
43
return ret;
44
45
} else if (typeof selector === 'string') {
46
47
if (!candidateIsSynchronized) {
48
return 0;
49
}
50
51
// short-hand notion, desugars to
52
// 'fooLang' -> { language: 'fooLang'}
53
// '*' -> { language: '*' }
54
if (selector === '*') {
55
return 5;
56
} else if (selector === candidateLanguage) {
57
return 10;
58
} else {
59
return 0;
60
}
61
62
} else if (selector) {
63
// filter -> select accordingly, use defaults for scheme
64
const { language, pattern, scheme, hasAccessToAllModels, notebookType } = selector as LanguageFilter; // TODO: microsoft/TypeScript#42768
65
66
if (!candidateIsSynchronized && !hasAccessToAllModels) {
67
return 0;
68
}
69
70
// selector targets a notebook -> use the notebook uri instead
71
// of the "normal" document uri.
72
if (notebookType && candidateNotebookUri) {
73
candidateUri = candidateNotebookUri;
74
}
75
76
let ret = 0;
77
78
if (scheme) {
79
if (scheme === candidateUri.scheme) {
80
ret = 10;
81
} else if (scheme === '*') {
82
ret = 5;
83
} else {
84
return 0;
85
}
86
}
87
88
if (language) {
89
if (language === candidateLanguage) {
90
ret = 10;
91
} else if (language === '*') {
92
ret = Math.max(ret, 5);
93
} else {
94
return 0;
95
}
96
}
97
98
if (notebookType) {
99
if (notebookType === candidateNotebookType) {
100
ret = 10;
101
} else if (notebookType === '*' && candidateNotebookType !== undefined) {
102
ret = Math.max(ret, 5);
103
} else {
104
return 0;
105
}
106
}
107
108
if (pattern) {
109
let normalizedPattern: string | IRelativePattern;
110
if (typeof pattern === 'string') {
111
normalizedPattern = pattern;
112
} else {
113
// Since this pattern has a `base` property, we need
114
// to normalize this path first before passing it on
115
// because we will compare it against `Uri.fsPath`
116
// which uses platform specific separators.
117
// Refs: https://github.com/microsoft/vscode/issues/99938
118
normalizedPattern = { ...pattern, base: normalize(pattern.base) };
119
}
120
121
if (normalizedPattern === candidateUri.fsPath || matchGlobPattern(normalizedPattern, candidateUri.fsPath)) {
122
ret = 10;
123
} else {
124
return 0;
125
}
126
}
127
128
return ret;
129
130
} else {
131
return 0;
132
}
133
}
134
135
136
export function targetsNotebooks(selector: LanguageSelector): boolean {
137
if (typeof selector === 'string') {
138
return false;
139
} else if (Array.isArray(selector)) {
140
return selector.some(targetsNotebooks);
141
} else {
142
return !!(<LanguageFilter>selector).notebookType;
143
}
144
}
145
146