实现一个vscode插件:打开多个vscode项目时根据.nvmrc文件自动切换nvm

实现一个vscode插件:打开多个vscode项目时根据.nvmrc文件自动切换nvm_第1张图片

开发背景与最终功能

需要维护一些老项目,同时开发新项目时,切换nvm很烦人
最终实现vscode插件:每个vscode实例打开一个项目,切换vscode实例时能自动切换版本(需要项目根目录有一个.nvmrc文件)

插件下载

vscode插件市场搜索vscode-nvmrc实现一个vscode插件:打开多个vscode项目时根据.nvmrc文件自动切换nvm_第2张图片

设计思路

项目根目录新建.nvmrc文件,这是nvm的官方文件,当使用nvm use时会自动查找这个文件,而windows系统一般使用的是nvm-for-windows,它是由另一个开发者维护的windows版本,并不支持nvm use查找.nvmrc
不过这并不影响vscode插件中实现nvm use功能,只不过了解下.nvmrc是nvm的官方文件

话不多说,上代码,很简单,vscode插件方法vscode.window.onDidChangeWindowState中读取下.nvmrc文件,e.focused表示当vscode窗口显示时触发,切换vscode实例时能够触发,然后调用child_process.exec 运行nvm use

import * as vscode from "vscode";
import { exec } from "child_process";
import { readFile } from "fs";
import { resolve } from "path";

let statusBar: vscode.StatusBarItem | undefined;
let timeout: NodeJS.Timeout;

enum Status {
  error = "error",
}
function customStatusBar(text: string, type?: Status, time = 4000) {
  if (statusBar) {
    statusBar.dispose();
  }
  if (timeout) {
    clearTimeout(timeout);
  }
  statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
  statusBar.color = "#ffffff";

  if (type === Status.error) {
    statusBar.backgroundColor = new vscode.ThemeColor(
      "statusBarItem.errorBackground"
    );
  }
  if (!type) {
    statusBar.backgroundColor = new vscode.ThemeColor(
      "statusBarItem.warningBackground"
    );
  }
  statusBar.text = "vscode-nvmrc: " + text;
  statusBar.show();
  timeout = setTimeout(() => {
    if (statusBar) {
      statusBar.dispose();
    }
  }, time);
  return;
}

function execute(cmd: string) {
  exec(cmd, (error, stdout, stderr) => {
    if (error) {
      customStatusBar(`${error}`);
    } else {
      if (stderr) {
        customStatusBar(stderr);
      } else {
        customStatusBar(stdout);
      }
    }
  });
}

function nvmuse(url: string) {
  readFile(url, { encoding: "utf8" }, (err, data) => {
    if (err) {
      customStatusBar(".nvmrc file not found.");
      return;
    }
    execute("nvm use " + data);
  });
}

function resolveRootPathAndNvmuse() {
  const workspaceFolders = vscode.workspace.workspaceFolders;
  if (workspaceFolders && workspaceFolders.length > 0) {
    const rootPath = workspaceFolders[0].uri.fsPath;
    if (rootPath) {
      const url = resolve(rootPath, ".nvmrc");
      nvmuse(url);
    }
  }
}

export function activate(context: vscode.ExtensionContext) {
  resolveRootPathAndNvmuse();
  const disposable = vscode.window.onDidChangeWindowState((e) => {
    if (e.focused) {
      resolveRootPathAndNvmuse();
    }
  });
  context.subscriptions.push(disposable);
}

export function deactivate() {}

你可能感兴趣的:(vscode,ide,编辑器)