Skip to content

Commit

Permalink
show line numbers to the side (#49)
Browse files Browse the repository at this point in the history
this PR adds
- `number` and `relative` to the config
- support for showing line numbers, relative or not
- color support for these in the config
  • Loading branch information
amtoine authored Apr 15, 2024
1 parent 763aba0 commit 8906b4a
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 2 deletions.
14 changes: 13 additions & 1 deletion examples/config/default.nuon
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
show_table_header: true, # whether or not to show the table header in "table" layout
layout: "table", # the layout of the data, either "table" or "compact"
margin: 10, # the number of lines to keep between the cursor and the top / bottom
number: false, # show line numbers
relativenumber: false, # show line numbers, relative to the current one (overrides number)

# "reset" is used instead of "black" in a dark terminal because, when the terminal is actually
# black, "black" is not really black which is ugly, whereas "reset" is really black.
Expand Down Expand Up @@ -58,7 +60,17 @@
warning: {
foreground: red,
background: yellow,
}
},
line_numbers: {
normal: {
background: reset,
foreground: white,
},
selected: {
background: white,
foreground: black,
},
},
}
keybindings: {
quit: 'q', # quit `explore`
Expand Down
80 changes: 80 additions & 0 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ pub struct EditorColorConfig {
pub buffer: BgFgColorConfig,
}

/// the configuration for the line numbers
#[derive(Clone, PartialEq, Debug)]
pub struct LineNumbersColorConfig {
// all lines
pub normal: BgFgColorConfig,
// the selected line
pub selected: BgFgColorConfig,
}

/// the colors of the application
#[derive(Clone, PartialEq, Debug)]
pub struct ColorConfig {
Expand All @@ -60,6 +69,8 @@ pub struct ColorConfig {
pub editor: EditorColorConfig,
/// the color of a warning banner
pub warning: BgFgColorConfig,
/// the color of the line numbers
pub line_numbers: LineNumbersColorConfig,
}

/// a pair of background / foreground colors
Expand Down Expand Up @@ -138,6 +149,8 @@ pub struct Config {
pub layout: Layout,
pub show_table_header: bool,
pub margin: usize,
pub number: bool,
pub relativenumber: bool,
}

impl Default for Config {
Expand All @@ -149,6 +162,8 @@ impl Default for Config {
show_table_header: true,
layout: Layout::Table,
margin: 10,
number: false,
relativenumber: false,
colors: ColorConfig {
normal: TableRowColorConfig {
name: BgFgColorConfig {
Expand Down Expand Up @@ -202,6 +217,16 @@ impl Default for Config {
background: Color::Yellow,
foreground: Color::Red,
},
line_numbers: LineNumbersColorConfig {
normal: BgFgColorConfig {
background: Color::Reset,
foreground: Color::White,
},
selected: BgFgColorConfig {
background: Color::White,
foreground: Color::Black,
},
},
},
keybindings: KeyBindingsMap {
quit: KeyEvent::new(KeyCode::Char('q'), KeyModifiers::NONE),
Expand Down Expand Up @@ -260,6 +285,16 @@ impl Config {
config.margin = val as usize
}
}
"number" => {
if let Some(val) = try_bool(&value, &["number"])? {
config.number = val
}
}
"relativenumber" => {
if let Some(val) = try_bool(&value, &["relativenumber"])? {
config.relativenumber = val
}
}
"colors" => {
let cell = follow_cell_path(&value, &["colors"]).unwrap();
let columns = match &cell {
Expand Down Expand Up @@ -461,6 +496,51 @@ impl Config {
config.colors.warning = val
}
}
"line_numbers" => {
let cell =
follow_cell_path(&value, &["colors", "line_numbers"]).unwrap();
let columns = match &cell {
Value::Record { val: rec, .. } => {
rec.columns().collect::<Vec<_>>()
}
x => {
return Err(invalid_type(
x,
&["colors", "line_numbers"],
"record",
))
}
};

for column in columns {
match column.as_str() {
"normal" => {
if let Some(val) = try_fg_bg_colors(
&value,
&["colors", "line_numbers", "normal"],
&config.colors.line_numbers.normal,
)? {
config.colors.line_numbers.normal = val
}
}
"selected" => {
if let Some(val) = try_fg_bg_colors(
&value,
&["colors", "line_numbers", "selected"],
&config.colors.line_numbers.selected,
)? {
config.colors.line_numbers.selected = val
}
}
x => {
return Err(invalid_field(
&["colors", "line_numbers", x],
cell.span(),
))
}
}
}
}
x => return Err(invalid_field(&["colors", x], cell.span())),
}
}
Expand Down
69 changes: 68 additions & 1 deletion src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,6 @@ fn render_data(frame: &mut Frame, app: &mut App, config: &Config) {
);
}
}
let rect_without_bottom_bar = Rect::new(0, 0, frame.size().width, data_frame_height);

let normal_name_style = Style::default()
.fg(config.colors.normal.name.foreground)
Expand All @@ -310,6 +309,23 @@ fn render_data(frame: &mut Frame, app: &mut App, config: &Config) {
None => 0,
};

let show_line_numbers = (config.number || config.relativenumber)
&& matches!(value, Value::List { .. } | Value::Record { .. });
let nb_lines = match value.clone() {
// NOTE: it's annoying that `vals` cant' be cloned
Value::List { vals, .. } => vals.len(),
Value::Record { val, .. } => val.columns().len(),
_ => 0,
};
let line_numbers_width = if show_line_numbers {
format!("{}", nb_lines).len() as u16
} else {
0
};

let rect_without_bottom_bar =
Rect::new(line_numbers_width, 0, frame.size().width, data_frame_height);

let height = data_frame_height as i32 - 3; // 3: border x 2 + header
let cursor = selected as i32;
let top = *app.rendering_tops.last().unwrap_or(&0);
Expand All @@ -326,6 +342,57 @@ fn render_data(frame: &mut Frame, app: &mut App, config: &Config) {

let margin_offset = *app.rendering_tops.last().unwrap_or(&0) as usize;

if show_line_numbers {
let rect_lines_without_bottom_bar = Rect::new(0, 0, line_numbers_width, data_frame_height);

let normal_line_style = Style::default()
.fg(config.colors.line_numbers.normal.foreground)
.bg(config.colors.line_numbers.normal.background);
let highlight_line_style = Style::default()
.fg(config.colors.line_numbers.selected.foreground)
.bg(config.colors.line_numbers.selected.background);

let mut line_numbers = vec![];
// add the lines at the top
for i in (1..(selected + 1 - margin_offset)).rev() {
let i = if config.relativenumber {
i
} else {
selected + 1 - i
};
line_numbers.push(i);
}
// add selected line
line_numbers.push(selected + 1);
// add the lines at the top
for i in 1..(margin_offset as i32 + height - selected as i32) {
if selected as i32 + 1 + i > nb_lines as i32 {
break;
}

let i = if config.relativenumber {
i
} else {
selected as i32 + 1 + i
};
line_numbers.push(i as usize);
}

let mut lines = vec![ListItem::new(Line::from("")); 2];
for i in line_numbers {
lines.push(ListItem::new(Line::from(Span::styled(
format!("{}", i),
normal_line_style,
))));
}

frame.render_stateful_widget(
List::new(lines).highlight_style(highlight_line_style),
rect_lines_without_bottom_bar,
&mut ListState::default().with_selected(Some(selected - margin_offset + 2)),
);
}

if is_a_table {
let (columns, shapes, cells) = match value {
Value::List { vals, .. } => {
Expand Down

0 comments on commit 8906b4a

Please sign in to comment.