提交 fcc508fd 编写于 作者: J Johannes Rieken

DocumentSelector matches on file and untitled only unless scheme is given, #21886

上级 3ae62a8d
......@@ -20,62 +20,86 @@ export default function matches(selection: LanguageSelector, uri: URI, language:
return score(selection, uri, language) > 0;
}
export function score(selector: LanguageSelector, uri: URI, language: string): number {
export function score(selector: LanguageSelector, candidateUri: URI, candidateLanguage: string): number {
if (Array.isArray(selector)) {
// for each
let values = (<LanguageSelector[]>selector).map(item => score(item, uri, language));
return Math.max(...values);
// array -> take max individual value
let ret = 0;
for (const filter of selector) {
const value = score(filter, candidateUri, candidateLanguage);
if (value === 10) {
return value; // already at the highest
}
if (value > ret) {
ret = value;
}
}
return ret;
} else if (typeof selector === 'string') {
// compare language id
if (selector === language) {
return 10;
} else if (selector === '*') {
// short-hand notion, desugars to
// 'fooLang' -> [{ language: 'fooLang', scheme: 'file' }, { language: 'fooLang', scheme: 'untitled' }]
// '*' -> { language: '*', scheme: '*' }
if (selector === '*') {
return 5;
} else if (selector === candidateLanguage && _defaultSchemes[candidateUri.scheme]) {
return 10;
} else {
return 0;
}
} else if (selector) {
// all must match but only highest score counts
const filter = <LanguageFilter>selector;
let valueLanguage = 0;
let valueScheme = 0;
let valuePattern = 0;
// language id
if (filter.language) {
if (filter.language === language) {
valueLanguage = 10;
} else if (filter.language === '*') {
valueLanguage = 5;
// filter -> select accordingly, use defaults for scheme
const { language, pattern, scheme } = selector;
let ret = 0;
if (scheme) {
if (scheme === candidateUri.scheme) {
ret = 10;
} else if (scheme === '*') {
ret = 5;
} else {
return 0;
}
}
// scheme
if (filter.scheme) {
if (filter.scheme === uri.scheme) {
valueScheme = 10;
if (language) {
if (language === candidateLanguage) {
ret = 10;
} else if (language === '*') {
ret = Math.max(ret, 5);
} else {
return 0;
}
}
// match fsPath with pattern
if (filter.pattern) {
if (filter.pattern === uri.fsPath) {
valuePattern = 10;
} else if (matchGlobPattern(filter.pattern, uri.fsPath)) {
valuePattern = 5;
if (pattern) {
if (pattern === candidateUri.fsPath || matchGlobPattern(pattern, candidateUri.fsPath)) {
ret = 10;
} else {
return 0;
}
}
return Math.max(valueLanguage, valueScheme, valuePattern);
if (!_defaultSchemes[candidateUri.scheme] && !scheme && language !== '*') {
// undo match when the uri-scheme is special and not
// explicitly selected
return 0;
} else {
return ret;
}
} else {
return undefined;
}
return undefined;
}
interface DefaultSchemes {
file: 'file';
untitled: 'untitled';
}
const _defaultSchemes: DefaultSchemes = Object.create(null);
_defaultSchemes.file = 'file';
_defaultSchemes.untitled = 'untitled';
......@@ -18,7 +18,7 @@ import { CodeActionProviderRegistry, LanguageIdentifier } from 'vs/editor/common
suite('QuickFix', () => {
const languageIdentifier = new LanguageIdentifier('foo-lang', 3);
let uri = URI.parse('fake:path');
let uri = URI.parse('untitled:path');
let model = Model.createFromString('foobar foo bar\nfarboo far boo', undefined, languageIdentifier, uri);
let markerService: MarkerService;
let editor: ICommonCodeEditor;
......
......@@ -21,7 +21,7 @@ suite('Suggest', function () {
setup(function () {
model = Model.createFromString('FOO\nbar\BAR\nfoo', undefined, undefined, URI.parse('foo:bar/path'));
registration = SuggestRegistry.register({ pattern: 'bar/path' }, {
registration = SuggestRegistry.register({ pattern: 'bar/path', scheme: 'foo' }, {
provideCompletionItems() {
return {
incomplete: false,
......@@ -98,7 +98,7 @@ suite('Suggest', function () {
};
}
};
const registration = SuggestRegistry.register({ pattern: 'bar/path' }, foo);
const registration = SuggestRegistry.register({ pattern: 'bar/path', scheme: 'foo' }, foo);
provideSuggestionItems(model, new Position(1, 1), undefined, [foo]).then(items => {
registration.dispose();
......
......@@ -26,6 +26,26 @@ suite('LanguageSelector', function () {
test('score, any language', function () {
assert.equal(score({ language: '*' }, model.uri, model.language), 5);
assert.equal(score('*', model.uri, model.language), 5);
assert.equal(score('*', URI.parse('foo:bar'), model.language), 5);
assert.equal(score('farboo', URI.parse('foo:bar'), model.language), 0);
});
test('score, default schemes', function () {
const uri = URI.parse('git:foo/file.txt');
const language = 'farboo';
assert.equal(score('*', uri, language), 5);
assert.equal(score('farboo', uri, language), 0);
assert.equal(score({ language: 'farboo', scheme: '' }, uri, language), 0);
assert.equal(score({ language: 'farboo', scheme: 'git' }, uri, language), 10);
assert.equal(score({ language: 'farboo', scheme: '*' }, uri, language), 10);
assert.equal(score({ language: 'farboo' }, uri, language), 0);
assert.equal(score({ language: '*' }, uri, language), 5);
assert.equal(score({ scheme: '*' }, uri, language), 5);
assert.equal(score({ scheme: 'git' }, uri, language), 10);
});
test('score, filter', function () {
......@@ -34,8 +54,10 @@ suite('LanguageSelector', function () {
assert.equal(score({ language: 'farboo', scheme: 'file' }, model.uri, model.language), 10);
assert.equal(score({ language: 'farboo', scheme: 'http' }, model.uri, model.language), 0);
assert.equal(score({ pattern: '**/*.fb' }, model.uri, model.language), 5);
// assert.equal(score({ pattern: '/testbed/file.fb' }, model.uri, model.language), 10); fails on windows
assert.equal(score({ pattern: '**/*.fb' }, model.uri, model.language), 10);
assert.equal(score({ pattern: '**/*.fb', scheme: 'file' }, model.uri, model.language), 10);
assert.equal(score({ pattern: '**/*.fb' }, URI.parse('foo:bar'), model.language), 0);
assert.equal(score({ pattern: '**/*.fb', scheme: 'foo' }, URI.parse('foo:bar'), model.language), 0);
});
test('score, max(filters)', function () {
......@@ -45,7 +67,8 @@ suite('LanguageSelector', function () {
assert.equal(score(match, model.uri, model.language), 10);
assert.equal(score(fail, model.uri, model.language), 0);
assert.equal(score([match, fail], model.uri, model.language), 10);
assert.equal(score([fail, fail], model.uri, model.language), 0);
assert.equal(score(['farboo', '*'], model.uri, model.language), 10);
assert.equal(score(['*', 'farboo'], model.uri, model.language), 10);
});
});
\ No newline at end of file
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册