Skip to content

Commit 19e925d

Browse files
authored
feat: register profile command (#3560)
* feat: register profile command * refactor: use progress display instead of notification * refactor: add Vernier check
1 parent 937e658 commit 19e925d

File tree

3 files changed

+84
-0
lines changed

3 files changed

+84
-0
lines changed

vscode/package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@
5757
"command": "rubyLsp.goToRelevantFile",
5858
"when": "rubyLsp.activated",
5959
"group": "navigation"
60+
},
61+
{
62+
"command": "rubyLsp.profileCurrentFile",
63+
"when": "editorTextFocus && resourceLangId == ruby",
64+
"group": "navigation",
65+
"icon": "$(record)"
6066
}
6167
],
6268
"view/title": [
@@ -189,6 +195,12 @@
189195
"command": "rubyLsp.showOutput",
190196
"title": "Show output channel",
191197
"category": "Ruby LSP"
198+
},
199+
{
200+
"command": "rubyLsp.profileCurrentFile",
201+
"title": "Profile current file",
202+
"category": "Ruby LSP",
203+
"icon": "$(record)"
192204
}
193205
],
194206
"configuration": {

vscode/src/common.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export enum Command {
3434
ShowOutput = "rubyLsp.showOutput",
3535
MigrateLaunchConfiguration = "rubyLsp.migrateLaunchConfiguration",
3636
GoToRelevantFile = "rubyLsp.goToRelevantFile",
37+
ProfileCurrentFile = "rubyLsp.profileCurrentFile",
3738
}
3839

3940
export interface RubyInterface {

vscode/src/rubyLsp.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import * as os from "os";
2+
import * as path from "path";
3+
14
import * as vscode from "vscode";
25
import { Range } from "vscode-languageclient/node";
36

@@ -737,6 +740,74 @@ export class RubyLsp {
737740
);
738741
}
739742
}),
743+
vscode.commands.registerCommand(Command.ProfileCurrentFile, async () => {
744+
const workspace = this.currentActiveWorkspace();
745+
746+
if (!workspace) {
747+
vscode.window.showInformationMessage("No workspace found");
748+
return;
749+
}
750+
751+
try {
752+
const { stdout } = await workspace.execute("vernier --version");
753+
const version = stdout.trim();
754+
const [major, minor, _] = version.split(".").map(Number);
755+
756+
if (major < 1 || (major === 1 && minor < 8)) {
757+
const install = await vscode.window.showInformationMessage(
758+
"Vernier version 1.8.0 or higher is required for profiling. Would you like to install it?",
759+
"Install",
760+
);
761+
762+
if (install === "Install") {
763+
await workspace.execute("gem install vernier");
764+
} else {
765+
return;
766+
}
767+
}
768+
} catch (error) {
769+
const install = await vscode.window.showInformationMessage(
770+
"Vernier is required for profiling. Would you like to install it?",
771+
"Install",
772+
);
773+
774+
if (install === "Install") {
775+
await workspace.execute("gem install vernier");
776+
} else {
777+
return;
778+
}
779+
}
780+
781+
const currentFile = vscode.window.activeTextEditor?.document.uri.fsPath;
782+
783+
if (!currentFile) {
784+
vscode.window.showInformationMessage(
785+
"No file opened in the editor to profile",
786+
);
787+
return;
788+
}
789+
790+
await vscode.window.withProgress(
791+
{
792+
location: vscode.ProgressLocation.Notification,
793+
title: "Profiling in progress...",
794+
cancellable: false,
795+
},
796+
async () => {
797+
const profileUri = vscode.Uri.file(
798+
path.join(os.tmpdir(), `profile-${Date.now()}.cpuprofile`),
799+
);
800+
801+
await workspace.execute(
802+
`vernier run --output ${profileUri.fsPath} --format cpuprofile -- ruby ${currentFile}`,
803+
);
804+
805+
await vscode.commands.executeCommand("vscode.open", profileUri, {
806+
viewColumn: vscode.ViewColumn.Beside,
807+
});
808+
},
809+
);
810+
}),
740811
];
741812
}
742813

0 commit comments

Comments
 (0)