diff options
-rw-r--r-- | main.rs | 88 |
1 files changed, 17 insertions, 71 deletions
@@ -13,6 +13,7 @@ extern crate termios; use termios::{Termios, TCSANOW, ECHO, ICANON, tcsetattr}; extern crate termion; +use termion::color; //use termion::{color, input}; use termion::input::TermRead; use termion::event::{Event, Key}; @@ -165,7 +166,7 @@ impl Edits { } trait EditMode { - fn render_bytes(&self, start: u64, bytes: std::slice::Iter<u8>) -> String; + fn render_bytes(&self, cursor: u64, start: u64, bytes: std::slice::Iter<u8>) -> String; // translates from the width of the display (terminal) // to the number of bytes this edit mode can display fn element_width(&self, display_width: u16) -> u64; @@ -178,14 +179,23 @@ struct HexMode { } impl EditMode for HexMode { - fn render_bytes(&self, start: u64, bytes: std::slice::Iter<u8>) -> String { + fn render_bytes(&self, cursor: u64, start: u64, bytes: std::slice::Iter<u8>) -> String { let mut text = "".to_owned(); let mut ascii_text = "".to_owned(); let col_size = 4; let mut i: usize = 0; for b in bytes { - text.push_str(&format!("{:02x}", b)); - ascii_text.push_str(&format!("{}", ascii_or_dot(b.to_owned()) as char)); + if cursor == start + i as u64 { + text.push_str(&format!("{}", color::Fg(color::Yellow))); + ascii_text.push_str(&format!("{}", color::Fg(color::Yellow))); + text.push_str(&format!("{:02x}", b)); + ascii_text.push_str(&format!("{}", ascii_or_dot(b.to_owned()) as char)); + text.push_str(&format!("{}", color::Fg(color::Reset))); + ascii_text.push_str(&format!("{}", color::Fg(color::Reset))); + } else { + text.push_str(&format!("{:02x}", b)); + ascii_text.push_str(&format!("{}", ascii_or_dot(b.to_owned()) as char)); + } if i % col_size == (col_size - 1) { text.push_str(" "); } else { @@ -228,7 +238,7 @@ struct Program<'a, 'b> { impl <'a, 'b> Program<'a, 'b> { fn lines_to_draw(&self) -> u64 { - self.view_byte_height() / (self.edit_views.len() as u64 + 1) + self.view_byte_height() / self.edit_views.len() as u64 } fn seek_to(&mut self, dest: u64) { self.cursor = dest; @@ -314,10 +324,6 @@ fn launch_interface(w: u16, h: u16, filename: String) { let mut state = Program { filename: filename.to_string(), width: w, - // let col_width = 4; - // w = 10 + 1 + 1 + 4 * 3 * x + x + 1 + 4 * x - // w = 13 + 17 * x - // w - 13 / 17 = x row_size: ((w - 13) / 17) * 4, height: h, old_term: termios, @@ -356,12 +362,10 @@ enum Mode { } fn interface_loop(state: &mut Program) { -// let buffer = populate_buf(&state.filename, state.cursor, state.width as u64 * state.height as u64); // sw*h over-estimates by about a factor of.. 4? render_interface(state); let stdin = std::io::stdin(); -// for input in KeyboardInput::from_stdin(&stdin.lock().bytes()) { for input in stdin.events() { match state.state { Mode::Edit => { @@ -520,26 +524,6 @@ fn interface_loop(state: &mut Program) { } } -/* -struct KeyboardInput { - -} - -impl KeyboardInput { - fn from_stdin(x: &Iterator<Item = io::Result<u8>>) -> KeyboardInput { - let x = KeyboardInput { }; - x - } -} - -impl Iterator for KeyboardInput { - type Item = KeyInfo; - fn next(&mut self) -> Option<Self::Item> { - Some(0) - } -} -*/ - fn ascii_or_dot(c: u8) -> u8 { let u = c as char; if @@ -577,60 +561,22 @@ fn render_interface(state: &mut Program) { writeln!(state.screen, "{}{} {}", cursor::Goto(1, 2), clear::CurrentLine, state.status).unwrap(); state.status = "".to_string(); } -// writeln!(state.screen, "Read {} bytes at {} ", bufsz, state.seek).unwrap(); - //let addr_width = 8; -// let ascii = bytes_width * cols; - let buffer = state.view.get_bytes(state.seek, bufsz); // &state.buf; + let buffer = state.view.get_bytes(state.seek, bufsz); // buffer is one screen of bytes, starting at seek. let start = (state.seek) as usize; - let mut idx: usize = 0; - let col_width = 4; let mut iface = String::new(); - // +1 here is a total hack to intermix typical line rendering.. let width = state.bytes_per_line(); for i in 0..state.lines_to_draw() { - let mut hex_line = String::new(); - let mut ascii_line = String::new(); - for _ in 0..(state.view_byte_width() / col_width) { - for _ in 0..col_width { - if idx < buffer.len() && ((idx + start) as u64) < state.view.size() { - let chr = buffer[idx]; - if idx as u64 + state.seek == state.cursor { - write!(&mut hex_line, "\x1b[33m").unwrap(); - write!(&mut ascii_line, "\x1b[33m").unwrap(); - } - write!(&mut hex_line, "{:02x} ", chr).unwrap(); - write!(&mut ascii_line, "{}", ascii_or_dot(chr) as char).unwrap(); - if idx as u64 + state.seek == state.cursor { - write!(&mut hex_line, "\x1b[0m").unwrap(); - write!(&mut ascii_line, "\x1b[0m").unwrap(); - } - } else { - write!(&mut hex_line, " ").unwrap(); - write!(&mut ascii_line, " ").unwrap(); - } - idx += 1; - } - write!(&mut hex_line, " ").unwrap(); - } - - let lineaddr = start as u64 + i * state.view_byte_width(); - let addr = if lineaddr < state.view.size() { - format!("0x{:08x}:", lineaddr) - } else { - " ".to_string() - }; - write!(iface, "{} {} {}", addr, hex_line, ascii_line).unwrap(); for view in state.edit_views.iter() { let slice_start = width * i; let slice_end = slice_start + width; - write!(iface, "\n{}", view.render_bytes(start as u64 + slice_start, buffer[(slice_start as usize)..(slice_end as usize)].iter())).unwrap(); + write!(iface, "{}", view.render_bytes(state.cursor, start as u64 + slice_start, buffer[(slice_start as usize)..(slice_end as usize)].iter())).unwrap(); } if i < state.lines_to_draw() - 1 { write!(iface, "\n").unwrap(); |