mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-21 01:07:46 +00:00
Fix CLI interactivity issue by eliminating multiple useKeypress hook conflicts
Co-authored-by: pomelo-nwu <10703060+pomelo-nwu@users.noreply.github.com>
This commit is contained in:
@@ -8,7 +8,6 @@ import { ToolConfirmationOutcome } from '@qwen-code/qwen-code-core';
|
|||||||
import { Box, Text } from 'ink';
|
import { Box, Text } from 'ink';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Colors } from '../colors.js';
|
import { Colors } from '../colors.js';
|
||||||
import { useKeypress } from '../hooks/useKeypress.js';
|
|
||||||
import {
|
import {
|
||||||
RadioButtonSelect,
|
RadioButtonSelect,
|
||||||
RadioSelectItem,
|
RadioSelectItem,
|
||||||
@@ -31,15 +30,6 @@ export const ShellConfirmationDialog: React.FC<
|
|||||||
> = ({ request }) => {
|
> = ({ request }) => {
|
||||||
const { commands, onConfirm } = request;
|
const { commands, onConfirm } = request;
|
||||||
|
|
||||||
useKeypress(
|
|
||||||
(key) => {
|
|
||||||
if (key.name === 'escape') {
|
|
||||||
onConfirm(ToolConfirmationOutcome.Cancel);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ isActive: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleSelect = (item: ToolConfirmationOutcome) => {
|
const handleSelect = (item: ToolConfirmationOutcome) => {
|
||||||
if (item === ToolConfirmationOutcome.Cancel) {
|
if (item === ToolConfirmationOutcome.Cancel) {
|
||||||
onConfirm(item);
|
onConfirm(item);
|
||||||
@@ -50,6 +40,10 @@ export const ShellConfirmationDialog: React.FC<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleEscape = () => {
|
||||||
|
onConfirm(ToolConfirmationOutcome.Cancel);
|
||||||
|
};
|
||||||
|
|
||||||
const options: Array<RadioSelectItem<ToolConfirmationOutcome>> = [
|
const options: Array<RadioSelectItem<ToolConfirmationOutcome>> = [
|
||||||
{
|
{
|
||||||
label: 'Yes, allow once',
|
label: 'Yes, allow once',
|
||||||
@@ -96,7 +90,12 @@ export const ShellConfirmationDialog: React.FC<
|
|||||||
<Text>Do you want to proceed?</Text>
|
<Text>Do you want to proceed?</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<RadioButtonSelect items={options} onSelect={handleSelect} isFocused />
|
<RadioButtonSelect
|
||||||
|
items={options}
|
||||||
|
onSelect={handleSelect}
|
||||||
|
onEscape={handleEscape}
|
||||||
|
isFocused
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import {
|
|||||||
RadioSelectItem,
|
RadioSelectItem,
|
||||||
} from '../shared/RadioButtonSelect.js';
|
} from '../shared/RadioButtonSelect.js';
|
||||||
import { MaxSizedBox } from '../shared/MaxSizedBox.js';
|
import { MaxSizedBox } from '../shared/MaxSizedBox.js';
|
||||||
import { useKeypress } from '../../hooks/useKeypress.js';
|
|
||||||
|
|
||||||
export interface ToolConfirmationMessageProps {
|
export interface ToolConfirmationMessageProps {
|
||||||
confirmationDetails: ToolCallConfirmationDetails;
|
confirmationDetails: ToolCallConfirmationDetails;
|
||||||
@@ -57,18 +56,11 @@ export const ToolConfirmationMessage: React.FC<
|
|||||||
onConfirm(outcome);
|
onConfirm(outcome);
|
||||||
};
|
};
|
||||||
|
|
||||||
useKeypress(
|
|
||||||
(key) => {
|
|
||||||
if (!isFocused) return;
|
|
||||||
if (key.name === 'escape' || (key.ctrl && key.name === 'c')) {
|
|
||||||
handleConfirm(ToolConfirmationOutcome.Cancel);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ isActive: isFocused },
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleSelect = (item: ToolConfirmationOutcome) => handleConfirm(item);
|
const handleSelect = (item: ToolConfirmationOutcome) => handleConfirm(item);
|
||||||
|
|
||||||
|
const handleEscape = () => handleConfirm(ToolConfirmationOutcome.Cancel);
|
||||||
|
const handleCancel = () => handleConfirm(ToolConfirmationOutcome.Cancel);
|
||||||
|
|
||||||
let bodyContent: React.ReactNode | null = null; // Removed contextDisplay here
|
let bodyContent: React.ReactNode | null = null; // Removed contextDisplay here
|
||||||
let question: string;
|
let question: string;
|
||||||
|
|
||||||
@@ -283,6 +275,8 @@ export const ToolConfirmationMessage: React.FC<
|
|||||||
<RadioButtonSelect
|
<RadioButtonSelect
|
||||||
items={options}
|
items={options}
|
||||||
onSelect={handleSelect}
|
onSelect={handleSelect}
|
||||||
|
onEscape={handleEscape}
|
||||||
|
onCancel={handleCancel}
|
||||||
isFocused={isFocused}
|
isFocused={isFocused}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ export interface RadioButtonSelectProps<T> {
|
|||||||
onSelect: (value: T) => void;
|
onSelect: (value: T) => void;
|
||||||
/** Function called when an item is highlighted. Receives the `value` of the selected item. */
|
/** Function called when an item is highlighted. Receives the `value` of the selected item. */
|
||||||
onHighlight?: (value: T) => void;
|
onHighlight?: (value: T) => void;
|
||||||
|
/** Function called when escape key is pressed. */
|
||||||
|
onEscape?: () => void;
|
||||||
|
/** Function called when Ctrl+C is pressed. */
|
||||||
|
onCancel?: () => void;
|
||||||
/** Whether this select input is currently focused and should respond to input. */
|
/** Whether this select input is currently focused and should respond to input. */
|
||||||
isFocused?: boolean;
|
isFocused?: boolean;
|
||||||
/** Whether to show the scroll arrows. */
|
/** Whether to show the scroll arrows. */
|
||||||
@@ -55,6 +59,8 @@ export function RadioButtonSelect<T>({
|
|||||||
initialIndex = 0,
|
initialIndex = 0,
|
||||||
onSelect,
|
onSelect,
|
||||||
onHighlight,
|
onHighlight,
|
||||||
|
onEscape,
|
||||||
|
onCancel,
|
||||||
isFocused,
|
isFocused,
|
||||||
showScrollArrows = false,
|
showScrollArrows = false,
|
||||||
maxItemsToShow = 10,
|
maxItemsToShow = 10,
|
||||||
@@ -91,6 +97,18 @@ export function RadioButtonSelect<T>({
|
|||||||
const { sequence, name } = key;
|
const { sequence, name } = key;
|
||||||
const isNumeric = showNumbers && /^[0-9]$/.test(sequence);
|
const isNumeric = showNumbers && /^[0-9]$/.test(sequence);
|
||||||
|
|
||||||
|
// Handle escape key
|
||||||
|
if (name === 'escape') {
|
||||||
|
onEscape?.();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Ctrl+C
|
||||||
|
if (key.ctrl && name === 'c') {
|
||||||
|
onCancel?.();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Any key press that is not a digit should clear the number input buffer.
|
// Any key press that is not a digit should clear the number input buffer.
|
||||||
if (!isNumeric && numberInputTimer.current) {
|
if (!isNumeric && numberInputTimer.current) {
|
||||||
clearTimeout(numberInputTimer.current);
|
clearTimeout(numberInputTimer.current);
|
||||||
|
|||||||
Reference in New Issue
Block a user