[codex] add terminal font size shortcuts
This commit is contained in:
70
application/AppHandlers.globalHotkeys.test.ts
Normal file
70
application/AppHandlers.globalHotkeys.test.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { handleGlobalHotkeyKeyDownImpl } from './app/AppHandlers.ts';
|
||||
import { matchesKeyBinding } from '../domain/models.ts';
|
||||
import { DEFAULT_KEY_BINDINGS } from '../domain/models/keyBindings.ts';
|
||||
|
||||
class FakeHTMLElement {
|
||||
tagName = 'TEXTAREA';
|
||||
isContentEditable = false;
|
||||
classList = {
|
||||
contains: (className: string) => className === 'xterm-helper-textarea',
|
||||
};
|
||||
|
||||
closest(selector: string): FakeHTMLElement | null {
|
||||
return selector.includes('xterm') ? this : null;
|
||||
}
|
||||
|
||||
hasAttribute(name: string): boolean {
|
||||
return name === 'data-session-id';
|
||||
}
|
||||
}
|
||||
|
||||
const previousHTMLElement = globalThis.HTMLElement;
|
||||
globalThis.HTMLElement = FakeHTMLElement as unknown as typeof HTMLElement;
|
||||
|
||||
test.after(() => {
|
||||
globalThis.HTMLElement = previousHTMLElement;
|
||||
});
|
||||
|
||||
test('global hotkey handler lets terminal font size shortcuts reach xterm', () => {
|
||||
const target = new FakeHTMLElement();
|
||||
const handledActions: string[] = [];
|
||||
let prevented = false;
|
||||
let stopped = false;
|
||||
const event = {
|
||||
key: '=',
|
||||
code: 'Equal',
|
||||
ctrlKey: true,
|
||||
metaKey: false,
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
target,
|
||||
composedPath: () => [target],
|
||||
preventDefault: () => {
|
||||
prevented = true;
|
||||
},
|
||||
stopPropagation: () => {
|
||||
stopped = true;
|
||||
},
|
||||
} as unknown as KeyboardEvent;
|
||||
|
||||
handleGlobalHotkeyKeyDownImpl(
|
||||
() => ({
|
||||
HOTKEY_DEBUG: false,
|
||||
closeTabKeyStr: 'Ctrl + W',
|
||||
executeHotkeyAction: (action: string) => {
|
||||
handledActions.push(action);
|
||||
},
|
||||
hotkeyScheme: 'pc',
|
||||
keyBindings: DEFAULT_KEY_BINDINGS,
|
||||
matchesKeyBinding,
|
||||
}),
|
||||
event,
|
||||
);
|
||||
|
||||
assert.deepEqual(handledActions, []);
|
||||
assert.equal(prevented, false);
|
||||
assert.equal(stopped, false);
|
||||
});
|
||||
@@ -2,8 +2,10 @@
|
||||
import type React from 'react';
|
||||
import type { Host, HostProtocol } from '../../types';
|
||||
import type { PassphraseRequest } from '../../components/PassphraseModal';
|
||||
import { getTerminalPassthroughActions } from '../state/useGlobalHotkeys';
|
||||
|
||||
type AppContextGetter = () => Record<string, any>;
|
||||
const TERMINAL_PASSTHROUGH_ACTIONS = getTerminalPassthroughActions();
|
||||
|
||||
export function handleTrayJumpToSessionImpl(getCtx: AppContextGetter, sessionId: string) {
|
||||
const { sessions, setActiveTabId, setWorkspaceFocusedSession } = getCtx();
|
||||
@@ -147,8 +149,7 @@ export function handleGlobalHotkeyKeyDownImpl(getCtx: AppContextGetter, e: Keybo
|
||||
if (binding.category === 'sftp') {
|
||||
continue;
|
||||
}
|
||||
const terminalActions = ['copy', 'paste', 'pasteSelection', 'selectAll', 'clearBuffer', 'searchTerminal'];
|
||||
if (terminalActions.includes(binding.action)) {
|
||||
if (TERMINAL_PASSTHROUGH_ACTIONS.has(binding.action)) {
|
||||
if (isTerminalElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -49,5 +49,8 @@ export const getTerminalPassthroughActions = (): Set<string> => {
|
||||
'selectAll',
|
||||
'clearBuffer',
|
||||
'searchTerminal',
|
||||
'increaseTerminalFontSize',
|
||||
'decreaseTerminalFontSize',
|
||||
'resetTerminalFontSize',
|
||||
]);
|
||||
};
|
||||
|
||||
@@ -103,6 +103,7 @@ const TerminalComponent: React.FC<TerminalProps> = ({
|
||||
hotkeyScheme = "disabled",
|
||||
keyBindings = [],
|
||||
onHotkeyAction,
|
||||
onTerminalFontSizeChange,
|
||||
onStatusChange,
|
||||
onSessionExit,
|
||||
onTerminalDataCapture,
|
||||
@@ -986,7 +987,7 @@ const TerminalComponent: React.FC<TerminalProps> = ({
|
||||
['--terminal-ui-toolbar-btn-active' as never]: `var(--terminal-preview-toolbar-btn-active, color-mix(in srgb, ${effectiveTheme.colors.cursor} 78%, ${effectiveTheme.colors.background} 22%))`,
|
||||
}), [effectiveTheme.colors.background, effectiveTheme.colors.cursor, effectiveTheme.colors.foreground]);
|
||||
|
||||
useTerminalEffects({ CONNECTION_TIMEOUT, Error, XTERM_PERFORMANCE_CONFIG, applyUserCursorPreference, auth, autocompleteCloseRef, autocompleteInputRef, autocompleteKeyEventRef, captureTerminalLogData, clearTerminalCwd, commandBufferRef, connectionLogBufferRef, containerRef, createPromptLineBreakState, createReplaySafeTerminalLogSanitizer, createXTermRuntime, effectiveFontSize, effectiveFontWeight, effectiveTheme, error, executeSnippetCommand, fitAddonRef, fontFamilyId, fontSize, fontWeightFixupDoneRef, forceSyncRenderAfterResize, handleOsc52ReadRequest, handleTerminalDataCaptureOnce, hasConnectedRef, host, hotkeySchemeRef, identities, inWorkspace, isBroadcastEnabledRef, isFocusMode, isFocused, isLocalConnection, isNetworkDevice, isResizing, isRestoringSelectionRef, isSearchOpen, isSerialConnection, isVisible, isVisibleRef, keyBindingsRef, keys, knownCwdRef, lastFittedSizeRef, lastToastedErrorRef, logger, mouseTrackingRef, onBroadcastInputRef, onCommandExecuted, onHotkeyActionRef, onSnippetShortkeyRef, onSnippetExecutorChange, onTerminalCwdChange, pendingAuthRef, pendingOutputScrollRef, prevIsResizingRef, primaryFontFamily, promptLineBreakStateRef, resizeSession, resolveHostAuth, resolvedFontFamily, safeFit, searchAddonRef, serialConfig, serialLineBufferRef, serializeAddonRef, sessionId, sessionRef, sessionStarters, setError, setHasMouseTracking, setHasSelection, setIsCancelling, setIsDisconnectedDialogDismissed, setIsSearchOpen, setNeedsHostKeyVerification, setPendingHostKeyInfo, setPendingHostKeyRequestId, setProgressLogs, setProgressValue, setShowLogs, setStatus, setTimeLeft, shouldEnableNativeUserInputAutoScroll, shouldProbeSessionCwd, snippetsRef, status, statusRef, t, teardown, termRef, terminalAltKeyOptions, terminalBackend, terminalContextActionsRef, terminalCwdTracker, terminalDataCapturedRef, terminalLogSanitizerRef, terminalSettings, terminalSettingsRef, toHostKeyInfo, toast, updateStatus, useEffect, useLayoutEffect, xtermRuntimeRef, zmodem, zmodemToastedRef });
|
||||
useTerminalEffects({ CONNECTION_TIMEOUT, Error, XTERM_PERFORMANCE_CONFIG, applyUserCursorPreference, auth, autocompleteCloseRef, autocompleteInputRef, autocompleteKeyEventRef, captureTerminalLogData, clearTerminalCwd, commandBufferRef, connectionLogBufferRef, containerRef, createPromptLineBreakState, createReplaySafeTerminalLogSanitizer, createXTermRuntime, effectiveFontSize, effectiveFontWeight, effectiveTheme, error, executeSnippetCommand, fitAddonRef, fontFamilyId, fontSize, fontWeightFixupDoneRef, forceSyncRenderAfterResize, handleOsc52ReadRequest, handleTerminalDataCaptureOnce, hasConnectedRef, host, hotkeySchemeRef, identities, inWorkspace, isBroadcastEnabledRef, isFocusMode, isFocused, isLocalConnection, isNetworkDevice, isResizing, isRestoringSelectionRef, isSearchOpen, isSerialConnection, isVisible, isVisibleRef, keyBindingsRef, keys, knownCwdRef, lastFittedSizeRef, lastToastedErrorRef, logger, mouseTrackingRef, onBroadcastInputRef, onCommandExecuted, onHotkeyActionRef, onSnippetShortkeyRef, onSnippetExecutorChange, onTerminalCwdChange, onTerminalFontSizeChange, pendingAuthRef, pendingOutputScrollRef, prevIsResizingRef, primaryFontFamily, promptLineBreakStateRef, resizeSession, resolveHostAuth, resolvedFontFamily, safeFit, searchAddonRef, serialConfig, serialLineBufferRef, serializeAddonRef, sessionId, sessionRef, sessionStarters, setError, setHasMouseTracking, setHasSelection, setIsCancelling, setIsDisconnectedDialogDismissed, setIsSearchOpen, setNeedsHostKeyVerification, setPendingHostKeyInfo, setPendingHostKeyRequestId, setProgressLogs, setProgressValue, setShowLogs, setStatus, setTimeLeft, shouldEnableNativeUserInputAutoScroll, shouldProbeSessionCwd, snippetsRef, status, statusRef, t, teardown, termRef, terminalAltKeyOptions, terminalBackend, terminalContextActionsRef, terminalCwdTracker, terminalDataCapturedRef, terminalLogSanitizerRef, terminalSettings, terminalSettingsRef, toHostKeyInfo, toast, updateStatus, useEffect, useLayoutEffect, xtermRuntimeRef, zmodem, zmodemToastedRef });
|
||||
|
||||
return <TerminalView ctx={{ ArrowDownToLine, ArrowUpFromLine, Button, Copy, Cpu, HardDrive, HoverCard, HoverCardContent, HoverCardTrigger, Maximize2, MemoryStick, Radio, TerminalAutocomplete, TerminalComposeBar, TerminalConnectionDialog, TerminalContextMenu, TerminalSearchBar, Tooltip, TooltipContent, TooltipTrigger, ZmodemOverwriteDialog, ZmodemProgressIndicator, auth, autocompleteAcceptTextRef, autocompleteCloseRef, autocompleteHostOs, autocompleteInputRef, autocompleteKeyEventRef, autocompleteRepositionRef, autocompleteSettings, chainProgress, cn, containerRef, effectiveTheme, error, executeSnippet, executeSnippetCommand, formatNetSpeed, handleCancelConnect, handleCloseDisconnectedSession, handleCloseSearch, handleDismissDisconnectedDialog, handleDragEnter, handleDragLeave, handleDragOver, handleDrop, handleFindNext, handleFindPrevious, handleHostKeyAddAndContinue, handleHostKeyClose, handleHostKeyContinue, handleOsc52ReadResponse, handleRetry, handleSearch, handleTopOverlayMouseDownCapture, hasMouseTracking, hasSelection, host, hotkeyScheme, inWorkspace, isBroadcastEnabled, isCancelling, isComposeBarOpen, isDraggingOver, isFocusMode, isLocalConnection, isSearchOpen, isVisible, keyBindings, keys, knownCwdRef, needsHostKeyVerification, onBroadcastInput, onCloseSession, onExpandToFocus, onSplitHorizontal, onSplitVertical, onToggleBroadcast, osc52ReadPromptVisible, pendingHostKeyInfo, progressLogs, progressValue, renderControls, scrollToBottomAfterProgrammaticInput, searchMatchCount, serverStats, sessionId, sessionRef, setIsComposeBarOpen, setShowLogs, shouldShowConnectionDialog, showLogs, snippets, status, statusDotTone, t, termRef, terminalBackend, terminalContextActions, terminalCwdTracker, terminalPreviewVars, terminalSettings, timeLeft, toast, zmodem }} />;
|
||||
};
|
||||
|
||||
@@ -481,6 +481,8 @@ const TerminalLayerInner: React.FC<TerminalLayerProps> = ({
|
||||
for (const h of hosts) map.set(h.id, h);
|
||||
return map;
|
||||
}, [hosts]);
|
||||
const hostMapRef = useRef(hostMap);
|
||||
hostMapRef.current = hostMap;
|
||||
const proxyProfileIdSet = useMemo(
|
||||
() => new Set(proxyProfiles.map((profile) => profile.id)),
|
||||
[proxyProfiles],
|
||||
@@ -589,6 +591,19 @@ const TerminalLayerInner: React.FC<TerminalLayerProps> = ({
|
||||
}, [sessions, sessionHostsMap, hostMap, groupConfigs, proxyProfileIdSet, proxyProfiles]);
|
||||
const sessionHostsMapRef = useRef(sessionHostsMap);
|
||||
sessionHostsMapRef.current = sessionHostsMap;
|
||||
const handleTerminalFontSizeChange = useCallback((sessionId: string, nextFontSize: number) => {
|
||||
const sessionHost = sessionHostsMapRef.current.get(sessionId);
|
||||
if (!sessionHost) return;
|
||||
|
||||
const rawHost = hostMapRef.current.get(sessionHost.id);
|
||||
const usesGlobalFontSize = sessionHost.protocol === 'local' || sessionHost.id?.startsWith('local-') || !rawHost;
|
||||
if (usesGlobalFontSize) {
|
||||
onUpdateTerminalFontSize?.(nextFontSize);
|
||||
return;
|
||||
}
|
||||
|
||||
onUpdateHost({ ...rawHost, fontSize: nextFontSize, fontSizeOverride: true });
|
||||
}, [onUpdateHost, onUpdateTerminalFontSize]);
|
||||
|
||||
const validAIScopeTargetIds = useMemo(() => {
|
||||
const ids = new Set<string>();
|
||||
@@ -966,7 +981,7 @@ const TerminalLayerInner: React.FC<TerminalLayerProps> = ({
|
||||
const prevFocusedSessionIdRef = useRef<string | undefined>(undefined);
|
||||
|
||||
useTerminalLayerEffects({ activeSidePanelTab, activeTabId, activeTabIdRef, activeTopTabsThemeId, activeWorkspace, activityTrackedSessions, appliedPreviewSessionRef, applyTerminalPreviewVars, applyTopTabsPreviewVars, cancelAnimationFrame, ChunkedEscapeFilter, clearTerminalPreviewVars, clearTimeout, clearTopTabsPreviewVars, document, dropHint, filterTabsMap, focusedSessionId, followAppTerminalTheme, getSessionActivityIdsToClear, handleOpenAI, handleToggleScriptsSidePanel, handleToggleSidePanel, hasNotifiableTerminalOutput, isFocusMode, isTerminalLayerVisible, lastSidePanelTabRef, Map, Math, onSessionData, onSplitSessionRef, onToggleBroadcastRef, onToggleWorkspaceViewModeRef, onUpdateSplitSizes, prevFocusedSessionIdRef, previewTargetSessionId, requestAnimationFrame, ResizeObserver, resizing, sessionActivityStore, sessions, Set, setDropHint, setResizing, setSftpHostForTab, setSftpInitialLocationForTab, setSftpPendingUploadsForTab, setSidePanelOpenTabs, setThemePreview, setTimeout, setupMcpApprovalBridge, setWorkspaceArea, sftpActiveHost, sftpHostForTab, shouldMarkSessionActivity, sidePanelOpenTabs, splitHorizontalHandlersRef, splitVerticalHandlersRef, terminalRendererCwdBySessionRef, themeCommitTimerRef, themePreview, toggleScriptsSidePanelRef, toggleSidePanelRef, validAIScopeTargetIds, validSessionActivityIds, visibleFocusedThemeId, window, workspaceBroadcastHandlersRef, workspaceFocusHandlersRef, workspaceInnerRef, workspaces });
|
||||
return <TerminalLayerView ctx={{ accentMode, activeResizers, activeSidePanelTab, activeTabId, activeWorkspace, AIChatPanelsHost, aiContextsByTabId, AIStateMaintenanceHost, AIStateProvider, Array, Button, cn, composeBarThemeColors, computeSplitHint, customAccent, draggingSessionId, dropHint, editorWordWrap, effectiveHosts, findSplitNode, focusedFontFamilyId, focusedFontFamilyOverridden, focusedFontSize, focusedFontSizeOverridden, focusedFontWeight, focusedFontWeightOverridden, focusedSessionId, focusedThemeOverridden, FolderTree, followAppTerminalTheme, fontSize, getTerminalCwd, handleAddKnownHost, handleBroadcastInput, handleCloseSession, handleCloseSidePanel, handleCommandExecuted, handleComposeSend, handleFontFamilyChangeForFocusedSession, handleFontFamilyResetForFocusedSession, handleFontSizeChangeForFocusedSession, handleFontSizeResetForFocusedSession, handleFontWeightChangeForFocusedSession, handleFontWeightResetForFocusedSession, handleOpenAI, handleOpenScripts, handleOpenSftp, handleOpenTheme, handleOsDetected, handlePendingUploadHandled, handleSessionExit, handleSftpInitialLocationApplied, handleSidePanelResizeStart, handleSnippetClickForFocusedSession, handleSnippetFromPanel, handleSnippetExecutorChange, handleStatusChange, handleTerminalCwdChange, handleTerminalDataCapture, handleThemeChangeForFocusedSession, handleThemeResetForFocusedSession, handleToggleSftpFromBar, handleToggleWorkspaceComposeBar, handleUpdateHost, handleWorkspaceDrop, hosts, hotkeyScheme, identities, isBroadcastEnabled, isComposeBarOpen, isFocusMode, isSidePanelOpenForCurrentTab, isTerminalLayerVisible, keyBindings, keys, knownHosts, MessageSquare, mountedAiTabIds, mountedSftpTabIds, onHotkeyAction, onSetWorkspaceFocusedSession, onSplitSession, Palette, PanelLeft, PanelRight, previewedOrVisibleThemeId, refocusActiveTerminalSession, refocusTerminalSession, renderFocusModeSidebar, resizing, resolveAIExecutorContext, resolvedPreviewTheme, ScriptsSidePanel, sessionChainHostsMap, sessionHostsMap, sessionLogConfig, sessions, setDropHint, setEditorWordWrap, setIsComposeBarOpen, setResizing, setSidePanelPosition, sftpActiveHost, sftpAutoSync, sftpDefaultViewMode, sftpDoubleClickBehavior, sftpInitialLocationForTab, sftpPendingUploadsForTab, sftpShowHiddenFiles, SftpSidePanel, sftpUseCompressedUpload, sidePanelPosition, sidePanelWidth, snippetPackages, snippets, splitHorizontalHandlersRef, splitVerticalHandlersRef, t, TerminalComposeBar, terminalFontFamilyId, TerminalPanesHost, terminalSettings, terminalTheme, themePreview, ThemeSidePanel, Tooltip, TooltipContent, TooltipTrigger, updateHosts, validAIScopeTargetIds, workspaceBroadcastHandlersRef, workspaceById, workspaceFocusHandlersRef, workspaceInnerRef, workspaceOuterRef, workspaceOverlayRef, workspaceRectsById, X, Zap }} />;
|
||||
return <TerminalLayerView ctx={{ accentMode, activeResizers, activeSidePanelTab, activeTabId, activeWorkspace, AIChatPanelsHost, aiContextsByTabId, AIStateMaintenanceHost, AIStateProvider, Array, Button, cn, composeBarThemeColors, computeSplitHint, customAccent, draggingSessionId, dropHint, editorWordWrap, effectiveHosts, findSplitNode, focusedFontFamilyId, focusedFontFamilyOverridden, focusedFontSize, focusedFontSizeOverridden, focusedFontWeight, focusedFontWeightOverridden, focusedSessionId, focusedThemeOverridden, FolderTree, followAppTerminalTheme, fontSize, getTerminalCwd, handleAddKnownHost, handleBroadcastInput, handleCloseSession, handleCloseSidePanel, handleCommandExecuted, handleComposeSend, handleFontFamilyChangeForFocusedSession, handleFontFamilyResetForFocusedSession, handleFontSizeChangeForFocusedSession, handleFontSizeResetForFocusedSession, handleFontWeightChangeForFocusedSession, handleFontWeightResetForFocusedSession, handleOpenAI, handleOpenScripts, handleOpenSftp, handleOpenTheme, handleOsDetected, handlePendingUploadHandled, handleSessionExit, handleSftpInitialLocationApplied, handleSidePanelResizeStart, handleSnippetClickForFocusedSession, handleSnippetFromPanel, handleSnippetExecutorChange, handleStatusChange, handleTerminalCwdChange, handleTerminalDataCapture, handleTerminalFontSizeChange, handleThemeChangeForFocusedSession, handleThemeResetForFocusedSession, handleToggleSftpFromBar, handleToggleWorkspaceComposeBar, handleUpdateHost, handleWorkspaceDrop, hosts, hotkeyScheme, identities, isBroadcastEnabled, isComposeBarOpen, isFocusMode, isSidePanelOpenForCurrentTab, isTerminalLayerVisible, keyBindings, keys, knownHosts, MessageSquare, mountedAiTabIds, mountedSftpTabIds, onHotkeyAction, onSetWorkspaceFocusedSession, onSplitSession, Palette, PanelLeft, PanelRight, previewedOrVisibleThemeId, refocusActiveTerminalSession, refocusTerminalSession, renderFocusModeSidebar, resizing, resolveAIExecutorContext, resolvedPreviewTheme, ScriptsSidePanel, sessionChainHostsMap, sessionHostsMap, sessionLogConfig, sessions, setDropHint, setEditorWordWrap, setIsComposeBarOpen, setResizing, setSidePanelPosition, sftpActiveHost, sftpAutoSync, sftpDefaultViewMode, sftpDoubleClickBehavior, sftpInitialLocationForTab, sftpPendingUploadsForTab, sftpShowHiddenFiles, SftpSidePanel, sftpUseCompressedUpload, sidePanelPosition, sidePanelWidth, snippetPackages, snippets, splitHorizontalHandlersRef, splitVerticalHandlersRef, t, TerminalComposeBar, terminalFontFamilyId, TerminalPanesHost, terminalSettings, terminalTheme, themePreview, ThemeSidePanel, Tooltip, TooltipContent, TooltipTrigger, updateHosts, validAIScopeTargetIds, workspaceBroadcastHandlersRef, workspaceById, workspaceFocusHandlersRef, workspaceInnerRef, workspaceOuterRef, workspaceOverlayRef, workspaceRectsById, X, Zap }} />;
|
||||
};
|
||||
|
||||
export const TerminalLayer = memo(TerminalLayerInner, terminalLayerAreEqual);
|
||||
|
||||
@@ -47,6 +47,10 @@ import { terminalAltKeyOptions } from "./altKeyOptions";
|
||||
import { optionArrowWordJumpSequence } from "./optionArrowWordJump";
|
||||
import { watchDevicePixelRatio } from "./rendererDprWatch";
|
||||
import { handleSerialLineModeInput } from "./serialLineInput";
|
||||
import {
|
||||
nextTerminalFontSizeForAction,
|
||||
nextTerminalFontSizeForWheel,
|
||||
} from "./terminalFontZoom";
|
||||
import {
|
||||
markExpectedTerminalCursorPositionReport,
|
||||
pasteTextIntoTerminal,
|
||||
@@ -106,6 +110,7 @@ export type CreateXTermRuntimeContext = {
|
||||
onHotkeyActionRef: RefObject<
|
||||
((action: string, event: KeyboardEvent) => void) | undefined
|
||||
>;
|
||||
onTerminalFontSizeChange?: (fontSize: number) => void;
|
||||
|
||||
isBroadcastEnabledRef: RefObject<boolean | undefined>;
|
||||
onBroadcastInputRef: RefObject<
|
||||
@@ -489,6 +494,39 @@ export const createXTermRuntime = (ctx: CreateXTermRuntimeContext): XTermRuntime
|
||||
term.scrollToBottom();
|
||||
}
|
||||
};
|
||||
const currentTerminalFontSize = () => {
|
||||
const optionFontSize = term.options.fontSize;
|
||||
return typeof optionFontSize === "number" ? optionFontSize : effectiveFontSize;
|
||||
};
|
||||
const applyTerminalFontSize = (nextFontSize: number | null): boolean => {
|
||||
if (nextFontSize === null) return false;
|
||||
const currentFontSize = currentTerminalFontSize();
|
||||
if (nextFontSize !== currentFontSize) {
|
||||
term.options.fontSize = nextFontSize;
|
||||
clearWebglTextureAtlas();
|
||||
try {
|
||||
fitAddon.fit();
|
||||
} catch (err) {
|
||||
logger.warn("[XTerm] fit after font size change failed", err);
|
||||
}
|
||||
ctx.onTerminalFontSizeChange?.(nextFontSize);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
const handleFontSizeWheel = (event: WheelEvent) => {
|
||||
const currentScheme = ctx.hotkeySchemeRef.current;
|
||||
const isMac = currentScheme === "mac" || (currentScheme === "disabled" && isMacPlatform());
|
||||
const nextFontSize = nextTerminalFontSizeForWheel(
|
||||
event,
|
||||
currentTerminalFontSize(),
|
||||
isMac,
|
||||
);
|
||||
if (nextFontSize === null) return;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
applyTerminalFontSize(nextFontSize);
|
||||
};
|
||||
ctx.container.addEventListener("wheel", handleFontSizeWheel, { passive: false });
|
||||
|
||||
term.attachCustomKeyEventHandler((e: KeyboardEvent) => {
|
||||
// Preserve mouse selection across keystrokes when enabled. xterm.js
|
||||
@@ -621,6 +659,14 @@ export const createXTermRuntime = (ctx: CreateXTermRuntimeContext): XTermRuntime
|
||||
ctx.setIsSearchOpen(true);
|
||||
break;
|
||||
}
|
||||
case "increaseTerminalFontSize":
|
||||
case "decreaseTerminalFontSize":
|
||||
case "resetTerminalFontSize": {
|
||||
applyTerminalFontSize(
|
||||
nextTerminalFontSizeForAction(action, currentTerminalFontSize()),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -938,6 +984,7 @@ export const createXTermRuntime = (ctx: CreateXTermRuntimeContext): XTermRuntime
|
||||
keywordHighlighter,
|
||||
clearTextureAtlas: clearWebglTextureAtlas,
|
||||
dispose: () => {
|
||||
ctx.container.removeEventListener("wheel", handleFontSizeWheel);
|
||||
cleanupMiddleClick?.();
|
||||
stopDprWatch();
|
||||
keywordHighlighter.dispose();
|
||||
|
||||
27
components/terminal/runtime/terminalFontZoom.test.ts
Normal file
27
components/terminal/runtime/terminalFontZoom.test.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import {
|
||||
nextTerminalFontSizeForAction,
|
||||
nextTerminalFontSizeForWheel,
|
||||
} from './terminalFontZoom.ts';
|
||||
|
||||
test('terminal font size actions step and reset within bounds', () => {
|
||||
assert.equal(nextTerminalFontSizeForAction('increaseTerminalFontSize', 14), 15);
|
||||
assert.equal(nextTerminalFontSizeForAction('decreaseTerminalFontSize', 14), 13);
|
||||
assert.equal(nextTerminalFontSizeForAction('resetTerminalFontSize', 18), 14);
|
||||
assert.equal(nextTerminalFontSizeForAction('increaseTerminalFontSize', 32), 32);
|
||||
assert.equal(nextTerminalFontSizeForAction('decreaseTerminalFontSize', 10), 10);
|
||||
assert.equal(nextTerminalFontSizeForAction('copy', 14), null);
|
||||
});
|
||||
|
||||
test('wheel adjusts terminal font size with the platform modifier only', () => {
|
||||
assert.equal(nextTerminalFontSizeForWheel({ ctrlKey: true, metaKey: false, deltaY: -1 }, 14, false), 15);
|
||||
assert.equal(nextTerminalFontSizeForWheel({ ctrlKey: true, metaKey: false, deltaY: 1 }, 14, false), 13);
|
||||
assert.equal(nextTerminalFontSizeForWheel({ ctrlKey: false, metaKey: true, deltaY: -1 }, 14, true), 15);
|
||||
assert.equal(nextTerminalFontSizeForWheel({ ctrlKey: false, metaKey: true, deltaY: 1 }, 14, true), 13);
|
||||
assert.equal(nextTerminalFontSizeForWheel({ ctrlKey: false, metaKey: true, deltaY: -1 }, 14, false), null);
|
||||
assert.equal(nextTerminalFontSizeForWheel({ ctrlKey: true, metaKey: false, deltaY: -1 }, 14, true), null);
|
||||
assert.equal(nextTerminalFontSizeForWheel({ ctrlKey: false, metaKey: false, deltaY: -1 }, 14, false), null);
|
||||
assert.equal(nextTerminalFontSizeForWheel({ ctrlKey: true, metaKey: false, deltaY: 0 }, 14, false), null);
|
||||
});
|
||||
38
components/terminal/runtime/terminalFontZoom.ts
Normal file
38
components/terminal/runtime/terminalFontZoom.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import {
|
||||
DEFAULT_FONT_SIZE,
|
||||
MAX_FONT_SIZE,
|
||||
MIN_FONT_SIZE,
|
||||
} from "../../../infrastructure/config/fonts";
|
||||
|
||||
type WheelLike = Pick<WheelEvent, "ctrlKey" | "metaKey" | "deltaY">;
|
||||
|
||||
export const clampTerminalFontSize = (fontSize: number): number =>
|
||||
Math.max(MIN_FONT_SIZE, Math.min(MAX_FONT_SIZE, fontSize));
|
||||
|
||||
export const nextTerminalFontSizeForAction = (
|
||||
action: string,
|
||||
currentFontSize: number,
|
||||
): number | null => {
|
||||
switch (action) {
|
||||
case "increaseTerminalFontSize":
|
||||
return clampTerminalFontSize(currentFontSize + 1);
|
||||
case "decreaseTerminalFontSize":
|
||||
return clampTerminalFontSize(currentFontSize - 1);
|
||||
case "resetTerminalFontSize":
|
||||
return DEFAULT_FONT_SIZE;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const nextTerminalFontSizeForWheel = (
|
||||
event: WheelLike,
|
||||
currentFontSize: number,
|
||||
isMac: boolean,
|
||||
): number | null => {
|
||||
const hasZoomModifier = isMac
|
||||
? event.metaKey && !event.ctrlKey
|
||||
: event.ctrlKey && !event.metaKey;
|
||||
if (!hasZoomModifier || event.deltaY === 0) return null;
|
||||
return clampTerminalFontSize(currentFontSize + (event.deltaY < 0 ? 1 : -1));
|
||||
};
|
||||
@@ -89,6 +89,7 @@ export interface TerminalProps {
|
||||
hotkeyScheme?: "disabled" | "mac" | "pc";
|
||||
keyBindings?: KeyBinding[];
|
||||
onHotkeyAction?: (action: string, event: KeyboardEvent) => void;
|
||||
onTerminalFontSizeChange?: (fontSize: number) => void;
|
||||
onStatusChange?: (sessionId: string, status: TerminalSession["status"]) => void;
|
||||
onSessionExit?: (sessionId: string, evt: { exitCode?: number; signal?: number; error?: string; reason?: "exited" | "error" | "timeout" | "closed" }) => void;
|
||||
onTerminalDataCapture?: (sessionId: string, data: string) => void;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
type TerminalEffectsContext = Record<string, any>;
|
||||
|
||||
export function useTerminalEffects(ctx: TerminalEffectsContext) {
|
||||
const { CONNECTION_TIMEOUT, Error, XTERM_PERFORMANCE_CONFIG, applyUserCursorPreference, auth, autocompleteCloseRef, autocompleteInputRef, autocompleteKeyEventRef, captureTerminalLogData, clearTerminalCwd, commandBufferRef, connectionLogBufferRef, containerRef, createPromptLineBreakState, createReplaySafeTerminalLogSanitizer, createXTermRuntime, effectiveFontSize, effectiveFontWeight, effectiveTheme, error, executeSnippetCommand, fitAddonRef, fontFamilyId, fontSize, fontWeightFixupDoneRef, forceSyncRenderAfterResize, handleOsc52ReadRequest, handleTerminalDataCaptureOnce, hasConnectedRef, host, hotkeySchemeRef, identities, inWorkspace, isBroadcastEnabledRef, isFocusMode, isFocused, isLocalConnection, isNetworkDevice, isResizing, isRestoringSelectionRef, isSearchOpen, isSerialConnection, isVisible, isVisibleRef, keyBindingsRef, keys, knownCwdRef, lastFittedSizeRef, lastToastedErrorRef, logger, mouseTrackingRef, onBroadcastInputRef, onCommandExecuted, onHotkeyActionRef, onSnippetExecutorChange, onTerminalCwdChange, pendingAuthRef, pendingOutputScrollRef, prevIsResizingRef, primaryFontFamily, promptLineBreakStateRef, resizeSession, resolveHostAuth, resolvedFontFamily, safeFit, searchAddonRef, serialConfig, serialLineBufferRef, serializeAddonRef, sessionId, sessionRef, sessionStarters, setError, setHasMouseTracking, setHasSelection, setIsCancelling, setIsDisconnectedDialogDismissed, setIsSearchOpen, setNeedsHostKeyVerification, setPendingHostKeyInfo, setPendingHostKeyRequestId, setProgressLogs, setProgressValue, setShowLogs, setStatus, setTimeLeft, shouldEnableNativeUserInputAutoScroll, shouldProbeSessionCwd, onSnippetShortkeyRef, snippetsRef, status, statusRef, t, teardown, termRef, terminalAltKeyOptions, terminalBackend, terminalContextActionsRef, terminalCwdTracker, terminalDataCapturedRef, terminalLogSanitizerRef, terminalSettings, terminalSettingsRef, toHostKeyInfo, toast, updateStatus, useEffect, useLayoutEffect, xtermRuntimeRef, zmodem, zmodemToastedRef } = ctx;
|
||||
const { CONNECTION_TIMEOUT, Error, XTERM_PERFORMANCE_CONFIG, applyUserCursorPreference, auth, autocompleteCloseRef, autocompleteInputRef, autocompleteKeyEventRef, captureTerminalLogData, clearTerminalCwd, commandBufferRef, connectionLogBufferRef, containerRef, createPromptLineBreakState, createReplaySafeTerminalLogSanitizer, createXTermRuntime, effectiveFontSize, effectiveFontWeight, effectiveTheme, error, executeSnippetCommand, fitAddonRef, fontFamilyId, fontSize, fontWeightFixupDoneRef, forceSyncRenderAfterResize, handleOsc52ReadRequest, handleTerminalDataCaptureOnce, hasConnectedRef, host, hotkeySchemeRef, identities, inWorkspace, isBroadcastEnabledRef, isFocusMode, isFocused, isLocalConnection, isNetworkDevice, isResizing, isRestoringSelectionRef, isSearchOpen, isSerialConnection, isVisible, isVisibleRef, keyBindingsRef, keys, knownCwdRef, lastFittedSizeRef, lastToastedErrorRef, logger, mouseTrackingRef, onBroadcastInputRef, onCommandExecuted, onHotkeyActionRef, onSnippetExecutorChange, onTerminalCwdChange, onTerminalFontSizeChange, pendingAuthRef, pendingOutputScrollRef, prevIsResizingRef, primaryFontFamily, promptLineBreakStateRef, resizeSession, resolveHostAuth, resolvedFontFamily, safeFit, searchAddonRef, serialConfig, serialLineBufferRef, serializeAddonRef, sessionId, sessionRef, sessionStarters, setError, setHasMouseTracking, setHasSelection, setIsCancelling, setIsDisconnectedDialogDismissed, setIsSearchOpen, setNeedsHostKeyVerification, setPendingHostKeyInfo, setPendingHostKeyRequestId, setProgressLogs, setProgressValue, setShowLogs, setStatus, setTimeLeft, shouldEnableNativeUserInputAutoScroll, shouldProbeSessionCwd, onSnippetShortkeyRef, snippetsRef, status, statusRef, t, teardown, termRef, terminalAltKeyOptions, terminalBackend, terminalContextActionsRef, terminalCwdTracker, terminalDataCapturedRef, terminalLogSanitizerRef, terminalSettings, terminalSettingsRef, toHostKeyInfo, toast, updateStatus, useEffect, useLayoutEffect, xtermRuntimeRef, zmodem, zmodemToastedRef } = ctx;
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
@@ -186,6 +186,7 @@ export function useTerminalEffects(ctx: TerminalEffectsContext) {
|
||||
hotkeySchemeRef,
|
||||
keyBindingsRef,
|
||||
onHotkeyActionRef,
|
||||
onTerminalFontSizeChange,
|
||||
isBroadcastEnabledRef,
|
||||
onBroadcastInputRef,
|
||||
snippetsRef,
|
||||
|
||||
@@ -450,6 +450,7 @@ interface TerminalPaneProps {
|
||||
isComposeBarOpen: boolean;
|
||||
sessionLog?: { enabled: true; directory: string; format: string };
|
||||
onHotkeyAction?: (action: string, event: KeyboardEvent) => void;
|
||||
onTerminalFontSizeChange?: (sessionId: string, fontSize: number) => void;
|
||||
onOpenSftp: (
|
||||
host: Host,
|
||||
initialPath?: string,
|
||||
@@ -516,6 +517,7 @@ const terminalPanePropsAreEqual = (
|
||||
prev.isComposeBarOpen === next.isComposeBarOpen &&
|
||||
prev.sessionLog === next.sessionLog &&
|
||||
prev.onHotkeyAction === next.onHotkeyAction &&
|
||||
prev.onTerminalFontSizeChange === next.onTerminalFontSizeChange &&
|
||||
prev.onOpenSftp === next.onOpenSftp &&
|
||||
prev.onTerminalCwdChange === next.onTerminalCwdChange &&
|
||||
prev.onOpenScripts === next.onOpenScripts &&
|
||||
@@ -565,6 +567,7 @@ const TerminalPane: React.FC<TerminalPaneProps> = memo(({
|
||||
isComposeBarOpen,
|
||||
sessionLog,
|
||||
onHotkeyAction,
|
||||
onTerminalFontSizeChange,
|
||||
onOpenSftp,
|
||||
onTerminalCwdChange,
|
||||
onOpenScripts,
|
||||
@@ -641,6 +644,9 @@ const TerminalPane: React.FC<TerminalPaneProps> = memo(({
|
||||
onSetWorkspaceFocusedSession?.(activeWorkspaceId, session.id);
|
||||
}
|
||||
}, [activeWorkspaceId, isFocusMode, onSetWorkspaceFocusedSession, session.id]);
|
||||
const handleTerminalFontSizeChange = useCallback((nextFontSize: number) => {
|
||||
onTerminalFontSizeChange?.(session.id, nextFontSize);
|
||||
}, [onTerminalFontSizeChange, session.id]);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -681,6 +687,7 @@ const TerminalPane: React.FC<TerminalPaneProps> = memo(({
|
||||
hotkeyScheme={hotkeyScheme}
|
||||
keyBindings={keyBindings}
|
||||
onHotkeyAction={onHotkeyAction}
|
||||
onTerminalFontSizeChange={handleTerminalFontSizeChange}
|
||||
onOpenSftp={onOpenSftp}
|
||||
onTerminalCwdChange={onTerminalCwdChange}
|
||||
onOpenScripts={onOpenScripts}
|
||||
@@ -738,6 +745,7 @@ interface TerminalPanesHostProps {
|
||||
isComposeBarOpen: boolean;
|
||||
sessionLog?: { enabled: true; directory: string; format: string };
|
||||
onHotkeyAction?: (action: string, event: KeyboardEvent) => void;
|
||||
onTerminalFontSizeChange?: TerminalPaneProps['onTerminalFontSizeChange'];
|
||||
onOpenSftp: TerminalPaneProps['onOpenSftp'];
|
||||
onTerminalCwdChange: TerminalPaneProps['onTerminalCwdChange'];
|
||||
onOpenScripts: () => void;
|
||||
|
||||
@@ -4,7 +4,7 @@ import React from 'react';
|
||||
type TerminalLayerViewContext = Record<string, any>;
|
||||
|
||||
export function TerminalLayerView({ ctx }: { ctx: TerminalLayerViewContext }) {
|
||||
const { accentMode, activeResizers, activeSidePanelTab, activeTabId, activeWorkspace, AIChatPanelsHost, aiContextsByTabId, AIStateMaintenanceHost, AIStateProvider, Array, Button, cn, composeBarThemeColors, computeSplitHint, customAccent, draggingSessionId, dropHint, editorWordWrap, effectiveHosts, findSplitNode, focusedFontFamilyId, focusedFontFamilyOverridden, focusedFontSize, focusedFontSizeOverridden, focusedFontWeight, focusedFontWeightOverridden, focusedSessionId, focusedThemeOverridden, FolderTree, followAppTerminalTheme, fontSize, getTerminalCwd, handleAddKnownHost, handleBroadcastInput, handleCloseSession, handleCloseSidePanel, handleCommandExecuted, handleComposeSend, handleFontFamilyChangeForFocusedSession, handleFontFamilyResetForFocusedSession, handleFontSizeChangeForFocusedSession, handleFontSizeResetForFocusedSession, handleFontWeightChangeForFocusedSession, handleFontWeightResetForFocusedSession, handleOpenAI, handleOpenScripts, handleOpenSftp, handleOpenTheme, handleOsDetected, handlePendingUploadHandled, handleSessionExit, handleSftpInitialLocationApplied, handleSidePanelResizeStart, handleSnippetFromPanel, handleSnippetExecutorChange, handleStatusChange, handleTerminalCwdChange, handleTerminalDataCapture, handleThemeChangeForFocusedSession, handleThemeResetForFocusedSession, handleToggleSftpFromBar, handleToggleWorkspaceComposeBar, handleUpdateHost, handleWorkspaceDrop, hosts, hotkeyScheme, identities, isBroadcastEnabled, isComposeBarOpen, isFocusMode, isSidePanelOpenForCurrentTab, isTerminalLayerVisible, keyBindings, keys, knownHosts, MessageSquare, mountedAiTabIds, mountedSftpTabIds, onHotkeyAction, onSetWorkspaceFocusedSession, onSplitSession, Palette, PanelLeft, PanelRight, previewedOrVisibleThemeId, refocusActiveTerminalSession, refocusTerminalSession, renderFocusModeSidebar, resizing, resolveAIExecutorContext, resolvedPreviewTheme, ScriptsSidePanel, sessionChainHostsMap, sessionHostsMap, sessionLogConfig, sessions, setDropHint, setEditorWordWrap, setIsComposeBarOpen, setResizing, setSidePanelPosition, sftpActiveHost, sftpAutoSync, sftpDefaultViewMode, sftpDoubleClickBehavior, sftpInitialLocationForTab, sftpPendingUploadsForTab, sftpShowHiddenFiles, SftpSidePanel, sftpUseCompressedUpload, sidePanelPosition, sidePanelWidth, snippetPackages, snippets, splitHorizontalHandlersRef, splitVerticalHandlersRef, t, TerminalComposeBar, terminalFontFamilyId, TerminalPanesHost, terminalSettings, terminalTheme, themePreview, ThemeSidePanel, Tooltip, TooltipContent, TooltipTrigger, updateHosts, validAIScopeTargetIds, workspaceBroadcastHandlersRef, workspaceById, workspaceFocusHandlersRef, workspaceInnerRef, workspaceOuterRef, workspaceOverlayRef, workspaceRectsById, X, Zap } = ctx;
|
||||
const { accentMode, activeResizers, activeSidePanelTab, activeTabId, activeWorkspace, AIChatPanelsHost, aiContextsByTabId, AIStateMaintenanceHost, AIStateProvider, Array, Button, cn, composeBarThemeColors, computeSplitHint, customAccent, draggingSessionId, dropHint, editorWordWrap, effectiveHosts, findSplitNode, focusedFontFamilyId, focusedFontFamilyOverridden, focusedFontSize, focusedFontSizeOverridden, focusedFontWeight, focusedFontWeightOverridden, focusedSessionId, focusedThemeOverridden, FolderTree, followAppTerminalTheme, fontSize, getTerminalCwd, handleAddKnownHost, handleBroadcastInput, handleCloseSession, handleCloseSidePanel, handleCommandExecuted, handleComposeSend, handleFontFamilyChangeForFocusedSession, handleFontFamilyResetForFocusedSession, handleFontSizeChangeForFocusedSession, handleFontSizeResetForFocusedSession, handleFontWeightChangeForFocusedSession, handleFontWeightResetForFocusedSession, handleOpenAI, handleOpenScripts, handleOpenSftp, handleOpenTheme, handleOsDetected, handlePendingUploadHandled, handleSessionExit, handleSftpInitialLocationApplied, handleSidePanelResizeStart, handleSnippetFromPanel, handleSnippetExecutorChange, handleStatusChange, handleTerminalCwdChange, handleTerminalDataCapture, handleTerminalFontSizeChange, handleThemeChangeForFocusedSession, handleThemeResetForFocusedSession, handleToggleSftpFromBar, handleToggleWorkspaceComposeBar, handleUpdateHost, handleWorkspaceDrop, hosts, hotkeyScheme, identities, isBroadcastEnabled, isComposeBarOpen, isFocusMode, isSidePanelOpenForCurrentTab, isTerminalLayerVisible, keyBindings, keys, knownHosts, MessageSquare, mountedAiTabIds, mountedSftpTabIds, onHotkeyAction, onSetWorkspaceFocusedSession, onSplitSession, Palette, PanelLeft, PanelRight, previewedOrVisibleThemeId, refocusActiveTerminalSession, refocusTerminalSession, renderFocusModeSidebar, resizing, resolveAIExecutorContext, resolvedPreviewTheme, ScriptsSidePanel, sessionChainHostsMap, sessionHostsMap, sessionLogConfig, sessions, setDropHint, setEditorWordWrap, setIsComposeBarOpen, setResizing, setSidePanelPosition, sftpActiveHost, sftpAutoSync, sftpDefaultViewMode, sftpDoubleClickBehavior, sftpInitialLocationForTab, sftpPendingUploadsForTab, sftpShowHiddenFiles, SftpSidePanel, sftpUseCompressedUpload, sidePanelPosition, sidePanelWidth, snippetPackages, snippets, splitHorizontalHandlersRef, splitVerticalHandlersRef, t, TerminalComposeBar, terminalFontFamilyId, TerminalPanesHost, terminalSettings, terminalTheme, themePreview, ThemeSidePanel, Tooltip, TooltipContent, TooltipTrigger, updateHosts, validAIScopeTargetIds, workspaceBroadcastHandlersRef, workspaceById, workspaceFocusHandlersRef, workspaceInnerRef, workspaceOuterRef, workspaceOverlayRef, workspaceRectsById, X, Zap } = ctx;
|
||||
return (
|
||||
<AIStateProvider>
|
||||
<AIStateMaintenanceHost validAIScopeTargetIds={validAIScopeTargetIds} />
|
||||
@@ -361,6 +361,7 @@ export function TerminalLayerView({ ctx }: { ctx: TerminalLayerViewContext }) {
|
||||
isComposeBarOpen={isComposeBarOpen}
|
||||
sessionLog={sessionLogConfig}
|
||||
onHotkeyAction={onHotkeyAction}
|
||||
onTerminalFontSizeChange={handleTerminalFontSizeChange}
|
||||
onOpenSftp={handleOpenSftp}
|
||||
onTerminalCwdChange={handleTerminalCwdChange}
|
||||
onOpenScripts={handleOpenScripts}
|
||||
|
||||
24
domain/keyBindings.terminalFontSize.test.ts
Normal file
24
domain/keyBindings.terminalFontSize.test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { DEFAULT_KEY_BINDINGS } from './models/keyBindings.ts';
|
||||
import { getTerminalPassthroughActions } from '../application/state/useGlobalHotkeys.ts';
|
||||
|
||||
test('default shortcuts include terminal font size controls', () => {
|
||||
const byAction = new Map(DEFAULT_KEY_BINDINGS.map((binding) => [binding.action, binding]));
|
||||
|
||||
assert.equal(byAction.get('increaseTerminalFontSize')?.pc, 'Ctrl + =');
|
||||
assert.equal(byAction.get('decreaseTerminalFontSize')?.pc, 'Ctrl + -');
|
||||
assert.equal(byAction.get('resetTerminalFontSize')?.pc, 'Ctrl + 0');
|
||||
assert.equal(byAction.get('increaseTerminalFontSize')?.category, 'terminal');
|
||||
assert.equal(byAction.get('decreaseTerminalFontSize')?.category, 'terminal');
|
||||
assert.equal(byAction.get('resetTerminalFontSize')?.category, 'terminal');
|
||||
});
|
||||
|
||||
test('terminal font size shortcuts are handled inside xterm', () => {
|
||||
const actions = getTerminalPassthroughActions();
|
||||
|
||||
assert.equal(actions.has('increaseTerminalFontSize'), true);
|
||||
assert.equal(actions.has('decreaseTerminalFontSize'), true);
|
||||
assert.equal(actions.has('resetTerminalFontSize'), true);
|
||||
});
|
||||
@@ -206,6 +206,9 @@ export const DEFAULT_KEY_BINDINGS: KeyBinding[] = [
|
||||
{ id: 'select-all', action: 'selectAll', label: 'Select All in Terminal', mac: '⌘ + A', pc: 'Ctrl + Shift + A', category: 'terminal' },
|
||||
{ id: 'clear-buffer', action: 'clearBuffer', label: 'Clear Terminal Buffer', mac: '⌘ + ⌃ + K', pc: 'Ctrl + Shift + K', category: 'terminal' },
|
||||
{ id: 'search-terminal', action: 'searchTerminal', label: 'Open Terminal Search', mac: '⌘ + F', pc: 'Ctrl + F', category: 'terminal' },
|
||||
{ id: 'increase-terminal-font-size', action: 'increaseTerminalFontSize', label: 'Increase Terminal Font Size', mac: '⌘ + =', pc: 'Ctrl + =', category: 'terminal' },
|
||||
{ id: 'decrease-terminal-font-size', action: 'decreaseTerminalFontSize', label: 'Decrease Terminal Font Size', mac: '⌘ + -', pc: 'Ctrl + -', category: 'terminal' },
|
||||
{ id: 'reset-terminal-font-size', action: 'resetTerminalFontSize', label: 'Reset Terminal Font Size', mac: '⌘ + 0', pc: 'Ctrl + 0', category: 'terminal' },
|
||||
|
||||
// Navigation / Split View
|
||||
{ id: 'move-focus', action: 'moveFocus', label: 'Move focus between Split View panes', mac: '⌘ + ⌥ + arrows', pc: 'Ctrl + Alt + arrows', category: 'navigation' },
|
||||
|
||||
Reference in New Issue
Block a user