deleting
This commit is contained in:
+14
-1
@@ -1,6 +1,6 @@
|
|||||||
use std::{cmp::min, mem::swap};
|
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)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum Action {
|
pub enum Action {
|
||||||
@@ -40,6 +40,8 @@ pub enum Action {
|
|||||||
|
|
||||||
ExtendLineBelow,
|
ExtendLineBelow,
|
||||||
ExtendLineAbove,
|
ExtendLineAbove,
|
||||||
|
|
||||||
|
Delete,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
@@ -81,6 +83,8 @@ impl App {
|
|||||||
|
|
||||||
Action::ExtendLineBelow => self.extend_line_below(),
|
Action::ExtendLineBelow => self.extend_line_below(),
|
||||||
Action::ExtendLineAbove => self.extend_line_above(),
|
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);
|
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
|
// helpers
|
||||||
|
|||||||
+18
-2
@@ -1,21 +1,29 @@
|
|||||||
use std::{env, fs::File, io::Read, path::PathBuf, process::exit};
|
use std::{env, fs::File, io::Read, path::PathBuf, process::exit};
|
||||||
use crossterm::{event::{self, Event, KeyEvent}, terminal::window_size};
|
use crossterm::{event::{self, Event, KeyEvent}, terminal::window_size};
|
||||||
use ratatui::style::Color;
|
use ratatui::style::Color;
|
||||||
|
use crate::{config::Config, cursor::Cursor, edit_action::EditAction};
|
||||||
use crate::{config::Config, cursor::Cursor};
|
|
||||||
|
|
||||||
mod widget;
|
mod widget;
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
pub config: Config,
|
pub config: Config,
|
||||||
pub file_name: String,
|
pub file_name: String,
|
||||||
|
|
||||||
pub contents: Vec<u8>,
|
pub contents: Vec<u8>,
|
||||||
|
|
||||||
pub window_rows: usize,
|
pub window_rows: usize,
|
||||||
|
|
||||||
pub scroll_position: usize,
|
pub scroll_position: usize,
|
||||||
pub cursor: Cursor,
|
pub cursor: Cursor,
|
||||||
|
|
||||||
pub should_quit: bool,
|
pub should_quit: bool,
|
||||||
|
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
pub partial_action: Option<PartialAction>,
|
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>,
|
pub logs: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,14 +85,22 @@ impl App {
|
|||||||
Self {
|
Self {
|
||||||
config: Config::default(),
|
config: Config::default(),
|
||||||
file_name: file_path.file_name().unwrap().to_str().unwrap().to_owned(),
|
file_name: file_path.file_name().unwrap().to_str().unwrap().to_owned(),
|
||||||
|
|
||||||
contents,
|
contents,
|
||||||
|
|
||||||
// -1 because of the status line
|
// -1 because of the status line
|
||||||
window_rows: window_size().unwrap().rows as usize - 1,
|
window_rows: window_size().unwrap().rows as usize - 1,
|
||||||
|
|
||||||
scroll_position: 0,
|
scroll_position: 0,
|
||||||
cursor: Cursor::default(),
|
cursor: Cursor::default(),
|
||||||
|
|
||||||
should_quit: false,
|
should_quit: false,
|
||||||
|
|
||||||
mode: Mode::Normal,
|
mode: Mode::Normal,
|
||||||
partial_action: None,
|
partial_action: None,
|
||||||
|
|
||||||
|
edit_history: Vec::new(),
|
||||||
|
|
||||||
logs: Vec::new(),
|
logs: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -361,7 +361,8 @@ mod status_line {
|
|||||||
Line::from_iter([
|
Line::from_iter([
|
||||||
self.render_mode(),
|
self.render_mode(),
|
||||||
" ".into(),
|
" ".into(),
|
||||||
self.render_file_name()
|
self.render_file_name(),
|
||||||
|
self.modified_indicator()
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
.bg(Color::ui_grey())
|
.bg(Color::ui_grey())
|
||||||
@@ -376,6 +377,14 @@ mod status_line {
|
|||||||
fn render_file_name(&self) -> Span<'_> {
|
fn render_file_name(&self) -> Span<'_> {
|
||||||
Span::from(&self.file_name)
|
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::ExtendLineBelow),
|
||||||
("X".try_into().unwrap(), Action::ExtendLineAbove),
|
("X".try_into().unwrap(), Action::ExtendLineAbove),
|
||||||
|
|
||||||
|
("d".try_into().unwrap(), Action::Delete),
|
||||||
].into()),
|
].into()),
|
||||||
(Some(PartialAction::Goto), [
|
(Some(PartialAction::Goto), [
|
||||||
("j".try_into().unwrap(), Action::GotoLineStart),
|
("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::ExtendLineBelow),
|
||||||
("X".try_into().unwrap(), Action::ExtendLineAbove),
|
("X".try_into().unwrap(), Action::ExtendLineAbove),
|
||||||
|
|
||||||
|
("d".try_into().unwrap(), Action::Delete),
|
||||||
].into())
|
].into())
|
||||||
].into())
|
].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 struct Cursor {
|
||||||
pub head: usize,
|
pub head: usize,
|
||||||
pub tail: usize
|
pub tail: usize
|
||||||
@@ -39,6 +41,14 @@ impl Cursor {
|
|||||||
self.tail = self.tail.clamp(scroll_position, max_row);
|
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) {
|
pub fn move_to_next_word(&mut self, max: usize) {
|
||||||
if self.head == max { return }
|
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 config;
|
||||||
mod cursor;
|
mod cursor;
|
||||||
mod action;
|
mod action;
|
||||||
|
mod edit_action;
|
||||||
|
|
||||||
const BYTES_PER_LINE: usize = 0x10;
|
const BYTES_PER_LINE: usize = 0x10;
|
||||||
const BYTES_PER_CHUNK: usize = 4;
|
const BYTES_PER_CHUNK: usize = 4;
|
||||||
|
|||||||
Reference in New Issue
Block a user