Skip to content

Commit 7838039

Browse files
committed
Add diagnostics command to help troubleshoot Ruby LSP issues
- Implement `diagnoseIssues` function in new `issueDiagnosingHelper.ts` file - Add new command `rubyLsp.diagnoseIssues` in `package.json` - Register the new command in `rubyLsp.ts` - Collect and display diagnostic information including: - VS Code version - Ruby LSP version - Installed Ruby LSP addons - Relevant installed VS Code extensions This feature will help users and maintainers quickly gather relevant information for troubleshooting Ruby LSP related issues.
1 parent 9d0417c commit 7838039

File tree

4 files changed

+108
-0
lines changed

4 files changed

+108
-0
lines changed

vscode/package.json

+5
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@
140140
"title": "Ruby file operations",
141141
"category": "Ruby LSP",
142142
"icon": "$(ruby)"
143+
},
144+
{
145+
"command": "rubyLsp.diagnoseIssues",
146+
"title": "Diagnose issues",
147+
"category": "Ruby LSP"
143148
}
144149
],
145150
"configuration": {

vscode/src/common.ts

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export enum Command {
2626
RailsGenerate = "rubyLsp.railsGenerate",
2727
RailsDestroy = "rubyLsp.railsDestroy",
2828
NewMinitestFile = "rubyLsp.newMinitestFile",
29+
DiagnoseIssues = "rubyLsp.diagnoseIssues",
2930
}
3031

3132
export interface RubyInterface {

vscode/src/issueDiagnosingHelper.ts

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import * as vscode from "vscode";
2+
3+
import { Workspace } from "./workspace";
4+
5+
export async function diagnoseIssues(workspace: Workspace | undefined) {
6+
if (!workspace) {
7+
await vscode.window.showErrorMessage("No active Ruby workspace found.");
8+
return;
9+
}
10+
11+
const diagnosticInfo = await collectDiagnosticInfo(workspace);
12+
const panel = vscode.window.createWebviewPanel(
13+
"rubyLspDiagnostics",
14+
"Ruby LSP Diagnostics",
15+
vscode.ViewColumn.One,
16+
{ enableScripts: true },
17+
);
18+
19+
panel.webview.html = generateDiagnosticsHtml(diagnosticInfo);
20+
}
21+
22+
async function collectDiagnosticInfo(
23+
workspace: Workspace,
24+
): Promise<Record<string, string | string[]>> {
25+
const vscodeVersion = vscode.version;
26+
const rubyLspVersion = workspace.lspClient?.serverVersion ?? "Unknown";
27+
const rubyLspAddons =
28+
workspace.lspClient?.addons?.map((addon) => addon.name) ?? [];
29+
const extensions = await getPublicExtensions();
30+
31+
return {
32+
// eslint-disable-next-line @typescript-eslint/naming-convention
33+
"VS Code Version": vscodeVersion,
34+
// eslint-disable-next-line @typescript-eslint/naming-convention
35+
"Ruby LSP Version": rubyLspVersion,
36+
// eslint-disable-next-line @typescript-eslint/naming-convention
37+
"Ruby LSP Addons": rubyLspAddons,
38+
// eslint-disable-next-line @typescript-eslint/naming-convention
39+
"Installed Extensions": extensions,
40+
};
41+
}
42+
43+
async function getPublicExtensions(): Promise<string[]> {
44+
return vscode.extensions.all
45+
.filter((ext) => {
46+
// Filter out built-in extensions
47+
if (ext.packageJSON.isBuiltin) {
48+
return false;
49+
}
50+
51+
// Check for marketplace identifier
52+
const galleryExtension = ext.packageJSON?.extensionPack?.[0] ?? ext.id;
53+
return galleryExtension.includes(".");
54+
})
55+
.map((ext) => `${ext.packageJSON.name} (${ext.packageJSON.version})`);
56+
}
57+
58+
function generateDiagnosticsHtml(
59+
info: Record<string, string | string[]>,
60+
): string {
61+
let html = `
62+
<!DOCTYPE html>
63+
<html lang="en">
64+
<head>
65+
<meta charset="UTF-8">
66+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
67+
<title>Ruby LSP Diagnostics</title>
68+
<style>
69+
body { font-family: var(--vscode-font-family); padding: 20px; }
70+
h1 { color: var(--vscode-editor-foreground); }
71+
dl { margin-left: 20px; }
72+
dt { font-weight: bold; margin-top: 10px; color: var(--vscode-editor-foreground); }
73+
dd { margin-left: 20px; color: var(--vscode-editor-foreground); }
74+
</style>
75+
</head>
76+
<body>
77+
<h1>Ruby LSP Diagnostics</h1>
78+
<dl>
79+
`;
80+
81+
for (const [key, value] of Object.entries(info)) {
82+
html += `<dt>${key}:</dt>`;
83+
if (Array.isArray(value)) {
84+
html += `<dd><ul>${value.map((val) => `<li>${val}</li>`).join("")}</ul></dd>`;
85+
} else {
86+
html += `<dd>${value}</dd>`;
87+
}
88+
}
89+
90+
html += `
91+
</dl>
92+
</body>
93+
</html>
94+
`;
95+
96+
return html;
97+
}

vscode/src/rubyLsp.ts

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { Debugger } from "./debugger";
1717
import { DependenciesTree } from "./dependenciesTree";
1818
import { Rails } from "./rails";
1919
import { ChatAgent } from "./chatAgent";
20+
import { diagnoseIssues } from "./issueDiagnosingHelper";
2021

2122
// The RubyLsp class represents an instance of the entire extension. This should only be instantiated once at the
2223
// activation event. One instance of this class controls all of the existing workspaces, telemetry and handles all
@@ -570,6 +571,10 @@ export class RubyLsp {
570571
await vscode.commands.executeCommand(pick.command, ...pick.args);
571572
}),
572573
vscode.commands.registerCommand(Command.NewMinitestFile, newMinitestFile),
574+
vscode.commands.registerCommand(Command.DiagnoseIssues, async () => {
575+
const workspace = await this.showWorkspacePick();
576+
await diagnoseIssues(workspace);
577+
}),
573578
);
574579
}
575580

0 commit comments

Comments
 (0)