Skip to content

Commit

Permalink
NOT READY! | Rust support
Browse files Browse the repository at this point in the history
Signed-off-by: paulober <[email protected]>
  • Loading branch information
paulober committed Sep 27, 2024
2 parents e594124 + 9ed53e1 commit 0c5673c
Show file tree
Hide file tree
Showing 18 changed files with 1,546 additions and 86 deletions.
1 change: 1 addition & 0 deletions .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ tmp.py
!scripts/lwipopts.h
!scripts/pico_configs.tsv
!scripts/pico_project.py
!scripts/portable-msvc.py
!scripts/pico-vscode.cmake
!scripts/Pico.code-profile
!scripts/raspberrypi-swd.cfg
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ For optimal functionality, consider enabling:

When prompted, select the `Pico` kit in CMake Tools, and set your build and launch targets accordingly. Use CMake Tools for compilation, but continue using this extension for debugging, as CMake Tools debugging is not compatible with Pico.

## Rust Prerequisites

### Linux

- **GCC** for the host architecture

## VS Code Profiles

If you work with multiple microcontroller toolchains, consider installing this extension into a [VS Code Profile](https://code.visualstudio.com/docs/editor/profiles) to avoid conflicts with other toolchains. Follow these steps:
Expand Down
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
},
"activationEvents": [
"workspaceContains:./pico_sdk_import.cmake",
"workspaceContains:./.pico-rs",
"onWebviewPanel:newPicoProject",
"onWebviewPanel:newPicoMicroPythonProject"
],
Expand All @@ -79,13 +80,13 @@
"command": "raspberry-pi-pico.switchSDK",
"title": "Switch Pico SDK",
"category": "Raspberry Pi Pico",
"enablement": "raspberry-pi-pico.isPicoProject"
"enablement": "raspberry-pi-pico.isPicoProject && !raspberry-pi-pico.isRustProject"
},
{
"command": "raspberry-pi-pico.switchBoard",
"title": "Switch Board",
"category": "Raspberry Pi Pico",
"enablement": "raspberry-pi-pico.isPicoProject"
"enablement": "raspberry-pi-pico.isPicoProject && !raspberry-pi-pico.isRustProject"
},
{
"command": "raspberry-pi-pico.launchTargetPath",
Expand Down Expand Up @@ -151,7 +152,7 @@
"command": "raspberry-pi-pico.runProject",
"title": "Run Pico Project (USB)",
"category": "Raspberry Pi Pico",
"enablement": "raspberry-pi-pico.isPicoProject"
"enablement": "raspberry-pi-pico.isPicoProject && !raspberry-pi-pico.isRustProject"
},
{
"command": "raspberry-pi-pico.clearGithubApiCache",
Expand All @@ -162,7 +163,7 @@
"command": "raspberry-pi-pico.conditionalDebugging",
"title": "Conditional Debugging",
"category": "Raspberry Pi Pico",
"enablement": "raspberry-pi-pico.isPicoProject && !inQuickOpen"
"enablement": "raspberry-pi-pico.isPicoProject && !inQuickOpen && !raspberry-pi-pico.isRustProject"
},
{
"command": "raspberry-pi-pico.debugLayout",
Expand All @@ -179,7 +180,7 @@
"command": "raspberry-pi-pico.configureCmake",
"title": "Configure CMake",
"category": "Raspberry Pi Pico",
"enablement": "raspberry-pi-pico.isPicoProject"
"enablement": "raspberry-pi-pico.isPicoProject && !raspberry-pi-pico.isRustProject"
},
{
"command": "raspberry-pi-pico.importProject",
Expand All @@ -200,7 +201,7 @@
"command": "raspberry-pi-pico.flashProject",
"title": "Flash Pico Project (SWD)",
"category": "Raspberry Pi Pico",
"enablement": "raspberry-pi-pico.isPicoProject"
"enablement": "raspberry-pi-pico.isPicoProject && !raspberry-pi-pico.isRustProject"
}
],
"configuration": {
Expand Down Expand Up @@ -307,6 +308,7 @@
"got": "^14.4.2",
"ini": "^4.1.3",
"rimraf": "^5.0.7",
"toml": "^3.0.0",
"undici": "^6.19.7",
"uuid": "^10.0.0",
"which": "^4.0.0"
Expand Down
8 changes: 8 additions & 0 deletions src/commands/compileProject.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { EventEmitter } from "events";
import { CommandWithResult } from "./command.mjs";
import Logger from "../logger.mjs";
import Settings, { SettingsKey } from "../settings.mjs";
import { ContextKeys } from "../contextKeys.mjs";

Check warning on line 6 in src/commands/compileProject.mts

View workflow job for this annotation

GitHub Actions / build

'ContextKeys' is defined but never used
import State from "../state.mjs";

export default class CompileProjectCommand extends CommandWithResult<boolean> {
private _logger: Logger = new Logger("CompileProjectCommand");
Expand All @@ -18,9 +20,15 @@ export default class CompileProjectCommand extends CommandWithResult<boolean> {
const task = (await tasks.fetchTasks()).find(
task => task.name === "Compile Project"
);
/*const isRustProject = await commands.executeCommand(
"getContext",
ContextKeys.isRustProject
);*/
const isRustProject = State.getInstance().isRustProject;

const settings = Settings.getInstance();
if (
!isRustProject &&
settings !== undefined &&
settings.getBoolean(SettingsKey.useCmakeTools)
) {
Expand Down
14 changes: 13 additions & 1 deletion src/commands/newProject.mts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { window, type Uri } from "vscode";
import { NewProjectPanel } from "../webview/newProjectPanel.mjs";
// eslint-disable-next-line max-len
import { NewMicroPythonProjectPanel } from "../webview/newMicroPythonProjectPanel.mjs";
import { NewRustProjectPanel } from "../webview/newRustProjectPanel.mjs";

/**
* Enum for the language of the project.
Expand All @@ -13,13 +14,15 @@ import { NewMicroPythonProjectPanel } from "../webview/newMicroPythonProjectPane
export enum ProjectLang {
cCpp = 1,
micropython = 2,
rust = 3,
}

export default class NewProjectCommand extends CommandWithArgs {
private readonly _logger: Logger = new Logger("NewProjectCommand");
private readonly _extensionUri: Uri;
private static readonly micropythonOption = "MicroPython";
private static readonly cCppOption = "C/C++";
private static readonly rustOption = "Rust (experimental)";

public static readonly id = "newProject";

Expand All @@ -34,6 +37,8 @@ export default class NewProjectCommand extends CommandWithArgs {
? NewProjectCommand.cCppOption
: preSelectedType === ProjectLang.micropython
? NewProjectCommand.micropythonOption
: preSelectedType === ProjectLang.rust
? NewProjectCommand.rustOption
: undefined;
}

Expand All @@ -42,7 +47,11 @@ export default class NewProjectCommand extends CommandWithArgs {
const lang =
this.preSelectedTypeToStr(preSelectedType) ??
(await window.showQuickPick(
[NewProjectCommand.cCppOption, NewProjectCommand.micropythonOption],
[
NewProjectCommand.cCppOption,
NewProjectCommand.micropythonOption,
NewProjectCommand.rustOption,
],
{
placeHolder: "Select which language to use for your new project",
canPickMany: false,
Expand All @@ -58,6 +67,9 @@ export default class NewProjectCommand extends CommandWithArgs {
if (lang === NewProjectCommand.micropythonOption) {
// create a new project with MicroPython
NewMicroPythonProjectPanel.createOrShow(this._extensionUri);
} else if (lang === NewProjectCommand.rustOption) {
// create a new project with Rust
NewRustProjectPanel.createOrShow(this._extensionUri);
} else {
// show webview where the process of creating a new project is continued
NewProjectPanel.createOrShow(this._extensionUri);
Expand Down
1 change: 1 addition & 0 deletions src/contextKeys.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ import { extensionName } from "./commands/command.mjs";

export enum ContextKeys {
isPicoProject = `${extensionName}.isPicoProject`,
isRustProject = `${extensionName}.isRustProject`,
}
118 changes: 78 additions & 40 deletions src/extension.mts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ import FlashProjectSWDCommand from "./commands/flashProjectSwd.mjs";
import { NewMicroPythonProjectPanel } from "./webview/newMicroPythonProjectPanel.mjs";
import type { Progress as GotProgress } from "got";
import findPython, { showPythonNotFoundError } from "./utils/pythonHelper.mjs";
import { downloadAndInstallRust } from "./utils/rustUtil.mjs";
import State from "./state.mjs";

export async function activate(context: ExtensionContext): Promise<void> {
Logger.info(LoggerSource.extension, "Extension activation triggered");
Expand Down Expand Up @@ -166,11 +168,15 @@ export async function activate(context: ExtensionContext): Promise<void> {
);

const workspaceFolder = workspace.workspaceFolders?.[0];
const isRustProject = workspaceFolder
? existsSync(join(workspaceFolder.uri.fsPath, ".pico-rs"))
: false;

// check if is a pico project
if (
workspaceFolder === undefined ||
!existsSync(join(workspaceFolder.uri.fsPath, "pico_sdk_import.cmake"))
(!existsSync(join(workspaceFolder.uri.fsPath, "pico_sdk_import.cmake")) &&
!isRustProject)
) {
// finish activation
Logger.warn(
Expand All @@ -186,55 +192,87 @@ export async function activate(context: ExtensionContext): Promise<void> {
return;
}

const cmakeListsFilePath = join(workspaceFolder.uri.fsPath, "CMakeLists.txt");
if (!existsSync(cmakeListsFilePath)) {
Logger.warn(
LoggerSource.extension,
"No CMakeLists.txt in workspace folder has been found."
);
await commands.executeCommand(
"setContext",
ContextKeys.isPicoProject,
false
/*void commands.executeCommand(
"setContext",
ContextKeys.isRustProject,
isRustProject
);*/
State.getInstance().isRustProject = isRustProject;

if (!isRustProject) {
const cmakeListsFilePath = join(
workspaceFolder.uri.fsPath,
"CMakeLists.txt"
);
if (!existsSync(cmakeListsFilePath)) {
Logger.warn(
LoggerSource.extension,
"No CMakeLists.txt in workspace folder has been found."
);
await commands.executeCommand(
"setContext",
ContextKeys.isPicoProject,
false
);

return;
return;
}

// check if it has .vscode folder and cmake donotedit header in CMakelists.txt
if (
!existsSync(join(workspaceFolder.uri.fsPath, ".vscode")) ||
!readFileSync(cmakeListsFilePath)
.toString("utf-8")
.includes(CMAKE_DO_NOT_EDIT_HEADER_PREFIX)
) {
Logger.warn(
LoggerSource.extension,
"No .vscode folder and/or cmake",
'"DO NOT EDIT"-header in CMakelists.txt found.'
);
await commands.executeCommand(
"setContext",
ContextKeys.isPicoProject,
false
);
const wantToImport = await window.showInformationMessage(
"Do you want to import this project as Raspberry Pi Pico project?",
"Yes",
"No"
);
if (wantToImport === "Yes") {
void commands.executeCommand(
`${extensionName}.${ImportProjectCommand.id}`,
workspaceFolder.uri
);
}

return;
}
}

// check if it has .vscode folder and cmake donotedit header in CMakelists.txt
if (
!existsSync(join(workspaceFolder.uri.fsPath, ".vscode")) ||
!readFileSync(cmakeListsFilePath)
.toString("utf-8")
.includes(CMAKE_DO_NOT_EDIT_HEADER_PREFIX)
) {
Logger.warn(
LoggerSource.extension,
"No .vscode folder and/or cmake",
'"DO NOT EDIT"-header in CMakelists.txt found.'
);
await commands.executeCommand(
"setContext",
ContextKeys.isPicoProject,
false
);
const wantToImport = await window.showInformationMessage(
"Do you want to import this project as Raspberry Pi Pico project?",
"Yes",
"No"
await commands.executeCommand("setContext", ContextKeys.isPicoProject, true);

if (isRustProject) {
const cargo = await window.withProgress(

Check failure on line 257 in src/extension.mts

View workflow job for this annotation

GitHub Actions / build

Unsafe assignment of an error typed value
{
location: ProgressLocation.Notification,
title: "Downloading and installing Rust. This may take a while...",
cancellable: false,
},
async () => downloadAndInstallRust()

Check failure on line 263 in src/extension.mts

View workflow job for this annotation

GitHub Actions / build

Async arrow function has no 'await' expression

Check failure on line 263 in src/extension.mts

View workflow job for this annotation

GitHub Actions / build

Unsafe return of a value of type error

Check failure on line 263 in src/extension.mts

View workflow job for this annotation

GitHub Actions / build

Unsafe call of an `error` type typed value
);
if (wantToImport === "Yes") {
void commands.executeCommand(
`${extensionName}.${ImportProjectCommand.id}`,
workspaceFolder.uri
);
if (!cargo) {
void window.showErrorMessage("Failed to install Rust.");

return;
}

ui.showStatusBarItems(isRustProject);

return;
}

await commands.executeCommand("setContext", ContextKeys.isPicoProject, true);

// get sdk selected in the project
const selectedToolchainAndSDKVersions =
await cmakeGetSelectedToolchainAndSDKVersions(workspaceFolder.uri);
Expand Down
1 change: 1 addition & 0 deletions src/logger.mts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export enum LoggerSource {
cmake = "cmakeUtil",
downloadHelper = "downloadHelper",
pythonHelper = "pythonHelper",
rustUtil = "rustUtil",
}

/**
Expand Down
14 changes: 14 additions & 0 deletions src/state.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default class State {
private static instance?: State;
public isRustProject = false;

public constructor() {}

public static getInstance(): State {
if (!State.instance) {
this.instance = new State();
}

return this.instance!;
}
}
Loading

0 comments on commit 0c5673c

Please sign in to comment.