11use dap:: { DapRegistry , DebugRequest } ;
2+ use futures:: channel:: oneshot;
23use fuzzy:: { StringMatch , StringMatchCandidate } ;
34use gpui:: { AppContext , DismissEvent , Entity , EventEmitter , Focusable , Render , Task } ;
45use gpui:: { Subscription , WeakEntity } ;
@@ -9,6 +10,7 @@ use task::ZedDebugConfig;
910use util:: debug_panic;
1011
1112use std:: sync:: Arc ;
13+
1214use sysinfo:: { ProcessRefreshKind , RefreshKind , System , UpdateKind } ;
1315use ui:: { Context , Tooltip , prelude:: * } ;
1416use ui:: { ListItem , ListItemSpacing } ;
@@ -23,25 +25,30 @@ pub(super) struct Candidate {
2325 pub ( super ) command : Vec < String > ,
2426}
2527
28+ pub ( crate ) enum ModalIntent {
29+ ResolveProcessId ( Option < oneshot:: Sender < Option < i32 > > > ) ,
30+ AttachToProcess ( ZedDebugConfig ) ,
31+ }
32+
2633pub ( crate ) struct AttachModalDelegate {
2734 selected_index : usize ,
2835 matches : Vec < StringMatch > ,
2936 placeholder_text : Arc < str > ,
30- pub ( crate ) definition : ZedDebugConfig ,
37+ pub ( crate ) intent : ModalIntent ,
3138 workspace : WeakEntity < Workspace > ,
3239 candidates : Arc < [ Candidate ] > ,
3340}
3441
3542impl AttachModalDelegate {
3643 fn new (
3744 workspace : WeakEntity < Workspace > ,
38- definition : ZedDebugConfig ,
45+ intent : ModalIntent ,
3946 candidates : Arc < [ Candidate ] > ,
4047 ) -> Self {
4148 Self {
4249 workspace,
43- definition,
4450 candidates,
51+ intent,
4552 selected_index : 0 ,
4653 matches : Vec :: default ( ) ,
4754 placeholder_text : Arc :: from ( "Select the process you want to attach the debugger to" ) ,
@@ -55,8 +62,8 @@ pub struct AttachModal {
5562}
5663
5764impl AttachModal {
58- pub fn new (
59- definition : ZedDebugConfig ,
65+ pub ( crate ) fn new (
66+ intent : ModalIntent ,
6067 workspace : WeakEntity < Workspace > ,
6168 project : Entity < Project > ,
6269 modal : bool ,
@@ -65,7 +72,7 @@ impl AttachModal {
6572 ) -> Self {
6673 let processes_task = get_processes_for_project ( & project, cx) ;
6774
68- let modal = Self :: with_processes ( workspace, definition , Arc :: new ( [ ] ) , modal, window, cx) ;
75+ let modal = Self :: with_processes ( workspace, Arc :: new ( [ ] ) , modal, intent , window, cx) ;
6976
7077 cx. spawn_in ( window, async move |this, cx| {
7178 let processes = processes_task. await ;
@@ -84,15 +91,15 @@ impl AttachModal {
8491
8592 pub ( super ) fn with_processes (
8693 workspace : WeakEntity < Workspace > ,
87- definition : ZedDebugConfig ,
8894 processes : Arc < [ Candidate ] > ,
8995 modal : bool ,
96+ intent : ModalIntent ,
9097 window : & mut Window ,
9198 cx : & mut Context < Self > ,
9299 ) -> Self {
93100 let picker = cx. new ( |cx| {
94101 Picker :: uniform_list (
95- AttachModalDelegate :: new ( workspace, definition , processes) ,
102+ AttachModalDelegate :: new ( workspace, intent , processes) ,
96103 window,
97104 cx,
98105 )
@@ -207,7 +214,7 @@ impl PickerDelegate for AttachModalDelegate {
207214 } )
208215 }
209216
210- fn confirm ( & mut self , secondary : bool , window : & mut Window , cx : & mut Context < Picker < Self > > ) {
217+ fn confirm ( & mut self , _secondary : bool , window : & mut Window , cx : & mut Context < Picker < Self > > ) {
211218 let candidate = self
212219 . matches
213220 . get ( self . selected_index ( ) )
@@ -216,69 +223,86 @@ impl PickerDelegate for AttachModalDelegate {
216223 self . candidates . get ( ix)
217224 } ) ;
218225
219- let Some ( candidate ) = candidate else {
220- return cx . emit ( DismissEvent ) ;
221- } ;
226+ match & mut self . intent {
227+ ModalIntent :: ResolveProcessId ( sender ) => {
228+ cx . emit ( DismissEvent ) ;
222229
223- match & mut self . definition . request {
224- DebugRequest :: Attach ( config) => {
225- config. process_id = Some ( candidate. pid ) ;
226- }
227- DebugRequest :: Launch ( _) => {
228- debug_panic ! ( "Debugger attach modal used on launch debug config" ) ;
229- return ;
230+ if let Some ( sender) = sender. take ( ) {
231+ sender
232+ . send ( candidate. map ( |candidate| candidate. pid as i32 ) )
233+ . ok ( ) ;
234+ }
230235 }
231- }
232-
233- let workspace = self . workspace . clone ( ) ;
234- let Some ( panel) = workspace
235- . update ( cx, |workspace, cx| workspace. panel :: < DebugPanel > ( cx) )
236- . ok ( )
237- . flatten ( )
238- else {
239- return ;
240- } ;
241-
242- if secondary {
243- // let Some(id) = worktree_id else { return };
244- // cx.spawn_in(window, async move |_, cx| {
245- // panel
246- // .update_in(cx, |debug_panel, window, cx| {
247- // debug_panel.save_scenario(&debug_scenario, id, window, cx)
248- // })?
249- // .await?;
250- // anyhow::Ok(())
251- // })
252- // .detach_and_log_err(cx);
253- }
254- let Some ( adapter) = cx. read_global :: < DapRegistry , _ > ( |registry, _| {
255- registry. adapter ( & self . definition . adapter )
256- } ) else {
257- return ;
258- } ;
259-
260- let definition = self . definition . clone ( ) ;
261- cx. spawn_in ( window, async move |this, cx| {
262- let Ok ( scenario) = adapter. config_from_zed_format ( definition) . await else {
263- return ;
264- } ;
236+ ModalIntent :: AttachToProcess ( definition) => {
237+ let Some ( candidate) = candidate else {
238+ return cx. emit ( DismissEvent ) ;
239+ } ;
240+
241+ match & mut definition. request {
242+ DebugRequest :: Attach ( config) => {
243+ config. process_id = Some ( candidate. pid ) ;
244+ }
245+ DebugRequest :: Launch ( _) => {
246+ debug_panic ! ( "Debugger attach modal used on launch debug config" ) ;
247+ return ;
248+ }
249+ }
265250
266- panel
267- . update_in ( cx, |panel, window, cx| {
268- panel. start_session ( scenario, Default :: default ( ) , None , None , window, cx) ;
251+ let workspace = self . workspace . clone ( ) ;
252+ let Some ( panel) = workspace
253+ . update ( cx, |workspace, cx| workspace. panel :: < DebugPanel > ( cx) )
254+ . ok ( )
255+ . flatten ( )
256+ else {
257+ return ;
258+ } ;
259+
260+ let Some ( adapter) = cx. read_global :: < DapRegistry , _ > ( |registry, _| {
261+ registry. adapter ( & definition. adapter )
262+ } ) else {
263+ return ;
264+ } ;
265+
266+ let definition = definition. clone ( ) ;
267+ cx. spawn_in ( window, async move |this, cx| {
268+ let Ok ( scenario) = adapter. config_from_zed_format ( definition) . await else {
269+ return ;
270+ } ;
271+
272+ panel
273+ . update_in ( cx, |panel, window, cx| {
274+ panel. start_session (
275+ scenario,
276+ Default :: default ( ) ,
277+ None ,
278+ None ,
279+ window,
280+ cx,
281+ ) ;
282+ } )
283+ . ok ( ) ;
284+ this. update ( cx, |_, cx| {
285+ cx. emit ( DismissEvent ) ;
286+ } )
287+ . ok ( ) ;
269288 } )
270- . ok ( ) ;
271- this. update ( cx, |_, cx| {
272- cx. emit ( DismissEvent ) ;
273- } )
274- . ok ( ) ;
275- } )
276- . detach ( ) ;
289+ . detach ( ) ;
290+ }
291+ }
277292 }
278293
279294 fn dismissed ( & mut self , _window : & mut Window , cx : & mut Context < Picker < Self > > ) {
280295 self . selected_index = 0 ;
281296
297+ match & mut self . intent {
298+ ModalIntent :: ResolveProcessId ( sender) => {
299+ if let Some ( sender) = sender. take ( ) {
300+ sender. send ( None ) . ok ( ) ;
301+ }
302+ }
303+ ModalIntent :: AttachToProcess ( _) => { }
304+ }
305+
282306 cx. emit ( DismissEvent ) ;
283307 }
284308
@@ -338,7 +362,7 @@ fn get_processes_for_project(project: &Entity<Project>, cx: &mut App) -> Task<Ar
338362
339363 if let Some ( remote_client) = project. remote_client ( ) {
340364 let proto_client = remote_client. read ( cx) . proto_client ( ) ;
341- cx. spawn ( async move |_cx| {
365+ cx. background_spawn ( async move {
342366 let response = proto_client
343367 . request ( proto:: GetProcesses {
344368 project_id : proto:: REMOTE_SERVER_PROJECT_ID ,
@@ -389,8 +413,21 @@ fn get_processes_for_project(project: &Entity<Project>, cx: &mut App) -> Task<Ar
389413 }
390414}
391415
392- #[ cfg( any( test, feature = "test-support" ) ) ]
393- pub ( crate ) fn _process_names ( modal : & AttachModal , cx : & mut Context < AttachModal > ) -> Vec < String > {
416+ #[ cfg( test) ]
417+ pub ( crate ) fn set_candidates (
418+ modal : & AttachModal ,
419+ candidates : Arc < [ Candidate ] > ,
420+ window : & mut Window ,
421+ cx : & mut Context < AttachModal > ,
422+ ) {
423+ modal. picker . update ( cx, |picker, cx| {
424+ picker. delegate . candidates = candidates;
425+ picker. refresh ( window, cx) ;
426+ } ) ;
427+ }
428+
429+ #[ cfg( test) ]
430+ pub ( crate ) fn process_names ( modal : & AttachModal , cx : & mut Context < AttachModal > ) -> Vec < String > {
394431 modal. picker . read_with ( cx, |picker, _| {
395432 picker
396433 . delegate
0 commit comments