make config (de)serializable
This commit is contained in:
+286
-4
@@ -1,16 +1,41 @@
|
||||
use std::{cmp::min, collections::hash_set::Entry, convert::identity, fs::File, io::Write, iter, mem::{replace, swap}};
|
||||
use ratatui::{style::{Color, Stylize}, text::Span};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::{BYTES_OF_PADDING, BYTES_PER_LINE, LINES_OF_PADDING, app::WindowSize, buffer::{Buffer, Mode, PartialAction, Popup}, cursor::Cursor, edit_action::EditAction};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Serialize, Deserialize)]
|
||||
#[derive(Debug)]
|
||||
#[serde(into = "&str")]
|
||||
#[serde(try_from = "&str")]
|
||||
pub enum Action {
|
||||
App(AppAction),
|
||||
Buffer(BufferAction),
|
||||
Cursor(CursorAction),
|
||||
}
|
||||
|
||||
impl From<Action> for &str {
|
||||
fn from(action: Action) -> Self {
|
||||
match action {
|
||||
Action::App(app_action) => app_action.into(),
|
||||
Action::Buffer(buffer_action) => buffer_action.into(),
|
||||
Action::Cursor(cursor_action) => cursor_action.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for Action {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(string: &str) -> Result<Self, String> {
|
||||
AppAction::try_from(string).map(Action::from)
|
||||
.or_else(|_| BufferAction::try_from(string).map(Action::from))
|
||||
.or_else(|_| CursorAction::try_from(string).map(Action::from))
|
||||
.map_err(|_| format!("invalid action: {}", string))
|
||||
}
|
||||
}
|
||||
|
||||
// actions that act on the app as a whole, not just one buffer
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, Deserialize)]
|
||||
pub enum AppAction {
|
||||
QuitIfSaved,
|
||||
Quit,
|
||||
@@ -21,13 +46,50 @@ pub enum AppAction {
|
||||
Yank,
|
||||
}
|
||||
|
||||
impl From<AppAction> for &str {
|
||||
fn from(app_action: AppAction) -> Self {
|
||||
use AppAction::*;
|
||||
|
||||
match app_action {
|
||||
QuitIfSaved => "quit_if_saved",
|
||||
Quit => "quit",
|
||||
|
||||
PreviousBuffer => "previous_buffer",
|
||||
NextBuffer => "next_buffer",
|
||||
|
||||
Yank => "yank",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AppAction> for Action {
|
||||
fn from(app_action: AppAction) -> Self {
|
||||
Self::App(app_action)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
impl TryFrom<&str> for AppAction {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(string: &str) -> Result<Self, ()> {
|
||||
use AppAction::*;
|
||||
|
||||
match string {
|
||||
"quit_if_saved" => Ok(QuitIfSaved),
|
||||
"quit" => Ok(Quit),
|
||||
|
||||
"previous_buffer" => Ok(PreviousBuffer),
|
||||
"next_buffer" => Ok(NextBuffer),
|
||||
|
||||
"yank" => Ok(Yank),
|
||||
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Deserialize)]
|
||||
#[derive(Debug)]
|
||||
pub enum BufferAction {
|
||||
NormalMode,
|
||||
SelectMode,
|
||||
@@ -93,13 +155,161 @@ pub enum BufferAction {
|
||||
InspectSelectionColor,
|
||||
}
|
||||
|
||||
impl From<BufferAction> for &str {
|
||||
fn from(buffer_action: BufferAction) -> Self {
|
||||
use BufferAction::*;
|
||||
|
||||
match buffer_action {
|
||||
NormalMode => "normal_mode",
|
||||
SelectMode => "select_mode",
|
||||
|
||||
Goto => "goto",
|
||||
View => "view",
|
||||
Replace => "replace",
|
||||
Space => "space",
|
||||
Repeat => "repeat",
|
||||
To => "to",
|
||||
|
||||
ScrollDown => "scroll_down",
|
||||
ScrollUp => "scroll_up",
|
||||
|
||||
PageCursorHalfDown => "page_cursor_half_down",
|
||||
PageCursorHalfUp => "page_cursor_half_up",
|
||||
|
||||
PageDown => "page_down",
|
||||
PageUp => "page_up",
|
||||
|
||||
CollapseSelection => "collapse_selection",
|
||||
FlipSelections => "flip_selections",
|
||||
|
||||
Delete => "delete",
|
||||
|
||||
Undo => "undo",
|
||||
Redo => "redo",
|
||||
|
||||
Save => "save",
|
||||
|
||||
CopySelectionOnNextLine => "copy_selection_on_next_line",
|
||||
|
||||
RotateSelectionsBackward => "rotate_selections_backward",
|
||||
RotateSelectionsForward => "rotate_selections_forward",
|
||||
|
||||
KeepPrimarySelection => "keep_primary_selection",
|
||||
RemovePrimarySelection => "remove_primary_selection",
|
||||
|
||||
SplitSelectionsInto1s => "split_selections_into_1_s",
|
||||
SplitSelectionsInto2s => "split_selections_into_2_s",
|
||||
SplitSelectionsInto3s => "split_selections_into_3_s",
|
||||
SplitSelectionsInto4s => "split_selections_into_4_s",
|
||||
SplitSelectionsInto5s => "split_selections_into_5_s",
|
||||
SplitSelectionsInto6s => "split_selections_into_6_s",
|
||||
SplitSelectionsInto7s => "split_selections_into_7_s",
|
||||
SplitSelectionsInto8s => "split_selections_into_8_s",
|
||||
SplitSelectionsInto9s => "split_selections_into_9_s",
|
||||
|
||||
JumpToSelectedOffset => "jump_to_selected_offset",
|
||||
JumpToSelectedOffsetRelativeToMark => "jump_to_selected_offset_relative_to_mark",
|
||||
|
||||
ToggleMark => "toggle_mark",
|
||||
|
||||
AlignViewCenter => "align_view_center",
|
||||
AlignViewBottom => "align_view_bottom",
|
||||
AlignViewTop => "align_view_top",
|
||||
|
||||
ExtendToMark => "extend_to_mark",
|
||||
ExtendToNull => "extend_to_null",
|
||||
ExtendToFF => "extend_to_ff",
|
||||
|
||||
InspectSelection => "inspect_selection",
|
||||
InspectSelectionColor => "inspect_selection_color",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BufferAction> for Action {
|
||||
fn from(buffer_action: BufferAction) -> Self {
|
||||
Self::Buffer(buffer_action)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
impl TryFrom<&str> for BufferAction {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(string: &str) -> Result<Self, ()> {
|
||||
use BufferAction::*;
|
||||
|
||||
match string {
|
||||
"normal_mode" => Ok(NormalMode),
|
||||
"select_mode" => Ok(SelectMode),
|
||||
|
||||
"goto" => Ok(Goto),
|
||||
"view" => Ok(View),
|
||||
"replace" => Ok(Replace),
|
||||
"space" => Ok(Space),
|
||||
"repeat" => Ok(Repeat),
|
||||
"to" => Ok(To),
|
||||
|
||||
"scroll_down" => Ok(ScrollDown),
|
||||
"scroll_up" => Ok(ScrollUp),
|
||||
|
||||
"page_cursor_half_down" => Ok(PageCursorHalfDown),
|
||||
"page_cursor_half_up" => Ok(PageCursorHalfUp),
|
||||
|
||||
"page_down" => Ok(PageDown),
|
||||
"page_up" => Ok(PageUp),
|
||||
|
||||
"collapse_selection" => Ok(CollapseSelection),
|
||||
"flip_selections" => Ok(FlipSelections),
|
||||
|
||||
"delete" => Ok(Delete),
|
||||
|
||||
"undo" => Ok(Undo),
|
||||
"redo" => Ok(Redo),
|
||||
|
||||
"save" => Ok(Save),
|
||||
|
||||
"copy_selection_on_next_line" => Ok(CopySelectionOnNextLine),
|
||||
|
||||
"rotate_selections_backward" => Ok(RotateSelectionsBackward),
|
||||
"rotate_selections_forward" => Ok(RotateSelectionsForward),
|
||||
|
||||
"keep_primary_selection" => Ok(KeepPrimarySelection),
|
||||
"remove_primary_selection" => Ok(RemovePrimarySelection),
|
||||
|
||||
"split_selections_into_1_s" => Ok(SplitSelectionsInto1s),
|
||||
"split_selections_into_2_s" => Ok(SplitSelectionsInto2s),
|
||||
"split_selections_into_3_s" => Ok(SplitSelectionsInto3s),
|
||||
"split_selections_into_4_s" => Ok(SplitSelectionsInto4s),
|
||||
"split_selections_into_5_s" => Ok(SplitSelectionsInto5s),
|
||||
"split_selections_into_6_s" => Ok(SplitSelectionsInto6s),
|
||||
"split_selections_into_7_s" => Ok(SplitSelectionsInto7s),
|
||||
"split_selections_into_8_s" => Ok(SplitSelectionsInto8s),
|
||||
"split_selections_into_9_s" => Ok(SplitSelectionsInto9s),
|
||||
|
||||
"jump_to_selected_offset" => Ok(JumpToSelectedOffset),
|
||||
"jump_to_selected_offset_relative_to_mark" => Ok(JumpToSelectedOffsetRelativeToMark),
|
||||
|
||||
"toggle_mark" => Ok(ToggleMark),
|
||||
|
||||
"align_view_center" => Ok(AlignViewCenter),
|
||||
"align_view_bottom" => Ok(AlignViewBottom),
|
||||
"align_view_top" => Ok(AlignViewTop),
|
||||
|
||||
"extend_to_mark" => Ok(ExtendToMark),
|
||||
"extend_to_null" => Ok(ExtendToNull),
|
||||
"extend_to_ff" => Ok(ExtendToFF),
|
||||
|
||||
"inspect_selection" => Ok(InspectSelection),
|
||||
"inspect_selection_color" => Ok(InspectSelectionColor),
|
||||
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Serialize, Deserialize)]
|
||||
#[derive(Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CursorAction {
|
||||
MoveByteUp,
|
||||
MoveByteDown,
|
||||
@@ -128,12 +338,84 @@ pub enum CursorAction {
|
||||
ExtendLineAbove,
|
||||
}
|
||||
|
||||
impl From<CursorAction> for &str {
|
||||
fn from(cursor_action: CursorAction) -> Self {
|
||||
use CursorAction::*;
|
||||
|
||||
match cursor_action {
|
||||
MoveByteUp => "move_byte_up",
|
||||
MoveByteDown => "move_byte_down",
|
||||
MoveByteLeft => "move_byte_left",
|
||||
MoveByteRight => "move_byte_right",
|
||||
|
||||
ExtendByteUp => "extend_byte_up",
|
||||
ExtendByteDown => "extend_byte_down",
|
||||
ExtendByteLeft => "extend_byte_left",
|
||||
ExtendByteRight => "extend_byte_right",
|
||||
|
||||
GotoLineStart => "goto_line_start",
|
||||
GotoLineEnd => "goto_line_end",
|
||||
GotoFileStart => "goto_file_start",
|
||||
GotoFileEnd => "goto_file_end",
|
||||
|
||||
MoveNextWordStart => "move_next_word_start",
|
||||
MoveNextWordEnd => "move_next_word_end",
|
||||
MovePreviousWordStart => "move_previous_word_start",
|
||||
|
||||
ExtendNextWordStart => "extend_next_word_start",
|
||||
ExtendNextWordEnd => "extend_next_word_end",
|
||||
ExtendPreviousWordStart => "extend_previous_word_start",
|
||||
|
||||
ExtendLineBelow => "extend_line_below",
|
||||
ExtendLineAbove => "extend_line_above",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CursorAction> for Action {
|
||||
fn from(cursor_action: CursorAction) -> Self {
|
||||
Self::Cursor(cursor_action)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for CursorAction {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(string: &str) -> Result<Self, ()> {
|
||||
use CursorAction::*;
|
||||
|
||||
match string {
|
||||
"move_byte_up" => Ok(MoveByteUp),
|
||||
"move_byte_down" => Ok(MoveByteDown),
|
||||
"move_byte_left" => Ok(MoveByteLeft),
|
||||
"move_byte_right" => Ok(MoveByteRight),
|
||||
|
||||
"extend_byte_up" => Ok(ExtendByteUp),
|
||||
"extend_byte_down" => Ok(ExtendByteDown),
|
||||
"extend_byte_left" => Ok(ExtendByteLeft),
|
||||
"extend_byte_right" => Ok(ExtendByteRight),
|
||||
|
||||
"goto_line_start" => Ok(GotoLineStart),
|
||||
"goto_line_end" => Ok(GotoLineEnd),
|
||||
"goto_file_start" => Ok(GotoFileStart),
|
||||
"goto_file_end" => Ok(GotoFileEnd),
|
||||
|
||||
"move_next_word_start" => Ok(MoveNextWordStart),
|
||||
"move_next_word_end" => Ok(MoveNextWordEnd),
|
||||
"move_previous_word_start" => Ok(MovePreviousWordStart),
|
||||
|
||||
"extend_next_word_start" => Ok(ExtendNextWordStart),
|
||||
"extend_next_word_end" => Ok(ExtendNextWordEnd),
|
||||
"extend_previous_word_start" => Ok(ExtendPreviousWordStart),
|
||||
|
||||
"extend_line_below" => Ok(ExtendLineBelow),
|
||||
"extend_line_above" => Ok(ExtendLineAbove),
|
||||
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
pub fn execute(&mut self, action: BufferAction, window_size: WindowSize) {
|
||||
match action {
|
||||
|
||||
Reference in New Issue
Block a user