Skip to content

Commit c39f750

Browse files
committed
Add search capability to unstaged file selection in commit message generation flow
- on a quick pick of unstaged files, should allow 'search in the selected results' └── apps └── editor └── src ├── commands │ ├── generate-commit-message-commands │ │ ├── actions │ │ │ ├── get-prompt-data.ts │ │ │ └── run-generate-action.ts │ │ ├── generate-commit-message-commands.ts │ │ ├── index.ts │ │ └── utils │ │ ├── build-commit-message-prompt.ts │ │ ├── generate-commit-message-with-api.ts │ │ ├── get-commit-message-config.ts │ │ └── strip-wrapping-quotes.ts │ └── select-referencing-files-commands │ ├── index.ts │ ├── select-referencing-files-commands.ts │ └── utils │ ├── get-referencing-files-for-position.ts │ ├── get-referencing-files-for-uris.ts │ └── prompt-for-referencing-files.ts ├── extension.ts └── utils └── git-repository-utils.ts
1 parent 1bc2d67 commit c39f750

3 files changed

Lines changed: 106 additions & 56 deletions

File tree

‎apps/editor/src/commands/generate-commit-message-commands/actions/get-prompt-data.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ import { CommitMessageDetails } from '../../../utils/commit-message-details'
99
import { normalize_path } from '@/utils/normalize-path'
1010
import { WorkspaceProvider } from '@/context/providers/workspace/workspace-provider'
1111
import { FilesCollector } from '@/utils/files-collector'
12+
import { WebSocketManager } from '@/services/websocket-manager'
1213

1314
export const get_prompt_data = async (params: {
1415
repository: GitRepository
1516
stage_all_if_none_staged: boolean
1617
selection_state?: { files?: string[] }
1718
extension_context: vscode.ExtensionContext
1819
workspace_provider: WorkspaceProvider
20+
websocket_manager: WebSocketManager
1921
files_staged_by_action?: boolean
2022
is_single_change_flow?: boolean
2123
skip_context_prompt?: boolean
@@ -33,7 +35,10 @@ export const get_prompt_data = async (params: {
3335
const diff = await prepare_staged_changes({
3436
repository: params.repository,
3537
stage_all_if_none_staged: params.stage_all_if_none_staged,
36-
selection_state: params.selection_state
38+
selection_state: params.selection_state,
39+
workspace_provider: params.workspace_provider,
40+
extension_context: params.extension_context,
41+
websocket_manager: params.websocket_manager
3742
})
3843
if (!diff) return null
3944

‎apps/editor/src/commands/generate-commit-message-commands/actions/run-generate-action.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export const run_generate_action = async (params: {
6464
selection_state,
6565
extension_context: params.extension_context,
6666
workspace_provider: params.workspace_provider,
67+
websocket_manager: params.websocket_manager,
6768
files_staged_by_action,
6869
is_single_change_flow: files_staged_by_action
6970
? is_single_change_flow

‎apps/editor/src/utils/git-repository-utils.ts‎

Lines changed: 99 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import { t } from '@/i18n'
66
import { MAX_FILE_TOKENS_FOR_COMMIT_MESSAGE } from '@/constants/values'
77
import { PromptBuilder } from './prompt-builder'
88
import { display_token_count } from '@shared/utils/display-token-count'
9+
import { WorkspaceProvider } from '@/context/providers/workspace/workspace-provider'
10+
import { WebSocketManager } from '@/services/websocket-manager'
11+
import { search_files } from '@/features/search-files'
912

1013
export type GitRepository = {
1114
rootUri: vscode.Uri
@@ -210,6 +213,9 @@ export const prepare_staged_changes = async (params: {
210213
repository: GitRepository
211214
stage_all_if_none_staged?: boolean
212215
selection_state?: { files?: string[] }
216+
workspace_provider?: WorkspaceProvider
217+
extension_context?: vscode.ExtensionContext
218+
websocket_manager?: WebSocketManager
213219
}): Promise<string | null> => {
214220
await params.repository.status()
215221
const staged_changes = params.repository.state.indexChanges || []
@@ -349,76 +355,114 @@ export const prepare_staged_changes = async (params: {
349355
})
350356
)
351357

352-
const selected = await new Promise<any[] | undefined>((resolve) => {
353-
const quick_pick = vscode.window.createQuickPick<any>()
354-
quick_pick.items = items
358+
let current_selected_fs_paths = params.selection_state?.files || items.map((i) => i.fsPath)
355359

356-
if (params.selection_state?.files) {
357-
quick_pick.selectedItems = items.filter((i) =>
358-
params.selection_state!.files!.includes(i.fsPath)
359-
)
360-
} else {
361-
quick_pick.selectedItems = items
362-
}
360+
while (true) {
361+
const selected = await new Promise<any[] | undefined | 'search'>((resolve) => {
362+
const quick_pick = vscode.window.createQuickPick<any>()
363+
quick_pick.items = items
364+
quick_pick.selectedItems = items.filter((i) => current_selected_fs_paths.includes(i.fsPath))
363365

364-
quick_pick.canSelectMany = true
365-
quick_pick.matchOnDescription = true
366-
quick_pick.title = t('command.generate-commit-message.unstaged-files')
367-
quick_pick.placeholder = t(
368-
'command.generate-commit-message.select-files'
369-
)
370-
quick_pick.ignoreFocusOut = true
371-
quick_pick.buttons = [
372-
{
366+
quick_pick.canSelectMany = true
367+
quick_pick.matchOnDescription = true
368+
quick_pick.title = t('command.generate-commit-message.unstaged-files')
369+
quick_pick.placeholder = t('command.generate-commit-message.select-files')
370+
quick_pick.ignoreFocusOut = true
371+
372+
const close_button = {
373373
iconPath: new vscode.ThemeIcon('close'),
374374
tooltip: t('common.close')
375375
}
376-
]
376+
const search_button = {
377+
iconPath: new vscode.ThemeIcon('search'),
378+
tooltip: t('common.search-in-selected-results')
379+
}
377380

378-
quick_pick.onDidTriggerButton((button) => {
379-
if (button.tooltip == t('common.close')) {
380-
resolve(undefined)
381+
quick_pick.buttons = params.workspace_provider && params.extension_context && params.websocket_manager
382+
? [search_button, close_button]
383+
: [close_button]
384+
385+
quick_pick.onDidTriggerButton((button) => {
386+
if (button.tooltip == t('common.close')) {
387+
resolve(undefined)
388+
quick_pick.hide()
389+
} else if (button.tooltip == t('common.search-in-selected-results')) {
390+
current_selected_fs_paths = Array.from(quick_pick.selectedItems).map((i: any) => i.fsPath)
391+
if (current_selected_fs_paths.length == 0) {
392+
vscode.window.showInformationMessage(t('common.info.select-files-to-search'))
393+
return
394+
}
395+
resolve('search')
396+
quick_pick.hide()
397+
}
398+
})
399+
400+
quick_pick.onDidTriggerItemButton(async (event) => {
401+
if (event.button.tooltip == t('common.go-to-file')) {
402+
const uri = vscode.Uri.file(event.item.fsPath)
403+
vscode.window.showTextDocument(uri, { preview: true })
404+
} else if (event.button.tooltip == t('command.generate-commit-message.show-diff')) {
405+
const uri = vscode.Uri.file(event.item.fsPath)
406+
await vscode.commands.executeCommand('git.openChange', uri)
407+
}
408+
})
409+
410+
quick_pick.onDidAccept(() => {
411+
const selected_items = Array.from(quick_pick.selectedItems)
412+
current_selected_fs_paths = selected_items.map((i: any) => i.fsPath)
413+
resolve(selected_items)
381414
quick_pick.hide()
382-
}
383-
})
415+
})
384416

385-
quick_pick.onDidTriggerItemButton(async (event) => {
386-
if (event.button.tooltip == t('common.go-to-file')) {
387-
const uri = vscode.Uri.file(event.item.fsPath)
388-
vscode.window.showTextDocument(uri, { preview: true })
389-
} else if (
390-
event.button.tooltip ==
391-
t('command.generate-commit-message.show-diff')
392-
) {
393-
const uri = vscode.Uri.file(event.item.fsPath)
394-
await vscode.commands.executeCommand('git.openChange', uri)
395-
}
417+
quick_pick.onDidHide(() => {
418+
resolve(undefined)
419+
quick_pick.dispose()
420+
})
421+
422+
quick_pick.show()
396423
})
397424

398-
quick_pick.onDidAccept(() => {
399-
const selected_items = Array.from(quick_pick.selectedItems)
400-
if (params.selection_state) {
401-
params.selection_state.files = selected_items.map(
402-
(i: any) => i.fsPath
403-
)
425+
if (!selected) {
426+
return null
427+
}
428+
429+
if (selected === 'search') {
430+
if (!params.workspace_provider || !params.extension_context || !params.websocket_manager) {
431+
continue
404432
}
405-
resolve(selected_items)
406-
quick_pick.hide()
407-
})
408433

409-
quick_pick.onDidHide(() => {
410-
resolve(undefined)
411-
quick_pick.dispose()
412-
})
434+
const search_result = await search_files({
435+
get_files: async () => current_selected_fs_paths,
436+
workspace_provider: params.workspace_provider,
437+
extension_context: params.extension_context,
438+
websocket_manager: params.websocket_manager,
439+
show_back_button: true
440+
})
413441

414-
quick_pick.show()
415-
})
442+
if (search_result === 'back') {
443+
continue
444+
}
416445

417-
if (!selected || selected.length == 0) {
418-
return null
419-
}
446+
if (!search_result || search_result.selected_paths.length === 0) {
447+
return null
448+
}
420449

421-
files_to_stage = selected.map((item) => item.fsPath)
450+
files_to_stage = search_result.selected_paths
451+
if (params.selection_state) {
452+
params.selection_state.files = files_to_stage
453+
}
454+
break
455+
} else {
456+
if (selected.length === 0) {
457+
return null
458+
}
459+
files_to_stage = selected.map((item) => item.fsPath)
460+
if (params.selection_state) {
461+
params.selection_state.files = files_to_stage
462+
}
463+
break
464+
}
465+
}
422466
}
423467

424468
const file_args = files_to_stage

0 commit comments

Comments
 (0)