use super::StatusEntry;
use crate::app::{App, Mode};
use crate::ui::style::{ACCENT, DANGER, SUCCESS, accent_style, muted_style, primary_style};
use crate::ui::{
confirm_tag_delete_entries, confirm_tag_push_all_entries, confirm_tag_push_entries,
};
use ratatui::style::{Modifier, Style};
use ratatui::text::Span;
pub(crate) fn commit_input_editing_entries() -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let entries_data = [
("Done Editing", "⌃C"),
("Toggle Amend", "⌃A"),
("Newline", "↵"),
("Cancel Commit", "⎋"),
("Max Size", "⌃D"),
("Scroll", "↑/↓"),
];
(None, super::build_status_entries(&entries_data))
}
pub(crate) fn commit_input_confirm_entries(
commit_amend: bool,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let amend_toggle_label = if commit_amend { "Amend: [Yes]" } else { "Amend: [No]" };
let entries_data = [
("Submit Commit", "↵"),
(amend_toggle_label, "a/space"),
("Edit Message", "e"),
("Cancel", "⎋/q"),
("Max Size", "d"),
("Scroll", "↑/↓"),
];
(None, super::build_status_entries(&entries_data))
}
pub(crate) fn confirm_delete_entries(
target: &str,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let message_spans = Some(vec![
Span::raw("Delete "),
Span::styled(
format!("\"{}\"", target),
Style::default().fg(DANGER()).add_modifier(Modifier::BOLD),
),
Span::raw("? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", Style::default().fg(DANGER()).add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋/↵", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_branch_delete_entries(
target: &str,
is_remote: bool,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let type_label = if is_remote { "remote-tracking branch" } else { "branch" };
let message_spans = Some(vec![
Span::raw("Delete "),
Span::raw(type_label),
Span::raw(" "),
Span::styled(
format!("\"{}\"", target),
Style::default().fg(DANGER()).add_modifier(Modifier::BOLD),
),
Span::raw("? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", Style::default().fg(DANGER()).add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_remote_delete_entries(
target: &str,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let message_spans = Some(vec![
Span::raw("Remove remote "),
Span::styled(
format!("\"{}\"", target),
Style::default().fg(DANGER()).add_modifier(Modifier::BOLD),
),
Span::raw("? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", Style::default().fg(DANGER()).add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_branch_checkout_entries(
target: &str,
is_remote: bool,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let type_label = if is_remote { "remote-tracking branch" } else { "branch" };
let message_spans = Some(vec![
Span::raw("Checkout "),
Span::raw(type_label),
Span::raw(" "),
Span::styled(format!("\"{}\"", target), accent_style().add_modifier(Modifier::BOLD)),
Span::raw("? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", accent_style().add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_tag_checkout_entries(
target: &str,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let message_spans = Some(vec![
Span::raw("Checkout tag "),
Span::styled(format!("\"{}\"", target), accent_style().add_modifier(Modifier::BOLD)),
Span::raw(" (detached HEAD)? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", accent_style().add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_commit_checkout_entries(
target: &str,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let short_oid = if target.len() > 7 { &target[..7] } else { target };
let message_spans = Some(vec![
Span::raw("Checkout commit "),
Span::styled(format!("\"{}\"", short_oid), accent_style().add_modifier(Modifier::BOLD)),
Span::raw(" (detached HEAD)? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", accent_style().add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_discard_changes_entries(
target: &str,
staged: bool,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let message_spans = if target == "All Changes" {
Some(vec![
Span::raw("Discard "),
Span::styled("ALL", Style::default().fg(DANGER()).add_modifier(Modifier::BOLD)),
Span::raw(" changes in the repository? "),
])
} else {
let area_label = if staged { "staged" } else { "unstaged" };
Some(vec![
Span::raw("Discard "),
Span::raw(area_label),
Span::raw(" changes in "),
Span::styled(
format!("\"{}\"", target),
Style::default().fg(DANGER()).add_modifier(Modifier::BOLD),
),
Span::raw("? "),
])
};
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", Style::default().fg(DANGER()).add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_branch_merge_entries(
target: &str,
is_remote: bool,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let type_label = if is_remote { "remote-tracking branch" } else { "branch" };
let message_spans = Some(vec![
Span::raw("Merge "),
Span::raw(type_label),
Span::raw(" "),
Span::styled(
format!("\"{}\"", target),
Style::default().fg(ACCENT()).add_modifier(Modifier::BOLD),
),
Span::raw(" into current branch? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", Style::default().fg(ACCENT()).add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_branch_rebase_entries(
target: &str,
is_remote: bool,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let type_label = if is_remote { "remote-tracking branch" } else { "branch" };
let message_spans = Some(vec![
Span::raw("Rebase current branch onto "),
Span::raw(type_label),
Span::raw(" "),
Span::styled(
format!("\"{}\"", target),
Style::default().fg(ACCENT()).add_modifier(Modifier::BOLD),
),
Span::raw("? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", Style::default().fg(ACCENT()).add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_branch_interactive_rebase_entries(
target: &str,
is_remote: bool,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let type_label = if is_remote { "remote-tracking branch" } else { "branch" };
let message_spans = Some(vec![
Span::raw("Interactively rebase current branch onto "),
Span::raw(type_label),
Span::raw(" "),
Span::styled(
format!("\"{}\"", target),
Style::default().fg(ACCENT()).add_modifier(Modifier::BOLD),
),
Span::raw("? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", Style::default().fg(ACCENT()).add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_stash_delete_entries(
target: &str,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let message_spans = Some(vec![
Span::raw("Delete stash "),
Span::styled(
format!("\"{}\"", target),
Style::default().fg(DANGER()).add_modifier(Modifier::BOLD),
),
Span::raw("? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", Style::default().fg(DANGER()).add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_stash_apply_entries(
target: &str,
delete_after: bool,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let message_spans = Some(vec![
Span::raw("Apply stash "),
Span::styled(
format!("\"{}\"", target),
Style::default().fg(ACCENT()).add_modifier(Modifier::BOLD),
),
Span::raw("? "),
]);
let delete_toggle_label =
if delete_after { "Delete after apply: [Yes]" } else { "Delete after apply: [No]" };
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", Style::default().fg(SUCCESS()).add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw(delete_toggle_label.to_string()),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("d/space/a", accent_style()),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn remote_picker_status_entries() -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let message_spans = Some(vec![Span::raw("Select a remote to use for this operation")]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Navigate"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("↑↓", accent_style()),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::raw(" Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("⏎", accent_style()),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::raw(" Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn confirm_branch_push_entries(
target: &str,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let message_spans = Some(vec![
Span::raw("Push branch "),
Span::styled(
format!("\"{}\"", target),
Style::default().fg(ACCENT()).add_modifier(Modifier::BOLD),
),
Span::raw("? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", Style::default().fg(ACCENT()).add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}
pub(crate) fn help_dismiss_entries(app: &App) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let compat = app.config.compatibility_mode;
let help_key = app.keybindings.format_action_keys(crate::keybindings::Action::Help, compat);
let close_key =
app.keybindings.format_action_keys(crate::keybindings::Action::CloseDetail, compat);
let close_keys = format!("{}/{}", help_key, close_key);
let entries = vec![StatusEntry::new(vec![
Span::raw("Close Help"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled(close_keys, accent_style()),
Span::styled("]", muted_style()),
])];
(None, entries)
}
pub(crate) fn about_dismiss_entries(app: &App) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let compat = app.config.compatibility_mode;
let about_key =
app.keybindings.format_action_keys(crate::keybindings::Action::HomeAbout, compat);
let close_key =
app.keybindings.format_action_keys(crate::keybindings::Action::CloseDetail, compat);
let close_keys = format!("{}/{}", about_key, close_key);
let entries = vec![StatusEntry::new(vec![
Span::raw("Close About"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled(close_keys, accent_style()),
Span::styled("]", muted_style()),
])];
(None, entries)
}
pub(crate) fn legend_dismiss_entries(app: &App) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let compat = app.config.compatibility_mode;
let legend_key =
app.keybindings.format_action_keys(crate::keybindings::Action::HomeSymbolsHelp, compat);
let close_key =
app.keybindings.format_action_keys(crate::keybindings::Action::CloseDetail, compat);
let close_keys = format!("{}/{}", legend_key, close_key);
let entries = vec![StatusEntry::new(vec![
Span::raw("Close Legend"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled(close_keys, accent_style()),
Span::styled("]", muted_style()),
])];
(None, entries)
}
pub(crate) fn confirm_submodule_delete_entries(
target: &str,
) -> (Option<Vec<Span<'static>>>, Vec<StatusEntry>) {
let message_spans = Some(vec![
Span::raw("Delete submodule "),
Span::styled(
format!("\"{}\"", target),
Style::default().fg(DANGER()).add_modifier(Modifier::BOLD),
),
Span::raw("? "),
]);
let entries = vec![
StatusEntry::new(vec![
Span::raw("Confirm"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("y", Style::default().fg(DANGER()).add_modifier(Modifier::BOLD)),
Span::styled("]", muted_style()),
]),
StatusEntry::new(vec![
Span::styled(" ", muted_style()),
Span::raw("Cancel"),
Span::raw(" "),
Span::styled("[", muted_style()),
Span::styled("n/⎋", accent_style()),
Span::styled("]", muted_style()),
]),
];
(message_spans, entries)
}