bug: fix bug with multiple tokens
This commit is contained in:
parent
e12c2f5212
commit
8307b06c56
|
@ -39,9 +39,25 @@ pub trait ProcessQuery {
|
|||
impl ProcessQuery for ProcWidgetState {
|
||||
fn parse_query(&self) -> Result<Query> {
|
||||
fn process_string_to_filter(query: &mut VecDeque<String>) -> Result<Query> {
|
||||
Ok(Query {
|
||||
query: process_and(query)?,
|
||||
})
|
||||
let mut lhs: And = process_and(query)?;
|
||||
|
||||
while query.front().is_some() {
|
||||
let rhs = Some(Box::new(process_or(query)?));
|
||||
|
||||
lhs = And {
|
||||
lhs: Or {
|
||||
lhs: Prefix {
|
||||
and: Some(Box::from(lhs)),
|
||||
compare_prefix: None,
|
||||
regex_prefix: None,
|
||||
},
|
||||
rhs: None,
|
||||
},
|
||||
rhs,
|
||||
};
|
||||
}
|
||||
|
||||
Ok(Query { query: lhs })
|
||||
}
|
||||
|
||||
fn process_and(query: &mut VecDeque<String>) -> Result<And> {
|
||||
|
@ -113,6 +129,10 @@ impl ProcessQuery for ProcWidgetState {
|
|||
fn process_prefix(query: &mut VecDeque<String>) -> Result<Prefix> {
|
||||
if let Some(queue_top) = query.pop_front() {
|
||||
if queue_top == "(" {
|
||||
if query.front().is_none() {
|
||||
return Err(QueryError("Missing closing parentheses".into()));
|
||||
}
|
||||
|
||||
// Get content within bracket; and check if paren is complete
|
||||
let and = process_and(query)?;
|
||||
if let Some(close_paren) = query.pop_front() {
|
||||
|
@ -190,6 +210,8 @@ impl ProcessQuery for ProcWidgetState {
|
|||
condition = Some(QueryComparison::Equal);
|
||||
if let Some(queue_next) = query.pop_front() {
|
||||
value = queue_next.parse::<f64>().ok();
|
||||
} else {
|
||||
return Err(QueryError("Missing value".into()));
|
||||
}
|
||||
} else if content == ">" || content == "<" {
|
||||
// We also have to check if the next string is an "="...
|
||||
|
@ -202,6 +224,8 @@ impl ProcessQuery for ProcWidgetState {
|
|||
});
|
||||
if let Some(queue_next_next) = query.pop_front() {
|
||||
value = queue_next_next.parse::<f64>().ok();
|
||||
} else {
|
||||
return Err(QueryError("Missing value".into()));
|
||||
}
|
||||
} else {
|
||||
condition = Some(if content == ">" {
|
||||
|
@ -211,6 +235,8 @@ impl ProcessQuery for ProcWidgetState {
|
|||
});
|
||||
value = queue_next.parse::<f64>().ok();
|
||||
}
|
||||
} else {
|
||||
return Err(QueryError("Missing value".into()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,11 +312,13 @@ impl ProcessQuery for ProcWidgetState {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(QueryError("Missing argument for search prefix".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(QueryError("Failed to parse comparator.".into()))
|
||||
Err(QueryError("Invalid search".into()))
|
||||
}
|
||||
|
||||
let mut split_query = VecDeque::new();
|
||||
|
|
|
@ -74,6 +74,7 @@ pub struct AppSearchState {
|
|||
pub char_cursor_position: usize,
|
||||
/// The query
|
||||
pub query: Option<Query>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for AppSearchState {
|
||||
|
@ -88,6 +89,7 @@ impl Default for AppSearchState {
|
|||
cursor_bar: 0,
|
||||
char_cursor_position: 0,
|
||||
query: None,
|
||||
error_message: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,15 +200,21 @@ impl ProcWidgetState {
|
|||
.current_search_query
|
||||
.is_empty()
|
||||
{
|
||||
self.process_search_state.search_state.is_invalid_search = false;
|
||||
self.process_search_state.search_state.is_blank_search = true;
|
||||
} else if let Ok(parsed_query) = self.parse_query() {
|
||||
self.process_search_state.search_state.is_invalid_search = false;
|
||||
self.process_search_state.search_state.error_message = None;
|
||||
} else {
|
||||
let parsed_query = self.parse_query();
|
||||
if let Ok(parsed_query) = parsed_query {
|
||||
self.process_search_state.search_state.query = Some(parsed_query);
|
||||
self.process_search_state.search_state.is_blank_search = false;
|
||||
self.process_search_state.search_state.is_invalid_search = false;
|
||||
} else {
|
||||
self.process_search_state.search_state.error_message = None;
|
||||
} else if let Err(err) = parsed_query {
|
||||
self.process_search_state.search_state.is_blank_search = false;
|
||||
self.process_search_state.search_state.is_invalid_search = true;
|
||||
self.process_search_state.search_state.error_message = Some(err.to_string());
|
||||
}
|
||||
}
|
||||
self.scroll_state.previous_scroll_position = 0;
|
||||
self.scroll_state.current_scroll_position = 0;
|
||||
|
|
|
@ -26,6 +26,7 @@ pub struct CanvasColours {
|
|||
pub graph_style: Style,
|
||||
// Full, Medium, Low
|
||||
pub battery_bar_styles: Vec<Style>,
|
||||
pub invalid_query_style: Style,
|
||||
}
|
||||
|
||||
impl Default for CanvasColours {
|
||||
|
@ -60,6 +61,7 @@ impl Default for CanvasColours {
|
|||
Style::default().fg(Color::Green),
|
||||
Style::default().fg(Color::Green),
|
||||
],
|
||||
invalid_query_style: tui::style::Style::default().fg(tui::style::Color::Red),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ impl ProcessTableWidget for Painter {
|
|||
widget_id: u64,
|
||||
) {
|
||||
if let Some(process_widget_state) = app_state.proc_state.widget_states.get(&widget_id) {
|
||||
let search_height = if draw_border { 3 } else { 2 };
|
||||
let search_height = if draw_border { 4 } else { 3 };
|
||||
if process_widget_state.is_search_enabled() {
|
||||
let processes_chunk = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
|
@ -335,9 +335,6 @@ impl ProcessTableWidget for Painter {
|
|||
let search_title = "> ";
|
||||
|
||||
let num_chars_for_text = search_title.len();
|
||||
|
||||
let mut search_text = vec![Text::styled(search_title, self.colours.table_header_style)];
|
||||
|
||||
let cursor_position = proc_widget_state.get_cursor_position();
|
||||
let current_cursor_position = proc_widget_state.get_char_cursor_position();
|
||||
let is_search_enabled = proc_widget_state.is_search_enabled();
|
||||
|
@ -356,6 +353,14 @@ impl ProcessTableWidget for Painter {
|
|||
app_state.is_force_redraw,
|
||||
);
|
||||
|
||||
let mut search_text = vec![Text::styled(
|
||||
search_title,
|
||||
if is_on_widget {
|
||||
self.colours.table_header_style
|
||||
} else {
|
||||
self.colours.text_style
|
||||
},
|
||||
)];
|
||||
let query = proc_widget_state.get_current_search_query().as_str();
|
||||
let grapheme_indices = UnicodeSegmentation::grapheme_indices(query, true);
|
||||
let query_with_cursor: Vec<Text<'_>> = build_query(
|
||||
|
@ -368,6 +373,8 @@ impl ProcessTableWidget for Painter {
|
|||
self.colours.text_style,
|
||||
);
|
||||
|
||||
// TODO: [QUERY] Make text/border go red if error?
|
||||
|
||||
// Text options shamelessly stolen from VS Code.
|
||||
let case_style = if !proc_widget_state.process_search_state.is_ignoring_case {
|
||||
self.colours.currently_selected_text_style
|
||||
|
@ -393,31 +400,43 @@ impl ProcessTableWidget for Painter {
|
|||
self.colours.text_style
|
||||
};
|
||||
|
||||
let mut option_text = vec![];
|
||||
let case_text = format!("Case({})", if self.is_mac_os { "F1" } else { "Alt+C" },);
|
||||
let whole_text = format!("Whole({})", if self.is_mac_os { "F2" } else { "Alt+W" },);
|
||||
let regex_text = format!("Regex({})", if self.is_mac_os { "F3" } else { "Alt+R" },);
|
||||
|
||||
let option_row = vec![
|
||||
let option_text = vec![
|
||||
Text::raw("\n"),
|
||||
Text::styled(&case_text, case_style),
|
||||
Text::styled(
|
||||
format!("Case({})", if self.is_mac_os { "F1" } else { "Alt+C" }),
|
||||
case_style,
|
||||
),
|
||||
Text::raw(" "),
|
||||
Text::styled(&whole_text, whole_word_style),
|
||||
Text::styled(
|
||||
format!("Whole({})", if self.is_mac_os { "F2" } else { "Alt+W" }),
|
||||
whole_word_style,
|
||||
),
|
||||
Text::raw(" "),
|
||||
Text::styled(®ex_text, regex_style),
|
||||
Text::styled(
|
||||
format!("Regex({})", if self.is_mac_os { "F3" } else { "Alt+R" }),
|
||||
regex_style,
|
||||
),
|
||||
];
|
||||
option_text.extend(option_row);
|
||||
|
||||
search_text.extend(query_with_cursor);
|
||||
search_text.extend(option_text);
|
||||
|
||||
let current_border_style = if proc_widget_state
|
||||
search_text.push(Text::styled(
|
||||
format!(
|
||||
"\n{}",
|
||||
if let Some(err) = &proc_widget_state
|
||||
.process_search_state
|
||||
.search_state
|
||||
.is_invalid_search
|
||||
.error_message
|
||||
{
|
||||
*INVALID_REGEX_STYLE
|
||||
} else if is_on_processes {
|
||||
err.as_str()
|
||||
} else {
|
||||
""
|
||||
}
|
||||
),
|
||||
self.colours.invalid_query_style,
|
||||
));
|
||||
search_text.extend(option_text);
|
||||
|
||||
let current_border_style = if is_on_processes {
|
||||
self.colours.highlighted_border_style
|
||||
} else {
|
||||
self.colours.border_style
|
||||
|
|
|
@ -35,8 +35,6 @@ lazy_static! {
|
|||
tui::style::Style::default().fg(tui::style::Color::Gray);
|
||||
pub static ref DEFAULT_HEADER_STYLE: tui::style::Style =
|
||||
tui::style::Style::default().fg(tui::style::Color::LightBlue);
|
||||
pub static ref INVALID_REGEX_STYLE: tui::style::Style =
|
||||
tui::style::Style::default().fg(tui::style::Color::Red);
|
||||
}
|
||||
|
||||
// Help text
|
||||
|
|
|
@ -49,9 +49,7 @@ impl std::fmt::Display for BottomError {
|
|||
BottomError::ConversionError(ref message) => {
|
||||
write!(f, "unable to convert: {}", message)
|
||||
}
|
||||
BottomError::QueryError(ref _message) => {
|
||||
write!(f, "invalid query - this should not be shown!")
|
||||
}
|
||||
BottomError::QueryError(ref message) => write!(f, "{}", message),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue