use crate::app::{self, App, FileTreeItem, FocusedPanel};
use crate::input::Action;
use crate::output::export_to_clipboard;
use crate::persistence::save_session;
pub fn handle_help_action(app: &mut App, action: Action) {
match action {
Action::CursorDown(n) => app.help_scroll_down(n),
Action::CursorUp(n) => app.help_scroll_up(n),
Action::HalfPageDown => app.help_scroll_down(app.help_state.viewport_height / 2),
Action::HalfPageUp => app.help_scroll_up(app.help_state.viewport_height / 2),
Action::PageDown => app.help_scroll_down(app.help_state.viewport_height),
Action::PageUp => app.help_scroll_up(app.help_state.viewport_height),
Action::GoToTop => app.help_scroll_to_top(),
Action::GoToBottom => app.help_scroll_to_bottom(),
Action::ToggleHelp => app.toggle_help(),
Action::Quit => app.should_quit = true,
_ => {}
}
}
pub fn handle_command_action(app: &mut App, action: Action) {
match action {
Action::InsertChar(c) => app.command_buffer.push(c),
Action::DeleteChar => {
app.command_buffer.pop();
}
Action::ExitMode => app.exit_command_mode(),
Action::SubmitInput => {
let cmd = app.command_buffer.trim().to_string();
match cmd.as_str() {
"q" | "quit" => app.should_quit = true,
"w" | "write" => match save_session(&app.session) {
Ok(path) => {
app.dirty = false;
app.set_message(format!("Saved to {}", path.display()));
}
Err(e) => app.set_error(format!("Save failed: {}", e)),
},
"x" | "wq" => match save_session(&app.session) {
Ok(_) => {
app.dirty = false;
if app.session.has_comments() {
app.exit_command_mode();
app.enter_confirm_mode(app::ConfirmAction::CopyAndQuit);
return;
} else {
app.should_quit = true;
}
}
Err(e) => app.set_error(format!("Save failed: {}", e)),
},
"e" | "reload" => match app.reload_diff_files() {
Ok(count) => app.set_message(format!("Reloaded {} files", count)),
Err(e) => app.set_error(format!("Reload failed: {}", e)),
},
"clip" | "export" => match export_to_clipboard(&app.session, &app.diff_source) {
Ok(msg) => app.set_message(msg),
Err(e) => app.set_warning(format!("{}", e)),
},
"version" => {
app.set_message(format!("tuicr v{}", env!("CARGO_PKG_VERSION")));
}
_ => app.set_message(format!("Unknown command: {}", cmd)),
}
app.exit_command_mode();
}
Action::Quit => app.should_quit = true,
_ => {}
}
}
pub fn handle_comment_action(app: &mut App, action: Action) {
match action {
Action::InsertChar(c) => {
app.comment_buffer.insert(app.comment_cursor, c);
app.comment_cursor += 1;
}
Action::DeleteChar => {
if app.comment_cursor > 0 {
app.comment_cursor -= 1;
app.comment_buffer.remove(app.comment_cursor);
}
}
Action::ExitMode => app.exit_comment_mode(),
Action::SubmitInput => app.save_comment(),
Action::CycleCommentType => app.cycle_comment_type(),
Action::TextCursorLeft => {
if app.comment_cursor > 0 {
app.comment_cursor -= 1;
}
}
Action::TextCursorRight => {
if app.comment_cursor < app.comment_buffer.len() {
app.comment_cursor += 1;
}
}
Action::DeleteWord => {
if app.comment_cursor > 0 {
while app.comment_cursor > 0
&& app
.comment_buffer
.chars()
.nth(app.comment_cursor - 1)
.map(|c| c.is_whitespace())
.unwrap_or(false)
{
app.comment_cursor -= 1;
app.comment_buffer.remove(app.comment_cursor);
}
while app.comment_cursor > 0
&& app
.comment_buffer
.chars()
.nth(app.comment_cursor - 1)
.map(|c| !c.is_whitespace())
.unwrap_or(false)
{
app.comment_cursor -= 1;
app.comment_buffer.remove(app.comment_cursor);
}
}
}
Action::ClearLine => {
app.comment_buffer.clear();
app.comment_cursor = 0;
}
Action::Quit => app.should_quit = true,
_ => {}
}
}
pub fn handle_confirm_action(app: &mut App, action: Action) {
match action {
Action::ConfirmYes => {
if let Some(app::ConfirmAction::CopyAndQuit) = app.pending_confirm {
match export_to_clipboard(&app.session, &app.diff_source) {
Ok(msg) => app.set_message(msg),
Err(e) => app.set_warning(format!("{}", e)),
}
}
app.exit_confirm_mode();
app.should_quit = true;
}
Action::ConfirmNo => {
app.exit_confirm_mode();
app.should_quit = true;
}
Action::Quit => app.should_quit = true,
_ => {}
}
}
pub fn handle_commit_select_action(app: &mut App, action: Action) {
match action {
Action::CommitSelectUp => app.commit_select_up(),
Action::CommitSelectDown => app.commit_select_down(),
Action::ToggleCommitSelect => app.toggle_commit_selection(),
Action::ConfirmCommitSelect => {
if let Err(e) = app.confirm_commit_selection() {
app.set_error(format!("Failed to load commits: {}", e));
}
}
Action::Quit => app.should_quit = true,
_ => {}
}
}
pub fn handle_file_list_action(app: &mut App, action: Action) {
match action {
Action::CursorDown(n) => app.file_list_down(n),
Action::CursorUp(n) => app.file_list_up(n),
Action::ScrollLeft(n) => app.file_list_state.scroll_left(n),
Action::ScrollRight(n) => app.file_list_state.scroll_right(n),
Action::SelectFile | Action::ToggleExpand => {
if let Some(item) = app.get_selected_tree_item() {
match item {
FileTreeItem::Directory { path, .. } => app.toggle_directory(&path),
FileTreeItem::File { file_idx, .. } => app.jump_to_file(file_idx),
}
}
}
_ => handle_shared_normal_action(app, action),
}
}
pub fn handle_diff_action(app: &mut App, action: Action) {
match action {
Action::CursorDown(n) => app.cursor_down(n),
Action::CursorUp(n) => app.cursor_up(n),
Action::ScrollLeft(n) => app.scroll_left(n),
Action::ScrollRight(n) => app.scroll_right(n),
Action::SelectFile => {
if let Some((gap_id, is_expanded)) = app.get_gap_at_cursor() {
if is_expanded {
app.collapse_gap(gap_id);
} else {
if let Err(e) = app.expand_gap(gap_id) {
app.set_error(format!("Failed to expand: {}", e));
}
}
}
}
_ => handle_shared_normal_action(app, action),
}
}
fn handle_shared_normal_action(app: &mut App, action: Action) {
match action {
Action::Quit => app.should_quit = true,
Action::HalfPageDown => app.scroll_down(15),
Action::HalfPageUp => app.scroll_up(15),
Action::PageDown => app.scroll_down(30),
Action::PageUp => app.scroll_up(30),
Action::GoToTop => app.jump_to_file(0),
Action::GoToBottom => {
let last = app.file_count().saturating_sub(1);
app.jump_to_file(last);
}
Action::NextFile => app.next_file(),
Action::PrevFile => app.prev_file(),
Action::NextHunk => app.next_hunk(),
Action::PrevHunk => app.prev_hunk(),
Action::ToggleReviewed => app.toggle_reviewed(),
Action::ToggleDiffView => app.toggle_diff_view_mode(),
Action::ToggleFocus => {
app.focused_panel = match app.focused_panel {
FocusedPanel::FileList => FocusedPanel::Diff,
FocusedPanel::Diff => FocusedPanel::FileList,
};
}
Action::ExpandAll => {
app.expand_all_dirs();
app.set_message("All directories expanded");
}
Action::CollapseAll => {
app.collapse_all_dirs();
app.set_message("All directories collapsed");
}
Action::ToggleHelp => app.toggle_help(),
Action::EnterCommandMode => app.enter_command_mode(),
Action::AddLineComment => {
let line = app.get_line_at_cursor();
if line.is_some() {
app.enter_comment_mode(false, line);
} else {
app.set_message("Move cursor to a diff line to add a line comment");
}
}
Action::AddFileComment => app.enter_comment_mode(true, None),
Action::EditComment => {
if !app.enter_edit_mode() {
app.set_message("No comment at cursor");
}
}
Action::ExportToClipboard => match export_to_clipboard(&app.session, &app.diff_source) {
Ok(msg) => app.set_message(msg),
Err(e) => app.set_warning(format!("{}", e)),
},
_ => {}
}
}