aboutsummaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
Diffstat (limited to 'editors')
-rw-r--r--editors/code/package.json12
-rw-r--r--editors/code/src/client.ts6
-rw-r--r--editors/code/src/config.ts124
-rw-r--r--editors/code/src/inlay_hints.ts2
-rw-r--r--editors/code/src/main.ts14
5 files changed, 72 insertions, 86 deletions
diff --git a/editors/code/package.json b/editors/code/package.json
index eb5748515..1d113ebb6 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -73,10 +73,18 @@
73 "type": "string" 73 "type": "string"
74 }, 74 },
75 "args": { 75 "args": {
76 "type": "array" 76 "type": "array",
77 "items": {
78 "type": "string"
79 }
77 }, 80 },
78 "env": { 81 "env": {
79 "type": "object" 82 "type": "object",
83 "patternProperties": {
84 ".+": {
85 "type": "string"
86 }
87 }
80 } 88 }
81 } 89 }
82 } 90 }
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 08d821dd0..82ca749f3 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -99,8 +99,10 @@ export async function createClient(config: Config, serverPath: string): Promise<
99 // Note that while the CallHierarchyFeature is stable the LSP protocol is not. 99 // Note that while the CallHierarchyFeature is stable the LSP protocol is not.
100 res.registerFeature(new CallHierarchyFeature(res)); 100 res.registerFeature(new CallHierarchyFeature(res));
101 101
102 if (config.highlightingSemanticTokens) { 102 if (config.package.enableProposedApi) {
103 res.registerFeature(new SemanticTokensFeature(res)); 103 if (config.highlightingSemanticTokens) {
104 res.registerFeature(new SemanticTokensFeature(res));
105 }
104 } 106 }
105 107
106 return res; 108 return res;
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index be5296fcf..7668c20b7 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -1,29 +1,10 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2import { log } from "./util"; 2import { log } from "./util";
3 3
4export interface InlayHintOptions {
5 typeHints: boolean;
6 parameterHints: boolean;
7 maxLength: number | null;
8}
9
10export interface CargoWatchOptions {
11 enable: boolean;
12 arguments: string[];
13 command: string;
14 allTargets: boolean;
15}
16
17export interface CargoFeatures {
18 noDefaultFeatures: boolean;
19 allFeatures: boolean;
20 features: string[];
21 loadOutDirsFromCheck: boolean;
22}
23
24export type UpdatesChannel = "stable" | "nightly"; 4export type UpdatesChannel = "stable" | "nightly";
25 5
26export const NIGHTLY_TAG = "nightly"; 6export const NIGHTLY_TAG = "nightly";
7
27export class Config { 8export class Config {
28 readonly extensionId = "matklad.rust-analyzer"; 9 readonly extensionId = "matklad.rust-analyzer";
29 10
@@ -38,37 +19,30 @@ export class Config {
38 ] 19 ]
39 .map(opt => `${this.rootSection}.${opt}`); 20 .map(opt => `${this.rootSection}.${opt}`);
40 21
41 readonly packageJsonVersion: string = vscode 22 readonly package: {
42 .extensions 23 version: string;
43 .getExtension(this.extensionId)! 24 releaseTag: string | undefined;
44 .packageJSON 25 enableProposedApi: boolean | undefined;
45 .version; 26 } = vscode.extensions.getExtension(this.extensionId)!.packageJSON;
46
47 readonly releaseTag: string | undefined = vscode
48 .extensions
49 .getExtension(this.extensionId)!
50 .packageJSON
51 .releaseTag ?? undefined;
52 27
53 private cfg!: vscode.WorkspaceConfiguration; 28 readonly globalStoragePath: string;
54 29
55 constructor(private readonly ctx: vscode.ExtensionContext) { 30 constructor(ctx: vscode.ExtensionContext) {
56 vscode.workspace.onDidChangeConfiguration(this.onConfigChange, this, ctx.subscriptions); 31 this.globalStoragePath = ctx.globalStoragePath;
57 this.refreshConfig(); 32 vscode.workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, ctx.subscriptions);
33 this.refreshLogging();
58 } 34 }
59 35
60 private refreshConfig() { 36 private refreshLogging() {
61 this.cfg = vscode.workspace.getConfiguration(this.rootSection); 37 log.setEnabled(this.traceExtension);
62 const enableLogging = this.cfg.get("trace.extension") as boolean;
63 log.setEnabled(enableLogging);
64 log.debug( 38 log.debug(
65 "Extension version:", this.packageJsonVersion, 39 "Extension version:", this.package.version,
66 "using configuration:", this.cfg 40 "using configuration:", this.cfg
67 ); 41 );
68 } 42 }
69 43
70 private async onConfigChange(event: vscode.ConfigurationChangeEvent) { 44 private async onDidChangeConfiguration(event: vscode.ConfigurationChangeEvent) {
71 this.refreshConfig(); 45 this.refreshLogging();
72 46
73 const requiresReloadOpt = this.requiresReloadOpts.find( 47 const requiresReloadOpt = this.requiresReloadOpts.find(
74 opt => event.affectsConfiguration(opt) 48 opt => event.affectsConfiguration(opt)
@@ -86,49 +60,53 @@ export class Config {
86 } 60 }
87 } 61 }
88 62
89 get globalStoragePath(): string { return this.ctx.globalStoragePath; }
90
91 // We don't do runtime config validation here for simplicity. More on stackoverflow: 63 // We don't do runtime config validation here for simplicity. More on stackoverflow:
92 // https://stackoverflow.com/questions/60135780/what-is-the-best-way-to-type-check-the-configuration-for-vscode-extension 64 // https://stackoverflow.com/questions/60135780/what-is-the-best-way-to-type-check-the-configuration-for-vscode-extension
93 65
94 get serverPath() { return this.cfg.get("serverPath") as null | string; } 66 private get cfg(): vscode.WorkspaceConfiguration {
95 get channel() { return this.cfg.get<"stable" | "nightly">("updates.channel")!; } 67 return vscode.workspace.getConfiguration(this.rootSection);
96 get askBeforeDownload() { return this.cfg.get("updates.askBeforeDownload") as boolean; } 68 }
97 get highlightingSemanticTokens() { return this.cfg.get("highlighting.semanticTokens") as boolean; } 69
98 get highlightingOn() { return this.cfg.get("highlightingOn") as boolean; } 70 get serverPath() { return this.cfg.get<null | string>("serverPath")!; }
99 get rainbowHighlightingOn() { return this.cfg.get("rainbowHighlightingOn") as boolean; } 71 get channel() { return this.cfg.get<UpdatesChannel>("updates.channel")!; }
100 get lruCapacity() { return this.cfg.get("lruCapacity") as null | number; } 72 get askBeforeDownload() { return this.cfg.get<boolean>("updates.askBeforeDownload")!; }
101 get inlayHints(): InlayHintOptions { 73 get highlightingSemanticTokens() { return this.cfg.get<boolean>("highlighting.semanticTokens")!; }
74 get highlightingOn() { return this.cfg.get<boolean>("highlightingOn")!; }
75 get rainbowHighlightingOn() { return this.cfg.get<boolean>("rainbowHighlightingOn")!; }
76 get lruCapacity() { return this.cfg.get<null | number>("lruCapacity")!; }
77 get excludeGlobs() { return this.cfg.get<string[]>("excludeGlobs")!; }
78 get useClientWatching() { return this.cfg.get<boolean>("useClientWatching")!; }
79 get featureFlags() { return this.cfg.get<Record<string, boolean>>("featureFlags")!; }
80 get rustfmtArgs() { return this.cfg.get<string[]>("rustfmtArgs")!; }
81 get loadOutDirsFromCheck() { return this.cfg.get<boolean>("loadOutDirsFromCheck")!; }
82 get traceExtension() { return this.cfg.get<boolean>("trace.extension")!; }
83
84 // for internal use
85 get withSysroot() { return this.cfg.get<boolean>("withSysroot", true)!; }
86
87 get inlayHints() {
102 return { 88 return {
103 typeHints: this.cfg.get("inlayHints.typeHints") as boolean, 89 typeHints: this.cfg.get<boolean>("inlayHints.typeHints")!,
104 parameterHints: this.cfg.get("inlayHints.parameterHints") as boolean, 90 parameterHints: this.cfg.get<boolean>("inlayHints.parameterHints")!,
105 maxLength: this.cfg.get("inlayHints.maxLength") as null | number, 91 maxLength: this.cfg.get<null | number>("inlayHints.maxLength")!,
106 }; 92 };
107 } 93 }
108 get excludeGlobs() { return this.cfg.get("excludeGlobs") as string[]; }
109 get useClientWatching() { return this.cfg.get("useClientWatching") as boolean; }
110 get featureFlags() { return this.cfg.get("featureFlags") as Record<string, boolean>; }
111 get rustfmtArgs() { return this.cfg.get("rustfmtArgs") as string[]; }
112 get loadOutDirsFromCheck() { return this.cfg.get("loadOutDirsFromCheck") as boolean; }
113 94
114 get cargoWatchOptions(): CargoWatchOptions { 95 get cargoWatchOptions() {
115 return { 96 return {
116 enable: this.cfg.get("cargo-watch.enable") as boolean, 97 enable: this.cfg.get<boolean>("cargo-watch.enable")!,
117 arguments: this.cfg.get("cargo-watch.arguments") as string[], 98 arguments: this.cfg.get<string[]>("cargo-watch.arguments")!,
118 allTargets: this.cfg.get("cargo-watch.allTargets") as boolean, 99 allTargets: this.cfg.get<boolean>("cargo-watch.allTargets")!,
119 command: this.cfg.get("cargo-watch.command") as string, 100 command: this.cfg.get<string>("cargo-watch.command")!,
120 }; 101 };
121 } 102 }
122 103
123 get cargoFeatures(): CargoFeatures { 104 get cargoFeatures() {
124 return { 105 return {
125 noDefaultFeatures: this.cfg.get("cargoFeatures.noDefaultFeatures") as boolean, 106 noDefaultFeatures: this.cfg.get<boolean>("cargoFeatures.noDefaultFeatures")!,
126 allFeatures: this.cfg.get("cargoFeatures.allFeatures") as boolean, 107 allFeatures: this.cfg.get<boolean>("cargoFeatures.allFeatures")!,
127 features: this.cfg.get("cargoFeatures.features") as string[], 108 features: this.cfg.get<string[]>("cargoFeatures.features")!,
128 loadOutDirsFromCheck: this.cfg.get("cargoFeatures.loadOutDirsFromCheck") as boolean, 109 loadOutDirsFromCheck: this.cfg.get<boolean>("cargoFeatures.loadOutDirsFromCheck")!,
129 }; 110 };
130 } 111 }
131
132 // for internal use
133 get withSysroot() { return this.cfg.get("withSysroot", true) as boolean; }
134} 112}
diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts
index b19b09ad5..17d0dfa33 100644
--- a/editors/code/src/inlay_hints.ts
+++ b/editors/code/src/inlay_hints.ts
@@ -134,8 +134,6 @@ class HintsUpdater implements Disposable {
134 134
135 // No text documents changed, so we may try to use the cache 135 // No text documents changed, so we may try to use the cache
136 if (!file.cachedDecorations) { 136 if (!file.cachedDecorations) {
137 file.inlaysRequest?.cancel();
138
139 const hints = await this.fetchHints(file); 137 const hints = await this.fetchHints(file);
140 if (!hints) return; 138 if (!hints) return;
141 139
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 5d2da9a76..7b7c19dfc 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -110,9 +110,9 @@ async function bootstrap(config: Config, state: PersistentState): Promise<string
110} 110}
111 111
112async function bootstrapExtension(config: Config, state: PersistentState): Promise<void> { 112async function bootstrapExtension(config: Config, state: PersistentState): Promise<void> {
113 if (config.releaseTag === undefined) return; 113 if (config.package.releaseTag === undefined) return;
114 if (config.channel === "stable") { 114 if (config.channel === "stable") {
115 if (config.releaseTag === NIGHTLY_TAG) { 115 if (config.package.releaseTag === NIGHTLY_TAG) {
116 vscode.window.showWarningMessage(`You are running a nightly version of rust-analyzer extension. 116 vscode.window.showWarningMessage(`You are running a nightly version of rust-analyzer extension.
117To switch to stable, uninstall the extension and re-install it from the marketplace`); 117To switch to stable, uninstall the extension and re-install it from the marketplace`);
118 } 118 }
@@ -185,7 +185,7 @@ async function getServer(config: Config, state: PersistentState): Promise<string
185 } 185 }
186 return explicitPath; 186 return explicitPath;
187 }; 187 };
188 if (config.releaseTag === undefined) return "rust-analyzer"; 188 if (config.package.releaseTag === undefined) return "rust-analyzer";
189 189
190 let binaryName: string | undefined = undefined; 190 let binaryName: string | undefined = undefined;
191 if (process.arch === "x64" || process.arch === "x32") { 191 if (process.arch === "x64" || process.arch === "x32") {
@@ -211,21 +211,21 @@ async function getServer(config: Config, state: PersistentState): Promise<string
211 await state.updateServerVersion(undefined); 211 await state.updateServerVersion(undefined);
212 } 212 }
213 213
214 if (state.serverVersion === config.packageJsonVersion) return dest; 214 if (state.serverVersion === config.package.version) return dest;
215 215
216 if (config.askBeforeDownload) { 216 if (config.askBeforeDownload) {
217 const userResponse = await vscode.window.showInformationMessage( 217 const userResponse = await vscode.window.showInformationMessage(
218 `Language server version ${config.packageJsonVersion} for rust-analyzer is not installed.`, 218 `Language server version ${config.package.version} for rust-analyzer is not installed.`,
219 "Download now" 219 "Download now"
220 ); 220 );
221 if (userResponse !== "Download now") return dest; 221 if (userResponse !== "Download now") return dest;
222 } 222 }
223 223
224 const release = await fetchRelease(config.releaseTag); 224 const release = await fetchRelease(config.package.releaseTag);
225 const artifact = release.assets.find(artifact => artifact.name === binaryName); 225 const artifact = release.assets.find(artifact => artifact.name === binaryName);
226 assert(!!artifact, `Bad release: ${JSON.stringify(release)}`); 226 assert(!!artifact, `Bad release: ${JSON.stringify(release)}`);
227 227
228 await download(artifact.browser_download_url, dest, "Downloading rust-analyzer server", { mode: 0o755 }); 228 await download(artifact.browser_download_url, dest, "Downloading rust-analyzer server", { mode: 0o755 });
229 await state.updateServerVersion(config.packageJsonVersion); 229 await state.updateServerVersion(config.package.version);
230 return dest; 230 return dest;
231} 231}