aboutsummaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
Diffstat (limited to 'editors')
-rw-r--r--editors/code/src/config.ts111
1 files changed, 96 insertions, 15 deletions
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index 6db073bec..e2b0f6f84 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -23,22 +23,36 @@ export interface CargoFeatures {
23 allFeatures: boolean; 23 allFeatures: boolean;
24 features: string[]; 24 features: string[];
25} 25}
26
27export const enum UpdatesChannel {
28 Stable = "stable",
29 Nightly = "nightly"
30}
31
32export const NIGHTLY_TAG = "nightly";
26export class Config { 33export class Config {
27 private static readonly rootSection = "rust-analyzer"; 34 readonly extensionId = "matklad.rust-analyzer";
28 private static readonly requiresReloadOpts = [ 35
36 private readonly rootSection = "rust-analyzer";
37 private readonly requiresReloadOpts = [
29 "cargoFeatures", 38 "cargoFeatures",
30 "cargo-watch", 39 "cargo-watch",
31 "highlighting.semanticTokens", 40 "highlighting.semanticTokens",
32 "inlayHints", 41 "inlayHints",
33 ] 42 ]
34 .map(opt => `${Config.rootSection}.${opt}`); 43 .map(opt => `${this.rootSection}.${opt}`);
35 44
36 private static readonly extensionVersion: string = (() => { 45 /**
46 * Either `nightly` or `YYYY-MM-DD` (i.e. `stable` release)
47 */
48 private readonly extensionVersion: string = (() => {
37 const packageJsonVersion = vscode 49 const packageJsonVersion = vscode
38 .extensions 50 .extensions
39 .getExtension("matklad.rust-analyzer")! 51 .getExtension(this.extensionId)!
40 .packageJSON 52 .packageJSON
41 .version as string; // n.n.YYYYMMDD 53 .version as string;
54
55 if (packageJsonVersion.endsWith(NIGHTLY_TAG)) return NIGHTLY_TAG;
42 56
43 const realVersionRegexp = /^\d+\.\d+\.(\d{4})(\d{2})(\d{2})/; 57 const realVersionRegexp = /^\d+\.\d+\.(\d{4})(\d{2})(\d{2})/;
44 const [, yyyy, mm, dd] = packageJsonVersion.match(realVersionRegexp)!; 58 const [, yyyy, mm, dd] = packageJsonVersion.match(realVersionRegexp)!;
@@ -54,7 +68,7 @@ export class Config {
54 } 68 }
55 69
56 private refreshConfig() { 70 private refreshConfig() {
57 this.cfg = vscode.workspace.getConfiguration(Config.rootSection); 71 this.cfg = vscode.workspace.getConfiguration(this.rootSection);
58 const enableLogging = this.cfg.get("trace.extension") as boolean; 72 const enableLogging = this.cfg.get("trace.extension") as boolean;
59 log.setEnabled(enableLogging); 73 log.setEnabled(enableLogging);
60 log.debug("Using configuration:", this.cfg); 74 log.debug("Using configuration:", this.cfg);
@@ -63,7 +77,7 @@ export class Config {
63 private async onConfigChange(event: vscode.ConfigurationChangeEvent) { 77 private async onConfigChange(event: vscode.ConfigurationChangeEvent) {
64 this.refreshConfig(); 78 this.refreshConfig();
65 79
66 const requiresReloadOpt = Config.requiresReloadOpts.find( 80 const requiresReloadOpt = this.requiresReloadOpts.find(
67 opt => event.affectsConfiguration(opt) 81 opt => event.affectsConfiguration(opt)
68 ); 82 );
69 83
@@ -121,8 +135,16 @@ export class Config {
121 } 135 }
122 } 136 }
123 137
138 get installedExtensionUpdateChannel() {
139 if (this.serverPath !== null) return null;
140
141 return this.extensionVersion === NIGHTLY_TAG
142 ? UpdatesChannel.Nightly
143 : UpdatesChannel.Stable;
144 }
145
124 get serverSource(): null | ArtifactSource { 146 get serverSource(): null | ArtifactSource {
125 const serverPath = RA_LSP_DEBUG ?? this.cfg.get<null | string>("serverPath"); 147 const serverPath = RA_LSP_DEBUG ?? this.serverPath;
126 148
127 if (serverPath) { 149 if (serverPath) {
128 return { 150 return {
@@ -135,23 +157,47 @@ export class Config {
135 157
136 if (!prebuiltBinaryName) return null; 158 if (!prebuiltBinaryName) return null;
137 159
160 return this.createGithubReleaseSource(
161 prebuiltBinaryName,
162 this.extensionVersion
163 );
164 }
165
166 private createGithubReleaseSource(file: string, tag: string): ArtifactSource.GithubRelease {
138 return { 167 return {
139 type: ArtifactSource.Type.GithubRelease, 168 type: ArtifactSource.Type.GithubRelease,
169 file,
170 tag,
140 dir: this.ctx.globalStoragePath, 171 dir: this.ctx.globalStoragePath,
141 file: prebuiltBinaryName,
142 storage: this.ctx.globalState,
143 tag: Config.extensionVersion,
144 askBeforeDownload: this.cfg.get("updates.askBeforeDownload") as boolean,
145 repo: { 172 repo: {
146 name: "rust-analyzer", 173 name: "rust-analyzer",
147 owner: "rust-analyzer", 174 owner: "rust-analyzer"
148 } 175 }
149 }; 176 }
150 } 177 }
151 178
179 get nightlyVsixSource(): ArtifactSource.GithubRelease {
180 return this.createGithubReleaseSource("rust-analyzer.vsix", NIGHTLY_TAG);
181 }
182
183 readonly installedNightlyExtensionReleaseDate = new DateStorage(
184 "rust-analyzer-installed-nightly-extension-release-date",
185 this.ctx.globalState
186 );
187 readonly serverReleaseDate = new DateStorage(
188 "rust-analyzer-server-release-date",
189 this.ctx.globalState
190 );
191 readonly serverReleaseTag = new StringStorage(
192 "rust-analyzer-release-tag", this.ctx.globalState
193 );
194
152 // We don't do runtime config validation here for simplicity. More on stackoverflow: 195 // We don't do runtime config validation here for simplicity. More on stackoverflow:
153 // https://stackoverflow.com/questions/60135780/what-is-the-best-way-to-type-check-the-configuration-for-vscode-extension 196 // https://stackoverflow.com/questions/60135780/what-is-the-best-way-to-type-check-the-configuration-for-vscode-extension
154 197
198 private get serverPath() { return this.cfg.get("serverPath") as null | string; }
199 get updatesChannel() { return this.cfg.get("updates.channel") as UpdatesChannel; }
200 get askBeforeDownload() { return this.cfg.get("updates.askBeforeDownload") as boolean; }
155 get highlightingSemanticTokens() { return this.cfg.get("highlighting.semanticTokens") as boolean; } 201 get highlightingSemanticTokens() { return this.cfg.get("highlighting.semanticTokens") as boolean; }
156 get highlightingOn() { return this.cfg.get("highlightingOn") as boolean; } 202 get highlightingOn() { return this.cfg.get("highlightingOn") as boolean; }
157 get rainbowHighlightingOn() { return this.cfg.get("rainbowHighlightingOn") as boolean; } 203 get rainbowHighlightingOn() { return this.cfg.get("rainbowHighlightingOn") as boolean; }
@@ -189,3 +235,38 @@ export class Config {
189 // for internal use 235 // for internal use
190 get withSysroot() { return this.cfg.get("withSysroot", true) as boolean; } 236 get withSysroot() { return this.cfg.get("withSysroot", true) as boolean; }
191} 237}
238
239export class StringStorage {
240 constructor(
241 private readonly key: string,
242 private readonly storage: vscode.Memento
243 ) {}
244
245 get(): null | string {
246 const tag = this.storage.get(this.key, null);
247 log.debug(this.key, "==", tag);
248 return tag;
249 }
250 async set(tag: string) {
251 log.debug(this.key, "=", tag);
252 await this.storage.update(this.key, tag);
253 }
254}
255export class DateStorage {
256
257 constructor(
258 private readonly key: string,
259 private readonly storage: vscode.Memento
260 ) {}
261
262 get(): null | Date {
263 const date = this.storage.get(this.key, null);
264 log.debug(this.key, "==", date);
265 return date ? new Date(date) : null;
266 }
267
268 async set(date: null | Date) {
269 log.debug(this.key, "=", date);
270 await this.storage.update(this.key, date);
271 }
272}