fix(cli): resolve home/end keybinding conflict (#17124)

This commit is contained in:
Tommaso Sciortino
2026-01-20 18:15:18 -08:00
committed by GitHub
parent 995ae42f53
commit 2455f939a3
5 changed files with 57 additions and 25 deletions

View File

@@ -19,8 +19,8 @@ available combinations.
| Action | Keys |
| ------------------------------------------- | ------------------------------------------------------------ |
| Move the cursor to the start of the line. | `Ctrl + A`<br />`Home` |
| Move the cursor to the end of the line. | `Ctrl + E`<br />`End` |
| Move the cursor to the start of the line. | `Ctrl + A`<br />`Home (no Ctrl, no Shift)` |
| Move the cursor to the end of the line. | `Ctrl + E`<br />`End (no Ctrl, no Shift)` |
| Move the cursor up one line. | `Up Arrow (no Ctrl, no Cmd)` |
| Move the cursor down one line. | `Down Arrow (no Ctrl, no Cmd)` |
| Move the cursor one character to the left. | `Left Arrow (no Ctrl, no Cmd)`<br />`Ctrl + B` |
@@ -44,14 +44,14 @@ available combinations.
#### Scrolling
| Action | Keys |
| ------------------------ | -------------------- |
| Scroll content up. | `Shift + Up Arrow` |
| Scroll content down. | `Shift + Down Arrow` |
| Scroll to the top. | `Home` |
| Scroll to the bottom. | `End` |
| Scroll up by one page. | `Page Up` |
| Scroll down by one page. | `Page Down` |
| Action | Keys |
| ------------------------ | --------------------------------- |
| Scroll content up. | `Shift + Up Arrow` |
| Scroll content down. | `Shift + Down Arrow` |
| Scroll to the top. | `Ctrl + Home`<br />`Shift + Home` |
| Scroll to the bottom. | `Ctrl + End`<br />`Shift + End` |
| Scroll up by one page. | `Page Up` |
| Scroll down by one page. | `Page Down` |
#### History & Search

View File

@@ -73,9 +73,27 @@ describe('keyBindings config', () => {
expect(dialogNavDown).toContainEqual({ key: 'down', shift: false });
expect(dialogNavDown).toContainEqual({ key: 'j', shift: false });
// Verify physical home/end keys
expect(defaultKeyBindings[Command.HOME]).toContainEqual({ key: 'home' });
expect(defaultKeyBindings[Command.END]).toContainEqual({ key: 'end' });
// Verify physical home/end keys for cursor movement
expect(defaultKeyBindings[Command.HOME]).toContainEqual({
key: 'home',
ctrl: false,
shift: false,
});
expect(defaultKeyBindings[Command.END]).toContainEqual({
key: 'end',
ctrl: false,
shift: false,
});
// Verify physical home/end keys for scrolling
expect(defaultKeyBindings[Command.SCROLL_HOME]).toContainEqual({
key: 'home',
ctrl: true,
});
expect(defaultKeyBindings[Command.SCROLL_END]).toContainEqual({
key: 'end',
ctrl: true,
});
});
});

View File

@@ -117,8 +117,14 @@ export const defaultKeyBindings: KeyBindingConfig = {
[Command.EXIT]: [{ key: 'd', ctrl: true }],
// Cursor Movement
[Command.HOME]: [{ key: 'a', ctrl: true }, { key: 'home' }],
[Command.END]: [{ key: 'e', ctrl: true }, { key: 'end' }],
[Command.HOME]: [
{ key: 'a', ctrl: true },
{ key: 'home', ctrl: false, shift: false },
],
[Command.END]: [
{ key: 'e', ctrl: true },
{ key: 'end', ctrl: false, shift: false },
],
[Command.MOVE_UP]: [{ key: 'up', ctrl: false, command: false }],
[Command.MOVE_DOWN]: [{ key: 'down', ctrl: false, command: false }],
[Command.MOVE_LEFT]: [
@@ -162,8 +168,14 @@ export const defaultKeyBindings: KeyBindingConfig = {
// Scrolling
[Command.SCROLL_UP]: [{ key: 'up', shift: true }],
[Command.SCROLL_DOWN]: [{ key: 'down', shift: true }],
[Command.SCROLL_HOME]: [{ key: 'home' }],
[Command.SCROLL_END]: [{ key: 'end' }],
[Command.SCROLL_HOME]: [
{ key: 'home', ctrl: true },
{ key: 'home', shift: true },
],
[Command.SCROLL_END]: [
{ key: 'end', ctrl: true },
{ key: 'end', shift: true },
],
[Command.PAGE_UP]: [{ key: 'pageup' }],
[Command.PAGE_DOWN]: [{ key: 'pagedown' }],

View File

@@ -356,18 +356,18 @@ describe('ScrollableList Demo Behavior', () => {
expect(listRef?.getScrollState()?.scrollTop).toBeLessThan(2);
});
// End -> \x1b[F
// End -> \x1b[1;5F (Ctrl+End)
await act(async () => {
stdin.write('\x1b[F');
stdin.write('\x1b[1;5F');
});
await waitFor(() => {
// Total 50 items, height 10. Max scroll ~40.
expect(listRef?.getScrollState()?.scrollTop).toBeGreaterThan(30);
});
// Home -> \x1b[H
// Home -> \x1b[1;5H (Ctrl+Home)
await act(async () => {
stdin.write('\x1b[H');
stdin.write('\x1b[1;5H');
});
await waitFor(() => {
expect(listRef?.getScrollState()?.scrollTop).toBe(0);

View File

@@ -43,6 +43,7 @@ describe('keyMatchers', () => {
createKey('a'),
createKey('a', { shift: true }),
createKey('b', { ctrl: true }),
createKey('home', { ctrl: true }),
],
},
{
@@ -52,6 +53,7 @@ describe('keyMatchers', () => {
createKey('e'),
createKey('e', { shift: true }),
createKey('a', { ctrl: true }),
createKey('end', { ctrl: true }),
],
},
{
@@ -157,13 +159,13 @@ describe('keyMatchers', () => {
},
{
command: Command.SCROLL_HOME,
positive: [createKey('home')],
negative: [createKey('end')],
positive: [createKey('home', { ctrl: true })],
negative: [createKey('end'), createKey('home')],
},
{
command: Command.SCROLL_END,
positive: [createKey('end')],
negative: [createKey('home')],
positive: [createKey('end', { ctrl: true })],
negative: [createKey('home'), createKey('end')],
},
{
command: Command.PAGE_UP,