summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Oram <dev@mitmaro.ca>2019-07-15 21:53:57 -0230
committerGitHub <noreply@github.com>2019-07-15 21:53:57 -0230
commit71ca096faa7e6c507b2d9bfe20974205e27b9e39 (patch)
tree131a52d08c403caf2dfd4297ffca95662f696bc6
parent98fa4e5754eadbef23ec74d75df5cf06bb3abc15 (diff)
parent90930bf702a7ed8b04fce778acfe0b0b3bf7c16f (diff)
Merge pull request #149 from MitMaro/tim/add-custom-key-bindings
Add custom key bindings
-rw-r--r--CHANGELOG.md1
-rw-r--r--README.md53
-rw-r--r--src/config.rs68
-rw-r--r--src/constants.rs51
-rw-r--r--src/help/help.rs51
-rw-r--r--src/help/mod.rs1
-rw-r--r--src/help/utils.rs90
-rw-r--r--src/input/input_handler.rs79
-rw-r--r--src/list/list.rs48
-rw-r--r--src/list/utils.rs77
-rw-r--r--src/main.rs4
-rw-r--r--src/process/process.rs4
-rw-r--r--src/view/view.rs15
13 files changed, 401 insertions, 141 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d6ebe3b..ea070e9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- The command of an exec action can now be edited
- Visual mode - change action and reorder with multiple selections
- Configuration option for vertical spacing character
+- Configurable key bindings
## [1.0.0] - 2019-04-10
diff --git a/README.md b/README.md
index 0b05669..0fff4ca 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,9 @@ interactive-rebase-tool --version
The tool has built-in help that can be accessed by hitting the `?` key.
-### Key Bindings
+### Default Key Bindings
+
+Key bindings can be configured, see [configuration](#configuration) for more information.
| Key | Mode | Description |
| ------------ | ------ | ----------- |
@@ -93,21 +95,54 @@ git config --global interactive-rebase-tool.foregroundColor black
| Key | Default | Type | Description |
| -------------------------- | ------- | ------ | ----------- |
| `autoSelectNext` | false | bool | If true, auto select the next line after action modification |
-| `foregroundColor` | white | Color | Color used for most text and the UI |
-| `indicatorColor` | cyan | Color | Color used for text the indicates or needs to standout |
-| `errorColor` | red | Color | Color used for showing error messages |
+| `breakColor` | white | Color | Color used for the break action |
| `diffAddColor` | green | Color | Color used for lines and files added in a diff |
-| `diffRemoveColor` | red | Color | Color used for lines and files removed in a diff |
| `diffChangeColor` | yellow | Color | Color used for lines and files changed in a diff |
-| `breakColor` | white | Color | Color used for the break action |
+| `diffRemoveColor` | red | Color | Color used for lines and files removed in a diff |
+| `dropColor` | red | Color | Color used for the drop action |
+| `editColor` | blue | Color | Color used for the edit action |
+| `errorColor` | red | Color | Color used for showing error messages |
+| `fixupColor` | magenta | Color | Color used for the fixup action |
+| `foregroundColor` | white | Color | Color used for most text and the UI |
+| `indicatorColor` | cyan | Color | Color used for text the indicates or needs to standout |
+| `inputAbort` | q | String | Key for abort rebase with prompt |
+| `inputActionBreak` | b | String | Key for setting action to rebase |
+| `inputActionDrop` | d | String | Key for setting action to drop |
+| `inputActionEdit` | e | String | Key for setting action to edit |
+| `inputActionFixup` | f | String | Key for setting action to fixup |
+| `inputActionPick` | p | String | Key for setting action to pick |
+| `inputActionReword` | r | String | Key for setting action to reword |
+| `inputActionSquash` | s | String | Key for setting action to squash |
+| `inputConfirmNo` | n | String | Key for rejecting a confirmation |
+| `inputConfirmYes` | y | String | Key for confirming a confirmation |
+| `inputEdit` | E | String | Key for entering edit mode |
+| `inputForceAbort` | Q | String | Key for forcing an abort of the rebase |
+| `inputForceRebase` | W | String | Key for forcing a rebase |
+| `inputHelp` | ? | String | Key for showing the help |
+| `inputMoveDown` | Down | String | Key for moving the selected line(s) down |
+| `inputMoveLeft` | Left | String | Key for moving the selected line(s) down |
+| `inputMoveRight` | Right | String | Key for moving the selected line(s) down |
+| `inputMoveSelectionDown` | j | String | Key for moving the selected line(s) down |
+| `inputMoveSelectionUp` | k | String | Key for moving the selected line(s) up |
+| `inputMoveUp` | Up | String | Key for moving the selected line(s) up |
+| `inputOpenInExternalEditor`| ! | String | Key for opening the external editor |
+| `inputRebase` | w | String | Key for rebasing with confirmation |
+| `inputShowCommit` | c | String | Key for showing the selected commit |
+| `inputToggleVisualMode` | v | String | Key for toggling visual mode |
| `pickColor` | green | Color | Color used for the pick action |
| `rewordColor` | yellow | Color | Color used for the reword action |
-| `editColor` | blue | Color | Color used for the edit action |
| `squashColor` | cyan | Color | Color used for the squash action |
-| `fixupColor` | magenta | Color | Color used for the fixup action |
-| `dropColor` | red | Color | Color used for the drop action |
| `verticalSpacingCharacter` | ~ | String | Vertical spacing character. Can be set to an empty string. |
+#### Special Keys
+
+| Key | Description |
+| ------- | ----------- |
+| `Down` | Down arrow key |
+| `Left` | Left arrow key |
+| `Right` | Right arrow key |
+| `Up` | Up arrow key |
+
#### Valid Color Values
The valid colors are the [eight original 8 ANSI colors][ANSIColors]. They are black, blue, cyan, green, magenta, red,
diff --git a/src/config.rs b/src/config.rs
index a899888..a1c73af 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -18,12 +18,54 @@ pub struct Config {
pub fixup_color: Color,
pub foreground_color: Color,
pub indicator_color: Color,
+ pub input_abort: String,
+ pub input_action_break: String,
+ pub input_action_drop: String,
+ pub input_action_edit: String,
+ pub input_action_fixup: String,
+ pub input_action_pick: String,
+ pub input_action_reword: String,
+ pub input_action_squash: String,
+ pub input_confirm_no: String,
+ pub input_confirm_yes: String,
+ pub input_edit: String,
+ pub input_force_abort: String,
+ pub input_force_rebase: String,
+ pub input_help: String,
+ pub input_move_down: String,
+ pub input_move_selection_down: String,
+ pub input_move_selection_up: String,
+ pub input_move_up: String,
+ pub input_open_in_external_editor: String,
+ pub input_rebase: String,
+ pub input_show_commit: String,
+ pub input_toggle_visual_mode: String,
pub pick_color: Color,
pub reword_color: Color,
pub squash_color: Color,
pub vertical_spacing_character: String,
}
+fn get_input(config: &git2::Config, name: &str, default: &str) -> Result<String, String> {
+ let value = get_string(config, name, default)?;
+
+ match value.to_lowercase().as_ref() {
+ "left" => Ok(String::from("Left")),
+ "right" => Ok(String::from("Right")),
+ "down" => Ok(String::from("Down")),
+ "up" => Ok(String::from("Up")),
+ _ => {
+ if value.len() > 1 {
+ return Err(format!(
+ "Error reading git config: {} must contain only one character",
+ name
+ ));
+ }
+ Ok(value)
+ },
+ }
+}
+
fn get_string(config: &git2::Config, name: &str, default: &str) -> Result<String, String> {
match config.get_string(name) {
Ok(v) => Ok(v),
@@ -92,6 +134,32 @@ impl Config {
fixup_color: get_color(&git_config, "interactive-rebase-tool.fixupColor", Color::Magenta)?,
foreground_color: get_color(&git_config, "interactive-rebase-tool.foregroundColor", Color::White)?,
indicator_color: get_color(&git_config, "interactive-rebase-tool.indicatorColor", Color::Cyan)?,
+ input_abort: get_input(&git_config, "interactive-rebase-tool.inputAbort", "q")?,
+ input_action_break: get_input(&git_config, "interactive-rebase-tool.inputActionBreak", "b")?,
+ input_action_drop: get_input(&git_config, "interactive-rebase-tool.inputActionDrop", "d")?,
+ input_action_edit: get_input(&git_config, "interactive-rebase-tool.inputActionEdit", "e")?,
+ input_action_fixup: get_input(&git_config, "interactive-rebase-tool.inputActionFixup", "f")?,
+ input_action_pick: get_input(&git_config, "interactive-rebase-tool.inputActionPick", "p")?,
+ input_action_reword: get_input(&git_config, "interactive-rebase-tool.inputActionReword", "r")?,
+ input_action_squash: get_input(&git_config, "interactive-rebase-tool.inputActionSquash", "s")?,
+ input_confirm_no: get_input(&git_config, "interactive-rebase-tool.inputConfirmNo", "n")?,
+ input_confirm_yes: get_input(&git_config, "interactive-rebase-tool.inputConfirmYes", "y")?,
+ input_edit: get_input(&git_config, "interactive-rebase-tool.inputEdit", "E")?,
+ input_force_abort: get_input(&git_config, "interactive-rebase-tool.inputForceAbort", "Q")?,
+ input_force_rebase: get_input(&git_config, "interactive-rebase-tool.inputForceRebase", "W")?,
+ input_help: get_input(&git_config, "interactive-rebase-tool.inputHelp", "?")?,
+ input_move_down: get_input(&git_config, "interactive-rebase-tool.inputMoveDown", "Down")?,
+ input_move_selection_down: get_input(&git_config, "interactive-rebase-tool.inputMoveSelectionDown", "j")?,
+ input_move_selection_up: get_input(&git_config, "interactive-rebase-tool.inputMoveSelectionUp", "k")?,
+ input_move_up: get_input(&git_config, "interactive-rebase-tool.inputMoveUp", "Up")?,
+ input_open_in_external_editor: get_input(
+ &git_config,
+ "interactive-rebase-tool.inputOpenInExternalEditor",
+ "!",
+ )?,
+ input_rebase: get_input(&git_config, "interactive-rebase-tool.inputRebase", "w")?,
+ input_show_commit: get_input(&git_config, "interactive-rebase-tool.inputShowCommit", "c")?,
+ input_toggle_visual_mode: get_input(&git_config, "interactive-rebase-tool.inputToggleVisualMode", "v")?,
pick_color: get_color(&git_config, "interactive-rebase-tool.pickColor", Color::Green)?,
reword_color: get_color(&git_config, "interactive-rebase-tool.rewordColor", Color::Yellow)?,
squash_color: get_color(&git_config, "interactive-rebase-tool.squashColor", Color::Cyan)?,
diff --git a/src/constants.rs b/src/constants.rs
index 1b6e40e..c18818a 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -2,19 +2,8 @@ pub const TITLE: &str = "Git Interactive Rebase Tool";
pub const TITLE_LENGTH: i32 = 27;
pub const TITLE_SHORT: &str = "Git Rebase";
pub const TITLE_SHORT_LENGTH: i32 = 10;
-pub const TITLE_HELP_INDICATOR: &str = "Help: ?";
pub const TITLE_HELP_INDICATOR_LENGTH: i32 = 7;
-pub const LIST_FOOTER_FULL: &str = " up, down, q/Q, w/W, c, j, k, b, p, r, e, s, f, d, E, !, ?";
-pub const LIST_FOOTER_FULL_WIDTH: usize = 58;
-pub const LIST_FOOTER_COMPACT: &str = "up,dn.q/Q,w/W,c,j,k,b,p,r,e,s,f,d,E,!,?";
-pub const LIST_FOOTER_COMPACT_WIDTH: usize = 39;
-
-pub const VISUAL_MODE_FOOTER_FULL: &str = "(VISUAL) up, down, j, k, p, r, e, s, f, d, ?";
-pub const VISUAL_MODE_FOOTER_FULL_WIDTH: usize = 44;
-pub const VISUAL_MODE_FOOTER_COMPACT: &str = "(V) up,down,j,k,p,r,e,s,f,d,?";
-pub const VISUAL_MODE_FOOTER_COMPACT_WIDTH: usize = 29;
-
pub const HEIGHT_ERROR_MESSAGE: &str = "Window too small, increase height to continue\n";
pub const MINIMUM_WINDOW_HEIGHT_ERROR_WIDTH: usize = 45;
pub const SHORT_ERROR_MESSAGE: &str = "Window too small\n";
@@ -26,43 +15,3 @@ pub const MINIMUM_FULL_WINDOW_WIDTH: usize = 34; // " > squash cccccccc mmmmmmmm
pub const NAME: &str = "interactive-rebase-tool";
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
-
-pub const LIST_HELP_LINES: &[(&str, &str)] = &[
- ("Up", "Move selection up"),
- ("Down", "Move selection down"),
- ("PgUp", "Move selection up 5 lines"),
- ("PgDn", "Move selection down 5 lines"),
- ("q", "Abort interactive rebase"),
- ("Q", "Immediately abort interactive rebase"),
- ("w", "Write interactive rebase file"),
- ("W", "Immediately write interactive rebase file"),
- ("?", "Show help"),
- ("c", "Show commit information"),
- ("j", "Move selected commit down"),
- ("k", "Move selected commit up"),
- ("b", "Toggle break action"),
- ("p", "Set selected commit to be picked"),
- ("r", "Set selected commit to be reworded"),
- ("e", "Set selected commit to be edited"),
- ("s", "Set selected commit to be squashed"),
- ("f", "Set selected commit to be fixed-up"),
- ("d", "Set selected commit to be dropped"),
- ("E", "Edit an exec action's command"),
- ("!", "Open the todo file in the default editor"),
-];
-
-pub const VISUAL_MODE_HELP_LINES: &[(&str, &str)] = &[
- ("Up", "Move selection up"),
- ("Down", "Move selection down"),
- ("PgUp", "Move selection up 5 lines"),
- ("PgDn", "Move selection down 5 lines"),
- ("?", "Show help"),
- ("j", "Move selected commits down"),
- ("k", "Move selected commits up"),
- ("p", "Set selected commits to be picked"),
- ("r", "Set selected commits to be reworded"),
- ("e", "Set selected commits to be edited"),
- ("s", "Set selected commits to be squashed"),
- ("f", "Set selected commits to be fixed-up"),
- ("d", "Set selected commits to be dropped"),
-];
diff --git a/src/help/help.rs b/src/help/help.rs
index 34af153..d0bf2a6 100644
--- a/src/help/help.rs
+++ b/src/help/help.rs
@@ -1,31 +1,20 @@
-use crate::constants::{LIST_HELP_LINES, VISUAL_MODE_HELP_LINES};
use crate::git_interactive::GitInteractive;
+use crate::help::utils::{get_list_normal_mode_help_lines, get_list_visual_mode_help_lines};
use crate::input::{Input, InputHandler};
use crate::process::{HandleInputResult, HandleInputResultBuilder, ProcessModule, State};
use crate::scroll::ScrollPosition;
use crate::view::{LineSegment, View, ViewLine};
use crate::window::WindowColor;
+use crate::Config;
-fn get_help_lines(return_state: &State) -> &[(&str, &str)] {
- if let State::List(visual_mode) = *return_state {
- if visual_mode {
- VISUAL_MODE_HELP_LINES
- }
- else {
- LIST_HELP_LINES
- }
- }
- else {
- &[]
- }
-}
-
-pub struct Help {
- scroll_position: ScrollPosition,
+pub struct Help<'h> {
+ normal_mode_help_lines: [(String, &'h str); 21],
return_state: State,
+ scroll_position: ScrollPosition,
+ visual_mode_help_lines: [(String, &'h str); 13],
}
-impl ProcessModule for Help {
+impl<'h> ProcessModule for Help<'h> {
fn activate(&mut self, state: State, _git_interactive: &GitInteractive) {
self.scroll_position.reset();
if let State::Help(return_state) = state {
@@ -49,11 +38,11 @@ impl ProcessModule for Help {
match input {
Input::MoveCursorDown => {
self.scroll_position
- .scroll_down(window_height, get_help_lines(&self.return_state).len());
+ .scroll_down(window_height, self.get_help_lines().len());
},
Input::MoveCursorUp => {
self.scroll_position
- .scroll_up(window_height, get_help_lines(&self.return_state).len());
+ .scroll_up(window_height, self.get_help_lines().len());
},
Input::Resize => {
self.scroll_position.reset();
@@ -70,7 +59,7 @@ impl ProcessModule for Help {
let mut view_lines: Vec<ViewLine> = vec![];
- for line in get_help_lines(&self.return_state) {
+ for line in self.get_help_lines() {
view_lines.push(ViewLine::new(vec![
LineSegment::new_with_color(format!(" {:4} ", line.0).as_str(), WindowColor::IndicatorColor),
LineSegment::new(line.1),
@@ -94,11 +83,27 @@ impl ProcessModule for Help {
}
}
-impl Help {
- pub fn new() -> Self {
+impl<'h> Help<'h> {
+ pub fn new(config: &'h Config) -> Self {
Self {
+ normal_mode_help_lines: get_list_normal_mode_help_lines(config),
return_state: State::List(false),
scroll_position: ScrollPosition::new(3, 6, 3),
+ visual_mode_help_lines: get_list_visual_mode_help_lines(config),
+ }
+ }
+
+ pub fn get_help_lines(&self) -> &[(String, &str)] {
+ if let State::List(visual_mode) = self.return_state {
+ if visual_mode {
+ &self.visual_mode_help_lines
+ }
+ else {
+ &self.normal_mode_help_lines
+ }
+ }
+ else {
+ &[]
}
}
}
diff --git a/src/help/mod.rs b/src/help/mod.rs
index 013e492..d5aa82e 100644
--- a/src/help/mod.rs
+++ b/src/help/mod.rs
@@ -1,4 +1,5 @@
#[allow(clippy::module_inception)]
mod help;
+mod utils;
pub use self::help::Help;
diff --git a/src/help/utils.rs b/src/help/utils.rs
new file mode 100644
index 0000000..7a8a97d
--- /dev/null
+++ b/src/help/utils.rs
@@ -0,0 +1,90 @@
+use crate::Config;
+
+pub fn get_list_normal_mode_help_lines(config: &Config) -> [(String, &str); 21] {
+ [
+ (String::from("Up"), "Move selection up"),
+ (String::from("Down"), "Move selection down"),
+ (String::from("PgUp"), "Move selection up 5 lines"),
+ (String::from("PgDn"), "Move selection down 5 lines"),
+ (config.input_abort.to_string(), "Abort interactive rebase"),
+ (
+ config.input_force_abort.to_string(),
+ "Immediately abort interactive rebase",
+ ),
+ (config.input_rebase.to_string(), "Write interactive rebase file"),
+ (
+ config.input_force_rebase.to_string(),
+ "Immediately write interactive rebase file",
+ ),
+ (config.input_help.to_string(), "Show help"),
+ (config.input_show_commit.to_string(), "Show commit information"),
+ (
+ config.input_move_selection_down.to_string(),
+ "Move selected commit down",
+ ),
+ (config.input_move_selection_up.to_string(), "Move selected commit up"),
+ (config.input_action_break.to_string(), "Toggle break action"),
+ (config.input_action_pick.to_string(), "Set selected commit to be picked"),
+ (
+ config.input_action_reword.to_string(),
+ "Set selected commit to be reworded",
+ ),
+ (config.input_action_edit.to_string(), "Set selected commit to be edited"),
+ (
+ config.input_action_squash.to_string(),
+ "Set selected commit to be squashed",
+ ),
+ (
+ config.input_action_fixup.to_string(),
+ "Set selected commit to be fixed-up",
+ ),
+ (
+ config.input_action_drop.to_string(),
+ "Set selected commit to be dropped",
+ ),
+ (config.input_edit.to_string(), "Edit an exec action's command"),
+ (
+ config.input_open_in_external_editor.to_string(),
+ "Open the todo file in the default editor",
+ ),
+ ]
+}
+
+pub fn get_list_visual_mode_help_lines(config: &Config) -> [(String, &str); 13] {
+ [
+ (String::from("Up"), "Move selection up"),
+ (String::from("Down"), "Move selection down"),
+ (String::from("PgUp"), "Move selection up 5 lines"),
+ (String::from("PgDn"), "Move selection down 5 lines"),
+ (config.input_help.to_string(), "Show help"),
+ (
+ config.input_move_selection_down.to_string(),
+ "Move selected commits down",
+ ),
+ (config.input_move_selection_up.to_string(), "Move selected commits up"),
+ (
+ config.input_action_pick.to_string(),
+ "Set selected commits to be picked",
+ ),
+ (
+ config.input_action_reword.to_string(),
+ "Set selected commits to be reworded",
+ ),
+ (
+ config.input_action_edit.to_string(),
+ "Set selected commits to be edited",
+ ),
+ (
+ config.input_action_squash.to_string(),
+ "Set selected commits to be squashed",
+ ),
+ (
+ config.input_action_fixup.to_string(),
+ "Set selected commits to be fixed-up",
+ ),
+ (
+ config.input_action_drop.to_string(),
+ "Set selected commits to be dropped",
+ ),
+ ]
+}
diff --git a/src/input/input_handler.rs b/src/input/input_handler.rs
index aeefe00..3de6023 100644
--- a/src/input/input_handler.rs
+++ b/src/input/input_handler.rs
@@ -1,14 +1,22 @@
use crate::input::Input;
use crate::window::Window;
+use crate::Config;
use pancurses::Input as PancursesInput;
pub struct InputHandler<'i> {
+ config: &'i Config,
+ confirm_yes_input: char,
window: &'i Window<'i>,
}
impl<'i> InputHandler<'i> {
- pub fn new(window: &'i Window) -> Self {
- Self { window }
+ pub fn new(window: &'i Window, config: &'i Config) -> Self {
+ let confirm_yes_input = config.input_confirm_yes.to_lowercase().chars().next().unwrap_or('y');
+ Self {
+ config,
+ confirm_yes_input,
+ window,
+ }
}
pub fn get_input(&self) -> Input {
@@ -20,37 +28,54 @@ impl<'i> InputHandler<'i> {
}
};
- match c {
- PancursesInput::Character(c) if c == '?' => Input::Help,
- PancursesInput::Character(c) if c == 'c' => Input::ShowCommit,
- PancursesInput::Character(c) if c == 'q' => Input::Abort,
- PancursesInput::Character(c) if c == 'Q' => Input::ForceAbort,
- PancursesInput::Character(c) if c == 'w' => Input::Rebase,
- PancursesInput::Character(c) if c == 'W' => Input::ForceRebase,
- PancursesInput::Character(c) if c == 'p' => Input::ActionPick,
- PancursesInput::Character(c) if c == 'b' => Input::ActionBreak,
- PancursesInput::Character(c) if c == 'r' => Input::ActionReword,
- PancursesInput::Character(c) if c == 'e' => Input::ActionEdit,
- PancursesInput::Character(c) if c == 's' => Input::ActionSquash,
- PancursesInput::Character(c) if c == 'f' => Input::ActionFixup,
- PancursesInput::Character(c) if c == 'd' => Input::ActionDrop,
- PancursesInput::Character(c) if c == 'E' => Input::Edit,
- PancursesInput::Character(c) if c == 'v' => Input::ToggleVisualMode,
- PancursesInput::Character(c) if c == 'j' => Input::SwapSelectedDown,
- PancursesInput::Character(c) if c == 'k' => Input::SwapSelectedUp,
- PancursesInput::KeyDown => Input::MoveCursorDown,
- PancursesInput::KeyUp => Input::MoveCursorUp,
- PancursesInput::KeyPPage => Input::MoveCursorPageUp,
- PancursesInput::KeyNPage => Input::MoveCursorPageDown,
- PancursesInput::KeyResize => Input::Resize,
- PancursesInput::Character(c) if c == '!' => Input::OpenInEditor,
+ let input = match c {
+ PancursesInput::Character(c) => c.to_string(),
+ PancursesInput::KeyDown => String::from("Down"),
+ PancursesInput::KeyUp => String::from("Up"),
+ PancursesInput::KeyPPage => String::from("PageUp"),
+ PancursesInput::KeyNPage => String::from("PageDown"),
+ PancursesInput::KeyResize => String::from("Resize"),
+ _ => String::from("Other"),
+ };
+
+ match input.as_str() {
+ i if i == self.config.input_abort.as_str() => Input::Abort,
+ i if i == self.config.input_action_break.as_str() => Input::ActionBreak,
+ i if i == self.config.input_action_drop.as_str() => Input::ActionDrop,
+ i if i == self.config.input_action_drop.as_str() => Input::Help,
+ i if i == self.config.input_action_edit.as_str() => Input::ActionEdit,
+ i if i == self.config.input_action_fixup.as_str() => Input::ActionFixup,
+ i if i == self.config.input_action_pick.as_str() => Input::ActionPick,
+ i if i == self.config.input_action_reword.as_str() => Input::ActionReword,
+ i if i == self.config.input_action_squash.as_str() => Input::ActionSquash,
+ i if i == self.config.input_edit.as_str() => Input::Edit,
+ i if i == self.config.input_force_abort.as_str() => Input::ForceAbort,
+ i if i == self.config.input_force_rebase.as_str() => Input::ForceRebase,
+ i if i == self.config.input_move_down.as_str() => Input::MoveCursorDown,
+ i if i == self.config.input_move_selection_down.as_str() => Input::SwapSelectedDown,
+ i if i == self.config.input_move_selection_up.as_str() => Input::SwapSelectedUp,
+ i if i == self.config.input_move_up.as_str() => Input::MoveCursorUp,
+ i if i == self.config.input_open_in_external_editor.as_str() => Input::OpenInEditor,
+ i if i == self.config.input_rebase.as_str() => Input::Rebase,
+ i if i == self.config.input_show_commit.as_str() => Input::ShowCommit,
+ i if i == self.config.input_toggle_visual_mode.as_str() => Input::ToggleVisualMode,
+ "PageUp" => Input::MoveCursorPageUp,
+ "PageDown" => Input::MoveCursorPageDown,
+ "Resize" => Input::Resize,
_ => Input::Other,
}
}
pub fn get_confirm(&self) -> Input {
match self.window.getch() {
- Some(PancursesInput::Character(c)) if c == 'y' || c == 'Y' => Input::Yes,
+ Some(PancursesInput::Character(c)) => {
+ if c.to_lowercase().next().unwrap() == self.confirm_yes_input {
+ Input::Yes
+ }
+ else {
+ Input::No
+ }
+ },
Some(PancursesInput::KeyResize) => Input::Resize,
_ => Input::No,
}
diff --git a/src/list/list.rs b/src/list/list.rs
index f604d92..60c3eaa 100644
--- a/src/list/list.rs
+++ b/src/list/list.rs
@@ -1,20 +1,16 @@
use crate::action::Action;
use crate::config::Config;
-use crate::constants::{
- LIST_FOOTER_COMPACT,
- LIST_FOOTER_COMPACT_WIDTH,
- LIST_FOOTER_FULL,
- LIST_FOOTER_FULL_WIDTH,
- MINIMUM_FULL_WINDOW_WIDTH,
- VISUAL_MODE_FOOTER_COMPACT,
- VISUAL_MODE_FOOTER_COMPACT_WIDTH,
- VISUAL_MODE_FOOTER_FULL,
- VISUAL_MODE_FOOTER_FULL_WIDTH,
-};
+use crate::constants::MINIMUM_FULL_WINDOW_WIDTH;
use crate::git_interactive::GitInteractive;
use crate::input::{Input, InputHandler};
use crate::line::Line;
-use crate::list::get_action_color;
+use crate::list::utils::{
+ get_action_color,
+ get_normal_footer_compact,
+ get_normal_footer_full,
+ get_visual_footer_compact,
+ get_visual_footer_full,
+};
use crate::process::{ExitStatus, HandleInputResult, HandleInputResultBuilder, ProcessModule, ProcessResult, State};
use crate::scroll::ScrollPosition;
use crate::view::{LineSegment, View, ViewLine};
@@ -29,8 +25,12 @@ enum ListState {
pub struct List<'l> {
config: &'l Config,
+ normal_footer_compact: String,
+ normal_footer_full: String,
scroll_position: ScrollPosition,
state: ListState,
+ visual_footer_compact: String,
+ visual_footer_full: String,
}
impl<'l> ProcessModule for List<'l> {
@@ -85,24 +85,24 @@ impl<'l> ProcessModule for List<'l> {
view.set_color(WindowColor::Foreground);
view.set_style(true, false, false);
if is_visual_mode {
- if view_width >= VISUAL_MODE_FOOTER_FULL_WIDTH {
- view.draw_str(VISUAL_MODE_FOOTER_FULL);
+ if view_width >= self.visual_footer_full.len() {
+ view.draw_str(self.visual_footer_full.as_str());
}
- else if view_width >= VISUAL_MODE_FOOTER_COMPACT_WIDTH {
- view.draw_str(VISUAL_MODE_FOOTER_COMPACT);
+ else if view_width >= self.visual_footer_compact.len() {
+ view.draw_str(self.visual_footer_compact.as_str());
}
else {
- view.draw_str("(Visual) Help: ?");
+ view.draw_str(format!("(Visual) Help: {}", self.config.input_help).as_str());
}
}
- else if view_width >= LIST_FOOTER_FULL_WIDTH {
- view.draw_str(LIST_FOOTER_FULL);
+ else if view_width >= self.normal_footer_full.len() {
+ view.draw_str(self.normal_footer_full.as_str());
}
- else if view_width >= LIST_FOOTER_COMPACT_WIDTH {
- view.draw_str(LIST_FOOTER_COMPACT);
+ else if view_width >= self.normal_footer_compact.len() {
+ view.draw_str(self.normal_footer_compact.as_str());
}
else {
- view.draw_str("Help: ?");
+ view.draw_str(format!("Help: {}", self.config.input_help).as_str());
}
view.set_style(false, false, false);
}
@@ -112,8 +112,12 @@ impl<'l> List<'l> {
pub fn new(config: &'l Config) -> Self {
Self {
config,
+ normal_footer_compact: get_normal_footer_compact(config),
+ normal_footer_full: get_normal_footer_full(config),
scroll_position: ScrollPosition::new(2, 1, 1),
state: ListState::Normal,
+ visual_footer_compact: get_visual_footer_compact(config),
+ visual_footer_full: get_visual_footer_full(config),
}
}
diff --git a/src/list/utils.rs b/src/list/utils.rs
index 8794ae7..1fd19c0 100644
--- a/src/list/utils.rs
+++ b/src/list/utils.rs
@@ -1,5 +1,6 @@
use crate::action::Action;
use crate::window::WindowColor;
+use crate::Config;
pub fn get_action_color(action: Action) -> WindowColor {
match action {
@@ -13,3 +14,79 @@ pub fn get_action_color(action: Action) -> WindowColor {
Action::Squash => WindowColor::ActionSquash,
}
}
+
+pub fn get_normal_footer_full(config: &Config) -> String {
+ format!(
+ " up, down, {}/{}, {}/{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}",
+ config.input_abort,
+ config.input_force_abort,
+ config.input_rebase,
+ config.input_force_rebase,
+ config.input_show_commit,
+ config.input_move_selection_down,
+ config.input_move_selection_up,
+ config.input_action_break,
+ config.input_action_pick,
+ config.input_action_reword,
+ config.input_action_edit,
+ config.input_action_squash,
+ config.input_action_fixup,
+ config.input_action_drop,
+ config.input_edit,
+ config.input_open_in_external_editor,
+ config.input_help,
+ )
+}
+
+pub fn get_visual_footer_full(config: &Config) -> String {
+ format!(
+ " up, down, {}, {}, {}, {}, {}, {}, {}, {}, {}",
+ config.input_move_selection_down,
+ config.input_move_selection_up,
+ config.input_action_pick,
+ config.input_action_reword,
+ config.input_action_edit,
+ config.input_action_squash,
+ config.input_action_fixup,
+ config.input_action_drop,
+ config.input_help,
+ )
+}
+
+pub fn get_normal_footer_compact(config: &Config) -> String {
+ format!(
+ "up,dn,{}/{},{}/{},{},{},{},{},{},{},{},{},{},{},{},{},{}",
+ config.input_abort,
+ config.input_force_abort,
+ config.input_rebase,
+ config.input_force_rebase,
+ config.input_show_commit,
+ config.input_move_selection_down,
+ config.input_move_selection_up,
+ config.input_action_break,
+ config.input_action_pick,
+ config.input_action_reword,
+ config.input_action_edit,
+ config.input_action_squash,
+ config.input_action_fixup,
+ config.input_action_drop,
+ config.input_edit,
+ config.input_open_in_external_editor,
+ config.input_help,
+ )
+}
+
+pub fn get_visual_footer_compact(config: &Config) -> String {
+ format!(
+ "up,dn,{},{},{},{},{},{},{},{},{}",
+ config.input_move_selection_down,
+ config.input_move_selection_up,
+ config.input_action_pick,
+ config.input_action_reword,
+ config.input_action_edit,
+ config.input_action_squash,
+ config.input_action_fixup,
+ config.input_action_drop,
+ config.input_help,
+ )
+}
diff --git a/src/main.rs b/src/main.rs
index 38bdc42..0c4edd0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -81,9 +81,9 @@ fn try_main() -> Result<ExitStatus, Exit> {
let window = Window::new(&config);
- let input_handler = InputHandler::new(&window);
+ let input_handler = InputHandler::new(&window, &config);
- let view = View::new(&window);
+ let view = View::new(&window, &config);
let mut process = Process::new(git_interactive, &view, &input_handler, &config);
diff --git a/src/process/process.rs b/src/process/process.rs
index d316162..fffe5bf 100644
--- a/src/process/process.rs
+++ b/src/process/process.rs
@@ -25,7 +25,7 @@ pub struct Process<'r> {
exiting: Exiting,
external_editor: ExternalEditor<'r>,
git_interactive: GitInteractive,
- help: Help,
+ help: Help<'r>,
input_handler: &'r InputHandler<'r>,
list: List<'r>,
show_commit: ShowCommit,
@@ -51,7 +51,7 @@ impl<'r> Process<'r> {
exiting: Exiting::new(),
external_editor: ExternalEditor::new(config),
git_interactive,
- help: Help::new(),
+ help: Help::new(config),
input_handler,
list: List::new(config),
show_commit: ShowCommit::new(),
diff --git a/src/view/view.rs b/src/view/view.rs
index 898cffb..48a377d 100644
--- a/src/view/view.rs
+++ b/src/view/view.rs
@@ -2,7 +2,6 @@ use crate::constants::{
MINIMUM_COMPACT_WINDOW_WIDTH,
MINIMUM_WINDOW_HEIGHT,
TITLE,
- TITLE_HELP_INDICATOR,
TITLE_HELP_INDICATOR_LENGTH,
TITLE_LENGTH,
TITLE_SHORT,
@@ -12,14 +11,16 @@ use crate::scroll::get_scroll_position;
use crate::view::ViewLine;
use crate::window::Window;
use crate::window::WindowColor;
+use crate::Config;
pub struct View<'v> {
+ config: &'v Config,
window: &'v Window<'v>,
}
impl<'v> View<'v> {
- pub fn new(window: &'v Window) -> Self {
- Self { window }
+ pub fn new(window: &'v Window, config: &'v Config) -> Self {
+ Self { window, config }
}
pub fn draw_str(&self, s: &str) {
@@ -116,7 +117,8 @@ impl<'v> View<'v> {
self.window.draw_str(padding.as_str());
}
if show_help {
- self.window.draw_str(TITLE_HELP_INDICATOR);
+ self.window
+ .draw_str(format!("Help: {}", self.config.inp