mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 14:45:24 +00:00
feat: move terminal settings, look and ssh tools into ssh-terminal plugin
This commit is contained in:
1 parent
ffa872ebd3
commit
d9bba10612
242 files changed
+25071
-7207
No files matched your search
@@ -1,56 +0,0 @@
|
||||
import type { TerminalConfig } from "@/types";
|
||||
|
||||
export type TerminalDefaults = Partial<
|
||||
Pick<
|
||||
TerminalConfig,
|
||||
| "cursorBlink"
|
||||
| "cursorStyle"
|
||||
| "fontSize"
|
||||
| "fontFamily"
|
||||
| "letterSpacing"
|
||||
| "lineHeight"
|
||||
| "theme"
|
||||
| "scrollback"
|
||||
| "bellStyle"
|
||||
| "minimumContrastRatio"
|
||||
| "backgroundImage"
|
||||
| "backgroundImageOpacity"
|
||||
| "customThemeColors"
|
||||
>
|
||||
>;
|
||||
|
||||
function parseObject<T extends object>(value?: string | null): Partial<T> {
|
||||
if (!value) return {};
|
||||
try {
|
||||
const parsed = JSON.parse(value);
|
||||
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
||||
? (parsed as Partial<T>)
|
||||
: {};
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export function parseTerminalDefaults(value?: string | null): TerminalDefaults {
|
||||
return parseObject<TerminalDefaults>(value);
|
||||
}
|
||||
|
||||
// Booleans have three states in the defaults UI: unset means the host decides.
|
||||
export type TriState = "inherit" | "on" | "off";
|
||||
|
||||
export function toTriState(value?: boolean): TriState {
|
||||
if (value === undefined) return "inherit";
|
||||
return value ? "on" : "off";
|
||||
}
|
||||
|
||||
export function fromTriState(value: TriState): boolean | undefined {
|
||||
if (value === "inherit") return undefined;
|
||||
return value === "on";
|
||||
}
|
||||
|
||||
export function resolveConnectionDefaults<T extends object>(
|
||||
defaults: Partial<T>,
|
||||
overrides?: Partial<T> | null,
|
||||
): Partial<T> {
|
||||
return { ...defaults, ...overrides };
|
||||
}
|
||||
@@ -22,6 +22,7 @@ export function hostToSSHHost(h: Host): SSHHost {
|
||||
keyType: h.keyType,
|
||||
credentialId: h.credentialId ? parseInt(h.credentialId, 10) : undefined,
|
||||
terminalConfig: h.terminalConfig,
|
||||
sshOptions: h.sshOptions,
|
||||
hasSudoPassword: h.hasSudoPassword,
|
||||
pluginSettings: h.pluginSettings ?? {},
|
||||
connectionType: "ssh",
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
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),
|
||||
);
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
const style = document.createElement("style");
|
||||
style.innerHTML = `
|
||||
@font-face {
|
||||
font-family: 'Caskaydia Cove Nerd Font Mono';
|
||||
src: url('./fonts/CaskaydiaCoveNerdFontMono-Regular.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Caskaydia Cove Nerd Font Mono';
|
||||
src: url('./fonts/CaskaydiaCoveNerdFontMono-Bold.ttf') format('truetype');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Caskaydia Cove Nerd Font Mono';
|
||||
src: url('./fonts/CaskaydiaCoveNerdFontMono-Italic.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Caskaydia Cove Nerd Font Mono';
|
||||
src: url('./fonts/CaskaydiaCoveNerdFontMono-BoldItalic.ttf') format('truetype');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
.xterm .xterm-viewport::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
background: transparent;
|
||||
}
|
||||
.xterm .xterm-viewport::-webkit-scrollbar-thumb {
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.xterm .xterm-viewport::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(0,0,0,0.5);
|
||||
}
|
||||
.xterm .xterm-viewport {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(0,0,0,0.3) transparent;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.dark .xterm .xterm-viewport::-webkit-scrollbar-thumb {
|
||||
background: rgba(255,255,255,0.3);
|
||||
}
|
||||
.dark .xterm .xterm-viewport::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
.dark .xterm .xterm-viewport {
|
||||
scrollbar-color: rgba(255,255,255,0.3) transparent;
|
||||
}
|
||||
|
||||
.xterm {
|
||||
font-feature-settings: "liga" 0, "calt" 0;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen {
|
||||
font-variant-ligatures: none;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen .xterm-char {
|
||||
font-feature-settings: "liga" 0, "calt" 0;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
// Canvas fillText() does not reliably trigger @font-face fetches on every
|
||||
// browser engine (notably Android WebView) the way rendering real DOM text
|
||||
// does. xterm.js draws glyphs to a <canvas>, so without an explicit load the
|
||||
// terminal can keep painting the fallback font's tofu boxes even after
|
||||
// document.fonts.ready resolves. Forcing the load here ensures the glyph
|
||||
// data is actually fetched before the terminal renders with it.
|
||||
export function ensureTerminalFontsLoaded(fontFamily: string): void {
|
||||
if (typeof document === "undefined" || !document.fonts) return;
|
||||
const specs = [
|
||||
`400 16px "${fontFamily}"`,
|
||||
`700 16px "${fontFamily}"`,
|
||||
`italic 400 16px "${fontFamily}"`,
|
||||
`italic 700 16px "${fontFamily}"`,
|
||||
];
|
||||
for (const spec of specs) {
|
||||
document.fonts.load(spec).catch(() => {});
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
import { TERMINAL_THEMES, type TerminalTheme } from "@/lib/terminal-themes.ts";
|
||||
import type { TerminalConfig } from "@/types/index.ts";
|
||||
|
||||
// Background/foreground per UI theme for "Termix Default" - must match index.css
|
||||
const TERMIX_DEFAULT_COLORS: Record<
|
||||
string,
|
||||
{ background: string; foreground: string }
|
||||
> = {
|
||||
dark: { background: "#0c0d0b", foreground: "#fafafa" },
|
||||
light: { background: "#ffffff", foreground: "#111210" },
|
||||
dracula: { background: "#282a36", foreground: "#f8f8f2" },
|
||||
catppuccin: { background: "#1e1e2e", foreground: "#cdd6f4" },
|
||||
nord: { background: "#2e3440", foreground: "#eceff4" },
|
||||
solarized: { background: "#002b36", foreground: "#839496" },
|
||||
"tokyo-night": { background: "#1a1b26", foreground: "#a9b1d6" },
|
||||
"one-dark": { background: "#282c34", foreground: "#abb2bf" },
|
||||
gruvbox: { background: "#282828", foreground: "#ebdbb2" },
|
||||
};
|
||||
|
||||
export function resolveTermixThemeColors(
|
||||
activeTheme: string,
|
||||
appTheme: string,
|
||||
customThemeColors?: TerminalConfig["customThemeColors"],
|
||||
): TerminalTheme["colors"] {
|
||||
if (activeTheme === "custom") {
|
||||
if (customThemeColors) {
|
||||
return customThemeColors;
|
||||
}
|
||||
return TERMINAL_THEMES.termixDark.colors;
|
||||
}
|
||||
if (activeTheme !== "termix") {
|
||||
return (
|
||||
TERMINAL_THEMES[activeTheme]?.colors || TERMINAL_THEMES.termixDark.colors
|
||||
);
|
||||
}
|
||||
let resolvedUiTheme = appTheme;
|
||||
if (appTheme === "system") {
|
||||
resolvedUiTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light";
|
||||
}
|
||||
const uiColors =
|
||||
TERMIX_DEFAULT_COLORS[resolvedUiTheme] ?? TERMIX_DEFAULT_COLORS.dark;
|
||||
const base = TERMINAL_THEMES.termixDark.colors;
|
||||
return {
|
||||
...base,
|
||||
background: uiColors.background,
|
||||
foreground: uiColors.foreground,
|
||||
cursor: uiColors.foreground,
|
||||
cursorAccent: uiColors.background,
|
||||
};
|
||||
}
|
||||
@@ -1,872 +0,0 @@
|
||||
export interface TerminalTheme {
|
||||
name: string;
|
||||
category: "dark" | "light" | "colorful";
|
||||
colors: {
|
||||
background: string;
|
||||
foreground: string;
|
||||
cursor?: string;
|
||||
cursorAccent?: string;
|
||||
selectionBackground?: string;
|
||||
selectionForeground?: string;
|
||||
black: string;
|
||||
red: string;
|
||||
green: string;
|
||||
yellow: string;
|
||||
blue: string;
|
||||
magenta: string;
|
||||
cyan: string;
|
||||
white: string;
|
||||
brightBlack: string;
|
||||
brightRed: string;
|
||||
brightGreen: string;
|
||||
brightYellow: string;
|
||||
brightBlue: string;
|
||||
brightMagenta: string;
|
||||
brightCyan: string;
|
||||
brightWhite: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const TERMINAL_THEMES: Record<string, TerminalTheme> = {
|
||||
termix: {
|
||||
name: "Termix Default",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#0c0d0b",
|
||||
foreground: "#f7f7f7",
|
||||
cursor: "#f7f7f7",
|
||||
cursorAccent: "#0c0d0b",
|
||||
selectionBackground: "#3a3a3d",
|
||||
black: "#2e3436",
|
||||
red: "#cc0000",
|
||||
green: "#4e9a06",
|
||||
yellow: "#c4a000",
|
||||
blue: "#3465a4",
|
||||
magenta: "#75507b",
|
||||
cyan: "#06989a",
|
||||
white: "#d3d7cf",
|
||||
brightBlack: "#555753",
|
||||
brightRed: "#ef2929",
|
||||
brightGreen: "#8ae234",
|
||||
brightYellow: "#fce94f",
|
||||
brightBlue: "#729fcf",
|
||||
brightMagenta: "#ad7fa8",
|
||||
brightCyan: "#34e2e2",
|
||||
brightWhite: "#eeeeec",
|
||||
},
|
||||
},
|
||||
|
||||
termixDark: {
|
||||
name: "Termix Dark",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#0c0d0b",
|
||||
foreground: "#f7f7f7",
|
||||
cursor: "#f7f7f7",
|
||||
cursorAccent: "#0c0d0b",
|
||||
selectionBackground: "#3a3a3d",
|
||||
black: "#2e3436",
|
||||
red: "#cc0000",
|
||||
green: "#4e9a06",
|
||||
yellow: "#c4a000",
|
||||
blue: "#3465a4",
|
||||
magenta: "#75507b",
|
||||
cyan: "#06989a",
|
||||
white: "#d3d7cf",
|
||||
brightBlack: "#555753",
|
||||
brightRed: "#ef2929",
|
||||
brightGreen: "#8ae234",
|
||||
brightYellow: "#fce94f",
|
||||
brightBlue: "#729fcf",
|
||||
brightMagenta: "#ad7fa8",
|
||||
brightCyan: "#34e2e2",
|
||||
brightWhite: "#eeeeec",
|
||||
},
|
||||
},
|
||||
|
||||
termixLight: {
|
||||
name: "Termix Light",
|
||||
category: "light",
|
||||
colors: {
|
||||
background: "#ffffff",
|
||||
foreground: "#18181b",
|
||||
cursor: "#18181b",
|
||||
cursorAccent: "#ffffff",
|
||||
selectionBackground: "#d1d5db",
|
||||
black: "#18181b",
|
||||
red: "#dc2626",
|
||||
green: "#16a34a",
|
||||
yellow: "#ca8a04",
|
||||
blue: "#2563eb",
|
||||
magenta: "#9333ea",
|
||||
cyan: "#0891b2",
|
||||
white: "#f4f4f5",
|
||||
brightBlack: "#71717a",
|
||||
brightRed: "#ef4444",
|
||||
brightGreen: "#22c55e",
|
||||
brightYellow: "#eab308",
|
||||
brightBlue: "#3b82f6",
|
||||
brightMagenta: "#a855f7",
|
||||
brightCyan: "#06b6d4",
|
||||
brightWhite: "#ffffff",
|
||||
},
|
||||
},
|
||||
|
||||
dracula: {
|
||||
name: "Dracula",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#282a36",
|
||||
foreground: "#f8f8f2",
|
||||
cursor: "#f8f8f2",
|
||||
cursorAccent: "#282a36",
|
||||
selectionBackground: "#44475a",
|
||||
black: "#21222c",
|
||||
red: "#ff5555",
|
||||
green: "#50fa7b",
|
||||
yellow: "#f1fa8c",
|
||||
blue: "#bd93f9",
|
||||
magenta: "#ff79c6",
|
||||
cyan: "#8be9fd",
|
||||
white: "#f8f8f2",
|
||||
brightBlack: "#6272a4",
|
||||
brightRed: "#ff6e6e",
|
||||
brightGreen: "#69ff94",
|
||||
brightYellow: "#ffffa5",
|
||||
brightBlue: "#d6acff",
|
||||
brightMagenta: "#ff92df",
|
||||
brightCyan: "#a4ffff",
|
||||
brightWhite: "#ffffff",
|
||||
},
|
||||
},
|
||||
|
||||
monokai: {
|
||||
name: "Monokai",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#272822",
|
||||
foreground: "#f8f8f2",
|
||||
cursor: "#f8f8f0",
|
||||
cursorAccent: "#272822",
|
||||
selectionBackground: "#49483e",
|
||||
black: "#272822",
|
||||
red: "#f92672",
|
||||
green: "#a6e22e",
|
||||
yellow: "#f4bf75",
|
||||
blue: "#66d9ef",
|
||||
magenta: "#ae81ff",
|
||||
cyan: "#a1efe4",
|
||||
white: "#f8f8f2",
|
||||
brightBlack: "#75715e",
|
||||
brightRed: "#f92672",
|
||||
brightGreen: "#a6e22e",
|
||||
brightYellow: "#f4bf75",
|
||||
brightBlue: "#66d9ef",
|
||||
brightMagenta: "#ae81ff",
|
||||
brightCyan: "#a1efe4",
|
||||
brightWhite: "#f9f8f5",
|
||||
},
|
||||
},
|
||||
|
||||
nord: {
|
||||
name: "Nord",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#2e3440",
|
||||
foreground: "#d8dee9",
|
||||
cursor: "#d8dee9",
|
||||
cursorAccent: "#2e3440",
|
||||
selectionBackground: "#434c5e",
|
||||
black: "#3b4252",
|
||||
red: "#bf616a",
|
||||
green: "#a3be8c",
|
||||
yellow: "#ebcb8b",
|
||||
blue: "#81a1c1",
|
||||
magenta: "#b48ead",
|
||||
cyan: "#88c0d0",
|
||||
white: "#e5e9f0",
|
||||
brightBlack: "#4c566a",
|
||||
brightRed: "#bf616a",
|
||||
brightGreen: "#a3be8c",
|
||||
brightYellow: "#ebcb8b",
|
||||
brightBlue: "#81a1c1",
|
||||
brightMagenta: "#b48ead",
|
||||
brightCyan: "#8fbcbb",
|
||||
brightWhite: "#eceff4",
|
||||
},
|
||||
},
|
||||
|
||||
gruvboxDark: {
|
||||
name: "Gruvbox Dark",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#282828",
|
||||
foreground: "#ebdbb2",
|
||||
cursor: "#ebdbb2",
|
||||
cursorAccent: "#282828",
|
||||
selectionBackground: "#504945",
|
||||
black: "#282828",
|
||||
red: "#cc241d",
|
||||
green: "#98971a",
|
||||
yellow: "#d79921",
|
||||
blue: "#458588",
|
||||
magenta: "#b16286",
|
||||
cyan: "#689d6a",
|
||||
white: "#a89984",
|
||||
brightBlack: "#928374",
|
||||
brightRed: "#fb4934",
|
||||
brightGreen: "#b8bb26",
|
||||
brightYellow: "#fabd2f",
|
||||
brightBlue: "#83a598",
|
||||
brightMagenta: "#d3869b",
|
||||
brightCyan: "#8ec07c",
|
||||
brightWhite: "#ebdbb2",
|
||||
},
|
||||
},
|
||||
|
||||
gruvboxLight: {
|
||||
name: "Gruvbox Light",
|
||||
category: "light",
|
||||
colors: {
|
||||
background: "#fbf1c7",
|
||||
foreground: "#3c3836",
|
||||
cursor: "#3c3836",
|
||||
cursorAccent: "#fbf1c7",
|
||||
selectionBackground: "#d5c4a1",
|
||||
black: "#fbf1c7",
|
||||
red: "#cc241d",
|
||||
green: "#98971a",
|
||||
yellow: "#d79921",
|
||||
blue: "#458588",
|
||||
magenta: "#b16286",
|
||||
cyan: "#689d6a",
|
||||
white: "#7c6f64",
|
||||
brightBlack: "#928374",
|
||||
brightRed: "#9d0006",
|
||||
brightGreen: "#79740e",
|
||||
brightYellow: "#b57614",
|
||||
brightBlue: "#076678",
|
||||
brightMagenta: "#8f3f71",
|
||||
brightCyan: "#427b58",
|
||||
brightWhite: "#3c3836",
|
||||
},
|
||||
},
|
||||
|
||||
solarizedDark: {
|
||||
name: "Solarized Dark",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#002b36",
|
||||
foreground: "#839496",
|
||||
cursor: "#839496",
|
||||
cursorAccent: "#002b36",
|
||||
selectionBackground: "#073642",
|
||||
black: "#073642",
|
||||
red: "#dc322f",
|
||||
green: "#859900",
|
||||
yellow: "#b58900",
|
||||
blue: "#268bd2",
|
||||
magenta: "#d33682",
|
||||
cyan: "#2aa198",
|
||||
white: "#eee8d5",
|
||||
brightBlack: "#002b36",
|
||||
brightRed: "#cb4b16",
|
||||
brightGreen: "#586e75",
|
||||
brightYellow: "#657b83",
|
||||
brightBlue: "#839496",
|
||||
brightMagenta: "#6c71c4",
|
||||
brightCyan: "#93a1a1",
|
||||
brightWhite: "#fdf6e3",
|
||||
},
|
||||
},
|
||||
|
||||
solarizedLight: {
|
||||
name: "Solarized Light",
|
||||
category: "light",
|
||||
colors: {
|
||||
background: "#fdf6e3",
|
||||
foreground: "#657b83",
|
||||
cursor: "#657b83",
|
||||
cursorAccent: "#fdf6e3",
|
||||
selectionBackground: "#eee8d5",
|
||||
black: "#073642",
|
||||
red: "#dc322f",
|
||||
green: "#859900",
|
||||
yellow: "#b58900",
|
||||
blue: "#268bd2",
|
||||
magenta: "#d33682",
|
||||
cyan: "#2aa198",
|
||||
white: "#eee8d5",
|
||||
brightBlack: "#002b36",
|
||||
brightRed: "#cb4b16",
|
||||
brightGreen: "#586e75",
|
||||
brightYellow: "#657b83",
|
||||
brightBlue: "#839496",
|
||||
brightMagenta: "#6c71c4",
|
||||
brightCyan: "#93a1a1",
|
||||
brightWhite: "#fdf6e3",
|
||||
},
|
||||
},
|
||||
|
||||
oneDark: {
|
||||
name: "One Dark",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#282c34",
|
||||
foreground: "#abb2bf",
|
||||
cursor: "#528bff",
|
||||
cursorAccent: "#282c34",
|
||||
selectionBackground: "#3e4451",
|
||||
black: "#282c34",
|
||||
red: "#e06c75",
|
||||
green: "#98c379",
|
||||
yellow: "#e5c07b",
|
||||
blue: "#61afef",
|
||||
magenta: "#c678dd",
|
||||
cyan: "#56b6c2",
|
||||
white: "#abb2bf",
|
||||
brightBlack: "#5c6370",
|
||||
brightRed: "#e06c75",
|
||||
brightGreen: "#98c379",
|
||||
brightYellow: "#e5c07b",
|
||||
brightBlue: "#61afef",
|
||||
brightMagenta: "#c678dd",
|
||||
brightCyan: "#56b6c2",
|
||||
brightWhite: "#ffffff",
|
||||
},
|
||||
},
|
||||
|
||||
tokyoNight: {
|
||||
name: "Tokyo Night",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#1a1b26",
|
||||
foreground: "#a9b1d6",
|
||||
cursor: "#a9b1d6",
|
||||
cursorAccent: "#1a1b26",
|
||||
selectionBackground: "#283457",
|
||||
black: "#15161e",
|
||||
red: "#f7768e",
|
||||
green: "#9ece6a",
|
||||
yellow: "#e0af68",
|
||||
blue: "#7aa2f7",
|
||||
magenta: "#bb9af7",
|
||||
cyan: "#7dcfff",
|
||||
white: "#a9b1d6",
|
||||
brightBlack: "#414868",
|
||||
brightRed: "#f7768e",
|
||||
brightGreen: "#9ece6a",
|
||||
brightYellow: "#e0af68",
|
||||
brightBlue: "#7aa2f7",
|
||||
brightMagenta: "#bb9af7",
|
||||
brightCyan: "#7dcfff",
|
||||
brightWhite: "#c0caf5",
|
||||
},
|
||||
},
|
||||
|
||||
ayuDark: {
|
||||
name: "Ayu Dark",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#0a0e14",
|
||||
foreground: "#b3b1ad",
|
||||
cursor: "#e6b450",
|
||||
cursorAccent: "#0a0e14",
|
||||
selectionBackground: "#253340",
|
||||
black: "#01060e",
|
||||
red: "#ea6c73",
|
||||
green: "#91b362",
|
||||
yellow: "#f9af4f",
|
||||
blue: "#53bdfa",
|
||||
magenta: "#fae994",
|
||||
cyan: "#90e1c6",
|
||||
white: "#c7c7c7",
|
||||
brightBlack: "#686868",
|
||||
brightRed: "#f07178",
|
||||
brightGreen: "#c2d94c",
|
||||
brightYellow: "#ffb454",
|
||||
brightBlue: "#59c2ff",
|
||||
brightMagenta: "#ffee99",
|
||||
brightCyan: "#95e6cb",
|
||||
brightWhite: "#ffffff",
|
||||
},
|
||||
},
|
||||
|
||||
ayuLight: {
|
||||
name: "Ayu Light",
|
||||
category: "light",
|
||||
colors: {
|
||||
background: "#fafafa",
|
||||
foreground: "#5c6166",
|
||||
cursor: "#ff9940",
|
||||
cursorAccent: "#fafafa",
|
||||
selectionBackground: "#d1e4f4",
|
||||
black: "#000000",
|
||||
red: "#f51818",
|
||||
green: "#86b300",
|
||||
yellow: "#f2ae49",
|
||||
blue: "#399ee6",
|
||||
magenta: "#a37acc",
|
||||
cyan: "#4cbf99",
|
||||
white: "#c7c7c7",
|
||||
brightBlack: "#686868",
|
||||
brightRed: "#ff3333",
|
||||
brightGreen: "#b8e532",
|
||||
brightYellow: "#ffc849",
|
||||
brightBlue: "#59c2ff",
|
||||
brightMagenta: "#bf7ce0",
|
||||
brightCyan: "#5cf7a0",
|
||||
brightWhite: "#ffffff",
|
||||
},
|
||||
},
|
||||
|
||||
materialTheme: {
|
||||
name: "Material Theme",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#263238",
|
||||
foreground: "#eeffff",
|
||||
cursor: "#ffcc00",
|
||||
cursorAccent: "#263238",
|
||||
selectionBackground: "#546e7a",
|
||||
black: "#000000",
|
||||
red: "#e53935",
|
||||
green: "#91b859",
|
||||
yellow: "#ffb62c",
|
||||
blue: "#6182b8",
|
||||
magenta: "#7c4dff",
|
||||
cyan: "#39adb5",
|
||||
white: "#ffffff",
|
||||
brightBlack: "#546e7a",
|
||||
brightRed: "#ff5370",
|
||||
brightGreen: "#c3e88d",
|
||||
brightYellow: "#ffcb6b",
|
||||
brightBlue: "#82aaff",
|
||||
brightMagenta: "#c792ea",
|
||||
brightCyan: "#89ddff",
|
||||
brightWhite: "#ffffff",
|
||||
},
|
||||
},
|
||||
|
||||
palenight: {
|
||||
name: "Palenight",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#292d3e",
|
||||
foreground: "#a6accd",
|
||||
cursor: "#ffcc00",
|
||||
cursorAccent: "#292d3e",
|
||||
selectionBackground: "#676e95",
|
||||
black: "#292d3e",
|
||||
red: "#f07178",
|
||||
green: "#c3e88d",
|
||||
yellow: "#ffcb6b",
|
||||
blue: "#82aaff",
|
||||
magenta: "#c792ea",
|
||||
cyan: "#89ddff",
|
||||
white: "#d0d0d0",
|
||||
brightBlack: "#434758",
|
||||
brightRed: "#ff8b92",
|
||||
brightGreen: "#ddffa7",
|
||||
brightYellow: "#ffe585",
|
||||
brightBlue: "#9cc4ff",
|
||||
brightMagenta: "#e1acff",
|
||||
brightCyan: "#a3f7ff",
|
||||
brightWhite: "#ffffff",
|
||||
},
|
||||
},
|
||||
|
||||
oceanicNext: {
|
||||
name: "Oceanic Next",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#1b2b34",
|
||||
foreground: "#cdd3de",
|
||||
cursor: "#c0c5ce",
|
||||
cursorAccent: "#1b2b34",
|
||||
selectionBackground: "#343d46",
|
||||
black: "#343d46",
|
||||
red: "#ec5f67",
|
||||
green: "#99c794",
|
||||
yellow: "#fac863",
|
||||
blue: "#6699cc",
|
||||
magenta: "#c594c5",
|
||||
cyan: "#5fb3b3",
|
||||
white: "#cdd3de",
|
||||
brightBlack: "#65737e",
|
||||
brightRed: "#ec5f67",
|
||||
brightGreen: "#99c794",
|
||||
brightYellow: "#fac863",
|
||||
brightBlue: "#6699cc",
|
||||
brightMagenta: "#c594c5",
|
||||
brightCyan: "#5fb3b3",
|
||||
brightWhite: "#d8dee9",
|
||||
},
|
||||
},
|
||||
|
||||
nightOwl: {
|
||||
name: "Night Owl",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#011627",
|
||||
foreground: "#d6deeb",
|
||||
cursor: "#80a4c2",
|
||||
cursorAccent: "#011627",
|
||||
selectionBackground: "#1d3b53",
|
||||
black: "#011627",
|
||||
red: "#ef5350",
|
||||
green: "#22da6e",
|
||||
yellow: "#c5e478",
|
||||
blue: "#82aaff",
|
||||
magenta: "#c792ea",
|
||||
cyan: "#21c7a8",
|
||||
white: "#ffffff",
|
||||
brightBlack: "#575656",
|
||||
brightRed: "#ef5350",
|
||||
brightGreen: "#22da6e",
|
||||
brightYellow: "#ffeb95",
|
||||
brightBlue: "#82aaff",
|
||||
brightMagenta: "#c792ea",
|
||||
brightCyan: "#7fdbca",
|
||||
brightWhite: "#ffffff",
|
||||
},
|
||||
},
|
||||
|
||||
synthwave84: {
|
||||
name: "Synthwave '84",
|
||||
category: "colorful",
|
||||
colors: {
|
||||
background: "#241b2f",
|
||||
foreground: "#f92aad",
|
||||
cursor: "#f92aad",
|
||||
cursorAccent: "#241b2f",
|
||||
selectionBackground: "#495495",
|
||||
black: "#000000",
|
||||
red: "#f6188f",
|
||||
green: "#1eff8e",
|
||||
yellow: "#ffe261",
|
||||
blue: "#03edf9",
|
||||
magenta: "#f10596",
|
||||
cyan: "#03edf9",
|
||||
white: "#ffffff",
|
||||
brightBlack: "#5a5a5a",
|
||||
brightRed: "#ff1a8e",
|
||||
brightGreen: "#1eff8e",
|
||||
brightYellow: "#ffff00",
|
||||
brightBlue: "#00d8ff",
|
||||
brightMagenta: "#ff00d4",
|
||||
brightCyan: "#00ffff",
|
||||
brightWhite: "#ffffff",
|
||||
},
|
||||
},
|
||||
|
||||
cobalt2: {
|
||||
name: "Cobalt2",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#193549",
|
||||
foreground: "#ffffff",
|
||||
cursor: "#f0cc09",
|
||||
cursorAccent: "#193549",
|
||||
selectionBackground: "#0050a4",
|
||||
black: "#000000",
|
||||
red: "#ff0000",
|
||||
green: "#38de21",
|
||||
yellow: "#ffe50a",
|
||||
blue: "#1460d2",
|
||||
magenta: "#ff005d",
|
||||
cyan: "#00bbbb",
|
||||
white: "#bbbbbb",
|
||||
brightBlack: "#555555",
|
||||
brightRed: "#f40e17",
|
||||
brightGreen: "#3bd01d",
|
||||
brightYellow: "#edc809",
|
||||
brightBlue: "#5555ff",
|
||||
brightMagenta: "#ff55ff",
|
||||
brightCyan: "#6ae3fa",
|
||||
brightWhite: "#ffffff",
|
||||
},
|
||||
},
|
||||
|
||||
snazzy: {
|
||||
name: "Snazzy",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#282a36",
|
||||
foreground: "#eff0eb",
|
||||
cursor: "#97979b",
|
||||
cursorAccent: "#282a36",
|
||||
selectionBackground: "#97979b",
|
||||
black: "#282a36",
|
||||
red: "#ff5c57",
|
||||
green: "#5af78e",
|
||||
yellow: "#f3f99d",
|
||||
blue: "#57c7ff",
|
||||
magenta: "#ff6ac1",
|
||||
cyan: "#9aedfe",
|
||||
white: "#f1f1f0",
|
||||
brightBlack: "#686868",
|
||||
brightRed: "#ff5c57",
|
||||
brightGreen: "#5af78e",
|
||||
brightYellow: "#f3f99d",
|
||||
brightBlue: "#57c7ff",
|
||||
brightMagenta: "#ff6ac1",
|
||||
brightCyan: "#9aedfe",
|
||||
brightWhite: "#eff0eb",
|
||||
},
|
||||
},
|
||||
|
||||
atomOneDark: {
|
||||
name: "Atom One Dark",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#1e2127",
|
||||
foreground: "#abb2bf",
|
||||
cursor: "#528bff",
|
||||
cursorAccent: "#1e2127",
|
||||
selectionBackground: "#3e4451",
|
||||
black: "#000000",
|
||||
red: "#e06c75",
|
||||
green: "#98c379",
|
||||
yellow: "#d19a66",
|
||||
blue: "#61afef",
|
||||
magenta: "#c678dd",
|
||||
cyan: "#56b6c2",
|
||||
white: "#abb2bf",
|
||||
brightBlack: "#5c6370",
|
||||
brightRed: "#e06c75",
|
||||
brightGreen: "#98c379",
|
||||
brightYellow: "#d19a66",
|
||||
brightBlue: "#61afef",
|
||||
brightMagenta: "#c678dd",
|
||||
brightCyan: "#56b6c2",
|
||||
brightWhite: "#ffffff",
|
||||
},
|
||||
},
|
||||
|
||||
catppuccinMocha: {
|
||||
name: "Catppuccin Mocha",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#1e1e2e",
|
||||
foreground: "#cdd6f4",
|
||||
cursor: "#f5e0dc",
|
||||
cursorAccent: "#1e1e2e",
|
||||
selectionBackground: "#585b70",
|
||||
black: "#45475a",
|
||||
red: "#f38ba8",
|
||||
green: "#a6e3a1",
|
||||
yellow: "#f9e2af",
|
||||
blue: "#89b4fa",
|
||||
magenta: "#f5c2e7",
|
||||
cyan: "#94e2d5",
|
||||
white: "#bac2de",
|
||||
brightBlack: "#585b70",
|
||||
brightRed: "#f38ba8",
|
||||
brightGreen: "#a6e3a1",
|
||||
brightYellow: "#f9e2af",
|
||||
brightBlue: "#89b4fa",
|
||||
brightMagenta: "#f5c2e7",
|
||||
brightCyan: "#94e2d5",
|
||||
brightWhite: "#a6adc8",
|
||||
},
|
||||
},
|
||||
|
||||
gentlemansChoice: {
|
||||
name: "Gentleman's Choice",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#1a1c1a",
|
||||
foreground: "#d1c7a3",
|
||||
cursor: "#d1c7a3",
|
||||
cursorAccent: "#1a1c1a",
|
||||
selectionBackground: "#3e4437",
|
||||
black: "#1a1c1a",
|
||||
red: "#9d3a3a",
|
||||
green: "#5a7a3a",
|
||||
yellow: "#b39a3a",
|
||||
blue: "#3a5a7a",
|
||||
magenta: "#7a3a5a",
|
||||
cyan: "#3a7a7a",
|
||||
white: "#d1c7a3",
|
||||
brightBlack: "#3e4437",
|
||||
brightRed: "#bf4a4a",
|
||||
brightGreen: "#7a9a4a",
|
||||
brightYellow: "#d1b34a",
|
||||
brightBlue: "#4a7abf",
|
||||
brightMagenta: "#9a4abf",
|
||||
brightCyan: "#4abfbf",
|
||||
brightWhite: "#e3dbc3",
|
||||
},
|
||||
},
|
||||
|
||||
midnightEspresso: {
|
||||
name: "Midnight Espresso",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#120f0d",
|
||||
foreground: "#ceb195",
|
||||
cursor: "#ceb195",
|
||||
cursorAccent: "#120f0d",
|
||||
selectionBackground: "#3d2b1f",
|
||||
black: "#120f0d",
|
||||
red: "#a05a4a",
|
||||
green: "#7a8a5a",
|
||||
yellow: "#b08a4a",
|
||||
blue: "#5a7a9a",
|
||||
magenta: "#8a5a7a",
|
||||
cyan: "#5a8a8a",
|
||||
white: "#ceb195",
|
||||
brightBlack: "#3d2b1f",
|
||||
brightRed: "#c07a6a",
|
||||
brightGreen: "#9aaa7a",
|
||||
brightYellow: "#d0aa6a",
|
||||
brightBlue: "#7a9aba",
|
||||
brightMagenta: "#aa7aba",
|
||||
brightCyan: "#7ababa",
|
||||
brightWhite: "#e0cbb5",
|
||||
},
|
||||
},
|
||||
|
||||
custom: {
|
||||
name: "Custom",
|
||||
category: "dark",
|
||||
colors: {
|
||||
background: "#0c0d0b",
|
||||
foreground: "#f7f7f7",
|
||||
cursor: "#f7f7f7",
|
||||
cursorAccent: "#0c0d0b",
|
||||
selectionBackground: "#3a3a3d",
|
||||
black: "#2e3436",
|
||||
red: "#cc0000",
|
||||
green: "#4e9a06",
|
||||
yellow: "#c4a000",
|
||||
blue: "#3465a4",
|
||||
magenta: "#75507b",
|
||||
cyan: "#06989a",
|
||||
white: "#d3d7cf",
|
||||
brightBlack: "#555753",
|
||||
brightRed: "#ef2929",
|
||||
brightGreen: "#8ae234",
|
||||
brightYellow: "#fce94f",
|
||||
brightBlue: "#729fcf",
|
||||
brightMagenta: "#ad7fa8",
|
||||
brightCyan: "#34e2e2",
|
||||
brightWhite: "#eeeeec",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const TERMINAL_FONTS = [
|
||||
{
|
||||
value: "Caskaydia Cove Nerd Font Mono",
|
||||
label: "Caskaydia Cove Nerd Font Mono",
|
||||
fallback:
|
||||
'"Caskaydia Cove Nerd Font Mono", "SF Mono", Consolas, "Liberation Mono", monospace',
|
||||
},
|
||||
{
|
||||
value: "JetBrains Mono",
|
||||
label: "JetBrains Mono",
|
||||
fallback:
|
||||
'"JetBrains Mono", "SF Mono", Consolas, "Liberation Mono", monospace',
|
||||
},
|
||||
{
|
||||
value: "Fira Code",
|
||||
label: "Fira Code",
|
||||
fallback: '"Fira Code", "SF Mono", Consolas, "Liberation Mono", monospace',
|
||||
},
|
||||
{
|
||||
value: "Cascadia Code",
|
||||
label: "Cascadia Code",
|
||||
fallback:
|
||||
'"Cascadia Code", "SF Mono", Consolas, "Liberation Mono", monospace',
|
||||
},
|
||||
{
|
||||
value: "Source Code Pro",
|
||||
label: "Source Code Pro",
|
||||
fallback:
|
||||
'"Source Code Pro", "SF Mono", Consolas, "Liberation Mono", monospace',
|
||||
},
|
||||
{
|
||||
value: "SF Mono",
|
||||
label: "SF Mono",
|
||||
fallback: '"SF Mono", Consolas, "Liberation Mono", monospace',
|
||||
},
|
||||
{
|
||||
value: "Consolas",
|
||||
label: "Consolas",
|
||||
fallback: 'Consolas, "Liberation Mono", monospace',
|
||||
},
|
||||
{
|
||||
value: "Monaco",
|
||||
label: "Monaco",
|
||||
fallback: 'Monaco, "Liberation Mono", monospace',
|
||||
},
|
||||
];
|
||||
|
||||
// Unknown values are treated as a custom font installed on the user's system.
|
||||
export function resolveTerminalFontFamily(fontFamily?: string): string {
|
||||
const known = TERMINAL_FONTS.find((f) => f.value === fontFamily);
|
||||
if (known) return known.fallback;
|
||||
if (fontFamily && fontFamily.trim()) {
|
||||
return `"${fontFamily.trim()}", "SF Mono", Consolas, "Liberation Mono", monospace`;
|
||||
}
|
||||
return TERMINAL_FONTS[0].fallback;
|
||||
}
|
||||
|
||||
export const CURSOR_STYLES = [
|
||||
{ value: "block", label: "Block", labelKey: "hosts.cursorStyleBlock" },
|
||||
{
|
||||
value: "underline",
|
||||
label: "Underline",
|
||||
labelKey: "hosts.cursorStyleUnderline",
|
||||
},
|
||||
{ value: "bar", label: "Bar", labelKey: "hosts.cursorStyleBar" },
|
||||
] as const;
|
||||
|
||||
export const BELL_STYLES = [
|
||||
{ value: "none", label: "None", labelKey: "hosts.bellStyleNone" },
|
||||
{ value: "sound", label: "Sound", labelKey: "hosts.bellStyleSound" },
|
||||
{ value: "visual", label: "Visual", labelKey: "hosts.bellStyleVisual" },
|
||||
{ value: "both", label: "Both", labelKey: "hosts.bellStyleBoth" },
|
||||
] as const;
|
||||
|
||||
export const FAST_SCROLL_MODIFIERS = [
|
||||
{ value: "alt", label: "Alt", labelKey: "hosts.fastScrollModifierAlt" },
|
||||
{ value: "ctrl", label: "Ctrl", labelKey: "hosts.fastScrollModifierCtrl" },
|
||||
{ value: "shift", label: "Shift", labelKey: "hosts.fastScrollModifierShift" },
|
||||
] as const;
|
||||
|
||||
export const DEFAULT_TERMINAL_CONFIG = {
|
||||
cursorBlink: true,
|
||||
cursorStyle: "bar" as const,
|
||||
fontSize: 14,
|
||||
fontFamily: "Caskaydia Cove Nerd Font Mono",
|
||||
letterSpacing: 0,
|
||||
lineHeight: 1.0,
|
||||
theme: "termix",
|
||||
|
||||
scrollback: 10000,
|
||||
bellStyle: "none" as const,
|
||||
rightClickSelectsWord: false,
|
||||
macOptionIsMeta: false,
|
||||
fastScrollModifier: "alt" as const,
|
||||
fastScrollSensitivity: 5,
|
||||
minimumContrastRatio: 1,
|
||||
|
||||
backspaceMode: "normal" as const,
|
||||
agentForwarding: false,
|
||||
environmentVariables: [] as Array<{ key: string; value: string }>,
|
||||
startupSnippetId: null as number | null,
|
||||
autoMosh: false,
|
||||
moshCommand: "mosh-server new -s -l LANG=en_US.UTF-8",
|
||||
passwordPromptAutoFill: true,
|
||||
sudoPasswordAutoFill: false,
|
||||
keepaliveInterval: undefined as number | undefined,
|
||||
keepaliveCountMax: undefined as number | undefined,
|
||||
autoTmux: false,
|
||||
backgroundImage: "" as string,
|
||||
backgroundImageOpacity: 0.15,
|
||||
};
|
||||
|
||||
export type TerminalConfigType = typeof DEFAULT_TERMINAL_CONFIG;
|
||||
Reference in new issue
Block a user