Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-view/src/document.rs')
-rw-r--r--helix-view/src/document.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index c827274e..7a67ac7f 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -149,7 +149,10 @@ pub struct Document {
///
/// To know if they're up-to-date, check the `id` field in `DocumentInlayHints`.
pub(crate) inlay_hints: HashMap<ViewId, DocumentInlayHints>,
+ /// Jump label overlays for each view.
pub(crate) jump_labels: HashMap<ViewId, Vec<Overlay>>,
+ /// LSP document highlights for each view, stored as char ranges.
+ pub(crate) document_highlights: HashMap<ViewId, DocumentHighlights>,
/// Set to `true` when the document is updated, reset to `false` on the next inlay hints
/// update from the LSP
pub inlay_hints_oudated: bool,
@@ -211,6 +214,8 @@ pub struct Document {
// NOTE: ideally this would live on the handler for color swatches. This is blocked on a
// large refactor that would make `&mut Editor` available on the `DocumentDidChange` event.
pub color_swatch_controller: TaskController,
+ /// Per-view task controllers for canceling in-flight document highlight requests.
+ pub document_highlight_controllers: HashMap<ViewId, TaskController>,
pub pull_diagnostic_controller: TaskController,
// NOTE: this field should eventually go away - we should use the Editor's syn_loader instead
@@ -226,6 +231,12 @@ pub struct DocumentColorSwatches {
pub color_swatches_padding: Vec<InlineAnnotation>,
}
+/// Highlight ranges returned by LSP `textDocument/documentHighlight` for a view.
+#[derive(Debug, Clone, Default)]
+pub struct DocumentHighlights {
+ pub ranges: Vec<std::ops::Range<usize>>,
+}
+
/// Inlay hints for a single `(Document, View)` combo.
///
/// There are `*_inlay_hints` field for each kind of hints an LSP can send since we offer the
@@ -728,8 +739,10 @@ impl Document {
focused_at: std::time::Instant::now(),
readonly: false,
jump_labels: HashMap::new(),
+ document_highlights: HashMap::new(),
color_swatches: None,
color_swatch_controller: TaskController::new(),
+ document_highlight_controllers: HashMap::new(),
syn_loader,
previous_diagnostic_id: None,
pull_diagnostic_controller: TaskController::new(),
@@ -1380,6 +1393,8 @@ impl Document {
self.selections.remove(&view_id);
self.inlay_hints.remove(&view_id);
self.jump_labels.remove(&view_id);
+ self.document_highlights.remove(&view_id);
+ self.document_highlight_controllers.remove(&view_id);
}
/// Apply a [`Transaction`] to the [`Document`] to change its text.
@@ -1531,6 +1546,28 @@ impl Document {
apply_inlay_hint_changes(padding_after_inlay_hints);
}
+ for highlights in self.document_highlights.values_mut() {
+ let text_len = self.text.len_chars();
+ let mut updated = Vec::with_capacity(highlights.ranges.len());
+ for mut range in highlights.ranges.drain(..) {
+ changes.update_positions(
+ [
+ (&mut range.start, Assoc::After),
+ (&mut range.end, Assoc::After),
+ ]
+ .into_iter(),
+ );
+ if range.start >= text_len {
+ continue;
+ }
+ let end = range.end.min(text_len);
+ if range.start < end {
+ updated.push(range.start..end);
+ }
+ }
+ highlights.ranges = updated;
+ }
+
helix_event::dispatch(DocumentDidChange {
doc: self,
view: view_id,
@@ -2297,6 +2334,40 @@ impl Document {
self.jump_labels.remove(&view_id);
}
+ pub fn set_document_highlights(
+ &mut self,
+ view_id: ViewId,
+ ranges: Vec<std::ops::Range<usize>>,
+ ) {
+ if ranges.is_empty() {
+ self.document_highlights.remove(&view_id);
+ } else {
+ self.document_highlights
+ .insert(view_id, DocumentHighlights { ranges });
+ }
+ }
+
+ pub fn clear_document_highlights(&mut self, view_id: ViewId) {
+ self.document_highlights.remove(&view_id);
+ }
+
+ pub fn clear_all_document_highlights(&mut self) {
+ self.document_highlights.clear();
+ self.document_highlight_controllers.clear();
+ }
+
+ pub fn document_highlights(&self, view_id: ViewId) -> Option<&[std::ops::Range<usize>]> {
+ self.document_highlights
+ .get(&view_id)
+ .map(|highlights| highlights.ranges.as_slice())
+ }
+
+ pub fn document_highlight_controller(&mut self, view_id: ViewId) -> &mut TaskController {
+ self.document_highlight_controllers
+ .entry(view_id)
+ .or_default()
+ }
+
/// Get the inlay hints for this document and `view_id`.
pub fn inlay_hints(&self, view_id: ViewId) -> Option<&DocumentInlayHints> {
self.inlay_hints.get(&view_id)