mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 09:26:19 +04:00
use slices instead of Rc for virtual text
This commit is contained in:
parent
a38ec6d6ca
commit
553f8706ab
@ -116,7 +116,7 @@ fn default() -> Self {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DocumentFormatter<'t> {
|
pub struct DocumentFormatter<'t> {
|
||||||
text_fmt: &'t TextFormat,
|
text_fmt: &'t TextFormat,
|
||||||
annotations: &'t TextAnnotations,
|
annotations: &'t TextAnnotations<'t>,
|
||||||
|
|
||||||
/// The visual position at the end of the last yielded word boundary
|
/// The visual position at the end of the last yielded word boundary
|
||||||
visual_pos: Position,
|
visual_pos: Position,
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use crate::doc_formatter::{DocumentFormatter, TextFormat};
|
use crate::doc_formatter::{DocumentFormatter, TextFormat};
|
||||||
use crate::text_annotations::{InlineAnnotation, Overlay, TextAnnotations};
|
use crate::text_annotations::{InlineAnnotation, Overlay, TextAnnotations};
|
||||||
|
|
||||||
@ -105,7 +103,7 @@ fn overlay_text(text: &str, char_pos: usize, softwrap: bool, overlays: &[Overlay
|
|||||||
DocumentFormatter::new_at_prev_checkpoint(
|
DocumentFormatter::new_at_prev_checkpoint(
|
||||||
text.into(),
|
text.into(),
|
||||||
&TextFormat::new_test(softwrap),
|
&TextFormat::new_test(softwrap),
|
||||||
TextAnnotations::default().add_overlay(overlays.into(), None),
|
TextAnnotations::default().add_overlay(overlays, None),
|
||||||
char_pos,
|
char_pos,
|
||||||
)
|
)
|
||||||
.0
|
.0
|
||||||
@ -142,7 +140,7 @@ fn annotate_text(text: &str, softwrap: bool, annotations: &[InlineAnnotation]) -
|
|||||||
DocumentFormatter::new_at_prev_checkpoint(
|
DocumentFormatter::new_at_prev_checkpoint(
|
||||||
text.into(),
|
text.into(),
|
||||||
&TextFormat::new_test(softwrap),
|
&TextFormat::new_test(softwrap),
|
||||||
TextAnnotations::default().add_inline_annotations(annotations.into(), None),
|
TextAnnotations::default().add_inline_annotations(annotations, None),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
.0
|
.0
|
||||||
@ -164,15 +162,24 @@ fn annotation() {
|
|||||||
"foo foo foo foo \n.foo foo foo foo \n.foo foo foo "
|
"foo foo foo foo \n.foo foo foo foo \n.foo foo foo "
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn annotation_and_overlay() {
|
fn annotation_and_overlay() {
|
||||||
|
let annotations = [InlineAnnotation {
|
||||||
|
char_idx: 0,
|
||||||
|
text: "fooo".into(),
|
||||||
|
}];
|
||||||
|
let overlay = [Overlay {
|
||||||
|
char_idx: 0,
|
||||||
|
grapheme: "\t".into(),
|
||||||
|
}];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
DocumentFormatter::new_at_prev_checkpoint(
|
DocumentFormatter::new_at_prev_checkpoint(
|
||||||
"bbar".into(),
|
"bbar".into(),
|
||||||
&TextFormat::new_test(false),
|
&TextFormat::new_test(false),
|
||||||
TextAnnotations::default()
|
TextAnnotations::default()
|
||||||
.add_inline_annotations(Rc::new([InlineAnnotation::new(0, "fooo")]), None)
|
.add_inline_annotations(annotations.as_slice(), None)
|
||||||
.add_overlay(Rc::new([Overlay::new(0, "\t")]), None),
|
.add_overlay(overlay.as_slice(), None),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
.0
|
.0
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use crate::syntax::Highlight;
|
use crate::syntax::Highlight;
|
||||||
use crate::Tendril;
|
use crate::Tendril;
|
||||||
@ -92,23 +91,23 @@ pub struct LineAnnotation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Layer<A, M> {
|
struct Layer<'a, A, M> {
|
||||||
annotations: Rc<[A]>,
|
annotations: &'a [A],
|
||||||
current_index: Cell<usize>,
|
current_index: Cell<usize>,
|
||||||
metadata: M,
|
metadata: M,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, M: Clone> Clone for Layer<A, M> {
|
impl<A, M: Clone> Clone for Layer<'_, A, M> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Layer {
|
Layer {
|
||||||
annotations: self.annotations.clone(),
|
annotations: self.annotations,
|
||||||
current_index: self.current_index.clone(),
|
current_index: self.current_index.clone(),
|
||||||
metadata: self.metadata.clone(),
|
metadata: self.metadata.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, M> Layer<A, M> {
|
impl<A, M> Layer<'_, A, M> {
|
||||||
pub fn reset_pos(&self, char_idx: usize, get_char_idx: impl Fn(&A) -> usize) {
|
pub fn reset_pos(&self, char_idx: usize, get_char_idx: impl Fn(&A) -> usize) {
|
||||||
let new_index = self
|
let new_index = self
|
||||||
.annotations
|
.annotations
|
||||||
@ -128,8 +127,8 @@ pub fn consume(&self, char_idx: usize, get_char_idx: impl Fn(&A) -> usize) -> Op
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, M> From<(Rc<[A]>, M)> for Layer<A, M> {
|
impl<'a, A, M> From<(&'a [A], M)> for Layer<'a, A, M> {
|
||||||
fn from((annotations, metadata): (Rc<[A]>, M)) -> Layer<A, M> {
|
fn from((annotations, metadata): (&'a [A], M)) -> Layer<A, M> {
|
||||||
Layer {
|
Layer {
|
||||||
annotations,
|
annotations,
|
||||||
current_index: Cell::new(0),
|
current_index: Cell::new(0),
|
||||||
@ -147,13 +146,13 @@ fn reset_pos<A, M>(layers: &[Layer<A, M>], pos: usize, get_pos: impl Fn(&A) -> u
|
|||||||
/// Annotations that change that is displayed when the document is render.
|
/// Annotations that change that is displayed when the document is render.
|
||||||
/// Also commonly called virtual text.
|
/// Also commonly called virtual text.
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
pub struct TextAnnotations {
|
pub struct TextAnnotations<'a> {
|
||||||
inline_annotations: Vec<Layer<InlineAnnotation, Option<Highlight>>>,
|
inline_annotations: Vec<Layer<'a, InlineAnnotation, Option<Highlight>>>,
|
||||||
overlays: Vec<Layer<Overlay, Option<Highlight>>>,
|
overlays: Vec<Layer<'a, Overlay, Option<Highlight>>>,
|
||||||
line_annotations: Vec<Layer<LineAnnotation, ()>>,
|
line_annotations: Vec<Layer<'a, LineAnnotation, ()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextAnnotations {
|
impl<'a> TextAnnotations<'a> {
|
||||||
/// Prepare the TextAnnotations for iteration starting at char_idx
|
/// Prepare the TextAnnotations for iteration starting at char_idx
|
||||||
pub fn reset_pos(&self, char_idx: usize) {
|
pub fn reset_pos(&self, char_idx: usize) {
|
||||||
reset_pos(&self.inline_annotations, char_idx, |annot| annot.char_idx);
|
reset_pos(&self.inline_annotations, char_idx, |annot| annot.char_idx);
|
||||||
@ -194,7 +193,7 @@ pub fn collect_overlay_highlights(
|
|||||||
/// the annotations that belong to the layers added first will be shown first.
|
/// the annotations that belong to the layers added first will be shown first.
|
||||||
pub fn add_inline_annotations(
|
pub fn add_inline_annotations(
|
||||||
&mut self,
|
&mut self,
|
||||||
layer: Rc<[InlineAnnotation]>,
|
layer: &'a [InlineAnnotation],
|
||||||
highlight: Option<Highlight>,
|
highlight: Option<Highlight>,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.inline_annotations.push((layer, highlight).into());
|
self.inline_annotations.push((layer, highlight).into());
|
||||||
@ -211,7 +210,7 @@ pub fn add_inline_annotations(
|
|||||||
///
|
///
|
||||||
/// If multiple layers contain overlay at the same position
|
/// If multiple layers contain overlay at the same position
|
||||||
/// the overlay from the layer added last will be show.
|
/// the overlay from the layer added last will be show.
|
||||||
pub fn add_overlay(&mut self, layer: Rc<[Overlay]>, highlight: Option<Highlight>) -> &mut Self {
|
pub fn add_overlay(&mut self, layer: &'a [Overlay], highlight: Option<Highlight>) -> &mut Self {
|
||||||
self.overlays.push((layer, highlight).into());
|
self.overlays.push((layer, highlight).into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -220,7 +219,7 @@ pub fn add_overlay(&mut self, layer: Rc<[Overlay]>, highlight: Option<Highlight>
|
|||||||
///
|
///
|
||||||
/// The line annotations **must be sorted** by their `char_idx`.
|
/// The line annotations **must be sorted** by their `char_idx`.
|
||||||
/// Multiple line annotations with the same `char_idx` **are not allowed**.
|
/// Multiple line annotations with the same `char_idx` **are not allowed**.
|
||||||
pub fn add_line_annotation(&mut self, layer: Rc<[LineAnnotation]>) -> &mut Self {
|
pub fn add_line_annotation(&mut self, layer: &'a [LineAnnotation]) -> &mut Self {
|
||||||
self.line_annotations.push((layer, ()).into());
|
self.line_annotations.push((layer, ()).into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -605,6 +605,7 @@ fn move_impl(cx: &mut Context, move_fn: MoveFn, dir: Direction, behaviour: Movem
|
|||||||
&mut annotations,
|
&mut annotations,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
drop(annotations);
|
||||||
doc.set_selection(view.id, selection);
|
doc.set_selection(view.id, selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1523,7 +1524,7 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
|
|||||||
let doc_text = doc.text().slice(..);
|
let doc_text = doc.text().slice(..);
|
||||||
let viewport = view.inner_area(doc);
|
let viewport = view.inner_area(doc);
|
||||||
let text_fmt = doc.text_format(viewport.width, None);
|
let text_fmt = doc.text_format(viewport.width, None);
|
||||||
let annotations = view.text_annotations(doc, None);
|
let annotations = view.text_annotations(&*doc, None);
|
||||||
(view.offset.anchor, view.offset.vertical_offset) = char_idx_at_visual_offset(
|
(view.offset.anchor, view.offset.vertical_offset) = char_idx_at_visual_offset(
|
||||||
doc_text,
|
doc_text,
|
||||||
view.offset.anchor,
|
view.offset.anchor,
|
||||||
@ -1577,6 +1578,7 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
|
|||||||
let mut sel = doc.selection(view.id).clone();
|
let mut sel = doc.selection(view.id).clone();
|
||||||
let idx = sel.primary_index();
|
let idx = sel.primary_index();
|
||||||
sel = sel.replace(idx, prim_sel);
|
sel = sel.replace(idx, prim_sel);
|
||||||
|
drop(annotations);
|
||||||
doc.set_selection(view.id, sel);
|
doc.set_selection(view.id, sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
use helix_core::doc_formatter::TextFormat;
|
use helix_core::doc_formatter::TextFormat;
|
||||||
use helix_core::encoding::Encoding;
|
use helix_core::encoding::Encoding;
|
||||||
use helix_core::syntax::{Highlight, LanguageServerFeature};
|
use helix_core::syntax::{Highlight, LanguageServerFeature};
|
||||||
use helix_core::text_annotations::{InlineAnnotation, TextAnnotations};
|
use helix_core::text_annotations::InlineAnnotation;
|
||||||
use helix_vcs::{DiffHandle, DiffProviderRegistry};
|
use helix_vcs::{DiffHandle, DiffProviderRegistry};
|
||||||
|
|
||||||
use ::parking_lot::Mutex;
|
use ::parking_lot::Mutex;
|
||||||
@ -1804,12 +1804,6 @@ pub fn text_format(&self, mut viewport_width: u16, theme: Option<&Theme>) -> Tex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the text annotations that apply to the whole document, those that do not apply to any
|
|
||||||
/// specific view.
|
|
||||||
pub fn text_annotations(&self, _theme: Option<&Theme>) -> TextAnnotations {
|
|
||||||
TextAnnotations::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the inlay hints for this document and `view_id`.
|
/// Set the inlay hints for this document and `view_id`.
|
||||||
pub fn set_inlay_hints(&mut self, view_id: ViewId, inlay_hints: DocumentInlayHints) {
|
pub fn set_inlay_hints(&mut self, view_id: ViewId, inlay_hints: DocumentInlayHints) {
|
||||||
self.inlay_hints.insert(view_id, inlay_hints);
|
self.inlay_hints.insert(view_id, inlay_hints);
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, VecDeque},
|
collections::{HashMap, VecDeque},
|
||||||
fmt,
|
fmt,
|
||||||
rc::Rc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const JUMP_LIST_CAPACITY: usize = 30;
|
const JUMP_LIST_CAPACITY: usize = 30;
|
||||||
@ -409,10 +408,12 @@ pub fn screen_coords_at_pos(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the text annotations to display in the current view for the given document and theme.
|
/// Get the text annotations to display in the current view for the given document and theme.
|
||||||
pub fn text_annotations(&self, doc: &Document, theme: Option<&Theme>) -> TextAnnotations {
|
pub fn text_annotations<'a>(
|
||||||
// TODO custom annotations for custom views like side by side diffs
|
&self,
|
||||||
|
doc: &'a Document,
|
||||||
let mut text_annotations = doc.text_annotations(theme);
|
theme: Option<&Theme>,
|
||||||
|
) -> TextAnnotations<'a> {
|
||||||
|
let mut text_annotations = TextAnnotations::default();
|
||||||
|
|
||||||
let DocumentInlayHints {
|
let DocumentInlayHints {
|
||||||
id: _,
|
id: _,
|
||||||
@ -436,20 +437,15 @@ pub fn text_annotations(&self, doc: &Document, theme: Option<&Theme>) -> TextAnn
|
|||||||
.and_then(|t| t.find_scope_index("ui.virtual.inlay-hint"))
|
.and_then(|t| t.find_scope_index("ui.virtual.inlay-hint"))
|
||||||
.map(Highlight);
|
.map(Highlight);
|
||||||
|
|
||||||
let mut add_annotations = |annotations: &Rc<[_]>, style| {
|
|
||||||
if !annotations.is_empty() {
|
|
||||||
text_annotations.add_inline_annotations(Rc::clone(annotations), style);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Overlapping annotations are ignored apart from the first so the order here is not random:
|
// Overlapping annotations are ignored apart from the first so the order here is not random:
|
||||||
// types -> parameters -> others should hopefully be the "correct" order for most use cases,
|
// types -> parameters -> others should hopefully be the "correct" order for most use cases,
|
||||||
// with the padding coming before and after as expected.
|
// with the padding coming before and after as expected.
|
||||||
add_annotations(padding_before_inlay_hints, None);
|
text_annotations
|
||||||
add_annotations(type_inlay_hints, type_style);
|
.add_inline_annotations(padding_before_inlay_hints, None)
|
||||||
add_annotations(parameter_inlay_hints, parameter_style);
|
.add_inline_annotations(type_inlay_hints, type_style)
|
||||||
add_annotations(other_inlay_hints, other_style);
|
.add_inline_annotations(parameter_inlay_hints, parameter_style)
|
||||||
add_annotations(padding_after_inlay_hints, None);
|
.add_inline_annotations(other_inlay_hints, other_style)
|
||||||
|
.add_inline_annotations(padding_after_inlay_hints, None);
|
||||||
|
|
||||||
text_annotations
|
text_annotations
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user