Implement missing function, fix some math issues between cursor_x and render_x

This commit is contained in:
Timothy Warren 2019-09-12 16:49:49 -04:00
parent d45911767d
commit f955e22c19
3 changed files with 83 additions and 26 deletions

View File

@ -407,14 +407,68 @@ impl Editor {
return Some(input[0]); return Some(input[0]);
} }
fn get_cursor_position(&mut self) -> TermSize {
let mut query = String::new();
// Move the cursor as far to the bottom right as is practical
query.push_str("\x1b[999C\x1b[999B");
// Ask the shell where the cursor is
query.push_str("\x1b[6n");
let stdout = io::stdout();
let mut handle = stdout.lock();
// If you can't write to stdout, you might as well just panic
handle.write_all(query.as_bytes()).unwrap();
let stdin = io::stdin();
let stdin = stdin.lock();
let mut handle = stdin.take(32);
let mut input = String::new();
let read_res = handle.read_to_string(&mut input);
clean_unwrap(read_res);
if input.len() < 6 {
panic!("Invalid or missing response to cursor location query: {:?}", input);
}
let mut row_str = String::new();
let mut col_str = String::new();
let mut index = 0;
for ch in input.chars() {
if ch == ';' {
index += 1;
} else if ch == 'R' {
break;
} else {
if index == 0 {
row_str.push(ch)
} else {
col_str.push(ch)
}
}
}
let rows = clean_unwrap(row_str.parse());
let cols = clean_unwrap(row_str.parse());
return TermSize {
cols,
rows,
}
}
fn get_window_size(&mut self) -> TermSize { fn get_window_size(&mut self) -> TermSize {
match get_term_size() { match get_term_size() {
Some(size) => size, Some(size) => size,
// I could have implemented this, but I felt that parsing None => {
// an escape code from stdin was of minimal value, print!("\x1b[999C\x1b[999B");
// when the ioctrl method works on any computer I've tried return self.get_cursor_position();
None => unimplemented!("The easy way usually works"), }
} }
} }
@ -1062,10 +1116,10 @@ impl Editor {
self.draw_message_bar(); self.draw_message_bar();
// Move cursor to state position // Move cursor to state position
let y = self.cursor_y - self.row_offset + 1; let y = (self.cursor_y - self.row_offset) + 1;
let x = self.render_x - self.col_offset + 1; let x = (self.render_x - self.col_offset) + 1;
let cursor_code = format!("\x1b[{y};{x}f", y = y, x = x); let cursor_code = format!("\x1b[{};{}H", y, x);
self.append_out(&cursor_code); self.append_out(&cursor_code.as_str());
// Show cursor // Show cursor
self.append_out("\x1b[?25h"); self.append_out("\x1b[?25h");
@ -1102,20 +1156,17 @@ impl Editor {
fn row_cx_to_rx(&mut self, index: usize, cx: usize) -> usize { fn row_cx_to_rx(&mut self, index: usize, cx: usize) -> usize {
let mut rx: usize = 0; let mut rx: usize = 0;
let mut i: usize = 0;
for ch in self.rows[index].chars.chars() { for (i, ch) in self.rows[index].chars.char_indices() {
if ch == '\t' { if i == cx {
rx += (KILO_TAB_STOP - 1) - (rx % KILO_TAB_STOP);
} else {
rx += 1;
}
if i > cx {
return rx; return rx;
} }
i += 1; if ch == '\t' {
rx += (KILO_TAB_STOP - 1) - (rx % KILO_TAB_STOP);
}
rx += 1;
} }
rx rx
@ -1128,10 +1179,10 @@ impl Editor {
for ch in self.rows[index].chars.chars() { for ch in self.rows[index].chars.chars() {
if ch == '\t' { if ch == '\t' {
current_rx += (KILO_TAB_STOP - 1) - (current_rx % KILO_TAB_STOP); current_rx += (KILO_TAB_STOP - 1) - (current_rx % KILO_TAB_STOP);
} else {
current_rx += 1;
} }
current_rx += 1;
if current_rx > rx { if current_rx > rx {
return cx; return cx;
} }

View File

@ -45,12 +45,13 @@ fn main() -> Result<(), Error> {
editor.refresh_screen(); editor.refresh_screen();
match editor.process_keypress() { match editor.process_keypress() {
Some(_key) => { Some(key) => {
/* match key { match key {
editor::EditorKey::OtherKey('\0') => (), editor::KeyCode::OtherKey('\0') => (),
_ => println!("{:?}\r\n", key)
}*/ // Just for debugging
() _ => () //println!("{:?}\r\n", key)
}
} }
None => break, None => break,
} }

View File

@ -36,6 +36,11 @@ pub fn get_termios(fd: RawFd) -> Termios {
/// Put terminal into raw mode so there is full control of terminal output /// Put terminal into raw mode so there is full control of terminal output
pub fn enable_raw_mode() { pub fn enable_raw_mode() {
// 'Access' the saved termios instance, to make sure it is set
// before you enable raw mode.
let mutex = Arc::clone(&super::ORIGINAL_TERMIOS);
mutex.lock().unwrap();
let mut raw = get_termios(STDIN_FILENO); let mut raw = get_termios(STDIN_FILENO);
raw.input_flags.remove( raw.input_flags.remove(