Skip to content

Run Button for Circuit Files - Standalone and Project #2455

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

ScottCarda-MS
Copy link
Contributor

Adds the VS Code Run button to circuit files so that the Q# project they are a part of can be run or debugged while looking at a circuit file. Also adds a command that the Run button can use for running just the circuit file and producing a dump machine for the circuit. This new functionality is available even if the circuit is not part of a Q# project.

@ScottCarda-MS ScottCarda-MS marked this pull request as ready for review May 23, 2025 19:22
}

function registerCommands(context: vscode.ExtensionContext) {
// Register commands for running and debugging Q# files.
context.subscriptions.push(
vscode.commands.registerCommand(
`${qsharpExtensionId}.runEditorContents`,
`${qsharpExtensionId}.runQsharp`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're renaming, may as well make it as accurate as possible - what about runProgram? We can run more than Q# with this command (i.e. qasm)

"command": "qsharp-vscode.runEditorContents",
"when": "resourceLangId == qsharp || resourceLangId == openqasm"
"command": "qsharp-vscode.runCircuitContents",
"when": "false"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why when: false? Why have this command here at all if it's never enabled?

(resource: vscode.Uri, expr?: string) => {
// if expr is not a string, ignore it. VS Code can sometimes
// pass other types when this command is invoked via UI buttons.
if (typeof expr !== "string") {
expr = undefined;
}
startQdkDebugging(resource, {
name: "Debug File",
name: "Debug",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, while we're renaming - ideally these names would be more descriptive and would more uniquely identify our scenario. They are visible to the user and correspond to the name field in launch.json. Perhaps: "QDK: Debug program"

}

// Returns true if any ancestor directory (excluding the file's own directory) contains qsharp.json
async function checkIfInQsharpProject(uri: vscode.Uri): Promise<boolean> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we talk about using findManifestDocument here instead of reimplementing the qsharp.json search logic?

Comment on lines +64 to +68
if (
document.languageId === "qsharp" ||
document.languageId === "openqasm" ||
document.languageId === "qsharpcircuit"
) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please prefer isQdkDocument instead of spot checking languageId like this - it's a more foolproof check

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought of one more thing - checking for QASM here is kind of meaningless since .qasm files and qsharp.json files never go together. Like a .qasm file could never be in a qsharp.json project. So you may want to tweak this check to use the more appropriate helpers from common.ts

vscode.commands.executeCommand(
"setContext",
"qsharp.isProjectFile",
isProjectFile,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we're setting a context key, I feel like we could make it something more helpful than just a boolean. Can we call this, say, activeQSharpProjectRoot and set it to the path of the active project directory (and null if we're not in a project)? This way, it's a bit more debuggable than true/false if something goes wrong and we don't understand what's happening.

let namespaceName: string | undefined = undefined;

try {
const program = await loadProject(resource);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably don't need the whole loadProject functionality here (which can be quite heavyweight especially if you have dependencies) since you just need the manifest path. Consider findManifestDocument

Copy link
Member

@billti billti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss design before proceeding with this. In general, I'm not sure the Run / Debug drop-down is the right place to add this functionality. compared to just a "Run" button in the editor or something. I'm not sure putting it in there is that discoverable or convenient (I'm guessing/hoping F5 still runs the project and not the circuit?)

Does it integrate with actual debugging (i.e. can you step through the circuit and see quantum state evolve)?

@@ -146,24 +146,33 @@
"menus": {
"editor/title/run": [
{
"command": "qsharp-vscode.runEditorContents",
"when": "resourceLangId == qsharp || resourceLangId == openqasm",
"command": "qsharp-vscode.runQsharp",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did all these get changed to *Qsharp from *Editor though? These apply to OpenQASM files also now, not just qsharp.

@@ -43,13 +43,11 @@ suite("OpenQASM Debugger Tests", function suite() {
vscode.debug.removeBreakpoints(vscode.debug.breakpoints);
});

test("Launch with debugEditorContents command", async () => {
test("Launch with debugQsharp command", async () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't get why the command name changed, and we should change it back. This is an OpenQASM test and you invoke debugQsharp, which is weird.

"command": "qsharp-vscode.debugEditorContents",
"when": "resourceLangId == qsharp || resourceLangId == openqasm"
"command": "qsharp-vscode.runQsharp",
"when": "resourceLangId == qsharp || resourceLangId == openqasm || (qsharp.isProjectFile && resourceLangId == qsharpcircuit)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you need this isProjectFile context for? There's a lot of clunky code to set it on updates, and anyway the PR description says "This new functionality is available even if the circuit is not part of a Q# project"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants