mirror of
https://github.com/nushell/nushell
synced 2024-11-10 15:14:14 +00:00
Fix find puts extra cols into record (#9397)
# Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> Trying to fix #9394. The problem with PR #9159 seems to be when searching for multiple terms, each term is checked against the original values. It outputs a new value for each such check, thus introducing replication for each search term. As a result, it works fine with num of search term = 1.
This commit is contained in:
parent
0bdc362e13
commit
e9508b578a
2 changed files with 58 additions and 30 deletions
|
@ -1,3 +1,4 @@
|
|||
use itertools::Itertools;
|
||||
use nu_cmd_lang::help::highlight_search_string;
|
||||
|
||||
use fancy_regex::Regex;
|
||||
|
@ -292,9 +293,9 @@ fn record_matches_regex(values: &[Value], re: &Regex, config: &Config) -> bool {
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
fn highlight_terms_in_record_with_search_columns(
|
||||
search_cols: &Vec<String>,
|
||||
cols: &mut [String],
|
||||
vals: &mut Vec<Value>,
|
||||
span: &mut Span,
|
||||
cols: &[String],
|
||||
vals: &[Value],
|
||||
span: &Span,
|
||||
config: &Config,
|
||||
terms: &[Value],
|
||||
string_style: Style,
|
||||
|
@ -305,38 +306,40 @@ fn highlight_terms_in_record_with_search_columns(
|
|||
} else {
|
||||
search_cols.to_vec()
|
||||
};
|
||||
let mut output = vec![];
|
||||
let term_strs: Vec<_> = terms.iter().map(|v| v.into_string("", config)).collect();
|
||||
|
||||
// We iterate every column in the record and every search term for matches
|
||||
for (cur_col, val) in cols.iter().zip(vals) {
|
||||
// iterator of Ok((val_str, term_str)) pairs if the value should be highlighted, otherwise Err(val)
|
||||
let try_val_highlight = vals.iter().zip(cols).map(|(val, col)| {
|
||||
let val_str = val.into_string("", config);
|
||||
for term in terms {
|
||||
let term_str = term.into_string("", config);
|
||||
let output_value =
|
||||
if contains_ignore_case(&val_str, &term_str) && cols_to_search.contains(cur_col) {
|
||||
let highlighted_str = match highlight_search_string(
|
||||
&val_str,
|
||||
&term_str,
|
||||
&string_style,
|
||||
&highlight_style,
|
||||
) {
|
||||
Ok(highlighted_str) => highlighted_str,
|
||||
Err(_) => string_style.paint(term_str).to_string(),
|
||||
};
|
||||
Value::String {
|
||||
val: highlighted_str,
|
||||
span: *span,
|
||||
}
|
||||
} else {
|
||||
val.clone()
|
||||
};
|
||||
output.push(output_value);
|
||||
}
|
||||
}
|
||||
let predicate = cols_to_search.contains(col);
|
||||
predicate
|
||||
.then_some(val_str)
|
||||
.and_then(|val_str| {
|
||||
term_strs
|
||||
.iter()
|
||||
.find(|term_str| contains_ignore_case(&val_str, term_str))
|
||||
.map(|term_str| (val_str, term_str))
|
||||
})
|
||||
.ok_or_else(|| val.clone())
|
||||
});
|
||||
|
||||
// turn Ok pairs into vals of highlighted strings, Err vals is original vals
|
||||
let new_vals = try_val_highlight
|
||||
.map_ok(|(val_str, term_str)| {
|
||||
let highlighted_str =
|
||||
highlight_search_string(&val_str, term_str, &string_style, &highlight_style)
|
||||
.unwrap_or_else(|_| string_style.paint(term_str).to_string());
|
||||
|
||||
Value::String {
|
||||
val: highlighted_str,
|
||||
span: *span,
|
||||
}
|
||||
})
|
||||
.map(|v| v.unwrap_or_else(|v| v));
|
||||
|
||||
Value::Record {
|
||||
cols: cols.to_vec(),
|
||||
vals: output,
|
||||
vals: new_vals.collect(),
|
||||
span: *span,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,3 +94,28 @@ fn inverted_find_in_table_keeps_row_if_none_of_the_selected_columns_matches() {
|
|||
|
||||
assert_eq!(actual.out, r#"["Maurice"]"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_in_table_keeps_row_with_single_matched_and_keeps_other_columns() {
|
||||
let actual = nu!("[[name nickname Age]; [Maurice moe 23] [Laurence larry 67] [William will 18]] | find Maurice");
|
||||
|
||||
println!("{:?}", actual.out);
|
||||
assert!(actual.out.contains("moe"));
|
||||
assert!(actual.out.contains("Maurice"));
|
||||
assert!(actual.out.contains("23"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_in_table_keeps_row_with_multiple_matched_and_keeps_other_columns() {
|
||||
let actual = nu!("[[name nickname Age]; [Maurice moe 23] [Laurence larry 67] [William will 18] [William bill 60]] | find moe William");
|
||||
|
||||
println!("{:?}", actual.out);
|
||||
assert!(actual.out.contains("moe"));
|
||||
assert!(actual.out.contains("Maurice"));
|
||||
assert!(actual.out.contains("23"));
|
||||
assert!(actual.out.contains("William"));
|
||||
assert!(actual.out.contains("will"));
|
||||
assert!(actual.out.contains("18"));
|
||||
assert!(actual.out.contains("bill"));
|
||||
assert!(actual.out.contains("60"));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue