Line numbers are now displayed in left-hand gutter.
This commit is contained in:
parent
9b24b2b4f2
commit
902d93e957
|
@ -7,6 +7,7 @@ use formatter::RoundingBehavior::*;
|
|||
use std::old_path::Path;
|
||||
use std::cmp::{min, max};
|
||||
use string_utils::grapheme_count;
|
||||
use utils::digit_count;
|
||||
use self::cursor::CursorSet;
|
||||
|
||||
mod cursor;
|
||||
|
@ -21,7 +22,11 @@ pub struct Editor<T: LineFormatter> {
|
|||
pub soft_tab_width: u8,
|
||||
pub dirty: bool,
|
||||
|
||||
// The dimensions and position of the editor's view within the buffer
|
||||
// The dimensions of the total editor in screen space, including the
|
||||
// header, gutter, etc.
|
||||
pub editor_dim: (usize, usize),
|
||||
|
||||
// The dimensions and position of just the text view portion of the editor
|
||||
pub view_dim: (usize, usize), // (height, width)
|
||||
pub view_pos: (usize, usize), // (grapheme index, visual horizontal offset)
|
||||
|
||||
|
@ -41,6 +46,7 @@ impl<T: LineFormatter> Editor<T> {
|
|||
soft_tabs: false,
|
||||
soft_tab_width: 4,
|
||||
dirty: false,
|
||||
editor_dim: (0, 0),
|
||||
view_dim: (0, 0),
|
||||
view_pos: (0, 0),
|
||||
cursors: CursorSet::new(),
|
||||
|
@ -63,6 +69,7 @@ impl<T: LineFormatter> Editor<T> {
|
|||
soft_tabs: false,
|
||||
soft_tab_width: 4,
|
||||
dirty: false,
|
||||
editor_dim: (0, 0),
|
||||
view_dim: (0, 0),
|
||||
view_pos: (0, 0),
|
||||
cursors: CursorSet::new(),
|
||||
|
@ -255,7 +262,19 @@ impl<T: LineFormatter> Editor<T> {
|
|||
|
||||
|
||||
pub fn update_dim(&mut self, h: usize, w: usize) {
|
||||
self.view_dim = (h, w);
|
||||
self.editor_dim = (h, w);
|
||||
self.update_view_dim();
|
||||
}
|
||||
|
||||
|
||||
pub fn update_view_dim(&mut self) {
|
||||
// TODO: generalize for non-terminal UI. Maybe this isn't where it
|
||||
// belongs, in fact. But for now, this is the easiest place to put
|
||||
// it.
|
||||
let line_count_digits = digit_count(self.buffer.line_count() as u32, 10) as usize;
|
||||
// Minus 1 vertically for the header, minus one more than the digits in
|
||||
// the line count for the gutter.
|
||||
self.view_dim = (self.editor_dim.0 - 1, self.editor_dim.1 - line_count_digits - 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ use term_ui::formatter::ConsoleLineFormatter;
|
|||
//use gui::formatter::GUILineFormatter;
|
||||
|
||||
mod string_utils;
|
||||
mod utils;
|
||||
mod buffer;
|
||||
mod formatter;
|
||||
mod editor;
|
||||
|
|
|
@ -7,6 +7,7 @@ use formatter::LineFormatter;
|
|||
use std::char;
|
||||
use std::time::duration::Duration;
|
||||
use string_utils::{is_line_ending};
|
||||
use utils::digit_count;
|
||||
use buffer::line::{line_ending_to_str, LineEnding};
|
||||
use self::formatter::ConsoleLineFormatter;
|
||||
|
||||
|
@ -88,6 +89,8 @@ impl TermUI {
|
|||
|
||||
loop {
|
||||
// Draw the editor to screen
|
||||
self.editor.update_view_dim();
|
||||
self.editor.formatter.wrap_width = self.editor.view_dim.1;
|
||||
self.rb.clear();
|
||||
self.draw_editor(&self.editor, (0, 0), (self.height-1, self.width-1));
|
||||
self.rb.present();
|
||||
|
@ -195,9 +198,7 @@ impl TermUI {
|
|||
if let Some((h, w)) = resize {
|
||||
self.width = w as usize;
|
||||
self.height = h as usize;
|
||||
self.editor.update_dim(self.height-1, self.width);
|
||||
self.editor.formatter.wrap_width = self.width;
|
||||
println!("Resized window!");
|
||||
self.editor.update_dim(self.height, self.width);
|
||||
}
|
||||
resize = None;
|
||||
|
||||
|
@ -220,6 +221,8 @@ impl TermUI {
|
|||
|
||||
loop {
|
||||
// Draw the editor to screen
|
||||
self.editor.update_view_dim();
|
||||
self.editor.formatter.wrap_width = self.editor.view_dim.1;
|
||||
self.rb.clear();
|
||||
self.draw_editor(&self.editor, (0, 0), (self.height-1, self.width-1));
|
||||
for i in 0..self.width {
|
||||
|
@ -353,14 +356,29 @@ impl TermUI {
|
|||
|
||||
fn draw_editor_text(&self, editor: &Editor<ConsoleLineFormatter>, c1: (usize, usize), c2: (usize, usize)) {
|
||||
// Calculate all the starting info
|
||||
let gutter_width = editor.editor_dim.1 - editor.view_dim.1;
|
||||
let (starting_line, _) = editor.buffer.index_to_line_col(editor.view_pos.0);
|
||||
let mut grapheme_index = editor.buffer.line_col_to_index((starting_line, 0));
|
||||
let (vis_line_offset, _) = editor.formatter.index_to_v2d(editor.buffer.get_line(starting_line), editor.view_pos.0 - grapheme_index);
|
||||
|
||||
let mut screen_line = c1.0 as isize - vis_line_offset as isize;
|
||||
let screen_col = c1.1 as isize;
|
||||
let screen_col = c1.1 as isize + gutter_width as isize;
|
||||
|
||||
// Fill in the gutter with the appropriate background
|
||||
for y in c1.0..(c2.0+1) {
|
||||
for x in c1.1..(c1.1+gutter_width-1) {
|
||||
self.rb.print(x, y, rustbox::RB_NORMAL, Color::White, Color::Blue, " ");
|
||||
}
|
||||
}
|
||||
|
||||
let mut line_num = starting_line + 1;
|
||||
for line in editor.buffer.line_iter_at_index(starting_line) {
|
||||
// Print line number
|
||||
let lnx = c1.1 + (gutter_width - 1 - digit_count(line_num as u32, 10) as usize);
|
||||
let lny = screen_line as usize;
|
||||
if lny >= c1.0 && lny <= c2.0 {
|
||||
self.rb.print(lnx, lny, rustbox::RB_NORMAL, Color::White, Color::Blue, format!("{}", line_num).as_slice());
|
||||
}
|
||||
|
||||
// Loop through the graphemes of the line and print them to
|
||||
// the screen.
|
||||
|
@ -417,6 +435,7 @@ impl TermUI {
|
|||
|
||||
let (dim_y, _) = editor.formatter.dimensions(line);
|
||||
screen_line += dim_y as isize;
|
||||
line_num += 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
34
src/utils.rs
Normal file
34
src/utils.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
pub fn digit_count(mut n: u32, b: u32) -> u32 {
|
||||
let mut d = 0;
|
||||
loop {
|
||||
n /= b;
|
||||
d += 1;
|
||||
if n == 0 {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn digit_count_base_10() {
|
||||
assert_eq!(digit_count(0, 10), 1);
|
||||
assert_eq!(digit_count(9, 10), 1);
|
||||
assert_eq!(digit_count(10, 10), 2);
|
||||
assert_eq!(digit_count(99, 10), 2);
|
||||
assert_eq!(digit_count(100, 10), 3);
|
||||
assert_eq!(digit_count(999, 10), 3);
|
||||
assert_eq!(digit_count(1000, 10), 4);
|
||||
assert_eq!(digit_count(9999, 10), 4);
|
||||
assert_eq!(digit_count(10000, 10), 5);
|
||||
assert_eq!(digit_count(99999, 10), 5);
|
||||
assert_eq!(digit_count(100000, 10), 6);
|
||||
assert_eq!(digit_count(999999, 10), 6);
|
||||
assert_eq!(digit_count(1000000, 10), 7);
|
||||
assert_eq!(digit_count(9999999, 10), 7);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user