Move filepath into the Buffer struct.

This commit is contained in:
Nathan Vegdahl 2020-02-24 07:35:04 +09:00
parent 4544efb299
commit e1d91ff43d
5 changed files with 60 additions and 73 deletions

View File

@ -4,13 +4,13 @@ use std::{
cmp::{max, min},
collections::HashMap,
fs::File,
io::{self, BufReader, BufWriter, Write},
path::{Path, PathBuf},
io::{self, BufWriter, Write},
};
use ropey::Rope;
use backend::{buffer::Buffer, marks::Mark};
use backend::{
buffer::{Buffer, BufferPath},
marks::Mark,
};
use crate::{
formatter::LineFormatter,
@ -24,7 +24,6 @@ use crate::{
pub struct Editor {
pub buffer: Buffer,
pub formatter: LineFormatter,
pub file_path: PathBuf,
pub line_ending_type: LineEnding,
pub soft_tabs: bool,
pub soft_tab_width: u8,
@ -43,48 +42,18 @@ pub struct Editor {
impl Editor {
/// Create a new blank editor
pub fn new(formatter: LineFormatter) -> Editor {
let (buffer, v_msi, c_msi) = {
let mut buffer = Buffer::new("".into());
let view_idx = buffer.add_mark_set();
let cursors_idx = buffer.add_mark_set();
pub fn new(buffer: Buffer, formatter: LineFormatter) -> Editor {
let mut buffer = buffer;
buffer.mark_sets[view_idx].add_mark(Mark::new(0, 0));
buffer.mark_sets[cursors_idx].add_mark(Mark::new(0, 0));
(buffer, view_idx, cursors_idx)
};
Editor {
buffer: buffer,
formatter: formatter,
file_path: PathBuf::new(),
line_ending_type: LineEnding::LF,
soft_tabs: false,
soft_tab_width: 4,
editor_dim: (0, 0),
view_dim: (0, 0),
v_msi: v_msi,
c_msi: c_msi,
}
}
pub fn new_from_file(formatter: LineFormatter, path: &Path) -> io::Result<Editor> {
let (buffer, v_msi, c_msi) = {
let mut buffer = Buffer::new(Rope::from_reader(BufReader::new(File::open(path)?))?);
let view_idx = buffer.add_mark_set();
let cursors_idx = buffer.add_mark_set();
buffer.mark_sets[view_idx].add_mark(Mark::new(0, 0));
buffer.mark_sets[cursors_idx].add_mark(Mark::new(0, 0));
(buffer, view_idx, cursors_idx)
};
// Create appropriate mark sets for view positions and cursors.
let v_msi = buffer.add_mark_set();
let c_msi = buffer.add_mark_set();
buffer.mark_sets[v_msi].add_mark(Mark::new(0, 0));
buffer.mark_sets[c_msi].add_mark(Mark::new(0, 0));
let mut ed = Editor {
buffer: buffer,
formatter: formatter,
file_path: path.to_path_buf(),
line_ending_type: LineEnding::LF,
soft_tabs: false,
soft_tab_width: 4,
@ -97,12 +66,13 @@ impl Editor {
ed.auto_detect_line_ending();
ed.auto_detect_indentation_style();
Ok(ed)
ed
}
pub fn save_if_dirty(&mut self) -> io::Result<()> {
if self.buffer.is_dirty && self.file_path != PathBuf::new() {
let mut f = BufWriter::new(File::create(&self.file_path)?);
if let BufferPath::File(ref file_path) = self.buffer.path {
if self.buffer.is_dirty {
let mut f = BufWriter::new(File::create(file_path)?);
for c in self.buffer.text.chunks() {
f.write(c.as_bytes())?;
@ -110,6 +80,7 @@ impl Editor {
self.buffer.is_dirty = false;
}
}
Ok(())
}

View File

@ -1,8 +1,13 @@
use std::{io::Write, path::Path};
use std::{
fs::File,
io::{BufReader, Write},
};
use backend::buffer::{Buffer, BufferPath};
use clap::{App, Arg};
use editor::Editor;
use formatter::LineFormatter;
use ropey::Rope;
use term_ui::TermUI;
mod editor;
@ -14,7 +19,7 @@ mod utils;
const VERSION: &str = env!("CARGO_PKG_VERSION");
fn main() {
fn main() -> std::io::Result<()> {
// Parse command line arguments.
let args = App::new("Led")
.version(VERSION)
@ -28,13 +33,17 @@ fn main() {
.get_matches();
// Load file, if specified
let editor = if let Some(filepath) = args.value_of("file") {
Editor::new_from_file(LineFormatter::new(4), &Path::new(&filepath[..]))
.expect(&format!("Couldn't open file '{}'.", filepath))
let buffer = if let Some(filepath) = args.value_of("file") {
Buffer::new(
Rope::from_reader(BufReader::new(File::open(filepath)?))?,
BufferPath::File(filepath.into()),
)
} else {
Editor::new(LineFormatter::new(4))
Buffer::new("".into(), BufferPath::Temp(0))
};
let editor = Editor::new(buffer, LineFormatter::new(4));
// Holds stderr output in an internal buffer, and prints it when dropped.
// This keeps stderr from being swallowed by the TUI.
let stderr_hold = gag::Hold::stderr().unwrap();
@ -58,4 +67,6 @@ fn main() {
// Resume panic unwind.
std::panic::resume_unwind(e);
}
Ok(())
}

View File

@ -10,9 +10,10 @@ use crossterm::{
style::Color,
};
use backend::buffer::BufferPath;
use crate::{
editor::Editor,
formatter::LineFormatter,
string_utils::{char_count, is_line_ending, line_ending_to_str, LineEnding},
utils::{digit_count, Timer},
};
@ -187,10 +188,6 @@ enum LoopStatus {
}
impl TermUI {
pub fn new() -> TermUI {
TermUI::new_from_editor(Editor::new(LineFormatter::new(4)))
}
pub fn new_from_editor(ed: Editor) -> TermUI {
let (w, h) = crossterm::terminal::size().unwrap();
let mut editor = ed;
@ -463,7 +460,10 @@ impl TermUI {
}
// Filename and dirty marker
let filename = editor.file_path.display();
let filename = match editor.buffer.path {
BufferPath::File(ref p) => format!("{}", p.display()),
BufferPath::Temp(i) => format!("Scratch #{}", i + 1),
};
let dirty_char = if editor.buffer.is_dirty { "*" } else { "" };
let name = format!("{}{}", filename, dirty_char);
self.screen.draw(c1.1 + 1, c1.0, &name[..], STYLE_INFO);

View File

@ -1,3 +1,5 @@
use std::path::PathBuf;
use ropey::Rope;
use crate::{
@ -5,9 +7,20 @@ use crate::{
marks::MarkSet,
};
/// A path for an open text buffer.
///
/// This indicates where the text data of the buffer came from, and
/// where it should be saved to.
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum BufferPath {
File(PathBuf), // A buffer for a normal file on disk.
Temp(usize), // A temporary buffer, with a number ID.
}
/// An open text buffer, currently being edited.
#[derive(Debug, Clone)]
pub struct Buffer {
pub path: BufferPath,
pub is_dirty: bool, // Is this buffer currently out of sync with disk.
pub text: Rope, // The actual text content.
pub mark_sets: Vec<MarkSet>, // MarkSets for cursors, view positions, etc.
@ -15,8 +28,9 @@ pub struct Buffer {
}
impl Buffer {
pub fn new(text: Rope) -> Buffer {
pub fn new(text: Rope, path: BufferPath) -> Buffer {
Buffer {
path: path,
is_dirty: false,
text: text,
mark_sets: Vec::new(),

View File

@ -1,5 +1,3 @@
use std::path::PathBuf;
use crate::buffer::Buffer;
/// A struct holding the current editor state.
@ -7,12 +5,5 @@ use crate::buffer::Buffer;
/// The Editor represents all currently open buffers available for editing.
#[derive(Debug)]
pub struct Editor {
open_buffers: Vec<(BufferID, Buffer)>,
}
/// An ID for an open text buffer.
#[derive(Debug, Clone)]
pub enum BufferID {
File(PathBuf), // A buffer for a normal file on disk, using the full on-disk path as the ID
Temp(usize), // A temporary buffer, with a number ID
open_buffers: Vec<Buffer>,
}