fix: legible caret and working :q!

CodeMirror injects its own `.cm-cursor` rule after our stylesheet, so the
equally specific override lost and the caret painted black on a dark
background. Qualify the selector, same as `.cm-activeLine`.

`:q!` reached the command table as the literal name `quit!`, which nothing
matched. Commands now carry an optional `bang` variant, and `runCommand`
splits a trailing `!` off any head before looking it up.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01476ZKdB4k3rPDwvVhXcnDg
This commit is contained in:
nvrlandClaude Opus 5 committed 2026-09-05 06:48:22 +02:00
1 parent e0565ea1b4
commit bf3c1f547a
4 files changed
+38 -16

No files matched your search

+19 -11
View File
@@ -16,6 +16,8 @@ export interface CommandSpec {
args?: string
help: string
run: (arg: string) => void | Promise<void>
/** The forcing variant, `:name!` — vim hands the bang over as an argument. */
bang?: { help: string; run: (arg: string) => void | Promise<void> }
}
const requireOpen = () => {
@@ -59,16 +61,15 @@ export const commands: CommandSpec[] = [
}
hooks.focusList()
},
},
{
name: 'q!',
help: 'discard changes and close the editor',
run: async () => {
const open = diary.open
diary.editing = false
diary.dirty = false
if (open) await diary.guard(() => diary.openEntry(open.id))
hooks.focusList()
bang: {
help: 'discard changes and close the editor',
run: async () => {
const open = diary.open
diary.editing = false
diary.dirty = false
if (open) await diary.guard(() => diary.openEntry(open.id))
hooks.focusList()
},
},
},
{
@@ -244,11 +245,18 @@ export async function runCommand(line: string): Promise<void> {
return
}
const spec = lookup.get(head)
// `:q!`, `:quit!` — the bang is part of the command name, not an argument.
const forced = head.endsWith('!')
const spec = lookup.get(forced ? head.slice(0, -1) : head)
if (!spec) {
diary.say(`E492: not an editor command: ${head}`, 'error')
return
}
if (forced) {
if (!spec.bang) return diary.say(`E477: no ! allowed: ${head}`, 'error')
await spec.bang.run(arg)
return
}
await spec.run(arg)
}