Compare commits

...

5 commits
0.1.6 ... main

Author SHA1 Message Date
f0ba8bf593
Few more commands 2025-07-06 00:20:06 +02:00
293da4f330
Cleanup 2025-07-03 23:01:21 +02:00
ab77d39ee0
Ergonomics pt2 2025-07-02 23:34:24 +02:00
cbcb8fef33
Ergonomics 2025-07-02 23:32:51 +02:00
8daf40d59e
Documentation and a few aliases 2025-07-02 23:29:01 +02:00
5 changed files with 67 additions and 41 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
/target /target
result result
.direnv .direnv
noise.zsh

View file

@ -1,39 +1,19 @@
use clap::{Command, CommandFactory}; use clap::CommandFactory;
// use clap_complete as complete; use clap_mangen::generate_to;
use clap_mangen as mangen;
// use complete::Shell;
use std::{path::PathBuf, str::FromStr};
#[path = "src/cli.rs"] #[path = "src/cli.rs"]
mod cli; mod cli;
use 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<()> { fn main() -> std::io::Result<()> {
let out_dir = let out_dir =
std::path::PathBuf::from(std::env::var_os("OUT_DIR").ok_or(std::io::ErrorKind::NotFound)?); 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(); let cmd = Cli::command();
generate_manpage(cmd, out_dir.clone())?; generate_to(cmd, &out_dir)?;
println!("cargo:warning=OUT_DIR: {out_dir:?}");
// eprintln!("{out_dir:?}");
// println!("cargo:warning=out_dir: {out_dir:?}");
Ok(()) Ok(())
} }

View file

@ -7,10 +7,10 @@
outputs = outputs =
{ {
self,
nixpkgs, nixpkgs,
utils, utils,
naersk, naersk,
...
}: }:
utils.lib.eachDefaultSystem ( utils.lib.eachDefaultSystem (
system: system:
@ -32,10 +32,6 @@
postInstall = postInstall =
with pkgs; with pkgs;
lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) '' 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 \ installShellCompletion --cmd noise \
--bash <($out/bin/noise --generate-completions bash) \ --bash <($out/bin/noise --generate-completions bash) \
--zsh <($out/bin/noise --generate-completions zsh) \ --zsh <($out/bin/noise --generate-completions zsh) \

View file

@ -5,8 +5,8 @@ use clap_complete::Shell;
#[command( #[command(
author = "Nox Sluijtman", author = "Nox Sluijtman",
version, version,
about, about = "A small MPD client",
long_about = "A small, opinionated MPD client", long_about = "I like how 'mpc' works for the most part, but I don't use most of its features and there are some parts of it that I feel could be more ergonomic. In comes 'noise', an opinionated, even more minimalist 'mpd' client than 'mpc'.",
name = "noise" name = "noise"
)] )]
#[command(propagate_version = true)] #[command(propagate_version = true)]
@ -19,35 +19,36 @@ pub struct Cli {
#[arg(short, long, global = true)] #[arg(short, long, global = true)]
pub verbose: bool, pub verbose: bool,
/// Hostname where MPD listens at /// Hostname where MPD listens at
#[arg(short = 'H', long, global = true)] #[arg(short = 'H', long, global = true, value_hint = ValueHint::Hostname)]
pub host: Option<String>, pub host: Option<String>,
/// Generate shell completions /// Generate shell completions
#[arg(long = "generate-completions", value_enum)] #[arg(long = "generate-completions", value_enum)]
pub completions: Option<Shell>, pub completions: Option<Shell>,
// /// Generate manpage
// #[arg(long = "generate-manpage", value_enum)]
// pub manpage: bool,
} }
#[derive(Subcommand, Debug, PartialEq)] #[derive(Subcommand, Debug, PartialEq)]
pub enum Commands { pub enum Commands {
/// Toggle MPD stream /// Toggle MPD playback
#[command(visible_alias = "t")]
Toggle, Toggle,
/// Skip to the next track /// Skip to the next track
#[command(visible_alias = "skip")]
Next, Next,
/// Revert to the previous track /// Revert to the previous track
Prev, Prev,
/// Stops playing /// Stops playing
Stop, Stop,
/// Play queueueu /// Play queueueu
#[command(visible_alias = "start")]
Play { Play {
#[arg(short, long, value_hint = ValueHint::Other)] #[arg(value_hint = ValueHint::Other)]
track: Option<u32>, track: Option<u32>,
}, },
/// Set or get crossfade /// Set or get crossfade
#[command(visible_alias = "fade")]
Crossfade { Crossfade {
#[arg(short, long, value_hint = ValueHint::Other)] #[arg(value_hint = ValueHint::Other)]
seconds: Option<i64>, seconds: Option<i64>,
}, },
///Update still needs some work ///Update still needs some work
@ -57,6 +58,7 @@ pub enum Commands {
/// Clear current queueueu /// Clear current queueueu
Clear, Clear,
/// Query database /// Query database
#[command(visible_alias = "q")]
Search { Search {
///Search query ///Search query
#[arg(trailing_var_arg = true, value_hint = ValueHint::Other)] #[arg(trailing_var_arg = true, value_hint = ValueHint::Other)]
@ -69,7 +71,8 @@ pub enum Commands {
// #[arg(short, long)] // #[arg(short, long)]
// insert: Option<u32>, // insert: Option<u32>,
}, },
/// Query database differently /// Query database autistically
#[command(visible_alias = "fd")]
Find { Find {
///Search query ///Search query
#[arg(trailing_var_arg = true, value_hint = ValueHint::Other)] #[arg(trailing_var_arg = true, value_hint = ValueHint::Other)]
@ -81,6 +84,7 @@ pub enum Commands {
append: bool, append: bool,
}, },
/// List items in the current queueueu /// List items in the current queueueu
#[command(visible_alias = "ls")]
List { List {
#[arg(short, long)] #[arg(short, long)]
file: bool, file: bool,
@ -90,5 +94,20 @@ pub enum Commands {
// position: Option<u32>, // position: Option<u32>,
// }, // },
/// Shuffles the current queueue /// Shuffles the current queueue
#[command(visible_alias = "scramble")]
Shuffle, Shuffle,
/// Toggles repeat
Repeat,
/// Toggles random
Random,
/// Toggles consume
Consume,
/// Toggles single
Single,
/// Get or set volume
#[command(visible_alias = "vol")]
Volume {
#[arg(value_hint = ValueHint::Other)]
percentage: Option<i8>,
},
} }

View file

@ -76,7 +76,7 @@ fn main() {
let thing = conn.update().unwrap(); let thing = conn.update().unwrap();
println!("{thing}") println!("{thing}")
} }
Commands::Current => (), // this is basically the same as having no command Commands::Current => (),
Commands::Clear => conn.clear().unwrap(), Commands::Clear => conn.clear().unwrap(),
Commands::Search { query, max } => { Commands::Search { query, max } => {
let query = query.join(" "); let query = query.join(" ");
@ -118,6 +118,30 @@ fn main() {
println!("Shuffling queueueu..."); println!("Shuffling queueueu...");
conn.shuffle(..).unwrap(); conn.shuffle(..).unwrap();
} }
Commands::Repeat => {
let repeat_state = conn.status().unwrap().repeat;
conn.repeat(!repeat_state).unwrap();
}
Commands::Random => {
let random_state = conn.status().unwrap().random;
// conn.repeat(!random_state).unwrap();
println!("{}", random_state)
}
Commands::Single => {
let single_state = conn.status().unwrap().single;
conn.single(!single_state).unwrap();
}
Commands::Consume => {
let consume_state = conn.status().unwrap().consume;
conn.consume(!consume_state).unwrap();
}
Commands::Volume { percentage } => {
if let Some(volume) = percentage {
conn.volume(*volume).unwrap()
}
let vol = conn.status().unwrap().volume;
println!("Volume at {vol}%")
}
} }
if let Commands::Stop if let Commands::Stop
@ -135,8 +159,14 @@ fn main() {
println!("{}", get_status(conn, cli.verbose, n)); println!("{}", get_status(conn, cli.verbose, n));
} }
// fn toggle_state(mut client: Client, state: ) -> () {}
fn format_song(song: Song) -> String { fn format_song(song: Song) -> String {
format!("{} - {}", song.artist.unwrap(), song.title.unwrap()) format!(
"{} - {}",
song.artist.unwrap_or("Unknown".into()),
song.title.unwrap()
)
} }
trait QuickFmt { trait QuickFmt {