feat(electrobun): settings overhaul — fonts, shells, providers, retention, chords

- Settings drawer: responsive width clamp(24rem, 45vw, 50rem)
- System font detection: fc-list for UI fonts (preferred sans-serif starred)
  and mono fonts (Nerd Fonts starred), fallback to hardcoded lists
- Scrollback: default 5000, min 1000, step 500
- Shell detection: system.shells RPC, pre-selects $SHELL login shell
- Provider enablement: provider.scan gates toggle, unavailable shown as N/A
- Session retention: count 0-100 (0=Keep all), age 0-365 (0=Forever)
- Chord keybindings: Ctrl+K → Ctrl+S style multi-key sequences,
  1s prefix wait, arrow separator display, 26 tests passing
This commit is contained in:
Hibryda 2026-03-25 01:42:34 +01:00
parent afaa2253de
commit 1de6c93e01
9 changed files with 346 additions and 187 deletions

View file

@ -29,7 +29,57 @@ export function createGitHandlers() {
// not installed
}
}
return { shells };
const loginShell = process.env.SHELL ?? '/bin/bash';
return { shells, loginShell };
},
"system.fonts": async () => {
const PREFERRED_SANS = new Set([
'Inter', 'Roboto', 'Noto Sans', 'Ubuntu', 'Open Sans', 'Lato',
'Source Sans 3', 'IBM Plex Sans', 'Fira Sans', 'PT Sans',
'Cantarell', 'DejaVu Sans', 'Liberation Sans',
]);
try {
const allRaw = execSync(
'fc-list :style=Regular --format="%{family}\\n" | sort -u',
{ encoding: 'utf8', timeout: 5000 },
);
const monoRaw = execSync(
'fc-list :spacing=mono --format="%{family}\\n" | sort -u',
{ encoding: 'utf8', timeout: 5000 },
);
const monoSet = new Set<string>();
const monoFonts: Array<{ family: string; isNerdFont: boolean }> = [];
for (const line of monoRaw.split('\n')) {
const family = line.split(',')[0].trim(); // fc-list returns comma-separated aliases
if (!family || monoSet.has(family)) continue;
monoSet.add(family);
monoFonts.push({ family, isNerdFont: family.includes('Nerd') });
}
monoFonts.sort((a, b) => {
if (a.isNerdFont !== b.isNerdFont) return a.isNerdFont ? -1 : 1;
return a.family.localeCompare(b.family);
});
const uiSet = new Set<string>();
const uiFonts: Array<{ family: string; preferred: boolean }> = [];
for (const line of allRaw.split('\n')) {
const family = line.split(',')[0].trim();
if (!family || uiSet.has(family) || monoSet.has(family)) continue;
uiSet.add(family);
uiFonts.push({ family, preferred: PREFERRED_SANS.has(family) });
}
uiFonts.sort((a, b) => {
if (a.preferred !== b.preferred) return a.preferred ? -1 : 1;
return a.family.localeCompare(b.family);
});
return { uiFonts, monoFonts };
} catch (err) {
console.error('[system.fonts] fc-list failed:', err);
return { uiFonts: [], monoFonts: [] };
}
},
"ssh.checkSshfs": async () => {