Skip to content

Key has Delete, PageUp and PageDown but no Insert #166

Description

@vyncint

Good first issue. Three short match arms and two test lines, with every
neighbour already written for you to copy.

Today

Key (crates/termlens/src/keys.rs:15) covers the navigation cluster — almost:

Delete    ESC [ 3 ~     keys.rs:100
Home      ESC [ H       keys.rs:105
End       ESC [ F       keys.rs:106
PageUp    ESC [ 5 ~     keys.rs:107
PageDown  ESC [ 6 ~     keys.rs:108

InsertESC [ 2 ~ — is missing. It is the 2 in a run that already has
3, 5 and 6.

A test for an application that binds Insert (a table editor toggling insert
mode, a file manager's "select and move down", vim-likes) cannot send it. The
closest workaround is Key::Char with a hand-written escape, which is not
something a test should have to know.

Fix

Three places, each with a Delete or PageUp line immediately next to it:

  1. The variant, keys.rs:48 area — beside Delete, with a doc comment in
    the same style: /// Insert (ESC [ 2 ~).
  2. Key::encode, keys.rs:100 area:
    Key::Insert => b"\x1b[2~".to_vec(),
  3. chord_base, keys.rs:311 area — this is what makes
    Key::Insert.shift() and friends encode correctly:
    Key::Insert => ChordBase::Tilde(2),

Not encode_modal (keys.rs:161). That handles DECCKM, which only applies
to the cursor keys and Home/End; Insert is unaffected and falls through to
encode correctly on its own. Worth a moment to convince yourself of that rather
than taking my word for it.

Tests

Two existing tables in keys.rs, one line each:

  • xterm_encodings (keys.rs:360): (Key::Insert, b"\x1b[2~")
  • chord_encodings (keys.rs:408): something like
    (Key::Insert.shift(), b"\x1b[2;2~") — check the modifier arithmetic against
    the Delete.ctrl() line right above it rather than trusting mine.

There is also an end-to-end path if you want it. tests/fixtures.rs:62 sends
keys to the form-echo fixture and asserts on the name it echoes back. The
fixture's describe (fixtures/form-echo/src/main.rs:90) has an arm per key and
currently has none for KeyCode::Insert; adding one and a case in the test table
proves the byte sequence survives a real PTY and a real input parser, not just
our own table. Optional, and a good stretch if the first part goes quickly.

One thing to know before you start

Key is not #[non_exhaustive] today, so adding a variant is a breaking
change
cargo-semver-checks runs at release and will say so. That is why
this sits in the v0.7 milestone rather than a patch.

#165 proposes making Key #[non_exhaustive], which would take that cost off
every future key. The two issues are independent — take either, in either order —
but if you fancy doing both, doing #165 first makes this one free from then on.

Done when

Key::Insert encodes ESC [ 2 ~, chords with modifiers correctly, is covered by
the encoding tables, and has a line under [Unreleased] in CHANGELOG.md.

Getting started

CONTRIBUTING.md has the setup and the DCO sign-off (git commit -s); AI help is
welcome, AI attribution is not. crates/termlens/src/keys.rs is 483 lines and
reads top to bottom — you can hold all of it at once, which is why this is a good
place to start. Ask here if anything is unclear.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions