Skip to content

Commit

Permalink
Use new lineprinter in ScreenWriter to prevent line wrapping.
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulJuliusMartinez committed Aug 31, 2021
1 parent 0ff12d4 commit a1dd70e
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 34 deletions.
11 changes: 7 additions & 4 deletions src/lineprinter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,16 @@ impl<'a, F: RichFormatter> Line<'a, F> {
pub fn print_line<W: Write>(&self, buf: &mut W) -> fmt::Result {
self.print_focus_and_container_indicators(buf)?;

let available_space = self
.width
.saturating_sub(INDICATOR_WIDTH)
.saturating_sub(self.depth * self.tab_size);
let label_depth = INDICATOR_WIDTH + self.depth * self.tab_size;
self.formatter
.position_cursor(buf, (1 + label_depth) as u16)?;

let mut available_space = self.width.saturating_sub(label_depth);

let space_used_for_label = self.fill_in_label(buf, available_space)?;

available_space = available_space.saturating_sub(space_used_for_label);

if self.label.is_some() && space_used_for_label == 0 {
self.print_truncated_indicator(buf)?;
} else {
Expand Down
62 changes: 50 additions & 12 deletions src/richformatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,29 @@ pub enum Color {
LightWhite,
}

impl Color {
fn id(&self) -> u8 {
match self {
Color::Black => 0,
Color::Red => 1,
Color::Green => 2,
Color::Yellow => 3,
Color::Blue => 4,
Color::Magenta => 5,
Color::Cyan => 6,
Color::White => 7,
Color::LightBlack => 8,
Color::LightRed => 9,
Color::LightGreen => 10,
Color::LightYellow => 11,
Color::LightBlue => 12,
Color::LightMagenta => 13,
Color::LightCyan => 14,
Color::LightWhite => 15,
}
}
}

pub trait RichFormatter {
fn position_cursor<W: Write>(&self, buf: &mut W, col: u16) -> Result;
fn fg_color<W: Write>(&self, buf: &mut W, color: Color) -> Result;
Expand All @@ -43,18 +66,38 @@ pub trait RichFormatter {
}
}

#[derive(Default)]
pub struct ColorFormatter {}

impl RichFormatter for ColorFormatter {
fn position_cursor<W: Write>(&self, buf: &mut W, col: u16) -> Result {
write!(buf, "\x1b[{}G", col)
}

fn fg_color<W: Write>(&self, buf: &mut W, color: Color) -> Result {
write!(buf, "\x1b[38;5;{}m", color.id())
}

fn bg_color<W: Write>(&self, buf: &mut W, color: Color) -> Result {
write!(buf, "\x1b[48;5;{}m", color.id())
}

fn bold<W: Write>(&self, buf: &mut W) -> Result {
write!(buf, "\x1b[1m")
}

fn reset_style<W: Write>(&self, buf: &mut W) -> Result {
write!(buf, "\x1b[0m")
}
}

#[cfg(test)]
pub mod test {
use super::*;

#[derive(Default)]
pub struct NoFormatting {}

impl Default for NoFormatting {
fn default() -> Self {
NoFormatting {}
}
}

impl RichFormatter for NoFormatting {
fn position_cursor<W: Write>(&self, _buf: &mut W, _col: u16) -> Result {
Ok(())
Expand All @@ -77,14 +120,9 @@ pub mod test {
}
}

#[derive(Default)]
pub struct VisibleEscapes {}

impl Default for VisibleEscapes {
fn default() -> Self {
VisibleEscapes {}
}
}

impl RichFormatter for VisibleEscapes {
fn position_cursor<W: Write>(&self, buf: &mut W, col: u16) -> Result {
write!(buf, "_COL({})_", col)
Expand Down
137 changes: 119 additions & 18 deletions src/screenwriter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use unicode_width::UnicodeWidthStr;

use crate::flatjson::{ContainerType, Index, OptionIndex, Row, Value};
use crate::jless::MAX_BUFFER_SIZE;
use crate::lineprinter as lp;
use crate::richformatter::{Color as TUIColor, ColorFormatter};
use crate::truncate::TruncationResult::{DoesntFit, NoTruncation, Truncated};
use crate::truncate::{truncate_left_to_fit, truncate_right_to_fit};
use crate::types::TTYDimensions;
Expand Down Expand Up @@ -154,6 +156,122 @@ impl ScreenWriter {
row: &Row,
is_focused: bool,
) -> std::io::Result<()> {
if !row.is_container() {
self.tty_writer.position_cursor(1, row_index + 1)?;

// USING LINEPRINTER
let depth = row
.depth
.saturating_sub(self.indentation_reduction as usize);

let focused = is_focused;

let mut label = None;
let mut index_label = "".to_string();
let mut number_value = "".to_string();

// Set up key label.
if let Some(key) = &row.key {
label = Some(lp::LineLabel::Key {
key,
quoted: viewer.mode == Mode::Line || !JS_IDENTIFIER.is_match(key),
});
}

// Set up index label.
if let OptionIndex::Index(parent) = row.parent {
if viewer.mode == Mode::Data && viewer.flatjson[parent].is_array() {
index_label = format!("{}", row.index);
label = Some(lp::LineLabel::Index {
index: &index_label,
});
}
}

let value = match &row.value {
Value::OpenContainer { .. } => panic!("Can't use line printer for containers yet"),
Value::CloseContainer { .. } => panic!("Can't use line printer for containers yet"),
Value::Null => lp::LineValue::Value {
s: "null",
quotes: false,
color: TUIColor::LightBlack,
},
Value::Boolean(b) => lp::LineValue::Value {
s: if *b { "true" } else { "false" },
quotes: false,
color: TUIColor::Yellow,
},
Value::Number(n) => {
number_value = n.to_string();
lp::LineValue::Value {
s: &number_value,
quotes: false,
color: TUIColor::Magenta,
}
}
Value::String(s) => lp::LineValue::Value {
s,
quotes: true,
color: TUIColor::Green,
},
Value::EmptyObject => lp::LineValue::Value {
s: "{}",
quotes: false,
color: TUIColor::White,
},
Value::EmptyArray => lp::LineValue::Value {
s: "[]",
quotes: false,
color: TUIColor::White,
},
};

let mut trailing_comma = false;

if viewer.mode == Mode::Line {
// The next_sibling field isn't set for CloseContainer rows, so
// we need to get the OpenContainer row before we check if a row
// is the last row in a container, and thus whether we should
// print a trailing comma or not.
let row_root = if row.is_closing_of_container() {
&viewer.flatjson[row.pair_index().unwrap()]
} else {
row
};

if row_root.next_sibling.is_some() {
if row.is_opening_of_container() && row.is_expanded() {
// Don't print trailing commas after { or [, but
// if it's collapsed, we do print one after the } or ].
} else {
trailing_comma = true;
}
}
}

let line = lp::Line {
mode: viewer.mode,
formatter: ColorFormatter {},

depth,
width: self.dimensions.width as usize,
tab_size: 2,

focused,
secondarily_focused: false,
trailing_comma,

label,
value,
};

let mut buf = String::new();
line.print_line(&mut buf).unwrap();
return write!(self.tty_writer, "{}", buf);
}

// OLD PRINT_LINE

let col = 2 * ((row.depth as u16).saturating_sub(self.indentation_reduction) + 1);
if viewer.mode == Mode::Line && is_focused {
self.tty_writer.position_cursor(1, row_index + 1)?;
Expand Down Expand Up @@ -272,24 +390,7 @@ impl ScreenWriter {
ContainerType::Array => self.tty_writer.write_char(']')?,
}
}
Value::Null => {
self.set_fg_color(LightBlack)?;
write!(self.tty_writer, "null")?;
}
Value::Boolean(b) => {
self.set_fg_color(Yellow)?;
write!(self.tty_writer, "{}", b)?;
}
Value::Number(n) => {
self.set_fg_color(Magenta)?;
write!(self.tty_writer, "{}", n)?;
}
Value::String(s) => {
self.set_fg_color(Green)?;
write!(self.tty_writer, "\"{}\"", s)?;
}
Value::EmptyObject => write!(self.tty_writer, "{{}}")?,
Value::EmptyArray => write!(self.tty_writer, "[]")?,
_ => {}
};

self.reset_style()?;
Expand Down

0 comments on commit a1dd70e

Please sign in to comment.