Skip to content

Commit

Permalink
introduce helper functions on Document .view_offset, set_view_offset
Browse files Browse the repository at this point in the history
  • Loading branch information
intarga committed Apr 27, 2024
1 parent 6494301 commit 83e3ce0
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 54 deletions.
24 changes: 12 additions & 12 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,7 @@ fn goto_window(cx: &mut Context, align: Align) {
let count = cx.count() - 1;
let config = cx.editor.config();
let (view, doc) = current!(cx.editor);
let view_offset = doc.view_data_mut(view.id).view_position;
let view_offset = doc.view_offset(view.id);

let height = view.inner_height();

Expand Down Expand Up @@ -1668,7 +1668,7 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction, sync_cursor
use Direction::*;
let config = cx.editor.config();
let (view, doc) = current!(cx.editor);
let view_offset = doc.view_data_mut(view.id).view_position;
let mut view_offset = doc.view_offset(view.id);

let range = doc.selection(view.id).primary();
let text = doc.text().slice(..);
Expand All @@ -1686,17 +1686,15 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction, sync_cursor
let viewport = view.inner_area(doc);
let text_fmt = doc.text_format(viewport.width, None);
let annotations = view.text_annotations(&*doc, None);
let (new_anchor, new_vertical_offset) = char_idx_at_visual_offset(
(view_offset.anchor, view_offset.vertical_offset) = char_idx_at_visual_offset(
doc_text,
view_offset.anchor,
view_offset.vertical_offset as isize + offset,
0,
&text_fmt,
&annotations,
);
let view_data = doc.view_data_mut(view.id);
view_data.view_position.anchor = new_anchor;
view_data.view_position.vertical_offset = new_vertical_offset;
doc.set_view_offset(view.id, view_offset);

let doc_text = doc.text().slice(..);
let mut annotations = view.text_annotations(&*doc, None);
Expand Down Expand Up @@ -1725,7 +1723,7 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction, sync_cursor
return;
}

let view_offset = doc.view_data(view.id).view_position;
let view_offset = doc.view_offset(view.id);

let mut head;
match direction {
Expand Down Expand Up @@ -5142,7 +5140,7 @@ fn split(editor: &mut Editor, action: Action) {
let (view, doc) = current!(editor);
let id = doc.id();
let selection = doc.selection(view.id).clone();
let offset = doc.view_data(view.id).view_position;
let offset = doc.view_offset(view.id);

editor.switch(id, action);

Expand All @@ -5151,7 +5149,7 @@ fn split(editor: &mut Editor, action: Action) {
doc.set_selection(view.id, selection);
// match the view scroll offset (switch doesn't handle this fully
// since the selection is only matched after the split)
doc.view_data_mut(view.id).view_position = offset;
doc.set_view_offset(view.id, offset);
}

fn hsplit(cx: &mut Context) {
Expand Down Expand Up @@ -5250,16 +5248,18 @@ fn align_view_middle(cx: &mut Context) {
let pos = doc.selection(view.id).primary().cursor(doc_text);
let pos = visual_offset_from_block(
doc_text,
doc.view_data(view.id).view_position.anchor,
doc.view_offset(view.id).anchor,
pos,
&text_fmt,
&annotations,
)
.0;

doc.view_data_mut(view.id).view_position.horizontal_offset = pos
let mut offset = doc.view_offset(view.id);
offset.horizontal_offset = pos
.col
.saturating_sub((view.inner_area(doc).width as usize) / 2);
doc.set_view_offset(view.id, offset);
}

fn scroll_up(cx: &mut Context) {
Expand Down Expand Up @@ -6120,7 +6120,7 @@ fn jump_to_word(cx: &mut Context, behaviour: Movement) {

// This is not necessarily exact if there is virtual text like soft wrap.
// It's ok though because the extra jump labels will not be rendered.
let start = text.line_to_char(text.char_to_line(doc.view_data(view.id).view_position.anchor));
let start = text.line_to_char(text.char_to_line(doc.view_offset(view.id).anchor));
let end = text.line_to_char(view.estimate_last_doc_line(doc) + 1);

let primary_selection = doc.selection(view.id).primary();
Expand Down
8 changes: 2 additions & 6 deletions helix-term/src/commands/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1208,12 +1208,8 @@ fn compute_inlay_hints_for_view(
// than computing all the hints for the full file (which could be dozens of time
// longer than the view is).
let view_height = view.inner_height();
let first_visible_line = doc_text.char_to_line(
doc.view_data(view_id)
.view_position
.anchor
.min(doc_text.len_chars()),
);
let first_visible_line =
doc_text.char_to_line(doc.view_offset(view_id).anchor.min(doc_text.len_chars()));
let first_line = first_visible_line.saturating_sub(view_height);
let last_line = first_visible_line
.saturating_add(view_height.saturating_mul(2))
Expand Down
7 changes: 1 addition & 6 deletions helix-term/src/commands/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1554,12 +1554,7 @@ fn tree_sitter_highlight_name(
// Query the same range as the one used in syntax highlighting.
let range = {
// Calculate viewport byte ranges:
let row = text.char_to_line(
doc.view_data(view.id)
.view_position
.anchor
.min(text.len_chars()),
);
let row = text.char_to_line(doc.view_offset(view.id).anchor.min(text.len_chars()));
// Saturating subs to make it inclusive zero indexing.
let last_line = text.len_lines().saturating_sub(1);
let height = view.inner_area(doc).height;
Expand Down
6 changes: 3 additions & 3 deletions helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl EditorView {
let theme = &editor.theme;
let config = editor.config();

let view_offset = doc.view_data(view.id).view_position;
let view_offset = doc.view_offset(view.id);

let text_annotations = view.text_annotations(doc, Some(theme));
let mut line_decorations: Vec<Box<dyn LineDecoration>> = Vec::new();
Expand Down Expand Up @@ -251,7 +251,7 @@ impl EditorView {
.and_then(|config| config.rulers.as_ref())
.unwrap_or(editor_rulers);

let view_offset = doc.view_data(view.id).view_position;
let view_offset = doc.view_offset(view.id);

rulers
.iter()
Expand Down Expand Up @@ -827,7 +827,7 @@ impl EditorView {
let inner_area = view.inner_area(doc);

let selection = doc.selection(view.id);
let view_offset = doc.view_data(view.id).view_position;
let view_offset = doc.view_offset(view.id);
let primary = selection.primary();
let text_format = doc.text_format(viewport.width, None);
for range in selection.iter() {
Expand Down
6 changes: 3 additions & 3 deletions helix-term/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub fn raw_regex_prompt(
let (view, doc) = current!(cx.editor);
let doc_id = view.doc;
let snapshot = doc.selection(view.id).clone();
let offset_snapshot = doc.view_data(view.id).view_position;
let offset_snapshot = doc.view_offset(view.id);
let config = cx.editor.config();

let mut prompt = Prompt::new(
Expand All @@ -94,7 +94,7 @@ pub fn raw_regex_prompt(
PromptEvent::Abort => {
let (view, doc) = current!(cx.editor);
doc.set_selection(view.id, snapshot.clone());
doc.view_data_mut(view.id).view_position = offset_snapshot;
doc.set_view_offset(view.id, offset_snapshot);
}
PromptEvent::Update | PromptEvent::Validate => {
// skip empty input
Expand Down Expand Up @@ -135,7 +135,7 @@ pub fn raw_regex_prompt(
Err(err) => {
let (view, doc) = current!(cx.editor);
doc.set_selection(view.id, snapshot.clone());
doc.view_data_mut(view.id).view_position = offset_snapshot;
doc.set_view_offset(view.id, offset_snapshot);

if event == PromptEvent::Validate {
let callback = async move {
Expand Down
21 changes: 15 additions & 6 deletions helix-view/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1734,19 +1734,28 @@ impl Document {
&self.selections
}

pub(crate) fn get_view_data(&self, view_id: ViewId) -> Option<&ViewData> {
self.view_data.get(&view_id)
}
pub fn view_data(&self, view_id: ViewId) -> &ViewData {
fn view_data(&self, view_id: ViewId) -> &ViewData {
self.view_data
.get(&view_id)
.expect("This should only be called after ensure_view_init")
}

pub fn view_data_mut(&mut self, view_id: ViewId) -> &mut ViewData {
fn view_data_mut(&mut self, view_id: ViewId) -> &mut ViewData {
self.view_data.entry(view_id).or_default()
}

pub(crate) fn get_view_offset(&self, view_id: ViewId) -> Option<ViewPosition> {
Some(self.view_data.get(&view_id)?.view_position)
}

pub fn view_offset(&self, view_id: ViewId) -> ViewPosition {
self.view_data(view_id).view_position
}

pub fn set_view_offset(&mut self, view_id: ViewId, new_offset: ViewPosition) {
self.view_data_mut(view_id).view_position = new_offset;
}

pub fn relative_path(&self) -> Option<Cow<Path>> {
self.path
.as_deref()
Expand Down Expand Up @@ -2023,7 +2032,7 @@ impl Document {

#[derive(Debug, Default)]
pub struct ViewData {
pub view_position: ViewPosition,
view_position: ViewPosition,
}

#[derive(Clone, Debug)]
Expand Down
7 changes: 3 additions & 4 deletions helix-view/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub fn align_view(doc: &mut Document, view: &View, align: Align) {
let cursor = doc.selection(view.id).primary().cursor(doc_text);
let viewport = view.inner_area(doc);
let last_line_height = viewport.height.saturating_sub(1);
let mut view_offset = doc.view_offset(view.id);

let relative = match align {
Align::Center => last_line_height / 2,
Expand All @@ -60,17 +61,15 @@ pub fn align_view(doc: &mut Document, view: &View, align: Align) {

let text_fmt = doc.text_format(viewport.width, None);
let annotations = view.text_annotations(doc, None);
let (new_anchor, new_vertical_offset) = char_idx_at_visual_offset(
(view_offset.anchor, view_offset.vertical_offset) = char_idx_at_visual_offset(
doc_text,
cursor,
-(relative as isize),
0,
&text_fmt,
&annotations,
);
let view_data = doc.view_data_mut(view.id);
view_data.view_position.anchor = new_anchor;
view_data.view_position.vertical_offset = new_vertical_offset;
doc.set_view_offset(view.id, view_offset);
}

pub use document::Document;
Expand Down
22 changes: 8 additions & 14 deletions helix-view/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ impl View {
doc: &Document,
scrolloff: usize,
) -> Option<ViewPosition> {
let view_offset = doc.get_view_data(self.id)?.view_position;
let view_offset = doc.get_view_offset(self.id)?;
let doc_text = doc.text().slice(..);
let viewport = self.inner_area(doc);
let vertical_viewport_end = view_offset.vertical_offset + viewport.height as usize;
Expand Down Expand Up @@ -298,13 +298,13 @@ impl View {

pub fn ensure_cursor_in_view(&self, doc: &mut Document, scrolloff: usize) {
if let Some(offset) = self.offset_coords_to_in_view_center::<false>(doc, scrolloff) {
doc.view_data_mut(self.id).view_position = offset;
doc.set_view_offset(self.id, offset);
}
}

pub fn ensure_cursor_in_view_center(&self, doc: &mut Document, scrolloff: usize) {
if let Some(offset) = self.offset_coords_to_in_view_center::<true>(doc, scrolloff) {
doc.view_data_mut(self.id).view_position = offset;
doc.set_view_offset(self.id, offset);
} else {
align_view(doc, self, Align::Center);
}
Expand All @@ -322,12 +322,7 @@ impl View {
#[inline]
pub fn estimate_last_doc_line(&self, doc: &Document) -> usize {
let doc_text = doc.text().slice(..);
let line = doc_text.char_to_line(
doc.view_data(self.id)
.view_position
.anchor
.min(doc_text.len_chars()),
);
let line = doc_text.char_to_line(doc.view_offset(self.id).anchor.min(doc_text.len_chars()));
// Saturating subs to make it inclusive zero indexing.
(line + self.inner_height())
.min(doc_text.len_lines())
Expand All @@ -341,11 +336,10 @@ impl View {
let viewport = self.inner_area(doc);
let text_fmt = doc.text_format(viewport.width, None);
let annotations = self.text_annotations(doc, None);
let view_offset = doc.view_data(self.id).view_position;
let view_offset = doc.view_offset(self.id);

// last visual line in view is trivial to compute
let visual_height =
doc.view_data(self.id).view_position.vertical_offset + viewport.height as usize;
let visual_height = doc.view_offset(self.id).vertical_offset + viewport.height as usize;

// fast path when the EOF is not visible on the screen,
if self.estimate_last_doc_line(doc) < doc_text.len_lines() - 1 {
Expand Down Expand Up @@ -378,7 +372,7 @@ impl View {
text: RopeSlice,
pos: usize,
) -> Option<Position> {
let view_offset = doc.view_data(self.id).view_position;
let view_offset = doc.view_offset(self.id);

if pos < view_offset.anchor {
// Line is not visible on screen
Expand Down Expand Up @@ -500,7 +494,7 @@ impl View {
ignore_virtual_text: bool,
) -> Option<usize> {
let text = doc.text().slice(..);
let view_offset = doc.view_data(self.id).view_position;
let view_offset = doc.view_offset(self.id);

let text_row = row as usize + view_offset.vertical_offset;
let text_col = column as usize + view_offset.horizontal_offset;
Expand Down

0 comments on commit 83e3ce0

Please sign in to comment.