diff --git a/Cargo.toml b/Cargo.toml index 8bb25bf..d66c8f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = ["libs/deob"] [dependencies] clap = { version = "4.5", features = ["std", "help", "usage", "derive", "error-context"], default-features = false } +clap_complete = "4.5" serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.9" quick-xml = { version = "0.37", features = ["escape-html", "serialize"], default-features = false } diff --git a/README.md b/README.md index ea90f0f..bbab25b 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,13 @@ sowie die Anzeige anhand eines Profils angepasst. Wird in einer OSC-Datei eine noch nicht bekannte Eigenschaft erkannt, wird die weitere Bearbeitung abgebrochen, um keine unvollständigen Ausgabedateien zu erzeugen. +### Command Completion + +Die Anwendung kann selbständig Scripte zur automatischen Ergänzung der Unterbefehle erstellen, +sollte dies nicht im Installationspaket enthalten sein. + +Weitere Informationen hier: [Command Completion](docs/completions.md) + ### Beispiele Die folgenden Unterbefehle sind verfügbar diff --git a/build.rs b/build.rs index e0ed92c..56a08a8 100644 --- a/build.rs +++ b/build.rs @@ -18,16 +18,16 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -use std::fs; -use std::io::Error; - +use clap::CommandFactory; use clap_complete::generate_to; use clap_complete::Shell::Bash; +use std::fs; +use std::io::Error; include!("src/cli.rs"); fn main() -> Result<(), Error> { - let mut cmd = build_cli(); + let mut cmd = Cli::command(); let package_name = std::env::var("CARGO_CRATE_NAME").unwrap_or("osc-variant".to_string()); diff --git a/docs/completions.md b/docs/completions.md new file mode 100644 index 0000000..35523e2 --- /dev/null +++ b/docs/completions.md @@ -0,0 +1,52 @@ +## Command Completion + +Die Anwendung kann selbständig Scripte zur automatischen Ergänzung der Unterbefehle erstellen, +sollte dies nicht im Installationspaket enthalten sein. + +### Bash + +Erzeugen des Completion-Files mit: + +```bash +mkdir -p ~/.local/share/bash-completion/completions +osc-variant completion bash > ~/.local/share/bash-completion/completions/osc-variant +``` + +Nach einem Neustart des Terminals sollte nun die Completion verfügbar sein. +Alternativ kann im aktuellen Terminal auch folgendes angewendet werden: + +```bash +source <(osc-variant completion bash) +``` + +### Zsh + +Erzeugen des Completions-Files mit: + +```sh +mkdir -p ~/.osc-variant/completions +osc-variant completion zsh > ~/.osc-variant/completions/_osc-variant +``` + +Hinzufügen zur Umgebungsvariable `FPATH` zur Konfiguration mit: + +```sh +cat <<"EOT" >> ~/.zshrc +FPATH="$HOME/.osc-variant/completions:$FPATH" +autoload -Uz compinit +compinit +EOT +``` + +Nach einem Neustart des Terminals sollte nun die Completion verfügbar sein. + +### Fish + +Erzeugen des Completions-Files mit: + +```sh +mkdir -p ~/.config/fish/completions +osc-variant completion fish > ~/.config/fish/completions/osc-variant.fish +``` + +Die Completion sollte sofort verfügbar sein. \ No newline at end of file diff --git a/src/cli.rs b/src/cli.rs index 505f4b6..f19e18f 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -18,12 +18,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -use clap::{Command, CommandFactory, Parser, Subcommand}; - -#[allow(dead_code)] -fn build_cli() -> Command { - Cli::command() -} +use clap::{Parser, Subcommand}; +use clap_complete::Shell; #[derive(Parser)] #[command(author, version, about)] @@ -35,6 +31,12 @@ pub struct Cli { #[derive(Subcommand)] pub enum SubCommand { + #[command( + name = "completion", + about = "Erzeuge und gebe Command-Completion aus", + hide = true + )] + Completion { shell: Shell }, #[command( name = "sha256sum", about = "Berechne SHA256 Prüfsumme für die angegebene Datei" diff --git a/src/commands.rs b/src/commands.rs index 04dd16a..df5f302 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -18,6 +18,18 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +use crate::checks::{check_file, print_checks, CheckNotice}; +use crate::cli::{Cli, SubCommand}; +use crate::file_io::{FileError, FileReader, InputFile}; +use crate::model::onkostar_editor::OnkostarEditor; +use crate::profile::Profile; +use clap::CommandFactory; +use clap_complete::generate; +use console::style; +use dialoguer::Confirm; +use quick_xml::se::Serializer; +use serde::Serialize; +use sha256::digest; use std::error::Error; use std::fs; use std::fs::OpenOptions; @@ -25,18 +37,6 @@ use std::io::Write; use std::ops::Add; use std::path::{Path, PathBuf}; -use console::style; -use dialoguer::Confirm; -use quick_xml::se::Serializer; -use serde::Serialize; -use sha256::digest; - -use crate::checks::{check_file, print_checks, CheckNotice}; -use crate::cli::SubCommand; -use crate::file_io::{FileError, FileReader, InputFile}; -use crate::model::onkostar_editor::OnkostarEditor; -use crate::profile::Profile; - fn write_outputfile(filename: String, content: &String) -> Result<(), FileError> { OpenOptions::new() .read(false) @@ -52,6 +52,15 @@ fn write_outputfile(filename: String, content: &String) -> Result<(), FileError> pub fn handle(command: SubCommand) -> Result<(), Box> { match command { + SubCommand::Completion { shell } => { + let command = &mut Cli::command(); + generate( + shell, + command, + command.get_name().to_string(), + &mut std::io::stdout(), + ); + } SubCommand::List { inputfile, sorted,