Skip to content

Commit 69f01fd

Browse files
committed
Auto merge of #13451 - Veykril:lang-config, r=Veykril
internal: Properly handle language configuration config changes
2 parents 2481721 + a8e0a20 commit 69f01fd

File tree

3 files changed

+89
-81
lines changed

3 files changed

+89
-81
lines changed

editors/code/src/config.ts

Lines changed: 77 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,17 @@ export type RunnableEnvCfg =
1111

1212
export class Config {
1313
readonly extensionId = "rust-lang.rust-analyzer";
14+
configureLang: vscode.Disposable | undefined;
1415

1516
readonly rootSection = "rust-analyzer";
16-
private readonly requiresWorkspaceReloadOpts = [
17-
// FIXME: This shouldn't be here, changing this setting should reload
18-
// `continueCommentsOnNewline` behavior without restart
19-
"typing",
20-
].map((opt) => `${this.rootSection}.${opt}`);
2117
private readonly requiresReloadOpts = [
2218
"cargo",
2319
"procMacro",
2420
"serverPath",
2521
"server",
2622
"files",
2723
"lens", // works as lens.*
28-
]
29-
.map((opt) => `${this.rootSection}.${opt}`)
30-
.concat(this.requiresWorkspaceReloadOpts);
24+
].map((opt) => `${this.rootSection}.${opt}`);
3125

3226
readonly package: {
3327
version: string;
@@ -45,6 +39,11 @@ export class Config {
4539
ctx.subscriptions
4640
);
4741
this.refreshLogging();
42+
this.configureLanguage();
43+
}
44+
45+
dispose() {
46+
this.configureLang?.dispose();
4847
}
4948

5049
private refreshLogging() {
@@ -58,33 +57,86 @@ export class Config {
5857
private async onDidChangeConfiguration(event: vscode.ConfigurationChangeEvent) {
5958
this.refreshLogging();
6059

60+
this.configureLanguage();
61+
6162
const requiresReloadOpt = this.requiresReloadOpts.find((opt) =>
6263
event.affectsConfiguration(opt)
6364
);
6465

6566
if (!requiresReloadOpt) return;
6667

67-
const requiresWorkspaceReloadOpt = this.requiresWorkspaceReloadOpts.find((opt) =>
68-
event.affectsConfiguration(opt)
69-
);
70-
71-
if (!requiresWorkspaceReloadOpt && this.restartServerOnConfigChange) {
68+
if (this.restartServerOnConfigChange) {
7269
await vscode.commands.executeCommand("rust-analyzer.reload");
7370
return;
7471
}
7572

76-
const message = requiresWorkspaceReloadOpt
77-
? `Changing "${requiresWorkspaceReloadOpt}" requires a window reload`
78-
: `Changing "${requiresReloadOpt}" requires a reload`;
79-
const userResponse = await vscode.window.showInformationMessage(message, "Reload now");
80-
81-
if (userResponse === "Reload now") {
82-
const command = requiresWorkspaceReloadOpt
83-
? "workbench.action.reloadWindow"
84-
: "rust-analyzer.reload";
85-
if (userResponse === "Reload now") {
86-
await vscode.commands.executeCommand(command);
87-
}
73+
const message = `Changing "${requiresReloadOpt}" requires a server restart`;
74+
const userResponse = await vscode.window.showInformationMessage(message, "Restart now");
75+
76+
if (userResponse) {
77+
const command = "rust-analyzer.reload";
78+
await vscode.commands.executeCommand(command);
79+
}
80+
}
81+
82+
/**
83+
* Sets up additional language configuration that's impossible to do via a
84+
* separate language-configuration.json file. See [1] for more information.
85+
*
86+
* [1]: https://github.com/Microsoft/vscode/issues/11514#issuecomment-244707076
87+
*/
88+
private configureLanguage() {
89+
if (this.typingContinueCommentsOnNewline && !this.configureLang) {
90+
const indentAction = vscode.IndentAction.None;
91+
92+
this.configureLang = vscode.languages.setLanguageConfiguration("rust", {
93+
onEnterRules: [
94+
{
95+
// Doc single-line comment
96+
// e.g. ///|
97+
beforeText: /^\s*\/{3}.*$/,
98+
action: { indentAction, appendText: "/// " },
99+
},
100+
{
101+
// Parent doc single-line comment
102+
// e.g. //!|
103+
beforeText: /^\s*\/{2}\!.*$/,
104+
action: { indentAction, appendText: "//! " },
105+
},
106+
{
107+
// Begins an auto-closed multi-line comment (standard or parent doc)
108+
// e.g. /** | */ or /*! | */
109+
beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/,
110+
afterText: /^\s*\*\/$/,
111+
action: {
112+
indentAction: vscode.IndentAction.IndentOutdent,
113+
appendText: " * ",
114+
},
115+
},
116+
{
117+
// Begins a multi-line comment (standard or parent doc)
118+
// e.g. /** ...| or /*! ...|
119+
beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/,
120+
action: { indentAction, appendText: " * " },
121+
},
122+
{
123+
// Continues a multi-line comment
124+
// e.g. * ...|
125+
beforeText: /^(\ \ )*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
126+
action: { indentAction, appendText: "* " },
127+
},
128+
{
129+
// Dedents after closing a multi-line comment
130+
// e.g. */|
131+
beforeText: /^(\ \ )*\ \*\/\s*$/,
132+
action: { indentAction, removeText: 1 },
133+
},
134+
],
135+
});
136+
}
137+
if (!this.typingContinueCommentsOnNewline && this.configureLang) {
138+
this.configureLang.dispose();
139+
this.configureLang = undefined;
88140
}
89141
}
90142

editors/code/src/ctx.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export class Ctx {
3838
this.dispose();
3939
},
4040
});
41+
extCtx.subscriptions.push(this);
4142
this.statusBar.text = "rust-analyzer";
4243
this.statusBar.tooltip = "ready";
4344
this.statusBar.command = "rust-analyzer.analyzerStatus";
@@ -48,10 +49,15 @@ export class Ctx {
4849
this.config = new Config(extCtx);
4950
}
5051

52+
dispose() {
53+
this.config.dispose();
54+
}
55+
5156
clientFetcher() {
57+
const self = this;
5258
return {
5359
get client(): lc.LanguageClient | undefined {
54-
return this.client;
60+
return self.client;
5561
},
5662
};
5763
}

editors/code/src/main.ts

Lines changed: 5 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,6 @@ async function activateServer(ctx: Ctx): Promise<RustAnalyzerExtensionApi> {
7777

7878
await initCommonContext(ctx);
7979

80-
if (ctx.config.typingContinueCommentsOnNewline) {
81-
ctx.pushExtCleanup(configureLanguage());
82-
}
83-
8480
vscode.workspace.onDidChangeConfiguration(
8581
async (_) => {
8682
await ctx
@@ -129,6 +125,11 @@ async function initCommonContext(ctx: Ctx) {
129125
ctx.registerCommand("stopServer", (_) => async () => {
130126
// FIXME: We should re-use the client, that is ctx.deactivate() if none of the configs have changed
131127
await ctx.disposeClient();
128+
ctx.setServerStatus({
129+
health: "ok",
130+
quiescent: true,
131+
message: "server is not running",
132+
});
132133
});
133134
ctx.registerCommand("analyzerStatus", commands.analyzerStatus);
134135
ctx.registerCommand("memoryUsage", commands.memoryUsage);
@@ -172,54 +173,3 @@ async function initCommonContext(ctx: Ctx) {
172173
defaultOnEnter.dispose();
173174
ctx.registerCommand("onEnter", commands.onEnter);
174175
}
175-
176-
/**
177-
* Sets up additional language configuration that's impossible to do via a
178-
* separate language-configuration.json file. See [1] for more information.
179-
*
180-
* [1]: https://github.com/Microsoft/vscode/issues/11514#issuecomment-244707076
181-
*/
182-
function configureLanguage(): vscode.Disposable {
183-
const indentAction = vscode.IndentAction.None;
184-
return vscode.languages.setLanguageConfiguration("rust", {
185-
onEnterRules: [
186-
{
187-
// Doc single-line comment
188-
// e.g. ///|
189-
beforeText: /^\s*\/{3}.*$/,
190-
action: { indentAction, appendText: "/// " },
191-
},
192-
{
193-
// Parent doc single-line comment
194-
// e.g. //!|
195-
beforeText: /^\s*\/{2}\!.*$/,
196-
action: { indentAction, appendText: "//! " },
197-
},
198-
{
199-
// Begins an auto-closed multi-line comment (standard or parent doc)
200-
// e.g. /** | */ or /*! | */
201-
beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/,
202-
afterText: /^\s*\*\/$/,
203-
action: { indentAction: vscode.IndentAction.IndentOutdent, appendText: " * " },
204-
},
205-
{
206-
// Begins a multi-line comment (standard or parent doc)
207-
// e.g. /** ...| or /*! ...|
208-
beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/,
209-
action: { indentAction, appendText: " * " },
210-
},
211-
{
212-
// Continues a multi-line comment
213-
// e.g. * ...|
214-
beforeText: /^(\ \ )*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
215-
action: { indentAction, appendText: "* " },
216-
},
217-
{
218-
// Dedents after closing a multi-line comment
219-
// e.g. */|
220-
beforeText: /^(\ \ )*\ \*\/\s*$/,
221-
action: { indentAction, removeText: 1 },
222-
},
223-
],
224-
});
225-
}

0 commit comments

Comments
 (0)