Merge pull request #20077 from markpots5/master

feat: Extend vscode 'run' command with optional mode argument for run…
This commit is contained in:
Lukas Wirth 2025-06-25 08:13:14 +00:00 committed by GitHub
commit 756f1bfd65
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 60 additions and 3 deletions

View file

@ -1114,11 +1114,11 @@ export function applySnippetWorkspaceEditCommand(_ctx: CtxInit): Cmd {
};
}
export function run(ctx: CtxInit): Cmd {
export function run(ctx: CtxInit, mode?: "cursor"): Cmd {
let prevRunnable: RunnableQuickPick | undefined;
return async () => {
const item = await selectRunnable(ctx, prevRunnable);
const item = await selectRunnable(ctx, prevRunnable, false, true, mode);
if (!item) return;
item.detail = "rerun";

View file

@ -167,7 +167,7 @@ function createCommands(): Record<string, CommandFactory> {
viewCrateGraph: { enabled: commands.viewCrateGraph },
viewFullCrateGraph: { enabled: commands.viewFullCrateGraph },
expandMacro: { enabled: commands.expandMacro },
run: { enabled: commands.run },
run: { enabled: (ctx) => (mode?: "cursor") => commands.run(ctx, mode)() },
copyRunCommandLine: { enabled: commands.copyRunCommandLine },
debug: { enabled: commands.debug },
newDebugConfig: { enabled: commands.newDebugConfig },

View file

@ -18,10 +18,15 @@ export async function selectRunnable(
prevRunnable?: RunnableQuickPick,
debuggeeOnly = false,
showButtons: boolean = true,
mode?: "cursor",
): Promise<RunnableQuickPick | undefined> {
const editor = ctx.activeRustEditor ?? ctx.activeCargoTomlEditor;
if (!editor) return;
if (mode === "cursor") {
return selectRunnableAtCursor(ctx, editor, prevRunnable);
}
// show a placeholder while we get the runnables from the server
const quickPick = vscode.window.createQuickPick();
quickPick.title = "Select Runnable";
@ -54,6 +59,58 @@ export async function selectRunnable(
);
}
async function selectRunnableAtCursor(
ctx: CtxInit,
editor: RustEditor,
prevRunnable?: RunnableQuickPick,
): Promise<RunnableQuickPick | undefined> {
const runnableQuickPicks = await getRunnables(ctx.client, editor, prevRunnable, false);
let runnableQuickPickAtCursor = null;
const cursorPosition = ctx.client.code2ProtocolConverter.asPosition(editor.selection.active);
for (const runnableQuickPick of runnableQuickPicks) {
if (!runnableQuickPick.runnable.location?.targetRange) {
continue;
}
const runnableQuickPickRange = runnableQuickPick.runnable.location.targetRange;
if (
runnableQuickPickAtCursor?.runnable?.location?.targetRange != null &&
rangeContainsOtherRange(
runnableQuickPickRange,
runnableQuickPickAtCursor.runnable.location.targetRange,
)
) {
continue;
}
if (rangeContainsPosition(runnableQuickPickRange, cursorPosition)) {
runnableQuickPickAtCursor = runnableQuickPick;
}
}
if (runnableQuickPickAtCursor == null) {
return;
}
return Promise.resolve(runnableQuickPickAtCursor);
}
function rangeContainsPosition(range: lc.Range, position: lc.Position): boolean {
return (
(position.line > range.start.line ||
(position.line === range.start.line && position.character >= range.start.character)) &&
(position.line < range.end.line ||
(position.line === range.end.line && position.character <= range.end.character))
);
}
function rangeContainsOtherRange(range: lc.Range, otherRange: lc.Range) {
return (
(range.start.line < otherRange.start.line ||
(range.start.line === otherRange.start.line &&
range.start.character <= otherRange.start.character)) &&
(range.end.line > otherRange.end.line ||
(range.end.line === otherRange.end.line &&
range.end.character >= otherRange.end.character))
);
}
export class RunnableQuickPick implements vscode.QuickPickItem {
public label: string;
public description?: string | undefined;