@@ -5,20 +5,26 @@ import { WorkspaceProvider } from '../../../context/providers/workspace/workspac
55import { display_token_count } from '../../../utils/display-token-count'
66import { FileAnalysisResult } from './analyze-workspace-files'
77import { t } from '@/i18n'
8+ import { dictionary } from '@shared/constants/dictionary'
9+ import { LAST_FIND_RELEVANT_FILES_MERGE_REPLACE_OPTION_STATE_KEY } from '../../../constants/state-keys'
810
911export const show_results_and_apply = async ( params : {
1012 extracted_files : string [ ]
1113 analysis : FileAnalysisResult
1214 workspace_provider : WorkspaceProvider
15+ extension_context : vscode . ExtensionContext
1316} ) : Promise < 'success' | 'back' | 'cancel' > => {
14- const currently_checked = params . workspace_provider . get_checked_files ( )
1517 const absolute_paths : string [ ] = [ ]
1618
1719 for ( const rel_path of params . extracted_files ) {
1820 const potential_abs = path . join ( params . analysis . workspace_root , rel_path )
1921 if ( fs . existsSync ( potential_abs ) ) absolute_paths . push ( potential_abs )
2022 }
2123
24+ const files_in_searched_folder = params . analysis . files_data . map (
25+ ( f ) => f . file_path
26+ )
27+
2228 const close_button = {
2329 iconPath : new vscode . ThemeIcon ( 'close' ) ,
2430 tooltip : t ( 'common.close' )
@@ -51,88 +57,203 @@ export const show_results_and_apply = async (params: {
5157 } )
5258 )
5359
54- const quick_pick = vscode . window . createQuickPick <
55- vscode . QuickPickItem & { file_path : string }
56- > ( )
57- quick_pick . items = quick_pick_items
58- quick_pick . selectedItems = quick_pick_items . filter ( ( item ) =>
59- currently_checked . includes ( item . file_path )
60- )
61- quick_pick . canSelectMany = true
62- quick_pick . title = t ( 'command.find-relevant-files.quick-pick.title' )
63- quick_pick . placeholder = t (
64- 'command.find-relevant-files.quick-pick.placeholder'
65- )
66- quick_pick . ignoreFocusOut = true
67- quick_pick . buttons = [ vscode . QuickInputButtons . Back , close_button ]
60+ while ( true ) {
61+ const currently_checked = params . workspace_provider . get_checked_files ( )
6862
69- return new Promise < 'success' | 'back' | 'cancel' > ( ( resolve ) => {
70- let is_resolved = false
63+ const quick_pick = vscode . window . createQuickPick <
64+ vscode . QuickPickItem & { file_path : string }
65+ > ( )
66+ quick_pick . items = quick_pick_items
67+ quick_pick . selectedItems = quick_pick_items . filter ( ( item ) =>
68+ currently_checked . includes ( item . file_path )
69+ )
70+ quick_pick . canSelectMany = true
71+ quick_pick . title = t ( 'command.find-relevant-files.quick-pick.title' )
72+ quick_pick . placeholder = t (
73+ 'command.find-relevant-files.quick-pick.placeholder'
74+ )
75+ quick_pick . ignoreFocusOut = true
76+ quick_pick . buttons = [ vscode . QuickInputButtons . Back , close_button ]
7177
72- quick_pick . onDidTriggerButton ( ( button ) => {
73- if ( button === vscode . QuickInputButtons . Back ) {
74- is_resolved = true
75- resolve ( 'back' )
76- quick_pick . hide ( )
77- } else if ( button === close_button ) {
78+ const list_selection = await new Promise <
79+ | readonly ( vscode . QuickPickItem & { file_path : string } ) [ ]
80+ | 'back'
81+ | 'cancel'
82+ > ( ( resolve ) => {
83+ let is_resolved = false
84+
85+ quick_pick . onDidTriggerButton ( ( button ) => {
86+ if ( button === vscode . QuickInputButtons . Back ) {
87+ is_resolved = true
88+ resolve ( 'back' )
89+ quick_pick . hide ( )
90+ } else if ( button === close_button ) {
91+ is_resolved = true
92+ resolve ( 'cancel' )
93+ quick_pick . hide ( )
94+ }
95+ } )
96+
97+ quick_pick . onDidAccept ( ( ) => {
7898 is_resolved = true
79- resolve ( 'cancel' )
99+ resolve ( quick_pick . selectedItems )
80100 quick_pick . hide ( )
81- }
101+ } )
102+
103+ quick_pick . onDidTriggerItemButton ( async ( e ) => {
104+ if ( e . button === open_file_button ) {
105+ try {
106+ const doc = await vscode . workspace . openTextDocument (
107+ e . item . file_path
108+ )
109+ await vscode . window . showTextDocument ( doc , { preview : true } )
110+ } catch ( error ) {
111+ vscode . window . showErrorMessage (
112+ t ( 'command.find-relevant-files.error.opening-file' , {
113+ error : String ( error )
114+ } )
115+ )
116+ }
117+ }
118+ } )
119+
120+ quick_pick . onDidHide ( ( ) => {
121+ if ( ! is_resolved ) {
122+ resolve ( 'back' )
123+ }
124+ quick_pick . dispose ( )
125+ } )
126+
127+ quick_pick . show ( )
82128 } )
83129
84- quick_pick . onDidAccept ( async ( ) => {
85- is_resolved = true
86- const selected_paths = quick_pick . selectedItems . map (
87- ( item ) => item . file_path
88- )
89- const unchecked_paths = absolute_paths . filter (
90- ( file_path ) => ! selected_paths . includes ( file_path )
91- )
130+ if ( list_selection === 'back' || list_selection === 'cancel' ) {
131+ return list_selection
132+ }
133+
134+ const selected_paths = list_selection . map ( ( item ) => item . file_path )
135+ const unchecked_paths = absolute_paths . filter (
136+ ( file_path ) => ! selected_paths . includes ( file_path )
137+ )
138+
139+ let paths_to_apply : string [ ] = [ ]
140+ let should_continue_loop = false
141+
142+ const currently_checked_in_folder = currently_checked . filter ( ( f ) =>
143+ files_in_searched_folder . includes ( f )
144+ )
92145
93- const paths_to_apply = [
94- ...new Set ( [
95- ...currently_checked . filter ( ( p ) => ! unchecked_paths . includes ( p ) ) ,
96- ...selected_paths
97- ] )
146+ if ( currently_checked_in_folder . length > 0 ) {
147+ const selected_paths_set = new Set ( selected_paths )
148+ const is_identical =
149+ currently_checked_in_folder . length == selected_paths_set . size &&
150+ currently_checked_in_folder . every ( ( file ) =>
151+ selected_paths_set . has ( file )
152+ )
153+
154+ if ( is_identical ) {
155+ vscode . window . showInformationMessage (
156+ dictionary . information_message . CONTEXT_ALREADY_SET
157+ )
158+ return 'success'
159+ }
160+
161+ const quick_pick_options = [
162+ {
163+ label : t ( 'command.apply-context.action.replace.label' ) ,
164+ description : t ( 'command.apply-context.action.replace.description' )
165+ } ,
166+ {
167+ label : t ( 'command.apply-context.action.merge.label' ) ,
168+ description : t ( 'command.apply-context.action.merge.description' )
169+ }
98170 ]
99- await params . workspace_provider . set_checked_files ( paths_to_apply )
100-
101- const newly_selected_count = selected_paths . filter (
102- ( p ) => ! currently_checked . includes ( p )
103- ) . length
104- vscode . window . showInformationMessage (
105- t ( 'command.find-relevant-files.success.added' , {
106- count : newly_selected_count
107- } )
108- )
109171
110- resolve ( 'success' )
111- quick_pick . hide ( )
112- } )
172+ const last_choice_label =
173+ params . extension_context . workspaceState . get < string > (
174+ LAST_FIND_RELEVANT_FILES_MERGE_REPLACE_OPTION_STATE_KEY
175+ )
176+
177+ const quick_pick_merge = vscode . window . createQuickPick ( )
178+ quick_pick_merge . items = quick_pick_options
179+ quick_pick_merge . placeholder = t ( 'command.apply-context.unstaged.apply' , {
180+ count : selected_paths . length
181+ } )
182+ quick_pick_merge . buttons = [ vscode . QuickInputButtons . Back ]
113183
114- quick_pick . onDidTriggerItemButton ( async ( e ) => {
115- if ( e . button === open_file_button ) {
116- try {
117- const doc = await vscode . workspace . openTextDocument ( e . item . file_path )
118- await vscode . window . showTextDocument ( doc , { preview : true } )
119- } catch ( error ) {
120- vscode . window . showErrorMessage (
121- t ( 'command.find-relevant-files.error.opening-file' , {
122- error : String ( error )
123- } )
124- )
184+ if ( last_choice_label ) {
185+ const active_item = quick_pick_options . find (
186+ ( opt ) => opt . label === last_choice_label
187+ )
188+ if ( active_item ) {
189+ quick_pick_merge . activeItems = [ active_item ]
125190 }
126191 }
127- } )
128192
129- quick_pick . onDidHide ( ( ) => {
130- if ( ! is_resolved ) {
131- resolve ( 'back' )
193+ const choice = await new Promise <
194+ vscode . QuickPickItem | 'back' | undefined
195+ > ( ( resolve_choice ) => {
196+ let is_accepted = false
197+ quick_pick_merge . onDidTriggerButton ( ( button ) => {
198+ if ( button === vscode . QuickInputButtons . Back ) {
199+ resolve_choice ( 'back' )
200+ quick_pick_merge . hide ( )
201+ }
202+ } )
203+ quick_pick_merge . onDidAccept ( ( ) => {
204+ is_accepted = true
205+ resolve_choice ( quick_pick_merge . selectedItems [ 0 ] )
206+ quick_pick_merge . hide ( )
207+ } )
208+ quick_pick_merge . onDidHide ( ( ) => {
209+ if ( ! is_accepted ) resolve_choice ( 'back' )
210+ quick_pick_merge . dispose ( )
211+ } )
212+ quick_pick_merge . show ( )
213+ } )
214+
215+ if ( choice === 'back' ) {
216+ should_continue_loop = true
217+ } else if ( ! choice ) {
218+ return 'cancel'
219+ } else {
220+ await params . extension_context . workspaceState . update (
221+ LAST_FIND_RELEVANT_FILES_MERGE_REPLACE_OPTION_STATE_KEY ,
222+ choice . label
223+ )
224+
225+ if ( choice . label == t ( 'command.apply-context.action.merge.label' ) ) {
226+ paths_to_apply = [
227+ ...new Set ( [
228+ ...currently_checked . filter ( ( p ) => ! unchecked_paths . includes ( p ) ) ,
229+ ...selected_paths
230+ ] )
231+ ]
232+ } else {
233+ paths_to_apply = [
234+ ...new Set ( [
235+ ...currently_checked . filter (
236+ ( p ) => ! files_in_searched_folder . includes ( p )
237+ ) ,
238+ ...selected_paths
239+ ] )
240+ ]
241+ }
132242 }
133- quick_pick . dispose ( )
134- } )
243+ } else {
244+ paths_to_apply = [ ...new Set ( [ ...currently_checked , ...selected_paths ] ) ]
245+ }
246+
247+ if ( should_continue_loop ) {
248+ continue
249+ }
250+
251+ await params . workspace_provider . set_checked_files ( paths_to_apply )
135252
136- quick_pick . show ( )
137- } )
253+ vscode . window . showInformationMessage (
254+ t ( 'command.find-relevant-files.success.added' )
255+ )
256+
257+ return 'success'
258+ }
138259}
0 commit comments