mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-06 03:25:23 +00:00
feat(cli): allow passing custom keybindings through the cli (#409)
Fixes #134
This commit is contained in:
parent
3a5b5ec0cc
commit
3222037a02
15
man/tv.1
15
man/tv.1
@ -1,10 +1,10 @@
|
|||||||
.ie \n(.g .ds Aq \(aq
|
.ie \n(.g .ds Aq \(aq
|
||||||
.el .ds Aq '
|
.el .ds Aq '
|
||||||
.TH television 1 "television 0.10.9"
|
.TH television 1 "television 0.10.10"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
television \- A cross\-platform, fast and extensible general purpose fuzzy finder TUI.
|
television \- A cross\-platform, fast and extensible general purpose fuzzy finder TUI.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
\fBtelevision\fR [\fB\-p\fR|\fB\-\-preview\fR] [\fB\-\-no\-preview\fR] [\fB\-\-delimiter\fR] [\fB\-t\fR|\fB\-\-tick\-rate\fR] [\fB\-f\fR|\fB\-\-frame\-rate\fR] [\fB\-\-passthrough\-keybindings\fR] [\fB\-i\fR|\fB\-\-input\fR] [\fB\-\-autocomplete\-prompt\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fICHANNEL\fR] [\fIPATH\fR] [\fIsubcommands\fR]
|
\fBtelevision\fR [\fB\-p\fR|\fB\-\-preview\fR] [\fB\-\-no\-preview\fR] [\fB\-\-delimiter\fR] [\fB\-t\fR|\fB\-\-tick\-rate\fR] [\fB\-f\fR|\fB\-\-frame\-rate\fR] [\fB\-k\fR|\fB\-\-keybindings\fR] [\fB\-\-passthrough\-keybindings\fR] [\fB\-i\fR|\fB\-\-input\fR] [\fB\-\-autocomplete\-prompt\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fICHANNEL\fR] [\fIPATH\fR] [\fIsubcommands\fR]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
A cross\-platform, fast and extensible general purpose fuzzy finder TUI.
|
A cross\-platform, fast and extensible general purpose fuzzy finder TUI.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
@ -44,6 +44,15 @@ compromise for most users.
|
|||||||
|
|
||||||
This option is deprecated and will be removed in a future release.
|
This option is deprecated and will be removed in a future release.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-k\fR, \fB\-\-keybindings\fR=\fISTRING\fR
|
||||||
|
Keybindings to override the default keybindings.
|
||||||
|
|
||||||
|
This can be used to override the default keybindings with a custom subset
|
||||||
|
The keybindings are specified as a semicolon separated list of keybinding
|
||||||
|
expressions using the configuration file formalism.
|
||||||
|
|
||||||
|
Example: `tv \-\-keybindings=\*(Aqquit="esc";select_next_entry=["down","ctrl\-j"]\*(Aq`
|
||||||
|
.TP
|
||||||
\fB\-\-passthrough\-keybindings\fR=\fISTRING\fR
|
\fB\-\-passthrough\-keybindings\fR=\fISTRING\fR
|
||||||
Passthrough keybindings (comma separated, e.g. "q,ctrl\-w,ctrl\-t")
|
Passthrough keybindings (comma separated, e.g. "q,ctrl\-w,ctrl\-t")
|
||||||
|
|
||||||
@ -95,6 +104,6 @@ Initializes shell completion ("tv init zsh")
|
|||||||
television\-help(1)
|
television\-help(1)
|
||||||
Print this message or the help of the given subcommand(s)
|
Print this message or the help of the given subcommand(s)
|
||||||
.SH VERSION
|
.SH VERSION
|
||||||
v0.10.9
|
v0.10.10
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
Alexandre Pasmantier <alex.pasmant@gmail.com>
|
Alexandre Pasmantier <alex.pasmant@gmail.com>
|
||||||
|
@ -110,7 +110,7 @@ impl App {
|
|||||||
let (render_tx, render_rx) = mpsc::unbounded_channel();
|
let (render_tx, render_rx) = mpsc::unbounded_channel();
|
||||||
let (_, event_rx) = mpsc::unbounded_channel();
|
let (_, event_rx) = mpsc::unbounded_channel();
|
||||||
let (event_abort_tx, _) = mpsc::unbounded_channel();
|
let (event_abort_tx, _) = mpsc::unbounded_channel();
|
||||||
let tick_rate = config.config.tick_rate;
|
let tick_rate = config.application.tick_rate;
|
||||||
let keybindings = merge_keybindings(config.keybindings.clone(), {
|
let keybindings = merge_keybindings(config.keybindings.clone(), {
|
||||||
&KeyBindings::from(passthrough_keybindings.iter().filter_map(
|
&KeyBindings::from(passthrough_keybindings.iter().filter_map(
|
||||||
|s| match parse_key(s) {
|
|s| match parse_key(s) {
|
||||||
|
@ -56,6 +56,16 @@ pub struct Cli {
|
|||||||
#[arg(short, long, value_name = "FLOAT", verbatim_doc_comment)]
|
#[arg(short, long, value_name = "FLOAT", verbatim_doc_comment)]
|
||||||
pub frame_rate: Option<f64>,
|
pub frame_rate: Option<f64>,
|
||||||
|
|
||||||
|
/// Keybindings to override the default keybindings.
|
||||||
|
///
|
||||||
|
/// This can be used to override the default keybindings with a custom subset
|
||||||
|
/// The keybindings are specified as a semicolon separated list of keybinding
|
||||||
|
/// expressions using the configuration file formalism.
|
||||||
|
///
|
||||||
|
/// Example: `tv --keybindings='quit="esc";select_next_entry=["down","ctrl-j"]'`
|
||||||
|
#[arg(short, long, value_name = "STRING", verbatim_doc_comment)]
|
||||||
|
pub keybindings: Option<String>,
|
||||||
|
|
||||||
/// Passthrough keybindings (comma separated, e.g. "q,ctrl-w,ctrl-t")
|
/// Passthrough keybindings (comma separated, e.g. "q,ctrl-w,ctrl-t")
|
||||||
///
|
///
|
||||||
/// These keybindings will trigger selection of the current entry and be
|
/// These keybindings will trigger selection of the current entry and be
|
||||||
|
@ -9,6 +9,7 @@ use crate::channels::{
|
|||||||
cable::CableChannelPrototype, entry::PreviewCommand, CliTvChannel,
|
cable::CableChannelPrototype, entry::PreviewCommand, CliTvChannel,
|
||||||
};
|
};
|
||||||
use crate::cli::args::{Cli, Command};
|
use crate::cli::args::{Cli, Command};
|
||||||
|
use crate::config::KeyBindings;
|
||||||
use crate::{
|
use crate::{
|
||||||
cable,
|
cable,
|
||||||
config::{get_config_dir, get_data_dir},
|
config::{get_config_dir, get_data_dir},
|
||||||
@ -28,6 +29,7 @@ pub struct PostProcessedCli {
|
|||||||
pub command: Option<Command>,
|
pub command: Option<Command>,
|
||||||
pub working_directory: Option<String>,
|
pub working_directory: Option<String>,
|
||||||
pub autocomplete_prompt: Option<String>,
|
pub autocomplete_prompt: Option<String>,
|
||||||
|
pub keybindings: Option<KeyBindings>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PostProcessedCli {
|
impl Default for PostProcessedCli {
|
||||||
@ -43,12 +45,21 @@ impl Default for PostProcessedCli {
|
|||||||
command: None,
|
command: None,
|
||||||
working_directory: None,
|
working_directory: None,
|
||||||
autocomplete_prompt: None,
|
autocomplete_prompt: None,
|
||||||
|
keybindings: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Cli> for PostProcessedCli {
|
impl From<Cli> for PostProcessedCli {
|
||||||
fn from(cli: Cli) -> Self {
|
fn from(cli: Cli) -> Self {
|
||||||
|
let keybindings: Option<KeyBindings> = cli.keybindings.map(|kb| {
|
||||||
|
parse_keybindings(&kb)
|
||||||
|
.map_err(|e| {
|
||||||
|
cli_parsing_error_exit(&e.to_string());
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
let passthrough_keybindings = cli
|
let passthrough_keybindings = cli
|
||||||
.passthrough_keybindings
|
.passthrough_keybindings
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
@ -62,11 +73,13 @@ impl From<Cli> for PostProcessedCli {
|
|||||||
command: preview,
|
command: preview,
|
||||||
delimiter: cli.delimiter.clone(),
|
delimiter: cli.delimiter.clone(),
|
||||||
})
|
})
|
||||||
.map(|preview_command| {
|
.map_or(PreviewKind::None, |preview_command| {
|
||||||
parse_preview_kind(&preview_command)
|
parse_preview_kind(&preview_command)
|
||||||
.expect("Error parsing preview command")
|
.map_err(|e| {
|
||||||
})
|
cli_parsing_error_exit(&e.to_string());
|
||||||
.unwrap_or(PreviewKind::None);
|
})
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
let channel: ParsedCliChannel;
|
let channel: ParsedCliChannel;
|
||||||
let working_directory: Option<String>;
|
let working_directory: Option<String>;
|
||||||
@ -102,10 +115,16 @@ impl From<Cli> for PostProcessedCli {
|
|||||||
command: cli.command,
|
command: cli.command,
|
||||||
working_directory,
|
working_directory,
|
||||||
autocomplete_prompt: cli.autocomplete_prompt,
|
autocomplete_prompt: cli.autocomplete_prompt,
|
||||||
|
keybindings,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cli_parsing_error_exit(message: &str) {
|
||||||
|
eprintln!("Error parsing CLI arguments: {message}\n");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
fn unknown_channel_exit(channel: &str) {
|
fn unknown_channel_exit(channel: &str) {
|
||||||
eprintln!("Unknown channel: {channel}\n");
|
eprintln!("Unknown channel: {channel}\n");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
@ -117,6 +136,24 @@ pub enum ParsedCliChannel {
|
|||||||
Cable(CableChannelPrototype),
|
Cable(CableChannelPrototype),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CLI_KEYBINDINGS_DELIMITER: char = ';';
|
||||||
|
|
||||||
|
/// Parse the keybindings string into a hashmap of key -> action.
|
||||||
|
///
|
||||||
|
/// The formalism used is the same as the one used in the configuration file:
|
||||||
|
/// ```ignore
|
||||||
|
/// quit="esc";select_next_entry=["down","ctrl-j"]
|
||||||
|
/// ```
|
||||||
|
/// Parsing it globally consists of splitting by the delimiter, reconstructing toml key-value pairs
|
||||||
|
/// and parsing that using logic already implemented in the configuration module.
|
||||||
|
fn parse_keybindings(cli_keybindings: &str) -> Result<KeyBindings> {
|
||||||
|
let toml_definition = cli_keybindings
|
||||||
|
.split(CLI_KEYBINDINGS_DELIMITER)
|
||||||
|
.fold(String::new(), |acc, kb| acc + kb + "\n");
|
||||||
|
|
||||||
|
toml::from_str(&toml_definition).map_err(|e| anyhow!(e))
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_channel(channel: &str) -> Result<ParsedCliChannel> {
|
fn parse_channel(channel: &str) -> Result<ParsedCliChannel> {
|
||||||
let cable_channels = cable::load_cable_channels().unwrap_or_default();
|
let cable_channels = cable::load_cable_channels().unwrap_or_default();
|
||||||
// try to parse the channel as a cable channel
|
// try to parse the channel as a cable channel
|
||||||
@ -259,7 +296,10 @@ Data directory: {data_dir_path}"
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::channels::entry::PreviewType;
|
use crate::{
|
||||||
|
action::Action, channels::entry::PreviewType, config::Binding,
|
||||||
|
event::Key,
|
||||||
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -273,6 +313,7 @@ mod tests {
|
|||||||
delimiter: ":".to_string(),
|
delimiter: ":".to_string(),
|
||||||
tick_rate: Some(50.0),
|
tick_rate: Some(50.0),
|
||||||
frame_rate: Some(60.0),
|
frame_rate: Some(60.0),
|
||||||
|
keybindings: None,
|
||||||
passthrough_keybindings: Some("q,ctrl-w,ctrl-t".to_string()),
|
passthrough_keybindings: Some("q,ctrl-w,ctrl-t".to_string()),
|
||||||
input: None,
|
input: None,
|
||||||
command: None,
|
command: None,
|
||||||
@ -315,6 +356,7 @@ mod tests {
|
|||||||
delimiter: ":".to_string(),
|
delimiter: ":".to_string(),
|
||||||
tick_rate: Some(50.0),
|
tick_rate: Some(50.0),
|
||||||
frame_rate: Some(60.0),
|
frame_rate: Some(60.0),
|
||||||
|
keybindings: None,
|
||||||
passthrough_keybindings: None,
|
passthrough_keybindings: None,
|
||||||
input: None,
|
input: None,
|
||||||
command: None,
|
command: None,
|
||||||
@ -344,6 +386,7 @@ mod tests {
|
|||||||
delimiter: ":".to_string(),
|
delimiter: ":".to_string(),
|
||||||
tick_rate: Some(50.0),
|
tick_rate: Some(50.0),
|
||||||
frame_rate: Some(60.0),
|
frame_rate: Some(60.0),
|
||||||
|
keybindings: None,
|
||||||
passthrough_keybindings: None,
|
passthrough_keybindings: None,
|
||||||
input: None,
|
input: None,
|
||||||
command: None,
|
command: None,
|
||||||
@ -368,6 +411,7 @@ mod tests {
|
|||||||
delimiter: ":".to_string(),
|
delimiter: ":".to_string(),
|
||||||
tick_rate: Some(50.0),
|
tick_rate: Some(50.0),
|
||||||
frame_rate: Some(60.0),
|
frame_rate: Some(60.0),
|
||||||
|
keybindings: None,
|
||||||
passthrough_keybindings: None,
|
passthrough_keybindings: None,
|
||||||
input: None,
|
input: None,
|
||||||
command: None,
|
command: None,
|
||||||
@ -382,4 +426,36 @@ mod tests {
|
|||||||
PreviewKind::Builtin(PreviewType::EnvVar)
|
PreviewKind::Builtin(PreviewType::EnvVar)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_custom_keybindings() {
|
||||||
|
let cli = Cli {
|
||||||
|
channel: "files".to_string(),
|
||||||
|
preview: Some(":env_var:".to_string()),
|
||||||
|
no_preview: false,
|
||||||
|
delimiter: ":".to_string(),
|
||||||
|
tick_rate: Some(50.0),
|
||||||
|
frame_rate: Some(60.0),
|
||||||
|
keybindings: Some(
|
||||||
|
"quit=\"esc\";select_next_entry=[\"down\",\"ctrl-j\"]"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
passthrough_keybindings: None,
|
||||||
|
input: None,
|
||||||
|
command: None,
|
||||||
|
working_directory: None,
|
||||||
|
autocomplete_prompt: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let post_processed_cli: PostProcessedCli = cli.into();
|
||||||
|
|
||||||
|
let mut expected = KeyBindings::default();
|
||||||
|
expected.insert(Action::Quit, Binding::SingleKey(Key::Esc));
|
||||||
|
expected.insert(
|
||||||
|
Action::SelectNextEntry,
|
||||||
|
Binding::MultipleKeys(vec![Key::Down, Key::Ctrl('j')]),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(post_processed_cli.keybindings, Some(expected));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ pub struct Config {
|
|||||||
/// General application configuration
|
/// General application configuration
|
||||||
#[allow(clippy::struct_field_names)]
|
#[allow(clippy::struct_field_names)]
|
||||||
#[serde(default, flatten)]
|
#[serde(default, flatten)]
|
||||||
pub config: AppConfig,
|
pub application: AppConfig,
|
||||||
/// Keybindings configuration
|
/// Keybindings configuration
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub keybindings: KeyBindings,
|
pub keybindings: KeyBindings,
|
||||||
@ -176,7 +176,7 @@ impl Config {
|
|||||||
user.keybindings = keybindings;
|
user.keybindings = keybindings;
|
||||||
|
|
||||||
Config {
|
Config {
|
||||||
config: user.config,
|
application: user.application,
|
||||||
keybindings: user.keybindings,
|
keybindings: user.keybindings,
|
||||||
ui: user.ui,
|
ui: user.ui,
|
||||||
previewers: user.previewers,
|
previewers: user.previewers,
|
||||||
@ -288,8 +288,8 @@ mod tests {
|
|||||||
file.write_all(DEFAULT_CONFIG.as_bytes()).unwrap();
|
file.write_all(DEFAULT_CONFIG.as_bytes()).unwrap();
|
||||||
|
|
||||||
let config = Config::load_user_config(config_dir).unwrap();
|
let config = Config::load_user_config(config_dir).unwrap();
|
||||||
assert_eq!(config.config.data_dir, get_data_dir());
|
assert_eq!(config.application.data_dir, get_data_dir());
|
||||||
assert_eq!(config.config.config_dir, get_config_dir());
|
assert_eq!(config.application.config_dir, get_config_dir());
|
||||||
assert_eq!(config, toml::from_str(DEFAULT_CONFIG).unwrap());
|
assert_eq!(config, toml::from_str(DEFAULT_CONFIG).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +310,7 @@ mod tests {
|
|||||||
toml::from_str(DEFAULT_CONFIG).unwrap();
|
toml::from_str(DEFAULT_CONFIG).unwrap();
|
||||||
default_config.shell_integration.merge_triggers();
|
default_config.shell_integration.merge_triggers();
|
||||||
|
|
||||||
assert_eq!(config.config, default_config.config);
|
assert_eq!(config.application, default_config.application);
|
||||||
assert_eq!(config.keybindings, default_config.keybindings);
|
assert_eq!(config.keybindings, default_config.keybindings);
|
||||||
assert_eq!(config.ui, default_config.ui);
|
assert_eq!(config.ui, default_config.ui);
|
||||||
assert_eq!(config.previewers, default_config.previewers);
|
assert_eq!(config.previewers, default_config.previewers);
|
||||||
@ -364,7 +364,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut default_config: Config =
|
let mut default_config: Config =
|
||||||
toml::from_str(DEFAULT_CONFIG).unwrap();
|
toml::from_str(DEFAULT_CONFIG).unwrap();
|
||||||
default_config.config.frame_rate = 30.0;
|
default_config.application.frame_rate = 30.0;
|
||||||
default_config.ui.ui_scale = 40;
|
default_config.ui.ui_scale = 40;
|
||||||
default_config.ui.theme = "television".to_string();
|
default_config.ui.theme = "television".to_string();
|
||||||
default_config.previewers.file.theme =
|
default_config.previewers.file.theme =
|
||||||
@ -392,7 +392,7 @@ mod tests {
|
|||||||
.insert("command_history".to_string(), "ctrl-h".to_string());
|
.insert("command_history".to_string(), "ctrl-h".to_string());
|
||||||
default_config.shell_integration.merge_triggers();
|
default_config.shell_integration.merge_triggers();
|
||||||
|
|
||||||
assert_eq!(config.config, default_config.config);
|
assert_eq!(config.application, default_config.application);
|
||||||
assert_eq!(config.keybindings, default_config.keybindings);
|
assert_eq!(config.keybindings, default_config.keybindings);
|
||||||
assert_eq!(config.ui, default_config.ui);
|
assert_eq!(config.ui, default_config.ui);
|
||||||
assert_eq!(config.previewers, default_config.previewers);
|
assert_eq!(config.previewers, default_config.previewers);
|
||||||
|
@ -19,7 +19,7 @@ use television::cli::{
|
|||||||
PostProcessedCli,
|
PostProcessedCli,
|
||||||
};
|
};
|
||||||
|
|
||||||
use television::config::{Config, ConfigEnv};
|
use television::config::{merge_keybindings, Config, ConfigEnv};
|
||||||
use television::utils::shell::render_autocomplete_script_template;
|
use television::utils::shell::render_autocomplete_script_template;
|
||||||
use television::utils::{
|
use television::utils::{
|
||||||
shell::{completion_script, Shell},
|
shell::{completion_script, Shell},
|
||||||
@ -45,11 +45,7 @@ async fn main() -> Result<()> {
|
|||||||
args.working_directory.as_ref().map(set_current_dir);
|
args.working_directory.as_ref().map(set_current_dir);
|
||||||
|
|
||||||
// optionally override configuration values with CLI arguments
|
// optionally override configuration values with CLI arguments
|
||||||
config.config.tick_rate =
|
apply_cli_overrides(&args, &mut config);
|
||||||
args.tick_rate.unwrap_or(config.config.tick_rate);
|
|
||||||
if args.no_preview {
|
|
||||||
config.ui.show_preview_panel = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine the channel to use based on the CLI arguments and configuration
|
// determine the channel to use based on the CLI arguments and configuration
|
||||||
let channel =
|
let channel =
|
||||||
@ -76,6 +72,22 @@ async fn main() -> Result<()> {
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Apply overrides from the CLI arguments to the configuration.
|
||||||
|
///
|
||||||
|
/// This function mutates the configuration in place.
|
||||||
|
fn apply_cli_overrides(args: &PostProcessedCli, config: &mut Config) {
|
||||||
|
if let Some(tick_rate) = args.tick_rate {
|
||||||
|
config.application.tick_rate = tick_rate;
|
||||||
|
}
|
||||||
|
if args.no_preview {
|
||||||
|
config.ui.show_preview_panel = false;
|
||||||
|
}
|
||||||
|
if let Some(keybindings) = &args.keybindings {
|
||||||
|
config.keybindings =
|
||||||
|
merge_keybindings(config.keybindings.clone(), keybindings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_current_dir(path: &String) -> Result<()> {
|
pub fn set_current_dir(path: &String) -> Result<()> {
|
||||||
let path = Path::new(path);
|
let path = Path::new(path);
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
@ -239,4 +251,18 @@ mod tests {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_apply_cli_overrides() {
|
||||||
|
let mut config = Config::default();
|
||||||
|
let args = PostProcessedCli {
|
||||||
|
tick_rate: Some(100_f64),
|
||||||
|
no_preview: true,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
apply_cli_overrides(&args, &mut config);
|
||||||
|
|
||||||
|
assert_eq!(config.application.tick_rate, 100_f64);
|
||||||
|
assert!(!config.ui.show_preview_panel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user