@@ -20,12 +20,23 @@ export const save_to_json_file = async (params: {
2020 workspace_provider : WorkspaceProvider
2121 extension_context : vscode . ExtensionContext
2222} ) : Promise < 'back' | void > => {
23- const { merged : file_contexts , context_to_roots } =
23+ let { merged : file_contexts , context_to_roots } =
2424 await load_and_merge_file_contexts ( )
2525 const LABEL_SAVE_NEW_CONTEXT = t (
2626 'command.context-restoration.save-new-context.label'
2727 )
2828
29+ const edit_button = {
30+ iconPath : new vscode . ThemeIcon ( 'edit' ) ,
31+ tooltip : t ( 'command.context-restoration.action.rename' )
32+ }
33+ const delete_button = {
34+ iconPath : new vscode . ThemeIcon ( 'trash' ) ,
35+ tooltip : t ( 'command.context-restoration.action.delete' )
36+ }
37+
38+ let name_to_highlight : string | undefined
39+
2940 while ( true ) {
3041 const items : any [ ] = [ ]
3142 items . push ( { label : LABEL_SAVE_NEW_CONTEXT } )
@@ -46,7 +57,8 @@ export const save_to_json_file = async (params: {
4657 items . push ( {
4758 label : context . name ,
4859 description,
49- context
60+ context,
61+ buttons : [ edit_button , delete_button ]
5062 } )
5163 }
5264 }
@@ -57,12 +69,38 @@ export const save_to_json_file = async (params: {
5769 quick_pick . items = items
5870 quick_pick . buttons = [ vscode . QuickInputButtons . Back ]
5971
72+ if ( name_to_highlight ) {
73+ const active_item = quick_pick . items . find (
74+ ( i : any ) => i . label == name_to_highlight
75+ )
76+ if ( active_item ) quick_pick . activeItems = [ active_item ]
77+ name_to_highlight = undefined
78+ }
79+
6080 const selection = await new Promise < any > ( ( resolve ) => {
81+ let is_resolved = false
82+ const resolve_once = ( val : any ) => {
83+ if ( ! is_resolved ) {
84+ is_resolved = true
85+ resolve ( val )
86+ }
87+ }
88+
6189 quick_pick . onDidTriggerButton ( ( btn ) => {
62- if ( btn === vscode . QuickInputButtons . Back ) resolve ( 'back' )
90+ if ( btn === vscode . QuickInputButtons . Back ) {
91+ quick_pick . hide ( )
92+ resolve_once ( 'back' )
93+ }
94+ } )
95+ quick_pick . onDidTriggerItemButton ( ( e ) => {
96+ quick_pick . hide ( )
97+ resolve_once ( { ...e . item , triggeredButton : e . button } )
6398 } )
64- quick_pick . onDidAccept ( ( ) => resolve ( quick_pick . selectedItems [ 0 ] ) )
65- quick_pick . onDidHide ( ( ) => resolve ( undefined ) )
99+ quick_pick . onDidAccept ( ( ) => {
100+ quick_pick . hide ( )
101+ resolve_once ( quick_pick . selectedItems [ 0 ] )
102+ } )
103+ quick_pick . onDidHide ( ( ) => resolve_once ( undefined ) )
66104 quick_pick . show ( )
67105 } )
68106
@@ -71,6 +109,102 @@ export const save_to_json_file = async (params: {
71109 if ( ! selection ) return
72110 if ( selection === 'back' ) return 'back'
73111
112+ if ( selection . triggeredButton ) {
113+ const item = selection
114+ const old_name = item . context . name
115+
116+ if ( selection . triggeredButton === edit_button ) {
117+ const input_box = vscode . window . createInputBox ( )
118+ input_box . title = t ( 'command.context-restoration.rename.title' )
119+ input_box . prompt = t ( 'command.context-restoration.rename.prompt' )
120+ input_box . value = old_name
121+ const new_name = await new Promise < string | undefined > ( ( resolve ) => {
122+ let accepted = false
123+ const disposables : vscode . Disposable [ ] = [ ]
124+ const validate = ( value : string ) => {
125+ const trimmed = value . trim ( )
126+ if ( ! trimmed ) {
127+ input_box . validationMessage = t (
128+ 'command.context-restoration.rename.empty'
129+ )
130+ return false
131+ }
132+ if (
133+ file_contexts . find (
134+ ( c ) => c . name === trimmed && c . name !== old_name
135+ )
136+ ) {
137+ input_box . validationMessage = t (
138+ 'command.context-restoration.rename.exists'
139+ )
140+ return false
141+ }
142+ input_box . validationMessage = ''
143+ return true
144+ }
145+ disposables . push (
146+ input_box . onDidChangeValue ( validate ) ,
147+ input_box . onDidAccept ( ( ) => {
148+ if ( ! validate ( input_box . value ) ) return
149+ accepted = true
150+ resolve ( input_box . value . trim ( ) )
151+ input_box . hide ( )
152+ } ) ,
153+ input_box . onDidHide ( ( ) => {
154+ if ( ! accepted ) resolve ( undefined )
155+ disposables . forEach ( ( d ) => d . dispose ( ) )
156+ input_box . dispose ( )
157+ } )
158+ )
159+ input_box . show ( )
160+ } )
161+
162+ if ( new_name && new_name !== old_name ) {
163+ const roots_to_update = context_to_roots . get ( old_name ) || [ ]
164+ for ( const root of roots_to_update ) {
165+ const p = get_contexts_file_path ( root )
166+ let contexts = load_contexts_from_file ( p )
167+ let changed = false
168+ contexts = contexts . map ( ( c ) => {
169+ if ( c . name === old_name ) {
170+ changed = true
171+ return { ...c , name : new_name }
172+ }
173+ return c
174+ } )
175+ if ( changed ) await save_contexts_to_file ( { contexts, file_path : p } )
176+ }
177+ const reloaded = await load_and_merge_file_contexts ( )
178+ file_contexts = reloaded . merged
179+ context_to_roots = reloaded . context_to_roots
180+ }
181+ name_to_highlight =
182+ new_name && new_name != old_name ? new_name : old_name
183+ } else if ( selection . triggeredButton === delete_button ) {
184+ const choice = await vscode . window . showInformationMessage (
185+ t ( 'command.context-restoration.delete.prompt' , { name : old_name } ) ,
186+ { modal : true } ,
187+ t ( 'command.context-restoration.delete.action' )
188+ )
189+
190+ if ( choice == t ( 'command.context-restoration.delete.action' ) ) {
191+ const roots_to_update = context_to_roots . get ( old_name ) || [ ]
192+ for ( const root of roots_to_update ) {
193+ const p = get_contexts_file_path ( root )
194+ let contexts = load_contexts_from_file ( p )
195+ const original_len = contexts . length
196+ contexts = contexts . filter ( ( c ) => c . name !== old_name )
197+ if ( contexts . length !== original_len )
198+ await save_contexts_to_file ( { contexts, file_path : p } )
199+ }
200+ const reloaded = await load_and_merge_file_contexts ( )
201+ file_contexts = reloaded . merged
202+ context_to_roots = reloaded . context_to_roots
203+ }
204+ }
205+ continue
206+ }
207+
74208 const checked_files = params . workspace_provider . get_checked_files ( )
75209 const files_by_workspace = group_files_by_workspace ( checked_files )
76210
@@ -111,7 +245,12 @@ export const save_to_json_file = async (params: {
111245 vscode . window . showInformationMessage (
112246 dictionary . information_message . CONTEXT_SAVED_SUCCESSFULLY
113247 )
114- return
248+
249+ const reloaded = await load_and_merge_file_contexts ( )
250+ file_contexts = reloaded . merged
251+ context_to_roots = reloaded . context_to_roots
252+
253+ continue
115254 }
116255
117256 if ( selection . context ) {
@@ -159,7 +298,12 @@ export const save_to_json_file = async (params: {
159298 vscode . window . showInformationMessage (
160299 dictionary . information_message . CONTEXT_UPDATED_SUCCESSFULLY
161300 )
162- return
301+
302+ const reloaded = await load_and_merge_file_contexts ( )
303+ file_contexts = reloaded . merged
304+ context_to_roots = reloaded . context_to_roots
305+
306+ continue
163307 } else {
164308 continue
165309 }
0 commit comments