use crate::keymap::remap_char;
use crate::types::{Action, AppMode};
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
pub fn handle_key_event(key: KeyEvent, mode: AppMode, can_pop: bool) -> Action {
if key.kind != KeyEventKind::Press {
return Action::None;
}
match mode {
AppMode::Normal => match key.code {
KeyCode::Char('q') | KeyCode::Esc => {
if can_pop {
Action::PopSheet
} else {
Action::Quit
}
}
KeyCode::Char('j') | KeyCode::Down => Action::MoveDown,
KeyCode::Char('k') | KeyCode::Up => Action::MoveUp,
KeyCode::Char('l') | KeyCode::Right => Action::MoveRight,
KeyCode::Char('h') | KeyCode::Left => Action::MoveLeft,
KeyCode::PageDown => Action::PageDown,
KeyCode::Char('f') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::PageDown,
KeyCode::PageUp => Action::PageUp,
KeyCode::Char('b') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::PageUp,
KeyCode::Home => Action::GoTop,
KeyCode::End | KeyCode::Char('G') => Action::GoBottom,
KeyCode::Char('[') => Action::SortAscending,
KeyCode::Char(']') => Action::SortDescending,
KeyCode::Enter => Action::OpenRow,
KeyCode::Char('r') => Action::ResetSort,
KeyCode::Char('R') => Action::ReloadFile,
KeyCode::Char('/') => Action::StartSearch,
KeyCode::Char('n') => Action::SearchNext,
KeyCode::Char('N') => Action::SearchPrev,
KeyCode::Char('c') => Action::ClearSearch,
KeyCode::Char(',') => Action::SelectByValue,
KeyCode::Char('|') => Action::StartSelectByRegex,
KeyCode::Char('F') => Action::OpenFrequencyTable,
KeyCode::Char('V') => Action::OpenChart,
KeyCode::Char('!') => Action::TogglePinColumn,
KeyCode::Char('1') if key.modifiers.contains(KeyModifiers::SHIFT) => {
Action::TogglePinColumn
}
KeyCode::Char('I') => Action::DescribeSheet,
KeyCode::Char('t') => Action::OpenTypeSelect,
KeyCode::Char('T') => Action::TransposeTable,
KeyCode::Char('e') => Action::StartEdit,
KeyCode::Char('E') => Action::TransposeRow,
KeyCode::Char('U') => Action::Undo,
KeyCode::Char('u') if key.modifiers.contains(KeyModifiers::SHIFT) => Action::Undo,
KeyCode::Char('s') if key.modifiers.contains(KeyModifiers::CONTROL) => Action::SaveFile,
KeyCode::Char('+') => Action::OpenAggregatorSelect,
KeyCode::Char('-') => Action::ClearAggregators,
KeyCode::Char('Z') => Action::QuickAggregate,
KeyCode::Char('=') => Action::StartExpression,
KeyCode::Char('_') => Action::AdjustColumnWidth,
KeyCode::Char('s') => Action::SelectRow,
KeyCode::Char('u') => Action::UnselectRow,
KeyCode::Char('g') => Action::EnterGPrefix,
KeyCode::Char('z') => Action::EnterZPrefix,
KeyCode::Char('y') => Action::EnterYPrefix,
KeyCode::Char('p') => Action::PasteRows,
KeyCode::Char('d') => Action::DeleteSelectedRows,
KeyCode::Char('"') => Action::CreateSheetFromSelection,
KeyCode::Char('W') => Action::OpenPivotTableInput,
KeyCode::Char('?') => Action::ShowHelp,
KeyCode::Char(c) => {
let remapped = remap_char(c);
if remapped != c {
match remapped {
'q' => Action::Quit,
'k' => Action::MoveUp,
'j' => Action::MoveDown,
'h' => Action::MoveLeft,
'l' => Action::MoveRight,
'g' => Action::EnterGPrefix,
'z' => Action::EnterZPrefix,
'y' => Action::EnterYPrefix,
'p' => Action::PasteRows,
'd' => Action::DeleteSelectedRows,
's' => Action::SelectRow,
'u' => Action::UnselectRow,
'/' => Action::StartSearch,
'|' => Action::StartSelectByRegex,
'=' => Action::StartExpression,
'+' => Action::OpenAggregatorSelect,
'-' => Action::ClearAggregators,
'v' => Action::OpenChart,
'r' => Action::ResetSort,
'R' => Action::ReloadFile,
'i' => Action::DescribeSheet,
'e' => Action::StartEdit,
'F' => Action::OpenFrequencyTable,
'Z' => Action::QuickAggregate,
'U' => Action::Undo,
't' => Action::OpenTypeSelect,
'T' => Action::TransposeTable,
'!' => Action::TogglePinColumn,
'W' => Action::OpenPivotTableInput,
_ => Action::None,
}
} else {
Action::None
}
}
_ => Action::None,
},
AppMode::PivotTableInput => match key.code {
KeyCode::Char(c) => Action::PivotInput(c),
KeyCode::Backspace => Action::PivotBackspace,
KeyCode::Delete => Action::PivotForwardDelete,
KeyCode::Left => Action::PivotCursorLeft,
KeyCode::Right => Action::PivotCursorRight,
KeyCode::Home => Action::PivotCursorStart,
KeyCode::End => Action::PivotCursorEnd,
KeyCode::Tab => Action::PivotAutocomplete,
KeyCode::Up => Action::PivotHistoryPrev,
KeyCode::Down => Action::PivotHistoryNext,
KeyCode::Enter => Action::ApplyPivotTable,
KeyCode::Esc => Action::CancelPivotTable,
_ => Action::None,
},
AppMode::ChartAggSelect => match key.code {
KeyCode::Up | KeyCode::Char('k') => Action::ChartAggSelectUp,
KeyCode::Down | KeyCode::Char('j') => Action::ChartAggSelectDown,
KeyCode::Enter => Action::ApplyChartAgg,
KeyCode::Esc | KeyCode::Char('q') => Action::CancelChartAgg,
_ => Action::None,
},
AppMode::Searching => match key.code {
KeyCode::Esc => Action::CancelSearch,
KeyCode::Enter => Action::ApplySearch,
KeyCode::Backspace => Action::SearchBackspace,
KeyCode::Delete => Action::SearchForwardDelete,
KeyCode::Left => Action::SearchCursorLeft,
KeyCode::Right => Action::SearchCursorRight,
KeyCode::Home => Action::SearchCursorStart,
KeyCode::End => Action::SearchCursorEnd,
KeyCode::Char(c) => Action::SearchInput(c),
_ => Action::None,
},
AppMode::SelectByRegex => match key.code {
KeyCode::Esc => Action::CancelSelectByRegex,
KeyCode::Enter => Action::ApplySelectByRegex,
KeyCode::Backspace => Action::SelectRegexBackspace,
KeyCode::Delete => Action::SelectRegexForwardDelete,
KeyCode::Left => Action::SelectRegexCursorLeft,
KeyCode::Right => Action::SelectRegexCursorRight,
KeyCode::Home => Action::SelectRegexCursorStart,
KeyCode::End => Action::SelectRegexCursorEnd,
KeyCode::Tab => Action::SelectRegexAutocomplete,
KeyCode::Char(c) => Action::SelectRegexInput(c),
_ => Action::None,
},
AppMode::ExpressionInput => match key.code {
KeyCode::Esc => Action::CancelExpression,
KeyCode::Enter => Action::ApplyExpression,
KeyCode::Backspace => Action::ExpressionBackspace,
KeyCode::Delete => Action::ExpressionForwardDelete,
KeyCode::Left => Action::ExpressionCursorLeft,
KeyCode::Right => Action::ExpressionCursorRight,
KeyCode::Home => Action::ExpressionCursorStart,
KeyCode::End => Action::ExpressionCursorEnd,
KeyCode::Char(c) => Action::ExpressionInputChar(c),
KeyCode::Tab => Action::ExpressionAutocomplete,
KeyCode::Up => Action::ExpressionHistoryPrev,
KeyCode::Down => Action::ExpressionHistoryNext,
_ => Action::None,
},
AppMode::TypeSelect => match key.code {
KeyCode::Up | KeyCode::Char('k') => Action::TypeSelectUp,
KeyCode::Down | KeyCode::Char('j') => Action::TypeSelectDown,
KeyCode::Enter => Action::ApplyTypeSelect,
KeyCode::Esc | KeyCode::Char('q') => Action::CancelTypeSelect,
_ => Action::None,
},
AppMode::CurrencySelect => match key.code {
KeyCode::Up | KeyCode::Char('k') => Action::CurrencySelectUp,
KeyCode::Down | KeyCode::Char('j') => Action::CurrencySelectDown,
KeyCode::Enter => Action::ApplyCurrencySelect,
KeyCode::Esc | KeyCode::Char('q') => Action::CancelCurrencySelect,
_ => Action::None,
},
AppMode::Editing => match key.code {
KeyCode::Esc => Action::CancelEdit,
KeyCode::Enter => Action::ApplyEdit,
KeyCode::Backspace => Action::EditBackspace,
KeyCode::Delete => Action::EditForwardDelete,
KeyCode::Left => Action::EditCursorLeft,
KeyCode::Right => Action::EditCursorRight,
KeyCode::Home => Action::EditCursorStart,
KeyCode::End => Action::EditCursorEnd,
KeyCode::Char(c) => Action::EditInput(c),
_ => Action::None,
},
AppMode::Loading | AppMode::Calculating => Action::None,
AppMode::AggregatorSelect => match key.code {
KeyCode::Enter => Action::ApplyAggregators,
KeyCode::Up | KeyCode::Char('k') => Action::AggregatorSelectUp,
KeyCode::Down | KeyCode::Char('j') => Action::AggregatorSelectDown,
KeyCode::Char(' ') => Action::ToggleAggregatorSelection,
KeyCode::Esc | KeyCode::Char('q') => Action::CancelAggregatorSelect,
_ => Action::None,
},
AppMode::Saving => match key.code {
KeyCode::Esc => Action::CancelSave,
KeyCode::Enter => Action::ApplySave,
KeyCode::Tab => Action::SavingAutocomplete,
KeyCode::Backspace => Action::SavingBackspace,
KeyCode::Delete => Action::SavingForwardDelete,
KeyCode::Left => Action::SavingCursorLeft,
KeyCode::Right => Action::SavingCursorRight,
KeyCode::Home => Action::SavingCursorStart,
KeyCode::End => Action::SavingCursorEnd,
KeyCode::Char(c) => Action::SavingInput(c),
_ => Action::None,
},
AppMode::Chart => match key.code {
KeyCode::Char('V') | KeyCode::Char('q') | KeyCode::Esc => Action::OpenChart, _ => Action::None,
},
AppMode::GPrefix => match key.code {
KeyCode::Char('g') => Action::GoTop, KeyCode::Char('s') => Action::SelectAllRows, KeyCode::Char('u') => Action::UnselectAllRows, KeyCode::Char('_') => Action::AdjustAllColumnWidths, KeyCode::Char('F') => Action::OpenMultiFrequencyTable, KeyCode::Char('D') | KeyCode::Char('d') | KeyCode::Char('U') => {
Action::DeduplicateByPinned
}
KeyCode::Esc => Action::CancelGPrefix,
_ => Action::CancelGPrefix,
},
AppMode::ZPrefix => match key.code {
KeyCode::Char('e') => Action::StartRenameColumn,
KeyCode::Char('d') => Action::DeleteColumn,
KeyCode::Char('i') => Action::StartInsertColumn,
KeyCode::Char('f') => Action::CreatePctColumn,
KeyCode::Char('F') => Action::OpenPartitionSelect,
KeyCode::Char('s') => Action::SelectColumn,
KeyCode::Char('u') => Action::UnselectColumn,
KeyCode::Left | KeyCode::Char('h') => Action::MoveColumnLeft,
KeyCode::Right | KeyCode::Char('l') => Action::MoveColumnRight,
KeyCode::Char('>') | KeyCode::Char('.') => Action::IncreasePrecision,
KeyCode::Char('<') | KeyCode::Char(',') => Action::DecreasePrecision,
KeyCode::Esc => Action::CancelZPrefix,
_ => Action::CancelZPrefix,
},
AppMode::PartitionSelect => match key.code {
KeyCode::Enter => Action::ApplyPartitionedPct,
KeyCode::Up | KeyCode::Char('k') => Action::PartitionSelectUp,
KeyCode::Down | KeyCode::Char('j') => Action::PartitionSelectDown,
KeyCode::Char(' ') => Action::TogglePartitionSelection,
KeyCode::Esc | KeyCode::Char('q') => Action::CancelPartitionSelect,
_ => Action::None,
},
AppMode::RenamingColumn => match key.code {
KeyCode::Esc => Action::CancelRenameColumn,
KeyCode::Enter => Action::ApplyRenameColumn,
KeyCode::Backspace => Action::RenameColumnBackspace,
KeyCode::Delete => Action::RenameColumnForwardDelete,
KeyCode::Left => Action::RenameColumnCursorLeft,
KeyCode::Right => Action::RenameColumnCursorRight,
KeyCode::Home => Action::RenameColumnCursorStart,
KeyCode::End => Action::RenameColumnCursorEnd,
KeyCode::Char(c) => Action::RenameColumnInput(c),
_ => Action::None,
},
AppMode::InsertingColumn => match key.code {
KeyCode::Esc => Action::CancelInsertColumn,
KeyCode::Enter => Action::ApplyInsertColumn,
KeyCode::Backspace => Action::InsertColumnBackspace,
KeyCode::Delete => Action::InsertColumnForwardDelete,
KeyCode::Left => Action::InsertColumnCursorLeft,
KeyCode::Right => Action::InsertColumnCursorRight,
KeyCode::Home => Action::InsertColumnCursorStart,
KeyCode::End => Action::InsertColumnCursorEnd,
KeyCode::Char(c) => Action::InsertColumnInput(c),
_ => Action::None,
},
AppMode::ConfirmQuit => match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') | KeyCode::Enter => Action::ConfirmQuitYes,
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => Action::ConfirmQuitNo,
_ => Action::None,
},
AppMode::YPrefix => match key.code {
KeyCode::Char('y') => Action::CopyCurrentRow,
KeyCode::Char('c') => Action::CopyCurrentCell,
KeyCode::Char('l') => Action::CopyCurrentColumn,
KeyCode::Char('s') => Action::CopySelectedRows,
KeyCode::Esc => Action::CancelYPrefix,
_ => Action::CancelYPrefix,
},
AppMode::Help => match key.code {
KeyCode::Esc | KeyCode::Char('?') | KeyCode::Char('q') => Action::CloseHelp,
_ => Action::CloseHelp,
},
}
}