mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
Handle stdin for prompts using readline for escape character parsing (#1972)
This commit is contained in:
@@ -574,8 +574,24 @@ describe('useTextBuffer', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useTextBuffer({ viewport, isValidPath: () => false }),
|
||||
);
|
||||
act(() => result.current.handleInput('h', {}));
|
||||
act(() => result.current.handleInput('i', {}));
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: 'h',
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: 'h',
|
||||
}),
|
||||
);
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: 'i',
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: 'i',
|
||||
}),
|
||||
);
|
||||
expect(getBufferState(result).text).toBe('hi');
|
||||
});
|
||||
|
||||
@@ -583,7 +599,15 @@ describe('useTextBuffer', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useTextBuffer({ viewport, isValidPath: () => false }),
|
||||
);
|
||||
act(() => result.current.handleInput(undefined, { return: true }));
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: 'return',
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: '\r',
|
||||
}),
|
||||
);
|
||||
expect(getBufferState(result).lines).toEqual(['', '']);
|
||||
});
|
||||
|
||||
@@ -596,7 +620,15 @@ describe('useTextBuffer', () => {
|
||||
}),
|
||||
);
|
||||
act(() => result.current.move('end'));
|
||||
act(() => result.current.handleInput(undefined, { backspace: true }));
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: 'backspace',
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: '\x7f',
|
||||
}),
|
||||
);
|
||||
expect(getBufferState(result).text).toBe('');
|
||||
});
|
||||
|
||||
@@ -671,9 +703,25 @@ describe('useTextBuffer', () => {
|
||||
}),
|
||||
);
|
||||
act(() => result.current.move('end')); // cursor [0,2]
|
||||
act(() => result.current.handleInput(undefined, { leftArrow: true })); // cursor [0,1]
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: 'left',
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: '\x1b[D',
|
||||
}),
|
||||
); // cursor [0,1]
|
||||
expect(getBufferState(result).cursor).toEqual([0, 1]);
|
||||
act(() => result.current.handleInput(undefined, { rightArrow: true })); // cursor [0,2]
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: 'right',
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: '\x1b[C',
|
||||
}),
|
||||
); // cursor [0,2]
|
||||
expect(getBufferState(result).cursor).toEqual([0, 2]);
|
||||
});
|
||||
|
||||
@@ -683,7 +731,15 @@ describe('useTextBuffer', () => {
|
||||
);
|
||||
const textWithAnsi = '\x1B[31mHello\x1B[0m \x1B[32mWorld\x1B[0m';
|
||||
// Simulate pasting by calling handleInput with a string longer than 1 char
|
||||
act(() => result.current.handleInput(textWithAnsi, {}));
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: undefined,
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: textWithAnsi,
|
||||
}),
|
||||
);
|
||||
expect(getBufferState(result).text).toBe('Hello World');
|
||||
});
|
||||
|
||||
@@ -691,7 +747,15 @@ describe('useTextBuffer', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useTextBuffer({ viewport, isValidPath: () => false }),
|
||||
);
|
||||
act(() => result.current.handleInput('\r', {})); // Simulates Shift+Enter in VSCode terminal
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: 'return',
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: true,
|
||||
sequence: '\r',
|
||||
}),
|
||||
); // Simulates Shift+Enter in VSCode terminal
|
||||
expect(getBufferState(result).lines).toEqual(['', '']);
|
||||
});
|
||||
|
||||
@@ -880,7 +944,15 @@ Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots
|
||||
useTextBuffer({ viewport, isValidPath: () => false }),
|
||||
);
|
||||
const textWithAnsi = '\x1B[31mHello\x1B[0m';
|
||||
act(() => result.current.handleInput(textWithAnsi, {}));
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: undefined,
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: textWithAnsi,
|
||||
}),
|
||||
);
|
||||
expect(getBufferState(result).text).toBe('Hello');
|
||||
});
|
||||
|
||||
@@ -889,7 +961,15 @@ Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots
|
||||
useTextBuffer({ viewport, isValidPath: () => false }),
|
||||
);
|
||||
const textWithControlChars = 'H\x07e\x08l\x0Bl\x0Co'; // BELL, BACKSPACE, VT, FF
|
||||
act(() => result.current.handleInput(textWithControlChars, {}));
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: undefined,
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: textWithControlChars,
|
||||
}),
|
||||
);
|
||||
expect(getBufferState(result).text).toBe('Hello');
|
||||
});
|
||||
|
||||
@@ -898,7 +978,15 @@ Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots
|
||||
useTextBuffer({ viewport, isValidPath: () => false }),
|
||||
);
|
||||
const textWithMixed = '\u001B[4mH\u001B[0mello';
|
||||
act(() => result.current.handleInput(textWithMixed, {}));
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: undefined,
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: textWithMixed,
|
||||
}),
|
||||
);
|
||||
expect(getBufferState(result).text).toBe('Hello');
|
||||
});
|
||||
|
||||
@@ -907,7 +995,15 @@ Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots
|
||||
useTextBuffer({ viewport, isValidPath: () => false }),
|
||||
);
|
||||
const validText = 'Hello World\nThis is a test.';
|
||||
act(() => result.current.handleInput(validText, {}));
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: undefined,
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: validText,
|
||||
}),
|
||||
);
|
||||
expect(getBufferState(result).text).toBe(validText);
|
||||
});
|
||||
|
||||
@@ -916,7 +1012,15 @@ Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots
|
||||
useTextBuffer({ viewport, isValidPath: () => false }),
|
||||
);
|
||||
const pastedText = '\u001B[4mPasted\u001B[4m Text';
|
||||
act(() => result.current.handleInput(pastedText, {}));
|
||||
act(() =>
|
||||
result.current.handleInput({
|
||||
name: undefined,
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false,
|
||||
sequence: pastedText,
|
||||
}),
|
||||
);
|
||||
expect(getBufferState(result).text).toBe('Pasted Text');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user