This is a small interface for the amused music player
#!/usr/bin/env rc
It's written in rc because I found easier to manage subprocesses in it rather than in sh.
There are two main processes involved: input and ui. The input process handles the keybindings and controls amused, the ui input waits for some events and redraws the interface.
fn input { ifs=()
$ifs needs to be set to the empty list (or empty string), otherwise we're not able to read spaces as keybindings.
run=1 while (~ $run 1) {
rc lacks a break statement, so I'm using a flag variable to quit looping.
stty raw t=`{dd bs=1 count=1 status=none} stty cooked
This is just a trick to read without echoing back the characters.
switch ($"t) { case n amused next case p amused prev case ' ' amused toggle case s amused stop case q run=0 case * printf ' unknown keybinding >'$t'<\r' } } }
The ui functions render the interface. I'd like to keep a small xterm open, that's why I'm narrowing (with grep -A -B) only to the songs around the currently played one.
fn ui { clear amused show -p | grep -A3 -B3 '^>' | awk '{printf "%s\r\n", $0}'
The awk trick deserves an explanation. Since the input function is very likely running, the terminal is in "raw" mode: we need \r to reposition the character at the start of the line.
}
The uiloop function is the driver for the ui process: it listens to interesting events and redraws the ui when they happen
fn uiloop { amused monitor next,prev,jump | { while (read) { ui }
A small note of merit: unlike other shells read is not a built in in rc bur rather an external command (/usr/local/plan9/bin/read here.)
} }
And that's all. I only need to launch the functions in the correct order and do one render at the start and amused-monitor is done!
ui uiloop & uipid=$apid input kill -INT -$uipid