Added menu::UseSelectedQuery
command that populates task modal query with the selected task name (#8572)
This commit is contained in:
parent
9bd5ebb74b
commit
b7429bf29d
10 changed files with 340 additions and 116 deletions
|
@ -17,3 +17,10 @@ serde.workspace = true
|
|||
ui.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
language = { workspace = true, features = ["test-support"] }
|
||||
project = { workspace = true, features = ["test-support"] }
|
||||
serde_json.workspace = true
|
||||
workspace = { workspace = true, features = ["test-support"] }
|
||||
|
|
|
@ -97,6 +97,7 @@ impl TasksModal {
|
|||
impl Render for TasksModal {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl gpui::prelude::IntoElement {
|
||||
v_flex()
|
||||
.key_context("TasksModal")
|
||||
.w(rems(34.))
|
||||
.child(self.picker.clone())
|
||||
.on_mouse_down_out(cx.listener(|modal, _, cx| {
|
||||
|
@ -134,9 +135,10 @@ impl PickerDelegate for TasksModalDelegate {
|
|||
|
||||
fn placeholder_text(&self, cx: &mut WindowContext) -> Arc<str> {
|
||||
Arc::from(format!(
|
||||
"{} runs the selected task, {} spawns a bash-like task from the prompt",
|
||||
cx.keystroke_text_for(&menu::Confirm),
|
||||
"{} use task name as prompt, {} spawns a bash-like task from the prompt, {} runs the selected task",
|
||||
cx.keystroke_text_for(&menu::UseSelectedQuery),
|
||||
cx.keystroke_text_for(&menu::SecondaryConfirm),
|
||||
cx.keystroke_text_for(&menu::Confirm),
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -266,4 +268,179 @@ impl PickerDelegate for TasksModalDelegate {
|
|||
.child(highlighted_location.render(cx)),
|
||||
)
|
||||
}
|
||||
|
||||
fn selected_as_query(&self) -> Option<String> {
|
||||
Some(self.matches.get(self.selected_index())?.string.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use gpui::{TestAppContext, VisualTestContext};
|
||||
use project::{FakeFs, Project};
|
||||
use serde_json::json;
|
||||
use workspace::AppState;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_name(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
json!({
|
||||
".zed": {
|
||||
"tasks.json": r#"[
|
||||
{
|
||||
"label": "example task",
|
||||
"command": "echo",
|
||||
"args": ["4"]
|
||||
},
|
||||
{
|
||||
"label": "another one",
|
||||
"command": "echo",
|
||||
"args": ["55"]
|
||||
},
|
||||
]"#,
|
||||
},
|
||||
"a.ts": "a"
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/dir".as_ref()], cx).await;
|
||||
project.update(cx, |project, cx| {
|
||||
project.task_inventory().update(cx, |inventory, cx| {
|
||||
inventory.add_source(TaskSourceKind::UserInput, |cx| OneshotSource::new(cx), cx)
|
||||
})
|
||||
});
|
||||
|
||||
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
|
||||
|
||||
let tasks_picker = open_spawn_tasks(&workspace, cx);
|
||||
assert_eq!(
|
||||
query(&tasks_picker, cx),
|
||||
"",
|
||||
"Initial query should be empty"
|
||||
);
|
||||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec!["another one", "example task"],
|
||||
"Initial tasks should be listed in alphabetical order"
|
||||
);
|
||||
|
||||
let query_str = "tas";
|
||||
cx.simulate_input(query_str);
|
||||
assert_eq!(query(&tasks_picker, cx), query_str);
|
||||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec!["example task"],
|
||||
"Only one task should match the query {query_str}"
|
||||
);
|
||||
|
||||
cx.dispatch_action(menu::UseSelectedQuery);
|
||||
assert_eq!(
|
||||
query(&tasks_picker, cx),
|
||||
"example task",
|
||||
"Query should be set to the selected task's name"
|
||||
);
|
||||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec!["example task"],
|
||||
"No other tasks should be listed"
|
||||
);
|
||||
cx.dispatch_action(menu::Confirm);
|
||||
|
||||
let tasks_picker = open_spawn_tasks(&workspace, cx);
|
||||
assert_eq!(
|
||||
query(&tasks_picker, cx),
|
||||
"",
|
||||
"Query should be reset after confirming"
|
||||
);
|
||||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec!["example task", "another one"],
|
||||
"Last recently used task should be listed first"
|
||||
);
|
||||
|
||||
let query_str = "echo 4";
|
||||
cx.simulate_input(query_str);
|
||||
assert_eq!(query(&tasks_picker, cx), query_str);
|
||||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
Vec::<String>::new(),
|
||||
"No tasks should match custom command query"
|
||||
);
|
||||
|
||||
cx.dispatch_action(menu::SecondaryConfirm);
|
||||
let tasks_picker = open_spawn_tasks(&workspace, cx);
|
||||
assert_eq!(
|
||||
query(&tasks_picker, cx),
|
||||
"",
|
||||
"Query should be reset after confirming"
|
||||
);
|
||||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec![query_str, "example task", "another one"],
|
||||
"Last recently used one show task should be listed first"
|
||||
);
|
||||
|
||||
cx.dispatch_action(menu::UseSelectedQuery);
|
||||
assert_eq!(
|
||||
query(&tasks_picker, cx),
|
||||
query_str,
|
||||
"Query should be set to the custom task's name"
|
||||
);
|
||||
assert_eq!(
|
||||
task_names(&tasks_picker, cx),
|
||||
vec![query_str],
|
||||
"Only custom task should be listed"
|
||||
);
|
||||
}
|
||||
|
||||
fn open_spawn_tasks(
|
||||
workspace: &View<Workspace>,
|
||||
cx: &mut VisualTestContext,
|
||||
) -> View<Picker<TasksModalDelegate>> {
|
||||
cx.dispatch_action(crate::modal::Spawn);
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace
|
||||
.active_modal::<TasksModal>(cx)
|
||||
.unwrap()
|
||||
.read(cx)
|
||||
.picker
|
||||
.clone()
|
||||
})
|
||||
}
|
||||
|
||||
fn query(spawn_tasks: &View<Picker<TasksModalDelegate>>, cx: &mut VisualTestContext) -> String {
|
||||
spawn_tasks.update(cx, |spawn_tasks, cx| spawn_tasks.query(cx))
|
||||
}
|
||||
|
||||
fn task_names(
|
||||
spawn_tasks: &View<Picker<TasksModalDelegate>>,
|
||||
cx: &mut VisualTestContext,
|
||||
) -> Vec<String> {
|
||||
spawn_tasks.update(cx, |spawn_tasks, _| {
|
||||
spawn_tasks
|
||||
.delegate
|
||||
.matches
|
||||
.iter()
|
||||
.map(|hit| hit.string.clone())
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
}
|
||||
|
||||
fn init_test(cx: &mut TestAppContext) -> Arc<AppState> {
|
||||
cx.update(|cx| {
|
||||
let state = AppState::test(cx);
|
||||
language::init(cx);
|
||||
crate::init(cx);
|
||||
editor::init(cx);
|
||||
workspace::init_settings(cx);
|
||||
Project::init_settings(cx);
|
||||
state
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue