pub struct Picker<T: Send + Sync + 'static, R> { /* private fields */ }Expand description
A fuzzy matching interactive item picker.
The parameter T is the item type and the parameter R is the renderer, which
describes how to represent T in the match list.
Initialize a picker with Picker::new, or with custom configuration using
PickerOptions, and add elements to the picker using an Injector returned
by the Picker::injector method.
use nucleo_picker::{render::StrRenderer, Picker};
// Initialize a picker using default settings, with item type `String`
let picker: Picker<String, _> = Picker::new(StrRenderer);See also the usage examples.
§Picker variants
The picker can be run in a number of different modes.
- The simplest (and most common) method is to use
Picker::pick. - If you wish to customize keybindings, use
Picker::pick_with_keybind. - If you wish to customize all IO to the picker, use
Picker::pick_with_io.
§A note on memory usage
Initializing a picker is a relatively expensive operation since the internal match engine uses an arena-based memory approach to minimize allocator costs, and this memory is initialized when the picker is created.
To re-use the picker without additional start-up costs, use the Picker::restart method.
§Example
Run the picker on Stdout with no interactivity checks, and quitting
gracefully on ctrl + c.
use std::io;
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
use nucleo_picker::{
Picker,
event::{Event, StdinReader, keybind_default},
render::StrRenderer,
};
/// Keybindings which use the default keybindings, but instead of aborting on `ctrl + c`,
/// simply perform a normal quit action.
fn keybind_no_interrupt(key_event: KeyEvent) -> Option<Event> {
match key_event {
KeyEvent {
kind: KeyEventKind::Press,
modifiers: KeyModifiers::CONTROL,
code: KeyCode::Char('c'),
..
} => Some(Event::Quit),
e => keybind_default(e),
}
}
fn main() -> io::Result<()> {
let mut picker = Picker::new(StrRenderer);
let choices = vec![
"Alvar Aalto",
"Frank Lloyd Wright",
"Zaha Hadid",
"Le Corbusier",
];
// populate the matcher using the convenience 'extend' implementation
picker.extend(choices);
// launch the interactive picker with the customized keybindings, and draw the picker on
// standard output
match picker.pick_with_io(
StdinReader::new(keybind_no_interrupt),
&mut std::io::stdout(),
)? {
Some(opt) => println!("Your preferred architect is: '{opt}'"),
None => println!("No architect selected!"),
}
Ok(())
}Implementations§
Source§impl<T: Send + Sync + 'static, R: Render<T>> Picker<T, R>
impl<T: Send + Sync + 'static, R: Render<T>> Picker<T, R>
Sourcepub fn new(render: R) -> Self
pub fn new(render: R) -> Self
Initialize a new picker with default configuration and the provided renderer.
Sourcepub fn update_query<Q: Into<String>>(&mut self, query: Q)
pub fn update_query<Q: Into<String>>(&mut self, query: Q)
Update the default query string. This is mainly useful for modifying the query string
before re-using the Picker.
See the PickerOptions::query method to set the query during initialization, and
PromptEvent::Reset to reset the query during interactive
use.
Sourcepub fn query(&self) -> &str
pub fn query(&self) -> &str
Returns the contents of the query string internal to the picker.
If called after running Picker::pick, this will contain the contents of the query string
at the moment that the item was selected or the picker quit.
Sourcepub fn injector_observer(
&mut self,
with_injector: bool,
) -> Observer<Injector<T, R>>
pub fn injector_observer( &mut self, with_injector: bool, ) -> Observer<Injector<T, R>>
Returns an Observer containing up-to-date Injectors for this picker. For example,
this is the channel to which new injectors will be sent when the picker processes a
restart event. See the Event documentation for more detail.
Restart events are not generated by this library. You only need this channel if you generate restart events in your own code.
If with_injector is true, the channel is intialized with an injector currently valid
for the picker on creation.
Sourcepub fn update_config(&mut self, config: Config)
pub fn update_config(&mut self, config: Config)
Update the internal nucleo configuration.
Sourcepub fn restart(&mut self)
pub fn restart(&mut self)
Restart the match engine, disconnecting all active injectors and clearing the existing search query.
Internally, this is a call to Nucleo::restart with clear_snapshot = true.
See the documentation for Nucleo::restart for more detail.
This method is mainly useful for re-using the picker for multiple matches since the
internal memory buffers are preserved. To restart the picker during interactive use, see
the Event documentation or the restart
example.
Sourcepub fn reset_renderer(&mut self, render: R)
pub fn reset_renderer(&mut self, render: R)
Restart the match engine, disconnecting all active injectors and replacing the internal renderer.
The provided Render implementation must be the same type as the one originally
provided; this is most useful for stateful renderers.
See Picker::restart and Nucleo::restart for more detail.
Sourcepub fn render<'a>(&self, item: &'a T) -> <R as Render<T>>::Str<'a>
pub fn render<'a>(&self, item: &'a T) -> <R as Render<T>>::Str<'a>
A convenience method to obtain the rendered version of an item as it would appear in the picker.
This is the same as calling Render::render on the Render implementation internal
to the picker.
Sourcepub fn pick(&mut self) -> Result<Option<&T>, PickError>
pub fn pick(&mut self) -> Result<Option<&T>, PickError>
Open the interactive picker prompt and return the picked item, if any.
§Stderr lock
The picker prompt is rendered in an alternate screen using the stderr file handle. In
order to prevent screen corruption, a lock is acquired to stderr; see
StderrLock for more detail.
In particular, while the picker is interactive, any other thread which attempts to write to
stderr will block. Note that stdin and stdout will remain fully interactive.
§IO customization
To further customize the IO behaviour of the picker, such as to provide your own writer
(for instance to write to Stdout instead) or use custom keybindings,
see the pick_with_io and
pick_with_keybind methods.
§Errors
Underlying IO errors from the standard library or crossterm will be propagated with the
PickError::IO variant.
This method also fails with:
PickError::NotInteractiveif stderr is not interactive.PickError::UserInterruptedif the user pressesctrl + c.
This method will never return PickError::Disconnected.
Sourcepub fn pick_with_keybind<F: FnMut(KeyEvent) -> Option<Event>>(
&mut self,
keybind: F,
) -> Result<Option<&T>, PickError>
pub fn pick_with_keybind<F: FnMut(KeyEvent) -> Option<Event>>( &mut self, keybind: F, ) -> Result<Option<&T>, PickError>
Open the interactive picker prompt and return the picked item, if any. Uses the provided keybindings for the interactive picker.
The picker prompt is rendered in an alternate screen using the stderr file handle. See
the pick method for more detail.
To further customize event generation, see the pick_with_io method.
The pick method is internally a call to this method with keybindings
provided by keybind_default.
§Errors
Underlying IO errors from the standard library or crossterm will be propagated with the
PickError::IO variant.
This method also fails with:
PickError::NotInteractiveif stderr is not interactive.PickError::UserInterruptedif a keybinding results in aEvent::UserInterrupt,
This method will never return PickError::Disconnected.
Sourcepub fn pick_with_io<E, W>(
&mut self,
event_source: E,
writer: &mut W,
) -> Result<Option<&T>, PickError<<E as EventSource>::AbortErr>>where
E: EventSource,
W: Write,
pub fn pick_with_io<E, W>(
&mut self,
event_source: E,
writer: &mut W,
) -> Result<Option<&T>, PickError<<E as EventSource>::AbortErr>>where
E: EventSource,
W: Write,
Run the picker interactively with a custom event source and writer.
The picker is rendered using the given writer. In most situations, you want to check that
the writer is interactive using, for instance, IsTerminal. The picker reads
events from the EventSource to update the screen. See the docs for EventSource
for more detail.
§Errors
Underlying IO errors from the standard library or crossterm will be propagated with the
PickError::IO variant.
Whether or not this fails with another PickError variant depends on the EventSource
implementation:
- If
EventSource::recv_timeoutfails with aRecvError::Disconnected, the error returned will bePickError::Disconnected. - The error will be
PickError::UserInterruptedif thePickerreceives anEvent::UserInterrupt. - The error will be
PickError::Abortedif thePickerreceives anEvent::Abort.
This method will never return PickError::NotInteractive since interactivity checks
are not done.
Trait Implementations§
Source§impl<T: Send + Sync + 'static, R: Render<T>> Extend<T> for Picker<T, R>
impl<T: Send + Sync + 'static, R: Render<T>> Extend<T> for Picker<T, R>
Source§fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)Auto Trait Implementations§
impl<T, R> Freeze for Picker<T, R>
impl<T, R> !RefUnwindSafe for Picker<T, R>
impl<T, R> Send for Picker<T, R>
impl<T, R> Sync for Picker<T, R>
impl<T, R> Unpin for Picker<T, R>
impl<T, R> !UnwindSafe for Picker<T, R>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more