From 0f3c10a021bbe79e20bde1f55b87465edeec476d Mon Sep 17 00:00:00 2001 From: Skyler Hawthorne Date: Wed, 16 Mar 2022 23:34:21 -0400 Subject: Fix initial selection of Document in new view When a new View of a Document is created, a default cursor of 0, 0 is created, and it does not get normalized to a single width cursor until at least one movement of the cursor happens. This appears to have no practical negative effect that I could find, but it makes tests difficult to work with, since the initial selection is not what you expect it to be. This changes the initial selection of a new View to be the width of the first grapheme in the text. --- helix-view/src/document.rs | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'helix-view/src/document.rs') diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index a2d2af77..00adaa1a 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -1,5 +1,6 @@ use anyhow::{anyhow, bail, Context, Error}; use helix_core::auto_pairs::AutoPairs; +use helix_core::Range; use serde::de::{self, Deserialize, Deserializer}; use serde::Serialize; use std::cell::Cell; @@ -83,7 +84,7 @@ impl Serialize for Mode { pub struct Document { pub(crate) id: DocumentId, text: Rope, - pub(crate) selections: HashMap, + selections: HashMap, path: Option, encoding: &'static encoding::Encoding, @@ -637,6 +638,37 @@ impl Document { .insert(view_id, selection.ensure_invariants(self.text().slice(..))); } + /// Find the origin selection of the text in a document, i.e. where + /// a single cursor would go if it were on the first grapheme. If + /// the text is empty, returns (0, 0). + pub fn origin(&self) -> Range { + if self.text().len_chars() == 0 { + return Range::new(0, 0); + } + + Range::new(0, 1).grapheme_aligned(self.text().slice(..)) + } + + /// Reset the view's selection on this document to the + /// [origin](Document::origin) cursor. + pub fn reset_selection(&mut self, view_id: ViewId) { + let origin = self.origin(); + self.set_selection(view_id, Selection::single(origin.anchor, origin.head)); + } + + /// Initializes a new selection for the given view if it does not + /// already have one. + pub fn ensure_view_init(&mut self, view_id: ViewId) { + if self.selections.get(&view_id).is_none() { + self.reset_selection(view_id); + } + } + + /// Remove a view's selection from this document. + pub fn remove_view(&mut self, view_id: ViewId) { + self.selections.remove(&view_id); + } + /// Apply a [`Transaction`] to the [`Document`] to change its text. fn apply_impl(&mut self, transaction: &Transaction, view_id: ViewId) -> bool { let old_doc = self.text().clone(); -- cgit v1.2.3-70-g09d2