]> Git Repo - pico-vscode.git/commitdiff
v0.1.0
authorpaulober <[email protected]>
Tue, 4 Jul 2023 00:10:53 +0000 (02:10 +0200)
committerpaulober <[email protected]>
Tue, 4 Jul 2023 00:10:53 +0000 (02:10 +0200)
- Add workaround for cpptools not supporting dynamic ${command:}

.vscodeignore
src/commands/newProject.mts
src/commands/switchSDK.mts
src/extension.mts
src/settings.mts
src/ui.mts
src/utils/cmakeUtil.mts
src/utils/picoSDKEnvUtil.mts [new file with mode: 0644]
src/utils/picoSDKUtil.mts
src/utils/vscodeConfigUtil.mts

index 28afc06ed7a40f749587f4485f2fbed9744c771d..01df924b073d26a086ec81afd39e07caef4e5b84 100644 (file)
@@ -16,3 +16,6 @@ rollup.config.mjs
 **/*.ts
 .pnp*
 *.vsix
+
+# make sure scripts are always included
+!scripts/**
index f0d902c43bdf73080fcdf0ef89cff25084ca1cb5..f9891c4c048871fa3b61978257c3a67057042948 100644 (file)
@@ -1,16 +1,17 @@
-import { type Uri, window } from "vscode";
+import { Uri, commands, window } from "vscode";
 import { Command } from "./command.mjs";
 import Logger from "../logger.mjs";
 import { dirname, join } from "path";
 import { fileURLToPath } from "url";
 import { type ExecOptions, exec } from "child_process";
-import { getSDKAndToolchainPath } from "../utils/picoSDKUtil.mjs";
+import { detectInstalledSDKs } from "../utils/picoSDKUtil.mjs";
 import type Settings from "../settings.mjs";
 import {
   checkForRequirements,
   showRquirementsNotMetErrorMessage,
 } from "../utils/requirementsUtil.mjs";
 import { redirectVSCodeConfig } from "../utils/vscodeConfigUtil.mjs";
+import { compare } from "semver";
 
 enum BoardType {
   pico = "Pico",
@@ -36,13 +37,13 @@ enum Libraries {
 function enumToParam(e: BoardType | ConsoleOptions | Libraries): string {
   switch (e) {
     case BoardType.pico:
-      return "--board pico";
+      return "-board pico";
     case BoardType.picoW:
-      return "--board pico_w";
+      return "-board pico_w";
     case ConsoleOptions.consoleOverUART:
-      return "--uart";
+      return "-uart";
     case ConsoleOptions.consoleOverUSB:
-      return "--usb";
+      return "-usb";
     case Libraries.spi:
       return "-f spi";
     case Libraries.i2c:
@@ -73,13 +74,11 @@ interface NewProjectOptions {
 }
 
 function getScriptsRoot(): string {
-  return join(dirname(fileURLToPath(import.meta.url)), "scripts");
+  return join(dirname(fileURLToPath(import.meta.url)), "..", "scripts");
 }
 
 export default class NewProjectCommand extends Command {
   private readonly _logger: Logger = new Logger("NewProjectCommand");
-  // check at runtime if the OS is Windows
-  private readonly _isWindows: boolean = process.platform === "win32";
   private readonly _settings: Settings;
 
   constructor(settings: Settings) {
@@ -190,36 +189,43 @@ export default class NewProjectCommand extends Command {
   private async executePicoProjectGenerator(
     options: NewProjectOptions
   ): Promise<void> {
-    const [PICO_SDK_PATH, COMPILER_PATH] = (await getSDKAndToolchainPath(
+    /*const [PICO_SDK_PATH, COMPILER_PATH] = (await getSDKAndToolchainPath(
       this._settings
-    )) ?? [undefined, undefined];
+    )) ?? [];*/
+    const installedSDKs = (await detectInstalledSDKs()).sort((a, b) =>
+      compare(a.version, b.version)
+    );
 
-    if (!PICO_SDK_PATH || !COMPILER_PATH) {
+    if (installedSDKs.length === 0) {
       void window.showErrorMessage(
-        "Could not find Pico SDK or Toolchain. Please check your settings."
+        "Could not find Pico SDK or Toolchain. Please check the wiki."
       );
-
-      return;
     }
 
+    const PICO_SDK_PATH = installedSDKs[0].sdkPath;
+    const TOOLCHAIN_PATH = installedSDKs[0].toolchainPath;
+
     const customEnv: { [key: string]: string } = {
       ...process.env,
       // eslint-disable-next-line @typescript-eslint/naming-convention
       PICO_SDK_PATH: PICO_SDK_PATH,
       // eslint-disable-next-line @typescript-eslint/naming-convention
-      PICO_TOOLCHAIN_PATH: COMPILER_PATH,
+      PICO_TOOLCHAIN_PATH: TOOLCHAIN_PATH,
     };
-    customEnv["PATH"] = `${COMPILER_PATH}:${customEnv.PATH}`;
+    customEnv["PATH"] = `${TOOLCHAIN_PATH}:${customEnv["PATH"]}`;
 
-    // TODO: --projectRoot
     const command: string = [
       "python3",
       join(getScriptsRoot(), "pico_project.py"),
       enumToParam(options.boardType),
       ...options.consoleOptions.map(option => enumToParam(option)),
+      !options.consoleOptions.includes(ConsoleOptions.consoleOverUART)
+        ? "-nouart"
+        : "",
       ...options.libraries.map(option => enumToParam(option)),
       // generate .vscode config
       "--project",
+      "vscode",
       "--projectRoot",
       `"${options.projectRoot}"`,
       options.name,
@@ -240,10 +246,18 @@ export default class NewProjectCommand extends Command {
       await redirectVSCodeConfig(
         join(options.projectRoot, options.name, ".vscode"),
         this._settings.getExtensionId(),
-        this._settings.getExtensionName()
+        this._settings.getExtensionName(),
+        TOOLCHAIN_PATH,
+        installedSDKs[0].version
       );
       void window.showInformationMessage(
-        `Successfully created project ${options.name}`
+        `Successfully created project: ${options.name}`
+      );
+      // open new folder
+      void commands.executeCommand(
+        "vscode.openFolder",
+        Uri.file(join(options.projectRoot, options.name)),
+        true
       );
     } else {
       this._logger.error(
index b4fa05ae2eac04f06fcf4956e105860391ae106c..f2ceb2c6f171292e2f135c06dd699e29e0a12d9d 100644 (file)
@@ -1,28 +1,37 @@
 import { compare } from "semver";
-import { type PicoSDK, detectInstalledSDKs } from "../utils/picoSDKUtil.mjs";
+import { detectInstalledSDKs } from "../utils/picoSDKUtil.mjs";
 import { Command } from "./command.mjs";
-import { window } from "vscode";
+import { window, workspace } from "vscode";
 import type Settings from "../settings.mjs";
 import { SettingsKey } from "../settings.mjs";
 import type UI from "../ui.mjs";
+import { updateVSCodeStaticConfigs } from "../utils/vscodeConfigUtil.mjs";
+import { join } from "path";
+import { setPicoSDKPath, setToolchainPath } from "../utils/picoSDKEnvUtil.mjs";
 
 export default class SwitchSDKCommand extends Command {
-  private _settigs: Settings;
+  private _settings: Settings;
   private _ui: UI;
 
   constructor(settings: Settings, ui: UI) {
     super("switchSDK");
 
-    this._settigs = settings;
+    this._settings = settings;
     this._ui = ui;
   }
 
   async execute(): Promise<void> {
-    const availableSDKs = (await detectInstalledSDKs()).sort((a, b) =>
-      compare(a.version, b.version)
-    );
+    const availableSDKs = (await detectInstalledSDKs())
+      .sort((a, b) => compare(a.version, b.version))
+      .map(sdk => ({
+        label: `Pico SDK v${sdk.version}`,
+        // TODO: maybe remove description
+        description: `${sdk.sdkPath}; ${sdk.toolchainPath}`,
+        sdkPath: sdk.sdkPath,
+        toolchainPath: sdk.toolchainPath,
+      }));
 
-    const selectedSDK = await window.showQuickPick<PicoSDK>(availableSDKs, {
+    const selectedSDK = await window.showQuickPick(availableSDKs, {
       placeHolder: "Select Pico SDK",
       canPickMany: false,
       ignoreFocusOut: false,
@@ -33,9 +42,21 @@ export default class SwitchSDKCommand extends Command {
       return;
     }
 
+    if (workspace.workspaceFolders && workspace.workspaceFolders.length > 0) {
+      await updateVSCodeStaticConfigs(
+        join(workspace.workspaceFolders?.[0].uri.fsPath, ".vscode"),
+        selectedSDK.toolchainPath
+      );
+    }
+
+    setPicoSDKPath(selectedSDK.sdkPath, this._settings.getExtensionId());
+    setToolchainPath(selectedSDK.toolchainPath);
+    void window.showWarningMessage(
+      "Reload window to apply changes to linting."
+    );
     // TODO: maybe ensure workspace settings are used
     // save selected SDK version to settings
-    await this._settigs.update(SettingsKey.picoSDK, selectedSDK.version);
-    this._ui.updateSDKVersion(selectedSDK.version);
+    await this._settings.update(SettingsKey.picoSDK, selectedSDK.label);
+    this._ui.updateSDKVersion(selectedSDK.label);
   }
 }
index 833bfc04b948006bc4d4b6c040f6d6de9a998944..0e0cee95a62a2bd694b0a36f98882e544c3c56e8 100644 (file)
@@ -10,6 +10,9 @@ import { getSDKAndToolchainPath } from "./utils/picoSDKUtil.mjs";
 import SwitchSDKCommand from "./commands/switchSDK.mjs";
 import GetSDKPathCommand from "./commands/getSDKPath.mjs";
 import GetToolchainPathCommand from "./commands/getToolchainPath.mjs";
+import { setPicoSDKPath, setToolchainPath } from "./utils/picoSDKEnvUtil.mjs";
+import { existsSync } from "fs";
+import { join } from "path";
 
 export async function activate(context: ExtensionContext): Promise<void> {
   Logger.log("Congratulations the extension is now active!");
@@ -22,6 +25,21 @@ export async function activate(context: ExtensionContext): Promise<void> {
   const ui = new UI();
   ui.init();
 
+  // WORKAROUND: this check is required because of this extension
+  // beeing dependency of cpptools so it also gets activated in
+  // many non pico projects and ui.show... in these other projects
+  // would be confusing
+  // TODO: maybe also check subdirectories
+  if (
+    workspace.workspaceFolders &&
+    workspace.workspaceFolders.length > 0 &&
+    existsSync(
+      join(workspace.workspaceFolders?.[0].uri.fsPath, "pico_sdk_import.cmake")
+    )
+  ) {
+    ui.showStatusBarItems();
+  }
+
   const COMMANDS: Array<Command | CommandWithResult<string>> = [
     new HelloWorldCommand(),
     new GetSDKPathCommand(settings),
@@ -33,6 +51,7 @@ export async function activate(context: ExtensionContext): Promise<void> {
   // TODO: somehow allow custom toolchain version in Windows installer so that the
   // user can also choose the version as the toolchainPath settings does normally
   // contain a machine specific path and is not suitable for repository
+  // or thught a third party config/registry editor
 
   // auto project configuration with cmake
   if (
@@ -41,9 +60,14 @@ export async function activate(context: ExtensionContext): Promise<void> {
     workspace.workspaceFolders.length > 0
   ) {
     //run `cmake -G Ninja -B ./build ` in the root folder
-    await configureCmakeNinja(workspace.workspaceFolders?.[0].uri);
+    // TODO: maybe do this after env variables have been set so that the paths
+    // are not queried twice
+    await configureCmakeNinja(workspace.workspaceFolders?.[0].uri, settings);
   } else {
-    Logger.log("No workspace folder for configuration found");
+    Logger.log(
+      "No workspace folder for configuration found " +
+        "or cmakeAutoConfigure disabled."
+    );
   }
 
   // register all command handlers
@@ -53,15 +77,36 @@ export async function activate(context: ExtensionContext): Promise<void> {
 
   // check selected SDK version
   const sdkVersion = settings.getString(SettingsKey.picoSDK);
+  const sdkPath = await getSDKAndToolchainPath(settings);
+  const customSDKPath =
+    settings.getString(SettingsKey.picoSDKPath) || undefined;
+  const customToolchainPath =
+    settings.getString(SettingsKey.toolchainPath) || undefined;
 
-  if (sdkVersion) {
-    ui.updateSDKVersion(sdkVersion);
+  if (
+    // a SDK version is selected
+    sdkVersion &&
+    sdkPath &&
+    // only one path is custom
+    (customSDKPath === undefined || customToolchainPath === undefined)
+  ) {
+    setPicoSDKPath(sdkPath[0], settings.getExtensionId());
+    setToolchainPath(sdkPath[1]);
+    ui.updateSDKVersion(
+      sdkVersion +
+        // if one custom path is set then the picoSDK is only partly replaced/modifed
+        (customSDKPath !== undefined || customToolchainPath !== undefined
+          ? " [MODIFIED]"
+          : "")
+    );
   } else {
-    // if still a path for sdk can be
-    // retrieved (either by custom path settings or env), show "custom"
-    if ((await getSDKAndToolchainPath(settings)) !== undefined) {
+    // both paths are custom, show "custom"
+    if (sdkPath !== undefined) {
+      setPicoSDKPath(sdkPath[0], settings.getExtensionId());
+      setToolchainPath(sdkPath[1]);
       ui.updateSDKVersion("custom");
     } else {
+      // could not find SDK && toolchain
       ui.updateSDKVersion("N/A");
     }
   }
index 9eb0a0c4186eab37031f05c8e8ab4165a21cc6a0..596a854460a4452fb0c2c9da079ed49e6e5e4e5d 100644 (file)
@@ -24,10 +24,10 @@ export default class Settings {
   private pkg: PackageJSON;
 
   constructor(context: Memento, packageJSON: PackageJSON) {
-    this.config = workspace.getConfiguration("raspberry-pi-pico");
-
     this.context = context;
     this.pkg = packageJSON;
+
+    this.config = workspace.getConfiguration(packageJSON.name);
   }
 
   public get(key: SettingsKey): Setting {
index 3ea7e6bc3a2efd6ca125e01e7068a4507608681e..d02cb61ea85b0e885c35978d72d0c62b08c2f430 100644 (file)
@@ -37,6 +37,10 @@ export default class UI {
     });
   }
 
+  public showStatusBarItems(): void {
+    Object.values(this._items).forEach(item => item.show());
+  }
+
   public updateSDKVersion(version: string): void {
     this._items[StatusBarItemKey.picoSDKQuickPick].text = STATUS_BAR_ITEMS[
       StatusBarItemKey.picoSDKQuickPick
index d0fafe41d59645cc328b1d973cc9e94ee6edfbfe..15b8164cfd355804491dc9dfdc15e99a7443e1d2 100644 (file)
@@ -4,12 +4,18 @@ import {
   checkForRequirements,
   showRquirementsNotMetErrorMessage,
 } from "./requirementsUtil.mjs";
+import { join } from "path";
+import { getSDKAndToolchainPath } from "./picoSDKUtil.mjs";
+import type Settings from "../settings.mjs";
 
-export async function configureCmakeNinja(folder: Uri): Promise<boolean> {
+export async function configureCmakeNinja(
+  folder: Uri,
+  settings: Settings
+): Promise<boolean> {
   try {
     // check if CMakeLists.txt exists in the root folder
     await workspace.fs.stat(
-      folder.with({ path: folder.path + "/CMakeLists.txt" })
+      folder.with({ path: join(folder.path, "CMakeLists.txt") })
     );
 
     const rquirementsAvailable = await checkForRequirements();
@@ -21,9 +27,15 @@ export async function configureCmakeNinja(folder: Uri): Promise<boolean> {
     }
 
     void window.withProgress(
-      { location: ProgressLocation.Notification, cancellable: true },
+      {
+        location: ProgressLocation.Notification,
+        cancellable: true,
+        title: "Configuring CMake...",
+      },
       // eslint-disable-next-line @typescript-eslint/require-await
       async (progress, token) => {
+        const sdkPaths = await getSDKAndToolchainPath(settings);
+
         // TODO: analyze command result
         // TODO: option for the user to choose the generator
         const child = exec(`cmake -G Ninja -B ./build ${folder.fsPath}`, {
@@ -32,9 +44,9 @@ export async function configureCmakeNinja(folder: Uri): Promise<boolean> {
             ...process.env,
             // TODO: set PICO_SDK_PATH
             // eslint-disable-next-line @typescript-eslint/naming-convention
-            PICO_SDK_PATH: "",
+            PICO_SDK_PATH: sdkPaths?.[0],
             // eslint-disable-next-line @typescript-eslint/naming-convention
-            PICO_TOOLCHAIN_PATH: "",
+            PICO_TOOLCHAIN_PATH: sdkPaths?.[1],
           },
         });
 
diff --git a/src/utils/picoSDKEnvUtil.mts b/src/utils/picoSDKEnvUtil.mts
new file mode 100644 (file)
index 0000000..350c972
--- /dev/null
@@ -0,0 +1,76 @@
+import { readFileSync, writeFileSync } from "fs";
+import { join } from "path";
+import { extensions } from "vscode";
+import Logger from "../logger.mjs";
+
+/**
+ * Sets the PICO_SDK_PATH environment variable for vscode
+ * but also preserves the systems PICO_SDK_PATH variable if set.
+ *
+ * @param path New PICO_SDK_PATH
+ */
+export function setPicoSDKPath(path: string, extensionId?: string): void {
+  if (process.env.PICO_SDK_PATH) {
+    process.env.OLD_PICO_SDK_PATH = process.env.PICO_SDK_PATH;
+  }
+  process.env.PICO_SDK_PATH = path;
+
+  if (!extensionId) {
+    return;
+  }
+
+  // WORKAROUND: cpptools not supporting ${command:} syntax so ${env:} is the only one working
+  // but this requires us to set PICO_SDK_PATH before cpptools extension is loaded
+  // and checks its c_cpp_properties.json
+  const cppToolsPath =
+    extensions.getExtension("ms-vscode.cpptools")?.extensionPath;
+  if (cppToolsPath) {
+    const cppToolsPacakgeJsonPath = join(cppToolsPath, "package.json");
+    try {
+      // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+      const jsonData = JSON.parse(
+        readFileSync(cppToolsPacakgeJsonPath, "utf8")
+      );
+
+      // Check if 'extensionDependencies' property exists
+      // eslint-disable-next-line max-len
+      // eslint-disable-next-line no-prototype-builtins, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
+      if (!jsonData.hasOwnProperty("extensionDependencies")) {
+        // Add 'extensionDependencies' property with an empty array
+        // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+        jsonData.extensionDependencies = [];
+      }
+
+      // Add 'extensid' to 'extensionDependencies' array if not already present
+      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+      const extensionDependencies = jsonData.extensionDependencies as string[];
+      if (!extensionDependencies.includes("paulober.raspberry-pi-pico")) {
+        extensionDependencies.push("paulober.raspberry-pi-pico");
+      } else {
+        // don't write to avoid vscode asking to reload because ext changed on disk
+        return;
+      }
+
+      // Write the modified JSON back to the file
+      writeFileSync(cppToolsPacakgeJsonPath, JSON.stringify(jsonData, null, 4));
+    } catch (error) {
+      Logger.log("Error while modifying cpptools.");
+    }
+  }
+}
+
+export function setToolchainPath(path: string): void {
+  process.env.PICO_TOOLCHAIN_PATH = path;
+  process.env.PATH = `${path};${process.env.PATH ?? ""}`;
+}
+
+/**
+ * Retrieves the PICO_SDK_PATH environment variable from outside vscode.
+ * Usefull for detecting the pico-sdk set by the user outside of vscode by env variable.
+ *
+ * @returns PICO_SDK_PATH environment variable unmatched by the extension
+ */
+export function getSystemPicoSDKPath(): string | undefined {
+  // if there was PICO_SDK_PATH set outside of vscode, use it
+  return process.env.OLD_PICO_SDK_PATH || undefined;
+}
index 43ffd2d338c084ef222b070bea8d8fe1f0d91d04..7661d3cf137c230f89c0dc878bf984d54389ffca 100644 (file)
@@ -6,22 +6,29 @@ import { type QuickPickItem, QuickPickItemKind } from "vscode";
 import type Settings from "../settings.mjs";
 import { SettingsKey } from "../settings.mjs";
 import which from "which";
+import { getSystemPicoSDKPath } from "./picoSDKEnvUtil.mjs";
 
 export class PicoSDK implements QuickPickItem {
   public version: string;
+  public label: string;
   public sdkPath: string;
   public toolchainPath: string;
   public kind: QuickPickItemKind = QuickPickItemKind.Default;
 
   constructor(version: string, sdkPath: string, toolchainPath: string) {
     this.version = version;
+    this.label = `Pico SDK v${version}`;
     this.sdkPath = sdkPath;
     this.toolchainPath = toolchainPath;
   }
 
-  get label(): string {
+  /*get label(): string {
     return `Pico SDK v${this.version}`;
-  }
+  }*/
+
+  /*get description(): string {
+    return this.sdkPath;
+  }*/
 }
 
 /**
@@ -56,10 +63,10 @@ export async function getSDKAndToolchainPath(
   }
 
   // use manual paths if set
-  if (manualPicoSDKPath) {
+  if (manualPicoSDKPath !== undefined && manualPicoSDKPath !== "") {
     sdkPath = manualPicoSDKPath;
   }
-  if (manualToolchainPath) {
+  if (manualToolchainPath !== undefined && manualToolchainPath !== "") {
     toolchainPath = manualToolchainPath;
   }
 
@@ -76,15 +83,17 @@ export async function getSDKAndToolchainPath(
 async function detectSDKAndToolchainFromEnv(): Promise<
   [string, string] | undefined
 > {
-  if (process.env.PICO_SDK_PATH) {
+  const PICO_SDK_PATH = getSystemPicoSDKPath();
+  if (PICO_SDK_PATH) {
     // TODO: move compiler name into variable (global)
+    // TODO: maybe also check PICO_TOOLCHAIN_PATH variable
     const toolchainPath: string | null = await which("arm-none-eabi-gcc", {
       nothrow: true,
     });
 
     if (toolchainPath !== null) {
       // get grandparent directory of compiler
-      return [process.env.PICO_SDK_PATH, dirname(toolchainPath)];
+      return [PICO_SDK_PATH, dirname(toolchainPath)];
     }
   }
 
@@ -102,7 +111,7 @@ export async function detectInstalledSDKs(): Promise<PicoSDK[]> {
         sdkPath: "/Users/paulober/pico-sdk",
         toolchainPath:
           "/Applications/ArmGNUToolchain/12.2.mpacbti-rel1" +
-          "/arm-none-eabi/bin/arm-none-eabi-gcc",
+          "/arm-none-eabi/bin",
       } as PicoSDK,
     ];
   } else {
index beb5128c8bcee02c6c186a278d88bcddca19e4f2..19cf7fead7fd77fd65ee6cde82a48e8026f91c3a 100644 (file)
@@ -2,6 +2,7 @@ import { readFile, writeFile } from "fs/promises";
 import Logger from "../logger.mjs";
 import { join } from "path";
 import { EOL } from "os";
+import { SettingsKey } from "../settings.mjs";
 
 interface Configuration {
   name: string;
@@ -33,7 +34,7 @@ export async function updateCppPropertiesFile(
     });
 
     // Write the updated JSON back to the file
-    const updatedJsonData = JSON.stringify(cppProperties, null, 2);
+    const updatedJsonData = JSON.stringify(cppProperties, null, 4);
     await writeFile(file, updatedJsonData, "utf8");
 
     console.log("cpp_properties.json file updated successfully.");
@@ -103,7 +104,7 @@ async function replacePicoSDKPathVariable(
 
     Logger.log("launch.json file updated successfully.");
   } catch (error) {
-    Logger.log("An error occurred while updating the launch.json file.");
+    Logger.log("An error occurred while replacing PICO_SDK_PATH variable.");
   }
 }
 
@@ -125,26 +126,77 @@ async function removeLineFromFile(
   }
 }
 
+interface SettingsJSON {
+  [key: string]: unknown;
+}
+
+async function addSetting(
+  filePath: string,
+  setting: string,
+  value: string | boolean
+): Promise<void> {
+  try {
+    // Read the JSON file
+    const jsonData = await readFile(filePath, "utf8");
+    const settingsJSON: SettingsJSON = JSON.parse(jsonData) as SettingsJSON;
+    settingsJSON[setting] = value;
+    await writeFile(filePath, JSON.stringify(settingsJSON, null, 4), "utf8");
+
+    Logger.log("Pico SDK version set successfully for new project.");
+  } catch (error) {
+    // TODO: log error
+    Logger.log(
+      "An error occurred while settings Pico SDK version for new project."
+    );
+  }
+}
+
+/**
+ * Modifies auto-generated VSCode configuration files to integrate
+ * with this extension. This includes:
+ * - replacing paths with ${command:extension.getSDKPath} and ${command:extension.getToolchainPath}
+ * - adding the extension to the list of recommended extensions
+ * - adding the Pico SDK version to the list of settings
+ * - removing the set(PICO_SDK_PATH ...) from CMakeLists.txt so it uses the one set by the ext
+ *
+ * @param folder
+ * @param extensionId
+ * @param extensionName
+ * @param toolchainPath
+ * @param newSDKVersion
+ */
 export async function redirectVSCodeConfig(
   folder: string,
   extensionId: string,
-  extensionName: string
+  extensionName: string,
+  // WORKAROUND: as c_cpp_properties.json from vscode-cpptools
+  // does not support ${command:} variables at the moment
+  toolchainPath: string,
+  newSDKVersion?: string
 ): Promise<void> {
   // eslint-disable-next-line max-len
   const redirectedPicoSDKPathVariable = `\${command:${extensionName}.getSDKPath}`;
   // eslint-disable-next-line max-len
-  const redirectedToolchainPathVariable = `\${command:${extensionName}.getToolchainPath}`;
+  // WORKAROUND: const redirectedToolchainPathVariable = `\${command:${extensionName}.getToolchainPath}`;
 
-  const cppPropertiesFile = join(folder, "cpp_properties.json");
+  const cppPropertiesFile = join(folder, "c_cpp_properties.json");
   await updateCppPropertiesFile(
     cppPropertiesFile,
-    redirectedToolchainPathVariable
+    join(
+      // WORKAROUND: redirectedToolchainPathVariable,
+      toolchainPath,
+      process.platform === "win32"
+        ? "arm-none-eabi-gcc.exe"
+        : "arm-none-eabi-gcc"
+    )
   );
 
-  await replacePicoSDKPathVariable(
+  // WORKAROUND: c_cpp_properties.json from vscode-cpptools
+  // does not support ${command:} variables at the moment
+  /*await replacePicoSDKPathVariable(
     cppPropertiesFile,
     redirectedPicoSDKPathVariable
-  );
+  );*/
 
   await updateExtensionsJSONFile(join(folder, "extensions.json"), extensionId);
 
@@ -154,5 +206,55 @@ export async function redirectVSCodeConfig(
   );
 
   // TODO: maybe search sub directories too to find the CMakeLists.txt file?
-  await removeLineFromFile(join(folder, "CMakeLists.txt"), "set(PICO_SDK_PATH");
+  // TODO: maybe repalce the path with the one selected by the user so it can
+  // also be build from the command line? where the ext can edit the path before cmake
+  // but also once the project is configured
+  // with cmake -G Ninja, CMakeLists.txt is not used anymore (ideally)
+  await removeLineFromFile(
+    join(folder, "..", "CMakeLists.txt"),
+    "set(PICO_SDK_PATH"
+  );
+
+  if (newSDKVersion) {
+    await addSetting(
+      join(folder, "settings.json"),
+      [extensionName, SettingsKey.picoSDK].join("."),
+      newSDKVersion
+    );
+  }
+
+  // disable cmake confgiuring
+  await addSetting(
+    join(folder, "settings.json"),
+    "cmake.configureOnOpen",
+    false
+  );
+  await addSetting(
+    join(folder, "settings.json"),
+    "cmake.automaticReconfigure",
+    false
+  );
+  await addSetting(
+    join(folder, "settings.json"),
+    "cmake.configureOnEdit",
+    false
+  );
+}
+
+export async function updateVSCodeStaticConfigs(
+  folder: string,
+  toolchainPath: string
+): Promise<void> {
+  const cppPropertiesFile = join(folder, "c_cpp_properties.json");
+  // WORKAROUND: because c_cpp_properties.json from vscode-cpptools
+  // does not support dynamic variables
+  await updateCppPropertiesFile(
+    cppPropertiesFile,
+    join(
+      toolchainPath,
+      process.platform === "win32"
+        ? "arm-none-eabi-gcc.exe"
+        : "arm-none-eabi-gcc"
+    )
+  );
 }
This page took 0.057549 seconds and 4 git commands to generate.