Skip to content

Commit 4e5c0e6

Browse files
committed
Add functionality to trigger preset selection on submit with control key
1 parent e153c3f commit 4e5c0e6

3 files changed

Lines changed: 41 additions & 52 deletions

File tree

packages/ui/src/components/editor/ChatInput/ChatInput.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type Props = {
99
chat_history_fim_mode: string[]
1010
on_change: (value: string) => void
1111
on_submit: () => void
12+
on_submit_with_control: () => void
1213
on_copy: () => void
1314
token_count?: number
1415
is_connected: boolean
@@ -87,14 +88,22 @@ export const ChatInput: React.FC<Props> = (props) => {
8788
}
8889
}
8990

90-
const handle_submit = (e?: React.MouseEvent<HTMLButtonElement>) => {
91-
e?.stopPropagation()
91+
const handle_submit = (
92+
e:
93+
| React.KeyboardEvent<HTMLTextAreaElement>
94+
| React.MouseEvent<HTMLButtonElement>
95+
) => {
96+
e.stopPropagation()
9297
if (
9398
!props.is_connected ||
9499
(!props.is_in_code_completions_mode && !props.value)
95100
)
96101
return
97-
props.on_submit()
102+
if (e.ctrlKey || e.metaKey) {
103+
props.on_submit_with_control()
104+
} else {
105+
props.on_submit()
106+
}
98107
set_history_index(-1) // Reset history index after submitting
99108
}
100109

@@ -126,7 +135,7 @@ export const ChatInput: React.FC<Props> = (props) => {
126135
}, 0)
127136
} else if (e.key == 'Enter' && !e.shiftKey) {
128137
e.preventDefault()
129-
handle_submit()
138+
handle_submit(e)
130139
} else if (
131140
(e.key == 'ArrowUp' || e.key == 'ArrowDown') &&
132141
is_history_enabled
@@ -301,7 +310,12 @@ export const ChatInput: React.FC<Props> = (props) => {
301310
!props.is_connected ||
302311
(!props.is_in_code_completions_mode && !props.value)
303312
}
304-
title={props.submit_disabled_title || 'Send'}
313+
title={
314+
!props.is_connected ||
315+
(!props.is_in_code_completions_mode && !props.value)
316+
? props.submit_disabled_title
317+
: 'Send'
318+
}
305319
>
306320
<div className={cn('codicon', 'codicon-send')} />
307321
</button>

packages/vscode/src/view/backend/message-handlers/handle-send-prompt.ts

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import { apply_preset_affixes_to_instruction } from '@/helpers/apply-preset-affi
66

77
async function validate_presets(
88
preset_names: string[],
9-
is_code_completions_mode: boolean,
10-
context: vscode.ExtensionContext
9+
is_code_completions_mode: boolean
1110
): Promise<string[]> {
1211
const config = vscode.workspace.getConfiguration('codeWebChat')
1312
const presets = config.get<any[]>('presets', [])
@@ -28,31 +27,21 @@ async function validate_presets(
2827
const preset_quick_pick_items = available_presets.map((preset) => ({
2928
label: preset.name,
3029
description: `${preset.chatbot}${
31-
preset.model ? ` - ${preset.model}` : ''
30+
preset.model ? ` ${preset.model}` : ''
3231
}`,
3332
picked: false
3433
}))
3534

36-
const placeholder = !is_code_completions_mode
37-
? 'Select one or more presets'
38-
: 'Select one or more presets to use when asking for code completions'
39-
40-
const selected_presets = await vscode.window.showQuickPick(
35+
const selected_preset = await vscode.window.showQuickPick(
4136
preset_quick_pick_items,
4237
{
43-
placeHolder: placeholder,
44-
canPickMany: true
38+
placeHolder: 'Select preset'
4539
}
4640
)
4741

48-
if (selected_presets) {
49-
const selected_names = selected_presets.map((preset) => preset.label)
50-
const selected_names_key = is_code_completions_mode
51-
? 'selectedCodeCompletionPresets'
52-
: 'selectedPresets'
53-
await context.globalState.update(selected_names_key, selected_names)
54-
55-
return selected_names
42+
if (selected_preset) {
43+
const selected_name = selected_preset.label
44+
return [selected_name]
5645
}
5746
return []
5847
}
@@ -64,20 +53,12 @@ export const handle_send_prompt = async (
6453
provider: ViewProvider,
6554
preset_names: string[]
6655
): Promise<void> => {
67-
// Validate presets first
6856
const valid_preset_names = await validate_presets(
6957
preset_names,
70-
provider.is_code_completions_mode,
71-
provider.context
58+
provider.is_code_completions_mode
7259
)
7360

74-
// If no presets were selected in the picker
75-
if (valid_preset_names.length == 0) {
76-
vscode.window.showInformationMessage(
77-
'Please select at least one preset to continue.'
78-
)
79-
return
80-
}
61+
if (valid_preset_names.length == 0) return
8162

8263
await vscode.workspace.saveAll()
8364

@@ -126,12 +107,7 @@ export const handle_send_prompt = async (
126107
valid_preset_names
127108
)
128109
} else if (!provider.is_code_completions_mode) {
129-
if (!provider.instructions) {
130-
vscode.window.showInformationMessage(
131-
'Please enter instructions.'
132-
)
133-
return
134-
}
110+
if (!provider.instructions) return
135111

136112
const context_text = await files_collector.collect_files({
137113
active_path
@@ -144,7 +120,6 @@ export const handle_send_prompt = async (
144120
valid_preset_names
145121
)
146122

147-
// Use the stored edit_format property
148123
const config = vscode.workspace.getConfiguration('codeWebChat')
149124
const edit_format_instructions = config.get<string>(
150125
`editFormatInstructions${

packages/vscode/src/view/frontend/tabs/chat/Main/Main.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,28 +48,21 @@ export const Main: React.FC<Props> = (props) => {
4848
? props.code_completion_suggestions
4949
: props.normal_instructions
5050

51-
// Calculate input token estimation
5251
useEffect(() => {
5352
let estimated_tokens = 0
54-
// Basic estimation for instruction
5553
let text = current_prompt
5654

57-
// If there's @selection in the instruction and we have an active selection
5855
if (
5956
text.includes('@selection') &&
6057
props.has_active_selection &&
6158
props.selection_text
6259
) {
63-
// Approximate replacement
6460
text = text.replace(/@selection/g, props.selection_text)
6561
}
6662

67-
// Rough estimation of tokens (chars/4) for the instruction
6863
estimated_tokens = Math.ceil(text.length / 4)
6964

70-
// Add active file length tokens when in FIM mode
7165
if (props.is_in_code_completions_mode && props.active_file_length) {
72-
// Estimate tokens for the file content
7366
const file_tokens = Math.ceil(props.active_file_length / 4)
7467
estimated_tokens += file_tokens
7568
}
@@ -86,9 +79,9 @@ export const Main: React.FC<Props> = (props) => {
8679
const handle_input_change = (value: string) => {
8780
// Update the appropriate instruction based on current mode
8881
if (props.is_in_code_completions_mode) {
89-
props.set_code_completion_suggestions(value) // Use prop setter
82+
props.set_code_completion_suggestions(value)
9083
} else {
91-
props.set_normal_instructions(value) // Use prop setter
84+
props.set_normal_instructions(value)
9285
}
9386
}
9487

@@ -101,16 +94,22 @@ export const Main: React.FC<Props> = (props) => {
10194
})
10295
}
10396

97+
// Let user select a preset
98+
const handle_submit_with_control = async () => {
99+
props.initialize_chats({
100+
prompt: current_prompt,
101+
preset_names: []
102+
})
103+
}
104+
104105
const handle_copy = () => {
105106
props.copy_to_clipboard(current_prompt)
106107
}
107108

108109
const handle_preset_copy = (preset_name: string) => {
109-
// Get the preset by name
110110
const preset = props.presets.find((p) => p.name == preset_name)
111111

112112
if (preset) {
113-
// Apply prefix and suffix if they exist
114113
let modified_instruction = current_prompt
115114
if (preset.prompt_prefix) {
116115
modified_instruction = `${preset.prompt_prefix} ${modified_instruction}`
@@ -149,13 +148,14 @@ export const Main: React.FC<Props> = (props) => {
149148
chat_history_fim_mode={props.chat_history_fim_mode}
150149
on_change={handle_input_change}
151150
on_submit={handle_submit}
151+
on_submit_with_control={handle_submit_with_control}
152152
on_copy={handle_copy}
153153
is_connected={props.is_connected}
154154
token_count={total_token_count}
155155
submit_disabled_title={
156156
!props.is_connected
157157
? 'WebSocket connection not established. Please install the browser extension.'
158-
: 'Initialize chats'
158+
: 'Enter instructions'
159159
}
160160
is_in_code_completions_mode={props.is_in_code_completions_mode}
161161
has_active_selection={props.has_active_selection}

0 commit comments

Comments
 (0)