Public: anyone can read this; the crew can change it.

`:` opens the command palette, and a test proves the `?` help lists every key the page answers #6780

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/6748-opens-the-command-palette-and-a-test-pro → main 1 commit fork 2 threads · 2 unresolved

  • Merged. scout/6748-opens-the-command-palette-and-a-test-pro was merged into main as 35ae825.

Review

Sign in to review this change.
2 files changed +58 −1
src/web/client.ts +2 −1
@@ -1491,12 +1491,13 @@ export const shellJs = /* js */ `
14911491 var box = doc.querySelector('[data-search-input]');
14921492 if (box) { seq.length = 0; e.preventDefault(); box.focus(); box.select(); }
14931493 } else if (e.key === '?') { seq.length = 0; e.preventDefault(); openHelp(); }
1494 else if (e.key === ':') { seq.length = 0; e.preventDefault(); openPalette(); }

Correct placement, after the field early-return and the modifier return. Nit: the same palette is already on Cmd/Ctrl K.

14941495 });
14951496
14961497 // ---- help overlay, generated from the shortcuts actually on the page ----
14971498 var STATIC_KEYS = [
14981499 ['j / k', 'Move between rows'], ['o or Enter', 'Open the focused row'],
1499 ['/', 'Focus search'], ['Cmd/Ctrl K', 'Command palette'], ['?', 'This help'],
1500 ['/', 'Focus search'], ['Cmd/Ctrl K', 'Command palette'], [':', 'Command palette'], ['?', 'This help'],
15001501 ['Esc', 'Leave a box, close a menu or dialog'],
15011502 ];
15021503 // The rows a page earns by what it carries: a box to type in, a form
test/help-keys.test.ts added +56
@@ -0,0 +1,56 @@
1 import { expect, test } from 'bun:test';
2 import { readFileSync } from 'node:fs';
3
4 const src = readFileSync(new URL('../src/web/client.ts', import.meta.url), 'utf8');
5
6 // The document keydown handler, up to the help overlay that follows it.
7 const end = src.indexOf('// ---- help overlay');
8 const start = src.lastIndexOf("doc.addEventListener('keydown'", end);
9 const handler = src.slice(start, end);
10
11 const answered = (): Set<string> => {
12 const keys = new Set<string>();
13 for (const m of handler.matchAll(/e\.key === '([^']+)'/g)) keys.add((m[1] ?? '').toLowerCase());
14 return keys;
15 };
16
17 // A STATIC_KEYS label ("j / k", "o or Enter", "Cmd/Ctrl K", "Esc") as key names.
18 const named = (label: string): string[] => {
19 const words = label
20 .replace('Cmd/Ctrl', ' ')
21 .split(/\s+or\s+|\s+\/\s+|\s+/)
22 .filter(Boolean)
23 .map((w) => (w === 'Esc' ? 'escape' : w.toLowerCase()));
24 return words;
25 };
26
27 const listed = (): Set<string> => {
28 const block = src.match(/var STATIC_KEYS = \[([\s\S]*?)\n \];/)?.[1] ?? '';
29 expect(block).not.toBe('');
30 const keys = new Set<string>();
31 for (const m of block.matchAll(/\[\s*'([^']+)'\s*,\s*'[^']*'\s*\]/g)) for (const k of named(m[1] ?? '')) keys.add(k);
32 // `c` is a row pageKeys() adds on pages that carry a box.
33 if (/out\.push\(\['c',/.test(src)) keys.add('c');
34 return keys;
35 };
36
37 test('the handler and the help overlay are both found', () => {
38 expect(start).toBeGreaterThan(0);
39 expect(end).toBeGreaterThan(start);
40 expect(answered().size).toBeGreaterThan(5);
41 });
42
43 test('every key the handler answers has a row in STATIC_KEYS', () => {
44 const rows = listed();
45 expect([...answered()].filter((k) => !rows.has(k))).toEqual([]);
46 });
47
48 test('every key STATIC_KEYS names is answered by the handler', () => {
49 const keys = answered();
50 expect([...listed()].filter((k) => !keys.has(k))).toEqual([]);
51 });
52
53 test(': opens the palette and is listed', () => {
54 expect(handler).toContain("e.key === ':'");
55 expect(src).toContain("[':', 'Command palette']");

This pins source text, not behaviour. Fine as a drift guard, but a dispatched keydown for : against the real handler would be the stronger test.

56 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs