mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 04:19:13 +00:00
Auto merge of #14366 - Veykril:linked-proj, r=Veykril
feat: Pop a notification prompting the user to add a Cargo.toml of unlinked file to the linkedProjects cc https://github.com/rust-lang/rust-analyzer/issues/13226 https://github.com/rust-lang/rust-analyzer/issues/9661
This commit is contained in:
commit
5bba438c9c
6 changed files with 74 additions and 15 deletions
|
@ -8,6 +8,7 @@ import * as diagnostics from "./diagnostics";
|
|||
import { WorkspaceEdit } from "vscode";
|
||||
import { Config, prepareVSCodeConfig } from "./config";
|
||||
import { randomUUID } from "crypto";
|
||||
import { sep as pathSeparator } from "path";
|
||||
|
||||
export interface Env {
|
||||
[name: string]: string;
|
||||
|
@ -69,7 +70,8 @@ export async function createClient(
|
|||
outputChannel: vscode.OutputChannel,
|
||||
initializationOptions: vscode.WorkspaceConfiguration,
|
||||
serverOptions: lc.ServerOptions,
|
||||
config: Config
|
||||
config: Config,
|
||||
unlinkedFiles: vscode.Uri[]
|
||||
): Promise<lc.LanguageClient> {
|
||||
const clientOptions: lc.LanguageClientOptions = {
|
||||
documentSelector: [{ scheme: "file", language: "rust" }],
|
||||
|
@ -119,6 +121,60 @@ export async function createClient(
|
|||
const preview = config.previewRustcOutput;
|
||||
const errorCode = config.useRustcErrorCode;
|
||||
diagnosticList.forEach((diag, idx) => {
|
||||
const value =
|
||||
typeof diag.code === "string" || typeof diag.code === "number"
|
||||
? diag.code
|
||||
: diag.code?.value;
|
||||
if (value === "unlinked-file" && !unlinkedFiles.includes(uri)) {
|
||||
const config = vscode.workspace.getConfiguration("rust-analyzer");
|
||||
if (config.get("showUnlinkedFileNotification")) {
|
||||
unlinkedFiles.push(uri);
|
||||
const folder = vscode.workspace.getWorkspaceFolder(uri)?.uri.fsPath;
|
||||
if (folder) {
|
||||
const parentBackslash = uri.fsPath.lastIndexOf(
|
||||
pathSeparator + "src"
|
||||
);
|
||||
const parent = uri.fsPath.substring(0, parentBackslash);
|
||||
|
||||
if (parent.startsWith(folder)) {
|
||||
const path = vscode.Uri.file(
|
||||
parent + pathSeparator + "Cargo.toml"
|
||||
);
|
||||
void vscode.workspace.fs.stat(path).then(async () => {
|
||||
const choice = await vscode.window.showInformationMessage(
|
||||
`This rust file does not belong to a loaded cargo project. It looks like it might belong to the workspace at ${path}, do you want to add it to the linked Projects?`,
|
||||
"Yes",
|
||||
"No",
|
||||
"Don't show this again"
|
||||
);
|
||||
switch (choice) {
|
||||
case "Yes":
|
||||
break;
|
||||
case "No":
|
||||
await config.update(
|
||||
"linkedProjects",
|
||||
config
|
||||
.get<any[]>("linkedProjects")
|
||||
?.concat(
|
||||
path.fsPath.substring(folder.length)
|
||||
),
|
||||
false
|
||||
);
|
||||
break;
|
||||
case "Don't show this again":
|
||||
await config.update(
|
||||
"showUnlinkedFileNotification",
|
||||
false,
|
||||
false
|
||||
);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Abuse the fact that VSCode leaks the LSP diagnostics data field through the
|
||||
// Diagnostic class, if they ever break this we are out of luck and have to go
|
||||
// back to the worst diagnostics experience ever:)
|
||||
|
@ -138,14 +194,6 @@ export async function createClient(
|
|||
.substring(0, index)
|
||||
.replace(/^ -->[^\n]+\n/m, "");
|
||||
}
|
||||
let value;
|
||||
if (errorCode) {
|
||||
if (typeof diag.code === "string" || typeof diag.code === "number") {
|
||||
value = diag.code;
|
||||
} else {
|
||||
value = diag.code?.value;
|
||||
}
|
||||
}
|
||||
diag.code = {
|
||||
target: vscode.Uri.from({
|
||||
scheme: diagnostics.URI_SCHEME,
|
||||
|
@ -153,7 +201,8 @@ export async function createClient(
|
|||
fragment: uri.toString(),
|
||||
query: idx.toString(),
|
||||
}),
|
||||
value: value ?? "Click for full compiler diagnostic",
|
||||
value:
|
||||
errorCode && value ? value : "Click for full compiler diagnostic",
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
|
@ -82,6 +82,7 @@ export class Ctx {
|
|||
private state: PersistentState;
|
||||
private commandFactories: Record<string, CommandFactory>;
|
||||
private commandDisposables: Disposable[];
|
||||
private unlinkedFiles: vscode.Uri[];
|
||||
|
||||
get client() {
|
||||
return this._client;
|
||||
|
@ -94,11 +95,11 @@ export class Ctx {
|
|||
) {
|
||||
extCtx.subscriptions.push(this);
|
||||
this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||
this.statusBar.show();
|
||||
this.workspace = workspace;
|
||||
this.clientSubscriptions = [];
|
||||
this.commandDisposables = [];
|
||||
this.commandFactories = commandFactories;
|
||||
this.unlinkedFiles = [];
|
||||
|
||||
this.state = new PersistentState(extCtx.globalState);
|
||||
this.config = new Config(extCtx);
|
||||
|
@ -218,7 +219,8 @@ export class Ctx {
|
|||
this.outputChannel,
|
||||
initializationOptions,
|
||||
serverOptions,
|
||||
this.config
|
||||
this.config,
|
||||
this.unlinkedFiles
|
||||
);
|
||||
this.pushClientCleanup(
|
||||
this._client.onNotification(ra.serverStatus, (params) =>
|
||||
|
@ -335,6 +337,7 @@ export class Ctx {
|
|||
setServerStatus(status: ServerStatusParams | { health: "stopped" }) {
|
||||
let icon = "";
|
||||
const statusBar = this.statusBar;
|
||||
statusBar.show();
|
||||
statusBar.tooltip = new vscode.MarkdownString("", true);
|
||||
statusBar.tooltip.isTrusted = true;
|
||||
switch (status.health) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue