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 {
|
impl ProcessQuery for ProcWidgetState {
|
||||||
fn parse_query(&self) -> Result<Query> {
|
fn parse_query(&self) -> Result<Query> {
|
||||||
fn process_string_to_filter(query: &mut VecDeque<String>) -> Result<Query> {
|
fn process_string_to_filter(query: &mut VecDeque<String>) -> Result<Query> {
|
||||||
Ok(Query {
|
let mut lhs: And = process_and(query)?;
|
||||||
query: 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> {
|
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> {
|
fn process_prefix(query: &mut VecDeque<String>) -> Result<Prefix> {
|
||||||
if let Some(queue_top) = query.pop_front() {
|
if let Some(queue_top) = query.pop_front() {
|
||||||
if queue_top == "(" {
|
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
|
// Get content within bracket; and check if paren is complete
|
||||||
let and = process_and(query)?;
|
let and = process_and(query)?;
|
||||||
if let Some(close_paren) = query.pop_front() {
|
if let Some(close_paren) = query.pop_front() {
|
||||||
|
@ -190,6 +210,8 @@ impl ProcessQuery for ProcWidgetState {
|
||||||
condition = Some(QueryComparison::Equal);
|
condition = Some(QueryComparison::Equal);
|
||||||
if let Some(queue_next) = query.pop_front() {
|
if let Some(queue_next) = query.pop_front() {
|
||||||
value = queue_next.parse::<f64>().ok();
|
value = queue_next.parse::<f64>().ok();
|
||||||
|
} else {
|
||||||
|
return Err(QueryError("Missing value".into()));
|
||||||
}
|
}
|
||||||
} else if content == ">" || content == "<" {
|
} else if content == ">" || content == "<" {
|
||||||
// We also have to check if the next string is an "="...
|
// 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() {
|
if let Some(queue_next_next) = query.pop_front() {
|
||||||
value = queue_next_next.parse::<f64>().ok();
|
value = queue_next_next.parse::<f64>().ok();
|
||||||
|
} else {
|
||||||
|
return Err(QueryError("Missing value".into()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
condition = Some(if content == ">" {
|
condition = Some(if content == ">" {
|
||||||
|
@ -211,6 +235,8 @@ impl ProcessQuery for ProcWidgetState {
|
||||||
});
|
});
|
||||||
value = queue_next.parse::<f64>().ok();
|
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();
|
let mut split_query = VecDeque::new();
|
||||||
|
|
|
@ -74,6 +74,7 @@ pub struct AppSearchState {
|
||||||
pub char_cursor_position: usize,
|
pub char_cursor_position: usize,
|
||||||
/// The query
|
/// The query
|
||||||
pub query: Option<Query>,
|
pub query: Option<Query>,
|
||||||
|
pub error_message: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AppSearchState {
|
impl Default for AppSearchState {
|
||||||
|
@ -88,6 +89,7 @@ impl Default for AppSearchState {
|
||||||
cursor_bar: 0,
|
cursor_bar: 0,
|
||||||
char_cursor_position: 0,
|
char_cursor_position: 0,
|
||||||
query: None,
|
query: None,
|
||||||
|
error_message: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,15 +200,21 @@ impl ProcWidgetState {
|
||||||
.current_search_query
|
.current_search_query
|
||||||
.is_empty()
|
.is_empty()
|
||||||
{
|
{
|
||||||
self.process_search_state.search_state.is_invalid_search = false;
|
|
||||||
self.process_search_state.search_state.is_blank_search = true;
|
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.query = Some(parsed_query);
|
|
||||||
self.process_search_state.search_state.is_blank_search = false;
|
|
||||||
self.process_search_state.search_state.is_invalid_search = false;
|
self.process_search_state.search_state.is_invalid_search = false;
|
||||||
|
self.process_search_state.search_state.error_message = None;
|
||||||
} else {
|
} else {
|
||||||
self.process_search_state.search_state.is_blank_search = false;
|
let parsed_query = self.parse_query();
|
||||||
self.process_search_state.search_state.is_invalid_search = true;
|
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;
|
||||||
|
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.previous_scroll_position = 0;
|
||||||
self.scroll_state.current_scroll_position = 0;
|
self.scroll_state.current_scroll_position = 0;
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub struct CanvasColours {
|
||||||
pub graph_style: Style,
|
pub graph_style: Style,
|
||||||
// Full, Medium, Low
|
// Full, Medium, Low
|
||||||
pub battery_bar_styles: Vec<Style>,
|
pub battery_bar_styles: Vec<Style>,
|
||||||
|
pub invalid_query_style: Style,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CanvasColours {
|
impl Default for CanvasColours {
|
||||||
|
@ -60,6 +61,7 @@ impl Default for CanvasColours {
|
||||||
Style::default().fg(Color::Green),
|
Style::default().fg(Color::Green),
|
||||||
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,
|
widget_id: u64,
|
||||||
) {
|
) {
|
||||||
if let Some(process_widget_state) = app_state.proc_state.widget_states.get(&widget_id) {
|
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() {
|
if process_widget_state.is_search_enabled() {
|
||||||
let processes_chunk = Layout::default()
|
let processes_chunk = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
|
@ -335,9 +335,6 @@ impl ProcessTableWidget for Painter {
|
||||||
let search_title = "> ";
|
let search_title = "> ";
|
||||||
|
|
||||||
let num_chars_for_text = search_title.len();
|
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 cursor_position = proc_widget_state.get_cursor_position();
|
||||||
let current_cursor_position = proc_widget_state.get_char_cursor_position();
|
let current_cursor_position = proc_widget_state.get_char_cursor_position();
|
||||||
let is_search_enabled = proc_widget_state.is_search_enabled();
|
let is_search_enabled = proc_widget_state.is_search_enabled();
|
||||||
|
@ -356,6 +353,14 @@ impl ProcessTableWidget for Painter {
|
||||||
app_state.is_force_redraw,
|
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 query = proc_widget_state.get_current_search_query().as_str();
|
||||||
let grapheme_indices = UnicodeSegmentation::grapheme_indices(query, true);
|
let grapheme_indices = UnicodeSegmentation::grapheme_indices(query, true);
|
||||||
let query_with_cursor: Vec<Text<'_>> = build_query(
|
let query_with_cursor: Vec<Text<'_>> = build_query(
|
||||||
|
@ -368,6 +373,8 @@ impl ProcessTableWidget for Painter {
|
||||||
self.colours.text_style,
|
self.colours.text_style,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// TODO: [QUERY] Make text/border go red if error?
|
||||||
|
|
||||||
// Text options shamelessly stolen from VS Code.
|
// Text options shamelessly stolen from VS Code.
|
||||||
let case_style = if !proc_widget_state.process_search_state.is_ignoring_case {
|
let case_style = if !proc_widget_state.process_search_state.is_ignoring_case {
|
||||||
self.colours.currently_selected_text_style
|
self.colours.currently_selected_text_style
|
||||||
|
@ -393,31 +400,43 @@ impl ProcessTableWidget for Painter {
|
||||||
self.colours.text_style
|
self.colours.text_style
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut option_text = vec![];
|
let 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![
|
|
||||||
Text::raw("\n"),
|
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::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::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(query_with_cursor);
|
||||||
|
search_text.push(Text::styled(
|
||||||
|
format!(
|
||||||
|
"\n{}",
|
||||||
|
if let Some(err) = &proc_widget_state
|
||||||
|
.process_search_state
|
||||||
|
.search_state
|
||||||
|
.error_message
|
||||||
|
{
|
||||||
|
err.as_str()
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
),
|
||||||
|
self.colours.invalid_query_style,
|
||||||
|
));
|
||||||
search_text.extend(option_text);
|
search_text.extend(option_text);
|
||||||
|
|
||||||
let current_border_style = if proc_widget_state
|
let current_border_style = if is_on_processes {
|
||||||
.process_search_state
|
|
||||||
.search_state
|
|
||||||
.is_invalid_search
|
|
||||||
{
|
|
||||||
*INVALID_REGEX_STYLE
|
|
||||||
} else if is_on_processes {
|
|
||||||
self.colours.highlighted_border_style
|
self.colours.highlighted_border_style
|
||||||
} else {
|
} else {
|
||||||
self.colours.border_style
|
self.colours.border_style
|
||||||
|
|
|
@ -35,8 +35,6 @@ lazy_static! {
|
||||||
tui::style::Style::default().fg(tui::style::Color::Gray);
|
tui::style::Style::default().fg(tui::style::Color::Gray);
|
||||||
pub static ref DEFAULT_HEADER_STYLE: tui::style::Style =
|
pub static ref DEFAULT_HEADER_STYLE: tui::style::Style =
|
||||||
tui::style::Style::default().fg(tui::style::Color::LightBlue);
|
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
|
// Help text
|
||||||
|
|
|
@ -49,9 +49,7 @@ impl std::fmt::Display for BottomError {
|
||||||
BottomError::ConversionError(ref message) => {
|
BottomError::ConversionError(ref message) => {
|
||||||
write!(f, "unable to convert: {}", message)
|
write!(f, "unable to convert: {}", message)
|
||||||
}
|
}
|
||||||
BottomError::QueryError(ref _message) => {
|
BottomError::QueryError(ref message) => write!(f, "{}", message),
|
||||||
write!(f, "invalid query - this should not be shown!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue