Horizontal scrolling! It only took a year to get around to it.

pull/11/head
Blaž Hrastnik 4 years ago
parent d692390d10
commit 978f5114d8

@ -189,18 +189,20 @@ impl EditorView {
} else if grapheme == "\t" { } else if grapheme == "\t" {
visual_x += (tab_width as u16); visual_x += (tab_width as u16);
} else { } else {
if visual_x >= viewport.width { let out_of_bounds = visual_x < view.first_col as u16
// if we're offscreen just keep going until we hit a new line || visual_x >= viewport.width + view.first_col as u16;
// TODO: will need tweaking when we also take into account
// horizontal scrolling
continue;
}
// Cow will prevent allocations if span contained in a single slice // Cow will prevent allocations if span contained in a single slice
// which should really be the majority case // which should really be the majority case
let grapheme = Cow::from(grapheme); let grapheme = Cow::from(grapheme);
let width = grapheme_width(&grapheme) as u16; let width = grapheme_width(&grapheme) as u16;
if out_of_bounds {
// if we're offscreen just keep going until we hit a new line
visual_x += width;
continue;
}
// ugh,interleave highlight spans with diagnostic spans // ugh,interleave highlight spans with diagnostic spans
let is_diagnostic = doc.diagnostics.iter().any(|diagnostic| { let is_diagnostic = doc.diagnostics.iter().any(|diagnostic| {
diagnostic.range.start <= char_index diagnostic.range.start <= char_index
@ -214,7 +216,7 @@ impl EditorView {
}; };
surface.set_string( surface.set_string(
viewport.x + visual_x, viewport.x + visual_x - view.first_col as u16,
viewport.y + line, viewport.y + line,
grapheme, grapheme,
style, style,

@ -4,6 +4,7 @@ use std::borrow::Cow;
use crate::{Document, DocumentId, ViewId}; use crate::{Document, DocumentId, ViewId};
use helix_core::{ use helix_core::{
coords_at_pos,
graphemes::{grapheme_width, RopeGraphemes}, graphemes::{grapheme_width, RopeGraphemes},
Position, RopeSlice, Selection, Position, RopeSlice, Selection,
}; };
@ -56,6 +57,7 @@ pub struct View {
pub id: ViewId, pub id: ViewId,
pub doc: DocumentId, pub doc: DocumentId,
pub first_line: usize, pub first_line: usize,
pub first_col: usize,
pub area: Rect, pub area: Rect,
pub jumps: JumpList, pub jumps: JumpList,
} }
@ -66,6 +68,7 @@ impl View {
id: ViewId::default(), id: ViewId::default(),
doc, doc,
first_line: 0, first_line: 0,
first_col: 0,
area: Rect::default(), // will get calculated upon inserting into tree area: Rect::default(), // will get calculated upon inserting into tree
jumps: JumpList::new((doc, Selection::point(0))), // TODO: use actual sel jumps: JumpList::new((doc, Selection::point(0))), // TODO: use actual sel
}; };
@ -75,18 +78,30 @@ impl View {
pub fn ensure_cursor_in_view(&mut self, doc: &Document) { pub fn ensure_cursor_in_view(&mut self, doc: &Document) {
let cursor = doc.selection(self.id).cursor(); let cursor = doc.selection(self.id).cursor();
let line = doc.text().char_to_line(cursor); let pos = coords_at_pos(doc.text().slice(..), cursor);
let document_end = self.first_line + (self.area.height as usize).saturating_sub(2); let line = pos.row;
let col = pos.col;
let last_line = self.first_line + (self.area.height as usize).saturating_sub(2);
// TODO: side scroll // TODO: not ideal
const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter
let last_col = self.first_col + (self.area.width as usize - OFFSET);
if line > document_end.saturating_sub(PADDING) { if line > last_line.saturating_sub(PADDING) {
// scroll down // scroll down
self.first_line += line - (document_end.saturating_sub(PADDING)); self.first_line += line - (last_line.saturating_sub(PADDING));
} else if line < self.first_line + PADDING { } else if line < self.first_line + PADDING {
// scroll up // scroll up
self.first_line = line.saturating_sub(PADDING); self.first_line = line.saturating_sub(PADDING);
} }
if col > last_col.saturating_sub(PADDING) {
// scroll right
self.first_col += col - (last_col.saturating_sub(PADDING));
} else if col < self.first_col + PADDING {
// scroll left
self.first_col = col.saturating_sub(PADDING);
}
} }
/// Calculates the last visible line on screen /// Calculates the last visible line on screen
@ -130,6 +145,7 @@ impl View {
} }
let row = line - self.first_line as usize; let row = line - self.first_line as usize;
let col = col - self.first_col as usize;
Some(Position::new(row, col)) Some(Position::new(row, col))
} }

Loading…
Cancel
Save