diff options
author | Pascal Kuthe | 2023-01-31 17:03:19 +0000 |
---|---|---|
committer | GitHub | 2023-01-31 17:03:19 +0000 |
commit | 4dcf1fe66ba30a78edc054780d9b65c2f826530f (patch) | |
tree | ffb84ea94f07ceb52494a955b1bd78f115395dc0 /helix-term/src/ui/picker.rs | |
parent | 4eca4b3079bf53de874959270d0b3471d320debc (diff) |
rework positioning/rendering and enable softwrap/virtual text (#5420)
* rework positioning/rendering, enables softwrap/virtual text
This commit is a large rework of the core text positioning and
rendering code in helix to remove the assumption that on-screen
columns/lines correspond to text columns/lines.
A generic `DocFormatter` is introduced that positions graphemes on
and is used both for rendering and for movements/scrolling.
Both virtual text support (inline, grapheme overlay and multi-line)
and a capable softwrap implementation is included.
fix picker highlight
cleanup doc formatter, use word bondaries for wrapping
make visual vertical movement a seperate commnad
estimate line gutter width to improve performance
cache cursor position
cleanup and optimize doc formatter
cleanup documentation
fix typos
Co-authored-by: Daniel Hines <d4hines@gmail.com>
update documentation
fix panic in last_visual_line funciton
improve soft-wrap documentation
add extend_visual_line_up/down commands
fix non-visual vertical movement
streamline virtual text highlighting, add softwrap indicator
fix cursor position if softwrap is disabled
improve documentation of text_annotations module
avoid crashes if view anchor is out of bounds
fix: consider horizontal offset when traslation char_idx -> vpos
improve default configuration
fix: mixed up horizontal and vertical offset
reset view position after config reload
apply suggestions from review
disabled softwrap for very small screens to avoid endless spin
fix wrap_indicator setting
fix bar cursor disappearring on the EOF character
add keybinding for linewise vertical movement
fix: inconsistent gutter highlights
improve virtual text API
make scope idx lookup more ergonomic
allow overlapping overlays
correctly track char_pos for virtual text
adjust configuration
deprecate old position fucntions
fix infinite loop in highlight lookup
fix gutter style
fix formatting
document max-line-width interaction with softwrap
change wrap-indicator example to use empty string
fix: rare panic when view is in invalid state (bis)
* Apply suggestions from code review
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
* improve documentation for positoning functions
* simplify tests
* fix documentation of Grapheme::width
* Apply suggestions from code review
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
* add explicit drop invocation
* Add explicit MoveFn type alias
* add docuntation to Editor::cursor_cache
* fix a few typos
* explain use of allow(deprecated)
* make gj and gk extend in select mode
* remove unneded debug and TODO
* mark tab_width_at #[inline]
* add fast-path to move_vertically_visual in case softwrap is disabled
* rename first_line to first_visual_line
* simplify duplicate if/else
---------
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
Diffstat (limited to 'helix-term/src/ui/picker.rs')
-rw-r--r-- | helix-term/src/ui/picker.rs | 81 |
1 files changed, 52 insertions, 29 deletions
diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 6bd64251..5fa75136 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -2,7 +2,12 @@ use crate::{ alt, compositor::{Component, Compositor, Context, Event, EventResult}, ctrl, key, shift, - ui::{self, fuzzy_match::FuzzyQuery, EditorView}, + ui::{ + self, + document::{render_document, LineDecoration, LinePos, TextRenderer}, + fuzzy_match::FuzzyQuery, + EditorView, + }, }; use futures_util::future::BoxFuture; use tui::{ @@ -19,11 +24,15 @@ use std::cmp::{self, Ordering}; use std::{collections::HashMap, io::Read, path::PathBuf}; use crate::ui::{Prompt, PromptEvent}; -use helix_core::{movement::Direction, unicode::segmentation::UnicodeSegmentation, Position}; +use helix_core::{ + movement::Direction, text_annotations::TextAnnotations, + unicode::segmentation::UnicodeSegmentation, Position, +}; use helix_view::{ editor::Action, graphics::{CursorKind, Margin, Modifier, Rect}, theme::Style, + view::ViewPosition, Document, DocumentId, Editor, }; @@ -179,7 +188,7 @@ impl<T: Item> FilePicker<T> { } _ => { // TODO: enable syntax highlighting; blocked by async rendering - Document::open(path, None, None) + Document::open(path, None, None, editor.config.clone()) .map(|doc| CachedPreview::Document(Box::new(doc))) .unwrap_or(CachedPreview::NotFound) } @@ -283,43 +292,57 @@ impl<T: Item + 'static> Component for FilePicker<T> { }) .unwrap_or(0); - let offset = Position::new(first_line, 0); + let offset = ViewPosition { + anchor: doc.text().line_to_char(first_line), + horizontal_offset: 0, + vertical_offset: 0, + }; - let mut highlights = - EditorView::doc_syntax_highlights(doc, offset, area.height, &cx.editor.theme); + let mut highlights = EditorView::doc_syntax_highlights( + doc, + offset.anchor, + area.height, + &cx.editor.theme, + ); for spans in EditorView::doc_diagnostics_highlights(doc, &cx.editor.theme) { if spans.is_empty() { continue; } highlights = Box::new(helix_core::syntax::merge(highlights, spans)); } - EditorView::render_text_highlights( + let mut decorations: Vec<Box<dyn LineDecoration>> = Vec::new(); + + if let Some((start, end)) = range { + let style = cx + .editor + .theme + .try_get("ui.highlight") + .unwrap_or_else(|| cx.editor.theme.get("ui.selection")); + let draw_highlight = move |renderer: &mut TextRenderer, pos: LinePos| { + if (start..=end).contains(&pos.doc_line) { + let area = Rect::new( + renderer.viewport.x, + renderer.viewport.y + pos.visual_line, + renderer.viewport.width, + 1, + ); + renderer.surface.set_style(area, style) + } + }; + decorations.push(Box::new(draw_highlight)) + } + + render_document( + surface, + inner, doc, offset, - inner, - surface, - &cx.editor.theme, + &TextAnnotations::default(), highlights, - &cx.editor.config(), + &cx.editor.theme, + &mut decorations, + &mut [], ); - - // highlight the line - if let Some((start, end)) = range { - let offset = start.saturating_sub(first_line) as u16; - surface.set_style( - Rect::new( - inner.x, - inner.y + offset, - inner.width, - (end.saturating_sub(start) as u16 + 1) - .min(inner.height.saturating_sub(offset)), - ), - cx.editor - .theme - .try_get("ui.highlight") - .unwrap_or_else(|| cx.editor.theme.get("ui.selection")), - ); - } } } |