Skip to content

Commit

Permalink
Customize key binds (#234)
Browse files Browse the repository at this point in the history
* customizable key config
* provide example vim key config
* automatically show correct key binding in bottom cmd-bar
  • Loading branch information
yanganto committed Aug 26, 2020
1 parent d8bd472 commit a95ffd7
Show file tree
Hide file tree
Showing 30 changed files with 1,643 additions and 921 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
.DS_Store
/.idea/
flamegraph.svg
KEY_CONFIG.md
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ keywords = [
[dependencies]
scopetime = { path = "./scopetime", version = "0.1" }
asyncgit = { path = "./asyncgit", version = "0.9" }
crossterm = "0.17"
crossterm = { version = "0.17", features = [ "serde" ] }
clap = { version = "2.33", default-features = false }
tui = { version = "0.9", default-features = false, features = ['crossterm'] }
bytesize = { version = "1.0.1", default-features = false}
Expand Down
15 changes: 15 additions & 0 deletions KEY_CONFIG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Key Config

Default using arrow key to navigate the gitui and Ctrl + C to quit the program

The first time Gitui will create `key_config.ron` file automatically.
You can change the every single key bindings of the program as what you like.

The config file format is [Ron format](https://github.com/ron-rs/ron).
And the path differs depending on the operating system:
* `$HOME/Library/Preferences/gitui/key_config.ron` (mac)
* `$XDG_CONFIG_HOME/gitui/key_config.ron` (linux using XDG)
* `$HOME/.config/gitui/key_config.ron` (linux)

Here is a [vim style key config](assets/vim_style_key_config.ron) with `h`, `j`, `k`, `l` to navigate and `Ctrl + C` to leave.
You can use it to replace `key_config.ron` and get a vim style setting.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,6 @@ However, you can customize everything to your liking: See [Themes](THEMES.md).
- [tig](https://github.com/jonas/tig)
- [GitUp](https://github.com/git-up/GitUp)
- It would be nice to come up with a way to have the map view available in a terminal tool

# Key Bindings
You can customize every keybing to your liking: See [Key Config](KEY_CONFIG.md).
66 changes: 66 additions & 0 deletions assets/vim_style_key_config.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// bit for modifiers
// bits: 0 None
// bits: 1 SHIFT
// bits: 2 CONTROL
(
tab_status: ( code: Char('1'), modifiers: ( bits: 0,),),
tab_log: ( code: Char('2'), modifiers: ( bits: 0,),),
tab_stashing: ( code: Char('3'), modifiers: ( bits: 0,),),
tab_stashes: ( code: Char('4'), modifiers: ( bits: 0,),),

tab_toggle: ( code: Tab, modifiers: ( bits: 0,),),
tab_toggle_reverse: ( code: BackTab, modifiers: ( bits: 0,),),
tab_toggle_reverse_windows: ( code: BackTab, modifiers: ( bits: 1,),),

focus_workdir: ( code: Char('w'), modifiers: ( bits: 0,),),
focus_stage: ( code: Char('s'), modifiers: ( bits: 0,),),
focus_right: ( code: Char('l'), modifiers: ( bits: 0,),),
focus_left: ( code: Char('h'), modifiers: ( bits: 0,),),
focus_above: ( code: Char('k'), modifiers: ( bits: 0,),),
focus_below: ( code: Char('j'), modifiers: ( bits: 0,),),

exit: ( code: Char('c'), modifiers: ( bits: 2,),),
exit_popup: ( code: Esc, modifiers: ( bits: 0,),),

close_msg: ( code: Enter, modifiers: ( bits: 0,),),
open_commit: ( code: Char('c'), modifiers: ( bits: 0,),),
open_commit_editor: ( code: Char('E'), modifiers: ( bits: 0,),),
open_help: ( code: F(1), modifiers: ( bits: 0,),),

move_left: ( code: Char('h'), modifiers: ( bits: 0,),),
move_right: ( code: Char('l'), modifiers: ( bits: 0,),),
home: ( code: Home, modifiers: ( bits: 0,),),
end: ( code: End, modifiers: ( bits: 0,),),
move_up: ( code: Char('k'), modifiers: ( bits: 0,),),
move_down: ( code: Char('j'), modifiers: ( bits: 0,),),
page_up: ( code: Char('u'), modifiers: ( bits: 2,),),
page_down: ( code: Char('d'), modifiers: ( bits: 2,),),

shift_up: ( code: Char('K'), modifiers: ( bits: 0,),),
shift_down: ( code: Char('J'), modifiers: ( bits: 0,),),

enter: ( code: Enter, modifiers: ( bits: 0,),),

edit_file: ( code: Char('I'), modifiers: ( bits: 0,),),

status_stage_file: ( code: Enter, modifiers: ( bits: 0,),),
status_stage_all: ( code: Char('a'), modifiers: ( bits: 0,),),
status_reset_file: ( code: Char('U'), modifiers: ( bits: 0,),),

diff_reset_hunk: ( code: Enter, modifiers: ( bits: 0,),),
status_ignore_file: ( code: Char('i'), modifiers: ( bits: 0,),),

stashing_save: ( code: Char('w'), modifiers: ( bits: 0,),),
stashing_toggle_untracked: ( code: Char('u'), modifiers: ( bits: 0,),),
stashing_toggle_index: ( code: Char('m'), modifiers: ( bits: 0,),),

stash_apply: ( code: Enter, modifiers: ( bits: 0,),),
stash_open: ( code: Char('l'), modifiers: ( bits: 0,),),
stash_drop: ( code: Char('D'), modifiers: ( bits: 0,),),

cmd_bar_toggle: ( code: Char('.'), modifiers: ( bits: 0,),),
log_commit_details: ( code: Enter, modifiers: ( bits: 0,),),
log_tag_commit: ( code: Char('t'), modifiers: ( bits: 0,),),
commit_amend: ( code: Char('A'), modifiers: ( bits: 0,),),
copy: ( code: Char('y'), modifiers: ( bits: 0,),),
)
129 changes: 81 additions & 48 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use crate::{
ResetComponent, StashMsgComponent, TagCommitComponent,
},
input::{Input, InputEvent, InputState},
keys,
keys::{KeyConfig, SharedKeyConfig},
queue::{Action, InternalEvent, NeedsUpdate, Queue},
strings::{self, commands, order},
strings::{self, order},
tabs::{Revlog, StashList, Stashing, Status},
ui::style::{SharedTheme, Theme},
};
Expand Down Expand Up @@ -49,6 +49,7 @@ pub struct App {
stashlist_tab: StashList,
queue: Queue,
theme: SharedTheme,
key_config: SharedKeyConfig,
input: Input,

// "Flags"
Expand All @@ -66,45 +67,77 @@ impl App {
let queue = Queue::default();

let theme = Rc::new(Theme::init());
let key_config = Rc::new(KeyConfig::init());

Self {
input,
reset: ResetComponent::new(queue.clone(), theme.clone()),
reset: ResetComponent::new(
queue.clone(),
theme.clone(),
key_config.clone(),
),
commit: CommitComponent::new(
queue.clone(),
theme.clone(),
key_config.clone(),
),
stashmsg_popup: StashMsgComponent::new(
queue.clone(),
theme.clone(),
key_config.clone(),
),
inspect_commit_popup: InspectCommitComponent::new(
&queue,
sender,
theme.clone(),
key_config.clone(),
),
external_editor_popup: ExternalEditorComponent::new(
theme.clone(),
key_config.clone(),
),
tag_commit_popup: TagCommitComponent::new(
queue.clone(),
theme.clone(),
key_config.clone(),
),
do_quit: false,
cmdbar: RefCell::new(CommandBar::new(theme.clone())),
help: HelpComponent::new(theme.clone()),
msg: MsgComponent::new(theme.clone()),
cmdbar: RefCell::new(CommandBar::new(
theme.clone(),
key_config.clone(),
)),
help: HelpComponent::new(
theme.clone(),
key_config.clone(),
),
msg: MsgComponent::new(theme.clone(), key_config.clone()),
tab: 0,
revlog: Revlog::new(&queue, sender, theme.clone()),
status_tab: Status::new(&queue, sender, theme.clone()),
revlog: Revlog::new(
&queue,
sender,
theme.clone(),
key_config.clone(),
),
status_tab: Status::new(
&queue,
sender,
theme.clone(),
key_config.clone(),
),
stashing_tab: Stashing::new(
sender,
&queue,
theme.clone(),
key_config.clone(),
),
stashlist_tab: StashList::new(
&queue,
theme.clone(),
key_config.clone(),
),
stashlist_tab: StashList::new(&queue, theme.clone()),
queue,
theme,
key_config,
requires_redraw: Cell::new(false),
file_to_open: None,
}
Expand Down Expand Up @@ -160,30 +193,26 @@ impl App {
if event_pump(ev, self.components_mut().as_mut_slice())? {
flags.insert(NeedsUpdate::COMMANDS);
} else if let Event::Key(k) = ev {
let new_flags = match k {
keys::TAB_TOGGLE => {
self.toggle_tabs(false)?;
NeedsUpdate::COMMANDS
}
keys::TAB_TOGGLE_REVERSE
| keys::TAB_TOGGLE_REVERSE_WINDOWS => {
self.toggle_tabs(true)?;
NeedsUpdate::COMMANDS
}
keys::TAB_1
| keys::TAB_2
| keys::TAB_3
| keys::TAB_4 => {
self.switch_tab(k)?;
NeedsUpdate::COMMANDS
}

keys::CMD_BAR_TOGGLE => {
self.cmdbar.borrow_mut().toggle_more();
NeedsUpdate::empty()
}

_ => NeedsUpdate::empty(),
let new_flags = if k == self.key_config.tab_toggle {
self.toggle_tabs(false)?;
NeedsUpdate::COMMANDS
} else if k == self.key_config.tab_toggle_reverse
|| k == self.key_config.tab_toggle_reverse_windows
{
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_stashing
|| k == self.key_config.tab_stashes
{
self.switch_tab(k)?;
NeedsUpdate::COMMANDS
} else if k == self.key_config.cmd_bar_toggle {
self.cmdbar.borrow_mut().toggle_more();
NeedsUpdate::empty()
} else {
NeedsUpdate::empty()
};

flags.insert(new_flags);
Expand Down Expand Up @@ -312,7 +341,7 @@ impl App {

fn check_quit_key(&mut self, ev: Event) -> bool {
if let Event::Key(e) = ev {
if let keys::EXIT = e {
if e == self.key_config.exit {
self.do_quit = true;
return true;
}
Expand Down Expand Up @@ -341,12 +370,14 @@ impl App {
}

fn switch_tab(&mut self, k: KeyEvent) -> Result<()> {
match k {
keys::TAB_1 => self.set_tab(0)?,
keys::TAB_2 => self.set_tab(1)?,
keys::TAB_3 => self.set_tab(2)?,
keys::TAB_4 => self.set_tab(3)?,
_ => (),
if k == self.key_config.tab_status {
self.set_tab(0)?
} else if k == self.key_config.tab_log {
self.set_tab(1)?
} else if k == self.key_config.tab_stashing {
self.set_tab(2)?
} else if k == self.key_config.tab_stashes {
self.set_tab(3)?
}

Ok(())
Expand Down Expand Up @@ -458,15 +489,17 @@ impl App {

res.push(
CommandInfo::new(
commands::TOGGLE_TABS,
strings::commands::toggle_tabs(&self.key_config),
true,
!self.any_popup_visible(),
)
.order(order::NAV),
);
res.push(
CommandInfo::new(
commands::TOGGLE_TABS_DIRECT,
strings::commands::toggle_tabs_direct(
&self.key_config,
),
true,
!self.any_popup_visible(),
)
Expand All @@ -475,7 +508,7 @@ impl App {

res.push(
CommandInfo::new(
commands::QUIT,
strings::commands::quit(&self.key_config),
true,
!self.any_popup_visible(),
)
Expand Down Expand Up @@ -531,10 +564,10 @@ impl App {
});

let tabs = &[
strings::TAB_STATUS,
strings::TAB_LOG,
strings::TAB_STASHING,
strings::TAB_STASHES,
strings::tab_status(&self.key_config),
strings::tab_log(&self.key_config),
strings::tab_stashing(&self.key_config),
strings::tab_stashes(&self.key_config),
];

f.render_widget(
Expand All @@ -547,7 +580,7 @@ impl App {
.titles(tabs)
.style(self.theme.tab(false))
.highlight_style(self.theme.tab(true))
.divider(strings::TAB_DIVIDER)
.divider(&strings::tab_divider(&self.key_config))
.select(self.tab),
r,
);
Expand Down

0 comments on commit a95ffd7

Please sign in to comment.