Shell completions
This commit is contained in:
parent
c21072727c
commit
e8e22b1a2c
6 changed files with 219 additions and 86 deletions
29
Cargo.lock
generated
29
Cargo.lock
generated
|
@ -86,6 +86,15 @@ dependencies = [
|
||||||
"strsim",
|
"strsim",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_complete"
|
||||||
|
version = "4.5.54"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.5.32"
|
version = "4.5.32"
|
||||||
|
@ -104,6 +113,16 @@ version = "0.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
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]]
|
[[package]]
|
||||||
name = "colorchoice"
|
name = "colorchoice"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
|
@ -249,9 +268,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "noise"
|
name = "noise"
|
||||||
version = "0.1.4"
|
version = "0.1.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
|
"clap_complete",
|
||||||
|
"clap_mangen",
|
||||||
"libnotify",
|
"libnotify",
|
||||||
"mpd",
|
"mpd",
|
||||||
]
|
]
|
||||||
|
@ -286,6 +307,12 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "roff"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
[package]
|
[package]
|
||||||
name = "noise"
|
name = "noise"
|
||||||
version = "0.1.4"
|
version = "0.1.6"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
authors = ["Nox Sluijtman"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.39", features = ["derive"] }
|
clap = { version = "4.5.39", features = ["derive"] }
|
||||||
|
clap_complete = "4.5.54"
|
||||||
libnotify = "1.0.3"
|
libnotify = "1.0.3"
|
||||||
mpd = "0.1.0"
|
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 = ./.;
|
src = ./.;
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
libnotify
|
libnotify
|
||||||
|
installShellFiles
|
||||||
];
|
];
|
||||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath nativeBuildInputs;
|
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath nativeBuildInputs;
|
||||||
|
|
||||||
RUST_SRC_PATH = pkgs.rustPlatform.rustLibSrc;
|
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 =
|
devShell =
|
||||||
with pkgs;
|
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,
|
||||||
|
}
|
102
src/main.rs
102
src/main.rs
|
@ -1,88 +1,37 @@
|
||||||
extern crate libnotify;
|
extern crate libnotify;
|
||||||
extern crate mpd;
|
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 libnotify::Notification;
|
||||||
use mpd::{Client, Query, Song, State, Term};
|
use mpd::{Client, Query, Song, State, Term};
|
||||||
use std::time::Duration;
|
use std::{io, time::Duration};
|
||||||
|
|
||||||
#[derive(Parser)]
|
fn print_completions<G: Generator>(generator: G, cmd: &mut Command) {
|
||||||
#[command(author, version, about, long_about = "Banaan")]
|
generate(
|
||||||
#[command(propagate_version = true)]
|
generator,
|
||||||
|
cmd,
|
||||||
struct Cli {
|
cmd.get_name().to_string(),
|
||||||
#[command(subcommand)]
|
&mut io::stdout(),
|
||||||
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 main() {
|
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();
|
libnotify::init("noise").unwrap();
|
||||||
|
|
||||||
let n = libnotify::Notification::new("Noise", None, None);
|
let n = libnotify::Notification::new("Noise", None, None);
|
||||||
let cli = Cli::parse();
|
|
||||||
|
|
||||||
let host = cli.host.unwrap_or("localhost:6600".into());
|
let host = cli.host.unwrap_or("localhost:6600".into());
|
||||||
|
|
||||||
|
@ -109,7 +58,9 @@ fn main() {
|
||||||
}
|
}
|
||||||
Commands::Next => conn.next().unwrap(),
|
Commands::Next => conn.next().unwrap(),
|
||||||
Commands::Prev => conn.prev().unwrap(),
|
Commands::Prev => conn.prev().unwrap(),
|
||||||
Commands::List { file } => conn.queue().unwrap().iter().for_each(|x| {
|
Commands::List { file } => {
|
||||||
|
let _current_song = conn.currentsong().unwrap();
|
||||||
|
conn.queue().unwrap().iter().for_each(|x| {
|
||||||
println!(
|
println!(
|
||||||
"{:<02} {}",
|
"{:<02} {}",
|
||||||
x.place.unwrap().pos,
|
x.place.unwrap().pos,
|
||||||
|
@ -119,7 +70,8 @@ fn main() {
|
||||||
format_song(x.clone())
|
format_song(x.clone())
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}),
|
});
|
||||||
|
}
|
||||||
Commands::Update => {
|
Commands::Update => {
|
||||||
let thing = conn.update().unwrap();
|
let thing = conn.update().unwrap();
|
||||||
println!("{thing}")
|
println!("{thing}")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue