Skip to content

Instantly share code, notes, and snippets.

@qryxip
Last active December 12, 2020 11:49
Show Gist options
  • Select an option

  • Save qryxip/1457bcfba3e8c7b19e754d5d06cef17f to your computer and use it in GitHub Desktop.

Select an option

Save qryxip/1457bcfba3e8c7b19e754d5d06cef17f to your computer and use it in GitHub Desktop.
A script for status bars like yabar or xmobar that prints the title of the music currently played on CMus.
#!usr/bin/env run-cargo-script
use std::io::{self, BufRead, BufReader};
use std::process::{ChildStdout, Command, Stdio};
fn main() {
use std::io::ErrorKind::NotFound;
match cmus_status() {
Err(ref e) if e.kind() == NotFound => println!(" \"cmus-remote\" not found"),
Err(ref e) => println!(" {}", e),
Ok(CmusStatus::CmusNotRunning) => println!(""),
Ok(CmusStatus::Stopped) => println!(" Selecting"),
Ok(CmusStatus::Paused(ref title)) => println!(" {}", title),
Ok(CmusStatus::Playing(ref title)) => println!(" {}", title),
}
}
fn cmus_status() -> io::Result<CmusStatus> {
let stdout = cmus_remote_query()?;
let mut lines = stdout.lines();
let music_status = {
let line = match lines.next() {
Some(line) => line?,
None => return Ok(CmusStatus::CmusNotRunning),
};
let mut words = line.split_whitespace();
match (words.next(), words.next()) {
(Some("status"), Some("stopped")) => return Ok(CmusStatus::Stopped),
(Some("status"), Some("paused")) => MusicStatus::Paused,
(Some("status"), Some("playing")) => MusicStatus::Playing,
_ => return Ok(CmusStatus::CmusNotRunning),
}
};
for line in lines {
let line = line?;
let mut words = line.split_whitespace();
if let (Some("tag"), Some("title")) = (words.next(), words.next()) {
return Ok(music_status.with_title(words.collect::<Vec<_>>().join(" ")));
}
}
Ok(CmusStatus::CmusNotRunning)
}
fn cmus_remote_query() -> io::Result<BufReader<ChildStdout>> {
Ok(BufReader::new(
Command::new("cmus-remote")
.arg("-Q")
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::null())
.spawn()?
.stdout
.unwrap(),
))
}
enum CmusStatus {
CmusNotRunning,
Stopped,
Paused(String),
Playing(String),
}
enum MusicStatus {
Paused,
Playing,
}
impl MusicStatus {
fn with_title(&self, title: String) -> CmusStatus {
match *self {
MusicStatus::Paused => CmusStatus::Paused(title),
MusicStatus::Playing => CmusStatus::Playing(title),
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment