cleanup: Make Buffer just a part of State.
This commit is contained in:
parent
579b6899f1
commit
8b3e152126
6 changed files with 36 additions and 48 deletions
|
@ -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 })
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -65,6 +65,6 @@ pub fn insert(state: &mut State, c: char) {
|
||||||
let pos = state.selection.primary().head;
|
let pos = state.selection.primary().head;
|
||||||
let changes = ChangeSet::insert(&state.doc, pos, c);
|
let changes = ChangeSet::insert(&state.doc, pos, c);
|
||||||
// TODO: need to store history
|
// TODO: need to store history
|
||||||
changes.apply(state.contents_mut());
|
changes.apply(&mut state.doc);
|
||||||
state.selection = state.selection.clone().map(&changes);
|
state.selection = state.selection.clone().map(&changes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
mod buffer;
|
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
mod graphemes;
|
mod graphemes;
|
||||||
mod selection;
|
mod selection;
|
||||||
|
@ -9,8 +8,6 @@ mod transaction;
|
||||||
pub use ropey::{Rope, RopeSlice};
|
pub use ropey::{Rope, RopeSlice};
|
||||||
pub use tendril::StrTendril as Tendril;
|
pub use tendril::StrTendril as Tendril;
|
||||||
|
|
||||||
pub use buffer::Buffer;
|
|
||||||
|
|
||||||
pub use selection::Range as SelectionRange;
|
pub use selection::Range as SelectionRange;
|
||||||
pub use selection::Selection;
|
pub use selection::Selection;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
use crate::graphemes::{nth_next_grapheme_boundary, nth_prev_grapheme_boundary, RopeGraphemes};
|
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 {
|
pub enum Mode {
|
||||||
Normal,
|
Normal,
|
||||||
|
@ -8,7 +11,9 @@ pub enum Mode {
|
||||||
|
|
||||||
/// A state represents the current editor state of a single buffer.
|
/// A state represents the current editor state of a single buffer.
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub doc: Buffer,
|
/// Path to file on disk.
|
||||||
|
pub path: Option<PathBuf>,
|
||||||
|
pub doc: Rope,
|
||||||
pub selection: Selection,
|
pub selection: Selection,
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
}
|
}
|
||||||
|
@ -28,15 +33,31 @@ pub enum Granularity {
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(doc: Buffer) -> Self {
|
pub fn new(doc: Rope) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
path: None,
|
||||||
doc,
|
doc,
|
||||||
selection: Selection::single(0, 0),
|
selection: Selection::single(0, 0),
|
||||||
mode: Mode::Normal,
|
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/transact:
|
||||||
// update(desc) => transaction ? transaction.doc() for applied doc
|
// update(desc) => transaction ? transaction.doc() for applied doc
|
||||||
|
@ -68,7 +89,7 @@ impl State {
|
||||||
granularity: Granularity,
|
granularity: Granularity,
|
||||||
count: usize,
|
count: usize,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
let text = &self.doc.contents;
|
let text = &self.doc;
|
||||||
match (dir, granularity) {
|
match (dir, granularity) {
|
||||||
// TODO: clamp movement to line, prevent moving onto \n at the end
|
// TODO: clamp movement to line, prevent moving onto \n at the end
|
||||||
(Direction::Backward, Granularity::Character) => {
|
(Direction::Backward, Granularity::Character) => {
|
||||||
|
@ -125,16 +146,6 @@ impl State {
|
||||||
Selection::new(ranges.collect(), sel.primary_index)
|
Selection::new(ranges.collect(), sel.primary_index)
|
||||||
// TODO: update selection in state via transaction
|
// 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.
|
/// Coordinates are a 0-indexed line and column pair.
|
||||||
|
|
|
@ -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
|
// TODO: divided into three different operations, I sort of like having just
|
||||||
// Splice { extent, Option<text>, distance } better.
|
// Splice { extent, Option<text>, distance } better.
|
||||||
|
@ -39,16 +39,16 @@ pub struct ChangeSet {
|
||||||
|
|
||||||
impl ChangeSet {
|
impl ChangeSet {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(buf: &Buffer) -> Self {
|
pub fn new(doc: &Rope) -> Self {
|
||||||
let len = buf.contents.len_chars();
|
let len = doc.len_chars();
|
||||||
Self {
|
Self {
|
||||||
changes: vec![Change::Retain(len)],
|
changes: vec![Change::Retain(len)],
|
||||||
len,
|
len,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(buf: &Buffer, pos: usize, c: char) -> Self {
|
pub fn insert(doc: &Rope, pos: usize, c: char) -> Self {
|
||||||
let len = buf.contents.len_chars();
|
let len = doc.len_chars();
|
||||||
Self {
|
Self {
|
||||||
changes: vec![
|
changes: vec![
|
||||||
Change::Retain(pos),
|
Change::Retain(pos),
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crossterm::{
|
||||||
terminal::{self, disable_raw_mode, enable_raw_mode},
|
terminal::{self, disable_raw_mode, enable_raw_mode},
|
||||||
};
|
};
|
||||||
use futures::{future::FutureExt, select, StreamExt};
|
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::io::{self, stdout, Write};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -38,9 +38,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open(&mut self, path: PathBuf) -> Result<(), Error> {
|
pub fn open(&mut self, path: PathBuf) -> Result<(), Error> {
|
||||||
let buffer = Buffer::load(path)?;
|
self.state = Some(State::load(path)?);
|
||||||
let state = State::new(buffer);
|
|
||||||
self.state = Some(state);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +46,7 @@ impl Editor {
|
||||||
match &self.state {
|
match &self.state {
|
||||||
Some(state) => {
|
Some(state) => {
|
||||||
let lines = state
|
let lines = state
|
||||||
.contents()
|
.doc
|
||||||
.lines_at(self.first_line as usize)
|
.lines_at(self.first_line as usize)
|
||||||
.take(self.size.1 as usize)
|
.take(self.size.1 as usize)
|
||||||
.map(|x| x.as_str().unwrap());
|
.map(|x| x.as_str().unwrap());
|
||||||
|
@ -90,7 +88,7 @@ impl Editor {
|
||||||
|
|
||||||
// render the cursor
|
// render the cursor
|
||||||
let pos = state.selection.primary().head;
|
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!(
|
execute!(
|
||||||
stdout,
|
stdout,
|
||||||
cursor::MoveTo((coords.1 + 2) as u16, coords.0 as u16)
|
cursor::MoveTo((coords.1 + 2) as u16, coords.0 as u16)
|
||||||
|
|
Loading…
Add table
Reference in a new issue