✨ feat(vscode): PyCharm 启动命令可配置(支持 ~/绝对路径),抽 expandTilde 复用
GUI 启动的 VS Code 扩展进程 PATH 常不含 JetBrains 启动器,裸 pycharm 易 ENOENT。 新增设置 pycharmCommand(默认 pycharm),贯穿 store/settings handler/messages/ KanbanPanel 与 webview,「钩子」分组在选 PyCharm 时显示「PyCharm 启动命令」输入框。 handleOpenWorktree 用该命令并经 expandTilde 展开 ~。expandTilde 从 resolveWorktreePath 抽出共用。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -842,6 +842,7 @@ export class KanbanWebviewPanel {
|
||||
autoBuildBranch: s.autoBuildBranch,
|
||||
worktreeDirectory: s.worktreeDirectory,
|
||||
worktreeOpenWith: s.worktreeOpenWith,
|
||||
pycharmCommand: s.pycharmCommand,
|
||||
worktreePostCreateScript: s.worktreePostCreateScript,
|
||||
worktreePreRemoveScript: s.worktreePreRemoveScript,
|
||||
implTabPreCreateScript: s.implTabPreCreateScript,
|
||||
@@ -903,6 +904,7 @@ export class KanbanWebviewPanel {
|
||||
autoBuildBranch: s.autoBuildBranch,
|
||||
worktreeDirectory: s.worktreeDirectory,
|
||||
worktreeOpenWith: s.worktreeOpenWith,
|
||||
pycharmCommand: s.pycharmCommand,
|
||||
worktreePostCreateScript: s.worktreePostCreateScript,
|
||||
worktreePreRemoveScript: s.worktreePreRemoveScript,
|
||||
implTabPreCreateScript: s.implTabPreCreateScript,
|
||||
|
||||
@@ -27,6 +27,7 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
|
||||
autoBuildBranch: string
|
||||
worktreeDirectory: string
|
||||
worktreeOpenWith: 'vscode' | 'pycharm'
|
||||
pycharmCommand: string
|
||||
worktreePostCreateScript: string
|
||||
worktreePreRemoveScript: string
|
||||
implTabPreCreateScript: string
|
||||
@@ -48,6 +49,9 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
|
||||
// worktree dir template: '' = "use default", so don't preserve blanks
|
||||
// specially — getSettings falls back to the default at read time.
|
||||
const trimmedWorktreeDir = payload.worktreeDirectory.trim()
|
||||
// pycharm launcher command: '' = "use default `pycharm`", getSettings falls
|
||||
// back at read time, so just strip whitespace here.
|
||||
const trimmedPycharmCmd = payload.pycharmCommand.trim()
|
||||
// Hook script paths: keep '' meaningful (= "use default
|
||||
// .spx/*.sh"). Just strip whitespace.
|
||||
const trimmedPostCreate = payload.worktreePostCreateScript.trim()
|
||||
@@ -78,6 +82,7 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
|
||||
autoBuildBranch: trimmedAutoBuildBranch,
|
||||
worktreeDirectory: trimmedWorktreeDir || prev.worktreeDirectory,
|
||||
worktreeOpenWith: payload.worktreeOpenWith || prev.worktreeOpenWith,
|
||||
pycharmCommand: trimmedPycharmCmd || prev.pycharmCommand,
|
||||
worktreePostCreateScript: trimmedPostCreate,
|
||||
worktreePreRemoveScript: trimmedPreRemove,
|
||||
implTabPreCreateScript: trimmedImplPre,
|
||||
@@ -98,6 +103,7 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
|
||||
autoBuildBranch: trimmedAutoBuildBranch,
|
||||
worktreeDirectory: trimmedWorktreeDir,
|
||||
worktreeOpenWith: payload.worktreeOpenWith,
|
||||
pycharmCommand: trimmedPycharmCmd,
|
||||
worktreePostCreateScript: trimmedPostCreate,
|
||||
worktreePreRemoveScript: trimmedPreRemove,
|
||||
implTabPreCreateScript: trimmedImplPre,
|
||||
@@ -179,6 +185,7 @@ export async function handleEditSettingsRequest(panel: KanbanWebviewPanel): Prom
|
||||
autoBuildBranch: s.autoBuildBranch,
|
||||
worktreeDirectory: s.worktreeDirectory,
|
||||
worktreeOpenWith: s.worktreeOpenWith,
|
||||
pycharmCommand: s.pycharmCommand,
|
||||
worktreePostCreateScript: s.worktreePostCreateScript,
|
||||
worktreePreRemoveScript: s.worktreePreRemoveScript,
|
||||
implTabPreCreateScript: s.implTabPreCreateScript,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { execFile } from 'node:child_process'
|
||||
import { commands, Uri, window, workspace } from 'vscode'
|
||||
import { getToken } from '../../auth/secrets'
|
||||
import { detectRepo } from '../../git/remote'
|
||||
import { resolveWorktreePath } from '../../git/worktree'
|
||||
import { expandTilde, resolveWorktreePath } from '../../git/worktree'
|
||||
import {
|
||||
runImplTabPostCloseHook,
|
||||
runImplTabPreCreateHook,
|
||||
@@ -32,13 +32,16 @@ export async function handleOpenWorktree(panel: KanbanWebviewPanel, relPath: str
|
||||
|
||||
// PyCharm 分支用 JetBrains 启动器打开目录。错误在回调里自行处理,不要落进
|
||||
// 下面 openFolder 的 catch。
|
||||
const { worktreeOpenWith } = getSettings(panel.context)
|
||||
const { worktreeOpenWith, pycharmCommand } = getSettings(panel.context)
|
||||
if (worktreeOpenWith === 'pycharm') {
|
||||
execFile('pycharm', [abs], (err) => {
|
||||
// GUI 启动的 VS Code 进程 PATH 常不含 JetBrains 启动器,故命令可配置;
|
||||
// 允许填 `~`/绝对路径,execFile 不走 shell,`~` 需自己展开。
|
||||
const cmd = expandTilde(pycharmCommand)
|
||||
execFile(cmd, [abs], (err) => {
|
||||
if (err) {
|
||||
const code = (err as NodeJS.ErrnoException).code ?? 'unknown'
|
||||
const message = code === 'ENOENT'
|
||||
? '找不到 pycharm 命令,请在 JetBrains Toolbox 里启用命令行启动器或把 pycharm 加入 PATH'
|
||||
? `找不到 ${cmd} 命令,请在「PyCharm 启动命令」里填启动器的完整路径,或确保它在 PATH 中`
|
||||
: err.message
|
||||
void window.showErrorMessage(`用 PyCharm 打开失败: ${message}`)
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ export type ExtensionToWebview
|
||||
autoBuildBranch: string
|
||||
worktreeDirectory: string
|
||||
worktreeOpenWith: 'vscode' | 'pycharm'
|
||||
pycharmCommand: string
|
||||
worktreePostCreateScript: string
|
||||
worktreePreRemoveScript: string
|
||||
implTabPreCreateScript: string
|
||||
@@ -119,6 +120,7 @@ export type WebviewToExtension
|
||||
autoBuildBranch: string
|
||||
worktreeDirectory: string
|
||||
worktreeOpenWith: 'vscode' | 'pycharm'
|
||||
pycharmCommand: string
|
||||
worktreePostCreateScript: string
|
||||
worktreePreRemoveScript: string
|
||||
implTabPreCreateScript: string
|
||||
|
||||
Reference in New Issue
Block a user