Add terminal font size shortcuts (#1047)

This commit is contained in:
ZacharyZcR
2026-07-14 01:14:24 +08:00
committed by GitHub
parent d44695eb79
commit 07d5f5a133
3 changed files with 126 additions and 9 deletions
+15 -9
View File
@@ -57,6 +57,10 @@ import { toast } from "sonner";
import { Button } from "@/components/button";
import { resolveTermixThemeColors } from "./terminal-theme.ts";
import type { TerminalHandle, TerminalHostConfig } from "./terminal-types.ts";
import {
getNextTerminalFontSize,
getTerminalFontZoomDirection,
} from "./terminal-font-zoom.ts";
export type { TerminalHandle, TerminalHostConfig } from "./terminal-types.ts";
type HostKeyVerificationData = Omit<
@@ -83,8 +87,6 @@ interface SSHTerminalProps {
disableAutoFocus?: boolean;
}
const TERMINAL_FONT_ZOOM_MIN = 8;
const TERMINAL_FONT_ZOOM_MAX = 36;
const ALTERNATE_SCREEN_SEQUENCE = /\x1b\[\?(47|1047|1049)([hl])/g;
function updateAlternateScreenMode(output: string, currentMode: boolean) {
@@ -497,16 +499,12 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
}
}
function zoomTerminalFont(deltaY: number) {
const direction = deltaY < 0 ? 1 : -1;
function changeTerminalFontSize(direction: -1 | 1) {
const currentFontSize =
terminal.options.fontSize ??
terminalFontSizeRef.current ??
DEFAULT_TERMINAL_CONFIG.fontSize;
const nextFontSize = Math.min(
TERMINAL_FONT_ZOOM_MAX,
Math.max(TERMINAL_FONT_ZOOM_MIN, currentFontSize + direction),
);
const nextFontSize = getNextTerminalFontSize(currentFontSize, direction);
if (nextFontSize === currentFontSize) {
return;
@@ -2167,7 +2165,7 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
terminal.attachCustomWheelEventHandler((ev) => {
if (ev.ctrlKey || ev.metaKey) {
zoomTerminalFont(ev.deltaY);
changeTerminalFontSize(ev.deltaY < 0 ? 1 : -1);
return false;
}
@@ -2398,6 +2396,14 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
}
}
const fontZoomDirection = getTerminalFontZoomDirection(e);
if (fontZoomDirection !== 0) {
e.preventDefault();
e.stopPropagation();
changeTerminalFontSize(fontZoomDirection);
return false;
}
if (
e.ctrlKey &&
!e.shiftKey &&
@@ -0,0 +1,74 @@
import { describe, expect, it } from "vitest";
import {
getNextTerminalFontSize,
getTerminalFontZoomDirection,
} from "./terminal-font-zoom";
function keyEvent(
overrides: Partial<KeyboardEvent>,
): Pick<KeyboardEvent, "altKey" | "code" | "ctrlKey" | "key" | "metaKey"> {
return {
altKey: false,
code: "",
ctrlKey: false,
key: "",
metaKey: false,
...overrides,
};
}
describe("getTerminalFontZoomDirection", () => {
it("recognizes Ctrl+Plus and Ctrl+Minus", () => {
expect(
getTerminalFontZoomDirection(
keyEvent({ ctrlKey: true, code: "Equal", key: "+" }),
),
).toBe(1);
expect(
getTerminalFontZoomDirection(
keyEvent({ ctrlKey: true, code: "Minus", key: "-" }),
),
).toBe(-1);
});
it("recognizes unshifted equal, numpad, and macOS shortcuts", () => {
expect(
getTerminalFontZoomDirection(
keyEvent({ ctrlKey: true, code: "Equal", key: "=" }),
),
).toBe(1);
expect(
getTerminalFontZoomDirection(
keyEvent({ ctrlKey: true, code: "NumpadAdd", key: "+" }),
),
).toBe(1);
expect(
getTerminalFontZoomDirection(
keyEvent({ metaKey: true, code: "NumpadSubtract", key: "-" }),
),
).toBe(-1);
});
it("ignores unmodified and Alt-modified keys", () => {
expect(
getTerminalFontZoomDirection(keyEvent({ code: "Equal", key: "+" })),
).toBe(0);
expect(
getTerminalFontZoomDirection(
keyEvent({ altKey: true, ctrlKey: true, code: "Minus", key: "-" }),
),
).toBe(0);
});
});
describe("getNextTerminalFontSize", () => {
it("changes the font size one pixel at a time", () => {
expect(getNextTerminalFontSize(14, 1)).toBe(15);
expect(getNextTerminalFontSize(14, -1)).toBe(13);
});
it("keeps the existing zoom limits", () => {
expect(getNextTerminalFontSize(36, 1)).toBe(36);
expect(getNextTerminalFontSize(8, -1)).toBe(8);
});
});
@@ -0,0 +1,37 @@
export const TERMINAL_FONT_ZOOM_MIN = 8;
export const TERMINAL_FONT_ZOOM_MAX = 36;
type ZoomKeyEvent = Pick<
KeyboardEvent,
"altKey" | "code" | "ctrlKey" | "key" | "metaKey"
>;
export function getTerminalFontZoomDirection(event: ZoomKeyEvent): -1 | 0 | 1 {
if ((!event.ctrlKey && !event.metaKey) || event.altKey) return 0;
if (
event.key === "+" ||
event.code === "Equal" ||
event.code === "NumpadAdd"
) {
return 1;
}
if (
event.key === "-" ||
event.code === "Minus" ||
event.code === "NumpadSubtract"
) {
return -1;
}
return 0;
}
export function getNextTerminalFontSize(
currentFontSize: number,
direction: -1 | 1,
): number {
return Math.min(
TERMINAL_FONT_ZOOM_MAX,
Math.max(TERMINAL_FONT_ZOOM_MIN, currentFontSize + direction),
);
}