Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support key binds mapping #21

Merged
merged 16 commits into from
Aug 9, 2024
Merged
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.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ semver = "1.0.23"
serde = { version = "1.0.204", features = ["derive"] }
serde_json = "1.0.122"
sha1 = "0.10.6"
strum = "0.26.3"
toml = "0.8.19"
tui-input = "0.9.0"
tui-tree-widget = "0.21.0"
Expand Down
30 changes: 30 additions & 0 deletions assets/default-keybind.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Quit = ["q", "ctrl-c"]
yanganto marked this conversation as resolved.
Show resolved Hide resolved
NavigateUp = ["k", "up"]
NavigateDown = ["j", "down"]
NavigateRight = ["l", "right"]
NavigateLeft = ["h", "left"]

# close widget or cancel progress but not quit app
CloseOrCancel = ["esc"]
HelpToggle = ["?"]
GoToTop = ["g"]
GoToBottom = ["shift-g"]
GoToNext = ["n"]
GoToPrevious = ["shift-N"]
yanganto marked this conversation as resolved.
Show resolved Hide resolved
ScrollDown = ["ctrl-e"]
ScrollUp = ["ctrl-y"]
PageUp = ["ctrl-b"]
PageDown = ["ctrl-f"]
HalfPageUp = ["ctrl-u"]
HalfPageDown = ["ctrl-d"]
SelectTop = ["shift-h"]
SelectMiddle = ["shift-m"]
SelectBottom = ["shift-l"]
ShowDetails = ["enter"]
yanganto marked this conversation as resolved.
Show resolved Hide resolved
Search = ["/"]

# copy part of information, ex: copy the short commit hash not all
ShortCopy = ["c"]
FullCopy = ["shift-c"]

RefListToggle = ["tab"]
82 changes: 82 additions & 0 deletions flake.lock

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

32 changes: 32 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
yanganto marked this conversation as resolved.
Show resolved Hide resolved
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
};

flake-utils.url = "github:numtide/flake-utils";
};

outputs = { self, rust-overlay, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
overlays = [ (import rust-overlay) ];
pkgs = import nixpkgs {
inherit system overlays;
};
in
with pkgs;
{
devShells = rec {
default = mkShell {
buildInputs = [
rust-bin.stable.latest.default
];
};
};
}
);
}
76 changes: 53 additions & 23 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ use ratatui::{
use crate::{
color::ColorSet,
config::Config,
event::{AppEvent, Receiver, Sender},
event::{AppEvent, Receiver, Sender, UserEvent},
external::copy_to_clipboard,
git::Repository,
graph::{Graph, GraphImage},
key_code_char,
keybind::KeyBind,
protocol::ImageProtocol,
view::View,
widget::commit_list::{CommitInfo, CommitListState},
Expand Down Expand Up @@ -46,16 +46,20 @@ pub struct App<'a> {
view: View<'a>,
status_line: StatusLine,

keybind: &'a KeyBind,
config: &'a Config,
image_protocol: ImageProtocol,
insert_mode: bool,
tx: Sender,
}

impl<'a> App<'a> {
#[allow(clippy::too_many_arguments)]
pub fn new(
repository: &'a Repository,
graph: &'a Graph,
graph_image: &'a GraphImage,
keybind: &'a KeyBind,
config: &'a Config,
color_set: &'a ColorSet,
image_protocol: ImageProtocol,
Expand Down Expand Up @@ -94,8 +98,10 @@ impl<'a> App<'a> {
repository,
status_line: StatusLine::None,
view,
keybind,
config,
image_protocol,
insert_mode: false,
tx,
}
}
Expand All @@ -111,31 +117,47 @@ impl App<'_> {
terminal.draw(|f| self.render(f))?;

match rx.recv() {
AppEvent::Key(key) => match key {
key_code_char!('c', Ctrl) => {
return Ok(());
}
_ => {
match self.status_line {
StatusLine::None | StatusLine::Input(_, _) => {
// do nothing
AppEvent::Key(key) => {
match self.keybind.get(&key) {
Some(UserEvent::Quit) => {
self.tx.send(AppEvent::Quit);
}
Some(UserEvent::CloseOrCancel) => {
if self.insert_mode {
self.insert_mode = false;
}
StatusLine::NotificationInfo(_)
| StatusLine::NotificationSuccess(_)
| StatusLine::NotificationWarn(_) => {
// Clear message and pass key input as is
self.clear_status_line();
self.view.handle_user_event(&UserEvent::CloseOrCancel);
}
Some(ue) => {
yanganto marked this conversation as resolved.
Show resolved Hide resolved
match self.status_line {
yanganto marked this conversation as resolved.
Show resolved Hide resolved
StatusLine::None | StatusLine::Input(_, _) => {
// do nothing
}
StatusLine::NotificationInfo(_)
| StatusLine::NotificationSuccess(_)
| StatusLine::NotificationWarn(_) => {
// Clear message and pass key input as is
self.clear_status_line();
}
StatusLine::NotificationError(_) => {
// Clear message and cancel key input
self.clear_status_line();
continue;
}
}
StatusLine::NotificationError(_) => {
// Clear message and cancel key input
self.clear_status_line();
continue;
if self.insert_mode {
self.view.insert_key(key);
} else {
self.view.handle_user_event(ue);
}
}
None => {
if self.insert_mode {
self.view.insert_key(key);
}
}

self.view.handle_key(key);
}
},
}
AppEvent::Resize(w, h) => {
let _ = (w, h);
}
Expand Down Expand Up @@ -187,6 +209,9 @@ impl App<'_> {
AppEvent::NotifyError(msg) => {
self.error_notification(msg);
}
AppEvent::Insert => {
self.insert_mode = true;
}
}
}
}
Expand Down Expand Up @@ -286,7 +311,12 @@ impl App<'_> {

fn open_help(&mut self) {
let before_view = std::mem::take(&mut self.view);
self.view = View::of_help(before_view, self.image_protocol, self.tx.clone());
self.view = View::of_help(
before_view,
self.image_protocol,
self.tx.clone(),
self.keybind,
);
}

fn close_help(&mut self) {
Expand Down
6 changes: 6 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use serde::Deserialize;

use crate::keybind::KeyBind;

const APP_DIR_NAME: &str = "serie";
const CONFIG_FILE_NAME: &str = "config.toml";

Expand All @@ -15,6 +17,7 @@ const DEFAULT_DETAIL_DATE_LOCAL: bool = true;
pub struct Config {
#[serde(default)]
pub ui: UiConfig,
pub custom_keybind_patch: Option<KeyBind>,
yanganto marked this conversation as resolved.
Show resolved Hide resolved
}

#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize)]
Expand Down Expand Up @@ -131,6 +134,7 @@ mod tests {
date_local: true,
},
},
custom_keybind_patch: None,
};
assert_eq!(actual, expected);
}
Expand Down Expand Up @@ -163,6 +167,7 @@ mod tests {
date_local: false,
},
},
custom_keybind_patch: None,
};
assert_eq!(actual, expected);
}
Expand All @@ -188,6 +193,7 @@ mod tests {
date_local: true,
},
},
custom_keybind_patch: None,
};
assert_eq!(actual, expected);
}
Expand Down
Loading