cleanup: Make Buffer just a part of State.

This commit is contained in:
Blaž Hrastnik 2020-09-07 11:28:52 +09:00
parent 579b6899f1
commit 8b3e152126
6 changed files with 36 additions and 48 deletions

View file

@ -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<Self, Error> {
let _current_dir = env::current_dir()?;
let contents = Rope::from_reader(BufReader::new(File::open(path)?))?;
// TODO: create if not found
Ok(Buffer { contents })
}
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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<PathBuf>,
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<Self, Error> {
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.

View file

@ -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<text>, 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),

View file

@ -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)