本来只想配个终端,结果和 Claude 一起写了个 VSCode 插件

1,039 阅读3分钟

仓库地址:vscode-wezterm-quickstart

VSCode 插件安装地址:VSCode WezTerm Quickstart

Why

在朋友的推荐下,我试用了 WezTerm 这个命令行工具,并且得到了非常满意的体验,于是打算依照自己的使用习惯把它整合到我的开发工作流中。

我的日常开发编辑器是 VSCode(虽然最近切换到了 Cursor,但是鉴于 Cursor 是基于 VSCode 的,并无不同),常常使用 VSCode 的默认快捷键 Shift + Command + C 基于当前工作区快速打开外部命令行工具。

VSCode 配置 MacOS系统下的外部命令行工具配置如下:

// user setting.json
"terminal.external.osxExec": "warp.app" // 我的上一个命令行工具是 Warp

于是我把该配置改为 "terminal.external.osxExec": "wezterm.app" ,改完后发现使用快捷键打开的外部命令行工具(WezTerm)的当前路径,并不是此时 VSCode 打开的项目路径,而是默认的 ~ 路径。

查阅一番发现以下相关的提及:

  1. Unable to use WezTerm as externalTerminal
  2. Launch as "externalTerminal" in Visual Studio Code
  3. VSCode open external terminal wezterm in home folder instead of in project folder

简单来说,由于各家的命令行工具对于“以某一指定路径启动”的命令和处理是不一致的,所以VSCode 无法对所有的应用进行适配,以至于把 WezTerm 设置为 VSCode 的外部命令行工具后,虽然启动 WezTerm,但是无法进入到指定的目录中;个人推测大概率是 VSCode 在启动 WezTerm 时传入的工作区路径无法被正确接收。

出于小心求证的方式,遂翻了一下 VSCode 的源码,顺藤摸瓜在src/vs/platform/externalTerminal/node/externalTerminalService.ts 文件中找到以下关键代码:

// class MacExternalTerminalService...
spawnTerminal(spawner: typeof cp, configuration: IExternalTerminalSettings, cwd?: string): Promise<void> {
		const terminalApp = configuration.osxExec || DEFAULT_TERMINAL_OSX;
		return new Promise<void>((c, e) => {
			const args = ['-a', terminalApp];
			if (cwd) {
				args.push(cwd);
			}
			const env = getSanitizedEnvironment(process);
			const child = spawner.spawn('/usr/bin/open', args, { cwd, env });
			child.on('error', e);
			child.on('exit', () => c());
		});
	}

可以看出,其核心的原理是使用 child_porcess 的 spawn 方法,调用 /usr/bin/open(Mac 系统命令行中的 open 工具)打开用户配置的外部命令行应用,同时传入 cwd env 参数,使得命令行工具可以在当前工作区路径启动。

通过以上可以看出,VSCode 确实是传入了工作区路径;但是 WezTerm 文档中并没有介绍(我没有找到)通过 open 命令以指定路径启动的具体方式;而提供了一种以 WezTerm CLI 启动的方式:

wezterm start --cwd /some/path

这样看来,确实是证实了前面的猜想。于是我打算做一个 VSCode 插件去解决这个问题,因为在我的日常开发中,已经完全摒弃了 VSCode 内建的命令行,原因如下:

  • 挤占代码窗的高度 / 空间
  • 同时使用不同的命令行(内建 / 外部命令行),体验割裂;但是外部命令行是不得不用的
  • 内建命令行的样式、字体、使用体验各方面一言难尽

所以我的习惯是 "All in only one terminal"。

How

知道要干嘛了,剩下就简单了。

首先列出需求:

  • 通过 Shift + Command + C 可以以当前 VSCode 工作区目录根地址打开 WezTerm
  • 如果当前已经打开过 WezTerm,则新开一个标签页而非一个新窗口

然后喂给 Claude🤪。没错,这点事情,让 Ai 做比我自己做更快,毕竟我在这之前从来没有写过 VSCode 插件。

经过我和 Claude 的“通力合作”,在耗费了半小时的微调后,插件完成了(其实第一个三分钟已经完成了,但是又探索了一些可能的实现方式),然后又花了一个小时注册 VSCode 插件发布者,打包,代码提交等等细枝末节。

最终,我终于可以愉快地在我的开发工作流中使用 WezTerm 了🎉~