@@ -6,19 +6,25 @@ use std::{
use dap::{DapRegistry, DebugRequest, adapters::DebugTaskDefinition};
use editor::{Editor, EditorElement, EditorStyle};
+use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{
- App, AppContext, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, Render, TextStyle,
- WeakEntity,
+ App, AppContext, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, Render,
+ Subscription, TextStyle, WeakEntity,
};
+use picker::{Picker, PickerDelegate, highlighted_match_with_paths::HighlightedMatch};
+use project::{TaskSourceKind, task_store::TaskStore};
+use session_modes::{AttachMode, DebugScenarioDelegate, LaunchMode};
use settings::Settings;
-use task::{DebugScenario, LaunchRequest, TaskContext};
+use task::{DebugScenario, LaunchRequest};
use theme::ThemeSettings;
use ui::{
ActiveTheme, Button, ButtonCommon, ButtonSize, CheckboxWithLabel, Clickable, Color, Context,
- ContextMenu, Disableable, DropdownMenu, FluentBuilder, InteractiveElement, IntoElement, Label,
- LabelCommon as _, ParentElement, RenderOnce, SharedString, Styled, StyledExt, ToggleButton,
- ToggleState, Toggleable, Window, div, h_flex, relative, rems, v_flex,
+ ContextMenu, Disableable, DropdownMenu, FluentBuilder, Icon, IconName, InteractiveElement,
+ IntoElement, Label, LabelCommon as _, ListItem, ListItemSpacing, ParentElement, RenderOnce,
+ SharedString, Styled, StyledExt, ToggleButton, ToggleState, Toggleable, Window, div, h_flex,
+ relative, rems, v_flex,
};
+use util::ResultExt;
use workspace::{ModalView, Workspace};
use crate::{attach_modal::AttachModal, debugger_panel::DebugPanel};
@@ -57,6 +63,7 @@ impl NewSessionModal {
past_debug_definition: Option<DebugTaskDefinition>,
debug_panel: WeakEntity<DebugPanel>,
workspace: WeakEntity<Workspace>,
+ task_store: Option<Entity<TaskStore>>,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
@@ -73,6 +80,18 @@ impl NewSessionModal {
_ => None,
};
+ if let Some(task_store) = task_store {
+ cx.defer_in(window, |this, window, cx| {
+ this.mode = NewSessionMode::scenario(
+ this.debug_panel.clone(),
+ this.workspace.clone(),
+ task_store,
+ window,
+ cx,
+ );
+ });
+ };
+
Self {
workspace: workspace.clone(),
debugger,
@@ -86,10 +105,10 @@ impl NewSessionModal {
}
}
- fn debug_config(&self, cx: &App, debugger: &str) -> DebugScenario {
- let request = self.mode.debug_task(cx);
+ fn debug_config(&self, cx: &App, debugger: &str) -> Option<DebugScenario> {
+ let request = self.mode.debug_task(cx)?;
let label = suggested_label(&request, debugger);
- DebugScenario {
+ Some(DebugScenario {
adapter: debugger.to_owned().into(),
label,
request: Some(request),
@@ -100,21 +119,42 @@ impl NewSessionModal {
_ => None,
},
build: None,
- }
+ })
}
fn start_new_session(&self, window: &mut Window, cx: &mut Context<Self>) {
let Some(debugger) = self.debugger.as_ref() else {
- // todo: show in UI.
+ // todo(debugger): show in UI.
log::error!("No debugger selected");
return;
};
- let config = self.debug_config(cx, debugger);
+
+ if let NewSessionMode::Scenario(picker) = &self.mode {
+ picker.update(cx, |picker, cx| {
+ picker.delegate.confirm(false, window, cx);
+ });
+ return;
+ }
+
+ let Some(config) = self.debug_config(cx, debugger) else {
+ log::error!("debug config not found in mode: {}", self.mode);
+ return;
+ };
+
let debug_panel = self.debug_panel.clone();
+ let workspace = self.workspace.clone();
cx.spawn_in(window, async move |this, cx| {
+ let task_contexts = workspace
+ .update_in(cx, |workspace, window, cx| {
+ tasks_ui::task_contexts(workspace, window, cx)
+ })?
+ .await;
+
+ let task_context = task_contexts.active_context().cloned().unwrap_or_default();
+
debug_panel.update_in(cx, |debug_panel, window, cx| {
- debug_panel.start_session(config, TaskContext::default(), None, window, cx)
+ debug_panel.start_session(config, task_context, None, window, cx)
})?;
this.update(cx, |_, cx| {
cx.emit(DismissEvent);
@@ -256,9 +296,14 @@ impl NewSessionModal {
.iter()
.flat_map(|task_inventory| {
task_inventory.read(cx).list_debug_scenarios(
- worktree.as_ref().map(|worktree| worktree.read(cx).id()),
+ worktree
+ .as_ref()
+ .map(|worktree| worktree.read(cx).id())
+ .iter()
+ .copied(),
)
})
+ .map(|(_source_kind, scenario)| scenario)
.collect()
})
.ok()
@@ -277,102 +322,22 @@ impl NewSessionModal {
}
}
-#[derive(Clone)]
-struct LaunchMode {
- program: Entity<Editor>,
- cwd: Entity<Editor>,
-}
-
-impl LaunchMode {
- fn new(
- past_launch_config: Option<LaunchRequest>,
- window: &mut Window,
- cx: &mut App,
- ) -> Entity<Self> {
- let (past_program, past_cwd) = past_launch_config
- .map(|config| (Some(config.program), config.cwd))
- .unwrap_or_else(|| (None, None));
-
- let program = cx.new(|cx| Editor::single_line(window, cx));
- program.update(cx, |this, cx| {
- this.set_placeholder_text("Program path", cx);
-
- if let Some(past_program) = past_program {
- this.set_text(past_program, window, cx);
- };
- });
- let cwd = cx.new(|cx| Editor::single_line(window, cx));
- cwd.update(cx, |this, cx| {
- this.set_placeholder_text("Working Directory", cx);
- if let Some(past_cwd) = past_cwd {
- this.set_text(past_cwd.to_string_lossy(), window, cx);
- };
- });
- cx.new(|_| Self { program, cwd })
- }
-
- fn debug_task(&self, cx: &App) -> task::LaunchRequest {
- let path = self.cwd.read(cx).text(cx);
- task::LaunchRequest {
- program: self.program.read(cx).text(cx),
- cwd: path.is_empty().not().then(|| PathBuf::from(path)),
- args: Default::default(),
- env: Default::default(),
- }
- }
-}
-
-#[derive(Clone)]
-struct AttachMode {
- definition: DebugTaskDefinition,
- attach_picker: Entity<AttachModal>,
-}
-
-impl AttachMode {
- fn new(
- debugger: Option<SharedString>,
- workspace: Entity<Workspace>,
- window: &mut Window,
- cx: &mut Context<NewSessionModal>,
- ) -> Entity<Self> {
- let definition = DebugTaskDefinition {
- adapter: debugger.clone().unwrap_or_default(),
- label: "Attach New Session Setup".into(),
- request: dap::DebugRequest::Attach(task::AttachRequest { process_id: None }),
- initialize_args: None,
- tcp_connection: None,
- stop_on_entry: Some(false),
- };
- let attach_picker = cx.new(|cx| {
- let modal = AttachModal::new(definition.clone(), workspace, false, window, cx);
- window.focus(&modal.focus_handle(cx));
-
- modal
- });
- cx.new(|_| Self {
- definition,
- attach_picker,
- })
- }
- fn debug_task(&self) -> task::AttachRequest {
- task::AttachRequest { process_id: None }
- }
-}
-
static SELECT_DEBUGGER_LABEL: SharedString = SharedString::new_static("Select Debugger");
static SELECT_SCENARIO_LABEL: SharedString = SharedString::new_static("Select Profile");
#[derive(Clone)]
enum NewSessionMode {
Launch(Entity<LaunchMode>),
+ Scenario(Entity<Picker<DebugScenarioDelegate>>),
Attach(Entity<AttachMode>),
}
impl NewSessionMode {
- fn debug_task(&self, cx: &App) -> DebugRequest {
+ fn debug_task(&self, cx: &App) -> Option<DebugRequest> {
match self {
- NewSessionMode::Launch(entity) => entity.read(cx).debug_task(cx).into(),
- NewSessionMode::Attach(entity) => entity.read(cx).debug_task().into(),
+ NewSessionMode::Launch(entity) => Some(entity.read(cx).debug_task(cx).into()),
+ NewSessionMode::Attach(entity) => Some(entity.read(cx).debug_task().into()),
+ NewSessionMode::Scenario(_) => None,
}
}
fn as_attach(&self) -> Option<&Entity<AttachMode>> {
@@ -382,6 +347,78 @@ impl NewSessionMode {
None
}
}
+
+ fn scenario(
+ debug_panel: WeakEntity<DebugPanel>,
+ workspace: WeakEntity<Workspace>,
+ task_store: Entity<TaskStore>,
+ window: &mut Window,
+ cx: &mut Context<NewSessionModal>,
+ ) -> NewSessionMode {
+ let picker = cx.new(|cx| {
+ Picker::uniform_list(
+ DebugScenarioDelegate::new(debug_panel, workspace, task_store),
+ window,
+ cx,
+ )
+ .modal(false)
+ });
+
+ cx.subscribe(&picker, |_, _, _, cx| {
+ cx.emit(DismissEvent);
+ })
+ .detach();
+
+ picker.focus_handle(cx).focus(window);
+ NewSessionMode::Scenario(picker)
+ }
+
+ fn attach(
+ debugger: Option<SharedString>,
+ workspace: Entity<Workspace>,
+ window: &mut Window,
+ cx: &mut Context<NewSessionModal>,
+ ) -> Self {
+ Self::Attach(AttachMode::new(debugger, workspace, window, cx))
+ }
+
+ fn launch(
+ past_launch_config: Option<LaunchRequest>,
+ window: &mut Window,
+ cx: &mut Context<NewSessionModal>,
+ ) -> Self {
+ Self::Launch(LaunchMode::new(past_launch_config, window, cx))
+ }
+
+ fn has_match(&self, cx: &App) -> bool {
+ match self {
+ NewSessionMode::Scenario(picker) => picker.read(cx).delegate.match_count() > 0,
+ NewSessionMode::Attach(picker) => {
+ picker
+ .read(cx)
+ .attach_picker
+ .read(cx)
+ .picker
+ .read(cx)
+ .delegate
+ .match_count()
+ > 0
+ }
+ _ => false,
+ }
+ }
+}
+
+impl std::fmt::Display for NewSessionMode {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ let mode = match self {
+ NewSessionMode::Launch(_) => "launch".to_owned(),
+ NewSessionMode::Attach(_) => "attach".to_owned(),
+ NewSessionMode::Scenario(_) => "scenario picker".to_owned(),
+ };
+
+ write!(f, "{}", mode)
+ }
}
impl Focusable for NewSessionMode {
@@ -389,6 +426,7 @@ impl Focusable for NewSessionMode {
match &self {
NewSessionMode::Launch(entity) => entity.read(cx).program.focus_handle(cx),
NewSessionMode::Attach(entity) => entity.read(cx).attach_picker.focus_handle(cx),
+ NewSessionMode::Scenario(entity) => entity.read(cx).focus_handle(cx),
}
}
}
@@ -437,27 +475,14 @@ impl RenderOnce for NewSessionMode {
NewSessionMode::Attach(entity) => entity.update(cx, |this, cx| {
this.clone().render(window, cx).into_any_element()
}),
+ NewSessionMode::Scenario(entity) => v_flex()
+ .w(rems(34.))
+ .child(entity.clone())
+ .into_any_element(),
}
}
}
-impl NewSessionMode {
- fn attach(
- debugger: Option<SharedString>,
- workspace: Entity<Workspace>,
- window: &mut Window,
- cx: &mut Context<NewSessionModal>,
- ) -> Self {
- Self::Attach(AttachMode::new(debugger, workspace, window, cx))
- }
- fn launch(
- past_launch_config: Option<LaunchRequest>,
- window: &mut Window,
- cx: &mut Context<NewSessionModal>,
- ) -> Self {
- Self::Launch(LaunchMode::new(past_launch_config, window, cx))
- }
-}
fn render_editor(editor: &Entity<Editor>, window: &mut Window, cx: &App) -> impl IntoElement {
let settings = ThemeSettings::get_global(cx);
let theme = cx.theme();
@@ -519,6 +544,34 @@ impl Render for NewSessionModal {
h_flex()
.justify_start()
.w_full()
+ .child(
+ ToggleButton::new("debugger-session-ui-picker-button", "Scenarios")
+ .size(ButtonSize::Default)
+ .style(ui::ButtonStyle::Subtle)
+ .toggle_state(matches!(self.mode, NewSessionMode::Scenario(_)))
+ .on_click(cx.listener(|this, _, window, cx| {
+ let Some(task_store) = this
+ .workspace
+ .update(cx, |workspace, cx| {
+ workspace.project().read(cx).task_store().clone()
+ })
+ .ok()
+ else {
+ return;
+ };
+
+ this.mode = NewSessionMode::scenario(
+ this.debug_panel.clone(),
+ this.workspace.clone(),
+ task_store,
+ window,
+ cx,
+ );
+
+ cx.notify();
+ }))
+ .first(),
+ )
.child(
ToggleButton::new(
"debugger-session-ui-launch-button",
@@ -532,7 +585,7 @@ impl Render for NewSessionModal {
this.mode.focus_handle(cx).focus(window);
cx.notify();
}))
- .first(),
+ .middle(),
)
.child(
ToggleButton::new(
@@ -601,10 +654,21 @@ impl Render for NewSessionModal {
})
.child(
Button::new("debugger-spawn", "Start")
- .on_click(cx.listener(|this, _, window, cx| {
- this.start_new_session(window, cx);
+ .on_click(cx.listener(|this, _, window, cx| match &this.mode {
+ NewSessionMode::Scenario(picker) => {
+ picker.update(cx, |picker, cx| {
+ picker.delegate.confirm(true, window, cx)
+ })
+ }
+ _ => this.start_new_session(window, cx),
}))
- .disabled(self.debugger.is_none()),
+ .disabled(match self.mode {
+ NewSessionMode::Scenario(_) => !self.mode.has_match(cx),
+ NewSessionMode::Attach(_) => {
+ self.debugger.is_none() || !self.mode.has_match(cx)
+ }
+ NewSessionMode::Launch(_) => self.debugger.is_none(),
+ }),
),
),
)
@@ -619,3 +683,319 @@ impl Focusable for NewSessionModal {
}
impl ModalView for NewSessionModal {}
+
+// This module makes sure that the modes setup the correct subscriptions whenever they're created
+mod session_modes {
+ use std::rc::Rc;
+
+ use super::*;
+
+ #[derive(Clone)]
+ #[non_exhaustive]
+ pub(super) struct LaunchMode {
+ pub(super) program: Entity<Editor>,
+ pub(super) cwd: Entity<Editor>,
+ }
+
+ impl LaunchMode {
+ pub(super) fn new(
+ past_launch_config: Option<LaunchRequest>,
+ window: &mut Window,
+ cx: &mut App,
+ ) -> Entity<Self> {
+ let (past_program, past_cwd) = past_launch_config
+ .map(|config| (Some(config.program), config.cwd))
+ .unwrap_or_else(|| (None, None));
+
+ let program = cx.new(|cx| Editor::single_line(window, cx));
+ program.update(cx, |this, cx| {
+ this.set_placeholder_text("Program path", cx);
+
+ if let Some(past_program) = past_program {
+ this.set_text(past_program, window, cx);
+ };
+ });
+ let cwd = cx.new(|cx| Editor::single_line(window, cx));
+ cwd.update(cx, |this, cx| {
+ this.set_placeholder_text("Working Directory", cx);
+ if let Some(past_cwd) = past_cwd {
+ this.set_text(past_cwd.to_string_lossy(), window, cx);
+ };
+ });
+ cx.new(|_| Self { program, cwd })
+ }
+
+ pub(super) fn debug_task(&self, cx: &App) -> task::LaunchRequest {
+ let path = self.cwd.read(cx).text(cx);
+ task::LaunchRequest {
+ program: self.program.read(cx).text(cx),
+ cwd: path.is_empty().not().then(|| PathBuf::from(path)),
+ args: Default::default(),
+ env: Default::default(),
+ }
+ }
+ }
+
+ #[derive(Clone)]
+ pub(super) struct AttachMode {
+ pub(super) definition: DebugTaskDefinition,
+ pub(super) attach_picker: Entity<AttachModal>,
+ _subscription: Rc<Subscription>,
+ }
+
+ impl AttachMode {
+ pub(super) fn new(
+ debugger: Option<SharedString>,
+ workspace: Entity<Workspace>,
+ window: &mut Window,
+ cx: &mut Context<NewSessionModal>,
+ ) -> Entity<Self> {
+ let definition = DebugTaskDefinition {
+ adapter: debugger.clone().unwrap_or_default(),
+ label: "Attach New Session Setup".into(),
+ request: dap::DebugRequest::Attach(task::AttachRequest { process_id: None }),
+ initialize_args: None,
+ tcp_connection: None,
+ stop_on_entry: Some(false),
+ };
+ let attach_picker = cx.new(|cx| {
+ let modal = AttachModal::new(definition.clone(), workspace, false, window, cx);
+ window.focus(&modal.focus_handle(cx));
+
+ modal
+ });
+
+ let subscription = cx.subscribe(&attach_picker, |_, _, _, cx| {
+ cx.emit(DismissEvent);
+ });
+
+ cx.new(|_| Self {
+ definition,
+ attach_picker,
+ _subscription: Rc::new(subscription),
+ })
+ }
+ pub(super) fn debug_task(&self) -> task::AttachRequest {
+ task::AttachRequest { process_id: None }
+ }
+ }
+
+ pub(super) struct DebugScenarioDelegate {
+ task_store: Entity<TaskStore>,
+ candidates: Option<Vec<(TaskSourceKind, DebugScenario)>>,
+ selected_index: usize,
+ matches: Vec<StringMatch>,
+ prompt: String,
+ debug_panel: WeakEntity<DebugPanel>,
+ workspace: WeakEntity<Workspace>,
+ }
+
+ impl DebugScenarioDelegate {
+ pub(super) fn new(
+ debug_panel: WeakEntity<DebugPanel>,
+ workspace: WeakEntity<Workspace>,
+ task_store: Entity<TaskStore>,
+ ) -> Self {
+ Self {
+ task_store,
+ candidates: None,
+ selected_index: 0,
+ matches: Vec::new(),
+ prompt: String::new(),
+ debug_panel,
+ workspace,
+ }
+ }
+ }
+
+ impl PickerDelegate for DebugScenarioDelegate {
+ type ListItem = ui::ListItem;
+
+ fn match_count(&self) -> usize {
+ self.matches.len()
+ }
+
+ fn selected_index(&self) -> usize {
+ self.selected_index
+ }
+
+ fn set_selected_index(
+ &mut self,
+ ix: usize,
+ _window: &mut Window,
+ _cx: &mut Context<picker::Picker<Self>>,
+ ) {
+ self.selected_index = ix;
+ }
+
+ fn placeholder_text(&self, _window: &mut Window, _cx: &mut App) -> std::sync::Arc<str> {
+ "".into()
+ }
+
+ fn update_matches(
+ &mut self,
+ query: String,
+ window: &mut Window,
+ cx: &mut Context<picker::Picker<Self>>,
+ ) -> gpui::Task<()> {
+ let candidates: Vec<_> = match &self.candidates {
+ Some(candidates) => candidates
+ .into_iter()
+ .enumerate()
+ .map(|(index, (_, candidate))| {
+ StringMatchCandidate::new(index, candidate.label.as_ref())
+ })
+ .collect(),
+ None => {
+ let worktree_ids: Vec<_> = self
+ .workspace
+ .update(cx, |this, cx| {
+ this.visible_worktrees(cx)
+ .map(|tree| tree.read(cx).id())
+ .collect()
+ })
+ .ok()
+ .unwrap_or_default();
+
+ let scenarios: Vec<_> = self
+ .task_store
+ .read(cx)
+ .task_inventory()
+ .map(|item| item.read(cx).list_debug_scenarios(worktree_ids.into_iter()))
+ .unwrap_or_default();
+
+ self.candidates = Some(scenarios.clone());
+
+ scenarios
+ .into_iter()
+ .enumerate()
+ .map(|(index, (_, candidate))| {
+ StringMatchCandidate::new(index, candidate.label.as_ref())
+ })
+ .collect()
+ }
+ };
+
+ cx.spawn_in(window, async move |picker, cx| {
+ let matches = fuzzy::match_strings(
+ &candidates,
+ &query,
+ true,
+ 1000,
+ &Default::default(),
+ cx.background_executor().clone(),
+ )
+ .await;
+
+ picker
+ .update(cx, |picker, _| {
+ let delegate = &mut picker.delegate;
+
+ delegate.matches = matches;
+ delegate.prompt = query;
+
+ if delegate.matches.is_empty() {
+ delegate.selected_index = 0;
+ } else {
+ delegate.selected_index =
+ delegate.selected_index.min(delegate.matches.len() - 1);
+ }
+ })
+ .log_err();
+ })
+ }
+
+ fn confirm(
+ &mut self,
+ _: bool,
+ window: &mut Window,
+ cx: &mut Context<picker::Picker<Self>>,
+ ) {
+ let debug_scenario =
+ self.matches
+ .get(self.selected_index())
+ .and_then(|match_candidate| {
+ self.candidates
+ .as_ref()
+ .map(|candidates| candidates[match_candidate.candidate_id].clone())
+ });
+
+ let Some((task_source_kind, debug_scenario)) = debug_scenario else {
+ return;
+ };
+
+ let task_context = if let TaskSourceKind::Worktree {
+ id: worktree_id,
+ directory_in_worktree: _,
+ id_base: _,
+ } = task_source_kind
+ {
+ let workspace = self.workspace.clone();
+
+ cx.spawn_in(window, async move |_, cx| {
+ workspace
+ .update_in(cx, |workspace, window, cx| {
+ tasks_ui::task_contexts(workspace, window, cx)
+ })
+ .ok()?
+ .await
+ .task_context_for_worktree_id(worktree_id)
+ .cloned()
+ })
+ } else {
+ gpui::Task::ready(None)
+ };
+
+ cx.spawn_in(window, async move |this, cx| {
+ let task_context = task_context.await.unwrap_or_default();
+
+ this.update_in(cx, |this, window, cx| {
+ this.delegate
+ .debug_panel
+ .update(cx, |panel, cx| {
+ panel.start_session(debug_scenario, task_context, None, window, cx);
+ })
+ .ok();
+
+ cx.emit(DismissEvent);
+ })
+ .ok();
+ })
+ .detach();
+ }
+
+ fn dismissed(&mut self, _: &mut Window, cx: &mut Context<picker::Picker<Self>>) {
+ cx.emit(DismissEvent);
+ }
+
+ fn render_match(
+ &self,
+ ix: usize,
+ selected: bool,
+ window: &mut Window,
+ cx: &mut Context<picker::Picker<Self>>,
+ ) -> Option<Self::ListItem> {
+ let hit = &self.matches[ix];
+
+ let highlighted_location = HighlightedMatch {
+ text: hit.string.clone(),
+ highlight_positions: hit.positions.clone(),
+ char_count: hit.string.chars().count(),
+ color: Color::Default,
+ };
+
+ let icon = Icon::new(IconName::FileTree)
+ .color(Color::Muted)
+ .size(ui::IconSize::Small);
+
+ Some(
+ ListItem::new(SharedString::from(format!("debug-scenario-selection-{ix}")))
+ .inset(true)
+ .start_slot::<Icon>(icon)
+ .spacing(ListItemSpacing::Sparse)
+ .toggle_state(selected)
+ .child(highlighted_location.render(window, cx)),
+ )
+ }
+ }
+}
@@ -10,7 +10,7 @@ use gpui::{
use itertools::Itertools;
use picker::{Picker, PickerDelegate, highlighted_match_with_paths::HighlightedMatch};
use project::{TaskSourceKind, task_store::TaskStore};
-use task::{DebugScenario, ResolvedTask, RevealTarget, TaskContext, TaskModal, TaskTemplate};
+use task::{DebugScenario, ResolvedTask, RevealTarget, TaskContext, TaskTemplate};
use ui::{
ActiveTheme, Button, ButtonCommon, ButtonSize, Clickable, Color, FluentBuilder as _, Icon,
IconButton, IconButtonShape, IconName, IconSize, IntoElement, KeyBinding, Label, LabelSize,
@@ -34,8 +34,6 @@ pub(crate) struct TasksModalDelegate {
prompt: String,
task_contexts: TaskContexts,
placeholder_text: Arc<str>,
- /// If this delegate is responsible for running a scripting task or a debugger
- task_modal_type: TaskModal,
}
/// Task template amendments to do before resolving the context.
@@ -50,7 +48,6 @@ impl TasksModalDelegate {
task_store: Entity<TaskStore>,
task_contexts: TaskContexts,
task_overrides: Option<TaskOverrides>,
- task_modal_type: TaskModal,
workspace: WeakEntity<Workspace>,
) -> Self {
let placeholder_text = if let Some(TaskOverrides {
@@ -71,7 +68,6 @@ impl TasksModalDelegate {
selected_index: 0,
prompt: String::default(),
task_contexts,
- task_modal_type,
task_overrides,
placeholder_text,
}
@@ -136,19 +132,12 @@ impl TasksModal {
task_contexts: TaskContexts,
task_overrides: Option<TaskOverrides>,
workspace: WeakEntity<Workspace>,
- task_modal_type: TaskModal,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
let picker = cx.new(|cx| {
Picker::uniform_list(
- TasksModalDelegate::new(
- task_store,
- task_contexts,
- task_overrides,
- task_modal_type,
- workspace,
- ),
+ TasksModalDelegate::new(task_store, task_contexts, task_overrides, workspace),
window,
cx,
)
@@ -231,9 +220,8 @@ impl PickerDelegate for TasksModalDelegate {
window: &mut Window,
cx: &mut Context<picker::Picker<Self>>,
) -> Task<()> {
- let task_type = self.task_modal_type.clone();
let candidates = match &self.candidates {
- Some(candidates) => Task::ready(string_match_candidates(candidates, task_type)),
+ Some(candidates) => Task::ready(string_match_candidates(candidates)),
None => {
if let Some(task_inventory) = self.task_store.read(cx).task_inventory().cloned() {
let (used, current) = task_inventory
@@ -276,8 +264,7 @@ impl PickerDelegate for TasksModalDelegate {
},
));
new_candidates.extend(current);
- let match_candidates =
- string_match_candidates(&new_candidates, task_type);
+ let match_candidates = string_match_candidates(&new_candidates);
let _ = picker.delegate.candidates.insert(new_candidates);
match_candidates
})
@@ -669,12 +656,10 @@ impl PickerDelegate for TasksModalDelegate {
fn string_match_candidates<'a>(
candidates: impl IntoIterator<Item = &'a (TaskSourceKind, ResolvedTask)> + 'a,
- task_modal_type: TaskModal,
) -> Vec<StringMatchCandidate> {
candidates
.into_iter()
.enumerate()
- .filter(|(_, (_, _))| task_modal_type == TaskModal::ScriptModal)
.map(|(index, (_, candidate))| StringMatchCandidate::new(index, candidate.display_label()))
.collect()
}