mirror of
https://github.com/wez/wezterm.git
synced 2024-11-27 12:23:46 +03:00
implement new pane trait methods for copy and quickselect overlays
This commit is contained in:
parent
f03dc68f96
commit
d492eef700
@ -223,6 +223,10 @@ impl Line {
|
||||
.replace(Arc::downgrade(&appdata));
|
||||
}
|
||||
|
||||
pub fn clear_appdata(&self) {
|
||||
self.appdata.lock().unwrap().take();
|
||||
}
|
||||
|
||||
/// Retrieve the appdata for the line, if any.
|
||||
/// This may return None in the case where the underlying data has
|
||||
/// been released: Line only stores a Weak reference to it.
|
||||
|
@ -1023,16 +1023,126 @@ impl Pane for CopyOverlay {
|
||||
self.delegate.get_changed_since(lines, seqno)
|
||||
}
|
||||
|
||||
fn with_lines_mut(&self, lines: Range<StableRowIndex>, with_lines: &mut dyn WithPaneLines) {
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn for_each_logical_line_in_stable_range_mut(
|
||||
&self,
|
||||
lines: Range<StableRowIndex>,
|
||||
for_line: &mut dyn ForEachPaneLogicalLine,
|
||||
) {
|
||||
todo!();
|
||||
self.delegate
|
||||
.for_each_logical_line_in_stable_range_mut(lines, for_line);
|
||||
}
|
||||
|
||||
fn with_lines_mut(&self, lines: Range<StableRowIndex>, with_lines: &mut dyn WithPaneLines) {
|
||||
// Take care to access self.delegate methods here before we get into
|
||||
// calling into its own with_lines_mut to avoid a runtime
|
||||
// borrow erro!
|
||||
let mut renderer = self.render.borrow_mut();
|
||||
if self.delegate.get_current_seqno() > renderer.last_result_seqno {
|
||||
renderer.update_search();
|
||||
}
|
||||
renderer.check_for_resize();
|
||||
let dims = self.get_dimensions();
|
||||
let search_row = renderer.compute_search_row();
|
||||
|
||||
struct OverlayLines<'a> {
|
||||
with_lines: &'a mut dyn WithPaneLines,
|
||||
dims: RenderableDimensions,
|
||||
search_row: StableRowIndex,
|
||||
renderer: &'a mut CopyRenderable,
|
||||
}
|
||||
|
||||
self.delegate.with_lines_mut(
|
||||
lines,
|
||||
&mut OverlayLines {
|
||||
with_lines,
|
||||
dims,
|
||||
search_row,
|
||||
renderer: &mut *renderer,
|
||||
},
|
||||
);
|
||||
|
||||
impl<'a> WithPaneLines for OverlayLines<'a> {
|
||||
fn with_lines_mut(&mut self, first_row: StableRowIndex, lines: &mut [&mut Line]) {
|
||||
let mut overlay_lines = vec![];
|
||||
let config = config::configuration();
|
||||
let colors = &config.resolved_palette;
|
||||
|
||||
for (idx, line) in lines.iter_mut().enumerate() {
|
||||
let mut line: Line = line.clone();
|
||||
|
||||
let stable_idx = idx as StableRowIndex + first_row;
|
||||
self.renderer.dirty_results.remove(stable_idx);
|
||||
if stable_idx == self.search_row
|
||||
&& (self.renderer.editing_search || !self.renderer.pattern.is_empty())
|
||||
{
|
||||
// Replace with search UI
|
||||
let rev = CellAttributes::default().set_reverse(true).clone();
|
||||
line.fill_range(0..self.dims.cols, &Cell::new(' ', rev.clone()), SEQ_ZERO);
|
||||
let mode = &match self.renderer.pattern {
|
||||
Pattern::CaseSensitiveString(_) => "case-sensitive",
|
||||
Pattern::CaseInSensitiveString(_) => "ignore-case",
|
||||
Pattern::Regex(_) => "regex",
|
||||
};
|
||||
line.overlay_text_with_attribute(
|
||||
0,
|
||||
&format!(
|
||||
"Search: {} ({}/{} matches. {})",
|
||||
*self.renderer.pattern,
|
||||
self.renderer.result_pos.map(|x| x + 1).unwrap_or(0),
|
||||
self.renderer.results.len(),
|
||||
mode
|
||||
),
|
||||
rev,
|
||||
SEQ_ZERO,
|
||||
);
|
||||
self.renderer.last_bar_pos = Some(self.search_row);
|
||||
line.clear_appdata();
|
||||
} else if let Some(matches) = self.renderer.by_line.get(&stable_idx) {
|
||||
for m in matches {
|
||||
// highlight
|
||||
for cell_idx in m.range.clone() {
|
||||
if let Some(cell) =
|
||||
line.cells_mut_for_attr_changes_only().get_mut(cell_idx)
|
||||
{
|
||||
if Some(m.result_index) == self.renderer.result_pos {
|
||||
cell.attrs_mut()
|
||||
.set_background(
|
||||
colors
|
||||
.copy_mode_active_highlight_bg
|
||||
.unwrap_or(AnsiColor::Yellow.into()),
|
||||
)
|
||||
.set_foreground(
|
||||
colors
|
||||
.copy_mode_active_highlight_fg
|
||||
.unwrap_or(AnsiColor::Black.into()),
|
||||
)
|
||||
.set_reverse(false);
|
||||
} else {
|
||||
cell.attrs_mut()
|
||||
.set_background(
|
||||
colors
|
||||
.copy_mode_inactive_highlight_bg
|
||||
.unwrap_or(AnsiColor::Fuchsia.into()),
|
||||
)
|
||||
.set_foreground(
|
||||
colors
|
||||
.copy_mode_inactive_highlight_fg
|
||||
.unwrap_or(AnsiColor::Black.into()),
|
||||
)
|
||||
.set_reverse(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
line.clear_appdata();
|
||||
}
|
||||
overlay_lines.push(line);
|
||||
}
|
||||
|
||||
let mut overlay_refs: Vec<&mut Line> = overlay_lines.iter_mut().collect();
|
||||
self.with_lines.with_lines_mut(first_row, &mut overlay_refs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_lines(&self, lines: Range<StableRowIndex>) -> (StableRowIndex, Vec<Line>) {
|
||||
|
@ -452,16 +452,124 @@ impl Pane for QuickSelectOverlay {
|
||||
dirty.intersection_with_range(lines)
|
||||
}
|
||||
|
||||
fn with_lines_mut(&self, lines: Range<StableRowIndex>, with_lines: &mut dyn WithPaneLines) {
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn for_each_logical_line_in_stable_range_mut(
|
||||
&self,
|
||||
lines: Range<StableRowIndex>,
|
||||
for_line: &mut dyn ForEachPaneLogicalLine,
|
||||
) {
|
||||
todo!();
|
||||
self.delegate
|
||||
.for_each_logical_line_in_stable_range_mut(lines, for_line);
|
||||
}
|
||||
|
||||
fn with_lines_mut(&self, lines: Range<StableRowIndex>, with_lines: &mut dyn WithPaneLines) {
|
||||
let mut renderer = self.renderer.borrow_mut();
|
||||
// Take care to access self.delegate methods here before we get into
|
||||
// calling into its own with_lines_mut to avoid a runtime
|
||||
// borrow erro!
|
||||
renderer.check_for_resize();
|
||||
let dims = self.get_dimensions();
|
||||
let search_row = renderer.compute_search_row();
|
||||
|
||||
struct OverlayLines<'a> {
|
||||
with_lines: &'a mut dyn WithPaneLines,
|
||||
dims: RenderableDimensions,
|
||||
search_row: StableRowIndex,
|
||||
renderer: &'a mut QuickSelectRenderable,
|
||||
}
|
||||
|
||||
self.delegate.with_lines_mut(
|
||||
lines,
|
||||
&mut OverlayLines {
|
||||
with_lines,
|
||||
dims,
|
||||
search_row,
|
||||
renderer: &mut *renderer,
|
||||
},
|
||||
);
|
||||
|
||||
impl<'a> WithPaneLines for OverlayLines<'a> {
|
||||
fn with_lines_mut(&mut self, first_row: StableRowIndex, lines: &mut [&mut Line]) {
|
||||
let mut overlay_lines = vec![];
|
||||
|
||||
let colors = self.renderer.config.resolved_palette.clone();
|
||||
|
||||
// Process the lines; for the search row we want to render instead
|
||||
// the search UI.
|
||||
// For rows with search results, we want to highlight the matching ranges
|
||||
|
||||
for (idx, line) in lines.iter_mut().enumerate() {
|
||||
let mut line: Line = line.clone();
|
||||
let stable_idx = idx as StableRowIndex + first_row;
|
||||
self.renderer.dirty_results.remove(stable_idx);
|
||||
if stable_idx == self.search_row {
|
||||
// Replace with search UI
|
||||
let rev = CellAttributes::default().set_reverse(true).clone();
|
||||
line.fill_range(0..self.dims.cols, &Cell::new(' ', rev.clone()), SEQ_ZERO);
|
||||
line.overlay_text_with_attribute(
|
||||
0,
|
||||
&format!(
|
||||
"Select: {} (type highlighted prefix to {}, uppercase pastes, ESC to cancel)",
|
||||
self.renderer.selection,
|
||||
if self.renderer.args.label.is_empty() {
|
||||
"copy"
|
||||
} else {
|
||||
&self.renderer.args.label
|
||||
},
|
||||
),
|
||||
rev,
|
||||
SEQ_ZERO,
|
||||
);
|
||||
self.renderer.last_bar_pos = Some(self.search_row);
|
||||
line.clear_appdata();
|
||||
} else if let Some(matches) = self.renderer.by_line.get(&stable_idx) {
|
||||
for m in matches {
|
||||
// highlight
|
||||
for cell_idx in m.range.clone() {
|
||||
if let Some(cell) =
|
||||
line.cells_mut_for_attr_changes_only().get_mut(cell_idx)
|
||||
{
|
||||
cell.attrs_mut()
|
||||
.set_background(
|
||||
colors
|
||||
.quick_select_match_bg
|
||||
.unwrap_or(AnsiColor::Black.into()),
|
||||
)
|
||||
.set_foreground(
|
||||
colors
|
||||
.quick_select_match_fg
|
||||
.unwrap_or(AnsiColor::Green.into()),
|
||||
)
|
||||
.set_reverse(false);
|
||||
}
|
||||
}
|
||||
for (idx, c) in m.label.chars().enumerate() {
|
||||
let mut attr = line
|
||||
.get_cell(idx)
|
||||
.map(|cell| cell.attrs().clone())
|
||||
.unwrap_or_else(|| CellAttributes::default());
|
||||
attr.set_background(
|
||||
colors
|
||||
.quick_select_label_bg
|
||||
.unwrap_or(AnsiColor::Black.into()),
|
||||
)
|
||||
.set_foreground(
|
||||
colors
|
||||
.quick_select_label_fg
|
||||
.unwrap_or(AnsiColor::Olive.into()),
|
||||
)
|
||||
.set_reverse(false);
|
||||
line.set_cell(m.range.start + idx, Cell::new(c, attr), SEQ_ZERO);
|
||||
}
|
||||
}
|
||||
line.clear_appdata();
|
||||
}
|
||||
overlay_lines.push(line);
|
||||
}
|
||||
|
||||
let mut overlay_refs: Vec<&mut Line> = overlay_lines.iter_mut().collect();
|
||||
self.with_lines.with_lines_mut(first_row, &mut overlay_refs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_lines(&self, lines: Range<StableRowIndex>) -> (StableRowIndex, Vec<Line>) {
|
||||
|
Loading…
Reference in New Issue
Block a user