allow config for key symbols (#997)

closes #465
This commit is contained in:
Stephan Dilly 2021-11-20 18:44:04 +01:00 committed by GitHub
parent e548e8c75f
commit 3db1a68515
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 603 additions and 424 deletions

View file

@ -297,24 +297,27 @@ impl App {
{
flags.insert(NeedsUpdate::COMMANDS);
} else if let Event::Key(k) = ev {
let new_flags = if k == self.key_config.tab_toggle {
let new_flags = if k
== self.key_config.keys.tab_toggle
{
self.toggle_tabs(false)?;
NeedsUpdate::COMMANDS
} else if k == self.key_config.tab_toggle_reverse {
} else if k == self.key_config.keys.tab_toggle_reverse
{
self.toggle_tabs(true)?;
NeedsUpdate::COMMANDS
} else if k == self.key_config.tab_status
|| k == self.key_config.tab_log
|| k == self.key_config.tab_files
|| k == self.key_config.tab_stashing
|| k == self.key_config.tab_stashes
} else if k == self.key_config.keys.tab_status
|| k == self.key_config.keys.tab_log
|| k == self.key_config.keys.tab_files
|| k == self.key_config.keys.tab_stashing
|| k == self.key_config.keys.tab_stashes
{
self.switch_tab(k)?;
NeedsUpdate::COMMANDS
} else if k == self.key_config.cmd_bar_toggle {
} else if k == self.key_config.keys.cmd_bar_toggle {
self.cmdbar.borrow_mut().toggle_more();
NeedsUpdate::empty()
} else if k == self.key_config.open_options {
} else if k == self.key_config.keys.open_options {
self.options_popup.show()?;
NeedsUpdate::ALL
} else {
@ -497,7 +500,7 @@ impl App {
return false;
}
if let Event::Key(e) = ev {
if e == self.key_config.quit {
if e == self.key_config.keys.quit {
self.do_quit = true;
return true;
}
@ -507,7 +510,7 @@ impl App {
fn check_hard_exit(&mut self, ev: Event) -> bool {
if let Event::Key(e) = ev {
if e == self.key_config.exit {
if e == self.key_config.keys.exit {
self.do_quit = true;
return true;
}
@ -537,15 +540,15 @@ impl App {
}
fn switch_tab(&mut self, k: KeyEvent) -> Result<()> {
if k == self.key_config.tab_status {
if k == self.key_config.keys.tab_status {
self.set_tab(0)?;
} else if k == self.key_config.tab_log {
} else if k == self.key_config.keys.tab_log {
self.set_tab(1)?;
} else if k == self.key_config.tab_files {
} else if k == self.key_config.keys.tab_files {
self.set_tab(2)?;
} else if k == self.key_config.tab_stashing {
} else if k == self.key_config.keys.tab_stashing {
self.set_tab(3)?;
} else if k == self.key_config.tab_stashes {
} else if k == self.key_config.keys.tab_stashes {
self.set_tab(4)?;
}

View file

@ -185,25 +185,25 @@ impl Component for BlameFileComponent {
) -> Result<EventState> {
if self.is_visible() {
if let Event::Key(key) = event {
if key == self.key_config.exit_popup {
if key == self.key_config.keys.exit_popup {
self.hide();
} else if key == self.key_config.move_up {
} else if key == self.key_config.keys.move_up {
self.move_selection(ScrollType::Up);
} else if key == self.key_config.move_down {
} else if key == self.key_config.keys.move_down {
self.move_selection(ScrollType::Down);
} else if key == self.key_config.shift_up
|| key == self.key_config.home
} else if key == self.key_config.keys.shift_up
|| key == self.key_config.keys.home
{
self.move_selection(ScrollType::Home);
} else if key == self.key_config.shift_down
|| key == self.key_config.end
} else if key == self.key_config.keys.shift_down
|| key == self.key_config.keys.end
{
self.move_selection(ScrollType::End);
} else if key == self.key_config.page_down {
} else if key == self.key_config.keys.page_down {
self.move_selection(ScrollType::PageDown);
} else if key == self.key_config.page_up {
} else if key == self.key_config.keys.page_up {
self.move_selection(ScrollType::PageUp);
} else if key == self.key_config.focus_right {
} else if key == self.key_config.keys.focus_right {
self.hide();
return self.selected_commit().map_or(

View file

@ -208,54 +208,55 @@ impl Component for BranchListComponent {
}
if let Event::Key(e) = ev {
if e == self.key_config.exit_popup {
if e == self.key_config.keys.exit_popup {
self.hide();
} else if e == self.key_config.move_down {
} else if e == self.key_config.keys.move_down {
return self
.move_selection(ScrollType::Up)
.map(Into::into);
} else if e == self.key_config.move_up {
} else if e == self.key_config.keys.move_up {
return self
.move_selection(ScrollType::Down)
.map(Into::into);
} else if e == self.key_config.page_down {
} else if e == self.key_config.keys.page_down {
return self
.move_selection(ScrollType::PageDown)
.map(Into::into);
} else if e == self.key_config.page_up {
} else if e == self.key_config.keys.page_up {
return self
.move_selection(ScrollType::PageUp)
.map(Into::into);
} else if e == self.key_config.home {
} else if e == self.key_config.keys.home {
return self
.move_selection(ScrollType::Home)
.map(Into::into);
} else if e == self.key_config.end {
} else if e == self.key_config.keys.end {
return self
.move_selection(ScrollType::End)
.map(Into::into);
} else if e == self.key_config.tab_toggle {
} else if e == self.key_config.keys.tab_toggle {
self.local = !self.local;
self.update_branches()?;
} else if e == self.key_config.enter {
} else if e == self.key_config.keys.enter {
try_or_popup!(
self,
"switch branch error:",
self.switch_to_selected_branch()
);
} else if e == self.key_config.create_branch && self.local
} else if e == self.key_config.keys.create_branch
&& self.local
{
self.queue.push(InternalEvent::CreateBranch);
} else if e == self.key_config.rename_branch
} else if e == self.key_config.keys.rename_branch
&& self.valid_selection()
{
self.rename_branch();
} else if e == self.key_config.delete_branch
} else if e == self.key_config.keys.delete_branch
&& !self.selection_is_cur_branch()
&& self.valid_selection()
{
self.delete_branch();
} else if e == self.key_config.merge_branch
} else if e == self.key_config.keys.merge_branch
&& !self.selection_is_cur_branch()
&& self.valid_selection()
{
@ -264,7 +265,7 @@ impl Component for BranchListComponent {
"merge branch error:",
self.merge_branch()
);
} else if e == self.key_config.rebase_branch
} else if e == self.key_config.keys.rebase_branch
&& !self.selection_is_cur_branch()
&& self.valid_selection()
{
@ -273,7 +274,7 @@ impl Component for BranchListComponent {
"rebase error:",
self.rebase_branch()
);
} else if e == self.key_config.move_right
} else if e == self.key_config.keys.move_right
&& self.valid_selection()
{
self.hide();
@ -281,7 +282,7 @@ impl Component for BranchListComponent {
self.queue
.push(InternalEvent::InspectCommit(b, None));
}
} else if e == self.key_config.compare_commits
} else if e == self.key_config.keys.compare_commits
&& self.valid_selection()
{
self.hide();
@ -289,7 +290,7 @@ impl Component for BranchListComponent {
self.queue
.push(InternalEvent::CompareCommits(b, None));
}
} else if e == self.key_config.cmd_bar_toggle {
} else if e == self.key_config.keys.cmd_bar_toggle {
//do not consume if its the more key
return Ok(EventState::NotConsumed);
}

View file

@ -242,7 +242,8 @@ impl Component for ChangesComponent {
if self.focused() {
if let Event::Key(e) = ev {
return if e == self.key_config.stage_unstage_item {
return if e == self.key_config.keys.stage_unstage_item
{
try_or_popup!(
self,
"staging error:",
@ -253,7 +254,7 @@ impl Component for ChangesComponent {
NeedsUpdate::ALL,
));
Ok(EventState::Consumed)
} else if e == self.key_config.status_stage_all
} else if e == self.key_config.keys.status_stage_all
&& !self.is_empty()
{
if self.is_working_dir {
@ -268,11 +269,11 @@ impl Component for ChangesComponent {
self.queue
.push(InternalEvent::StatusLastFileMoved);
Ok(EventState::Consumed)
} else if e == self.key_config.status_reset_item
} else if e == self.key_config.keys.status_reset_item
&& self.is_working_dir
{
Ok(self.dispatch_reset_workdir().into())
} else if e == self.key_config.status_ignore_file
} else if e == self.key_config.keys.status_ignore_file
&& self.is_working_dir
&& !self.is_empty()
{

View file

@ -316,17 +316,20 @@ impl Component for CommitComponent {
}
if let Event::Key(e) = ev {
if e == self.key_config.enter && self.can_commit() {
if e == self.key_config.keys.enter
&& self.can_commit()
{
try_or_popup!(
self,
"commit error:",
self.commit()
);
} else if e == self.key_config.commit_amend
} else if e == self.key_config.keys.commit_amend
&& self.can_amend()
{
self.amend()?;
} else if e == self.key_config.open_commit_editor {
} else if e == self.key_config.keys.open_commit_editor
{
self.queue.push(
InternalEvent::OpenExternalEditor(None),
);

View file

@ -357,16 +357,16 @@ impl Component for DetailsComponent {
fn event(&mut self, event: Event) -> Result<EventState> {
if self.focused {
if let Event::Key(e) = event {
return Ok(if e == self.key_config.move_up {
return Ok(if e == self.key_config.keys.move_up {
self.move_scroll_top(ScrollType::Up).into()
} else if e == self.key_config.move_down {
} else if e == self.key_config.keys.move_down {
self.move_scroll_top(ScrollType::Down).into()
} else if e == self.key_config.home
|| e == self.key_config.shift_up
} else if e == self.key_config.keys.home
|| e == self.key_config.keys.shift_up
{
self.move_scroll_top(ScrollType::Home).into()
} else if e == self.key_config.end
|| e == self.key_config.shift_down
} else if e == self.key_config.keys.end
|| e == self.key_config.keys.shift_down
{
self.move_scroll_top(ScrollType::End).into()
} else {

View file

@ -214,13 +214,13 @@ impl Component for CommitDetailsComponent {
if self.focused() {
if let Event::Key(e) = ev {
return if e == self.key_config.focus_below
return if e == self.key_config.keys.focus_below
&& self.details_focused()
{
self.set_details_focus(false);
self.file_tree.focus(true);
Ok(EventState::Consumed)
} else if e == self.key_config.focus_above
} else if e == self.key_config.keys.focus_above
&& self.file_tree.focused()
&& !self.is_compare()
{

View file

@ -423,28 +423,29 @@ impl DrawableComponent for CommitList {
impl Component for CommitList {
fn event(&mut self, ev: Event) -> Result<EventState> {
if let Event::Key(k) = ev {
let selection_changed = if k == self.key_config.move_up {
self.move_selection(ScrollType::Up)?
} else if k == self.key_config.move_down {
self.move_selection(ScrollType::Down)?
} else if k == self.key_config.shift_up
|| k == self.key_config.home
{
self.move_selection(ScrollType::Home)?
} else if k == self.key_config.shift_down
|| k == self.key_config.end
{
self.move_selection(ScrollType::End)?
} else if k == self.key_config.page_up {
self.move_selection(ScrollType::PageUp)?
} else if k == self.key_config.page_down {
self.move_selection(ScrollType::PageDown)?
} else if k == self.key_config.log_mark_commit {
self.mark();
true
} else {
false
};
let selection_changed =
if k == self.key_config.keys.move_up {
self.move_selection(ScrollType::Up)?
} else if k == self.key_config.keys.move_down {
self.move_selection(ScrollType::Down)?
} else if k == self.key_config.keys.shift_up
|| k == self.key_config.keys.home
{
self.move_selection(ScrollType::Home)?
} else if k == self.key_config.keys.shift_down
|| k == self.key_config.keys.end
{
self.move_selection(ScrollType::End)?
} else if k == self.key_config.keys.page_up {
self.move_selection(ScrollType::PageUp)?
} else if k == self.key_config.keys.page_down {
self.move_selection(ScrollType::PageDown)?
} else if k == self.key_config.keys.log_mark_commit {
self.mark();
true
} else {
false
};
return Ok(selection_changed.into());
}

View file

@ -112,19 +112,19 @@ impl Component for CompareCommitsComponent {
}
if let Event::Key(e) = ev {
if e == self.key_config.exit_popup {
if e == self.key_config.keys.exit_popup {
self.hide();
} else if e == self.key_config.focus_right
} else if e == self.key_config.keys.focus_right
&& self.can_focus_diff()
{
self.details.focus(false);
self.diff.focus(true);
} else if e == self.key_config.focus_left
} else if e == self.key_config.keys.focus_left
&& self.diff.focused()
{
self.details.focus(true);
self.diff.focus(false);
} else if e == self.key_config.focus_left {
} else if e == self.key_config.keys.focus_left {
self.hide();
}

View file

@ -67,7 +67,7 @@ impl Component for CreateBranchComponent {
}
if let Event::Key(e) = ev {
if e == self.key_config.enter {
if e == self.key_config.keys.enter {
self.create_branch();
}

View file

@ -105,7 +105,7 @@ impl Component for CredComponent {
fn event(&mut self, ev: Event) -> Result<EventState> {
if self.visible {
if let Event::Key(e) = ev {
if e == self.key_config.exit_popup {
if e == self.key_config.keys.exit_popup {
self.hide();
return Ok(EventState::Consumed);
}
@ -113,7 +113,7 @@ impl Component for CredComponent {
|| self.input_password.event(ev)?.is_consumed()
{
return Ok(EventState::Consumed);
} else if e == self.key_config.enter {
} else if e == self.key_config.keys.enter {
if self.input_username.is_visible() {
self.cred = BasicAuthCredential::new(
Some(

View file

@ -714,31 +714,31 @@ impl Component for DiffComponent {
fn event(&mut self, ev: Event) -> Result<EventState> {
if self.focused {
if let Event::Key(e) = ev {
return if e == self.key_config.move_down {
return if e == self.key_config.keys.move_down {
self.move_selection(ScrollType::Down);
Ok(EventState::Consumed)
} else if e == self.key_config.shift_down {
} else if e == self.key_config.keys.shift_down {
self.modify_selection(Direction::Down);
Ok(EventState::Consumed)
} else if e == self.key_config.shift_up {
} else if e == self.key_config.keys.shift_up {
self.modify_selection(Direction::Up);
Ok(EventState::Consumed)
} else if e == self.key_config.end {
} else if e == self.key_config.keys.end {
self.move_selection(ScrollType::End);
Ok(EventState::Consumed)
} else if e == self.key_config.home {
} else if e == self.key_config.keys.home {
self.move_selection(ScrollType::Home);
Ok(EventState::Consumed)
} else if e == self.key_config.move_up {
} else if e == self.key_config.keys.move_up {
self.move_selection(ScrollType::Up);
Ok(EventState::Consumed)
} else if e == self.key_config.page_up {
} else if e == self.key_config.keys.page_up {
self.move_selection(ScrollType::PageUp);
Ok(EventState::Consumed)
} else if e == self.key_config.page_down {
} else if e == self.key_config.keys.page_down {
self.move_selection(ScrollType::PageDown);
Ok(EventState::Consumed)
} else if e == self.key_config.stage_unstage_item
} else if e == self.key_config.keys.stage_unstage_item
&& !self.is_immutable
{
try_or_popup!(
@ -748,7 +748,7 @@ impl Component for DiffComponent {
);
Ok(EventState::Consumed)
} else if e == self.key_config.status_reset_item
} else if e == self.key_config.keys.status_reset_item
&& !self.is_immutable
&& !self.is_stage()
{
@ -760,12 +760,12 @@ impl Component for DiffComponent {
}
}
Ok(EventState::Consumed)
} else if e == self.key_config.diff_stage_lines
} else if e == self.key_config.keys.diff_stage_lines
&& !self.is_immutable
{
self.stage_lines();
Ok(EventState::Consumed)
} else if e == self.key_config.diff_reset_lines
} else if e == self.key_config.keys.diff_reset_lines
&& !self.is_immutable
&& !self.is_stage()
{
@ -776,7 +776,7 @@ impl Component for DiffComponent {
}
}
Ok(EventState::Consumed)
} else if e == self.key_config.copy {
} else if e == self.key_config.keys.copy {
self.copy_selection();
Ok(EventState::Consumed)
} else {

View file

@ -298,13 +298,13 @@ impl Component for FileFindPopup {
) -> Result<EventState> {
if self.is_visible() {
if let Event::Key(key) = &event {
if *key == self.key_config.exit_popup
|| *key == self.key_config.enter
if *key == self.key_config.keys.exit_popup
|| *key == self.key_config.keys.enter
{
self.hide();
} else if *key == self.key_config.move_down {
} else if *key == self.key_config.keys.move_down {
self.move_selection(ScrollType::Down);
} else if *key == self.key_config.move_up {
} else if *key == self.key_config.keys.move_up {
self.move_selection(ScrollType::Up);
}
}

View file

@ -406,7 +406,7 @@ impl Component for FileTreeComponent {
fn event(&mut self, ev: Event) -> Result<EventState> {
if self.focused {
if let Event::Key(e) = ev {
return if e == self.key_config.blame {
return if e == self.key_config.keys.blame {
match (&self.queue, self.selection_file()) {
(Some(queue), Some(status_item)) => {
queue.push(InternalEvent::BlameFile(
@ -417,27 +417,27 @@ impl Component for FileTreeComponent {
}
_ => Ok(EventState::NotConsumed),
}
} else if e == self.key_config.move_down {
} else if e == self.key_config.keys.move_down {
Ok(self
.move_selection(MoveSelection::Down)
.into())
} else if e == self.key_config.move_up {
} else if e == self.key_config.keys.move_up {
Ok(self.move_selection(MoveSelection::Up).into())
} else if e == self.key_config.home
|| e == self.key_config.shift_up
} else if e == self.key_config.keys.home
|| e == self.key_config.keys.shift_up
{
Ok(self
.move_selection(MoveSelection::Home)
.into())
} else if e == self.key_config.end
|| e == self.key_config.shift_down
} else if e == self.key_config.keys.end
|| e == self.key_config.keys.shift_down
{
Ok(self.move_selection(MoveSelection::End).into())
} else if e == self.key_config.move_left {
} else if e == self.key_config.keys.move_left {
Ok(self
.move_selection(MoveSelection::Left)
.into())
} else if e == self.key_config.move_right {
} else if e == self.key_config.keys.move_right {
Ok(self
.move_selection(MoveSelection::Right)
.into())

View file

@ -124,11 +124,11 @@ impl Component for HelpComponent {
fn event(&mut self, ev: Event) -> Result<EventState> {
if self.visible {
if let Event::Key(e) = ev {
if e == self.key_config.exit_popup {
if e == self.key_config.keys.exit_popup {
self.hide();
} else if e == self.key_config.move_down {
} else if e == self.key_config.keys.move_down {
self.move_selection(true);
} else if e == self.key_config.move_up {
} else if e == self.key_config.keys.move_up {
self.move_selection(false);
} else {
}
@ -136,7 +136,7 @@ impl Component for HelpComponent {
Ok(EventState::Consumed)
} else if let Event::Key(k) = ev {
if k == self.key_config.open_help {
if k == self.key_config.keys.open_help {
self.show()?;
Ok(EventState::Consumed)
} else {

View file

@ -125,26 +125,26 @@ impl Component for InspectCommitComponent {
}
if let Event::Key(e) = ev {
if e == self.key_config.exit_popup {
if e == self.key_config.keys.exit_popup {
self.hide();
} else if e == self.key_config.focus_right
} else if e == self.key_config.keys.focus_right
&& self.can_focus_diff()
{
self.details.focus(false);
self.diff.focus(true);
} else if e == self.key_config.focus_left
} else if e == self.key_config.keys.focus_left
&& self.diff.focused()
{
self.details.focus(true);
self.diff.focus(false);
} else if e == self.key_config.open_file_tree {
} else if e == self.key_config.keys.open_file_tree {
if let Some(commit) = self.commit_id {
self.queue.push(InternalEvent::OpenFileTree(
commit,
));
self.hide();
}
} else if e == self.key_config.focus_left {
} else if e == self.key_config.keys.focus_left {
self.hide();
}

View file

@ -92,7 +92,7 @@ impl Component for MsgComponent {
fn event(&mut self, ev: Event) -> Result<EventState> {
if self.visible {
if let Event::Key(e) = ev {
if e == self.key_config.enter {
if e == self.key_config.keys.enter {
self.hide();
}
}

View file

@ -344,15 +344,15 @@ impl Component for OptionsPopupComponent {
) -> Result<EventState> {
if self.is_visible() {
if let Event::Key(key) = &event {
if *key == self.key_config.exit_popup {
if *key == self.key_config.keys.exit_popup {
self.hide();
} else if *key == self.key_config.move_up {
} else if *key == self.key_config.keys.move_up {
self.move_selection(true);
} else if *key == self.key_config.move_down {
} else if *key == self.key_config.keys.move_down {
self.move_selection(false);
} else if *key == self.key_config.move_right {
} else if *key == self.key_config.keys.move_right {
self.switch_option(true);
} else if *key == self.key_config.move_left {
} else if *key == self.key_config.keys.move_left {
self.switch_option(false);
}
}

View file

@ -304,7 +304,7 @@ impl Component for PushComponent {
)?;
self.input_cred.hide();
}
} else if e == self.key_config.exit_popup
} else if e == self.key_config.keys.exit_popup
&& !self.pending
{
self.hide();

View file

@ -234,7 +234,7 @@ impl Component for PushTagsComponent {
))?;
self.input_cred.hide();
}
} else if e == self.key_config.exit_popup
} else if e == self.key_config.keys.exit_popup
&& !self.pending
{
self.hide();

View file

@ -64,7 +64,7 @@ impl Component for RenameBranchComponent {
}
if let Event::Key(e) = ev {
if e == self.key_config.enter {
if e == self.key_config.keys.enter {
self.rename_branch();
}

View file

@ -73,9 +73,9 @@ impl Component for ConfirmComponent {
fn event(&mut self, ev: Event) -> Result<EventState> {
if self.visible {
if let Event::Key(e) = ev {
if e == self.key_config.exit_popup {
if e == self.key_config.keys.exit_popup {
self.hide();
} else if e == self.key_config.enter {
} else if e == self.key_config.keys.enter {
self.confirm();
}

View file

@ -290,26 +290,26 @@ impl Component for RevisionFilesComponent {
{
self.selection_changed();
return Ok(EventState::Consumed);
} else if key == self.key_config.blame {
} else if key == self.key_config.keys.blame {
if self.blame() {
self.hide();
return Ok(EventState::Consumed);
}
} else if key == self.key_config.move_right {
} else if key == self.key_config.keys.move_right {
if is_tree_focused {
self.focus = Focus::File;
self.current_file.focus(true);
self.focus(true);
return Ok(EventState::Consumed);
}
} else if key == self.key_config.move_left {
} else if key == self.key_config.keys.move_left {
if !is_tree_focused {
self.focus = Focus::Tree;
self.current_file.focus(false);
self.focus(false);
return Ok(EventState::Consumed);
}
} else if key == self.key_config.file_find {
} else if key == self.key_config.keys.file_find {
if is_tree_focused {
self.open_finder();
return Ok(EventState::Consumed);
@ -347,10 +347,10 @@ fn tree_nav(
) -> bool {
if let Some(common_nav) = common_nav(key, key_config) {
tree.move_selection(common_nav)
} else if key == key_config.tree_collapse_recursive {
} else if key == key_config.keys.tree_collapse_recursive {
tree.collapse_recursive();
true
} else if key == key_config.tree_expand_recursive {
} else if key == key_config.keys.tree_expand_recursive {
tree.expand_recursive();
true
} else {

View file

@ -111,7 +111,7 @@ impl Component for RevisionFilesPopup {
) -> Result<EventState> {
if self.is_visible() {
if let Event::Key(key) = &event {
if *key == self.key_config.exit_popup {
if *key == self.key_config.keys.exit_popup {
self.hide();
}
}

View file

@ -62,7 +62,7 @@ impl Component for StashMsgComponent {
}
if let Event::Key(e) = ev {
if e == self.key_config.enter {
if e == self.key_config.keys.enter {
match sync::stash_save(
CWD,
if self.input.get_text().is_empty() {

View file

@ -64,7 +64,7 @@ impl Component for TagCommitComponent {
}
if let Event::Key(e) = ev {
if e == self.key_config.enter {
if e == self.key_config.keys.enter {
self.tag();
}

View file

@ -177,25 +177,25 @@ impl Component for TagListComponent {
fn event(&mut self, event: Event) -> Result<EventState> {
if self.visible {
if let Event::Key(key) = event {
if key == self.key_config.exit_popup {
if key == self.key_config.keys.exit_popup {
self.hide();
} else if key == self.key_config.move_up {
} else if key == self.key_config.keys.move_up {
self.move_selection(ScrollType::Up);
} else if key == self.key_config.move_down {
} else if key == self.key_config.keys.move_down {
self.move_selection(ScrollType::Down);
} else if key == self.key_config.shift_up
|| key == self.key_config.home
} else if key == self.key_config.keys.shift_up
|| key == self.key_config.keys.home
{
self.move_selection(ScrollType::Home);
} else if key == self.key_config.shift_down
|| key == self.key_config.end
} else if key == self.key_config.keys.shift_down
|| key == self.key_config.keys.end
{
self.move_selection(ScrollType::End);
} else if key == self.key_config.page_down {
} else if key == self.key_config.keys.page_down {
self.move_selection(ScrollType::PageDown);
} else if key == self.key_config.page_up {
} else if key == self.key_config.keys.page_up {
self.move_selection(ScrollType::PageUp);
} else if key == self.key_config.delete_tag {
} else if key == self.key_config.keys.delete_tag {
return self.selected_tag().map_or(
Ok(EventState::NotConsumed),
|tag| {
@ -209,7 +209,7 @@ impl Component for TagListComponent {
Ok(EventState::Consumed)
},
);
} else if key == self.key_config.select_tag {
} else if key == self.key_config.keys.select_tag {
return self.selected_tag().map_or(
Ok(EventState::NotConsumed),
|tag| {
@ -221,7 +221,7 @@ impl Component for TagListComponent {
Ok(EventState::Consumed)
},
);
} else if key == self.key_config.push {
} else if key == self.key_config.keys.push {
self.queue.push(InternalEvent::PushTags);
}
}

View file

@ -346,7 +346,7 @@ impl Component for TextInputComponent {
fn event(&mut self, ev: Event) -> Result<EventState> {
if self.visible {
if let Event::Key(e) = ev {
if e == self.key_config.exit_popup {
if e == self.key_config.keys.exit_popup {
self.hide();
return Ok(EventState::Consumed);
}

149
src/keys/key_config.rs Normal file
View file

@ -0,0 +1,149 @@
use anyhow::Result;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use std::{fs, path::PathBuf, rc::Rc};
use crate::{args::get_app_config_path, strings::symbol};
use super::{key_list::KeysList, symbols::KeySymbols};
pub type SharedKeyConfig = Rc<KeyConfig>;
#[derive(Default)]
pub struct KeyConfig {
pub keys: KeysList,
symbols: KeySymbols,
}
impl KeyConfig {
fn get_config_file() -> Result<PathBuf> {
let app_home = get_app_config_path()?;
Ok(app_home.join("key_config.ron"))
}
fn get_symbols_file() -> Result<PathBuf> {
let app_home = get_app_config_path()?;
Ok(app_home.join("key_symbols.ron"))
}
fn init_keys() -> Result<KeysList> {
let file = Self::get_config_file()?;
if file.exists() {
match KeysList::read_file(file.clone()) {
Err(e) => {
let config_path = file.clone();
let config_path_old =
format!("{}.old", file.to_string_lossy());
fs::rename(
config_path.clone(),
config_path_old.clone(),
)?;
KeysList::default().save(file)?;
Err(anyhow::anyhow!("{}\n Old file was renamed to {:?}.\n Defaults loaded and saved as {:?}",
e,config_path_old,config_path.to_string_lossy()))
}
Ok(keys) => Ok(keys),
}
} else {
KeysList::default().save(file)?;
Ok(KeysList::default())
}
}
pub fn init() -> Result<Self> {
let keys = Self::init_keys()?;
let symbols = KeySymbols::init(Self::get_symbols_file()?);
Ok(Self { keys, symbols })
}
fn get_key_symbol(&self, k: KeyCode) -> &str {
match k {
KeyCode::Enter => &self.symbols.enter,
KeyCode::Left => &self.symbols.left,
KeyCode::Right => &self.symbols.right,
KeyCode::Up => &self.symbols.up,
KeyCode::Down => &self.symbols.down,
KeyCode::Backspace => &self.symbols.backspace,
KeyCode::Home => &self.symbols.home,
KeyCode::End => &self.symbols.end,
KeyCode::PageUp => &self.symbols.page_up,
KeyCode::PageDown => &self.symbols.page_down,
KeyCode::Tab => &self.symbols.tab,
KeyCode::BackTab => &self.symbols.back_tab,
KeyCode::Delete => &self.symbols.delete,
KeyCode::Insert => &self.symbols.insert,
KeyCode::Esc => &self.symbols.esc,
_ => "?",
}
}
pub fn get_hint(&self, ev: KeyEvent) -> String {
match ev.code {
KeyCode::Down
| KeyCode::Up
| KeyCode::Right
| KeyCode::Left
| KeyCode::Enter
| KeyCode::Backspace
| KeyCode::Home
| KeyCode::End
| KeyCode::PageUp
| KeyCode::PageDown
| KeyCode::Tab
| KeyCode::BackTab
| KeyCode::Delete
| KeyCode::Insert
| KeyCode::Esc => {
format!(
"{}{}",
self.get_modifier_hint(ev.modifiers),
self.get_key_symbol(ev.code)
)
}
KeyCode::Char(' ') => String::from(symbol::SPACE),
KeyCode::Char(c) => {
format!(
"{}{}",
self.get_modifier_hint(ev.modifiers),
c
)
}
KeyCode::F(u) => {
format!(
"{}F{}",
self.get_modifier_hint(ev.modifiers),
u
)
}
KeyCode::Null => {
self.get_modifier_hint(ev.modifiers).into()
}
}
}
fn get_modifier_hint(&self, modifier: KeyModifiers) -> &str {
match modifier {
KeyModifiers::CONTROL => &self.symbols.control,
KeyModifiers::SHIFT => &self.symbols.shift,
KeyModifiers::ALT => &self.symbols.alt,
_ => "",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
#[test]
fn test_get_hint() {
let config = KeyConfig::default();
let h = config.get_hint(KeyEvent {
code: KeyCode::Char('c'),
modifiers: KeyModifiers::CONTROL,
});
assert_eq!(h, "^c");
}
}

View file

@ -1,6 +1,3 @@
//TODO: remove once fixed https://github.com/rust-lang/rust-clippy/issues/6818
#![allow(clippy::use_self)]
use anyhow::Result;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use ron::{
@ -9,18 +6,13 @@ use ron::{
};
use serde::{Deserialize, Serialize};
use std::{
fs::{self, File},
fs::File,
io::{Read, Write},
path::PathBuf,
rc::Rc,
};
use crate::{args::get_app_config_path, strings::symbol};
pub type SharedKeyConfig = Rc<KeyConfig>;
#[derive(Serialize, Deserialize, Debug)]
pub struct KeyConfig {
pub struct KeysList {
pub tab_status: KeyEvent,
pub tab_log: KeyEvent,
pub tab_files: KeyEvent,
@ -92,7 +84,7 @@ pub struct KeyConfig {
}
#[rustfmt::skip]
impl Default for KeyConfig {
impl Default for KeysList {
fn default() -> Self {
Self {
tab_status: KeyEvent { code: KeyCode::Char('1'), modifiers: KeyModifiers::empty()},
@ -167,150 +159,30 @@ impl Default for KeyConfig {
}
}
impl KeyConfig {
fn save(&self, file: PathBuf) -> Result<()> {
impl KeysList {
pub fn save(&self, file: PathBuf) -> Result<()> {
let mut file = File::create(file)?;
let data = to_string_pretty(self, PrettyConfig::default())?;
file.write_all(data.as_bytes())?;
Ok(())
}
pub fn get_config_file() -> Result<PathBuf> {
let app_home = get_app_config_path()?;
Ok(app_home.join("key_config.ron"))
}
fn read_file(config_file: PathBuf) -> Result<Self> {
pub fn read_file(config_file: PathBuf) -> Result<Self> {
let mut f = File::open(config_file)?;
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
Ok(ron::de::from_bytes(&buffer)?)
}
pub fn init(file: PathBuf) -> Result<Self> {
if file.exists() {
match Self::read_file(file.clone()) {
Err(e) => {
let config_path = file.clone();
let config_path_old =
format!("{}.old", file.to_string_lossy());
fs::rename(
config_path.clone(),
config_path_old.clone(),
)?;
Self::default().save(file)?;
Err(anyhow::anyhow!("{}\n Old file was renamed to {:?}.\n Defaults loaded and saved as {:?}",
e,config_path_old,config_path.to_string_lossy()))
}
Ok(res) => Ok(res),
}
} else {
Self::default().save(file)?;
Ok(Self::default())
}
}
//TODO: make this configurable (https://github.com/extrawurst/gitui/issues/465)
#[allow(clippy::unused_self)]
const fn get_key_symbol(&self, k: KeyCode) -> &str {
match k {
KeyCode::Enter => "\u{23ce}", //⏎
KeyCode::Left => "\u{2190}", //←
KeyCode::Right => "\u{2192}", //→
KeyCode::Up => "\u{2191}", //↑
KeyCode::Down => "\u{2193}", //↓
KeyCode::Backspace => "\u{232b}", //⌫
KeyCode::Home => "\u{2912}", //⤒
KeyCode::End => "\u{2913}", //⤓
KeyCode::PageUp => "\u{21de}", //⇞
KeyCode::PageDown => "\u{21df}", //⇟
KeyCode::Tab => "\u{21e5}", //⇥
KeyCode::BackTab => "\u{21e4}", //⇤
KeyCode::Delete => "\u{2326}", //⌦
KeyCode::Insert => "\u{2380}", //⎀
KeyCode::Esc => "\u{238b}", //⎋
_ => "?",
}
}
pub fn get_hint(&self, ev: KeyEvent) -> String {
match ev.code {
KeyCode::Down
| KeyCode::Up
| KeyCode::Right
| KeyCode::Left
| KeyCode::Enter
| KeyCode::Backspace
| KeyCode::Home
| KeyCode::End
| KeyCode::PageUp
| KeyCode::PageDown
| KeyCode::Tab
| KeyCode::BackTab
| KeyCode::Delete
| KeyCode::Insert
| KeyCode::Esc => {
format!(
"{}{}",
Self::get_modifier_hint(ev.modifiers),
self.get_key_symbol(ev.code)
)
}
KeyCode::Char(' ') => String::from(symbol::SPACE),
KeyCode::Char(c) => {
format!(
"{}{}",
Self::get_modifier_hint(ev.modifiers),
c
)
}
KeyCode::F(u) => {
format!(
"{}F{}",
Self::get_modifier_hint(ev.modifiers),
u
)
}
KeyCode::Null => Self::get_modifier_hint(ev.modifiers),
}
}
//TODO: make customizable (see https://github.com/extrawurst/gitui/issues/465)
fn get_modifier_hint(modifier: KeyModifiers) -> String {
match modifier {
KeyModifiers::CONTROL => "^".to_string(),
KeyModifiers::SHIFT => {
"\u{21e7}".to_string() //⇧
}
KeyModifiers::ALT => {
"\u{2325}".to_string() //⌥
}
_ => String::new(),
}
}
}
#[cfg(test)]
mod tests {
use super::KeyConfig;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
#[test]
fn test_get_hint() {
let config = KeyConfig::default();
let h = config.get_hint(KeyEvent {
code: KeyCode::Char('c'),
modifiers: KeyModifiers::CONTROL,
});
assert_eq!(h, "^c");
}
use super::*;
#[test]
fn test_load_vim_style_example() {
assert_eq!(
KeyConfig::read_file("vim_style_key_config.ron".into())
KeysList::read_file("vim_style_key_config.ron".into())
.is_ok(),
true
);

5
src/keys/mod.rs Normal file
View file

@ -0,0 +1,5 @@
mod key_config;
mod key_list;
mod symbols;
pub use key_config::{KeyConfig, SharedKeyConfig};

121
src/keys/symbols.rs Normal file
View file

@ -0,0 +1,121 @@
use std::{fs::File, io::Read, path::PathBuf};
use anyhow::Result;
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct KeySymbols {
pub enter: String,
pub left: String,
pub right: String,
pub up: String,
pub down: String,
pub backspace: String,
pub home: String,
pub end: String,
pub page_up: String,
pub page_down: String,
pub tab: String,
pub back_tab: String,
pub delete: String,
pub insert: String,
pub esc: String,
pub control: String,
pub shift: String,
pub alt: String,
}
#[rustfmt::skip]
impl Default for KeySymbols {
fn default() -> Self {
Self {
enter: "\u{23ce}".into(), //⏎
left: "\u{2190}".into(), //←
right: "\u{2192}".into(), //→
up: "\u{2191}".into(), //↑
down: "\u{2193}".into(), //↓
backspace: "\u{232b}".into(), //⌫
home: "\u{2912}".into(), //⤒
end: "\u{2913}".into(), //⤓
page_up: "\u{21de}".into(), //⇞
page_down: "\u{21df}".into(), //⇟
tab: "\u{21e5}".into(), //⇥
back_tab: "\u{21e4}".into(), //⇤
delete: "\u{2326}".into(), //⌦
insert: "\u{2380}".into(), //⎀
esc: "\u{238b}".into(), //⎋
control: "^".into(),
shift: "\u{21e7}".into(), //⇧
alt: "\u{2325}".into(), //⌥
}
}
}
impl KeySymbols {
pub fn init(file: PathBuf) -> Self {
if file.exists() {
let file =
KeySymbolsFile::read_file(file).unwrap_or_default();
file.get_symbols()
} else {
Self::default()
}
}
}
//TODO: this could auto generated in a proc macro
#[derive(Serialize, Deserialize, Default)]
pub struct KeySymbolsFile {
pub enter: Option<String>,
pub left: Option<String>,
pub right: Option<String>,
pub up: Option<String>,
pub down: Option<String>,
pub backspace: Option<String>,
pub home: Option<String>,
pub end: Option<String>,
pub page_up: Option<String>,
pub page_down: Option<String>,
pub tab: Option<String>,
pub back_tab: Option<String>,
pub delete: Option<String>,
pub insert: Option<String>,
pub esc: Option<String>,
pub control: Option<String>,
pub shift: Option<String>,
pub alt: Option<String>,
}
impl KeySymbolsFile {
fn read_file(config_file: PathBuf) -> Result<Self> {
let mut f = File::open(config_file)?;
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
Ok(ron::de::from_bytes(&buffer)?)
}
pub fn get_symbols(self) -> KeySymbols {
let default = KeySymbols::default();
KeySymbols {
enter: self.enter.unwrap_or(default.enter),
left: self.left.unwrap_or(default.left),
right: self.right.unwrap_or(default.right),
up: self.up.unwrap_or(default.up),
down: self.down.unwrap_or(default.down),
backspace: self.backspace.unwrap_or(default.backspace),
home: self.home.unwrap_or(default.home),
end: self.end.unwrap_or(default.end),
page_up: self.page_up.unwrap_or(default.page_up),
page_down: self.page_down.unwrap_or(default.page_down),
tab: self.tab.unwrap_or(default.tab),
back_tab: self.back_tab.unwrap_or(default.back_tab),
delete: self.delete.unwrap_or(default.delete),
insert: self.insert.unwrap_or(default.insert),
esc: self.esc.unwrap_or(default.esc),
control: self.control.unwrap_or(default.control),
shift: self.shift.unwrap_or(default.shift),
alt: self.alt.unwrap_or(default.alt),
}
}
}

View file

@ -109,7 +109,7 @@ fn main() -> Result<()> {
return Ok(());
}
let key_config = KeyConfig::init(KeyConfig::get_config_file()?)
let key_config = KeyConfig::init()
.map_err(|e| eprintln!("KeyConfig loading error: {}", e))
.unwrap_or_default();
let theme = Theme::init(cliargs.theme)

View file

@ -48,24 +48,30 @@ pub fn title_index(_key_config: &SharedKeyConfig) -> String {
"Staged Changes".to_string()
}
pub fn tab_status(key_config: &SharedKeyConfig) -> String {
format!("Status [{}]", key_config.get_hint(key_config.tab_status))
format!(
"Status [{}]",
key_config.get_hint(key_config.keys.tab_status)
)
}
pub fn tab_log(key_config: &SharedKeyConfig) -> String {
format!("Log [{}]", key_config.get_hint(key_config.tab_log))
format!("Log [{}]", key_config.get_hint(key_config.keys.tab_log))
}
pub fn tab_files(key_config: &SharedKeyConfig) -> String {
format!("Files [{}]", key_config.get_hint(key_config.tab_files))
format!(
"Files [{}]",
key_config.get_hint(key_config.keys.tab_files)
)
}
pub fn tab_stashing(key_config: &SharedKeyConfig) -> String {
format!(
"Stashing [{}]",
key_config.get_hint(key_config.tab_stashing)
key_config.get_hint(key_config.keys.tab_stashing)
)
}
pub fn tab_stashes(key_config: &SharedKeyConfig) -> String {
format!(
"Stashes [{}]",
key_config.get_hint(key_config.tab_stashes)
key_config.get_hint(key_config.keys.tab_stashes)
)
}
pub fn tab_divider(_key_config: &SharedKeyConfig) -> String {
@ -310,6 +316,7 @@ pub fn rename_branch_popup_msg(
pub mod commit {
use crate::keys::SharedKeyConfig;
pub fn details_author() -> String {
"Author: ".to_string()
}
@ -368,7 +375,7 @@ pub mod commands {
CommandText::new(
format!(
"Next [{}]",
key_config.get_hint(key_config.tab_toggle)
key_config.get_hint(key_config.keys.tab_toggle)
),
"switch to next tab",
CMD_GROUP_GENERAL,
@ -378,7 +385,7 @@ pub mod commands {
CommandText::new(
format!(
"Find [{}]",
key_config.get_hint(key_config.file_find)
key_config.get_hint(key_config.keys.file_find)
),
"find file in tree",
CMD_GROUP_GENERAL,
@ -390,11 +397,11 @@ pub mod commands {
CommandText::new(
format!(
"Tab [{}{}{}{}{}]",
key_config.get_hint(key_config.tab_status),
key_config.get_hint(key_config.tab_log),
key_config.get_hint(key_config.tab_files),
key_config.get_hint(key_config.tab_stashing),
key_config.get_hint(key_config.tab_stashes),
key_config.get_hint(key_config.keys.tab_status),
key_config.get_hint(key_config.keys.tab_log),
key_config.get_hint(key_config.keys.tab_files),
key_config.get_hint(key_config.keys.tab_stashing),
key_config.get_hint(key_config.keys.tab_stashes),
),
"switch top level tabs directly",
CMD_GROUP_GENERAL,
@ -406,7 +413,7 @@ pub mod commands {
CommandText::new(
format!(
"Options [{}]",
key_config.get_hint(key_config.open_options),
key_config.get_hint(key_config.keys.open_options),
),
"open options popup",
CMD_GROUP_GENERAL,
@ -416,7 +423,7 @@ pub mod commands {
CommandText::new(
format!(
"Help [{}]",
key_config.get_hint(key_config.open_help)
key_config.get_hint(key_config.keys.open_help)
),
"open this help screen",
CMD_GROUP_GENERAL,
@ -428,8 +435,8 @@ pub mod commands {
CommandText::new(
format!(
"Nav [{}{}]",
key_config.get_hint(key_config.move_up),
key_config.get_hint(key_config.move_down)
key_config.get_hint(key_config.keys.move_up),
key_config.get_hint(key_config.keys.move_down)
),
"navigate commit message",
CMD_GROUP_GENERAL,
@ -441,10 +448,10 @@ pub mod commands {
CommandText::new(
format!(
"Nav [{}{}{}{}]",
key_config.get_hint(key_config.move_up),
key_config.get_hint(key_config.move_down),
key_config.get_hint(key_config.move_right),
key_config.get_hint(key_config.move_left)
key_config.get_hint(key_config.keys.move_up),
key_config.get_hint(key_config.keys.move_down),
key_config.get_hint(key_config.keys.move_right),
key_config.get_hint(key_config.keys.move_left)
),
"navigate tree view, collapse, expand",
CMD_GROUP_GENERAL,
@ -454,8 +461,8 @@ pub mod commands {
CommandText::new(
format!(
"Scroll [{}{}]",
key_config.get_hint(key_config.focus_above),
key_config.get_hint(key_config.focus_below)
key_config.get_hint(key_config.keys.focus_above),
key_config.get_hint(key_config.keys.focus_below)
),
"scroll up or down in focused view",
CMD_GROUP_GENERAL,
@ -469,7 +476,7 @@ pub mod commands {
format!(
"{} [{}]",
if marked { "Unmark" } else { "Mark" },
key_config.get_hint(key_config.log_mark_commit),
key_config.get_hint(key_config.keys.log_mark_commit),
),
"mark multiple commits",
CMD_GROUP_GENERAL,
@ -479,7 +486,7 @@ pub mod commands {
CommandText::new(
format!(
"Copy [{}]",
key_config.get_hint(key_config.copy),
key_config.get_hint(key_config.keys.copy),
),
"copy selected lines to clipboard",
CMD_GROUP_DIFF,
@ -489,7 +496,7 @@ pub mod commands {
CommandText::new(
format!(
"Copy Hash [{}]",
key_config.get_hint(key_config.copy),
key_config.get_hint(key_config.keys.copy),
),
"copy selected commit hash to clipboard",
CMD_GROUP_LOG,
@ -499,7 +506,7 @@ pub mod commands {
CommandText::new(
format!(
"Push Tags [{}]",
key_config.get_hint(key_config.push),
key_config.get_hint(key_config.keys.push),
),
"push tags to remote",
CMD_GROUP_LOG,
@ -511,10 +518,10 @@ pub mod commands {
CommandText::new(
format!(
"Jump up/down [{},{},{},{}]",
key_config.get_hint(key_config.home),
key_config.get_hint(key_config.end),
key_config.get_hint(key_config.move_up),
key_config.get_hint(key_config.move_down)
key_config.get_hint(key_config.keys.home),
key_config.get_hint(key_config.keys.end),
key_config.get_hint(key_config.keys.move_up),
key_config.get_hint(key_config.keys.move_down)
),
"scroll to top or bottom of diff",
CMD_GROUP_DIFF,
@ -526,7 +533,8 @@ pub mod commands {
CommandText::new(
format!(
"Add hunk [{}]",
key_config.get_hint(key_config.stage_unstage_item),
key_config
.get_hint(key_config.keys.stage_unstage_item),
),
"adds selected hunk to stage",
CMD_GROUP_DIFF,
@ -538,7 +546,8 @@ pub mod commands {
CommandText::new(
format!(
"Reset hunk [{}]",
key_config.get_hint(key_config.status_reset_item),
key_config
.get_hint(key_config.keys.status_reset_item),
),
"reverts selected hunk",
CMD_GROUP_DIFF,
@ -550,7 +559,7 @@ pub mod commands {
CommandText::new(
format!(
"Reset lines [{}]",
key_config.get_hint(key_config.diff_reset_lines),
key_config.get_hint(key_config.keys.diff_reset_lines),
),
"resets selected lines",
CMD_GROUP_DIFF,
@ -562,7 +571,7 @@ pub mod commands {
CommandText::new(
format!(
"Stage lines [{}]",
key_config.get_hint(key_config.diff_stage_lines),
key_config.get_hint(key_config.keys.diff_stage_lines),
),
"stage selected lines",
CMD_GROUP_DIFF,
@ -574,7 +583,7 @@ pub mod commands {
CommandText::new(
format!(
"Unstage lines [{}]",
key_config.get_hint(key_config.diff_stage_lines),
key_config.get_hint(key_config.keys.diff_stage_lines),
),
"unstage selected lines",
CMD_GROUP_DIFF,
@ -586,7 +595,8 @@ pub mod commands {
CommandText::new(
format!(
"Remove hunk [{}]",
key_config.get_hint(key_config.stage_unstage_item),
key_config
.get_hint(key_config.keys.stage_unstage_item),
),
"removes selected hunk from stage",
CMD_GROUP_DIFF,
@ -596,7 +606,7 @@ pub mod commands {
CommandText::new(
format!(
"Close [{}]",
key_config.get_hint(key_config.exit_popup),
key_config.get_hint(key_config.keys.exit_popup),
),
"close overlay (e.g commit, help)",
CMD_GROUP_GENERAL,
@ -606,7 +616,7 @@ pub mod commands {
CommandText::new(
format!(
"Close [{}]",
key_config.get_hint(key_config.enter),
key_config.get_hint(key_config.keys.enter),
),
"close msg popup (e.g msg)",
CMD_GROUP_GENERAL,
@ -617,7 +627,7 @@ pub mod commands {
CommandText::new(
format!(
"Validate [{}]",
key_config.get_hint(key_config.enter),
key_config.get_hint(key_config.keys.enter),
),
"validate msg",
CMD_GROUP_GENERAL,
@ -629,7 +639,7 @@ pub mod commands {
CommandText::new(
format!(
"Abort merge [{}]",
key_config.get_hint(key_config.abort_merge),
key_config.get_hint(key_config.keys.abort_merge),
),
"abort ongoing merge",
CMD_GROUP_GENERAL,
@ -642,7 +652,7 @@ pub mod commands {
CommandText::new(
format!(
"Continue rebase [{}]",
key_config.get_hint(key_config.rebase_branch),
key_config.get_hint(key_config.keys.rebase_branch),
),
"continue ongoing rebase",
CMD_GROUP_GENERAL,
@ -653,7 +663,7 @@ pub mod commands {
CommandText::new(
format!(
"Abort rebase [{}]",
key_config.get_hint(key_config.abort_merge),
key_config.get_hint(key_config.keys.abort_merge),
),
"abort ongoing rebase",
CMD_GROUP_GENERAL,
@ -666,7 +676,7 @@ pub mod commands {
CommandText::new(
format!(
"To stage [{}]",
key_config.get_hint(key_config.toggle_workarea),
key_config.get_hint(key_config.keys.toggle_workarea),
),
"focus/select staging area",
CMD_GROUP_GENERAL,
@ -678,7 +688,7 @@ pub mod commands {
CommandText::new(
format!(
"To unstaged [{}]",
key_config.get_hint(key_config.toggle_workarea),
key_config.get_hint(key_config.keys.toggle_workarea),
),
"focus/select unstaged area",
CMD_GROUP_GENERAL,
@ -688,7 +698,7 @@ pub mod commands {
CommandText::new(
format!(
"Undo Commit [{}]",
key_config.get_hint(key_config.undo_commit),
key_config.get_hint(key_config.keys.undo_commit),
),
"undo last commit",
CMD_GROUP_GENERAL,
@ -698,7 +708,7 @@ pub mod commands {
CommandText::new(
format!(
"Commit [{}]",
key_config.get_hint(key_config.open_commit),
key_config.get_hint(key_config.keys.open_commit),
),
"open commit popup (available in non-empty stage)",
CMD_GROUP_COMMIT,
@ -710,7 +720,8 @@ pub mod commands {
CommandText::new(
format!(
"Open editor [{}]",
key_config.get_hint(key_config.open_commit_editor),
key_config
.get_hint(key_config.keys.open_commit_editor),
),
"open commit editor (available in commit popup)",
CMD_GROUP_COMMIT,
@ -720,7 +731,7 @@ pub mod commands {
CommandText::new(
format!(
"Commit [{}]",
key_config.get_hint(key_config.enter),
key_config.get_hint(key_config.keys.enter),
),
"commit (available when commit message is non-empty)",
CMD_GROUP_COMMIT,
@ -731,7 +742,7 @@ pub mod commands {
CommandText::new(
format!(
"Amend [{}]",
key_config.get_hint(key_config.commit_amend),
key_config.get_hint(key_config.keys.commit_amend),
),
"amend last commit (available in commit popup)",
CMD_GROUP_COMMIT,
@ -741,7 +752,7 @@ pub mod commands {
CommandText::new(
format!(
"Edit [{}]",
key_config.get_hint(key_config.edit_file),
key_config.get_hint(key_config.keys.edit_file),
),
"edit the currently selected file in an external editor",
CMD_GROUP_CHANGES,
@ -751,7 +762,8 @@ pub mod commands {
CommandText::new(
format!(
"Stage [{}]",
key_config.get_hint(key_config.stage_unstage_item),
key_config
.get_hint(key_config.keys.stage_unstage_item),
),
"stage currently selected file or entire path",
CMD_GROUP_CHANGES,
@ -761,7 +773,7 @@ pub mod commands {
CommandText::new(
format!(
"Stage All [{}]",
key_config.get_hint(key_config.status_stage_all),
key_config.get_hint(key_config.keys.status_stage_all),
),
"stage all changes (in unstaged files)",
CMD_GROUP_CHANGES,
@ -771,7 +783,8 @@ pub mod commands {
CommandText::new(
format!(
"Unstage [{}]",
key_config.get_hint(key_config.stage_unstage_item),
key_config
.get_hint(key_config.keys.stage_unstage_item),
),
"unstage currently selected file or entire path",
CMD_GROUP_CHANGES,
@ -781,7 +794,7 @@ pub mod commands {
CommandText::new(
format!(
"Unstage all [{}]",
key_config.get_hint(key_config.status_stage_all),
key_config.get_hint(key_config.keys.status_stage_all),
),
"unstage all files (in staged files)",
CMD_GROUP_CHANGES,
@ -791,7 +804,8 @@ pub mod commands {
CommandText::new(
format!(
"Reset [{}]",
key_config.get_hint(key_config.status_reset_item),
key_config
.get_hint(key_config.keys.status_reset_item),
),
"revert changes in selected file or entire path",
CMD_GROUP_CHANGES,
@ -801,7 +815,8 @@ pub mod commands {
CommandText::new(
format!(
"Ignore [{}]",
key_config.get_hint(key_config.status_ignore_file),
key_config
.get_hint(key_config.keys.status_ignore_file),
),
"Add file or path to .gitignore",
CMD_GROUP_CHANGES,
@ -814,7 +829,7 @@ pub mod commands {
CommandText::new(
format!(
"Back [{}]",
key_config.get_hint(key_config.focus_left),
key_config.get_hint(key_config.keys.focus_left),
),
"view and select changed files",
CMD_GROUP_GENERAL,
@ -826,7 +841,7 @@ pub mod commands {
CommandText::new(
format!(
"Diff [{}]",
key_config.get_hint(key_config.focus_right),
key_config.get_hint(key_config.keys.focus_right),
),
"inspect file diff",
CMD_GROUP_GENERAL,
@ -836,7 +851,7 @@ pub mod commands {
CommandText::new(
format!(
"Quit [{}]",
key_config.get_hint(key_config.exit),
key_config.get_hint(key_config.keys.exit),
),
"quit gitui application",
CMD_GROUP_GENERAL,
@ -848,7 +863,7 @@ pub mod commands {
CommandText::new(
format!(
"Confirm [{}]",
key_config.get_hint(key_config.enter),
key_config.get_hint(key_config.keys.enter),
),
"confirm action",
CMD_GROUP_GENERAL,
@ -860,7 +875,7 @@ pub mod commands {
CommandText::new(
format!(
"Save [{}]",
key_config.get_hint(key_config.stashing_save),
key_config.get_hint(key_config.keys.stashing_save),
),
"opens stash name input popup",
CMD_GROUP_STASHING,
@ -872,7 +887,8 @@ pub mod commands {
CommandText::new(
format!(
"Toggle Staged [{}]",
key_config.get_hint(key_config.stashing_toggle_index),
key_config
.get_hint(key_config.keys.stashing_toggle_index),
),
"toggle including staged files into stash",
CMD_GROUP_STASHING,
@ -884,8 +900,9 @@ pub mod commands {
CommandText::new(
format!(
"Toggle Untracked [{}]",
key_config
.get_hint(key_config.stashing_toggle_untracked),
key_config.get_hint(
key_config.keys.stashing_toggle_untracked
),
),
"toggle including untracked files into stash",
CMD_GROUP_STASHING,
@ -897,7 +914,7 @@ pub mod commands {
CommandText::new(
format!(
"Stash [{}]",
key_config.get_hint(key_config.enter),
key_config.get_hint(key_config.keys.enter),
),
"save files to stash",
CMD_GROUP_STASHING,
@ -909,7 +926,7 @@ pub mod commands {
CommandText::new(
format!(
"Apply [{}]",
key_config.get_hint(key_config.stash_apply),
key_config.get_hint(key_config.keys.stash_apply),
),
"apply selected stash",
CMD_GROUP_STASHES,
@ -927,7 +944,7 @@ pub mod commands {
} else {
format!(" {}", marked)
},
key_config.get_hint(key_config.stash_drop),
key_config.get_hint(key_config.keys.stash_drop),
),
"drop selected stash",
CMD_GROUP_STASHES,
@ -939,7 +956,7 @@ pub mod commands {
CommandText::new(
format!(
"Pop [{}]",
key_config.get_hint(key_config.enter),
key_config.get_hint(key_config.keys.enter),
),
"pop selected stash",
CMD_GROUP_STASHES,
@ -951,7 +968,7 @@ pub mod commands {
CommandText::new(
format!(
"Inspect [{}]",
key_config.get_hint(key_config.focus_right),
key_config.get_hint(key_config.keys.focus_right),
),
"open stash commit details (allows to diff files)",
CMD_GROUP_STASHES,
@ -963,7 +980,7 @@ pub mod commands {
CommandText::new(
format!(
"Details [{}]",
key_config.get_hint(key_config.enter),
key_config.get_hint(key_config.keys.enter),
),
"open details of selected commit",
CMD_GROUP_LOG,
@ -976,7 +993,7 @@ pub mod commands {
CommandText::new(
format!(
"Inspect [{}]",
key_config.get_hint(key_config.focus_right),
key_config.get_hint(key_config.keys.focus_right),
),
"inspect selected commit in detail",
CMD_GROUP_GENERAL,
@ -987,7 +1004,7 @@ pub mod commands {
CommandText::new(
format!(
"Blame [{}]",
key_config.get_hint(key_config.blame),
key_config.get_hint(key_config.keys.blame),
),
"open blame view of selected file",
CMD_GROUP_LOG,
@ -999,7 +1016,7 @@ pub mod commands {
CommandText::new(
format!(
"Tag [{}]",
key_config.get_hint(key_config.log_tag_commit),
key_config.get_hint(key_config.keys.log_tag_commit),
),
"tag commit",
CMD_GROUP_LOG,
@ -1011,7 +1028,7 @@ pub mod commands {
CommandText::new(
format!(
"Files [{}]",
key_config.get_hint(key_config.open_file_tree),
key_config.get_hint(key_config.keys.open_file_tree),
),
"inspect file tree at specific revision",
CMD_GROUP_LOG,
@ -1023,7 +1040,7 @@ pub mod commands {
CommandText::new(
format!(
"Tag [{}]",
key_config.get_hint(key_config.enter),
key_config.get_hint(key_config.keys.enter),
),
"tag commit",
CMD_GROUP_LOG,
@ -1035,7 +1052,7 @@ pub mod commands {
CommandText::new(
format!(
"Create Branch [{}]",
key_config.get_hint(key_config.enter),
key_config.get_hint(key_config.keys.enter),
),
"create branch",
CMD_GROUP_BRANCHES,
@ -1048,7 +1065,7 @@ pub mod commands {
CommandText::new(
format!(
"Create [{}]",
key_config.get_hint(key_config.create_branch),
key_config.get_hint(key_config.keys.create_branch),
),
"open create branch popup",
CMD_GROUP_BRANCHES,
@ -1060,7 +1077,7 @@ pub mod commands {
CommandText::new(
format!(
"Rename Branch [{}]",
key_config.get_hint(key_config.enter),
key_config.get_hint(key_config.keys.enter),
),
"rename branch",
CMD_GROUP_BRANCHES,
@ -1073,7 +1090,7 @@ pub mod commands {
CommandText::new(
format!(
"Rename Branch [{}]",
key_config.get_hint(key_config.rename_branch),
key_config.get_hint(key_config.keys.rename_branch),
),
"rename branch",
CMD_GROUP_BRANCHES,
@ -1085,7 +1102,7 @@ pub mod commands {
CommandText::new(
format!(
"Delete [{}]",
key_config.get_hint(key_config.delete_branch),
key_config.get_hint(key_config.keys.delete_branch),
),
"delete a branch",
CMD_GROUP_BRANCHES,
@ -1097,7 +1114,7 @@ pub mod commands {
CommandText::new(
format!(
"Merge [{}]",
key_config.get_hint(key_config.merge_branch),
key_config.get_hint(key_config.keys.merge_branch),
),
"merge a branch",
CMD_GROUP_BRANCHES,
@ -1110,7 +1127,7 @@ pub mod commands {
CommandText::new(
format!(
"Rebase [{}]",
key_config.get_hint(key_config.rebase_branch),
key_config.get_hint(key_config.keys.rebase_branch),
),
"rebase a branch",
CMD_GROUP_BRANCHES,
@ -1123,7 +1140,7 @@ pub mod commands {
CommandText::new(
format!(
"Compare [{}]",
key_config.get_hint(key_config.compare_commits),
key_config.get_hint(key_config.keys.compare_commits),
),
"compare with head",
CMD_GROUP_BRANCHES,
@ -1136,7 +1153,7 @@ pub mod commands {
CommandText::new(
format!(
"Compare Commits [{}]",
key_config.get_hint(key_config.compare_commits),
key_config.get_hint(key_config.keys.compare_commits),
),
"compare two marked commits",
CMD_GROUP_LOG,
@ -1149,7 +1166,7 @@ pub mod commands {
CommandText::new(
format!(
"Checkout [{}]",
key_config.get_hint(key_config.enter),
key_config.get_hint(key_config.keys.enter),
),
"checkout branch",
CMD_GROUP_BRANCHES,
@ -1163,7 +1180,7 @@ pub mod commands {
format!(
"{} [{}]",
if local { "Remote" } else { "Local" },
key_config.get_hint(key_config.tab_toggle),
key_config.get_hint(key_config.keys.tab_toggle),
),
"toggle branch type (remote/local)",
CMD_GROUP_BRANCHES,
@ -1175,7 +1192,7 @@ pub mod commands {
CommandText::new(
format!(
"Branches [{}]",
key_config.get_hint(key_config.select_branch),
key_config.get_hint(key_config.keys.select_branch),
),
"open branch popup",
CMD_GROUP_BRANCHES,
@ -1188,7 +1205,7 @@ pub mod commands {
CommandText::new(
format!(
"Tags [{}]",
key_config.get_hint(key_config.tags),
key_config.get_hint(key_config.keys.tags),
),
"open tags popup",
CMD_GROUP_GENERAL,
@ -1200,7 +1217,7 @@ pub mod commands {
CommandText::new(
format!(
"Delete [{}]",
key_config.get_hint(key_config.delete_tag),
key_config.get_hint(key_config.keys.delete_tag),
),
"delete a tag",
CMD_GROUP_GENERAL,
@ -1210,7 +1227,7 @@ pub mod commands {
CommandText::new(
format!(
"Select commit [{}]",
key_config.get_hint(key_config.select_tag),
key_config.get_hint(key_config.keys.select_tag),
),
"Select commit in revlog",
CMD_GROUP_LOG,
@ -1221,7 +1238,7 @@ pub mod commands {
CommandText::new(
format!(
"Push [{}]",
key_config.get_hint(key_config.push),
key_config.get_hint(key_config.keys.push),
),
"push to origin",
CMD_GROUP_GENERAL,
@ -1233,7 +1250,7 @@ pub mod commands {
CommandText::new(
format!(
"Force Push [{}]",
key_config.get_hint(key_config.force_push),
key_config.get_hint(key_config.keys.force_push),
),
"force push to origin",
CMD_GROUP_GENERAL,
@ -1243,7 +1260,7 @@ pub mod commands {
CommandText::new(
format!(
"Pull [{}]",
key_config.get_hint(key_config.pull),
key_config.get_hint(key_config.keys.pull),
),
"fetch/merge",
CMD_GROUP_GENERAL,

View file

@ -221,17 +221,17 @@ impl Component for Revlog {
self.update()?;
return Ok(EventState::Consumed);
} else if let Event::Key(k) = ev {
if k == self.key_config.enter {
if k == self.key_config.keys.enter {
self.commit_details.toggle_visible()?;
self.update()?;
return Ok(EventState::Consumed);
} else if k == self.key_config.copy {
} else if k == self.key_config.keys.copy {
self.copy_commit_hash()?;
return Ok(EventState::Consumed);
} else if k == self.key_config.push {
} else if k == self.key_config.keys.push {
self.queue.push(InternalEvent::PushTags);
return Ok(EventState::Consumed);
} else if k == self.key_config.log_tag_commit {
} else if k == self.key_config.keys.log_tag_commit {
return self.selected_commit().map_or(
Ok(EventState::NotConsumed),
|id| {
@ -240,7 +240,7 @@ impl Component for Revlog {
Ok(EventState::Consumed)
},
);
} else if k == self.key_config.focus_right
} else if k == self.key_config.keys.focus_right
&& self.commit_details.is_visible()
{
return self.selected_commit().map_or(
@ -257,10 +257,10 @@ impl Component for Revlog {
Ok(EventState::Consumed)
},
);
} else if k == self.key_config.select_branch {
} else if k == self.key_config.keys.select_branch {
self.queue.push(InternalEvent::SelectBranch);
return Ok(EventState::Consumed);
} else if k == self.key_config.open_file_tree {
} else if k == self.key_config.keys.open_file_tree {
return self.selected_commit().map_or(
Ok(EventState::NotConsumed),
|id| {
@ -270,10 +270,10 @@ impl Component for Revlog {
Ok(EventState::Consumed)
},
);
} else if k == self.key_config.tags {
} else if k == self.key_config.keys.tags {
self.queue.push(InternalEvent::Tags);
return Ok(EventState::Consumed);
} else if k == self.key_config.compare_commits
} else if k == self.key_config.keys.compare_commits
&& self.list.marked_count() > 0
{
if self.list.marked_count() == 1 {

View file

@ -217,7 +217,7 @@ impl Component for Stashing {
}
if let Event::Key(k) = ev {
return if k == self.key_config.stashing_save
return if k == self.key_config.keys.stashing_save
&& !self.index.is_empty()
{
self.queue.push(InternalEvent::PopupStashing(
@ -225,13 +225,15 @@ impl Component for Stashing {
));
Ok(EventState::Consumed)
} else if k == self.key_config.stashing_toggle_index {
} else if k
== self.key_config.keys.stashing_toggle_index
{
self.options.keep_index =
!self.options.keep_index;
self.update()?;
Ok(EventState::Consumed)
} else if k
== self.key_config.stashing_toggle_untracked
== self.key_config.keys.stashing_toggle_untracked
{
self.options.stash_untracked =
!self.options.stash_untracked;

View file

@ -184,13 +184,13 @@ impl Component for StashList {
}
if let Event::Key(k) = ev {
if k == self.key_config.enter {
if k == self.key_config.keys.enter {
self.pop_stash();
} else if k == self.key_config.stash_apply {
} else if k == self.key_config.keys.stash_apply {
self.apply_stash();
} else if k == self.key_config.stash_drop {
} else if k == self.key_config.keys.stash_drop {
self.drop_stash();
} else if k == self.key_config.stash_open {
} else if k == self.key_config.keys.stash_open {
self.inspect();
}
}

View file

@ -747,7 +747,7 @@ impl Component for Status {
}
if let Event::Key(k) = ev {
return if k == self.key_config.edit_file
return if k == self.key_config.keys.edit_file
&& (self.can_focus_diff()
|| self.is_focus_on_diff())
{
@ -759,58 +759,58 @@ impl Component for Status {
);
}
Ok(EventState::Consumed)
} else if k == self.key_config.open_commit
} else if k == self.key_config.keys.open_commit
&& self.can_commit()
{
self.queue.push(InternalEvent::OpenCommit);
Ok(EventState::Consumed)
} else if k == self.key_config.toggle_workarea
} else if k == self.key_config.keys.toggle_workarea
&& !self.is_focus_on_diff()
{
self.switch_focus(self.focus.toggled_focus())
.map(Into::into)
} else if k == self.key_config.focus_right
} else if k == self.key_config.keys.focus_right
&& self.can_focus_diff()
{
self.switch_focus(Focus::Diff).map(Into::into)
} else if k == self.key_config.focus_left {
} else if k == self.key_config.keys.focus_left {
self.switch_focus(match self.diff_target {
DiffTarget::Stage => Focus::Stage,
DiffTarget::WorkingDir => Focus::WorkDir,
})
.map(Into::into)
} else if k == self.key_config.move_down
} else if k == self.key_config.keys.move_down
&& self.focus == Focus::WorkDir
&& !self.index.is_empty()
{
self.switch_focus(Focus::Stage).map(Into::into)
} else if k == self.key_config.move_up
} else if k == self.key_config.keys.move_up
&& self.focus == Focus::Stage
&& !self.index_wd.is_empty()
{
self.switch_focus(Focus::WorkDir).map(Into::into)
} else if k == self.key_config.select_branch
} else if k == self.key_config.keys.select_branch
&& !self.is_focus_on_diff()
{
self.queue.push(InternalEvent::SelectBranch);
Ok(EventState::Consumed)
} else if k == self.key_config.force_push
} else if k == self.key_config.keys.force_push
&& !self.is_focus_on_diff()
&& self.can_push()
{
self.push(true);
Ok(EventState::Consumed)
} else if k == self.key_config.push
} else if k == self.key_config.keys.push
&& !self.is_focus_on_diff()
{
self.push(false);
Ok(EventState::Consumed)
} else if k == self.key_config.pull
} else if k == self.key_config.keys.pull
&& !self.is_focus_on_diff()
{
self.pull();
Ok(EventState::Consumed)
} else if k == self.key_config.undo_commit
} else if k == self.key_config.keys.undo_commit
&& !self.is_focus_on_diff()
{
self.undo_last_commit();
@ -818,7 +818,7 @@ impl Component for Status {
NeedsUpdate::ALL,
));
Ok(EventState::Consumed)
} else if k == self.key_config.abort_merge
} else if k == self.key_config.keys.abort_merge
&& Self::can_abort_merge()
{
self.queue.push(InternalEvent::ConfirmAction(
@ -826,7 +826,7 @@ impl Component for Status {
));
Ok(EventState::Consumed)
} else if k == self.key_config.abort_merge
} else if k == self.key_config.keys.abort_merge
&& Self::pending_rebase()
{
self.queue.push(InternalEvent::ConfirmAction(
@ -834,7 +834,7 @@ impl Component for Status {
));
Ok(EventState::Consumed)
} else if k == self.key_config.rebase_branch
} else if k == self.key_config.keys.rebase_branch
&& Self::pending_rebase()
{
self.continue_rebase();

View file

@ -118,21 +118,25 @@ pub fn common_nav(
key: crossterm::event::KeyEvent,
key_config: &SharedKeyConfig,
) -> Option<MoveSelection> {
if key == key_config.move_down {
if key == key_config.keys.move_down {
Some(MoveSelection::Down)
} else if key == key_config.move_up {
} else if key == key_config.keys.move_up {
Some(MoveSelection::Up)
} else if key == key_config.page_up {
} else if key == key_config.keys.page_up {
Some(MoveSelection::PageUp)
} else if key == key_config.page_down {
} else if key == key_config.keys.page_down {
Some(MoveSelection::PageDown)
} else if key == key_config.move_right {
} else if key == key_config.keys.move_right {
Some(MoveSelection::Right)
} else if key == key_config.move_left {
} else if key == key_config.keys.move_left {
Some(MoveSelection::Left)
} else if key == key_config.home || key == key_config.shift_up {
} else if key == key_config.keys.home
|| key == key_config.keys.shift_up
{
Some(MoveSelection::Top)
} else if key == key_config.end || key == key_config.shift_down {
} else if key == key_config.keys.end
|| key == key_config.keys.shift_down
{
Some(MoveSelection::End)
} else {
None