feat(tui): support searching in the kernel parameters

This commit is contained in:
Orhun Parmaksız 2022-01-12 02:53:54 +03:00
parent 0bb24a3838
commit cdffaef310
No known key found for this signature in database
GPG key ID: F83424824B3E4B90
3 changed files with 60 additions and 10 deletions

View file

@ -18,6 +18,8 @@ pub struct App<'a> {
pub input: Option<String>,
/// Time tracker for measuring the time for clearing the input.
pub input_time: Option<Instant>,
/// Whether if the search mode is enabled.
pub search_mode: bool,
/// List of sysctl parameters.
pub parameter_list: StatefulTable<Parameter>,
/// Sysctl controller.
@ -31,6 +33,7 @@ impl<'a> App<'a> {
running: true,
input: None,
input_time: None,
search_mode: false,
parameter_list: StatefulTable::with_items(sysctl.parameters.clone()),
sysctl,
}
@ -41,6 +44,26 @@ impl<'a> App<'a> {
self.input.is_some() && self.input_time.is_none()
}
/// Performs a search operation in the kernel parameter list.
fn search(&mut self) {
if let Some(query) = &self.input {
self.parameter_list.items = self
.sysctl
.parameters
.clone()
.into_iter()
.filter(|param| param.name.contains(query))
.collect();
if self.parameter_list.items.is_empty() {
self.parameter_list.state.select(None);
} else {
self.parameter_list.state.select(Some(0));
}
} else {
self.parameter_list = StatefulTable::with_items(self.sysctl.parameters.clone());
}
}
/// Runs the given command and updates the application.
pub fn run_command(&mut self, command: Command) -> Result<()> {
match command {
@ -50,9 +73,20 @@ impl<'a> App<'a> {
Command::ScrollDown => {
self.parameter_list.next();
}
Command::EnableSearch => {
if self.input_time.is_some() {
self.input_time = None;
}
self.search_mode = true;
self.search();
self.input = Some(String::new());
}
Command::ProcessInput => {
if self.input_time.is_some() {
return Ok(());
} else if self.search_mode {
self.input = None;
self.search_mode = false;
} else if let Some(input) = &self.input {
if let Ok(command) = Command::from_str(input) {
self.run_command(command)?;
@ -62,19 +96,25 @@ impl<'a> App<'a> {
}
}
}
Command::UpdateInput(v) => match self.input.as_mut() {
Some(input) => {
if self.input_time.is_some() {
self.input_time = None;
Command::UpdateInput(v) => {
match self.input.as_mut() {
Some(input) => {
if self.input_time.is_some() {
self.input_time = None;
self.input = Some(String::new());
} else {
input.push(v);
}
}
None => {
self.input = Some(String::new());
} else {
input.push(v);
self.search_mode = false;
}
}
None => {
self.input = Some(String::new());
if self.search_mode {
self.search();
}
},
}
Command::ClearInput(cancel) => {
if self.input_time.is_some() {
return Ok(());
@ -85,6 +125,9 @@ impl<'a> App<'a> {
self.input = None;
}
}
if self.search_mode {
self.search();
}
}
Command::Refresh => {
self.input = None;

View file

@ -8,6 +8,8 @@ pub enum Command {
ScrollUp,
/// Scroll down on the widget.
ScrollDown,
/// Enable the search mode.
EnableSearch,
/// Process the input.
ProcessInput,
/// Update the input buffer.
@ -51,6 +53,7 @@ impl Command {
Key::Up => Command::ScrollUp,
Key::Down => Command::ScrollDown,
Key::Char(':') => Command::UpdateInput(' '),
Key::Char('/') => Command::EnableSearch,
Key::Char('r') => Command::Refresh,
Key::Esc => Command::Exit,
_ => Command::None,

View file

@ -187,7 +187,11 @@ fn render_input_prompt<B: Backend>(
"MSG: "
} else {
frame.set_cursor(input.width() as u16 + 2, cursor_y);
":"
if app.search_mode {
"/"
} else {
":"
}
},
input,
),