diff options
Diffstat (limited to 'helix-view/src/document.rs')
-rw-r--r-- | helix-view/src/document.rs | 74 |
1 files changed, 61 insertions, 13 deletions
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 6b33ea6a..798b5400 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -1,7 +1,11 @@ use anyhow::{anyhow, bail, Context, Error}; +use arc_swap::access::DynAccess; use futures_util::future::BoxFuture; use futures_util::FutureExt; use helix_core::auto_pairs::AutoPairs; +use helix_core::doc_formatter::TextFormat; +use helix_core::syntax::Highlight; +use helix_core::text_annotations::TextAnnotations; use helix_core::Range; use helix_vcs::{DiffHandle, DiffProviderRegistry}; @@ -26,8 +30,8 @@ use helix_core::{ DEFAULT_LINE_ENDING, }; -use crate::editor::RedrawHandle; -use crate::{DocumentId, Editor, View, ViewId}; +use crate::editor::{Config, RedrawHandle}; +use crate::{DocumentId, Editor, Theme, View, ViewId}; /// 8kB of buffer space for encoding and decoding `Rope`s. const BUF_SIZE: usize = 8192; @@ -127,6 +131,7 @@ pub struct Document { // it back as it separated from the edits. We could split out the parts manually but that will // be more troublesome. pub history: Cell<History>, + pub config: Arc<dyn DynAccess<Config>>, pub savepoint: Option<Transaction>, @@ -351,7 +356,11 @@ use helix_lsp::lsp; use url::Url; impl Document { - pub fn from(text: Rope, encoding: Option<&'static encoding::Encoding>) -> Self { + pub fn from( + text: Rope, + encoding: Option<&'static encoding::Encoding>, + config: Arc<dyn DynAccess<Config>>, + ) -> Self { let encoding = encoding.unwrap_or(encoding::UTF_8); let changes = ChangeSet::new(&text); let old_state = None; @@ -377,9 +386,13 @@ impl Document { modified_since_accessed: false, language_server: None, diff_handle: None, + config, } } - + pub fn default(config: Arc<dyn DynAccess<Config>>) -> Self { + let text = Rope::from(DEFAULT_LINE_ENDING.as_str()); + Self::from(text, None, config) + } // TODO: async fn? /// Create a new document from `path`. Encoding is auto-detected, but it can be manually /// overwritten with the `encoding` parameter. @@ -387,6 +400,7 @@ impl Document { path: &Path, encoding: Option<&'static encoding::Encoding>, config_loader: Option<Arc<syntax::Loader>>, + config: Arc<dyn DynAccess<Config>>, ) -> Result<Self, Error> { // Open the file if it exists, otherwise assume it is a new file (and thus empty). let (rope, encoding) = if path.exists() { @@ -398,7 +412,7 @@ impl Document { (Rope::from(DEFAULT_LINE_ENDING.as_str()), encoding) }; - let mut doc = Self::from(rope, Some(encoding)); + let mut doc = Self::from(rope, Some(encoding), config); // set the path and try detecting the language doc.set_path(Some(path))?; @@ -1192,12 +1206,34 @@ impl Document { None => global_config, } } -} -impl Default for Document { - fn default() -> Self { - let text = Rope::from(DEFAULT_LINE_ENDING.as_str()); - Self::from(text, None) + pub fn text_format(&self, mut viewport_width: u16, theme: Option<&Theme>) -> TextFormat { + if let Some(max_line_len) = self + .language_config() + .and_then(|config| config.max_line_length) + { + viewport_width = viewport_width.min(max_line_len as u16) + } + let config = self.config.load(); + let soft_wrap = &config.soft_wrap; + let tab_width = self.tab_width() as u16; + TextFormat { + soft_wrap: soft_wrap.enable && viewport_width > 10, + tab_width, + max_wrap: soft_wrap.max_wrap.min(viewport_width / 4), + max_indent_retain: soft_wrap.max_indent_retain.min(viewport_width * 2 / 5), + // avoid spinning forever when the window manager + // sets the size to something tiny + viewport_width, + wrap_indicator: soft_wrap.wrap_indicator.clone().into_boxed_str(), + wrap_indicator_highlight: theme + .and_then(|theme| theme.find_scope_index("ui.virtual.wrap")) + .map(Highlight), + } + } + + pub fn text_annotations(&self, _theme: Option<&Theme>) -> TextAnnotations { + TextAnnotations::default() } } @@ -1236,13 +1272,19 @@ impl Display for FormatterError { #[cfg(test)] mod test { + use arc_swap::ArcSwap; + use super::*; #[test] fn changeset_to_changes_ignore_line_endings() { use helix_lsp::{lsp, Client, OffsetEncoding}; let text = Rope::from("hello\r\nworld"); - let mut doc = Document::from(text, None); + let mut doc = Document::from( + text, + None, + Arc::new(ArcSwap::new(Arc::new(Config::default()))), + ); let view = ViewId::default(); doc.set_selection(view, Selection::single(0, 0)); @@ -1276,7 +1318,11 @@ mod test { fn changeset_to_changes() { use helix_lsp::{lsp, Client, OffsetEncoding}; let text = Rope::from("hello"); - let mut doc = Document::from(text, None); + let mut doc = Document::from( + text, + None, + Arc::new(ArcSwap::new(Arc::new(Config::default()))), + ); let view = ViewId::default(); doc.set_selection(view, Selection::single(5, 5)); @@ -1389,7 +1435,9 @@ mod test { #[test] fn test_line_ending() { assert_eq!( - Document::default().text().to_string(), + Document::default(Arc::new(ArcSwap::new(Arc::new(Config::default())))) + .text() + .to_string(), DEFAULT_LINE_ENDING.as_str() ); } |