Auto merge of #13451 - Veykril:lang-config, r=Veykril

internal: Properly handle language configuration config changes
This commit is contained in:
bors 2022-10-20 19:15:30 +00:00
commit 69f01fdff5
3 changed files with 88 additions and 80 deletions

View file

@ -11,13 +11,9 @@ export type RunnableEnvCfg =
export class Config {
readonly extensionId = "rust-lang.rust-analyzer";
configureLang: vscode.Disposable | undefined;
readonly rootSection = "rust-analyzer";
private readonly requiresWorkspaceReloadOpts = [
// FIXME: This shouldn't be here, changing this setting should reload
// `continueCommentsOnNewline` behavior without restart
"typing",
].map((opt) => `${this.rootSection}.${opt}`);
private readonly requiresReloadOpts = [
"cargo",
"procMacro",
@ -25,9 +21,7 @@ export class Config {
"server",
"files",
"lens", // works as lens.*
]
.map((opt) => `${this.rootSection}.${opt}`)
.concat(this.requiresWorkspaceReloadOpts);
].map((opt) => `${this.rootSection}.${opt}`);
readonly package: {
version: string;
@ -45,6 +39,11 @@ export class Config {
ctx.subscriptions
);
this.refreshLogging();
this.configureLanguage();
}
dispose() {
this.configureLang?.dispose();
}
private refreshLogging() {
@ -58,33 +57,86 @@ export class Config {
private async onDidChangeConfiguration(event: vscode.ConfigurationChangeEvent) {
this.refreshLogging();
this.configureLanguage();
const requiresReloadOpt = this.requiresReloadOpts.find((opt) =>
event.affectsConfiguration(opt)
);
if (!requiresReloadOpt) return;
const requiresWorkspaceReloadOpt = this.requiresWorkspaceReloadOpts.find((opt) =>
event.affectsConfiguration(opt)
);
if (!requiresWorkspaceReloadOpt && this.restartServerOnConfigChange) {
if (this.restartServerOnConfigChange) {
await vscode.commands.executeCommand("rust-analyzer.reload");
return;
}
const message = requiresWorkspaceReloadOpt
? `Changing "${requiresWorkspaceReloadOpt}" requires a window reload`
: `Changing "${requiresReloadOpt}" requires a reload`;
const userResponse = await vscode.window.showInformationMessage(message, "Reload now");
const message = `Changing "${requiresReloadOpt}" requires a server restart`;
const userResponse = await vscode.window.showInformationMessage(message, "Restart now");
if (userResponse === "Reload now") {
const command = requiresWorkspaceReloadOpt
? "workbench.action.reloadWindow"
: "rust-analyzer.reload";
if (userResponse === "Reload now") {
await vscode.commands.executeCommand(command);
}
if (userResponse) {
const command = "rust-analyzer.reload";
await vscode.commands.executeCommand(command);
}
}
/**
* Sets up additional language configuration that's impossible to do via a
* separate language-configuration.json file. See [1] for more information.
*
* [1]: https://github.com/Microsoft/vscode/issues/11514#issuecomment-244707076
*/
private configureLanguage() {
if (this.typingContinueCommentsOnNewline && !this.configureLang) {
const indentAction = vscode.IndentAction.None;
this.configureLang = vscode.languages.setLanguageConfiguration("rust", {
onEnterRules: [
{
// Doc single-line comment
// e.g. ///|
beforeText: /^\s*\/{3}.*$/,
action: { indentAction, appendText: "/// " },
},
{
// Parent doc single-line comment
// e.g. //!|
beforeText: /^\s*\/{2}\!.*$/,
action: { indentAction, appendText: "//! " },
},
{
// Begins an auto-closed multi-line comment (standard or parent doc)
// e.g. /** | */ or /*! | */
beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/,
afterText: /^\s*\*\/$/,
action: {
indentAction: vscode.IndentAction.IndentOutdent,
appendText: " * ",
},
},
{
// Begins a multi-line comment (standard or parent doc)
// e.g. /** ...| or /*! ...|
beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/,
action: { indentAction, appendText: " * " },
},
{
// Continues a multi-line comment
// e.g. * ...|
beforeText: /^(\ \ )*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
action: { indentAction, appendText: "* " },
},
{
// Dedents after closing a multi-line comment
// e.g. */|
beforeText: /^(\ \ )*\ \*\/\s*$/,
action: { indentAction, removeText: 1 },
},
],
});
}
if (!this.typingContinueCommentsOnNewline && this.configureLang) {
this.configureLang.dispose();
this.configureLang = undefined;
}
}