feat(cli): add the ability to specify a custom keybinding/symbols file via the cli (#2731)

This commit is contained in:
0x61nas 2025-12-01 18:19:33 +02:00 committed by GitHub
parent 92e3b739d7
commit e1029b00d1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 58 additions and 10 deletions

View file

@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* add `use_selection_fg` to theme file to allow customizing selection foreground color [[@Upsylonbare](https://github.com/Upsylonbare)] ([#2515](https://github.com/gitui-org/gitui/pull/2515))
* add "go to line" command for the blame view [[@andrea-berling](https://github.com/andrea-berling)] ([#2262](https://github.com/extrawurst/gitui/pull/2262))
* add `--file` cli flag to open the files tab with the given file already selected [[@laktak](https://github.com/laktak)] ([#2510](https://github.com/gitui-org/gitui/issues/2510))
* add the ability to specify a custom keybinding/symbols file via the cli [[@0x61nas](https://github.com/0x61nas)] ([#2731](https://github.com/gitui-org/gitui/pull/2731))
### Changed
* execute git-hooks directly if possible (on *nix) else use sh instead of bash (without reading SHELL variable) [[@Joshix](https://github.com/Joshix-1)] ([#2483](https://github.com/extrawurst/gitui/pull/2483))

View file

@ -20,6 +20,8 @@ const WORKDIR_FLAG_ID: &str = "workdir";
const FILE_FLAG_ID: &str = "file";
const GIT_DIR_FLAG_ID: &str = "directory";
const WATCHER_FLAG_ID: &str = "watcher";
const KEY_BINDINGS_FLAG_ID: &str = "key_bindings";
const KEY_SYMBOLS_FLAG_ID: &str = "key_symbols";
const DEFAULT_THEME: &str = "theme.ron";
const DEFAULT_GIT_DIR: &str = ".";
@ -29,6 +31,8 @@ pub struct CliArgs {
pub select_file: Option<PathBuf>,
pub repo_path: RepoPath,
pub notify_watcher: bool,
pub key_bindings_path: Option<PathBuf>,
pub key_symbols_path: Option<PathBuf>,
}
pub fn process_cmdline() -> Result<CliArgs> {
@ -80,11 +84,21 @@ pub fn process_cmdline() -> Result<CliArgs> {
let notify_watcher: bool =
*arg_matches.get_one(WATCHER_FLAG_ID).unwrap_or(&false);
let key_bindings_path = arg_matches
.get_one::<String>(KEY_BINDINGS_FLAG_ID)
.map(PathBuf::from);
let key_symbols_path = arg_matches
.get_one::<String>(KEY_SYMBOLS_FLAG_ID)
.map(PathBuf::from);
Ok(CliArgs {
theme,
select_file,
repo_path,
notify_watcher,
key_bindings_path,
key_symbols_path,
})
}
@ -103,6 +117,22 @@ fn app() -> ClapApp {
{all-args}{after-help}
",
)
.arg(
Arg::new(KEY_BINDINGS_FLAG_ID)
.help("Use a custom keybindings file")
.short('k')
.long("key-bindings")
.value_name("KEY_LIST_FILENAME")
.num_args(1),
)
.arg(
Arg::new(KEY_SYMBOLS_FLAG_ID)
.help("Use a custom symbols file")
.short('s')
.long("key-symbols")
.value_name("KEY_SYMBOLS_FILENAME")
.num_args(1),
)
.arg(
Arg::new(THEME_FLAG_ID)

View file

@ -34,9 +34,21 @@ impl KeyConfig {
.map_or_else(|_| Ok(symbols_file), Ok)
}
pub fn init() -> Result<Self> {
let keys = KeysList::init(Self::get_config_file()?);
let symbols = KeySymbols::init(Self::get_symbols_file()?);
pub fn init(
key_bindings_path: Option<&PathBuf>,
key_symbols_path: Option<&PathBuf>,
) -> Result<Self> {
let keys = KeysList::init(
key_bindings_path
.unwrap_or(&Self::get_config_file()?)
.clone(),
);
let symbols = KeySymbols::init(
key_symbols_path
.unwrap_or(&Self::get_symbols_file()?)
.clone(),
);
Ok(Self { keys, symbols })
}
@ -185,7 +197,7 @@ mod tests {
// testing
let result = std::panic::catch_unwind(|| {
let loaded_config = KeyConfig::init().unwrap();
let loaded_config = KeyConfig::init(None, None).unwrap();
assert_eq!(
loaded_config.keys.move_down,
KeysList::default().move_down
@ -200,7 +212,7 @@ mod tests {
&original_key_symbols_path,
)
.unwrap();
let loaded_config = KeyConfig::init().unwrap();
let loaded_config = KeyConfig::init(None, None).unwrap();
assert_eq!(
loaded_config.keys.move_down,
KeysList::default().move_down
@ -212,7 +224,7 @@ mod tests {
&original_key_list_path,
)
.unwrap();
let loaded_config = KeyConfig::init().unwrap();
let loaded_config = KeyConfig::init(None, None).unwrap();
assert_eq!(
loaded_config.keys.move_down,
GituiKeyEvent::new(
@ -223,7 +235,7 @@ mod tests {
assert_eq!(loaded_config.symbols.esc, "Esc");
fs::remove_file(&original_key_symbols_path).unwrap();
let loaded_config = KeyConfig::init().unwrap();
let loaded_config = KeyConfig::init(None, None).unwrap();
assert_eq!(
loaded_config.keys.move_down,
GituiKeyEvent::new(

View file

@ -170,9 +170,12 @@ fn main() -> Result<()> {
asyncgit::register_tracing_logging();
ensure_valid_path(&cliargs.repo_path)?;
let key_config = KeyConfig::init()
.map_err(|e| log_eprintln!("KeyConfig loading error: {e}"))
.unwrap_or_default();
let key_config = KeyConfig::init(
cliargs.key_bindings_path.as_ref(),
cliargs.key_symbols_path.as_ref(),
)
.map_err(|e| log_eprintln!("KeyConfig loading error: {e}"))
.unwrap_or_default();
let theme = Theme::init(&cliargs.theme);
setup_terminal()?;
@ -212,6 +215,8 @@ fn main() -> Result<()> {
select_file: None,
theme: args.theme,
notify_watcher: args.notify_watcher,
key_bindings_path: args.key_bindings_path,
key_symbols_path: args.key_symbols_path,
}
}
_ => break,