aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/ui/picker.rs
diff options
context:
space:
mode:
authorPascal Kuthe2023-01-31 17:03:19 +0000
committerGitHub2023-01-31 17:03:19 +0000
commit4dcf1fe66ba30a78edc054780d9b65c2f826530f (patch)
treeffb84ea94f07ceb52494a955b1bd78f115395dc0 /helix-term/src/ui/picker.rs
parent4eca4b3079bf53de874959270d0b3471d320debc (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.rs81
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")),
- );
- }
}
}