mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 00:13:21 +01:00
explore
refactoring+clarification (#12940)
Another very boring PR cleaning up and documenting some of `explore`'s innards. Mostly renaming things that I found confusing or vague when reading through the code, also adding some comments.
This commit is contained in:
parent
f53aa6fcbf
commit
0b5a4c0d95
@ -8,24 +8,27 @@ use ratatui::{
|
||||
widgets::Widget,
|
||||
};
|
||||
|
||||
pub struct ColoredTextW<'a> {
|
||||
/// A widget that represents a single line of text with ANSI styles.
|
||||
pub struct ColoredTextWidget<'a> {
|
||||
text: &'a str,
|
||||
/// Column to start rendering from
|
||||
col: usize,
|
||||
}
|
||||
|
||||
impl<'a> ColoredTextW<'a> {
|
||||
impl<'a> ColoredTextWidget<'a> {
|
||||
pub fn new(text: &'a str, col: usize) -> Self {
|
||||
Self { text, col }
|
||||
}
|
||||
|
||||
pub fn what(&self, area: Rect) -> String {
|
||||
cut_string(self.text, self.col, area.width as usize)
|
||||
/// Return a window of the text that fits into the given width, with ANSI styles stripped.
|
||||
pub fn get_plain_text(&self, max_width: usize) -> String {
|
||||
cut_string(self.text, self.col, max_width)
|
||||
.ansi_strip()
|
||||
.into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for ColoredTextW<'_> {
|
||||
impl Widget for ColoredTextWidget<'_> {
|
||||
fn render(self, area: Rect, buf: &mut ratatui::buffer::Buffer) {
|
||||
let text = cut_string(self.text, self.col, area.width as usize);
|
||||
|
@ -1,5 +1,5 @@
|
||||
mod binary;
|
||||
mod coloredtextw;
|
||||
mod colored_text_widget;
|
||||
mod cursor;
|
||||
mod interactive;
|
||||
mod preview;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{coloredtextw::ColoredTextW, cursor::XYCursor, Layout, View, ViewConfig};
|
||||
use super::{colored_text_widget::ColoredTextWidget, cursor::XYCursor, Layout, View, ViewConfig};
|
||||
use crate::{
|
||||
nu_common::{NuSpan, NuText},
|
||||
pager::{report::Report, Frame, Transition, ViewInfo},
|
||||
@ -43,13 +43,14 @@ impl View for Preview {
|
||||
|
||||
let lines = &self.lines[self.cursor.row_starts_at()..];
|
||||
for (i, line) in lines.iter().enumerate().take(area.height as usize) {
|
||||
let text = ColoredTextW::new(line, self.cursor.column());
|
||||
let s = text.what(area);
|
||||
let text_widget = ColoredTextWidget::new(line, self.cursor.column());
|
||||
let plain_text = text_widget.get_plain_text(area.width as usize);
|
||||
|
||||
let area = Rect::new(area.x, area.y + i as u16, area.width, 1);
|
||||
f.render_widget(text, area);
|
||||
f.render_widget(text_widget, area);
|
||||
|
||||
layout.push(&s, area.x, area.y, area.width, area.height);
|
||||
// push the plain text to layout so it can be searched
|
||||
layout.push(&plain_text, area.x, area.y, area.width, area.height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
mod tablew;
|
||||
mod table_widget;
|
||||
|
||||
use self::tablew::{TableStyle, TableW, TableWState};
|
||||
use self::table_widget::{TableStyle, TableWidget, TableWidgetState};
|
||||
use super::{
|
||||
cursor::XYCursor,
|
||||
util::{make_styled_string, nu_style_to_tui},
|
||||
@ -25,7 +25,7 @@ use nu_protocol::{
|
||||
use ratatui::{layout::Rect, widgets::Block};
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
|
||||
pub use self::tablew::Orientation;
|
||||
pub use self::table_widget::Orientation;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RecordView<'a> {
|
||||
@ -175,7 +175,7 @@ impl<'a> RecordView<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn create_tablew(&'a self, cfg: ViewConfig<'a>) -> TableW<'a> {
|
||||
fn create_tablew(&'a self, cfg: ViewConfig<'a>) -> TableWidget<'a> {
|
||||
let layer = self.get_layer_last();
|
||||
let mut data = convert_records_to_string(&layer.records, cfg.nu_config, cfg.style_computer);
|
||||
|
||||
@ -185,7 +185,7 @@ impl<'a> RecordView<'a> {
|
||||
let style_computer = cfg.style_computer;
|
||||
let (row, column) = self.get_current_offset();
|
||||
|
||||
TableW::new(
|
||||
TableWidget::new(
|
||||
headers,
|
||||
data,
|
||||
style_computer,
|
||||
@ -225,7 +225,7 @@ impl<'a> RecordView<'a> {
|
||||
|
||||
impl View for RecordView<'_> {
|
||||
fn draw(&mut self, f: &mut Frame, area: Rect, cfg: ViewConfig<'_>, layout: &mut Layout) {
|
||||
let mut table_layout = TableWState::default();
|
||||
let mut table_layout = TableWidgetState::default();
|
||||
let table = self.create_tablew(cfg);
|
||||
f.render_stateful_widget(table, area, &mut table_layout);
|
||||
|
||||
|
@ -18,13 +18,13 @@ use std::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TableW<'a> {
|
||||
pub struct TableWidget<'a> {
|
||||
columns: Cow<'a, [String]>,
|
||||
data: Cow<'a, [Vec<NuText>]>,
|
||||
index_row: usize,
|
||||
index_column: usize,
|
||||
style: TableStyle,
|
||||
head_position: Orientation,
|
||||
header_position: Orientation,
|
||||
style_computer: &'a StyleComputer<'a>,
|
||||
}
|
||||
|
||||
@ -38,14 +38,13 @@ pub enum Orientation {
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
pub struct TableStyle {
|
||||
pub splitline_style: NuStyle,
|
||||
pub shift_line_style: NuStyle,
|
||||
pub show_index: bool,
|
||||
pub show_header: bool,
|
||||
pub column_padding_left: usize,
|
||||
pub column_padding_right: usize,
|
||||
}
|
||||
|
||||
impl<'a> TableW<'a> {
|
||||
impl<'a> TableWidget<'a> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
columns: impl Into<Cow<'a, [String]>>,
|
||||
@ -54,7 +53,7 @@ impl<'a> TableW<'a> {
|
||||
index_row: usize,
|
||||
index_column: usize,
|
||||
style: TableStyle,
|
||||
head_position: Orientation,
|
||||
header_position: Orientation,
|
||||
) -> Self {
|
||||
Self {
|
||||
columns: columns.into(),
|
||||
@ -63,21 +62,21 @@ impl<'a> TableW<'a> {
|
||||
index_row,
|
||||
index_column,
|
||||
style,
|
||||
head_position,
|
||||
header_position,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct TableWState {
|
||||
pub struct TableWidgetState {
|
||||
pub layout: Layout,
|
||||
pub count_rows: usize,
|
||||
pub count_columns: usize,
|
||||
pub data_height: u16,
|
||||
}
|
||||
|
||||
impl StatefulWidget for TableW<'_> {
|
||||
type State = TableWState;
|
||||
impl StatefulWidget for TableWidget<'_> {
|
||||
type State = TableWidgetState;
|
||||
|
||||
fn render(
|
||||
self,
|
||||
@ -89,7 +88,7 @@ impl StatefulWidget for TableW<'_> {
|
||||
return;
|
||||
}
|
||||
|
||||
let is_horizontal = matches!(self.head_position, Orientation::Top);
|
||||
let is_horizontal = matches!(self.header_position, Orientation::Top);
|
||||
if is_horizontal {
|
||||
self.render_table_horizontal(area, buf, state);
|
||||
} else {
|
||||
@ -99,8 +98,8 @@ impl StatefulWidget for TableW<'_> {
|
||||
}
|
||||
|
||||
// todo: refactoring these to methods as they have quite a bit in common.
|
||||
impl<'a> TableW<'a> {
|
||||
fn render_table_horizontal(self, area: Rect, buf: &mut Buffer, state: &mut TableWState) {
|
||||
impl<'a> TableWidget<'a> {
|
||||
fn render_table_horizontal(self, area: Rect, buf: &mut Buffer, state: &mut TableWidgetState) {
|
||||
let padding_l = self.style.column_padding_left as u16;
|
||||
let padding_r = self.style.column_padding_right as u16;
|
||||
|
||||
@ -108,7 +107,6 @@ impl<'a> TableW<'a> {
|
||||
let show_head = self.style.show_header;
|
||||
|
||||
let splitline_s = self.style.splitline_style;
|
||||
let shift_column_s = self.style.shift_line_style;
|
||||
|
||||
let mut data_height = area.height;
|
||||
let mut data_y = area.y;
|
||||
@ -164,7 +162,8 @@ impl<'a> TableW<'a> {
|
||||
);
|
||||
}
|
||||
|
||||
let mut do_render_shift_column = false;
|
||||
// if there is more data than we can show, add an ellipsis to the column headers to hint at that
|
||||
let mut show_overflow_indicator = false;
|
||||
state.count_rows = data.len();
|
||||
state.count_columns = 0;
|
||||
state.data_height = data_height;
|
||||
@ -191,11 +190,11 @@ impl<'a> TableW<'a> {
|
||||
|
||||
let pad = padding_l + padding_r;
|
||||
let head = show_head.then_some(&mut head);
|
||||
let (w, ok, shift) =
|
||||
let (w, ok, overflow) =
|
||||
truncate_column_width(space, 1, use_space, pad, is_last, &mut column, head);
|
||||
|
||||
if shift {
|
||||
do_render_shift_column = true;
|
||||
if overflow {
|
||||
show_overflow_indicator = true;
|
||||
}
|
||||
|
||||
if w == 0 && !ok {
|
||||
@ -232,14 +231,14 @@ impl<'a> TableW<'a> {
|
||||
|
||||
state.count_columns += 1;
|
||||
|
||||
if do_render_shift_column {
|
||||
if show_overflow_indicator {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if do_render_shift_column && show_head {
|
||||
if show_overflow_indicator && show_head {
|
||||
width += render_space(buf, width, data_y, data_height, padding_l);
|
||||
width += render_shift_column(buf, width, head_y, 1, shift_column_s);
|
||||
width += render_overflow_column(buf, width, head_y, 1);
|
||||
width += render_space(buf, width, data_y, data_height, padding_r);
|
||||
}
|
||||
|
||||
@ -264,7 +263,7 @@ impl<'a> TableW<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn render_table_vertical(self, area: Rect, buf: &mut Buffer, state: &mut TableWState) {
|
||||
fn render_table_vertical(self, area: Rect, buf: &mut Buffer, state: &mut TableWidgetState) {
|
||||
if area.width == 0 || area.height == 0 {
|
||||
return;
|
||||
}
|
||||
@ -275,7 +274,6 @@ impl<'a> TableW<'a> {
|
||||
let show_index = self.style.show_index;
|
||||
let show_head = self.style.show_header;
|
||||
let splitline_s = self.style.splitline_style;
|
||||
let shift_column_s = self.style.shift_line_style;
|
||||
|
||||
let mut left_w = 0;
|
||||
|
||||
@ -358,7 +356,8 @@ impl<'a> TableW<'a> {
|
||||
);
|
||||
}
|
||||
|
||||
let mut do_render_shift_column = false;
|
||||
// if there is more data than we can show, add an ellipsis to the column headers to hint at that
|
||||
let mut show_overflow_indicator = false;
|
||||
|
||||
state.count_rows = columns.len();
|
||||
state.count_columns = 0;
|
||||
@ -375,11 +374,11 @@ impl<'a> TableW<'a> {
|
||||
let available = area.width - left_w;
|
||||
let is_last = col + 1 == self.data.len();
|
||||
let pad = padding_l + padding_r;
|
||||
let (column_width, ok, shift) =
|
||||
let (column_width, ok, overflow) =
|
||||
truncate_column_width(available, 1, column_width, pad, is_last, &mut column, None);
|
||||
|
||||
if shift {
|
||||
do_render_shift_column = true;
|
||||
if overflow {
|
||||
show_overflow_indicator = true;
|
||||
}
|
||||
|
||||
if column_width == 0 && !ok {
|
||||
@ -403,16 +402,16 @@ impl<'a> TableW<'a> {
|
||||
state.count_columns += 1;
|
||||
}
|
||||
|
||||
if do_render_shift_column {
|
||||
if show_overflow_indicator {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if do_render_shift_column {
|
||||
if show_overflow_indicator {
|
||||
let x = area.x + left_w;
|
||||
left_w += render_space(buf, x, area.y, area.height, padding_l);
|
||||
let x = area.x + left_w;
|
||||
left_w += render_shift_column(buf, x, area.y, area.height, shift_column_s);
|
||||
left_w += render_overflow_column(buf, x, area.y, area.height);
|
||||
let x = area.x + left_w;
|
||||
left_w += render_space(buf, x, area.y, area.height, padding_r);
|
||||
}
|
||||
@ -433,13 +432,13 @@ fn truncate_column_width(
|
||||
) -> (u16, bool, bool) {
|
||||
let result = check_column_width(space, min, w, pad, is_last);
|
||||
|
||||
let (width, shift_column) = match result {
|
||||
let (width, overflow) = match result {
|
||||
Some(result) => result,
|
||||
None => return (w, true, false),
|
||||
};
|
||||
|
||||
if width == 0 {
|
||||
return (0, false, shift_column);
|
||||
return (0, false, overflow);
|
||||
}
|
||||
|
||||
truncate_list(column, width as usize);
|
||||
@ -447,7 +446,7 @@ fn truncate_column_width(
|
||||
truncate_str(head, width as usize);
|
||||
}
|
||||
|
||||
(width, false, shift_column)
|
||||
(width, false, overflow)
|
||||
}
|
||||
|
||||
fn check_column_width(
|
||||
@ -652,10 +651,11 @@ fn truncate_list(list: &mut [NuText], width: usize) {
|
||||
}
|
||||
}
|
||||
|
||||
fn render_shift_column(buf: &mut Buffer, x: u16, y: u16, height: u16, style: NuStyle) -> u16 {
|
||||
/// Render a column with an ellipsis in the header to indicate that there is more data than can be displayed
|
||||
fn render_overflow_column(buf: &mut Buffer, x: u16, y: u16, height: u16) -> u16 {
|
||||
let style = TextStyle {
|
||||
alignment: Alignment::Left,
|
||||
color_style: Some(style),
|
||||
color_style: None,
|
||||
};
|
||||
|
||||
repeat_vertical(buf, x, y, 1, height, '…', style);
|
Loading…
Reference in New Issue
Block a user