From bf95ee27aa3c9f137e34f30a01f25e4930a8b1bb Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Tue, 16 Mar 2021 18:27:57 +0900 Subject: Store Document on the Editor type, make View reference it. --- helix-view/src/editor.rs | 37 +++++++++++++++++++++++++++++-------- helix-view/src/lib.rs | 3 +++ helix-view/src/view.rs | 17 ++++++++++------- 3 files changed, 42 insertions(+), 15 deletions(-) (limited to 'helix-view') diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index d294d190..08f4183d 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -1,14 +1,15 @@ -use crate::{theme::Theme, tree::Tree, Document, View}; +use crate::{theme::Theme, tree::Tree, Document, DocumentId, View}; use std::path::PathBuf; +use std::{cell::RefCell, rc::Rc}; -use slotmap::DefaultKey as Key; +use slotmap::{DefaultKey as Key, SlotMap}; use anyhow::Error; pub struct Editor { pub tree: Tree, - // pub documents: Vec, + pub documents: SlotMap>>, pub count: Option, pub theme: Theme, pub language_servers: helix_lsp::Registry, @@ -25,6 +26,7 @@ impl Editor { Self { tree: Tree::new(area), + documents: SlotMap::with_key(), count: None, theme, language_servers, @@ -33,10 +35,12 @@ impl Editor { } pub fn open(&mut self, path: PathBuf) -> Result<(), Error> { + // TODO: issues with doc already being borrowed if called from inside goto() + let existing_view = self .tree .views() - .find(|(view, _)| view.doc.path() == Some(&path)); + .find(|(view, _)| view.doc.borrow().path() == Some(&path)); if let Some((view, _)) = existing_view { self.tree.focus = view.id; @@ -69,6 +73,10 @@ impl Editor { .unwrap(); } + let doc = Rc::new(RefCell::new(doc)); + // TODO: store id as doc.id + let id = self.documents.insert(doc.clone()); + let view = View::new(doc)?; self.tree.insert(view); Ok(()) @@ -80,7 +88,7 @@ impl Editor { let language_servers = &mut self.language_servers; let executor = self.executor; - let doc = &view.doc; + let doc = view.doc.borrow(); let language_server = doc .language @@ -90,7 +98,19 @@ impl Editor { if let Some(language_server) = language_server { smol::block_on(language_server.text_document_did_close(doc.identifier())).unwrap(); } - self.tree.remove(id) + + drop(doc); // to stop borrowing self.tree + + // self.documents.remove(view.doc); + self.tree.remove(id); + } + + pub fn resize(&mut self) { + self.tree.focus_next(); + } + + pub fn focus_next(&mut self) { + self.tree.focus_next(); } pub fn should_close(&self) -> bool { @@ -108,8 +128,9 @@ impl Editor { pub fn cursor_position(&self) -> Option { const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter let view = self.view(); - let cursor = view.doc.selection().cursor(); - if let Some(mut pos) = view.screen_coords_at_pos(view.doc.text().slice(..), cursor) { + let doc = view.doc.borrow(); + let cursor = doc.selection().cursor(); + if let Some(mut pos) = view.screen_coords_at_pos(doc.text().slice(..), cursor) { pos.col += view.area.x as usize + OFFSET as usize; pos.row += view.area.y as usize; return Some(pos); diff --git a/helix-view/src/lib.rs b/helix-view/src/lib.rs index 05de7e9f..d98d2c5a 100644 --- a/helix-view/src/lib.rs +++ b/helix-view/src/lib.rs @@ -4,6 +4,9 @@ pub mod theme; pub mod tree; pub mod view; +use slotmap::new_key_type; +new_key_type! { pub struct DocumentId; } + pub use document::Document; pub use editor::Editor; pub use theme::Theme; diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index 31a36047..2a77f2c0 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -1,8 +1,9 @@ use anyhow::Error; use std::borrow::Cow; +use std::{cell::RefCell, rc::Rc}; -use crate::Document; +use crate::{Document, DocumentId}; use helix_core::{ graphemes::{grapheme_width, RopeGraphemes}, Position, RopeSlice, @@ -14,13 +15,13 @@ pub const PADDING: usize = 5; pub struct View { pub id: Key, - pub doc: Document, + pub doc: Rc>, pub first_line: usize, pub area: Rect, } impl View { - pub fn new(doc: Document) -> Result { + pub fn new(doc: Rc>) -> Result { let view = Self { id: Key::default(), doc, @@ -32,8 +33,9 @@ impl View { } pub fn ensure_cursor_in_view(&mut self) { - let cursor = self.doc.selection().cursor(); - let line = self.doc.text().char_to_line(cursor); + let doc = self.doc.borrow(); + let cursor = doc.selection().cursor(); + let line = doc.text().char_to_line(cursor); let document_end = self.first_line + (self.area.height as usize).saturating_sub(2); // TODO: side scroll @@ -50,10 +52,11 @@ impl View { /// Calculates the last visible line on screen #[inline] pub fn last_line(&self) -> usize { + let doc = self.doc.borrow(); let height = self.area.height.saturating_sub(1); // - 1 for statusline std::cmp::min( self.first_line + height as usize, - self.doc.text().len_lines() - 1, + doc.text().len_lines() - 1, ) } @@ -71,7 +74,7 @@ impl View { let line_start = text.line_to_char(line); let line_slice = text.slice(line_start..pos); let mut col = 0; - let tab_width = self.doc.tab_width(); + let tab_width = self.doc.borrow().tab_width(); for grapheme in RopeGraphemes::new(line_slice) { if grapheme == "\t" { -- cgit v1.2.3-70-g09d2