use ratatui::{
crossterm::{
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
ExecutableCommand,
},
DefaultTerminal,
};
use serde::{Deserialize, Deserializer};
use std::{io::stdout, process};
use tracing::error;
use crate::{
app::{Message, ScrollAmount},
debug_log, explorer, help_modal, input, note_editor,
note_editor::state::Operator,
note_editor::Direction,
outline, splash_modal, theme_selector_modal, vault_selector_modal,
};
trait ReplaceVar {
fn replace_var(&self, variable: &str, content: &str) -> Self;
}
impl ReplaceVar for String {
fn replace_var(&self, variable: &str, content: &str) -> Self {
self.replace(variable, content)
}
}
#[derive(Clone, Debug, PartialEq)]
pub(crate) enum Command {
Quit,
SplashUp,
SplashDown,
SplashOpen,
ExplorerUp,
ExplorerDown,
ExplorerOpen,
ExplorerSort,
ExplorerToggle,
ExplorerNewUntitledNote,
ExplorerNewUntitledFolder,
ExplorerToggleInputRename,
ExplorerToggleOutline,
ExplorerSwitchPaneNext,
ExplorerSwitchPanePrevious,
ExplorerHidePane,
ExplorerExpandPane,
ExplorerScrollUpOne,
ExplorerScrollDownOne,
ExplorerScrollUpHalfPage,
ExplorerScrollDownHalfPage,
OutlineUp,
OutlineDown,
OutlineSelect,
OutlineExpand,
OutlineToggle,
OutlineToggleExplorer,
OutlineSwitchPaneNext,
OutlineSwitchPanePrevious,
HelpModalScrollUpOne,
HelpModalScrollDownOne,
HelpModalScrollUpHalfPage,
HelpModalScrollDownHalfPage,
HelpModalToggle,
HelpModalClose,
NoteEditorScrollUpOne,
NoteEditorScrollDownOne,
NoteEditorScrollUpHalfPage,
NoteEditorScrollDownHalfPage,
NoteEditorSwitchPaneNext,
NoteEditorSwitchPanePrevious,
NoteEditorToggleExplorer,
NoteEditorToggleOutline,
NoteEditorCursorUp,
NoteEditorCursorDown,
NoteEditorScrollToTop,
NoteEditorScrollToBottom,
ExplorerScrollToTop,
ExplorerScrollToBottom,
TabNext,
TabPrevious,
TabClose,
NoteEditorExperimentalCursorWordForward,
NoteEditorExperimentalCursorWordBackward,
NoteEditorExperimentalToggleView,
NoteEditorExperimentalSetEditView,
NoteEditorExperimentalSetReadView,
NoteEditorExperimentalSave,
NoteEditorExperimentalExit,
NoteEditorExperimentalCursorLeft,
NoteEditorExperimentalCursorRight,
NoteEditorInsertMode,
NoteEditorAppend,
NoteEditorReplaceChar,
NoteEditorVisualMode,
NoteEditorVisualLineMode,
NoteEditorCursorLineStart,
NoteEditorCursorLineEnd,
NoteEditorCursorFirstNonblank,
NoteEditorCursorWordEnd,
NoteEditorCursorWordForwardBig,
NoteEditorCursorWordBackwardBig,
NoteEditorCursorWordEndBig,
NoteEditorParagraphForward,
NoteEditorParagraphBackward,
NoteEditorMatchingPair,
NoteEditorCursorDocStart,
NoteEditorCursorDocEnd,
NoteEditorFindForward,
NoteEditorFindBackward,
NoteEditorTillForward,
NoteEditorTillBackward,
NoteEditorRepeatFind,
NoteEditorRepeatFindReverse,
NoteEditorDelete,
NoteEditorChange,
NoteEditorYankOperator,
NoteEditorDeleteUnderCursor,
NoteEditorDeleteToLineEnd,
NoteEditorChangeToLineEnd,
NoteEditorSubstituteChar,
NoteEditorPasteAfter,
NoteEditorPasteBefore,
NoteEditorUndo,
NoteEditorRedo,
VaultSelectorModalUp,
VaultSelectorModalDown,
VaultSelectorModalClose,
VaultSelectorModalOpen,
VaultSelectorModalToggle,
DebugLogToggle,
DebugLogClose,
DebugLogClear,
DebugLogCycleLevel,
DebugLogScrollUpOne,
DebugLogScrollDownOne,
DebugLogScrollUpHalfPage,
DebugLogScrollDownHalfPage,
ThemeSelectorModalUp,
ThemeSelectorModalDown,
ThemeSelectorModalClose,
ThemeSelectorModalOpen,
ThemeSelectorModalToggle,
InputModalWordForward,
InputModalWordBackward,
InputModalLeft,
InputModalRight,
InputModalCancel,
InputModalAccept,
InputModalEditMode,
Exec(String),
Spawn(String),
}
fn str_to_command(s: &str) -> Option<Command> {
match s {
"quit" => Some(Command::Quit),
"splash_up" => Some(Command::SplashUp),
"splash_down" => Some(Command::SplashDown),
"splash_open" => Some(Command::SplashOpen),
"explorer_up" => Some(Command::ExplorerUp),
"explorer_down" => Some(Command::ExplorerDown),
"explorer_open" => Some(Command::ExplorerOpen),
"explorer_sort" => Some(Command::ExplorerSort),
"explorer_toggle" => Some(Command::ExplorerToggle),
"explorer_new_untitled_note" => Some(Command::ExplorerNewUntitledNote),
"explorer_new_untitled_folder" => Some(Command::ExplorerNewUntitledFolder),
"explorer_toggle_outline" => Some(Command::ExplorerToggleOutline),
"explorer_toggle_input_rename" => Some(Command::ExplorerToggleInputRename),
"explorer_switch_pane_next" => Some(Command::ExplorerSwitchPaneNext),
"explorer_hide_pane" => Some(Command::ExplorerHidePane),
"explorer_expand_pane" => Some(Command::ExplorerExpandPane),
"explorer_switch_pane_previous" => Some(Command::ExplorerSwitchPanePrevious),
"explorer_scroll_up_one" => Some(Command::ExplorerScrollUpOne),
"explorer_scroll_down_one" => Some(Command::ExplorerScrollDownOne),
"explorer_scroll_up_half_page" => Some(Command::ExplorerScrollUpHalfPage),
"explorer_scroll_down_half_page" => Some(Command::ExplorerScrollDownHalfPage),
"input_modal_word_forward" => Some(Command::InputModalWordForward),
"input_modal_word_backward" => Some(Command::InputModalWordBackward),
"input_modal_left" => Some(Command::InputModalLeft),
"input_modal_right" => Some(Command::InputModalRight),
"input_modal_cancel" => Some(Command::InputModalCancel),
"input_modal_accept" => Some(Command::InputModalAccept),
"input_modal_edit_mode" => Some(Command::InputModalEditMode),
"outline_up" => Some(Command::OutlineUp),
"outline_down" => Some(Command::OutlineDown),
"outline_select" => Some(Command::OutlineSelect),
"outline_expand" => Some(Command::OutlineExpand),
"outline_toggle" => Some(Command::OutlineToggle),
"outline_toggle_explorer" => Some(Command::OutlineToggleExplorer),
"outline_switch_pane_next" => Some(Command::OutlineSwitchPaneNext),
"outline_switch_pane_previous" => Some(Command::OutlineSwitchPanePrevious),
"help_modal_scroll_up_one" => Some(Command::HelpModalScrollUpOne),
"help_modal_scroll_down_one" => Some(Command::HelpModalScrollDownOne),
"help_modal_scroll_up_half_page" => Some(Command::HelpModalScrollUpHalfPage),
"help_modal_scroll_down_half_page" => Some(Command::HelpModalScrollDownHalfPage),
"help_modal_toggle" => Some(Command::HelpModalToggle),
"help_modal_close" => Some(Command::HelpModalClose),
"note_editor_scroll_up_one" => Some(Command::NoteEditorScrollUpOne),
"note_editor_scroll_down_one" => Some(Command::NoteEditorScrollDownOne),
"note_editor_scroll_up_half_page" => Some(Command::NoteEditorScrollUpHalfPage),
"note_editor_scroll_down_half_page" => Some(Command::NoteEditorScrollDownHalfPage),
"note_editor_switch_pane_next" => Some(Command::NoteEditorSwitchPaneNext),
"note_editor_switch_pane_previous" => Some(Command::NoteEditorSwitchPanePrevious),
"note_editor_toggle_explorer" => Some(Command::NoteEditorToggleExplorer),
"note_editor_toggle_outline" => Some(Command::NoteEditorToggleOutline),
"note_editor_cursor_up" => Some(Command::NoteEditorCursorUp),
"note_editor_cursor_down" => Some(Command::NoteEditorCursorDown),
"note_editor_scroll_to_top" => Some(Command::NoteEditorScrollToTop),
"note_editor_scroll_to_bottom" => Some(Command::NoteEditorScrollToBottom),
"explorer_scroll_to_top" => Some(Command::ExplorerScrollToTop),
"explorer_scroll_to_bottom" => Some(Command::ExplorerScrollToBottom),
"tab_next" => Some(Command::TabNext),
"tab_previous" => Some(Command::TabPrevious),
"tab_close" => Some(Command::TabClose),
"note_editor_experimental_cursor_word_forward" => {
Some(Command::NoteEditorExperimentalCursorWordForward)
}
"note_editor_experimental_cursor_word_backward" => {
Some(Command::NoteEditorExperimentalCursorWordBackward)
}
"note_editor_experimental_set_edit_view" => {
Some(Command::NoteEditorExperimentalSetEditView)
}
"note_editor_experimental_toggle_view" => Some(Command::NoteEditorExperimentalToggleView),
"note_editor_experimental_set_read_view" => {
Some(Command::NoteEditorExperimentalSetReadView)
}
"note_editor_experimental_save" => Some(Command::NoteEditorExperimentalSave),
"note_editor_experimental_exit" => Some(Command::NoteEditorExperimentalExit),
"note_editor_experimental_cursor_left" => Some(Command::NoteEditorExperimentalCursorLeft),
"note_editor_experimental_cursor_right" => Some(Command::NoteEditorExperimentalCursorRight),
"note_editor_insert_mode" => Some(Command::NoteEditorInsertMode),
"note_editor_append" => Some(Command::NoteEditorAppend),
"note_editor_replace_char" => Some(Command::NoteEditorReplaceChar),
"note_editor_visual_mode" => Some(Command::NoteEditorVisualMode),
"note_editor_visual_line_mode" => Some(Command::NoteEditorVisualLineMode),
"note_editor_delete" => Some(Command::NoteEditorDelete),
"note_editor_change" => Some(Command::NoteEditorChange),
"note_editor_yank" => Some(Command::NoteEditorYankOperator),
"note_editor_delete_under_cursor" => Some(Command::NoteEditorDeleteUnderCursor),
"note_editor_delete_to_line_end" => Some(Command::NoteEditorDeleteToLineEnd),
"note_editor_change_to_line_end" => Some(Command::NoteEditorChangeToLineEnd),
"note_editor_substitute_char" => Some(Command::NoteEditorSubstituteChar),
"note_editor_paste_after" => Some(Command::NoteEditorPasteAfter),
"note_editor_paste_before" => Some(Command::NoteEditorPasteBefore),
"note_editor_undo" => Some(Command::NoteEditorUndo),
"note_editor_redo" => Some(Command::NoteEditorRedo),
"note_editor_cursor_line_start" => Some(Command::NoteEditorCursorLineStart),
"note_editor_cursor_line_end" => Some(Command::NoteEditorCursorLineEnd),
"note_editor_cursor_first_non_blank" => Some(Command::NoteEditorCursorFirstNonblank),
"note_editor_cursor_word_end" => Some(Command::NoteEditorCursorWordEnd),
"note_editor_cursor_word_forward_big" => Some(Command::NoteEditorCursorWordForwardBig),
"note_editor_cursor_word_backward_big" => Some(Command::NoteEditorCursorWordBackwardBig),
"note_editor_cursor_word_end_big" => Some(Command::NoteEditorCursorWordEndBig),
"note_editor_paragraph_forward" => Some(Command::NoteEditorParagraphForward),
"note_editor_paragraph_backward" => Some(Command::NoteEditorParagraphBackward),
"note_editor_matching_pair" => Some(Command::NoteEditorMatchingPair),
"note_editor_cursor_doc_start" => Some(Command::NoteEditorCursorDocStart),
"note_editor_cursor_doc_end" => Some(Command::NoteEditorCursorDocEnd),
"note_editor_find_forward" => Some(Command::NoteEditorFindForward),
"note_editor_find_backward" => Some(Command::NoteEditorFindBackward),
"note_editor_till_forward" => Some(Command::NoteEditorTillForward),
"note_editor_till_backward" => Some(Command::NoteEditorTillBackward),
"note_editor_repeat_find" => Some(Command::NoteEditorRepeatFind),
"note_editor_repeat_find_reverse" => Some(Command::NoteEditorRepeatFindReverse),
"vault_selector_modal_up" => Some(Command::VaultSelectorModalUp),
"vault_selector_modal_down" => Some(Command::VaultSelectorModalDown),
"vault_selector_modal_close" => Some(Command::VaultSelectorModalClose),
"vault_selector_modal_open" => Some(Command::VaultSelectorModalOpen),
"vault_selector_modal_toggle" => Some(Command::VaultSelectorModalToggle),
"debug_log_toggle" => Some(Command::DebugLogToggle),
"debug_log_close" => Some(Command::DebugLogClose),
"debug_log_clear" => Some(Command::DebugLogClear),
"debug_log_cycle_level" => Some(Command::DebugLogCycleLevel),
"debug_log_scroll_up_one" => Some(Command::DebugLogScrollUpOne),
"debug_log_scroll_down_one" => Some(Command::DebugLogScrollDownOne),
"debug_log_scroll_up_half_page" => Some(Command::DebugLogScrollUpHalfPage),
"debug_log_scroll_down_half_page" => Some(Command::DebugLogScrollDownHalfPage),
"theme_selector_modal_up" => Some(Command::ThemeSelectorModalUp),
"theme_selector_modal_down" => Some(Command::ThemeSelectorModalDown),
"theme_selector_modal_close" => Some(Command::ThemeSelectorModalClose),
"theme_selector_modal_open" => Some(Command::ThemeSelectorModalOpen),
"theme_selector_modal_toggle" => Some(Command::ThemeSelectorModalToggle),
"note_editor_experimental_set_edit_mode" => {
Some(Command::NoteEditorExperimentalSetEditView)
}
"note_editor_experimental_set_read_mode" => {
Some(Command::NoteEditorExperimentalSetReadView)
}
"note_editor_experimental_exit_mode" => Some(Command::NoteEditorExperimentalExit),
_ => None,
}
}
impl<'de> Deserialize<'de> for Command {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
if let Some(command) = s
.strip_prefix("exec:")
.map(|command| Command::Exec(command.to_string()))
.or(s
.strip_prefix("spawn:")
.map(|command| Command::Spawn(command.to_string())))
{
return Ok(command);
}
str_to_command(&s).ok_or(serde::de::Error::custom(format!(
"{s} is not a valid command"
)))
}
}
impl From<Command> for Message<'_> {
fn from(value: Command) -> Self {
match value {
Command::Quit => Message::Quit,
Command::SplashUp => Message::Splash(splash_modal::Message::Up),
Command::SplashDown => Message::Splash(splash_modal::Message::Down),
Command::SplashOpen => Message::Splash(splash_modal::Message::Open),
Command::ExplorerUp => Message::Explorer(explorer::Message::Up),
Command::ExplorerDown => Message::Explorer(explorer::Message::Down),
Command::ExplorerOpen => Message::Explorer(explorer::Message::Select),
Command::ExplorerSort => Message::Explorer(explorer::Message::Sort),
Command::ExplorerToggle => Message::Explorer(explorer::Message::Toggle),
Command::ExplorerToggleOutline => Message::Explorer(explorer::Message::ToggleOutline),
Command::ExplorerToggleInputRename => {
Message::Explorer(explorer::Message::ToggleInputRename)
}
Command::ExplorerHidePane => Message::Explorer(explorer::Message::HidePane),
Command::ExplorerExpandPane => Message::Explorer(explorer::Message::ExpandPane),
Command::ExplorerSwitchPaneNext => Message::Explorer(explorer::Message::SwitchPaneNext),
Command::ExplorerSwitchPanePrevious => {
Message::Explorer(explorer::Message::SwitchPanePrevious)
}
Command::ExplorerScrollUpOne => {
Message::Explorer(explorer::Message::ScrollUp(ScrollAmount::One))
}
Command::ExplorerScrollDownOne => {
Message::Explorer(explorer::Message::ScrollDown(ScrollAmount::One))
}
Command::ExplorerScrollUpHalfPage => {
Message::Explorer(explorer::Message::ScrollUp(ScrollAmount::HalfPage))
}
Command::ExplorerScrollDownHalfPage => {
Message::Explorer(explorer::Message::ScrollDown(ScrollAmount::HalfPage))
}
Command::ExplorerNewUntitledNote => Message::CreateUntitledNote,
Command::ExplorerNewUntitledFolder => Message::CreateUntitledFolder,
Command::InputModalEditMode => Message::Input(input::Message::EditMode),
Command::InputModalAccept => Message::Input(input::Message::Accept),
Command::InputModalCancel => Message::Input(input::Message::Cancel),
Command::InputModalLeft => Message::Input(input::Message::CursorLeft),
Command::InputModalRight => Message::Input(input::Message::CursorRight),
Command::InputModalWordForward => Message::Input(input::Message::CursorWordForward),
Command::InputModalWordBackward => Message::Input(input::Message::CursorWordBackward),
Command::OutlineUp => Message::Outline(outline::Message::Up),
Command::OutlineDown => Message::Outline(outline::Message::Down),
Command::OutlineSelect => Message::Outline(outline::Message::Select),
Command::OutlineExpand => Message::Outline(outline::Message::Expand),
Command::OutlineToggle => Message::Outline(outline::Message::Toggle),
Command::OutlineToggleExplorer => Message::Outline(outline::Message::ToggleExplorer),
Command::OutlineSwitchPaneNext => Message::Outline(outline::Message::SwitchPaneNext),
Command::OutlineSwitchPanePrevious => {
Message::Outline(outline::Message::SwitchPanePrevious)
}
Command::HelpModalScrollUpOne => {
Message::HelpModal(help_modal::Message::ScrollUp(ScrollAmount::One))
}
Command::HelpModalScrollDownOne => {
Message::HelpModal(help_modal::Message::ScrollDown(ScrollAmount::One))
}
Command::HelpModalScrollUpHalfPage => {
Message::HelpModal(help_modal::Message::ScrollUp(ScrollAmount::HalfPage))
}
Command::HelpModalScrollDownHalfPage => {
Message::HelpModal(help_modal::Message::ScrollDown(ScrollAmount::HalfPage))
}
Command::HelpModalToggle => Message::HelpModal(help_modal::Message::Toggle),
Command::HelpModalClose => Message::HelpModal(help_modal::Message::Close),
Command::NoteEditorScrollUpOne => {
Message::NoteEditor(note_editor::Message::ScrollUp(ScrollAmount::One))
}
Command::NoteEditorScrollDownOne => {
Message::NoteEditor(note_editor::Message::ScrollDown(ScrollAmount::One))
}
Command::NoteEditorScrollUpHalfPage => {
Message::NoteEditor(note_editor::Message::ScrollUp(ScrollAmount::HalfPage))
}
Command::NoteEditorScrollDownHalfPage => {
Message::NoteEditor(note_editor::Message::ScrollDown(ScrollAmount::HalfPage))
}
Command::NoteEditorSwitchPaneNext => {
Message::NoteEditor(note_editor::Message::SwitchPaneNext)
}
Command::NoteEditorSwitchPanePrevious => {
Message::NoteEditor(note_editor::Message::SwitchPanePrevious)
}
Command::NoteEditorCursorUp => Message::NoteEditor(note_editor::Message::CursorUp),
Command::NoteEditorCursorDown => Message::NoteEditor(note_editor::Message::CursorDown),
Command::NoteEditorScrollToTop => {
Message::NoteEditor(note_editor::Message::ScrollToTop)
}
Command::NoteEditorScrollToBottom => {
Message::NoteEditor(note_editor::Message::ScrollToBottom)
}
Command::ExplorerScrollToTop => Message::Explorer(explorer::Message::ScrollToTop),
Command::ExplorerScrollToBottom => Message::Explorer(explorer::Message::ScrollToBottom),
Command::TabNext => Message::TabNext,
Command::TabPrevious => Message::TabPrevious,
Command::TabClose => Message::CloseTab,
Command::NoteEditorToggleExplorer => {
Message::NoteEditor(note_editor::Message::ToggleExplorer)
}
Command::NoteEditorToggleOutline => {
Message::NoteEditor(note_editor::Message::ToggleOutline)
}
Command::NoteEditorExperimentalToggleView => {
Message::NoteEditor(note_editor::Message::ToggleView)
}
Command::NoteEditorExperimentalSetEditView => {
Message::NoteEditor(note_editor::Message::EditView)
}
Command::NoteEditorExperimentalSetReadView => {
Message::NoteEditor(note_editor::Message::ReadView)
}
Command::NoteEditorExperimentalSave => Message::NoteEditor(note_editor::Message::Save),
Command::NoteEditorExperimentalExit => Message::NoteEditor(note_editor::Message::Exit),
Command::NoteEditorExperimentalCursorWordForward => {
Message::NoteEditor(note_editor::Message::CursorWordForward)
}
Command::NoteEditorExperimentalCursorWordBackward => {
Message::NoteEditor(note_editor::Message::CursorWordBackward)
}
Command::NoteEditorExperimentalCursorLeft => {
Message::NoteEditor(note_editor::Message::CursorLeft)
}
Command::NoteEditorExperimentalCursorRight => {
Message::NoteEditor(note_editor::Message::CursorRight)
}
Command::NoteEditorInsertMode => Message::NoteEditor(note_editor::Message::InsertMode),
Command::NoteEditorAppend => Message::NoteEditor(note_editor::Message::Append),
Command::NoteEditorReplaceChar => {
Message::NoteEditor(note_editor::Message::ReplaceChar)
}
Command::NoteEditorVisualMode => Message::NoteEditor(note_editor::Message::VisualMode),
Command::NoteEditorVisualLineMode => {
Message::NoteEditor(note_editor::Message::VisualLineMode)
}
Command::NoteEditorDelete => {
Message::NoteEditor(note_editor::Message::Operator(Operator::Delete))
}
Command::NoteEditorChange => {
Message::NoteEditor(note_editor::Message::Operator(Operator::Change))
}
Command::NoteEditorYankOperator => {
Message::NoteEditor(note_editor::Message::Operator(Operator::Yank))
}
Command::NoteEditorDeleteUnderCursor => {
Message::NoteEditor(note_editor::Message::DeleteUnderCursor)
}
Command::NoteEditorDeleteToLineEnd => {
Message::NoteEditor(note_editor::Message::DeleteToLineEnd)
}
Command::NoteEditorChangeToLineEnd => {
Message::NoteEditor(note_editor::Message::ChangeToLineEnd)
}
Command::NoteEditorSubstituteChar => {
Message::NoteEditor(note_editor::Message::SubstituteChar)
}
Command::NoteEditorPasteAfter => Message::NoteEditor(note_editor::Message::PasteAfter),
Command::NoteEditorPasteBefore => {
Message::NoteEditor(note_editor::Message::PasteBefore)
}
Command::NoteEditorUndo => Message::NoteEditor(note_editor::Message::Undo),
Command::NoteEditorRedo => Message::NoteEditor(note_editor::Message::Redo),
Command::NoteEditorCursorLineStart => {
Message::NoteEditor(note_editor::Message::CursorLineStart)
}
Command::NoteEditorCursorLineEnd => {
Message::NoteEditor(note_editor::Message::CursorLineEnd)
}
Command::NoteEditorCursorFirstNonblank => {
Message::NoteEditor(note_editor::Message::CursorFirstNonblank)
}
Command::NoteEditorCursorWordEnd => {
Message::NoteEditor(note_editor::Message::CursorWordEnd)
}
Command::NoteEditorCursorWordForwardBig => {
Message::NoteEditor(note_editor::Message::CursorWordForwardBig)
}
Command::NoteEditorCursorWordBackwardBig => {
Message::NoteEditor(note_editor::Message::CursorWordBackwardBig)
}
Command::NoteEditorCursorWordEndBig => {
Message::NoteEditor(note_editor::Message::CursorWordEndBig)
}
Command::NoteEditorParagraphForward => {
Message::NoteEditor(note_editor::Message::ParagraphForward)
}
Command::NoteEditorParagraphBackward => {
Message::NoteEditor(note_editor::Message::ParagraphBackward)
}
Command::NoteEditorMatchingPair => {
Message::NoteEditor(note_editor::Message::MatchingPair)
}
Command::NoteEditorCursorDocStart => {
Message::NoteEditor(note_editor::Message::CursorDocStart)
}
Command::NoteEditorCursorDocEnd => {
Message::NoteEditor(note_editor::Message::CursorDocEnd)
}
Command::NoteEditorFindForward => Message::NoteEditor(note_editor::Message::FindChar {
direction: Direction::Forward,
till: false,
}),
Command::NoteEditorFindBackward => {
Message::NoteEditor(note_editor::Message::FindChar {
direction: Direction::Backward,
till: false,
})
}
Command::NoteEditorTillForward => Message::NoteEditor(note_editor::Message::FindChar {
direction: Direction::Forward,
till: true,
}),
Command::NoteEditorTillBackward => {
Message::NoteEditor(note_editor::Message::FindChar {
direction: Direction::Backward,
till: true,
})
}
Command::NoteEditorRepeatFind => {
Message::NoteEditor(note_editor::Message::RepeatFind { reverse: false })
}
Command::NoteEditorRepeatFindReverse => {
Message::NoteEditor(note_editor::Message::RepeatFind { reverse: true })
}
Command::VaultSelectorModalClose => {
Message::VaultSelectorModal(vault_selector_modal::Message::Close)
}
Command::VaultSelectorModalToggle => {
Message::VaultSelectorModal(vault_selector_modal::Message::Toggle)
}
Command::VaultSelectorModalUp => {
Message::VaultSelectorModal(vault_selector_modal::Message::Up)
}
Command::VaultSelectorModalDown => {
Message::VaultSelectorModal(vault_selector_modal::Message::Down)
}
Command::VaultSelectorModalOpen => {
Message::VaultSelectorModal(vault_selector_modal::Message::Select)
}
Command::DebugLogToggle => Message::DebugLog(debug_log::Message::Toggle),
Command::DebugLogClose => Message::DebugLog(debug_log::Message::Close),
Command::DebugLogClear => Message::DebugLog(debug_log::Message::Clear),
Command::DebugLogCycleLevel => Message::DebugLog(debug_log::Message::CycleLevel),
Command::DebugLogScrollUpOne => {
Message::DebugLog(debug_log::Message::ScrollUp(ScrollAmount::One))
}
Command::DebugLogScrollDownOne => {
Message::DebugLog(debug_log::Message::ScrollDown(ScrollAmount::One))
}
Command::DebugLogScrollUpHalfPage => {
Message::DebugLog(debug_log::Message::ScrollUp(ScrollAmount::HalfPage))
}
Command::DebugLogScrollDownHalfPage => {
Message::DebugLog(debug_log::Message::ScrollDown(ScrollAmount::HalfPage))
}
Command::ThemeSelectorModalClose => {
Message::ThemeSelectorModal(theme_selector_modal::Message::Close)
}
Command::ThemeSelectorModalToggle => {
Message::ThemeSelectorModal(theme_selector_modal::Message::Toggle)
}
Command::ThemeSelectorModalUp => {
Message::ThemeSelectorModal(theme_selector_modal::Message::Up)
}
Command::ThemeSelectorModalDown => {
Message::ThemeSelectorModal(theme_selector_modal::Message::Down)
}
Command::ThemeSelectorModalOpen => {
Message::ThemeSelectorModal(theme_selector_modal::Message::Select)
}
Command::Exec(command) => Message::Exec(command),
Command::Spawn(command) => Message::Spawn(command),
}
}
}
pub fn run_command<'a>(
command: String,
vault_name: &str,
note_name: &str,
note_path: &str,
mut callback: impl FnMut(&str, &[&str]) -> Option<Message<'a>>,
) -> Option<Message<'a>> {
let expanded = command
.replace_var("%vault", vault_name)
.replace_var("%note_path", note_path)
.replace_var("%note", note_name);
let args = expanded.split_whitespace().collect::<Vec<_>>();
match args.as_slice() {
[command, args @ ..] => callback(command, args),
[] => None,
}
}
pub fn sync_command<'a>(
terminal: &mut DefaultTerminal,
command: String,
vault_name: &str,
note_name: &str,
note_path: &str,
) -> Option<Message<'a>> {
fn enter_alternate_screen(terminal: &mut DefaultTerminal) -> Result<(), std::io::Error> {
disable_raw_mode()?;
stdout().execute(LeaveAlternateScreen)?;
stdout().execute(EnterAlternateScreen)?;
enable_raw_mode()?;
terminal.clear()
}
run_command(
command,
vault_name,
note_name,
note_path,
|command, args| {
if let Err(error) = process::Command::new(command).arg(args.join(" ")).status() {
error!(?error, command, "exec command failed");
return None;
}
enter_alternate_screen(terminal)
.map(|_| Message::Explorer(explorer::Message::Select))
.ok()
},
)
}
pub fn spawn_command<'a>(
command: String,
vault_name: &str,
note_name: &str,
note_path: &str,
) -> Option<Message<'a>> {
run_command(
command,
vault_name,
note_name,
note_path,
|command, args| {
if let Err(error) = process::Command::new(command).arg(args.join(" ")).spawn() {
error!(?error, command, "spawn command failed");
}
None
},
)
}