diff options
Diffstat (limited to '.claude')
| -rwxr-xr-x | .claude/hooks/validate-el.sh | 2 | ||||
| -rw-r--r-- | .claude/rules/interaction.md | 16 | ||||
| -rw-r--r-- | .claude/rules/keybinding-display.md | 42 |
3 files changed, 60 insertions, 0 deletions
diff --git a/.claude/hooks/validate-el.sh b/.claude/hooks/validate-el.sh index 803badf8..782f04ca 100755 --- a/.claude/hooks/validate-el.sh +++ b/.claude/hooks/validate-el.sh @@ -51,6 +51,7 @@ case "$f" in -L "$PROJECT_ROOT" \ -L "$PROJECT_ROOT/modules" \ -L "$PROJECT_ROOT/tests" \ + -L "$PROJECT_ROOT/themes" \ --eval '(package-initialize)' \ "$f" \ --eval '(check-parens)' \ @@ -92,6 +93,7 @@ if [ "$count" -ge 1 ] && [ "$count" -le "$MAX_AUTO_TEST_FILES" ]; then -L "$PROJECT_ROOT" \ -L "$PROJECT_ROOT/modules" \ -L "$PROJECT_ROOT/tests" \ + -L "$PROJECT_ROOT/themes" \ --eval '(package-initialize)' \ -l ert "${load_args[@]}" \ --eval "(ert-run-tests-batch-and-exit '(not (tag :slow)))" 2>&1)"; then diff --git a/.claude/rules/interaction.md b/.claude/rules/interaction.md index 4d9279ba..83afc45a 100644 --- a/.claude/rules/interaction.md +++ b/.claude/rules/interaction.md @@ -29,3 +29,19 @@ For multi-select decisions, say so explicitly: "Pick any combination — reply w Reserve `AskUserQuestion` only when the user explicitly asks for the popup form ("use the popup for this one") or for genuinely free-form input where numbered options don't fit. This rule applies to all three approval gates in the `commits.md` publish flow (commit message, PR description, PR review reply): print the draft inline, then offer numbered approve / changes / edit options inline. Do not switch to the popup form for the gate even though the prior protocol referenced it. + +**Enforcement:** a global `PreToolUse` hook (matcher `AskUserQuestion`) in `~/.claude/settings.json` hard-denies the popup and returns this rule as the reason — the prose alone proved too easy to forget. Because the deny is unconditional, the "use the popup for this one" exception above can't be honored in-turn; to get the popup, disable the hook via `/hooks` (or edit settings) first. + +## No Reverse-Video Highlighting in Chat Output + +In conversational output to the user, do not use Markdown bold (`**...**`) or inline-code spans (backtick `` `...` ``). The user's terminal renders both as reverse video, which is hard to read on the display. + +**Why:** The styling that looks like emphasis in most renderers comes through as inverted foreground/background here. Plain prose, plain identifiers, and plain key chords read cleanly; the "highlight" actively hurts legibility. + +**How to apply:** + +- Write command names, file paths, key chords, and code identifiers as plain text — `pearl-save-issue` becomes pearl-save-issue, `C-; L s s` becomes C-; L s s. +- Use structure that doesn't invert colors: headers, numbered lists, dashes, parentheses, and double quotes for labels are all fine. +- Fenced code blocks (triple backtick) are acceptable when the user explicitly wants a block to copy — they don't invert the way inline spans do. Default to plain text otherwise. + +This governs **chat output**, not the Markdown source of rule files, specs, or docs the user reads in an editor — those keep normal Markdown formatting. The constraint is the terminal rendering of the live conversation. diff --git a/.claude/rules/keybinding-display.md b/.claude/rules/keybinding-display.md new file mode 100644 index 00000000..ad45720f --- /dev/null +++ b/.claude/rules/keybinding-display.md @@ -0,0 +1,42 @@ +# Keybinding Display Format + +Applies to: `**/*` + +How to present a keymap's bindings when the user asks to see them — "show the keybindings", "list the bindings", "what's bound under X", or any request to display a prefix keymap and its structure. + +## The Format + +A bulleted list grouped by **category**, where each category is one level of the keymap's prefix tree. + +- **One header per category.** Format: `<Package> <Category> — <full prefix>:`. The package name is the keymap's owner (e.g. `Pearl`); the category is the human name for that sub-map (`Save`, `Edit`, `Add`, `Delete`); the full prefix is the complete chord that lands on that sub-map. +- **The top level is always the `General` category.** Its prefix is the base prefix itself. General lists the terminal commands bound directly off the base prefix **and** the sub-prefix keys that lead into the other categories — so the reader sees every door off the top level in one place. +- **Each bullet is three fields:** `<full keybinding> — <command> — "<which-key label>"`. + - *Full keybinding* — the complete chord, base prefix included (`C-; L s s`), not just the leaf key. The reader should be able to type it verbatim. + - *Command* — the bound command symbol. For a sub-prefix entry in the General category, mark it as a prefix rather than a command (e.g. *(Save prefix)*). + - *Which-key label* — the short string that shows in the which-key popup, in quotes (`"save ticket"`). For a sub-prefix, use the which-key prefix label (`"+save"`). +- **General comes first**, then one section per sub-category in a sensible order. + +## Plain text in chat + +Render this in chat as plain text — no Markdown bold and no inline-code spans. Headers, dashes, parentheses, and double-quoted labels carry the structure without them. See the "No Reverse-Video Highlighting in Chat Output" rule in [`interaction.md`](interaction.md): bold and backtick spans invert to reverse video on the user's terminal. The example below is shown the way it should appear in chat. + +## Example + +For an imaginary command set Pearl on base prefix C-; L: + +Pearl General — C-; L: +- C-; L s — (save prefix) — "+save" +- C-; L e — (edit prefix) — "+edit" +- C-; L m — pearl-menu — "menu" + +Pearl Save — C-; L s: +- C-; L s s — pearl-save-issue — "save ticket" +- C-; L s a — pearl-save-all — "save all" + +Pearl Edit — C-; L e: +- C-; L e p — pearl-set-priority — "priority" +- C-; L e s — pearl-set-state — "state" + +## Why + +The header carries the full prefix so the category's depth is unambiguous — the reader knows exactly how many keys deep each section sits. Listing the sub-prefixes inside General makes the top level a complete map of where every door leads, rather than scattering that across the sections. The three-field bullet ties the chord a user types to the command it runs and the label they'll actually see in which-key, so the written view matches the on-screen view. |
