mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-04 10:50:15 +00:00
feat: Extend vscode 'run' command with optional mode argument for running test(s) or bin at keyboard cursor
This commit is contained in:
parent
df50136c23
commit
92da17cfa5
3 changed files with 70 additions and 4 deletions
|
@ -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";
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import * as vscode from "vscode";
|
||||
import type * as lc from "vscode-languageclient/node";
|
||||
import * as ra from "./lsp_ext";
|
||||
import * as commands from "./commands";
|
||||
|
||||
import { Config, prepareVSCodeConfig } from "./config";
|
||||
import { createClient } from "./client";
|
||||
|
@ -462,9 +463,17 @@ export class Ctx implements RustAnalyzerExtensionApi {
|
|||
for (const [name, factory] of Object.entries(this.commandFactories)) {
|
||||
const fullName = `rust-analyzer.${name}`;
|
||||
let callback;
|
||||
|
||||
if (isClientRunning(this)) {
|
||||
// we asserted that `client` is defined
|
||||
callback = factory.enabled(this);
|
||||
if (name === "run") {
|
||||
// Special case: support optional argument for `run`
|
||||
callback = (mode?: "cursor") => {
|
||||
return commands.run(this, mode)();
|
||||
};
|
||||
} else {
|
||||
// we asserted that `client` is defined
|
||||
callback = factory.enabled(this);
|
||||
}
|
||||
} else if (factory.disabled) {
|
||||
callback = factory.disabled(this);
|
||||
} else {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue