use crate::{ app::{Action, Alignment, App, DateMode, IdMode, NameMode, RefMode}, history::{DecorationKind, Decorations},}; #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]pub(crate) enum CommandId { Date, Ids, Emails, Names, Mailmap, Trailers, Refs, Hidden, Reword, NewCommit, NewEmptyCommit, Amend, Spill, Split, Forget, Pin, Unpin, Stash, Unstash, Rebase, RebaseUpdate, StartReview, FinishReview, Squash, CopyInsert, MoveInsert, StackInsert, ForkCommit, Attach, Todo, Note, ChecksPass, GitNote, VerifySignatures, Alignment, RefTree, CommitMessage, Changes,} #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]pub(crate) enum CommandGroup { View, Actions, Enrich, Information,} impl CommandGroup { pub(crate) fn label(self) -> &'static str { match self { CommandGroup::View => "View", CommandGroup::Actions => "Actions", CommandGroup::Enrich => "Enrich", CommandGroup::Information => "Information", } } pub(crate) fn prefix(self) -> char { match self { CommandGroup::View => 'v', CommandGroup::Actions => 'a', CommandGroup::Enrich => 'n', CommandGroup::Information => '?', } } fn index(self) -> usize { match self { CommandGroup::View => 0, CommandGroup::Actions => 1, CommandGroup::Enrich => 2, CommandGroup::Information => 3, } }} #[derive(Clone, Debug, Eq, PartialEq)]pub(crate) struct Command { pub(crate) id: CommandId, pub(crate) group: CommandGroup, pub(crate) row: usize, pub(crate) label: &'static str, pub(crate) shortcut: &'static str, pub(crate) active: bool, pub(crate) action: Action,} impl Command { pub(crate) fn key(&self) -> char { self.shortcut .chars() .next_back() .expect("command shortcuts always contain a leaf key") }} pub(crate) fn commands(app: &App, decorations: &Decorations, has_verifiable_signatures: bool) -> Vec<Command> { let mut out = Vec::with_capacity(35); let mut push = |id, group, row, label, shortcut, active, action| { out.push(Command { id, group, row, label, shortcut, active, action, }); }; let (date_label, date_active) = match app.date_mode { DateMode::Author => ("author date", true), DateMode::Committer => ("committer date", true), DateMode::None => ("date", false), }; push( CommandId::Date, CommandGroup::View, 0, date_label, "vd", date_active, Action::ToggleDate, ); let (ids_label, ids_active) = match (app.id_mode, app.effective_id_mode()) { (IdMode::Off, IdMode::Change) => ("auto change ids", true), (IdMode::Commit, _) => ("commit ids", true), (IdMode::Change, _) => ("change ids", true), (IdMode::Off, _) => ("ids", false), }; push( CommandId::Ids, CommandGroup::View, 0, ids_label, "vi", ids_active, Action::CycleIds, ); push( CommandId::Emails, CommandGroup::View, 0, "emails", "vs", app.show_emails, Action::ToggleEmail, ); let (names_label, names_active) = match app.name_mode { NameMode::All => ("names", true), NameMode::Author => ("name", true), NameMode::None => ("name", false), }; push( CommandId::Names, CommandGroup::View, 0, names_label, "ve", names_active, Action::ToggleName, ); push( CommandId::Mailmap, CommandGroup::View, 0, "mailmap", "vm", app.use_mailmap, Action::ToggleMailmap, ); push( CommandId::Trailers, CommandGroup::View, 0, "trailers", "vt", app.show_trailers, Action::ToggleTrailers, ); let refs_label = match app.ref_mode { RefMode::All => "all refs", RefMode::Default => "refs", RefMode::None => "no refs", }; push( CommandId::Refs, CommandGroup::View, 0, refs_label, "vr", app.ref_mode != RefMode::None, Action::CycleRefs, ); if app.has_hidden_filter { push( CommandId::Hidden, CommandGroup::View, 0, if app.show_hidden { "hide hidden" } else { "show hidden" }, "vh", app.show_hidden, Action::ToggleHidden, ); } let selected_is_segment = app.selected_is_segment(); let actions_visible = !selected_is_segment && (app.changes_focus != Some(crate::app::ChangePane::Worktree) || app.can_amend()); if actions_visible { if app.changes_focus.is_none() && app.reword_shortcut_visible() { push( CommandId::Reword, CommandGroup::Actions, 0, "reword", "ao", true, Action::Reword, ); } if app.changes_focus.is_none() && app.can_create_commit() { push( CommandId::NewCommit, CommandGroup::Actions, 0, "new", "aw", true, Action::NewCommit, ); } if app.changes_focus.is_none() && app.can_create_empty_commit() { push( CommandId::NewEmptyCommit, CommandGroup::Actions, 0, "new-empty", "an", true, Action::NewEmptyCommit, ); } if app.can_amend() { push( CommandId::Amend, CommandGroup::Actions, 0, "amend", "ae", true, Action::Amend, ); } if app.can_spill() { push( CommandId::Spill, CommandGroup::Actions, 0, "spill", "al", true, Action::Spill, ); } if app.can_split() { push( CommandId::Split, CommandGroup::Actions, 0, "split", "ap", true, Action::Split, ); } if app.changes_focus.is_none() && app.can_forget() { push( CommandId::Forget, CommandGroup::Actions, 0, "d forget", "ad", true, Action::Forget, ); } if app.changes_focus.is_none() && let Some(selected) = app.selected.and_then(|index| app.rows.get(index)) { let pinned = decorations.get(&selected.id).is_some_and(|decorations| { decorations .iter() .any(|decoration| decoration.kind == DecorationKind::Pin) }); push( if pinned { CommandId::Unpin } else { CommandId::Pin }, CommandGroup::Actions, 0, if pinned { "unpin" } else { "pin" }, "ai", true, Action::TogglePin, ); } if app.changes_focus.is_none() && app.can_stash() { push( CommandId::Stash, CommandGroup::Actions, 1, "z stash", "az", true, Action::Stash, ); } else if app.changes_focus.is_none() && app.can_unstash() { push( CommandId::Unstash, CommandGroup::Actions, 1, "z unstash", "az", true, Action::Stash, ); } if app.changes_focus.is_none() && app.can_rebase() { push( CommandId::Rebase, CommandGroup::Actions, 1, "rebase", "ab", true, Action::Rebase, ); } if app.changes_focus.is_none() && app.can_rebase_update() { push( CommandId::RebaseUpdate, CommandGroup::Actions, 1, "rebase-update", "au", true, Action::RebaseUpdate, ); } if app.changes_focus.is_none() && app.can_finish_review() { push( CommandId::FinishReview, CommandGroup::Actions, 1, "finish-review", "ar", true, Action::Review, ); } else if app.changes_focus.is_none() && app.can_review() { push( CommandId::StartReview, CommandGroup::Actions, 1, "review", "ar", true, Action::Review, ); } if app.changes_focus.is_none() && app.can_squash() { push( CommandId::Squash, CommandGroup::Actions, 1, "squash", "as", true, Action::Squash, ); } if app.changes_focus.is_none() && app.can_copy_insert() { push( CommandId::CopyInsert, CommandGroup::Actions, 1, "copy-insert", "ay", true, Action::CopyInsert, ); } if app.changes_focus.is_none() && app.can_move_insert() { push( CommandId::MoveInsert, CommandGroup::Actions, 1, "move-insert", "am", true, Action::MoveInsert, ); } if app.changes_focus.is_none() && app.can_stack_insert() { push( CommandId::StackInsert, CommandGroup::Actions, 1, "stack-insert", "at", true, Action::StackInsert, ); } if app.changes_focus.is_none() && app.can_fork_commit() { push( CommandId::ForkCommit, CommandGroup::Actions, 1, "fork", "af", true, Action::ForkCommit, ); } if app.changes_focus.is_none() && app.can_attach() { push( CommandId::Attach, CommandGroup::Actions, 1, "attach", "ah", true, Action::Attach, ); } } if !selected_is_segment && let Some(row) = app.selected.and_then(|index| app.rows.get(index)) { if app.can_reword() { push( CommandId::Todo, CommandGroup::Enrich, 0, "todo", "nt", app.todo(row.id), Action::ToggleTodo, ); push( CommandId::Note, CommandGroup::Enrich, 0, "note", "no", app.note(row.id).is_some(), Action::EditNote, ); } push( CommandId::ChecksPass, CommandGroup::Enrich, 0, "checks-pass", "ne", app.checks_pass(row.id), Action::ToggleChecksPass, ); push( CommandId::GitNote, CommandGroup::Enrich, 0, "git note", "ng", !app.notes(row.id).is_empty(), Action::EditGitNote, ); } if app.signature_failures > 0 || has_verifiable_signatures { push( CommandId::VerifySignatures, CommandGroup::Information, 0, "verify signatures", "?s", true, Action::VerifySignatures, ); } let (alignment_label, alignment_active) = match app.alignment { Alignment::Title => ("[ title", true),Lines 1–500 of 710. Load more
use crate::{ app::{Action, Alignment, App, DateMode, IdMode, NameMode, RefMode}, history::{DecorationKind, Decorations}, }; #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub(crate) enum CommandId { Date, Ids, Emails, Names, Mailmap, Trailers, Refs, Hidden, Reword, NewCommit, NewEmptyCommit, Amend, Spill, Split, Forget, Pin, Unpin, Stash, Unstash, Rebase, RebaseUpdate, StartReview, FinishReview, Squash, CopyInsert, MoveInsert, StackInsert, ForkCommit, Attach, Todo, Note, ChecksPass, GitNote, VerifySignatures, Alignment, RefTree, CommitMessage, Changes, } #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub(crate) enum CommandGroup { View, Actions, Enrich, Information, } impl CommandGroup { pub(crate) fn label(self) -> &'static str { match self { CommandGroup::View => "View", CommandGroup::Actions => "Actions", CommandGroup::Enrich => "Enrich", CommandGroup::Information => "Information", } } pub(crate) fn prefix(self) -> char { match self { CommandGroup::View => 'v', CommandGroup::Actions => 'a', CommandGroup::Enrich => 'n', CommandGroup::Information => '?', } } fn index(self) -> usize { match self { CommandGroup::View => 0, CommandGroup::Actions => 1, CommandGroup::Enrich => 2, CommandGroup::Information => 3, } } } #[derive(Clone, Debug, Eq, PartialEq)] pub(crate) struct Command { pub(crate) id: CommandId, pub(crate) group: CommandGroup, pub(crate) row: usize, pub(crate) label: &'static str, pub(crate) shortcut: &'static str, pub(crate) active: bool, pub(crate) action: Action, } impl Command { pub(crate) fn key(&self) -> char { self.shortcut .chars() .next_back() .expect("command shortcuts always contain a leaf key") } } pub(crate) fn commands(app: &App, decorations: &Decorations, has_verifiable_signatures: bool) -> Vec<Command> { let mut out = Vec::with_capacity(35); let mut push = |id, group, row, label, shortcut, active, action| { out.push(Command { id, group, row, label, shortcut, active, action, }); }; let (date_label, date_active) = match app.date_mode { DateMode::Author => ("author date", true), DateMode::Committer => ("committer date", true), DateMode::None => ("date", false), }; push( CommandId::Date, CommandGroup::View, 0, date_label, "vd", date_active, Action::ToggleDate, ); let (ids_label, ids_active) = match (app.id_mode, app.effective_id_mode()) { (IdMode::Off, IdMode::Change) => ("auto change ids", true), (IdMode::Commit, _) => ("commit ids", true), (IdMode::Change, _) => ("change ids", true), (IdMode::Off, _) => ("ids", false), }; push( CommandId::Ids, CommandGroup::View, 0, ids_label, "vi", ids_active, Action::CycleIds, ); push( CommandId::Emails, CommandGroup::View, 0, "emails", "vs", app.show_emails, Action::ToggleEmail, ); let (names_label, names_active) = match app.name_mode { NameMode::All => ("names", true), NameMode::Author => ("name", true), NameMode::None => ("name", false), }; push( CommandId::Names, CommandGroup::View, 0, names_label, "ve", names_active, Action::ToggleName, ); push( CommandId::Mailmap, CommandGroup::View, 0, "mailmap", "vm", app.use_mailmap, Action::ToggleMailmap, ); push( CommandId::Trailers, CommandGroup::View, 0, "trailers", "vt", app.show_trailers, Action::ToggleTrailers, ); let refs_label = match app.ref_mode { RefMode::All => "all refs", RefMode::Default => "refs", RefMode::None => "no refs", }; push( CommandId::Refs, CommandGroup::View, 0, refs_label, "vr", app.ref_mode != RefMode::None, Action::CycleRefs, ); if app.has_hidden_filter { push( CommandId::Hidden, CommandGroup::View, 0, if app.show_hidden { "hide hidden" } else { "show hidden" }, "vh", app.show_hidden, Action::ToggleHidden, ); } let selected_is_segment = app.selected_is_segment(); let actions_visible = !selected_is_segment && (app.changes_focus != Some(crate::app::ChangePane::Worktree) || app.can_amend()); if actions_visible { if app.changes_focus.is_none() && app.reword_shortcut_visible() { push( CommandId::Reword, CommandGroup::Actions, 0, "reword", "ao", true, Action::Reword, ); } if app.changes_focus.is_none() && app.can_create_commit() { push( CommandId::NewCommit, CommandGroup::Actions, 0, "new", "aw", true, Action::NewCommit, ); } if app.changes_focus.is_none() && app.can_create_empty_commit() { push( CommandId::NewEmptyCommit, CommandGroup::Actions, 0, "new-empty", "an", true, Action::NewEmptyCommit, ); } if app.can_amend() { push( CommandId::Amend, CommandGroup::Actions, 0, "amend", "ae", true, Action::Amend, ); } if app.can_spill() { push( CommandId::Spill, CommandGroup::Actions, 0, "spill", "al", true, Action::Spill, ); } if app.can_split() { push( CommandId::Split, CommandGroup::Actions, 0, "split", "ap", true, Action::Split, ); } if app.changes_focus.is_none() && app.can_forget() { push( CommandId::Forget, CommandGroup::Actions, 0, "d forget", "ad", true, Action::Forget, ); } if app.changes_focus.is_none() && let Some(selected) = app.selected.and_then(|index| app.rows.get(index)) { let pinned = decorations.get(&selected.id).is_some_and(|decorations| { decorations .iter() .any(|decoration| decoration.kind == DecorationKind::Pin) }); push( if pinned { CommandId::Unpin } else { CommandId::Pin }, CommandGroup::Actions, 0, if pinned { "unpin" } else { "pin" }, "ai", true, Action::TogglePin, ); } if app.changes_focus.is_none() && app.can_stash() { push( CommandId::Stash, CommandGroup::Actions, 1, "z stash", "az", true, Action::Stash, ); } else if app.changes_focus.is_none() && app.can_unstash() { push( CommandId::Unstash, CommandGroup::Actions, 1, "z unstash", "az", true, Action::Stash, ); } if app.changes_focus.is_none() && app.can_rebase() { push( CommandId::Rebase, CommandGroup::Actions, 1, "rebase", "ab", true, Action::Rebase, ); } if app.changes_focus.is_none() && app.can_rebase_update() { push( CommandId::RebaseUpdate, CommandGroup::Actions, 1, "rebase-update", "au", true, Action::RebaseUpdate, ); } if app.changes_focus.is_none() && app.can_finish_review() { push( CommandId::FinishReview, CommandGroup::Actions, 1, "finish-review", "ar", true, Action::Review, ); } else if app.changes_focus.is_none() && app.can_review() { push( CommandId::StartReview, CommandGroup::Actions, 1, "review", "ar", true, Action::Review, ); } if app.changes_focus.is_none() && app.can_squash() { push( CommandId::Squash, CommandGroup::Actions, 1, "squash", "as", true, Action::Squash, ); } if app.changes_focus.is_none() && app.can_copy_insert() { push( CommandId::CopyInsert, CommandGroup::Actions, 1, "copy-insert", "ay", true, Action::CopyInsert, ); } if app.changes_focus.is_none() && app.can_move_insert() { push( CommandId::MoveInsert, CommandGroup::Actions, 1, "move-insert", "am", true, Action::MoveInsert, ); } if app.changes_focus.is_none() && app.can_stack_insert() { push( CommandId::StackInsert, CommandGroup::Actions, 1, "stack-insert", "at", true, Action::StackInsert, ); } if app.changes_focus.is_none() && app.can_fork_commit() { push( CommandId::ForkCommit, CommandGroup::Actions, 1, "fork", "af", true, Action::ForkCommit, ); } if app.changes_focus.is_none() && app.can_attach() { push( CommandId::Attach, CommandGroup::Actions, 1, "attach", "ah", true, Action::Attach, ); } } if !selected_is_segment && let Some(row) = app.selected.and_then(|index| app.rows.get(index)) { if app.can_reword() { push( CommandId::Todo, CommandGroup::Enrich, 0, "todo", "nt", app.todo(row.id), Action::ToggleTodo, ); push( CommandId::Note, CommandGroup::Enrich, 0, "note", "no", app.note(row.id).is_some(), Action::EditNote, ); } push( CommandId::ChecksPass, CommandGroup::Enrich, 0, "checks-pass", "ne", app.checks_pass(row.id), Action::ToggleChecksPass, ); push( CommandId::GitNote, CommandGroup::Enrich, 0, "git note", "ng", !app.notes(row.id).is_empty(), Action::EditGitNote, ); } if app.signature_failures > 0 || has_verifiable_signatures { push( CommandId::VerifySignatures, CommandGroup::Information, 0, "verify signatures", "?s", true, Action::VerifySignatures, ); } let (alignment_label, alignment_active) = match app.alignment { Alignment::Title => ("[ title", true),