Shell completions
This commit is contained in:
parent
c21072727c
commit
49f7746f57
6 changed files with 219 additions and 86 deletions
29
Cargo.lock
generated
29
Cargo.lock
generated
|
@ -86,6 +86,15 @@ dependencies = [
|
|||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.32"
|
||||
|
@ -104,6 +113,16 @@ version = "0.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||
|
||||
[[package]]
|
||||
name = "clap_mangen"
|
||||
version = "0.2.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc33c849748320656a90832f54a5eeecaa598e92557fb5dedebc3355746d31e4"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"roff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.4"
|
||||
|
@ -249,9 +268,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "noise"
|
||||
version = "0.1.4"
|
||||
version = "0.1.6"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_mangen",
|
||||
"libnotify",
|
||||
"mpd",
|
||||
]
|
||||
|
@ -286,6 +307,12 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roff"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
[package]
|
||||
name = "noise"
|
||||
version = "0.1.4"
|
||||
version = "0.1.6"
|
||||
edition = "2024"
|
||||
authors = ["Nox Sluijtman"]
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.39", features = ["derive"] }
|
||||
clap_complete = "4.5.54"
|
||||
libnotify = "1.0.3"
|
||||
mpd = "0.1.0"
|
||||
|
||||
[build-dependencies]
|
||||
clap = { version = "4.5.39", features = ["derive"] }
|
||||
clap_complete = "4.5.54"
|
||||
clap_mangen = "0.2.27"
|
||||
|
|
39
build.rs
Normal file
39
build.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
use clap::{Command, CommandFactory};
|
||||
// use clap_complete as complete;
|
||||
use clap_mangen as mangen;
|
||||
// use complete::Shell;
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
||||
#[path = "src/cli.rs"]
|
||||
mod cli;
|
||||
|
||||
use cli::*;
|
||||
|
||||
fn generate_manpage(cmd: Command, out_dir: PathBuf) -> std::io::Result<()> {
|
||||
let _path = mangen::generate_to(cmd, &out_dir)?;
|
||||
println!("cargo:warning=manpage is generated: {out_dir:?}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// fn generate_completions(cmd: &mut Command, out_dir: PathBuf) -> std::io::Result<()> {
|
||||
// let path = complete::generate_to(Shell::Zsh, cmd, "noise", out_dir)?;
|
||||
// println!("cargo:warning=completion file is generated: {path:?}");
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
let out_dir =
|
||||
std::path::PathBuf::from(std::env::var_os("OUT_DIR").ok_or(std::io::ErrorKind::NotFound)?);
|
||||
|
||||
// let out_dir = PathBuf::from_str("./").unwrap();
|
||||
|
||||
let cmd = Cli::command();
|
||||
|
||||
generate_manpage(cmd, out_dir.clone())?;
|
||||
|
||||
// eprintln!("{out_dir:?}");
|
||||
// println!("cargo:warning=out_dir: {out_dir:?}");
|
||||
|
||||
Ok(())
|
||||
}
|
14
flake.nix
14
flake.nix
|
@ -23,10 +23,24 @@
|
|||
src = ./.;
|
||||
nativeBuildInputs = with pkgs; [
|
||||
libnotify
|
||||
installShellFiles
|
||||
];
|
||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath nativeBuildInputs;
|
||||
|
||||
RUST_SRC_PATH = pkgs.rustPlatform.rustLibSrc;
|
||||
|
||||
postInstall =
|
||||
with pkgs;
|
||||
lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
|
||||
# installShellCompletion --cmd noise \
|
||||
# --bash <($out/bin/fd --generate-completions bash) \
|
||||
# --fish <($out/bin/fd --generate-completions fish)
|
||||
# installShellCompletion --zsh contrib/completion/_fd
|
||||
installShellCompletion --cmd noise \
|
||||
--bash <($out/bin/noise --generate-completions bash) \
|
||||
--zsh <($out/bin/noise --generate-completions zsh) \
|
||||
--fish <($out/bin/noise --generate-completions fish)
|
||||
'';
|
||||
};
|
||||
devShell =
|
||||
with pkgs;
|
||||
|
|
94
src/cli.rs
Normal file
94
src/cli.rs
Normal file
|
@ -0,0 +1,94 @@
|
|||
use clap::{Parser, Subcommand, ValueHint};
|
||||
use clap_complete::Shell;
|
||||
|
||||
#[derive(Parser, Debug, PartialEq)]
|
||||
#[command(
|
||||
author = "Nox Sluijtman",
|
||||
version,
|
||||
about,
|
||||
long_about = "A small, opinionated MPD client",
|
||||
name = "noise"
|
||||
)]
|
||||
#[command(propagate_version = true)]
|
||||
|
||||
pub struct Cli {
|
||||
#[command(subcommand)]
|
||||
pub command: Option<Commands>,
|
||||
|
||||
/// Enables verbose output
|
||||
#[arg(short, long, global = true)]
|
||||
pub verbose: bool,
|
||||
/// Hostname where MPD listens at
|
||||
#[arg(short = 'H', long, global = true)]
|
||||
pub host: Option<String>,
|
||||
|
||||
/// Generate shell completions
|
||||
#[arg(long = "generate-completions", value_enum)]
|
||||
pub completions: Option<Shell>,
|
||||
// /// Generate manpage
|
||||
// #[arg(long = "generate-manpage", value_enum)]
|
||||
// pub manpage: bool,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug, PartialEq)]
|
||||
pub enum Commands {
|
||||
/// Toggle MPD stream
|
||||
Toggle,
|
||||
/// Skip to the next track
|
||||
Next,
|
||||
/// Revert to the previous track
|
||||
Prev,
|
||||
/// Stops playing
|
||||
Stop,
|
||||
/// Play queueueu
|
||||
Play {
|
||||
#[arg(short, long, value_hint = ValueHint::Other)]
|
||||
track: Option<u32>,
|
||||
},
|
||||
/// Set or get crossfade
|
||||
Crossfade {
|
||||
#[arg(short, long, value_hint = ValueHint::Other)]
|
||||
seconds: Option<i64>,
|
||||
},
|
||||
///Update still needs some work
|
||||
Update,
|
||||
/// Return currently playing song
|
||||
Current,
|
||||
/// Clear current queueueu
|
||||
Clear,
|
||||
/// Query database
|
||||
Search {
|
||||
///Search query
|
||||
#[arg(trailing_var_arg = true, value_hint = ValueHint::Other)]
|
||||
query: Vec<String>,
|
||||
///Only return the first n results
|
||||
#[arg(short, long, value_hint = ValueHint::Other)]
|
||||
max: Option<u32>,
|
||||
// #[arg(short, long)]
|
||||
// append: bool,
|
||||
// #[arg(short, long)]
|
||||
// insert: Option<u32>,
|
||||
},
|
||||
/// Query database differently
|
||||
Find {
|
||||
///Search query
|
||||
#[arg(trailing_var_arg = true, value_hint = ValueHint::Other)]
|
||||
query: Vec<String>,
|
||||
///Only return the first n results
|
||||
#[arg(short, long, value_hint = ValueHint::Other)]
|
||||
max: Option<u32>,
|
||||
#[arg(short, long)]
|
||||
append: bool,
|
||||
},
|
||||
/// List items in the current queueueu
|
||||
List {
|
||||
#[arg(short, long)]
|
||||
file: bool,
|
||||
},
|
||||
// Add {
|
||||
// #[arg(short, long)]
|
||||
// position: Option<u32>,
|
||||
// },
|
||||
/// Shuffles the current queueue
|
||||
Shuffle,
|
||||
}
|
120
src/main.rs
120
src/main.rs
|
@ -1,88 +1,37 @@
|
|||
extern crate libnotify;
|
||||
extern crate mpd;
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
mod cli;
|
||||
use cli::*;
|
||||
|
||||
use clap::{Command, CommandFactory, Parser};
|
||||
use clap_complete::{generate, Generator};
|
||||
use libnotify::Notification;
|
||||
use mpd::{Client, Query, Song, State, Term};
|
||||
use std::time::Duration;
|
||||
use std::{io, time::Duration};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = "Banaan")]
|
||||
#[command(propagate_version = true)]
|
||||
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Option<Commands>,
|
||||
|
||||
#[arg(short, long, global = true)]
|
||||
verbose: bool,
|
||||
///hostname where MPD listens at
|
||||
#[arg(short = 'H', long, global = true)]
|
||||
host: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Toggle MPD stream
|
||||
Toggle,
|
||||
/// Skip to the next track
|
||||
Next,
|
||||
/// Revert to the previous track
|
||||
Prev,
|
||||
/// Stops playing
|
||||
Stop,
|
||||
/// Play queueueu
|
||||
Play { track: Option<u32> },
|
||||
/// Set or get crossfade
|
||||
Crossfade { seconds: Option<i64> },
|
||||
///Update still needs some work
|
||||
Update,
|
||||
/// Return currently playing song
|
||||
Current,
|
||||
/// Clear current queueueu
|
||||
Clear,
|
||||
/// Query database
|
||||
Search {
|
||||
///Search query
|
||||
#[arg(trailing_var_arg = true)]
|
||||
query: Vec<String>,
|
||||
///Only return the first n results
|
||||
#[arg(short, long)]
|
||||
max: Option<u32>,
|
||||
// #[arg(short, long)]
|
||||
// append: bool,
|
||||
// #[arg(short, long)]
|
||||
// insert: Option<u32>,
|
||||
},
|
||||
/// Query database differently
|
||||
Find {
|
||||
///Search query
|
||||
#[arg(trailing_var_arg = true)]
|
||||
query: Vec<String>,
|
||||
///Only return the first n results
|
||||
#[arg(short, long)]
|
||||
max: Option<u32>,
|
||||
#[arg(short, long)]
|
||||
append: bool,
|
||||
},
|
||||
/// List items in the current queueueu
|
||||
List {
|
||||
#[arg(short, long)]
|
||||
file: bool,
|
||||
},
|
||||
// Add {
|
||||
// #[arg(short, long)]
|
||||
// position: Option<u32>,
|
||||
// },
|
||||
/// Shuffles the current queueue
|
||||
Shuffle,
|
||||
fn print_completions<G: Generator>(generator: G, cmd: &mut Command) {
|
||||
generate(
|
||||
generator,
|
||||
cmd,
|
||||
cmd.get_name().to_string(),
|
||||
&mut io::stdout(),
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let cli = Cli::parse();
|
||||
|
||||
if let Some(completions) = cli.completions {
|
||||
let mut cmd = Cli::command();
|
||||
eprintln!("Generating completion file for {completions:?}...");
|
||||
print_completions(completions, &mut cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
libnotify::init("noise").unwrap();
|
||||
|
||||
let n = libnotify::Notification::new("Noise", None, None);
|
||||
let cli = Cli::parse();
|
||||
|
||||
let host = cli.host.unwrap_or("localhost:6600".into());
|
||||
|
||||
|
@ -109,17 +58,20 @@ fn main() {
|
|||
}
|
||||
Commands::Next => conn.next().unwrap(),
|
||||
Commands::Prev => conn.prev().unwrap(),
|
||||
Commands::List { file } => conn.queue().unwrap().iter().for_each(|x| {
|
||||
println!(
|
||||
"{:<02} {}",
|
||||
x.place.unwrap().pos,
|
||||
if *file {
|
||||
x.file.clone()
|
||||
} else {
|
||||
format_song(x.clone())
|
||||
}
|
||||
)
|
||||
}),
|
||||
Commands::List { file } => {
|
||||
let _current_song = conn.currentsong().unwrap();
|
||||
conn.queue().unwrap().iter().for_each(|x| {
|
||||
println!(
|
||||
"{:<02} {}",
|
||||
x.place.unwrap().pos,
|
||||
if *file {
|
||||
x.file.clone()
|
||||
} else {
|
||||
format_song(x.clone())
|
||||
}
|
||||
)
|
||||
});
|
||||
}
|
||||
Commands::Update => {
|
||||
let thing = conn.update().unwrap();
|
||||
println!("{thing}")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue