-
Notifications
You must be signed in to change notification settings - Fork 0
/
resolver.ts
122 lines (104 loc) · 3.56 KB
/
resolver.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE.md in the project root for license information.
* -------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
import * as vscodeTextmate from 'vscode-textmate';
import type { PartialDeep, JsonObject, JsonArray, PackageJson } from 'type-fest';
import { readFileText } from '../util/loader';
type PartialJsonObject = PartialDeep<JsonObject>;
export interface GrammarLanguageContribution extends PartialJsonObject {
language: string;
scopeName: string;
path: string;
embeddedLanguages?: { [scopeName: string]: string };
}
export interface GrammarInjectionContribution extends PartialJsonObject {
scopeName: string;
path: string;
injectTo: string[];
}
export type GrammarContribution = GrammarLanguageContribution | GrammarInjectionContribution;
export interface LanguageContribution extends PartialJsonObject {
id: string;
extensions?: string[];
filenames?: string[];
}
export interface ExtensionManifest extends PackageJson {
contributes?: {
grammars?: GrammarContribution[] & JsonArray;
languages?: LanguageContribution[] & JsonArray;
};
'textmate-languageservices'?: { [languageId: string]: string };
}
export class ResolverService implements vscodeTextmate.RegistryOptions {
constructor(private _context: vscode.ExtensionContext, private _grammars: GrammarContribution[], private _languages: LanguageContribution[], public onigLib: Promise<vscodeTextmate.IOnigLib>) {
}
public findLanguageByExtension(fileExtension: string): string | null {
for (const language of this._languages) {
if (!language.extensions) {
continue;
}
for (const extension of language.extensions) {
if (extension === fileExtension) {
return language.id;
}
}
}
return null;
}
public findLanguageByFilename(fileLabel: string): string | null {
for (const language of this._languages) {
if (!language.filenames) {
continue;
}
for (const filename of language.filenames) {
if (filename === fileLabel) {
return language.id;
}
}
}
return null;
}
public findScopeByFilename(filename: string): string | null {
const extname = filename.substring(filename.lastIndexOf('.'));
const language = this.findLanguageByExtension(extname) || this.findLanguageByFilename(filename);
if (!language) {
return null;
}
const grammar = this.findGrammarByLanguageId(language);
return grammar ? grammar.scopeName : null;
}
public findLanguageById(id: string): LanguageContribution {
for (const language of this._languages) {
if (language.id === id) {
return language;
}
}
throw new Error('Could not find language contribution for language ID "' + id + '"');
}
public findGrammarByLanguageId(id: string): GrammarContribution {
for (const grammar of this._grammars) {
if (grammar.language === id) {
return grammar;
}
}
throw new Error('Could not find grammar contribution for language ID "' + id + '"');
}
public async loadGrammar(scopeName: string): Promise<vscodeTextmate.IRawGrammar | null> {
for (const grammar of this._grammars) {
if (grammar.scopeName !== scopeName) {
continue;
}
try {
const uri = vscode.Uri.joinPath(this._context.extensionUri, grammar.path);
const text = await readFileText(uri);
return vscodeTextmate.parseRawGrammar(text, uri.path);
} catch (e) {
throw e;
}
}
return null;
}
}