mirror of
https://github.com/wez/wezterm.git
synced 2024-11-22 13:16:39 +03:00
parent
b9aec2fcad
commit
348ddcb122
@ -401,7 +401,7 @@ macro_rules! pdu {
|
||||
/// The overall version of the codec.
|
||||
/// This must be bumped when backwards incompatible changes
|
||||
/// are made to the types and protocol.
|
||||
pub const CODEC_VERSION: usize = 9;
|
||||
pub const CODEC_VERSION: usize = 10;
|
||||
|
||||
// Defines the Pdu enum.
|
||||
// Each struct has an explicit identifying number.
|
||||
|
@ -15,6 +15,8 @@ As features stabilize some brief notes about them will accumulate here.
|
||||
|
||||
#### Changed
|
||||
|
||||
* quickselect: we now de-duplicate labels for results with the same textual content. [#1271](https://github.com/wez/wezterm/issues/1271)
|
||||
|
||||
#### Updated and Improved
|
||||
|
||||
* macos: removing the titlebar from `window_decorations` now preserves rounded window corners [#1034](https://github.com/wez/wezterm/issues/1034)
|
||||
|
@ -367,6 +367,7 @@ impl Pane for LocalPane {
|
||||
let mut results = vec![];
|
||||
let mut haystack = String::new();
|
||||
let mut coords = vec![];
|
||||
let mut uniq_matches: HashMap<String, usize> = HashMap::new();
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Coord {
|
||||
@ -389,6 +390,7 @@ impl Pane for LocalPane {
|
||||
pattern: &Pattern,
|
||||
haystack: &str,
|
||||
coords: &[Coord],
|
||||
uniq_matches: &mut HashMap<String, usize>,
|
||||
) {
|
||||
if haystack.is_empty() {
|
||||
return;
|
||||
@ -399,6 +401,14 @@ impl Pane for LocalPane {
|
||||
// haystack strings
|
||||
Pattern::CaseInSensitiveString(s) | Pattern::CaseSensitiveString(s) => {
|
||||
for (idx, s) in haystack.match_indices(s) {
|
||||
let match_id = match uniq_matches.get(s).copied() {
|
||||
Some(id) => id,
|
||||
None => {
|
||||
let id = uniq_matches.len();
|
||||
uniq_matches.insert(s.to_owned(), id);
|
||||
id
|
||||
}
|
||||
};
|
||||
let (start_x, start_y) = haystack_idx_to_coord(idx, coords);
|
||||
let (end_x, end_y) = haystack_idx_to_coord(idx + s.len(), coords);
|
||||
results.push(SearchResult {
|
||||
@ -406,6 +416,7 @@ impl Pane for LocalPane {
|
||||
start_y,
|
||||
end_x,
|
||||
end_y,
|
||||
match_id,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -418,6 +429,16 @@ impl Pane for LocalPane {
|
||||
// `c.iter().rev()` as the capture iterator isn't double-ended.
|
||||
for idx in (0..c.len()).rev() {
|
||||
if let Some(m) = c.get(idx) {
|
||||
let s = m.as_str();
|
||||
let match_id = match uniq_matches.get(s).copied() {
|
||||
Some(id) => id,
|
||||
None => {
|
||||
let id = uniq_matches.len();
|
||||
uniq_matches.insert(s.to_owned(), id);
|
||||
id
|
||||
}
|
||||
};
|
||||
|
||||
let (start_x, start_y) =
|
||||
haystack_idx_to_coord(m.start(), coords);
|
||||
let (end_x, end_y) = haystack_idx_to_coord(m.end(), coords);
|
||||
@ -426,6 +447,7 @@ impl Pane for LocalPane {
|
||||
start_y,
|
||||
end_x,
|
||||
end_y,
|
||||
match_id,
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -468,14 +490,26 @@ impl Pane for LocalPane {
|
||||
haystack.push('\n');
|
||||
}
|
||||
} else {
|
||||
collect_matches(&mut results, &pattern, &haystack, &coords);
|
||||
collect_matches(
|
||||
&mut results,
|
||||
&pattern,
|
||||
&haystack,
|
||||
&coords,
|
||||
&mut uniq_matches,
|
||||
);
|
||||
haystack.clear();
|
||||
coords.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collect_matches(&mut results, &pattern, &haystack, &coords);
|
||||
collect_matches(
|
||||
&mut results,
|
||||
&pattern,
|
||||
&haystack,
|
||||
&coords,
|
||||
&mut uniq_matches,
|
||||
);
|
||||
Ok(results)
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,9 @@ pub struct SearchResult {
|
||||
pub end_y: StableRowIndex,
|
||||
/// The cell index into the line of the end of the match
|
||||
pub end_x: usize,
|
||||
/// An identifier that can be used to group results that have
|
||||
/// the same textual content
|
||||
pub match_id: usize,
|
||||
}
|
||||
|
||||
pub use config::keyassignment::Pattern;
|
||||
|
@ -520,18 +520,38 @@ impl QuickSelectRenderable {
|
||||
}
|
||||
|
||||
fn recompute_results(&mut self) {
|
||||
let num_results = self.results.len();
|
||||
let labels = compute_labels_for_alphabet(&self.config.quick_select_alphabet, num_results);
|
||||
/// Produce the sorted seq of unique match_ids from the results
|
||||
fn compute_uniq_results(results: &[SearchResult]) -> Vec<usize> {
|
||||
let mut ids: Vec<usize> = results.iter().map(|sr| sr.match_id).collect();
|
||||
ids.sort();
|
||||
ids.dedup();
|
||||
ids
|
||||
}
|
||||
|
||||
let uniq_results = compute_uniq_results(&self.results);
|
||||
|
||||
// Label each unique result
|
||||
let labels =
|
||||
compute_labels_for_alphabet(&self.config.quick_select_alphabet, uniq_results.len());
|
||||
self.by_label.clear();
|
||||
|
||||
for ((result_index, res), label) in self
|
||||
.results
|
||||
.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.take(labels.len())
|
||||
.zip(labels.into_iter())
|
||||
{
|
||||
// Keep track of match_id -> label
|
||||
let mut assigned_labels: HashMap<usize, usize> = HashMap::new();
|
||||
|
||||
// Work through the results in reverse order, so that we assign eg: `a` to the
|
||||
// bottom-right-most result first and so on
|
||||
for (result_index, res) in self.results.iter().enumerate().rev() {
|
||||
// Figure out which label to use based on the match_id
|
||||
let label_index = match assigned_labels.get(&res.match_id).copied() {
|
||||
Some(idx) => idx,
|
||||
None => {
|
||||
let idx = assigned_labels.len();
|
||||
assigned_labels.insert(res.match_id, idx);
|
||||
idx
|
||||
}
|
||||
};
|
||||
let label = &labels[label_index];
|
||||
|
||||
self.by_label.insert(label.clone(), result_index);
|
||||
for idx in res.start_y..=res.end_y {
|
||||
let range = if idx == res.start_y && idx == res.end_y {
|
||||
|
Loading…
Reference in New Issue
Block a user