From 8b3e152126ec8f0e67dad378dc62c734ea97a4b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Mon, 7 Sep 2020 11:28:52 +0900 Subject: [PATCH] cleanup: Make Buffer just a part of State. --- helix-core/src/buffer.rs | 18 --------------- helix-core/src/commands.rs | 2 +- helix-core/src/lib.rs | 3 --- helix-core/src/state.rs | 41 ++++++++++++++++++++++------------- helix-core/src/transaction.rs | 10 ++++----- helix-term/src/editor.rs | 10 ++++----- 6 files changed, 36 insertions(+), 48 deletions(-) delete mode 100644 helix-core/src/buffer.rs diff --git a/helix-core/src/buffer.rs b/helix-core/src/buffer.rs deleted file mode 100644 index 746e01ea5..000000000 --- a/helix-core/src/buffer.rs +++ /dev/null @@ -1,18 +0,0 @@ -use anyhow::Error; -use ropey::Rope; -use std::{env, fs::File, io::BufReader, path::PathBuf}; - -pub struct Buffer { - pub contents: Rope, -} - -impl Buffer { - pub fn load(path: PathBuf) -> Result { - let _current_dir = env::current_dir()?; - - let contents = Rope::from_reader(BufReader::new(File::open(path)?))?; - - // TODO: create if not found - Ok(Buffer { contents }) - } -} diff --git a/helix-core/src/commands.rs b/helix-core/src/commands.rs index a6b74449f..705960452 100644 --- a/helix-core/src/commands.rs +++ b/helix-core/src/commands.rs @@ -65,6 +65,6 @@ pub fn insert(state: &mut State, c: char) { let pos = state.selection.primary().head; let changes = ChangeSet::insert(&state.doc, pos, c); // TODO: need to store history - changes.apply(state.contents_mut()); + changes.apply(&mut state.doc); state.selection = state.selection.clone().map(&changes); } diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index f9e987a6e..c7c020d6d 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -1,5 +1,4 @@ #![allow(unused)] -mod buffer; pub mod commands; mod graphemes; mod selection; @@ -9,8 +8,6 @@ mod transaction; pub use ropey::{Rope, RopeSlice}; pub use tendril::StrTendril as Tendril; -pub use buffer::Buffer; - pub use selection::Range as SelectionRange; pub use selection::Selection; diff --git a/helix-core/src/state.rs b/helix-core/src/state.rs index 8568c3c3f..c3a5c3cd8 100644 --- a/helix-core/src/state.rs +++ b/helix-core/src/state.rs @@ -1,5 +1,8 @@ use crate::graphemes::{nth_next_grapheme_boundary, nth_prev_grapheme_boundary, RopeGraphemes}; -use crate::{Buffer, Rope, RopeSlice, Selection, SelectionRange}; +use crate::{Rope, RopeSlice, Selection, SelectionRange}; +use anyhow::Error; + +use std::path::PathBuf; pub enum Mode { Normal, @@ -8,7 +11,9 @@ pub enum Mode { /// A state represents the current editor state of a single buffer. pub struct State { - pub doc: Buffer, + /// Path to file on disk. + pub path: Option, + pub doc: Rope, pub selection: Selection, pub mode: Mode, } @@ -28,15 +33,31 @@ pub enum Granularity { impl State { #[must_use] - pub fn new(doc: Buffer) -> Self { + pub fn new(doc: Rope) -> Self { Self { + path: None, doc, selection: Selection::single(0, 0), mode: Mode::Normal, } } - // TODO: buf/selection accessors + #[must_use] + pub fn load(path: PathBuf) -> Result { + use std::{env, fs::File, io::BufReader, path::PathBuf}; + let _current_dir = env::current_dir()?; + + let doc = Rope::from_reader(BufReader::new(File::open(path.clone())?))?; + + // TODO: create if not found + + let mut state = Self::new(doc); + state.path = Some(path); + + Ok(state) + } + + // TODO: doc/selection accessors // update/transact: // update(desc) => transaction ? transaction.doc() for applied doc @@ -68,7 +89,7 @@ impl State { granularity: Granularity, count: usize, ) -> usize { - let text = &self.doc.contents; + let text = &self.doc; match (dir, granularity) { // TODO: clamp movement to line, prevent moving onto \n at the end (Direction::Backward, Granularity::Character) => { @@ -125,16 +146,6 @@ impl State { Selection::new(ranges.collect(), sel.primary_index) // TODO: update selection in state via transaction } - - pub fn contents(&self) -> &Rope { - // used to access file contents for rendering to screen - &self.doc.contents - } - - pub fn contents_mut(&mut self) -> &mut Rope { - // used to access file contents for rendering to screen - &mut self.doc.contents - } } /// Coordinates are a 0-indexed line and column pair. diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs index 2d8afc9b4..d078679c7 100644 --- a/helix-core/src/transaction.rs +++ b/helix-core/src/transaction.rs @@ -1,4 +1,4 @@ -use crate::{Buffer, Rope, Selection, Tendril}; +use crate::{Rope, Selection, Tendril}; // TODO: divided into three different operations, I sort of like having just // Splice { extent, Option, distance } better. @@ -39,16 +39,16 @@ pub struct ChangeSet { impl ChangeSet { #[must_use] - pub fn new(buf: &Buffer) -> Self { - let len = buf.contents.len_chars(); + pub fn new(doc: &Rope) -> Self { + let len = doc.len_chars(); Self { changes: vec![Change::Retain(len)], len, } } - pub fn insert(buf: &Buffer, pos: usize, c: char) -> Self { - let len = buf.contents.len_chars(); + pub fn insert(doc: &Rope, pos: usize, c: char) -> Self { + let len = doc.len_chars(); Self { changes: vec![ Change::Retain(pos), diff --git a/helix-term/src/editor.rs b/helix-term/src/editor.rs index ef4af3dc7..4abc8477b 100644 --- a/helix-term/src/editor.rs +++ b/helix-term/src/editor.rs @@ -9,7 +9,7 @@ use crossterm::{ terminal::{self, disable_raw_mode, enable_raw_mode}, }; use futures::{future::FutureExt, select, StreamExt}; -use helix_core::{state::coords_at_pos, state::Mode, Buffer, State}; +use helix_core::{state::coords_at_pos, state::Mode, State}; use std::io::{self, stdout, Write}; use std::path::PathBuf; use std::time::Duration; @@ -38,9 +38,7 @@ impl Editor { } pub fn open(&mut self, path: PathBuf) -> Result<(), Error> { - let buffer = Buffer::load(path)?; - let state = State::new(buffer); - self.state = Some(state); + self.state = Some(State::load(path)?); Ok(()) } @@ -48,7 +46,7 @@ impl Editor { match &self.state { Some(state) => { let lines = state - .contents() + .doc .lines_at(self.first_line as usize) .take(self.size.1 as usize) .map(|x| x.as_str().unwrap()); @@ -90,7 +88,7 @@ impl Editor { // render the cursor let pos = state.selection.primary().head; - let coords = coords_at_pos(&state.doc.contents.slice(..), pos); + let coords = coords_at_pos(&state.doc.slice(..), pos); execute!( stdout, cursor::MoveTo((coords.1 + 2) as u16, coords.0 as u16)