mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-17 16:51:15 -07:00
fix(cli): allow scrolling keys in copy mode (Ctrl+S selection mode) (#19933)
Co-authored-by: Jacob Richman <jacob314@gmail.com>
This commit is contained in:
@@ -2770,7 +2770,7 @@ describe('AppContainer State Management', () => {
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should exit copy mode on any key press', async () => {
|
||||
it('should exit copy mode on non-scroll key press', async () => {
|
||||
await setupCopyModeTest(isAlternateMode);
|
||||
|
||||
// Enter copy mode
|
||||
@@ -2792,6 +2792,61 @@ describe('AppContainer State Management', () => {
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should not exit copy mode on PageDown and should pass it through', async () => {
|
||||
const childHandler = vi.fn().mockReturnValue(false);
|
||||
await setupCopyModeTest(true, childHandler);
|
||||
|
||||
// Enter copy mode
|
||||
act(() => {
|
||||
stdin.write('\x13'); // Ctrl+S
|
||||
});
|
||||
rerender();
|
||||
expect(disableMouseEvents).toHaveBeenCalled();
|
||||
|
||||
childHandler.mockClear();
|
||||
(enableMouseEvents as Mock).mockClear();
|
||||
|
||||
// PageDown should be passed through to lower-priority handlers.
|
||||
act(() => {
|
||||
stdin.write('\x1b[6~');
|
||||
});
|
||||
rerender();
|
||||
|
||||
expect(enableMouseEvents).not.toHaveBeenCalled();
|
||||
expect(childHandler).toHaveBeenCalled();
|
||||
expect(childHandler).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ name: 'pagedown' }),
|
||||
);
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should not exit copy mode on Shift+Down and should pass it through', async () => {
|
||||
const childHandler = vi.fn().mockReturnValue(false);
|
||||
await setupCopyModeTest(true, childHandler);
|
||||
|
||||
// Enter copy mode
|
||||
act(() => {
|
||||
stdin.write('\x13'); // Ctrl+S
|
||||
});
|
||||
rerender();
|
||||
expect(disableMouseEvents).toHaveBeenCalled();
|
||||
|
||||
childHandler.mockClear();
|
||||
(enableMouseEvents as Mock).mockClear();
|
||||
|
||||
act(() => {
|
||||
stdin.write('\x1b[1;2B'); // Shift+Down
|
||||
});
|
||||
rerender();
|
||||
|
||||
expect(enableMouseEvents).not.toHaveBeenCalled();
|
||||
expect(childHandler).toHaveBeenCalled();
|
||||
expect(childHandler).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ name: 'down', shift: true }),
|
||||
);
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should have higher priority than other priority listeners when enabled', async () => {
|
||||
// 1. Initial state with a child component's priority listener (already subscribed)
|
||||
// It should NOT handle Ctrl+S so we can enter copy mode.
|
||||
|
||||
@@ -1864,7 +1864,18 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
||||
useKeypress(handleGlobalKeypress, { isActive: true, priority: true });
|
||||
|
||||
useKeypress(
|
||||
() => {
|
||||
(key: Key) => {
|
||||
if (
|
||||
keyMatchers[Command.SCROLL_UP](key) ||
|
||||
keyMatchers[Command.SCROLL_DOWN](key) ||
|
||||
keyMatchers[Command.PAGE_UP](key) ||
|
||||
keyMatchers[Command.PAGE_DOWN](key) ||
|
||||
keyMatchers[Command.SCROLL_HOME](key) ||
|
||||
keyMatchers[Command.SCROLL_END](key)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setCopyModeEnabled(false);
|
||||
enableMouseEvents();
|
||||
return true;
|
||||
|
||||
@@ -35,7 +35,8 @@ describe('CopyModeWarning', () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = render(<CopyModeWarning />);
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toContain('In Copy Mode');
|
||||
expect(lastFrame()).toContain('Press any key to exit');
|
||||
expect(lastFrame()).toContain('Use Page Up/Down to scroll');
|
||||
expect(lastFrame()).toContain('Press Ctrl+S or any other key to exit');
|
||||
unmount();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,8 @@ export const CopyModeWarning: React.FC = () => {
|
||||
return (
|
||||
<Box>
|
||||
<Text color={theme.status.warning}>
|
||||
In Copy Mode. Press any key to exit.
|
||||
In Copy Mode. Use Page Up/Down to scroll. Press Ctrl+S or any other key
|
||||
to exit.
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user