pull/12520/merge
Nik Revenco 2025-06-15 22:41:15 -07:00 committed by GitHub
commit 4a34d06853
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 43 additions and 17 deletions

View File

@ -2663,7 +2663,8 @@ fn global_search(cx: &mut Context) {
Some((path.as_path().into(), Some((*line_num, *line_num)))) Some((path.as_path().into(), Some((*line_num, *line_num))))
}) })
.with_history_register(Some(reg)) .with_history_register(Some(reg))
.with_dynamic_query(get_files, Some(275)); .with_dynamic_query(get_files, Some(275))
.with_title("Search".into());
cx.push_layer(Box::new(overlaid(picker))); cx.push_layer(Box::new(overlaid(picker)));
} }
@ -3199,7 +3200,8 @@ fn buffer_picker(cx: &mut Context) {
(cursor_line, cursor_line) (cursor_line, cursor_line)
}); });
Some((meta.id.into(), lines)) Some((meta.id.into(), lines))
}); })
.with_title("Buffers".into());
cx.push_layer(Box::new(overlaid(picker))); cx.push_layer(Box::new(overlaid(picker)));
} }
@ -3290,7 +3292,8 @@ fn jumplist_picker(cx: &mut Context) {
let doc = &editor.documents.get(&meta.id)?; let doc = &editor.documents.get(&meta.id)?;
let line = meta.selection.primary().cursor_line(doc.text().slice(..)); let line = meta.selection.primary().cursor_line(doc.text().slice(..));
Some((meta.id.into(), Some((line, line)))) Some((meta.id.into(), Some((line, line))))
}); })
.with_title("Jump List".into());
cx.push_layer(Box::new(overlaid(picker))); cx.push_layer(Box::new(overlaid(picker)));
} }
@ -3372,7 +3375,8 @@ fn changed_file_picker(cx: &mut Context) {
} }
}, },
) )
.with_preview(|_editor, meta| Some((meta.path().into(), None))); .with_preview(|_editor, meta| Some((meta.path().into(), None)))
.with_title("Changed Files".into());
let injector = picker.injector(); let injector = picker.injector();
cx.editor cx.editor
@ -3464,7 +3468,8 @@ pub fn command_palette(cx: &mut Context) {
doc.append_changes_to_history(view); doc.append_changes_to_history(view);
} }
} }
}); })
.with_title("Command Palette".into());
compositor.push(Box::new(overlaid(picker))); compositor.push(Box::new(overlaid(picker)));
}, },
)); ));

View File

@ -296,6 +296,7 @@ fn diag_picker(
}, },
) )
.with_preview(move |_editor, diag| location_to_file_location(&diag.location)) .with_preview(move |_editor, diag| location_to_file_location(&diag.location))
.with_title("Diagnostics".into())
.truncate_start(false) .truncate_start(false)
} }
@ -424,6 +425,7 @@ pub fn symbol_picker(cx: &mut Context) {
}, },
) )
.with_preview(move |_editor, item| location_to_file_location(&item.location)) .with_preview(move |_editor, item| location_to_file_location(&item.location))
.with_title("Document Symbols".into())
.truncate_start(false); .truncate_start(false);
compositor.push(Box::new(overlaid(picker))) compositor.push(Box::new(overlaid(picker)))
@ -551,6 +553,7 @@ pub fn workspace_symbol_picker(cx: &mut Context) {
) )
.with_preview(|_editor, item| location_to_file_location(&item.location)) .with_preview(|_editor, item| location_to_file_location(&item.location))
.with_dynamic_query(get_symbols, None) .with_dynamic_query(get_symbols, None)
.with_title("Workspace Symbols".into())
.truncate_start(false); .truncate_start(false);
cx.push_layer(Box::new(overlaid(picker))); cx.push_layer(Box::new(overlaid(picker)));
@ -841,7 +844,12 @@ impl Display for ApplyEditErrorKind {
} }
/// Precondition: `locations` should be non-empty. /// Precondition: `locations` should be non-empty.
fn goto_impl(editor: &mut Editor, compositor: &mut Compositor, locations: Vec<Location>) { fn goto_impl(
title: &'static str,
editor: &mut Editor,
compositor: &mut Compositor,
locations: Vec<Location>,
) {
let cwdir = helix_stdx::env::current_working_dir(); let cwdir = helix_stdx::env::current_working_dir();
match locations.as_slice() { match locations.as_slice() {
@ -866,7 +874,8 @@ fn goto_impl(editor: &mut Editor, compositor: &mut Compositor, locations: Vec<Lo
let picker = Picker::new(columns, 0, locations, cwdir, |cx, location, action| { let picker = Picker::new(columns, 0, locations, cwdir, |cx, location, action| {
jump_to_location(cx.editor, location, action) jump_to_location(cx.editor, location, action)
}) })
.with_preview(|_editor, location| location_to_file_location(location)); .with_preview(|_editor, location| location_to_file_location(location))
.with_title(title.into());
compositor.push(Box::new(overlaid(picker))); compositor.push(Box::new(overlaid(picker)));
} }
} }
@ -925,7 +934,7 @@ where
if locations.is_empty() { if locations.is_empty() {
editor.set_error("No definition found."); editor.set_error("No definition found.");
} else { } else {
goto_impl(editor, compositor, locations); goto_impl("Goto Implementation", editor, compositor, locations);
} }
}; };
Ok(Callback::EditorCompositor(Box::new(call))) Ok(Callback::EditorCompositor(Box::new(call)))
@ -1002,7 +1011,7 @@ pub fn goto_reference(cx: &mut Context) {
if locations.is_empty() { if locations.is_empty() {
editor.set_error("No references found."); editor.set_error("No references found.");
} else { } else {
goto_impl(editor, compositor, locations); goto_impl("Goto Reference", editor, compositor, locations);
} }
}; };
Ok(Callback::EditorCompositor(Box::new(call))) Ok(Callback::EditorCompositor(Box::new(call)))

View File

@ -1460,7 +1460,8 @@ fn lsp_workspace_command(
move |cx, (ls_id, command), _action| { move |cx, (ls_id, command), _action| {
cx.editor.execute_lsp_command(command.clone(), *ls_id); cx.editor.execute_lsp_command(command.clone(), *ls_id);
}, },
); )
.with_title("LSP Commands".into());
compositor.push(Box::new(overlaid(picker))) compositor.push(Box::new(overlaid(picker)))
}, },
)); ));

View File

@ -274,7 +274,8 @@ pub fn file_picker(editor: &Editor, root: PathBuf) -> FilePicker {
cx.editor.set_error(err); cx.editor.set_error(err);
} }
}) })
.with_preview(|_editor, path| Some((path.as_path().into(), None))); .with_preview(|_editor, path| Some((path.as_path().into(), None)))
.with_title("Files".into());
let injector = picker.injector(); let injector = picker.injector();
let timeout = std::time::Instant::now() + std::time::Duration::from_millis(30); let timeout = std::time::Instant::now() + std::time::Duration::from_millis(30);
@ -321,7 +322,7 @@ pub fn file_explorer(root: PathBuf, editor: &Editor) -> Result<FileExplorer, std
columns, columns,
0, 0,
directory_content, directory_content,
(root, directory_style), (root.clone(), directory_style),
move |cx, (path, is_dir): &(PathBuf, bool), action| { move |cx, (path, is_dir): &(PathBuf, bool), action| {
if *is_dir { if *is_dir {
let new_root = helix_stdx::path::normalize(path); let new_root = helix_stdx::path::normalize(path);
@ -345,7 +346,8 @@ pub fn file_explorer(root: PathBuf, editor: &Editor) -> Result<FileExplorer, std
} }
}, },
) )
.with_preview(|_editor, (path, _is_dir)| Some((path.as_path().into(), None))); .with_preview(|_editor, (path, _is_dir)| Some((path.as_path().into(), None)))
.with_title("File Explorer".into());
Ok(picker) Ok(picker)
} }

View File

@ -268,6 +268,7 @@ pub struct Picker<T: 'static + Send + Sync, D: 'static> {
/// An event handler for syntax highlighting the currently previewed file. /// An event handler for syntax highlighting the currently previewed file.
preview_highlight_handler: Sender<Arc<Path>>, preview_highlight_handler: Sender<Arc<Path>>,
dynamic_query_handler: Option<Sender<DynamicQueryChange>>, dynamic_query_handler: Option<Sender<DynamicQueryChange>>,
title: Option<Spans<'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> {
@ -389,6 +390,7 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
file_fn: None, file_fn: None,
preview_highlight_handler: PreviewHighlightHandler::<T, D>::default().spawn(), preview_highlight_handler: PreviewHighlightHandler::<T, D>::default().spawn(),
dynamic_query_handler: None, dynamic_query_handler: None,
title: None,
} }
} }
@ -408,6 +410,11 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
self self
} }
pub fn with_title(mut self, title: Spans<'static>) -> Self {
self.title = Some(title);
self
}
pub fn with_preview( pub fn with_preview(
mut self, mut self,
preview_fn: impl for<'a> Fn(&'a Editor, &'a T) -> Option<FileLocation<'a>> + 'static, preview_fn: impl for<'a> Fn(&'a Editor, &'a T) -> Option<FileLocation<'a>> + 'static,
@ -680,12 +687,14 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
let background = cx.editor.theme.get("ui.background"); let background = cx.editor.theme.get("ui.background");
surface.clear_with(area, background); surface.clear_with(area, background);
const BLOCK: Block<'_> = Block::bordered(); let block: Block<'_> = self.title.as_ref().map_or(Block::bordered(), |title| {
Block::bordered().title(title.clone())
});
// calculate the inner area inside the box // calculate the inner area inside the box
let inner = BLOCK.inner(area); let inner = block.inner(area);
BLOCK.render(area, surface); block.render(area, surface);
// -- Render the input bar: // -- Render the input bar:
@ -991,7 +1000,7 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
impl<I: 'static + Send + Sync, D: 'static + Send + Sync> Component for Picker<I, D> { impl<I: 'static + Send + Sync, D: 'static + Send + Sync> Component for Picker<I, D> {
fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) { fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {
// +---------+ +---------+ // +--title--+ +---------+
// |prompt | |preview | // |prompt | |preview |
// +---------+ | | // +---------+ | |
// |picker | | | // |picker | | |