amused-monitor

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