diff --git a/assets/completions/_zellij b/assets/completions/_zellij index cd8dce56..8b89db14 100644 --- a/assets/completions/_zellij +++ b/assets/completions/_zellij @@ -22,8 +22,6 @@ _zellij() { '--max-panes=[Maximum panes on screen, caution: opening more panes will close old ones]' \ '-l+[Path to a layout yaml file]' \ '--layout=[Path to a layout yaml file]' \ -'-c+[Path to the configuration yaml file]' \ -'--config=[Path to the configuration yaml file]' \ '-m[Send "move focused pane" to active zellij session]' \ '--move-focus[Send "move focused pane" to active zellij session]' \ '-d[]' \ @@ -32,16 +30,59 @@ _zellij() { '--help[Prints help information]' \ '-V[Prints version information]' \ '--version[Prints version information]' \ +":: :_zellij_commands" \ +"*::: :->zellij" \ && ret=0 - + case $state in + (zellij) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:zellij-command-$line[1]:" + case $line[1] in + (config) +_arguments "${_arguments_options[@]}" \ +'--clean[Disables loading of configuration file at default location]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +'::path:_files' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +&& ret=0 +;; + esac + ;; +esac } (( $+functions[_zellij_commands] )) || _zellij_commands() { local commands; commands=( - + "config:Path to the configuration yaml file" \ +"help:Prints this message or the help of the given subcommand(s)" \ ) _describe -t commands 'zellij commands' commands "$@" } +(( $+functions[_zellij__config_commands] )) || +_zellij__config_commands() { + local commands; commands=( + + ) + _describe -t commands 'zellij config commands' commands "$@" +} +(( $+functions[_zellij__help_commands] )) || +_zellij__help_commands() { + local commands; commands=( + + ) + _describe -t commands 'zellij help commands' commands "$@" +} _zellij "$@" \ No newline at end of file diff --git a/assets/completions/zellij.bash b/assets/completions/zellij.bash index 0ede5cce..549b1e9f 100644 --- a/assets/completions/zellij.bash +++ b/assets/completions/zellij.bash @@ -13,6 +13,12 @@ _zellij() { cmd="zellij" ;; + config) + cmd+="__config" + ;; + help) + cmd+="__help" + ;; *) ;; esac @@ -20,7 +26,7 @@ _zellij() { case "${cmd}" in zellij) - opts=" -m -d -h -V -s -o -l -c --move-focus --debug --help --version --split --open-file --max-panes --layout --config " + opts=" -m -d -h -V -s -o -l --move-focus --debug --help --version --split --open-file --max-panes --layout config help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -55,14 +61,6 @@ _zellij() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --config) - COMPREPLY=($(compgen -f "${cur}")) - return 0 - ;; - -c) - COMPREPLY=($(compgen -f "${cur}")) - return 0 - ;; *) COMPREPLY=() ;; @@ -71,6 +69,36 @@ _zellij() { return 0 ;; + zellij__config) + opts=" -h -V --clean --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + zellij__help) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; esac } diff --git a/assets/completions/zellij.fish b/assets/completions/zellij.fish index eaba9fa4..36bab192 100644 --- a/assets/completions/zellij.fish +++ b/assets/completions/zellij.fish @@ -2,8 +2,14 @@ complete -c zellij -n "__fish_use_subcommand" -s s -l split -d 'Send "split (dir complete -c zellij -n "__fish_use_subcommand" -s o -l open-file -d 'Send "open file in new pane" to active zellij session' complete -c zellij -n "__fish_use_subcommand" -l max-panes -d 'Maximum panes on screen, caution: opening more panes will close old ones' complete -c zellij -n "__fish_use_subcommand" -s l -l layout -d 'Path to a layout yaml file' -complete -c zellij -n "__fish_use_subcommand" -s c -l config -d 'Path to the configuration yaml file' complete -c zellij -n "__fish_use_subcommand" -s m -l move-focus -d 'Send "move focused pane" to active zellij session' complete -c zellij -n "__fish_use_subcommand" -s d -l debug complete -c zellij -n "__fish_use_subcommand" -s h -l help -d 'Prints help information' complete -c zellij -n "__fish_use_subcommand" -s V -l version -d 'Prints version information' +complete -c zellij -n "__fish_use_subcommand" -f -a "config" -d 'Path to the configuration yaml file' +complete -c zellij -n "__fish_use_subcommand" -f -a "help" -d 'Prints this message or the help of the given subcommand(s)' +complete -c zellij -n "__fish_seen_subcommand_from config" -l clean -d 'Disables loading of configuration file at default location' +complete -c zellij -n "__fish_seen_subcommand_from config" -s h -l help -d 'Prints help information' +complete -c zellij -n "__fish_seen_subcommand_from config" -s V -l version -d 'Prints version information' +complete -c zellij -n "__fish_seen_subcommand_from help" -s h -l help -d 'Prints help information' +complete -c zellij -n "__fish_seen_subcommand_from help" -s V -l version -d 'Prints version information' diff --git a/src/cli.rs b/src/cli.rs index 67a92196..740879f0 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use structopt::StructOpt; -#[derive(StructOpt, Debug, Default)] +#[derive(StructOpt, Debug)] #[structopt(name = "zellij")] pub struct CliArgs { /// Send "split (direction h == horizontal / v == vertical)" to active zellij session @@ -24,10 +24,20 @@ pub struct CliArgs { #[structopt(short, long)] pub layout: Option, - /// Path to the configuration yaml file - #[structopt(short, long)] - pub config: Option, + #[structopt(subcommand)] + pub config: Option, #[structopt(short, long)] pub debug: bool, } + +#[derive(Debug, StructOpt)] +pub enum ConfigCli { + /// Path to the configuration yaml file + Config { + path: Option, + #[structopt(long)] + /// Disables loading of configuration file at default location + clean: bool, + }, +} diff --git a/src/common/input/config.rs b/src/common/input/config.rs index d9d1f784..668b4106 100644 --- a/src/common/input/config.rs +++ b/src/common/input/config.rs @@ -6,10 +6,13 @@ use std::io::{self, Read}; use std::path::{Path, PathBuf}; use super::keybinds::{Keybinds, KeybindsFromYaml}; +use crate::cli::ConfigCli; use directories_next::ProjectDirs; use serde::Deserialize; +type ConfigResult = Result; + /// Intermediate deserialisation config struct #[derive(Debug, Deserialize)] pub struct ConfigFromYaml { @@ -41,7 +44,7 @@ impl Default for Config { impl Config { /// Uses defaults, but lets config override them. - pub fn from_yaml(yaml_config: &str) -> Result { + pub fn from_yaml(yaml_config: &str) -> ConfigResult { let config_from_yaml: ConfigFromYaml = serde_yaml::from_str(&yaml_config)?; let keybinds = Keybinds::get_default_keybinds_with_config(config_from_yaml.keybinds); Ok(Config { keybinds }) @@ -49,7 +52,7 @@ impl Config { /// Deserializes from given path. #[allow(unused_must_use)] - pub fn new(path: &Path) -> Result { + pub fn new(path: &Path) -> ConfigResult { match File::open(path) { Ok(mut file) => { let mut yaml_config = String::new(); @@ -57,15 +60,13 @@ impl Config { .map_err(|e| ConfigError::IoPath(e, path.to_path_buf()))?; Ok(Config::from_yaml(&yaml_config)?) } - Err(_) => { - Ok(Config::default()) - } + Err(_) => Ok(Config::default()), } } /// Deserializes the config from an optional path, or a platform specific path, /// merges the default configuration - options take precedence. - pub fn from_option_or_default(option: Option) -> Result { + fn from_option_or_default(option: Option) -> ConfigResult { if let Some(config_path) = option { Ok(Config::new(&config_path)?) } else { @@ -75,6 +76,14 @@ impl Config { Ok(Config::new(&config_path)?) } } + + pub fn from_cli_config(cli_config: Option) -> ConfigResult { + match cli_config { + Some(ConfigCli::Config { clean, .. }) if clean => Ok(Config::default()), + Some(ConfigCli::Config { path, .. }) => Ok(Config::from_option_or_default(path)?), + None => Ok(Config::default()), + } + } } impl Display for ConfigError { diff --git a/src/common/mod.rs b/src/common/mod.rs index 02e75f98..777b615f 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -169,8 +169,7 @@ pub fn start(mut os_input: Box, opts: CliArgs) { let mut app_state = AppState::default(); - #[allow(unused_must_use)] - let config = Config::from_option_or_default(opts.config) + let config = Config::from_cli_config(opts.config) .map_err(|e| { eprintln!("There was an error in the config file:\n{}", e); std::process::exit(1);