feat(terminal): Align the terminal with IDEA's tabs, menu and settings

- ⌘T (Ctrl+Shift+T on Windows) opens a terminal tab while the terminal
  has focus; elsewhere the key keeps its IDE action.
- The tab bar's ▾ menu lists installed shells under "New Predefined
  Session" (login shell, shell integration) and links to Settings.
- Settings › Tools › Terminal: pick the shell path from the installed
  shells or browse for one, "Move focus to the Editor with Escape",
  fallback font, column width and a link to the Terminal keymap.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
Цей коміт міститься в:
l0ng-ai committed 2026-10-24 13:02:52 +08:00
1 джерело 1f5fcb477d
коміт be49490153
17 files changed
+320 -23

No files matched your search

+2
Переглянути файл
@@ -252,6 +252,8 @@ export const intellijMacos: Record<string, string[]> = {
"db.sqlScript": [],
"db.goToReferencedTable": [],
"db.collapseAll": [],
// Terminal (keyWhen: terminalFocus); after VCS Update / Go to Test so it wins there.
"terminal.new": ["Meta+T"],
// Last: later bindings win, so ⌘N is Generate in the editor and New in tool windows.
"code.generate": ["Meta+N"],
};
+2
Переглянути файл
@@ -249,6 +249,8 @@ export const intellijWindows: Record<string, string[]> = {
"db.sqlScript": [],
"db.goToReferencedTable": [],
"db.collapseAll": [],
// Terminal (keyWhen: terminalFocus); after VCS Update / Go to Test so it wins there.
"terminal.new": ["Ctrl+Shift+T"],
// Last: later bindings win, so Alt+Insert is Generate in the editor and New in tool windows.
"code.generate": ["Alt+Insert"],
};
+1
Переглянути файл
@@ -144,6 +144,7 @@ export const vscodeMacos: Record<string, string[]> = {
"toolwindow.git": ["Ctrl+Shift+G"],
"toolwindow.commit": [],
"toolwindow.terminal": ["Ctrl+`"],
"terminal.new": [],
"toolwindow.hideAll": ["Meta+B"],
"toolwindow.maximize": [],
"toolwindow.jumpToLast": [],
+10 -1
Переглянути файл
@@ -2324,5 +2324,14 @@
"Custom": "自定义",
"On PATH": "PATH 中",
"Reinstall": "重新安装",
"Auto-detect": "自动检测"
"Auto-detect": "自动检测",
"Move focus to the Editor with Escape": "按 Escape 将焦点移到编辑器",
"Otherwise Escape goes to the shell.": "否则 Escape 发送给 shell。",
"Configure terminal keybindings": "配置终端快捷键",
"Used for characters the main font lacks.": "用于主字体缺少的字符。",
"Column width": "列宽",
"Installed Shells": "已安装的 Shell",
"Installed shells": "已安装的 Shell",
"Shell Path": "Shell 路径",
"New Predefined Session": "新建预定义会话"
}
+10
Переглянути файл
@@ -91,12 +91,15 @@ export interface TerminalSettingsValid {
shellIntegration: boolean;
highlightHyperlinks: boolean;
optionAsMeta: boolean;
escapeToEditor: boolean;
cursorShape: CursorShape;
cursorBlink: boolean;
useEditorFont: boolean;
fontFamily: string;
fontSize: number;
lineHeight: number;
fallbackFontFamily: string;
columnWidth: number;
}
export interface ActionsOnSaveValid {
@@ -135,6 +138,7 @@ export const WORKFLOW_LIMITS = {
terminationTimeoutMs: { min: 0, max: 600_000 },
terminalFontSize: { min: 6, max: 72 },
terminalLineHeight: { min: 0.5, max: 3 },
terminalColumnWidth: { min: 0.5, max: 2 },
} as const;
export const DEFAULT_EXTERNAL_TOOL: ExternalToolValid = {
@@ -221,12 +225,15 @@ export const DEFAULT_WORKFLOW: WorkflowSettings = {
shellIntegration: true,
highlightHyperlinks: true,
optionAsMeta: false,
escapeToEditor: false,
cursorShape: "block",
cursorBlink: true,
useEditorFont: true,
fontFamily: "JetBrains Mono",
fontSize: 13,
lineHeight: 1,
fallbackFontFamily: "",
columnWidth: 1,
},
actionsOnSave: { optimizeImports: false, cleanup: false },
externalTools: [],
@@ -357,12 +364,15 @@ export function validateTerminal(raw: unknown): TerminalSettingsValid {
shellIntegration: bool(v.shellIntegration, d.shellIntegration),
highlightHyperlinks: bool(v.highlightHyperlinks, d.highlightHyperlinks),
optionAsMeta: bool(v.optionAsMeta, d.optionAsMeta),
escapeToEditor: bool(v.escapeToEditor, d.escapeToEditor),
cursorShape: oneOf(v.cursorShape, ["block", "underline", "bar"] as const, d.cursorShape),
cursorBlink: bool(v.cursorBlink, d.cursorBlink),
useEditorFont: bool(v.useEditorFont, d.useEditorFont),
fontFamily: nonEmpty(v.fontFamily, d.fontFamily),
fontSize: num(v.fontSize, d.fontSize, WORKFLOW_LIMITS.terminalFontSize),
lineHeight: num(v.lineHeight, d.lineHeight, WORKFLOW_LIMITS.terminalLineHeight),
fallbackFontFamily: text(v.fallbackFontFamily, d.fallbackFontFamily).trim(),
columnWidth: num(v.columnWidth, d.columnWidth, WORKFLOW_LIMITS.terminalColumnWidth),
};
}