Skip to content

Make open-editor binding configurable via keymap#192

Merged
umputun merged 1 commit into
masterfrom
feat/open-editor-keymap
May 13, 2026
Merged

Make open-editor binding configurable via keymap#192
umputun merged 1 commit into
masterfrom
feat/open-editor-keymap

Conversation

@umputun
Copy link
Copy Markdown
Owner

@umputun umputun commented May 13, 2026

the Ctrl+E key that opens $EDITOR during annotation input was hardcoded, conflicting with the standard readline/emacs end-of-line binding. This routes it through the keymap system as the open_editor action so users can remap it via ~/.config/revdiff/keybindings.

what changed:

  • ActionOpenEditor added to keymap with ctrl+e default binding
  • handleAnnotateKey resolves through keymap instead of hardcoded tea.KeyCtrlE
  • placeholder text dynamically reflects the bound key, omits hint when unbound
  • chord bindings filtered from placeholder (chords do not fire during text input)
  • displayKeyName uppercases only first char after ctrl+ to preserve chord case
  • open_editor added to available-actions lists across all doc surfaces
  • chord limitation during modal text input documented in README, docs.html, and plugin configs

to remap:

unmap ctrl+e
map ctrl+g open_editor

Addresses #190

Copilot AI review requested due to automatic review settings May 13, 2026 09:03
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes the “open external editor while entering an annotation” keybinding configurable through the existing keymap system (new open_editor action), removing the hardcoded Ctrl+E behavior that conflicts with common readline/emacs bindings.

Changes:

  • Add ActionOpenEditor / open_editor to the keymap with a default ctrl+e binding and help metadata.
  • Route annotation-input handling through keymap resolution (instead of hardcoded tea.KeyCtrlE) and update placeholder text to reflect the currently bound key (or omit the hint when unbound).
  • Update documentation surfaces (README, HTML docs, plugin reference docs) to list open_editor and clarify chord limitations during text input.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
site/docs.html Documents open_editor, adds chord-in-text-input limitation note, updates available actions list.
README.md Documents open_editor, chord limitation note, updates available actions list.
plugins/codex/skills/revdiff/references/usage.md Mirrors README/docs updates for Codex plugin reference usage.
plugins/codex/skills/revdiff/references/config.md Adds open_editor to action list and documents chord limitation in text input.
app/ui/handlers.go Adjusts display formatting for ctrl+ key names (for help/placeholder display).
app/ui/handlers_test.go Adds coverage for displayKeyName formatting behavior (including chords).
app/ui/annotate.go Uses keymap-driven open_editor dispatch during annotation input and dynamic placeholders.
app/ui/annotate_test.go Adds tests for remapped/unbound editor binding behavior and placeholder rendering.
app/keymap/keymap.go Adds ActionOpenEditor, default binding, and help entry.
app/keymap/keymap_test.go Adds tests validating open_editor action validity, default binding, and help entry.
.claude-plugin/skills/revdiff/references/usage.md Mirrors README/docs updates for Claude plugin reference usage.
.claude-plugin/skills/revdiff/references/config.md Adds open_editor to action list and documents chord limitation in text input.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/ui/annotate.go Outdated
keys := m.keymap.KeysFor(keymap.ActionOpenEditor)
var single []string
for _, k := range keys {
if !strings.Contains(k, ">") {
Available actions: `down`, `up`, `page_down`, `page_up`, `half_page_down`, `half_page_up`, `home`, `end`, `scroll_left`, `scroll_right`, `scroll_center`, `scroll_top`, `scroll_bottom`, `next_item`, `prev_item`, `next_hunk`, `prev_hunk`, `toggle_pane`, `focus_tree`, `focus_diff`, `search`, `confirm`, `annotate_file`, `delete_annotation`, `annot_list`, `open_editor`, `toggle_collapsed`, `toggle_compact`, `toggle_wrap`, `toggle_tree`, `toggle_line_numbers`, `toggle_blame`, `toggle_hunk`, `toggle_untracked`, `mark_reviewed`, `theme_select`, `filter`, `info`, `quit`, `discard_quit`, `help`, `dismiss`

Modal keys (annotation input, search input, confirm discard) are not remappable.
Modal keys (annotation input, search input, confirm discard) are not remappable. Chord bindings do not fire during text input — use single-key `ctrl+*` bindings for actions like `open_editor` that need to work during annotation input.
Available actions: `down`, `up`, `page_down`, `page_up`, `half_page_down`, `half_page_up`, `home`, `end`, `scroll_left`, `scroll_right`, `scroll_center`, `scroll_top`, `scroll_bottom`, `next_item`, `prev_item`, `next_hunk`, `prev_hunk`, `toggle_pane`, `focus_tree`, `focus_diff`, `search`, `confirm`, `annotate_file`, `delete_annotation`, `annot_list`, `open_editor`, `toggle_collapsed`, `toggle_compact`, `toggle_wrap`, `toggle_tree`, `toggle_line_numbers`, `toggle_blame`, `toggle_hunk`, `toggle_untracked`, `mark_reviewed`, `theme_select`, `filter`, `info`, `quit`, `discard_quit`, `help`, `dismiss`

Modal keys (annotation input, search input, confirm discard) are not remappable.
Modal keys (annotation input, search input, confirm discard) are not remappable. Chord bindings do not fire during text input — use single-key `ctrl+*` bindings for actions like `open_editor` that need to work during annotation input.
Comment thread site/docs.html
<div class="code-block"><code>map ctrl+w&gt;x mark_reviewed
map alt+t&gt;n theme_select</code></div>
<p>When the leader is pressed, the status bar shows <code>Pending: ctrl+w, esc to cancel</code>; press the second key to dispatch, or <code>esc</code> to cancel silently. Binding a key as both a standalone action and a chord prefix drops the standalone binding (the chord wins, with a warning). Chord bindings work under non-Latin keyboard layouts &mdash; the second-stage key is translated via the same layout-resolve fallback as single-key bindings.</p>
<p>When the leader is pressed, the status bar shows <code>Pending: ctrl+w, esc to cancel</code>; press the second key to dispatch, or <code>esc</code> to cancel silently. Binding a key as both a standalone action and a chord prefix drops the standalone binding (the chord wins, with a warning). Chord bindings work under non-Latin keyboard layouts &mdash; the second-stage key is translated via the same layout-resolve fallback as single-key bindings. Note: chord bindings do not fire during text input (annotation and search prompts) &mdash; use single-key <code>ctrl+*</code> bindings for actions like <code>open_editor</code> that need to work during annotation input.</p>
Comment thread README.md
```

When the leader is pressed, the status bar shows `Pending: ctrl+w, esc to cancel`; press the second key to dispatch, or `esc` to cancel silently. Binding a key as both a standalone action and a chord prefix drops the standalone binding (the chord wins, with a warning). Chord bindings work under non-Latin keyboard layouts — the second-stage key is translated via the same layout-resolve fallback as single-key bindings.
When the leader is pressed, the status bar shows `Pending: ctrl+w, esc to cancel`; press the second key to dispatch, or `esc` to cancel silently. Binding a key as both a standalone action and a chord prefix drops the standalone binding (the chord wins, with a warning). Chord bindings work under non-Latin keyboard layouts — the second-stage key is translated via the same layout-resolve fallback as single-key bindings. Note: chord bindings do not fire during text input (annotation and search prompts) — the leader key is consumed by the text input widget. Use single-key `ctrl+*` bindings for actions like `open_editor` that need to work during annotation input.
route the Ctrl+E editor key in annotation mode through the keymap system
as the open_editor action so users can remap it via keybindings file.

- add ActionOpenEditor to keymap with ctrl+e default binding
- handleAnnotateKey resolves through keymap instead of hardcoded tea.KeyCtrlE
- placeholder text dynamically reflects the bound key, omits hint when unbound
- filter chord bindings from placeholder (chords do not fire during text input)
- displayKeyName uppercases only first char after ctrl+ to preserve chord case
- add open_editor to available-actions lists across all doc surfaces
- document chord limitation during modal text input
- add tests for remapped/unbound editor key, displayKeyName, action validity
@umputun umputun force-pushed the feat/open-editor-keymap branch from 0630be4 to 5c3a18c Compare May 13, 2026 09:14
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 13, 2026

Deploying revdiff with  Cloudflare Pages  Cloudflare Pages

Latest commit: 5c3a18c
Status: ✅  Deploy successful!
Preview URL: https://2680c110.revdiff.pages.dev
Branch Preview URL: https://feat-open-editor-keymap.revdiff.pages.dev

View logs

@umputun umputun merged commit 9ef7580 into master May 13, 2026
5 checks passed
@umputun umputun deleted the feat/open-editor-keymap branch May 13, 2026 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants