mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-30 12:40:44 +00:00
Merge branch 'main' into feature/extension-management-tui
This commit is contained in:
commit
2699b88661
282 changed files with 21375 additions and 6462 deletions
|
|
@ -1335,6 +1335,40 @@ describe('KeypressContext - Kitty Protocol', () => {
|
|||
);
|
||||
});
|
||||
|
||||
describe('Printable CSI-u keys', () => {
|
||||
it('parses kitty CSI-u space as a space key with literal sequence', () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHook(() => useKeypressContext(), { wrapper });
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
act(() => stdin.sendKittySequence(`\x1b[32u`));
|
||||
|
||||
expect(keyHandler).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
name: 'space',
|
||||
sequence: ' ',
|
||||
kittyProtocol: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('parses kitty CSI-u printable letters as literal input', () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHook(() => useKeypressContext(), { wrapper });
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
act(() => stdin.sendKittySequence(`\x1b[100u`)); // 'd'
|
||||
|
||||
expect(keyHandler).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
name: 'd',
|
||||
sequence: 'd',
|
||||
kittyProtocol: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Shift+Tab forms', () => {
|
||||
it.each([
|
||||
{ sequence: `\x1b[Z`, description: 'legacy reverse Tab' },
|
||||
|
|
|
|||
|
|
@ -332,6 +332,36 @@ export function KeypressProvider({
|
|||
};
|
||||
}
|
||||
|
||||
// Printable CSI-u keys (including space) should behave like regular
|
||||
// character input so downstream text inputs receive the literal char.
|
||||
if (
|
||||
terminator === 'u' &&
|
||||
!ctrl &&
|
||||
keyCode >= 32 &&
|
||||
keyCode !== 127 &&
|
||||
keyCode <= 0x10ffff
|
||||
) {
|
||||
const char = String.fromCodePoint(keyCode);
|
||||
const printableName =
|
||||
char === ' '
|
||||
? 'space'
|
||||
: /^[A-Za-z]$/.test(char)
|
||||
? char.toLowerCase()
|
||||
: char;
|
||||
return {
|
||||
key: {
|
||||
name: printableName,
|
||||
ctrl: false,
|
||||
meta: alt,
|
||||
shift,
|
||||
paste: false,
|
||||
sequence: char,
|
||||
kittyProtocol: true,
|
||||
},
|
||||
length: m[0].length,
|
||||
};
|
||||
}
|
||||
|
||||
// Ctrl+letters
|
||||
if (
|
||||
ctrl &&
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import {
|
|||
import { type SettingScope } from '../../config/settings.js';
|
||||
import { type CodingPlanRegion } from '../../constants/codingPlan.js';
|
||||
import type { AuthState } from '../types.js';
|
||||
import { type VisionSwitchOutcome } from '../components/ModelSwitchDialog.js';
|
||||
// OpenAICredentials type (previously imported from OpenAIKeyPrompt)
|
||||
export interface OpenAICredentials {
|
||||
apiKey: string;
|
||||
|
|
@ -67,9 +66,8 @@ export interface UIActions {
|
|||
onSuggestionsVisibilityChange: (visible: boolean) => void;
|
||||
refreshStatic: () => void;
|
||||
handleFinalSubmit: (value: string) => void;
|
||||
handleRetryLastPrompt: () => void;
|
||||
handleClearScreen: () => void;
|
||||
// Vision switch dialog
|
||||
handleVisionSwitchSelect: (outcome: VisionSwitchOutcome) => void;
|
||||
// Welcome back dialog
|
||||
handleWelcomeBackSelection: (choice: 'continue' | 'restart') => void;
|
||||
handleWelcomeBackClose: () => void;
|
||||
|
|
|
|||
|
|
@ -115,8 +115,6 @@ export interface UIState {
|
|||
extensionsUpdateState: Map<string, ExtensionUpdateState>;
|
||||
activePtyId: number | undefined;
|
||||
embeddedShellFocused: boolean;
|
||||
// Vision switch dialog
|
||||
isVisionSwitchDialogOpen: boolean;
|
||||
// Welcome back dialog
|
||||
showWelcomeBackDialog: boolean;
|
||||
welcomeBackInfo: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue