deleting
This commit is contained in:
+14
-1
@@ -1,6 +1,6 @@
|
||||
use std::{cmp::min, mem::swap};
|
||||
|
||||
use crate::{BYTES_PER_LINE, app::{App, Mode, PartialAction}};
|
||||
use crate::{BYTES_PER_LINE, app::{App, Mode, PartialAction}, edit_action::EditAction};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Action {
|
||||
@@ -40,6 +40,8 @@ pub enum Action {
|
||||
|
||||
ExtendLineBelow,
|
||||
ExtendLineAbove,
|
||||
|
||||
Delete,
|
||||
}
|
||||
|
||||
impl App {
|
||||
@@ -81,6 +83,8 @@ impl App {
|
||||
|
||||
Action::ExtendLineBelow => self.extend_line_below(),
|
||||
Action::ExtendLineAbove => self.extend_line_above(),
|
||||
|
||||
Action::Delete => self.delete(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,6 +277,15 @@ impl App {
|
||||
self.cursor.tail += BYTES_PER_LINE - 1 - (self.cursor.tail % BYTES_PER_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
fn delete(&mut self) {
|
||||
self.execute_and_add(
|
||||
EditAction::Delete {
|
||||
cursor: self.cursor,
|
||||
data: self.contents[self.cursor.range()].into()
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// helpers
|
||||
|
||||
+18
-2
@@ -1,21 +1,29 @@
|
||||
use std::{env, fs::File, io::Read, path::PathBuf, process::exit};
|
||||
use crossterm::{event::{self, Event, KeyEvent}, terminal::window_size};
|
||||
use ratatui::style::Color;
|
||||
|
||||
use crate::{config::Config, cursor::Cursor};
|
||||
use crate::{config::Config, cursor::Cursor, edit_action::EditAction};
|
||||
|
||||
mod widget;
|
||||
|
||||
pub struct App {
|
||||
pub config: Config,
|
||||
pub file_name: String,
|
||||
|
||||
pub contents: Vec<u8>,
|
||||
|
||||
pub window_rows: usize,
|
||||
|
||||
pub scroll_position: usize,
|
||||
pub cursor: Cursor,
|
||||
|
||||
pub should_quit: bool,
|
||||
|
||||
pub mode: Mode,
|
||||
pub partial_action: Option<PartialAction>,
|
||||
|
||||
pub edit_history: Vec<EditAction>,
|
||||
// some index to keep track of where we are? edit_prophecy?
|
||||
|
||||
pub logs: Vec<String>,
|
||||
}
|
||||
|
||||
@@ -77,14 +85,22 @@ impl App {
|
||||
Self {
|
||||
config: Config::default(),
|
||||
file_name: file_path.file_name().unwrap().to_str().unwrap().to_owned(),
|
||||
|
||||
contents,
|
||||
|
||||
// -1 because of the status line
|
||||
window_rows: window_size().unwrap().rows as usize - 1,
|
||||
|
||||
scroll_position: 0,
|
||||
cursor: Cursor::default(),
|
||||
|
||||
should_quit: false,
|
||||
|
||||
mode: Mode::Normal,
|
||||
partial_action: None,
|
||||
|
||||
edit_history: Vec::new(),
|
||||
|
||||
logs: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
+10
-1
@@ -361,7 +361,8 @@ mod status_line {
|
||||
Line::from_iter([
|
||||
self.render_mode(),
|
||||
" ".into(),
|
||||
self.render_file_name()
|
||||
self.render_file_name(),
|
||||
self.modified_indicator()
|
||||
])
|
||||
)
|
||||
.bg(Color::ui_grey())
|
||||
@@ -376,6 +377,14 @@ mod status_line {
|
||||
fn render_file_name(&self) -> Span<'_> {
|
||||
Span::from(&self.file_name)
|
||||
}
|
||||
|
||||
fn modified_indicator(&self) -> Span<'static> {
|
||||
if self.edit_history.is_empty() {
|
||||
"".into()
|
||||
} else {
|
||||
" [+]".into()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,6 +131,8 @@ impl Default for Config {
|
||||
|
||||
("x".try_into().unwrap(), Action::ExtendLineBelow),
|
||||
("X".try_into().unwrap(), Action::ExtendLineAbove),
|
||||
|
||||
("d".try_into().unwrap(), Action::Delete),
|
||||
].into()),
|
||||
(Some(PartialAction::Goto), [
|
||||
("j".try_into().unwrap(), Action::GotoLineStart),
|
||||
@@ -171,6 +173,8 @@ impl Default for Config {
|
||||
|
||||
("x".try_into().unwrap(), Action::ExtendLineBelow),
|
||||
("X".try_into().unwrap(), Action::ExtendLineAbove),
|
||||
|
||||
("d".try_into().unwrap(), Action::Delete),
|
||||
].into())
|
||||
].into())
|
||||
].into()
|
||||
|
||||
+11
-1
@@ -1,4 +1,6 @@
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
#[derive(Clone, Copy, Default, PartialEq, Eq)]
|
||||
pub struct Cursor {
|
||||
pub head: usize,
|
||||
pub tail: usize
|
||||
@@ -39,6 +41,14 @@ impl Cursor {
|
||||
self.tail = self.tail.clamp(scroll_position, max_row);
|
||||
}
|
||||
|
||||
pub const fn range(&self) -> RangeInclusive<usize> {
|
||||
if self.head < self.tail {
|
||||
self.head..=self.tail
|
||||
} else {
|
||||
self.tail..=self.head
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_to_next_word(&mut self, max: usize) {
|
||||
if self.head == max { return }
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
use std::cmp::min;
|
||||
use crate::{app::App, cursor::Cursor};
|
||||
|
||||
pub enum EditAction {
|
||||
Delete {
|
||||
cursor: Cursor,
|
||||
data: Vec<u8>
|
||||
}
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn execute_and_add(&mut self, edit_action: EditAction) {
|
||||
self.execute_edit(&edit_action);
|
||||
self.edit_history.push(edit_action);
|
||||
}
|
||||
|
||||
fn execute_edit(&mut self, edit_action: &EditAction) {
|
||||
match edit_action {
|
||||
EditAction::Delete { cursor, .. } => self.delete_at(*cursor),
|
||||
}
|
||||
}
|
||||
|
||||
fn delete_at(&mut self, cursor: Cursor) {
|
||||
self.contents.drain(cursor.range());
|
||||
|
||||
self.cursor.head = min(cursor.head, cursor.tail);
|
||||
self.cursor.collapse();
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ mod app;
|
||||
mod config;
|
||||
mod cursor;
|
||||
mod action;
|
||||
mod edit_action;
|
||||
|
||||
const BYTES_PER_LINE: usize = 0x10;
|
||||
const BYTES_PER_CHUNK: usize = 4;
|
||||
|
||||
Reference in New Issue
Block a user