ADR 0026: Keybinding scheme fix, Help/About panels, find bar repositioned¶
Status¶
Accepted
Context¶
Direct user feedback right after Phase 15 landed, several threads at once:
- A real bug: the bare
:keypress opened the command line unconditionally — meaning:could never be typed as a literal character into the buffer.:as the command-line trigger is a Vim convention (the ex-command line); this editor isn't in Vim mode yet, so a bare:has to stay a normal, typeable character. - Wants a non-conflicting modifier scheme for the command line,
compile, and output toggle, since bare
:was wrong anyway. - Wants to discuss the keybinding scheme as its own topic, and wants a Help panel (all keybindings) and an About panel (app info, author, links) — both centered like the rest.
- Find/replace specifically feels wrong centered — wants it moved to the top-right instead, leaving every other panel centered.
- Raised a question about closing panels / quitting — resolved by explicitly choosing to change nothing there (see Decision).
Decision¶
The : bug and the new modifier scheme¶
Removed the bare-: interception entirely (event->text() == ":") —
: now always inserts a literal colon, like any other character.
Replaced with Ctrl+; for the command line (matches the visual
association: ; sits right next to where : would be, Shift'd). Two
new direct shortcuts, bypassing the command line for the two :
sub-commands used often enough to deserve one: Ctrl+B compiles
directly (build_command, ADR 0025) — not Ctrl+C, which is already
Copy; Ctrl+Shift+O toggles the output panel directly, alongside
the existing (unshifted) Ctrl+O for Open — same shifted-variant-for-
secondary-action pattern Ctrl+S/Ctrl+Shift+S already established.
Both also share their implementation with the :compile/:output
command-line paths (EditorViewport::compile(), new
toggleOutputPanel()) rather than duplicating logic.
Close/quit: deliberately unchanged¶
Put directly to the user: keep Escape closing whichever panel is
open (already true, per-panel, since Phase 13) and Ctrl+Q/:q
always quitting the app outright, with no new dual-purpose binding.
Chosen specifically to keep "quit" a single, deliberate, unambiguous
action — never a side effect of a "close panel" gesture that could
misfire from muscle memory. No code changed here; recorded because the
alternative (a Vim-:q-style "close panel, or quit if nothing's open"
cascade) was seriously considered and explicitly declined.
HelpPanel (gui/src/help_panel.{h,cpp}) — Ctrl+/, "?" badge¶
Same FloatingPanel family as everything else, but the first one with
no input field: a QScrollArea wrapping a rich-text QLabel, built
from a hand-maintained two-column HTML table grouped by category
(Navigation, Editing, Find & replace, Files, Build, Command line,
Other). Hand-maintained rather than generated from the keybinding
dispatch code — a generated single source of truth is real, unscoped
work, and the two can drift; accepted as a v1 tradeoff. No color in
the markup itself (only structure) so it inherits the QLabel's own
palette — same "one font color" pillar every other panel already
follows. Escape closes it (the QScrollArea is given focus and
installed as its own event filter target, the same pattern every other
panel's input widget already uses, just with a scroll area standing in
for a QLineEdit).
AboutPanel (gui/src/about_panel.{h,cpp}) — Ctrl+I, "i" badge¶
Same shape as HelpPanel minus the scroll area (content is short): a
QLabel with setOpenExternalLinks(true) so the GitHub/website links
are real clickable links, opened via the system browser. Content: app
name, version (0.0.0 — pulled from CMakeLists.txt's project()
call, not invented), one line on what the editor is, "Developed by
Saeed" with the two links the user gave directly
(https://github.com/saeeedhany, https://saeedz.vercel.app — not
guessed), and a short current-state note (all "complete normal editor"
phases done, Vim mode next, not yet published while the license
decision stays open — pulled from README.md's own wording, not
newly invented).
One real bug caught and fixed during verification: the notes
paragraph used a literal UTF-8 em dash character in the C string
literal, but the code loaded it via QString::fromLatin1, which
doesn't understand UTF-8 — corrupted into visible mojibake on screen.
Switched both HelpPanel and AboutPanel to QString::fromUtf8 (the
correct match for this file's actual encoding, and the codebase's
convention everywhere else — e.g. the em dashes already throughout
gui/src/*.cpp comments).
Find bar repositioned — the one panel that isn't centered¶
New FloatingPanel::Anchor (Center / TopRight), set once per
panel (not re-checked per open — a panel's screen position isn't
config-driven the way its colors/animation are).
targetGeometry() branches on it. FindBar is the only panel that
calls setAnchor(Anchor::TopRight); every other panel keeps the
default. Reasoning, from the user directly: find/replace is a panel
you keep open while actively scanning matches in the text below it —
centered, it sits on top of the very thing you're looking at, in a way
a glance-act-dismiss panel like Open/Save-As doesn't suffer from.
Consequences¶
Verified live via xdotool: a literal : types correctly into the
buffer (confirmed the bug, then the fix); Ctrl+; opens the command
line; the find bar renders top-right, clear of the text; Ctrl+/ and
Ctrl+I open Help/About respectively, both correctly themed and
scrollable/link-clickable; the em-dash mojibake was caught by actually
looking at the rendered screenshot, not just confirming the panel
opened; Escape closes both new panels and returns focus to the editor,
confirmed by typing immediately afterward. Full test suite unaffected
(GUI-only change) — 9/9 still passing.
Not built: a generated (rather than hand-maintained) keybinding reference; any settings/rebinding UI (this app's keybindings are still compile-time constants, same as every phase before this one). Vim mode remains the next planned phase, unscoped until its own dedicated design pass.