ui: Make editor more resilient about being shrunk too small.

pull/8/head
Blaž Hrastnik 4 years ago
parent 2c9b02039b
commit 00808afe3c

@ -70,10 +70,11 @@ impl Application {
let area = self.terminal.size().unwrap(); let area = self.terminal.size().unwrap();
compositor.render(area, self.terminal.current_buffer_mut(), &mut cx); compositor.render(area, self.terminal.current_buffer_mut(), &mut cx);
let pos = compositor.cursor_position(area, &editor); let pos = compositor
.cursor_position(area, &editor)
.map(|pos| (pos.col as u16, pos.row as u16));
self.terminal.draw(); self.terminal.draw(pos);
self.terminal.set_cursor(pos.col as u16, pos.row as u16);
} }
pub async fn event_loop(&mut self) { pub async fn event_loop(&mut self) {

@ -1072,9 +1072,10 @@ pub fn completion(cx: &mut Context) {
cx.callback = Some(Box::new( cx.callback = Some(Box::new(
move |compositor: &mut Compositor, editor: &mut Editor| { move |compositor: &mut Compositor, editor: &mut Editor| {
let area = tui::layout::Rect::default(); // TODO: unused remove from cursor_position let area = tui::layout::Rect::default(); // TODO: unused remove from cursor_position
let mut pos = compositor.cursor_position(area, editor); if let Some(mut pos) = compositor.cursor_position(area, editor) {
pos.row += 1; // shift down by one row pos.row += 1; // shift down by one row
menu.set_position(pos); menu.set_position(pos);
};
compositor.push(Box::new(menu)); compositor.push(Box::new(menu));
}, },
@ -1133,9 +1134,10 @@ pub fn hover(cx: &mut Context) {
cx.callback = Some(Box::new( cx.callback = Some(Box::new(
move |compositor: &mut Compositor, editor: &mut Editor| { move |compositor: &mut Compositor, editor: &mut Editor| {
let area = tui::layout::Rect::default(); // TODO: unused remove from cursor_position let area = tui::layout::Rect::default(); // TODO: unused remove from cursor_position
let mut pos = compositor.cursor_position(area, editor); if let Some(mut pos) = compositor.cursor_position(area, editor) {
pos.row += 1; // shift down by one row pos.row += 1; // shift down by one row
popup.set_position(pos); popup.set_position(pos);
};
compositor.push(Box::new(popup)); compositor.push(Box::new(popup));
}, },

@ -120,12 +120,12 @@ impl Compositor {
} }
} }
pub fn cursor_position(&self, area: Rect, editor: &Editor) -> Position { pub fn cursor_position(&self, area: Rect, editor: &Editor) -> Option<Position> {
for layer in self.layers.iter().rev() { for layer in self.layers.iter().rev() {
if let Some(pos) = layer.cursor_position(area, editor) { if let Some(pos) = layer.cursor_position(area, editor) {
return pos; return Some(pos);
} }
} }
panic!("No layer returned a position!"); None
} }
} }

@ -154,7 +154,7 @@ where
/// Synchronizes terminal size, calls the rendering closure, flushes the current internal state /// Synchronizes terminal size, calls the rendering closure, flushes the current internal state
/// and prepares for the next draw call. /// and prepares for the next draw call.
pub fn draw(&mut self) -> io::Result<()> { pub fn draw(&mut self, cursor_position: Option<(u16, u16)>) -> io::Result<()> {
// // Autoresize - otherwise we get glitches if shrinking or potential desync between widgets // // Autoresize - otherwise we get glitches if shrinking or potential desync between widgets
// // and the terminal (if growing), which may OOB. // // and the terminal (if growing), which may OOB.
// self.autoresize()?; // self.autoresize()?;
@ -169,13 +169,13 @@ where
// Draw to stdout // Draw to stdout
self.flush()?; self.flush()?;
// match cursor_position { match cursor_position {
// None => self.hide_cursor()?, None => self.hide_cursor()?,
// Some((x, y)) => { Some((x, y)) => {
// self.show_cursor()?; self.show_cursor()?;
// self.set_cursor(x, y)?; self.set_cursor(x, y)?;
// } }
// } }
// Swap buffers // Swap buffers
self.buffers[1 - self.current].reset(); self.buffers[1 - self.current].reset();

@ -42,7 +42,7 @@ impl EditorView {
viewport.x + OFFSET, viewport.x + OFFSET,
viewport.y, viewport.y,
viewport.width - OFFSET, viewport.width - OFFSET,
viewport.height - 1, viewport.height.saturating_sub(1),
); // - 1 for statusline ); // - 1 for statusline
self.render_buffer(view, area, surface, theme, is_focused); self.render_buffer(view, area, surface, theme, is_focused);
@ -52,7 +52,7 @@ impl EditorView {
let area = Rect::new( let area = Rect::new(
viewport.x, viewport.x,
viewport.y + viewport.height - 1, viewport.y + viewport.height.saturating_sub(1),
viewport.width, viewport.width,
1, 1,
); );
@ -433,14 +433,16 @@ impl Component for EditorView {
// Mode::Insert => write!(stdout, "\x1B[6 q"), // Mode::Insert => write!(stdout, "\x1B[6 q"),
// mode => write!(stdout, "\x1B[2 q"), // mode => write!(stdout, "\x1B[2 q"),
// }; // };
let view = editor.view(); // let view = editor.view();
let cursor = view.doc.selection().cursor(); // let cursor = view.doc.selection().cursor();
let mut pos = view // if let Some(mut pos) = view.screen_coords_at_pos(view.doc.text().slice(..), cursor) {
.screen_coords_at_pos(view.doc.text().slice(..), cursor) // pos.col += view.area.x as usize + area.x as usize + OFFSET as usize;
.expect("Cursor is out of bounds."); // pos.row += view.area.y as usize + area.y as usize;
pos.col += view.area.x as usize + area.x as usize + OFFSET as usize; // return Some(pos);
pos.row += view.area.y as usize + area.y as usize; // }
Some(pos)
// It's easier to just not render the cursor and use selection rendering instead.
None
} }
} }

@ -65,7 +65,7 @@ impl View {
/// Calculates the last visible line on screen /// Calculates the last visible line on screen
#[inline] #[inline]
pub fn last_line(&self) -> usize { pub fn last_line(&self) -> usize {
let viewport = Rect::new(6, 0, self.area.width, self.area.height - 1); // - 1 for statusline let viewport = Rect::new(6, 0, self.area.width, self.area.height.saturating_sub(1)); // - 1 for statusline
std::cmp::min( std::cmp::min(
self.first_line + (viewport.height as usize), self.first_line + (viewport.height as usize),
self.doc.text().len_lines() - 1, self.doc.text().len_lines() - 1,

Loading…
Cancel
Save