diff --git a/src/terminal_pane/scroll.rs b/src/terminal_pane/scroll.rs index 2953187e..8034431d 100644 --- a/src/terminal_pane/scroll.rs +++ b/src/terminal_pane/scroll.rs @@ -26,6 +26,14 @@ pub struct CanonicalLine { pub wrapped_fragments: Vec } +fn debug_log_to_file (message: String) { + use std::fs::OpenOptions; + use std::io::prelude::*; + let mut file = OpenOptions::new().append(true).create(true).open("/tmp/mosaic-log.txt").unwrap(); + file.write_all(message.as_bytes()).unwrap(); + file.write_all("\n".as_bytes()).unwrap(); +} + impl CanonicalLine { pub fn new() -> Self { CanonicalLine { @@ -56,6 +64,9 @@ impl CanonicalLine { wrapped_fragments.push(WrappedFragment::from_vec(characters.drain(..).collect())); } } + if wrapped_fragments.len() == 0 { + wrapped_fragments.push(WrappedFragment::new()); + } self.wrapped_fragments = wrapped_fragments; } pub fn clear_after(&mut self, fragment_index: usize, column_index: usize) { @@ -116,7 +127,7 @@ impl Debug for WrappedFragment { #[derive(Debug)] pub struct CursorPosition { line_index: (usize, usize), // (canonical line index, fragment index in line) - column_index: usize // 0 is the first character from the pane edge + column_index: usize // 0 is the first character from the pane edge } impl CursorPosition { @@ -185,7 +196,7 @@ impl Scroll { canonical_lines: vec![CanonicalLine::new()], // The rest will be created by newlines explicitly total_columns, lines_in_view, - cursor_position, + cursor_position, viewport_bottom_offset: None, scroll_region: None, show_cursor: true, @@ -243,6 +254,7 @@ impl Scroll { current_line.add_new_wrap(terminal_character); self.cursor_position.move_to_next_linewrap(); self.cursor_position.move_to_beginning_of_linewrap(); + self.cursor_position.move_forward(1); } } pub fn show_cursor (&mut self) { @@ -356,8 +368,8 @@ impl Scroll { canonical_line.change_width(columns); } let cursor_line = self.canonical_lines.get(self.cursor_position.line_index.0).expect("cursor out of bounds"); - if cursor_line.wrapped_fragments.len() < self.cursor_position.line_index.1 { - self.cursor_position.line_index.1 = cursor_line.wrapped_fragments.len(); + if cursor_line.wrapped_fragments.len() <= self.cursor_position.line_index.1 { + self.cursor_position.line_index.1 = cursor_line.wrapped_fragments.len() - 1; } } self.lines_in_view = lines; diff --git a/src/terminal_pane/terminal_pane.rs b/src/terminal_pane/terminal_pane.rs index d45f669e..853ff54f 100644 --- a/src/terminal_pane/terminal_pane.rs +++ b/src/terminal_pane/terminal_pane.rs @@ -189,7 +189,12 @@ impl TerminalPane { self.scroll.change_size(columns, rows); } pub fn buffer_as_vte_output(&mut self) -> Option { // TODO: rename to render - if self.should_render { + // if self.should_render { + if true { + // while checking should_render rather than rendering each pane every time + // is more performant, it causes some problems when the pane to the left should be + // rendered and has wide characters (eg. Chinese characters or emoji) + // as a (hopefully) temporary hack, we render all panes until we find a better solution let mut vte_output = String::new(); let buffer_lines = &self.read_buffer_as_lines(); let display_cols = self.get_columns(); @@ -271,7 +276,7 @@ impl TerminalPane { } fn debug_log_to_file (message: String, pid: RawFd) { - if pid == 0 { + if pid == 3 { use std::fs::OpenOptions; use std::io::prelude::*; let mut file = OpenOptions::new().append(true).create(true).open("/tmp/mosaic-log.txt").unwrap(); @@ -529,7 +534,7 @@ impl vte::Perform for TerminalPane { debug_log_to_file(format!("unhandled csi m code {:?}", params), self.pid); } } else if c == 'C' { // move cursor forward - let move_by = params[0] as usize; + let move_by = if params[0] == 0 { 1 } else { params[0] as usize }; self.scroll.move_cursor_forward(move_by); } else if c == 'K' { // clear line (0 => right, 1 => left, 2 => all) if params[0] == 0 {