on master help sign in
cleanup: Make Buffer just a part of State.
commit8b3e152126ec8f0e67dad378dc62c734ea97a4b0 authorBlaž Hrastnik <blaz@mxxn.io> dateMon 7 Sep 2020, 11:28 (6 years ago) parent579b689
6 files changed+36−48
helix-core/src/buffer.rs−18 helix-core/src/commands.rs+1−1 helix-core/src/lib.rs−3 helix-core/src/state.rs+26−15 helix-core/src/transaction.rs+5−5 helix-term/src/editor.rs+4−6
helix-core/src/buffer.rsdeleted−18
@@ -1,18 +0,0 @@
1−use anyhow::Error;
2−use ropey::Rope;
3−use std::{env, fs::File, io::BufReader, path::PathBuf};
4−
5−pub struct Buffer {
6− pub contents: Rope,
7−}
8−
9−impl Buffer {
10− pub fn load(path: PathBuf) -> Result<Self, Error> {
11− let _current_dir = env::current_dir()?;
12−
13− let contents = Rope::from_reader(BufReader::new(File::open(path)?))?;
14−
15− // TODO: create if not found
16− Ok(Buffer { contents })
17− }
18−}
helix-core/src/commands.rs+1−1
@@ -65,6 +65,6 @@ pub fn insert(state: &mut State, c: char) {
6565 let pos = state.selection.primary().head;
6666 let changes = ChangeSet::insert(&state.doc, pos, c);
6767 // TODO: need to store history
68− changes.apply(state.contents_mut());
68+ changes.apply(&mut state.doc);
6969 state.selection = state.selection.clone().map(&changes);
7070}
helix-core/src/lib.rs−3
@@ -1,5 +1,4 @@
11#![allow(unused)]
2−mod buffer;
32pub mod commands;
43mod graphemes;
54mod selection;
@@ -9,8 +8,6 @@ mod transaction;
98pub use ropey::{Rope, RopeSlice};
109pub use tendril::StrTendril as Tendril;
1110
12−pub use buffer::Buffer;
13−
1411pub use selection::Range as SelectionRange;
1512pub use selection::Selection;
1613
helix-core/src/state.rs+26−15
@@ -1,5 +1,8 @@
11use crate::graphemes::{nth_next_grapheme_boundary, nth_prev_grapheme_boundary, RopeGraphemes};
2−use crate::{Buffer, Rope, RopeSlice, Selection, SelectionRange};
2+use crate::{Rope, RopeSlice, Selection, SelectionRange};
3+use anyhow::Error;
4+
5+use std::path::PathBuf;
36
47pub enum Mode {
58 Normal,
@@ -8,7 +11,9 @@ pub enum Mode {
811
912/// A state represents the current editor state of a single buffer.
1013pub struct State {
11− pub doc: Buffer,
14+ /// Path to file on disk.
15+ pub path: Option<PathBuf>,
16+ pub doc: Rope,
1217 pub selection: Selection,
1318 pub mode: Mode,
1419}
@@ -28,15 +33,31 @@ pub enum Granularity {
2833
2934impl State {
3035 #[must_use]
31− pub fn new(doc: Buffer) -> Self {
36+ pub fn new(doc: Rope) -> Self {
3237 Self {
38+ path: None,
3339 doc,
3440 selection: Selection::single(0, 0),
3541 mode: Mode::Normal,
3642 }
3743 }
3844
39− // TODO: buf/selection accessors
45+ #[must_use]
46+ pub fn load(path: PathBuf) -> Result<Self, Error> {
47+ use std::{env, fs::File, io::BufReader, path::PathBuf};
48+ let _current_dir = env::current_dir()?;
49+
50+ let doc = Rope::from_reader(BufReader::new(File::open(path.clone())?))?;
51+
52+ // TODO: create if not found
53+
54+ let mut state = Self::new(doc);
55+ state.path = Some(path);
56+
57+ Ok(state)
58+ }
59+
60+ // TODO: doc/selection accessors
4061
4162 // update/transact:
4263 // update(desc) => transaction ? transaction.doc() for applied doc
@@ -68,7 +89,7 @@ impl State {
6889 granularity: Granularity,
6990 count: usize,
7091 ) -> usize {
71− let text = &self.doc.contents;
92+ let text = &self.doc;
7293 match (dir, granularity) {
7394 // TODO: clamp movement to line, prevent moving onto \n at the end
7495 (Direction::Backward, Granularity::Character) => {
@@ -125,16 +146,6 @@ impl State {
125146 Selection::new(ranges.collect(), sel.primary_index)
126147 // TODO: update selection in state via transaction
127148 }
128−
129− pub fn contents(&self) -> &Rope {
130− // used to access file contents for rendering to screen
131− &self.doc.contents
132− }
133−
134− pub fn contents_mut(&mut self) -> &mut Rope {
135− // used to access file contents for rendering to screen
136− &mut self.doc.contents
137− }
138149}
139150
140151/// Coordinates are a 0-indexed line and column pair.
helix-core/src/transaction.rs+5−5
@@ -1,4 +1,4 @@
1−use crate::{Buffer, Rope, Selection, Tendril};
1+use crate::{Rope, Selection, Tendril};
22
33// TODO: divided into three different operations, I sort of like having just
44// Splice { extent, Option<text>, distance } better.
@@ -39,16 +39,16 @@ pub struct ChangeSet {
3939
4040impl ChangeSet {
4141 #[must_use]
42− pub fn new(buf: &Buffer) -> Self {
43− let len = buf.contents.len_chars();
42+ pub fn new(doc: &Rope) -> Self {
43+ let len = doc.len_chars();
4444 Self {
4545 changes: vec![Change::Retain(len)],
4646 len,
4747 }
4848 }
4949
50− pub fn insert(buf: &Buffer, pos: usize, c: char) -> Self {
51− let len = buf.contents.len_chars();
50+ pub fn insert(doc: &Rope, pos: usize, c: char) -> Self {
51+ let len = doc.len_chars();
5252 Self {
5353 changes: vec![
5454 Change::Retain(pos),
helix-term/src/editor.rs+4−6
@@ -9,7 +9,7 @@ use crossterm::{
99 terminal::{self, disable_raw_mode, enable_raw_mode},
1010};
1111use futures::{future::FutureExt, select, StreamExt};
12−use helix_core::{state::coords_at_pos, state::Mode, Buffer, State};
12+use helix_core::{state::coords_at_pos, state::Mode, State};
1313use std::io::{self, stdout, Write};
1414use std::path::PathBuf;
1515use std::time::Duration;
@@ -38,9 +38,7 @@ impl Editor {
3838 }
3939
4040 pub fn open(&mut self, path: PathBuf) -> Result<(), Error> {
41− let buffer = Buffer::load(path)?;
42− let state = State::new(buffer);
43− self.state = Some(state);
41+ self.state = Some(State::load(path)?);
4442 Ok(())
4543 }
4644
@@ -48,7 +46,7 @@ impl Editor {
4846 match &self.state {
4947 Some(state) => {
5048 let lines = state
51− .contents()
49+ .doc
5250 .lines_at(self.first_line as usize)
5351 .take(self.size.1 as usize)
5452 .map(|x| x.as_str().unwrap());
@@ -90,7 +88,7 @@ impl Editor {
9088
9189 // render the cursor
9290 let pos = state.selection.primary().head;
93− let coords = coords_at_pos(&state.doc.contents.slice(..), pos);
91+ let coords = coords_at_pos(&state.doc.slice(..), pos);
9492 execute!(
9593 stdout,
9694 cursor::MoveTo((coords.1 + 2) as u16, coords.0 as u16)