Skip to content

Add CSI u - #18

Merged
Pajn merged 5 commits into
mainfrom
csi-u
Jul 19, 2026
Merged

Add CSI u#18
Pajn merged 5 commits into
mainfrom
csi-u

Conversation

@Pajn

@Pajn Pajn commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Stack

Summary by CodeRabbit

  • New Features
    • Added mode-aware kitty keyboard protocol support for encoding/decoding, including correct modifier handling.
    • Added “next-tab” and “prev-tab” actions bound to Ctrl+Tab and Ctrl+Shift+Tab.
  • Bug Fixes
    • Improved parsing robustness for CSI-u/kitty key reports, including proper key-release consumption and safer fallbacks.
    • Normalized text/space key behavior across encodings; improved Ctrl+Q quit detection for both encodings; corrected SS3 unmodified F1–F4 mapping.
    • Ensured CSI-u non-text keys don’t affect search input.
  • Tests
    • Expanded keyboard protocol decoding/encoding, modifier parsing, snapshot/round-trip coverage, and updated/removals of outdated controller tests.

This was referenced Jul 10, 2026
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ff86f404-935d-4d47-8641-efc747def535

📥 Commits

Reviewing files that changed from the base of the PR and between 2a9c6c7 and 3e70533.

📒 Files selected for processing (20)
  • crates/embers-cli/src/interactive.rs
  • crates/embers-client/src/configured_client.rs
  • crates/embers-client/src/controller.rs
  • crates/embers-client/src/input/encoding.rs
  • crates/embers-client/src/input/keyparse.rs
  • crates/embers-client/src/input/mod.rs
  • crates/embers-client/src/lib.rs
  • crates/embers-client/tests/configured_client.rs
  • crates/embers-client/tests/controller.rs
  • crates/embers-client/tests/fixtures/repository_config.rhai
  • crates/embers-client/tests/integration.rs
  • crates/embers-client/tests/reducer.rs
  • crates/embers-client/tests/support/mod.rs
  • crates/embers-core/src/snapshot.rs
  • crates/embers-protocol/schema/embers.fbs
  • crates/embers-protocol/src/codec.rs
  • crates/embers-protocol/src/types.rs
  • crates/embers-protocol/tests/family_round_trip.rs
  • crates/embers-server/src/server.rs
  • crates/embers-server/src/terminal_backend.rs
💤 Files with no reviewable changes (2)
  • crates/embers-client/tests/controller.rs
  • crates/embers-client/tests/integration.rs

📝 Walkthrough

Walkthrough

Kitty keyboard protocol flags now propagate through terminal snapshots and protocol messages. Clients encode keys according to negotiated modes, while interactive parsing decodes CSI-u and modified legacy reports with safe fallbacks. Typed key bindings, passthrough actions, and tab-navigation fixtures were updated.

Changes

Kitty keyboard protocol

Layer / File(s) Summary
Keyboard mode propagation
crates/embers-core/..., crates/embers-protocol/..., crates/embers-server/..., crates/embers-client/tests/...
Terminal backends derive kitty keyboard flags and include them in visible snapshots, FlatBuffers, server responses, and fixtures.
Typed key parsing and encoding
crates/embers-client/src/input/..., crates/embers-client/src/controller.rs, crates/embers-client/src/lib.rs
Key codes and modifiers are represented explicitly, parsed from bindings, encoded through legacy or kitty formats, and routed by controllers.
Mode-aware client routing
crates/embers-client/src/configured_client.rs, crates/embers-client/tests/fixtures/repository_config.rhai
Passthrough paths and SendKeys use buffer keyboard modes; key normalization, search handling, and Ctrl/Shift-Tab bindings are updated.
Interactive terminal decoding
crates/embers-cli/src/interactive.rs
CSI-u and modified legacy reports are decoded, key-release reports are ignored, malformed input falls back safely, and kitty mode is pushed and popped around interactive sessions.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Terminal
  participant Server
  participant Snapshot
  participant Client
  participant Program
  Terminal->>Server: update kitty keyboard mode
  Server->>Snapshot: publish keyboard_mode
  Snapshot->>Client: deliver visible snapshot
  Client->>Client: encode key using buffer mode
  Client->>Program: send legacy or CSI-u bytes
Loading

Poem

I’m a rabbit with keys in a bright little row,
Kitty flags hop where the snapshots flow.
CSI carrots decode with a click,
Ctrl-Tab paths make the bindings move quick.
Safe bytes return when sequences go wrong!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: adding CSI-u keyboard support and related encoding/handling updates.
Docstring Coverage ✅ Passed Docstring coverage is 94.44% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Pajn
Pajn force-pushed the csi-u branch 2 times, most recently from 9b4f478 to 6466f96 Compare July 11, 2026 07:07
@Pajn
Pajn force-pushed the smaller branch 2 times, most recently from ce7ceef to 8121c78 Compare July 11, 2026 08:22
@Pajn
Pajn force-pushed the csi-u branch 2 times, most recently from f4a313f to fbb9350 Compare July 11, 2026 10:43
@Pajn
Pajn force-pushed the smaller branch 2 times, most recently from 4c1a2e9 to cf89152 Compare July 13, 2026 09:27
@Pajn
Pajn force-pushed the csi-u branch 2 times, most recently from 116541f to 2da6314 Compare July 13, 2026 10:21
@Pajn
Pajn force-pushed the smaller branch 2 times, most recently from 17e79ca to f1e8397 Compare July 13, 2026 12:08
@Pajn
Pajn force-pushed the csi-u branch 2 times, most recently from 76ebaf5 to ba13544 Compare July 14, 2026 07:52
@Pajn
Pajn force-pushed the smaller branch 2 times, most recently from d0a91e0 to fee8dbe Compare July 15, 2026 07:26
Base automatically changed from smaller to main July 16, 2026 06:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/embers-cli/src/interactive.rs`:
- Around line 654-661: Update the keyboard escape-sequence parsing path around
the event-type check so key-release reports are represented as consumed/ignored
rather than returned as unrecognized. Ensure releases such as CSI 97;5:3u stop
without producing any input event or reaching the raw-byte fallback that creates
KeyEvent::Bytes. Preserve handling for press, repeat, and absent event types.

In `@crates/embers-client/src/controller.rs`:
- Around line 144-146: Update the KeyEvent::Key handling in map_key to pass the
focused buffer’s negotiated keyboard mode to encode_key instead of hardcoding 0.
Resolve or thread that mode through the surrounding input flow, preserving CSI-u
disambiguation for keys such as Ctrl+I.

In `@crates/embers-client/src/input/encoding.rs`:
- Around line 69-90: The encode_key function must route modes with either
KITTY_DISAMBIGUATE_ESC_CODES or KITTY_REPORT_ALL_KEYS_AS_ESC set through
encode_kitty; update the condition to use both mode predicates while preserving
legacy encoding when neither bit is set. In
crates/embers-client/src/input/encoding.rs lines 69-90, change encode_key only;
crates/embers-protocol/schema/embers.fbs lines 531-532 requires no direct change
because bit 4 is intentional.
- Around line 132-155: Update encode_legacy and ctrl_byte so legacy text keys
preserve shift and alt when combined with ctrl, including emitting alt before
the control byte for combinations such as Ctrl+Alt+x. Apply shift to character
encoding, and replace the blanket ASCII bitmask mapping with terminal-compatible
control mappings so Ctrl+Space and digit cases such as Ctrl+3 encode correctly.
Add coverage for Ctrl+Space, a digit control case, and mixed-modifier text keys
including Ctrl+Alt+x and Shift+a.

In `@crates/embers-client/src/input/keyparse.rs`:
- Around line 134-137: Update the key parsing logic around the modifier/key
split to preserve `-` as a valid base key: parse only recognized modifier
prefixes and treat the final hyphen as the base key, so bindings like `<C-->`
and `<C-S-->` do not create an empty modifier or return `InvalidModifier`. Add
regression coverage for both forms.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: de8940d2-f951-4b41-8c0c-449543fb92c5

📥 Commits

Reviewing files that changed from the base of the PR and between 21b0894 and 4a0bf63.

📒 Files selected for processing (18)
  • crates/embers-cli/src/interactive.rs
  • crates/embers-client/src/configured_client.rs
  • crates/embers-client/src/controller.rs
  • crates/embers-client/src/input/encoding.rs
  • crates/embers-client/src/input/keyparse.rs
  • crates/embers-client/src/input/mod.rs
  • crates/embers-client/src/lib.rs
  • crates/embers-client/tests/configured_client.rs
  • crates/embers-client/tests/fixtures/repository_config.rhai
  • crates/embers-client/tests/reducer.rs
  • crates/embers-client/tests/support/mod.rs
  • crates/embers-core/src/snapshot.rs
  • crates/embers-protocol/schema/embers.fbs
  • crates/embers-protocol/src/codec.rs
  • crates/embers-protocol/src/types.rs
  • crates/embers-protocol/tests/family_round_trip.rs
  • crates/embers-server/src/server.rs
  • crates/embers-server/src/terminal_backend.rs

Comment thread crates/embers-cli/src/interactive.rs Outdated
Comment thread crates/embers-client/src/controller.rs Outdated
Comment thread crates/embers-client/src/input/encoding.rs
Comment thread crates/embers-client/src/input/encoding.rs
Comment thread crates/embers-client/src/input/keyparse.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/embers-client/src/configured_client.rs (1)

3326-3338: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Route ordinary keys through the mode-aware encoder too.

In KITTY_REPORT_ALL_KEYS_AS_ESC, unmatched characters and keys such as Tab still emit literal legacy bytes because these branches bypass encode_key. Route all supported key tokens through it; disambiguate-only mode already preserves their legacy encoding.

Proposed direction
-            KeyToken::Char(ch) => {
-                let mut encoded = [0; 4];
-                bytes.extend_from_slice(ch.encode_utf8(&mut encoded).as_bytes());
-            }
-            KeyToken::Space => bytes.push(b' '),
-            KeyToken::Tab => bytes.push(b'\t'),
-            KeyToken::Enter => bytes.push(b'\r'),
-            KeyToken::Backspace => bytes.push(0x7f),
-            KeyToken::Escape => bytes.push(0x1b),
+            KeyToken::Char(ch) => bytes.extend(crate::input::encode_key(
+                crate::input::KeyCode::Char(*ch),
+                crate::input::Modifiers::NONE,
+                mode,
+            )),
+            KeyToken::Space => bytes.extend(crate::input::encode_key(
+                crate::input::KeyCode::Char(' '),
+                crate::input::Modifiers::NONE,
+                mode,
+            )),
+            // Route Tab, Enter, Backspace, and Escape through encode_key likewise.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/embers-client/src/configured_client.rs` around lines 3326 - 3338,
Update sequence_to_bytes to route every supported KeyToken, including ordinary
characters and special keys such as Tab, through the mode-aware encode_key path
when mode is KITTY_REPORT_ALL_KEYS_AS_ESC. Preserve legacy byte output in
disambiguate-only mode and retain the existing handling for unsupported tokens
or errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/embers-cli/src/interactive.rs`:
- Around line 667-724: Update the CSI key parsing flow around the key-code match
and modifier event-type handling so the final byte and key number are validated
first. Return None for unsupported keys before interpreting the event type; then
return Consumed only for event type 3, accept absent/1/2, and reject other event
types without consuming them.

In `@crates/embers-protocol/schema/embers.fbs`:
- Around line 531-532: Update the comment above keyboard_mode in the FlatBuffers
schema to document the correct Kitty keyboard protocol flags: bit 0/value 1 is
disambiguate, bit 3/value 8 is report-all, and bit 4/value 16 is
report-associated-text. Leave the keyboard_mode field unchanged.

---

Outside diff comments:
In `@crates/embers-client/src/configured_client.rs`:
- Around line 3326-3338: Update sequence_to_bytes to route every supported
KeyToken, including ordinary characters and special keys such as Tab, through
the mode-aware encode_key path when mode is KITTY_REPORT_ALL_KEYS_AS_ESC.
Preserve legacy byte output in disambiguate-only mode and retain the existing
handling for unsupported tokens or errors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: cc6e9c8f-d361-4e44-ae29-1161f29cc352

📥 Commits

Reviewing files that changed from the base of the PR and between 4a0bf63 and f082620.

📒 Files selected for processing (18)
  • crates/embers-cli/src/interactive.rs
  • crates/embers-client/src/configured_client.rs
  • crates/embers-client/src/controller.rs
  • crates/embers-client/src/input/encoding.rs
  • crates/embers-client/src/input/keyparse.rs
  • crates/embers-client/src/input/mod.rs
  • crates/embers-client/src/lib.rs
  • crates/embers-client/tests/configured_client.rs
  • crates/embers-client/tests/fixtures/repository_config.rhai
  • crates/embers-client/tests/reducer.rs
  • crates/embers-client/tests/support/mod.rs
  • crates/embers-core/src/snapshot.rs
  • crates/embers-protocol/schema/embers.fbs
  • crates/embers-protocol/src/codec.rs
  • crates/embers-protocol/src/types.rs
  • crates/embers-protocol/tests/family_round_trip.rs
  • crates/embers-server/src/server.rs
  • crates/embers-server/src/terminal_backend.rs

Comment thread crates/embers-cli/src/interactive.rs Outdated
Comment on lines +531 to +532
// Appended: kitty keyboard protocol flags (bit 0 disambiguate, bit 4 report-all).
keyboard_mode:ubyte = 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the schema context around the commented lines.
sed -n '515,545p' crates/embers-protocol/schema/embers.fbs

# Find other mentions of kitty keyboard protocol flags or keyboard_mode.
rg -n "kitty keyboard protocol|keyboard_mode|report-all|report-associated-text|disambiguate" crates/embers-protocol -S

Repository: Pajn/Embers

Length of output: 1634


🌐 Web query:

Kitty keyboard protocol report-all report-associated-text bit 3 bit 4 official documentation

💡 Result:

In the kitty keyboard protocol, progressive enhancement is managed using a bitmask of flags that applications send to the terminal to request specific reporting behaviors [1][2]. The flags you mentioned correspond to the following bit values within this mask: - Bit 3 (value 8): report_all_keys. This flag causes the terminal to report all key events as escape codes [1][3]. In the legacy protocol, keys that generate text (such as plain character keys) do not produce escape codes. Enabling this flag ensures that even these keys generate events, which is necessary for applications requiring key repeat or release notifications for all keys [1][4]. - Bit 4 (value 16): report_text. This flag is an enhancement to report_all_keys and causes key events that generate text to include the associated Unicode text (as codepoints) directly within the CSI u escape code [1][3]. Using this flag without report_all_keys is undefined [1]. In summary, when both bits are enabled (value 8 + 16 = 24), the terminal reports all key presses as escape codes and embeds the corresponding character text within those codes [1][5]. Sources: [6] https://sw.kovidgoyal.net/kitty/keyboard-protocol/ [1] https://github.com/kovidgoyal/kitty/blob/f13c8cd4/docs/keyboard-protocol.rst [3] https://deepwiki.com/kovidgoyal/kitty/5.3-keyboard-protocol-and-key-mapping [4] https://blessed.readthedocs.io/en/1.41/keyboard_kitty.html [5] https://ocaml.org/p/matrix/latest/doc/matrix.terminal/Terminal/index.html [2] https://terminfo.dev/extensions/kitty-keyboard-protocol

Citations:


Fix the Kitty flag docs
crates/embers-protocol/schema/embers.fbs: bit 3/value 8 is report-all, and bit 4/value 16 is report-associated-text; bit 0/value 1 is disambiguate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/embers-protocol/schema/embers.fbs` around lines 531 - 532, Update the
comment above keyboard_mode in the FlatBuffers schema to document the correct
Kitty keyboard protocol flags: bit 0/value 1 is disambiguate, bit 3/value 8 is
report-all, and bit 4/value 16 is report-associated-text. Leave the
keyboard_mode field unchanged.

@Pajn
Pajn force-pushed the csi-u branch 2 times, most recently from 4acf6e6 to ddd2fb8 Compare July 16, 2026 17:38

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/embers-cli/src/interactive.rs`:
- Around line 643-652: Update decode_kitty_mods to return Option<Modifiers> and
reject masks containing unsupported kitty modifier bits for hyper, meta,
caps-lock, or num-lock. Return None for any unrepresentable mask so callers use
the raw-byte fallback, while returning Some with the existing shift, alt, ctrl,
and super_ mappings for supported masks.
- Around line 681-698: Update the final-byte matching logic in the interactive
key decoder so modified-legacy finals b'A' through b'S' are recognized only when
first equals 1; otherwise fall back to the existing raw-byte handling. Preserve
the current mappings for valid first == 1 sequences and the b'u' branch
behavior.

In `@crates/embers-client/src/configured_client.rs`:
- Around line 2304-2305: Update the search-mode key handling around the
KeyEvent::Key arm so unmodified CSI-u keys for ordinary characters, Tab, Enter,
Backspace, and Escape flow through the existing search branches instead of being
swallowed. Continue ignoring genuinely modified or unsupported keys, while
preserving the existing PageDown behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 47055bb0-b9fb-48c4-ac7a-69b17f3b3df3

📥 Commits

Reviewing files that changed from the base of the PR and between f082620 and ddd2fb8.

📒 Files selected for processing (20)
  • crates/embers-cli/src/interactive.rs
  • crates/embers-client/src/configured_client.rs
  • crates/embers-client/src/controller.rs
  • crates/embers-client/src/input/encoding.rs
  • crates/embers-client/src/input/keyparse.rs
  • crates/embers-client/src/input/mod.rs
  • crates/embers-client/src/lib.rs
  • crates/embers-client/tests/configured_client.rs
  • crates/embers-client/tests/controller.rs
  • crates/embers-client/tests/fixtures/repository_config.rhai
  • crates/embers-client/tests/integration.rs
  • crates/embers-client/tests/reducer.rs
  • crates/embers-client/tests/support/mod.rs
  • crates/embers-core/src/snapshot.rs
  • crates/embers-protocol/schema/embers.fbs
  • crates/embers-protocol/src/codec.rs
  • crates/embers-protocol/src/types.rs
  • crates/embers-protocol/tests/family_round_trip.rs
  • crates/embers-server/src/server.rs
  • crates/embers-server/src/terminal_backend.rs
💤 Files with no reviewable changes (2)
  • crates/embers-client/tests/integration.rs
  • crates/embers-client/tests/controller.rs

Comment thread crates/embers-cli/src/interactive.rs Outdated
Comment thread crates/embers-cli/src/interactive.rs Outdated
Comment thread crates/embers-client/src/configured_client.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (2)
crates/embers-client/src/input/encoding.rs (2)

77-84: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Treat report-all mode as disambiguated.

mode_disambiguates(0b1000) currently returns false, although report-all represents every key canonically and explicitly implies disambiguation. This public helper can therefore misroute report-all-only modes. (sw.kovidgoyal.net)

Proposed fix
 pub const fn mode_disambiguates(mode: u8) -> bool {
-    mode & KITTY_DISAMBIGUATE_ESC_CODES != 0
+    mode & (KITTY_DISAMBIGUATE_ESC_CODES | KITTY_REPORT_ALL_KEYS_AS_ESC) != 0
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/embers-client/src/input/encoding.rs` around lines 77 - 84, Update the
public mode_disambiguates function to return true when either
KITTY_DISAMBIGUATE_ESC_CODES or KITTY_REPORT_ALL_KEYS_AS_ESC is enabled, so
report-all-only mode is treated as disambiguated. Leave mode_reports_all_keys
unchanged.

88-97: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Select CSI-u based on whether the key combination has a legacy representation.

Under disambiguate-only mode, Shift-only text such as <S-a> should remain text (A), but the nonempty modifier check emits CSI-u. Conversely, without negotiated flags, combinations such as Ctrl+Shift+A or Super+A have no legacy representation and must use CSI-u rather than dropping modifiers. The current Ctrl+Shift test consequently codifies the wrong result. (sw.kovidgoyal.net)

Also applies to: 123-128, 139-166, 368-382

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/embers-client/src/input/encoding.rs` around lines 88 - 97, Update
encode_key to choose CSI-u based on whether the key/modifier combination has a
valid legacy encoding, rather than solely on mode_disambiguates or
mode_reports_all_keys. Preserve Shift-only text such as <S-a> as legacy output
in disambiguate-only mode, while routing combinations without legacy
representations (for example Ctrl+Shift+A and Super+A) through encode_kitty even
when no flags are negotiated. Adjust the related tests covering these cases and
the current Ctrl+Shift expectation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/embers-cli/src/interactive.rs`:
- Around line 647-648: Update decode_kitty_mods so modifier value 0 returns None
before subtracting the encoding offset; only values of at least 1 should convert
via value minus one into a Modifiers bitmask, preserving raw-byte fallback for
CSI 97;0u.

In `@crates/embers-client/src/configured_client.rs`:
- Around line 3299-3348: Apply normalize_text_key to unmodified CSI-u KeyEvents
before every input-routing path, including tokenization and the hints matching
path near the affected handlers. Ensure ordinary characters, Tab, Enter,
Backspace, and Escape become their legacy events while modified or non-text keys
remain unchanged. Add report-all input tests covering ordinary bindings,
Tab/Space bindings, and hints labels.

In `@crates/embers-client/src/input/encoding.rs`:
- Around line 168-171: Update encode_legacy’s KeyCode handling to consult the C0
modifier table before emitting default bytes for Enter, Tab, Backspace, and
Escape. Include Shift+Tab/backtab, Alt+Enter, Ctrl+Backspace, and Ctrl+Shift+Tab
mappings, while preserving unmodified legacy byte behavior.

---

Duplicate comments:
In `@crates/embers-client/src/input/encoding.rs`:
- Around line 77-84: Update the public mode_disambiguates function to return
true when either KITTY_DISAMBIGUATE_ESC_CODES or KITTY_REPORT_ALL_KEYS_AS_ESC is
enabled, so report-all-only mode is treated as disambiguated. Leave
mode_reports_all_keys unchanged.
- Around line 88-97: Update encode_key to choose CSI-u based on whether the
key/modifier combination has a valid legacy encoding, rather than solely on
mode_disambiguates or mode_reports_all_keys. Preserve Shift-only text such as
<S-a> as legacy output in disambiguate-only mode, while routing combinations
without legacy representations (for example Ctrl+Shift+A and Super+A) through
encode_kitty even when no flags are negotiated. Adjust the related tests
covering these cases and the current Ctrl+Shift expectation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 69958558-6931-4f33-af51-5733fcd0ec61

📥 Commits

Reviewing files that changed from the base of the PR and between ddd2fb8 and 883c424.

📒 Files selected for processing (20)
  • crates/embers-cli/src/interactive.rs
  • crates/embers-client/src/configured_client.rs
  • crates/embers-client/src/controller.rs
  • crates/embers-client/src/input/encoding.rs
  • crates/embers-client/src/input/keyparse.rs
  • crates/embers-client/src/input/mod.rs
  • crates/embers-client/src/lib.rs
  • crates/embers-client/tests/configured_client.rs
  • crates/embers-client/tests/controller.rs
  • crates/embers-client/tests/fixtures/repository_config.rhai
  • crates/embers-client/tests/integration.rs
  • crates/embers-client/tests/reducer.rs
  • crates/embers-client/tests/support/mod.rs
  • crates/embers-core/src/snapshot.rs
  • crates/embers-protocol/schema/embers.fbs
  • crates/embers-protocol/src/codec.rs
  • crates/embers-protocol/src/types.rs
  • crates/embers-protocol/tests/family_round_trip.rs
  • crates/embers-server/src/server.rs
  • crates/embers-server/src/terminal_backend.rs
💤 Files with no reviewable changes (2)
  • crates/embers-client/tests/integration.rs
  • crates/embers-client/tests/controller.rs

Comment thread crates/embers-cli/src/interactive.rs Outdated
Comment thread crates/embers-client/src/configured_client.rs
Comment thread crates/embers-client/src/input/encoding.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/embers-cli/src/interactive.rs`:
- Around line 712-717: Update the modifier parsing in the event-report handling
match to reject extra colon-separated fields: after parsing the value and event
type from modifier.split(':'), ensure no further component remains and return
None when one does. Preserve valid reports with at most one event-type field and
the existing raw-byte fallback for malformed input.

In `@crates/embers-client/src/input/encoding.rs`:
- Around line 166-173: Update the mode-aware encoder around ctrl_byte and the
Ctrl-chord branch in crates/embers-client/src/input/encoding.rs:166-173 to
return an encoding error for non-ASCII Ctrl chords when Kitty mode is
unavailable, while retaining existing ASCII encoding. In
crates/embers-client/src/input/keyparse.rs:175-182, preserve the typed Ctrl
chord instead of rejecting it during parsing so validation is deferred to
encoding.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 33816cba-9d39-4729-94a8-35d7a602fceb

📥 Commits

Reviewing files that changed from the base of the PR and between 883c424 and 3f909e9.

📒 Files selected for processing (20)
  • crates/embers-cli/src/interactive.rs
  • crates/embers-client/src/configured_client.rs
  • crates/embers-client/src/controller.rs
  • crates/embers-client/src/input/encoding.rs
  • crates/embers-client/src/input/keyparse.rs
  • crates/embers-client/src/input/mod.rs
  • crates/embers-client/src/lib.rs
  • crates/embers-client/tests/configured_client.rs
  • crates/embers-client/tests/controller.rs
  • crates/embers-client/tests/fixtures/repository_config.rhai
  • crates/embers-client/tests/integration.rs
  • crates/embers-client/tests/reducer.rs
  • crates/embers-client/tests/support/mod.rs
  • crates/embers-core/src/snapshot.rs
  • crates/embers-protocol/schema/embers.fbs
  • crates/embers-protocol/src/codec.rs
  • crates/embers-protocol/src/types.rs
  • crates/embers-protocol/tests/family_round_trip.rs
  • crates/embers-server/src/server.rs
  • crates/embers-server/src/terminal_backend.rs
💤 Files with no reviewable changes (2)
  • crates/embers-client/tests/integration.rs
  • crates/embers-client/tests/controller.rs

Comment thread crates/embers-cli/src/interactive.rs
Comment thread crates/embers-client/src/input/encoding.rs
@Pajn

Pajn commented Jul 18, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/embers-cli/src/interactive.rs`:
- Around line 755-771: Remove the b'R' mapping in the CSI key decoder so
cursor-position reports such as CSI 1;2R fall back to raw bytes instead of
becoming F3. Preserve F3 decoding through the existing tilde-sequence match by
adding or updating the 13;mods~ mapping, and add regression tests for raw CSI
1;2R and Shift+F3 from CSI 13;2~.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ce2f721b-1ec0-4e59-a82a-588b158352fa

📥 Commits

Reviewing files that changed from the base of the PR and between 883c424 and 2a9c6c7.

📒 Files selected for processing (20)
  • crates/embers-cli/src/interactive.rs
  • crates/embers-client/src/configured_client.rs
  • crates/embers-client/src/controller.rs
  • crates/embers-client/src/input/encoding.rs
  • crates/embers-client/src/input/keyparse.rs
  • crates/embers-client/src/input/mod.rs
  • crates/embers-client/src/lib.rs
  • crates/embers-client/tests/configured_client.rs
  • crates/embers-client/tests/controller.rs
  • crates/embers-client/tests/fixtures/repository_config.rhai
  • crates/embers-client/tests/integration.rs
  • crates/embers-client/tests/reducer.rs
  • crates/embers-client/tests/support/mod.rs
  • crates/embers-core/src/snapshot.rs
  • crates/embers-protocol/schema/embers.fbs
  • crates/embers-protocol/src/codec.rs
  • crates/embers-protocol/src/types.rs
  • crates/embers-protocol/tests/family_round_trip.rs
  • crates/embers-server/src/server.rs
  • crates/embers-server/src/terminal_backend.rs
💤 Files with no reviewable changes (2)
  • crates/embers-client/tests/controller.rs
  • crates/embers-client/tests/integration.rs

Comment thread crates/embers-cli/src/interactive.rs
Pajn added 5 commits July 19, 2026 21:08
Foundation for extended-keys support, added additively so legacy encodings
and bindings are unchanged:

- input/encoding.rs: a single encode_key(code, mods, mode) used by both the
  host controller and the scripted send-keys path. Emits legacy VT sequences
  by default and kitty CSI-u sequences when the target's keyboard mode has
  DISAMBIGUATE_ESC_CODES (honoring REPORT_ALL_KEYS_AS_ESC); KeyCode +
  Modifiers model the logical key
- keyparse grammar: S- shift, multi-modifier (<C-S-Tab>), and function keys
  <F1>-<F12> now parse into a new KeyToken::Key { code, mods }; single
  C-/A- char keys still produce the legacy Ctrl/Alt tokens
- KeyEvent::Key alongside the legacy variants; key_event_to_token and
  sequence_to_bytes handle it via the shared encoder

Tests: encoder table (legacy vs disambiguate vs report-all, modified arrows,
C-S-Tab, function keys) and keyparse grammar (<C-S-Tab>, <S-Left>, <F5>,
invalid combos).
- terminal backend enables alacritty's kitty_keyboard, so inner apps can
  push/pop/query disambiguation flags; the CSI ? u query reply rides
  Event::PtyWrite (already forwarded)
- the active kitty flags are read into a compact keyboard_mode bitfield
  (bit 0 disambiguate, bit 4 report-all-keys) on TerminalModes /
  BackendMetadata and flow through the visible snapshot to the protocol
  (VisibleSnapshotResponse.keyboard_mode) and on to the client, mirroring
  bracketed_paste; the client encoder is ready to consume it

Tests: backend push/pop of the kitty mode; protocol round-trip of a
non-zero keyboard_mode.
- interactive client pushes the kitty keyboard protocol (disambiguate-only,
  \x1b[>1u) on enter and pops it (\x1b[<u) on exit; unsupported terminals
  ignore both harmlessly
- parse_extended_key decodes CSI-u (code;mods u) and modified-legacy
  (CSI 1;mods A-D/H/F, CSI n;mods ~, F-key letters) reports into
  KeyEvent::Key, ignoring event-type sub-parameters; unknown sequences
  still fall back to KeyEvent::Bytes passthrough
- passthrough coherence: unmatched keys re-encode through the shared
  encoder using the focused buffer's negotiated keyboard mode
  (buffer_keyboard_mode), so csi-u in yields csi-u out when the inner app
  wants it and legacy translation when it doesn't; the SendKeys action and
  alternate-screen binding passthrough use it too
- fixture config binds <C-Tab>/<C-S-Tab> to next/prev tab

Tests: parser units (CSI-u, C-S-Tab, modified arrows, modified F-key,
fallback to bytes).
Controller::map_key was a legacy input mapper superseded by the
ConfiguredClient input path (bindings, modes, and encode_key with the
buffer's negotiated keyboard mode). It was only exercised by its own
tests, never in the live flow, and hardcoded keyboard mode 0.

Remove the Controller struct, map_key, and its private helpers
(ctrl_byte, alt_bytes_request, input_request), drop tests/controller.rs
and the crate export. The shared KeyEvent/MouseEvent input types in the
same module are kept — they remain in live use.
The compact keyboard_mode byte put report-all-keys at bit 4, which is the
kitty protocol's report-associated-text position — an internally
consistent but confusing reuse of a spec bit for a different flag.

Move report-all-keys to bit 3 (its kitty-spec position) across the
producer (terminal_backend::kitty_keyboard_mode), the consumer constant
(KITTY_REPORT_ALL_KEYS_AS_ESC), and the field docs (snapshot.rs, the
FlatBuffers schema). Bit 0 = disambiguate and bit 3 = report-all now
match the protocol's own numbering, so the byte never reuses a spec bit
position for a different meaning.
@Pajn
Pajn merged commit 22fe7a9 into main Jul 19, 2026
4 checks passed
@Pajn
Pajn deleted the csi-u branch July 19, 2026 19:19
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.

1 participant