mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-20 10:10:56 -07:00
fix(cli): Fix word navigation for CJK characters (#14475)
This commit is contained in:
@@ -2241,4 +2241,103 @@ describe('Unicode helper functions', () => {
|
||||
expect(cpLen('hello مرحبا world')).toBe(17);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useTextBuffer CJK Navigation', () => {
|
||||
const viewport = { width: 80, height: 24 };
|
||||
|
||||
it('should navigate by word in Chinese', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useTextBuffer({
|
||||
initialText: '你好世界',
|
||||
initialCursorOffset: 4, // End of string
|
||||
viewport,
|
||||
isValidPath: () => false,
|
||||
}),
|
||||
);
|
||||
|
||||
// Initial state: cursor at end (index 2 in code points if 4 is length? wait. length is 2 code points? No. '你好世界' length is 4.)
|
||||
// '你好世界' length is 4. Code points length is 4.
|
||||
|
||||
// Move word left
|
||||
act(() => {
|
||||
result.current.move('wordLeft');
|
||||
});
|
||||
|
||||
// Should be at start of "世界" (index 2)
|
||||
// "你好世界" -> "你好" | "世界"
|
||||
expect(result.current.cursor[1]).toBe(2);
|
||||
|
||||
// Move word left again
|
||||
act(() => {
|
||||
result.current.move('wordLeft');
|
||||
});
|
||||
|
||||
// Should be at start of "你好" (index 0)
|
||||
expect(result.current.cursor[1]).toBe(0);
|
||||
|
||||
// Move word left again (should stay at 0)
|
||||
act(() => {
|
||||
result.current.move('wordLeft');
|
||||
});
|
||||
expect(result.current.cursor[1]).toBe(0);
|
||||
|
||||
// Move word right
|
||||
act(() => {
|
||||
result.current.move('wordRight');
|
||||
});
|
||||
|
||||
// Should be at end of "你好" (index 2)
|
||||
expect(result.current.cursor[1]).toBe(2);
|
||||
|
||||
// Move word right again
|
||||
act(() => {
|
||||
result.current.move('wordRight');
|
||||
});
|
||||
|
||||
// Should be at end of "世界" (index 4)
|
||||
expect(result.current.cursor[1]).toBe(4);
|
||||
|
||||
// Move word right again (should stay at end)
|
||||
act(() => {
|
||||
result.current.move('wordRight');
|
||||
});
|
||||
expect(result.current.cursor[1]).toBe(4);
|
||||
});
|
||||
|
||||
it('should navigate mixed English and Chinese', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useTextBuffer({
|
||||
initialText: 'Hello你好World',
|
||||
initialCursorOffset: 10, // End
|
||||
viewport,
|
||||
isValidPath: () => false,
|
||||
}),
|
||||
);
|
||||
|
||||
// Hello (5) + 你好 (2) + World (5) = 12 chars.
|
||||
// initialCursorOffset 10? 'Hello你好World'.length is 12.
|
||||
// Let's set it to end.
|
||||
|
||||
act(() => {
|
||||
result.current.move('end');
|
||||
});
|
||||
expect(result.current.cursor[1]).toBe(12);
|
||||
|
||||
// wordLeft -> start of "World" (index 7)
|
||||
act(() => result.current.move('wordLeft'));
|
||||
expect(result.current.cursor[1]).toBe(7);
|
||||
|
||||
// wordLeft -> start of "你好" (index 5)
|
||||
act(() => result.current.move('wordLeft'));
|
||||
expect(result.current.cursor[1]).toBe(5);
|
||||
|
||||
// wordLeft -> start of "Hello" (index 0)
|
||||
act(() => result.current.move('wordLeft'));
|
||||
expect(result.current.cursor[1]).toBe(0);
|
||||
|
||||
// wordLeft -> start of line (should stay at 0)
|
||||
act(() => result.current.move('wordLeft'));
|
||||
expect(result.current.cursor[1]).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user