Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/lib/settings.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { persisted } from "svelte-persisted-store";
import themes, { type ThemeName, defaultTheme } from "./ui/themes";
import fonts, { type FontName, defaultFont } from "./ui/fonts";
import { derived, type Readable } from "svelte/store";

export type Settings = {
name: string;
theme: ThemeName;
font: FontName;
scrollback: number;
};

Expand All @@ -22,6 +24,11 @@ export const settings: Readable<Settings> = derived(
theme = defaultTheme;
}

let font = $storedSettings.font;
if (!font || !Object.hasOwn(fonts, font)) {
font = defaultFont;
}

let scrollback = $storedSettings.scrollback;
if (typeof scrollback !== "number" || scrollback < 0) {
scrollback = 5000;
Expand All @@ -30,6 +37,7 @@ export const settings: Readable<Settings> = derived(
return {
name,
theme,
font,
scrollback,
};
},
Expand Down
25 changes: 25 additions & 0 deletions src/lib/ui/Settings.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import { settings, updateSettings } from "$lib/settings";
import OverlayMenu from "./OverlayMenu.svelte";
import themes, { type ThemeName } from "./themes";
import fonts, { type FontName } from "./fonts";

export let open: boolean;

let inputName: string;
let inputTheme: ThemeName;
let inputFont: FontName;
let inputScrollback: number;

let initialized = false;
Expand All @@ -17,6 +19,7 @@
initialized = true;
inputName = $settings.name;
inputTheme = $settings.theme;
inputFont = $settings.font;
inputScrollback = $settings.scrollback;
}
</script>
Expand Down Expand Up @@ -68,6 +71,28 @@
</select>
</div>
</div>
<div class="item">
<div>
<p class="item-title">Font</p>
<p class="item-subtitle">Font family for text in terminals.</p>
</div>
<div class="relative">
<ChevronDownIcon
class="absolute top-[11px] right-2.5 w-4 h-4 text-zinc-400"
/>
<select
class="input-common !pr-5"
bind:value={inputFont}
on:change={() => updateSettings({ font: inputFont })}
>
{#each Object.entries(fonts) as [fontName, fontFamily] (fontName)}
<option value={fontName} style:font-family={fontFamily}
>{fontName}</option
>
{/each}
</select>
</div>
</div>
<div class="item">
<div>
<p class="item-title">Scrollback</p>
Expand Down
7 changes: 4 additions & 3 deletions src/lib/ui/XTerm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import { Buffer } from "buffer";

import themes from "./themes";
import fonts from "./fonts";
import CircleButton from "./CircleButton.svelte";
import CircleButtons from "./CircleButtons.svelte";
import { settings } from "$lib/settings";
Expand Down Expand Up @@ -68,10 +69,12 @@
let term: Terminal | null = null;

$: theme = themes[$settings.theme];
$: fontFamily = fonts[$settings.font];

$: if (term) {
// If the theme changes, update existing terminals' appearance.
term.options.theme = theme;
term.options.fontFamily = fontFamily;
term.options.scrollback = $settings.scrollback;
}

Expand Down Expand Up @@ -132,9 +135,7 @@
allowTransparency: false,
cursorBlink: false,
cursorStyle: "block",
// This is the monospace font family configured in Tailwind.
fontFamily:
'"Fira Code VF", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
fontFamily,
fontSize: 14,
fontWeight: 400,
fontWeightBold: 500,
Expand Down
27 changes: 27 additions & 0 deletions src/lib/ui/fonts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/** Fallback stack appended to every terminal font, matching Tailwind's mono. */
const fallback =
'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace';

/**
* Font families available for terminal text. Only Fira Code is bundled with
* the app; the others are used if installed locally, else the fallback applies.
*/
const fonts = {
"Fira Code": `"Fira Code VF", ${fallback}`,
// Nerd Font variants include icon glyphs used by prompts like Starship.
"FiraCode Nerd Font": `"FiraCode Nerd Font Mono", ${fallback}`,
"D2Coding Nerd Font": `"D2CodingLigature Nerd Font Mono", ${fallback}`,
"JetBrains Mono": `"JetBrains Mono", ${fallback}`,
"Cascadia Code": `"Cascadia Code", ${fallback}`,
"Source Code Pro": `"Source Code Pro", ${fallback}`,
"SF Mono": `"SF Mono", ${fallback}`,
Menlo: `Menlo, ${fallback}`,
Consolas: `Consolas, ${fallback}`,
"System Default": "monospace",
};

export type FontName = keyof typeof fonts;

export const defaultFont: FontName = "Fira Code";

export default fonts;
Loading