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
Insert — ESC [ 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:
- The variant,
keys.rs:48 area — beside Delete, with a doc comment in
the same style: /// Insert (ESC [ 2 ~).
Key::encode, keys.rs:100 area:
Key::Insert => b"\x1b[2~".to_vec(),
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.
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:Insert—ESC [ 2 ~— is missing. It is the2in a run that already has3,5and6.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::Charwith a hand-written escape, which is notsomething a test should have to know.
Fix
Three places, each with a
DeleteorPageUpline immediately next to it:keys.rs:48area — besideDelete, with a doc comment inthe same style:
/// Insert (ESC [ 2 ~).Key::encode,keys.rs:100area:chord_base,keys.rs:311area — this is what makesKey::Insert.shift()and friends encode correctly:Not
encode_modal(keys.rs:161). That handles DECCKM, which only appliesto the cursor keys and
Home/End;Insertis unaffected and falls through toencodecorrectly on its own. Worth a moment to convince yourself of that ratherthan 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 againstthe
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:62sendskeys to the
form-echofixture and asserts on the name it echoes back. Thefixture's
describe(fixtures/form-echo/src/main.rs:90) has an arm per key andcurrently has none for
KeyCode::Insert; adding one and a case in the test tableproves 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
Keyis not#[non_exhaustive]today, so adding a variant is a breakingchange —
cargo-semver-checksruns at release and will say so. That is whythis sits in the v0.7 milestone rather than a patch.
#165 proposes making
Key#[non_exhaustive], which would take that cost offevery 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::InsertencodesESC [ 2 ~, chords with modifiers correctly, is covered bythe encoding tables, and has a line under
[Unreleased]inCHANGELOG.md.Getting started
CONTRIBUTING.mdhas the setup and the DCO sign-off (git commit -s); AI help iswelcome, AI attribution is not.
crates/termlens/src/keys.rsis 483 lines andreads 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.