Implement missing function, fix some math issues between cursor_x and render_x
This commit is contained in:
parent
d45911767d
commit
f955e22c19
@ -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;
|
||||||
}
|
}
|
||||||
|
13
src/main.rs
13
src/main.rs
@ -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,
|
||||||
}
|
}
|
||||||
|
@ -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(
|
||||||
|
Loading…
Reference in New Issue
Block a user