Accept 'IntoIterator<Item = Column<T, D>>' for picker columns

This allows us to replace any `vec![..]`s of columns where all columns
are static with static slices `[..]`.
This commit is contained in:
Michael Davis 2024-04-24 09:22:22 -04:00
parent 009bbdaf8d
commit a7777b3c11
No known key found for this signature in database
6 changed files with 31 additions and 21 deletions

View File

@ -2265,7 +2265,7 @@ struct GlobalSearchConfig {
file_picker_config: config.file_picker.clone(), file_picker_config: config.file_picker.clone(),
}; };
let columns = vec![ let columns = [
PickerColumn::new("path", |item: &FileResult, _| { PickerColumn::new("path", |item: &FileResult, _| {
let path = helix_stdx::path::get_relative_path(&item.path); let path = helix_stdx::path::get_relative_path(&item.path);
format!("{}:{}", path.to_string_lossy(), item.line_num + 1).into() format!("{}:{}", path.to_string_lossy(), item.line_num + 1).into()
@ -2886,7 +2886,7 @@ struct BufferMeta {
// mru // mru
items.sort_unstable_by_key(|item| std::cmp::Reverse(item.focused_at)); items.sort_unstable_by_key(|item| std::cmp::Reverse(item.focused_at));
let columns = vec![ let columns = [
PickerColumn::new("id", |meta: &BufferMeta, _| meta.id.to_string().into()), PickerColumn::new("id", |meta: &BufferMeta, _| meta.id.to_string().into()),
PickerColumn::new("flags", |meta: &BufferMeta, _| { PickerColumn::new("flags", |meta: &BufferMeta, _| {
let mut flags = String::new(); let mut flags = String::new();
@ -2960,7 +2960,7 @@ struct JumpMeta {
} }
}; };
let columns = vec![ let columns = [
ui::PickerColumn::new("id", |item: &JumpMeta, _| item.id.to_string().into()), ui::PickerColumn::new("id", |item: &JumpMeta, _| item.id.to_string().into()),
ui::PickerColumn::new("path", |item: &JumpMeta, _| { ui::PickerColumn::new("path", |item: &JumpMeta, _| {
let path = item let path = item
@ -3039,7 +3039,7 @@ pub struct FileChangeData {
let deleted = cx.editor.theme.get("diff.minus"); let deleted = cx.editor.theme.get("diff.minus");
let renamed = cx.editor.theme.get("diff.delta.moved"); let renamed = cx.editor.theme.get("diff.delta.moved");
let columns = vec![ let columns = [
PickerColumn::new("change", |change: &FileChange, data: &FileChangeData| { PickerColumn::new("change", |change: &FileChange, data: &FileChangeData| {
match change { match change {
FileChange::Untracked { .. } => Span::styled("+ untracked", data.style_untracked), FileChange::Untracked { .. } => Span::styled("+ untracked", data.style_untracked),
@ -3130,7 +3130,7 @@ pub fn command_palette(cx: &mut Context) {
}), }),
); );
let columns = vec![ let columns = [
ui::PickerColumn::new("name", |item, _| match item { ui::PickerColumn::new("name", |item, _| match item {
MappableCommand::Typable { name, .. } => format!(":{name}").into(), MappableCommand::Typable { name, .. } => format!(":{name}").into(),
MappableCommand::Static { name, .. } => (*name).into(), MappableCommand::Static { name, .. } => (*name).into(),

View File

@ -41,7 +41,7 @@ fn thread_picker(
let debugger = debugger!(editor); let debugger = debugger!(editor);
let thread_states = debugger.thread_states.clone(); let thread_states = debugger.thread_states.clone();
let columns = vec![ let columns = [
ui::PickerColumn::new("name", |item: &Thread, _| item.name.as_str().into()), ui::PickerColumn::new("name", |item: &Thread, _| item.name.as_str().into()),
ui::PickerColumn::new("state", |item: &Thread, thread_states: &ThreadStates| { ui::PickerColumn::new("state", |item: &Thread, thread_states: &ThreadStates| {
thread_states thread_states
@ -250,7 +250,7 @@ pub fn dap_launch(cx: &mut Context) {
let templates = config.templates.clone(); let templates = config.templates.clone();
let columns = vec![ui::PickerColumn::new( let columns = [ui::PickerColumn::new(
"template", "template",
|item: &DebugTemplate, _| item.name.as_str().into(), |item: &DebugTemplate, _| item.name.as_str().into(),
)]; )];
@ -725,7 +725,7 @@ pub fn dap_switch_stack_frame(cx: &mut Context) {
let frames = debugger.stack_frames[&thread_id].clone(); let frames = debugger.stack_frames[&thread_id].clone();
let columns = vec![ui::PickerColumn::new("frame", |item: &StackFrame, _| { let columns = [ui::PickerColumn::new("frame", |item: &StackFrame, _| {
item.name.as_str().into() // TODO: include thread_states in the label item.name.as_str().into() // TODO: include thread_states in the label
})]; })];
let picker = Picker::new(columns, 0, frames, (), move |cx, frame, _action| { let picker = Picker::new(columns, 0, frames, (), move |cx, frame, _action| {

View File

@ -371,7 +371,7 @@ fn nested_to_flat(
symbols.append(&mut lsp_items); symbols.append(&mut lsp_items);
} }
let call = move |_editor: &mut Editor, compositor: &mut Compositor| { let call = move |_editor: &mut Editor, compositor: &mut Compositor| {
let columns = vec![ let columns = [
ui::PickerColumn::new("kind", |item: &SymbolInformationItem, _| { ui::PickerColumn::new("kind", |item: &SymbolInformationItem, _| {
display_symbol_kind(item.symbol.kind).into() display_symbol_kind(item.symbol.kind).into()
}), }),
@ -478,7 +478,7 @@ pub fn workspace_symbol_picker(cx: &mut Context) {
} }
.boxed() .boxed()
}; };
let columns = vec![ let columns = [
ui::PickerColumn::new("kind", |item: &SymbolInformationItem, _| { ui::PickerColumn::new("kind", |item: &SymbolInformationItem, _| {
display_symbol_kind(item.symbol.kind).into() display_symbol_kind(item.symbol.kind).into()
}), }),
@ -855,7 +855,7 @@ fn goto_impl(
} }
[] => unreachable!("`locations` should be non-empty for `goto_impl`"), [] => unreachable!("`locations` should be non-empty for `goto_impl`"),
_locations => { _locations => {
let columns = vec![ui::PickerColumn::new( let columns = [ui::PickerColumn::new(
"location", "location",
|item: &lsp::Location, cwdir: &std::path::PathBuf| { |item: &lsp::Location, cwdir: &std::path::PathBuf| {
// The preallocation here will overallocate a few characters since it will account for the // The preallocation here will overallocate a few characters since it will account for the

View File

@ -1404,7 +1404,7 @@ fn lsp_workspace_command(
let callback = async move { let callback = async move {
let call: job::Callback = Callback::EditorCompositor(Box::new( let call: job::Callback = Callback::EditorCompositor(Box::new(
move |_editor: &mut Editor, compositor: &mut Compositor| { move |_editor: &mut Editor, compositor: &mut Compositor| {
let columns = vec![ui::PickerColumn::new( let columns = [ui::PickerColumn::new(
"title", "title",
|(_ls_id, command): &(_, helix_lsp::lsp::Command), _| { |(_ls_id, command): &(_, helix_lsp::lsp::Command), _| {
command.title.as_str().into() command.title.as_str().into()

View File

@ -219,7 +219,7 @@ pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> FilePi
}); });
log::debug!("file_picker init {:?}", Instant::now().duration_since(now)); log::debug!("file_picker init {:?}", Instant::now().duration_since(now));
let columns = vec![PickerColumn::new( let columns = [PickerColumn::new(
"path", "path",
|item: &PathBuf, root: &PathBuf| { |item: &PathBuf, root: &PathBuf| {
item.strip_prefix(root) item.strip_prefix(root)

View File

@ -275,7 +275,11 @@ pub struct Picker<T: 'static + Send + Sync, D: 'static> {
} }
impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> { impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
pub fn stream(columns: Vec<Column<T, D>>, editor_data: D) -> (Nucleo<T>, Injector<T, D>) { pub fn stream(
columns: impl IntoIterator<Item = Column<T, D>>,
editor_data: D,
) -> (Nucleo<T>, Injector<T, D>) {
let columns: Arc<[_]> = columns.into_iter().collect();
let matcher_columns = columns.iter().filter(|col| col.filter).count() as u32; let matcher_columns = columns.iter().filter(|col| col.filter).count() as u32;
assert!(matcher_columns > 0); assert!(matcher_columns > 0);
let matcher = Nucleo::new( let matcher = Nucleo::new(
@ -286,7 +290,7 @@ pub fn stream(columns: Vec<Column<T, D>>, editor_data: D) -> (Nucleo<T>, Injecto
); );
let streamer = Injector { let streamer = Injector {
dst: matcher.injector(), dst: matcher.injector(),
columns: columns.into(), columns,
editor_data: Arc::new(editor_data), editor_data: Arc::new(editor_data),
version: 0, version: 0,
picker_version: Arc::new(AtomicUsize::new(0)), picker_version: Arc::new(AtomicUsize::new(0)),
@ -295,13 +299,19 @@ pub fn stream(columns: Vec<Column<T, D>>, editor_data: D) -> (Nucleo<T>, Injecto
(matcher, streamer) (matcher, streamer)
} }
pub fn new( pub fn new<C, O, F>(
columns: Vec<Column<T, D>>, columns: C,
primary_column: usize, primary_column: usize,
options: impl IntoIterator<Item = T>, options: O,
editor_data: D, editor_data: D,
callback_fn: impl Fn(&mut Context, &T, Action) + 'static, callback_fn: F,
) -> Self { ) -> Self
where
C: IntoIterator<Item = Column<T, D>>,
O: IntoIterator<Item = T>,
F: Fn(&mut Context, &T, Action) + 'static,
{
let columns: Arc<[_]> = columns.into_iter().collect();
let matcher_columns = columns.iter().filter(|col| col.filter).count() as u32; let matcher_columns = columns.iter().filter(|col| col.filter).count() as u32;
assert!(matcher_columns > 0); assert!(matcher_columns > 0);
let matcher = Nucleo::new( let matcher = Nucleo::new(
@ -316,7 +326,7 @@ pub fn new(
} }
Self::with( Self::with(
matcher, matcher,
columns.into(), columns,
primary_column, primary_column,
Arc::new(editor_data), Arc::new(editor_data),
Arc::new(AtomicUsize::new(0)), Arc::new(AtomicUsize::new(0)),