https://github.com/akkartik/mu/blob/master/029tools.cc
  1 //: Allow Mu programs to log facts just like we've been doing in C++ so far.
  2 
  3 :(scenario trace)
  4 def main [
  5   trace 1, [foo], [this is a trace in Mu]
  6 ]
  7 +foo: this is a trace in Mu
  8 
  9 :(before "End Primitive Recipe Declarations")
 10 TRACE,
 11 :(before "End Primitive Recipe Numbers")
 12 put(Recipe_ordinal, "trace", TRACE);
 13 :(before "End Primitive Recipe Checks")
 14 case TRACE: {
 15   if (SIZE(inst.ingredients) < 3) {
 16     raise << maybe(get(Recipe, r).name) << "'trace' takes three or more ingredients rather than '" << to_original_string(inst) << "'\n" << end();
 17     break;
 18   }
 19   if (!is_mu_number(inst.ingredients.at(0))) {
 20     raise << maybe(get(Recipe, r).name) << "first ingredient of 'trace' should be a number (depth), but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
 21     break;
 22   }
 23   if (!is_literal_text(inst.ingredients.at(1))) {
 24     raise << maybe(get(Recipe, r).name) << "second ingredient of 'trace' should be a literal string (label), but got '" << inst.ingredients.at(1).original_string << "'\n" << end();
 25     break;
 26   }
 27   break;
 28 }
 29 :(before "End Primitive Recipe Implementations")
 30 case TRACE: {
 31   int depth = ingredients.at(0).at(0);
 32   string label = current_instruction().ingredients.at(1).name;
 33   ostringstream out;
 34   for (int i = 2;  i < SIZE(current_instruction().ingredients);  ++i) {
 35     if (i > 2) out << ' ';
 36     out << inspect(current_instruction().ingredients.at(i), ingredients.at(i));
 37   }
 38   trace(depth, label) << out.str() << end();
 39   break;
 40 }
 41 
 42 //: simpler limited version of 'trace'
 43 
 44 :(before "End Primitive Recipe Declarations")
 45 STASH,
 46 :(before "End Primitive Recipe Numbers")
 47 put(Recipe_ordinal, "stash", STASH);
 48 :(before "End Primitive Recipe Checks")
 49 case STASH: {
 50   break;
 51 }
 52 :(before "End Primitive Recipe Implementations")
 53 case STASH: {
 54   ostringstream out;
 55   for (int i = 0;  i < SIZE(current_instruction().ingredients);  ++i) {
 56     if (i) out << ' ';
 57 
/*
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 * See LICENSE file for license details.
 */
#include "dwm.h"

/* static */

static Client *
minclient() {
	Client *c, *min;

	if((clients && clients->isfloat) || arrange == dofloat)
		return clients; /* don't touch floating order */
	for(min = c = clients; c; c = c->next)
		if(c->weight < min->weight)
			min = c;
	return min;
}

static void
reorder() {
	Client *c, *newclients, *tail;

	newclients = tail = NULL;
	while((c = minclient())) {
		detach(c);
		if(tail) {
			c->prev = tail;
			tail->next = c;
			tail = c;
		}
		else
			tail = newclients = c;
	}
	clients = newclients;
}

static Client *
nexttiled(Client *c) {
	for(c = getnext(c); c && c->isfloat; c = getnext(c->next));
	return c;
}

/* extern */

void (*arrange)(Arg *) = DEFMODE;

void
detach(Client *c) {
	if(c->prev)
		c->prev->next = c->next;
	if(c->next)
		c->next->prev = c->prev;
	if(c == clients)
		clients = c->next;
	c->next = c->prev = NULL;
}

void
dofloat(Arg *arg) {
	Client *c;

	for(c = clients; c; c = c->next) {
		if(isvisible(c)) {
			resize(c, True, TopLeft);
		}
		else
			ban(c);
	}
	if(!sel || !isvisible(sel)) {
		for(c = stack; c && !isvisible(c); c = c->snext);
		focus(c);
	}
	restack();
}

void
dotile(Arg *arg) {
	int h, i, n, w;
	Client *c;

	w = sw - mw;
	for(n = 0, c = clients; c; c = c->next)
		if(isvisible(c) && !c->isfloat)
			n++;

	if(n > 1)
		h = (sh - bh) / (n - 1);
	else
		h = sh - bh;

	for(i = 0, c = clients; c; c = c->next) {
		if(isvisible(c)) {
			if(c->isfloat) {
				resize(c, True, TopLeft);
				continue;
			}
			if(n == 1) {
				c->x = sx;
				c->y = sy + bh;
				c->w = sw - 2;
				c->h = sh - 2 - bh;
			}
			else if(i == 0) {
				c->x = sx;
				c->y = sy + bh;
				c->w = mw - 2;
				c->h = sh - 2 - bh;
			}
			else if(h > bh) {
				c->x = sx + mw;
				c->y = sy + (i - 1) * h + bh;
				c->w = w - 2;
				if(i + 1 == n)
					c->h = sh - c->y - 2;
				else
					c->h = h - 2;
			}
			else { /* fallback if h < bh */
				c->x = sx + mw;
				c->y = sy + bh;
				c->w = w - 2;
				c->h = sh - 2 - bh;
			}
			resize(c, False, TopLeft);
			i++;
		}
		else
			ban(c);
	}
	if(!sel || !isvisible(sel)) {
		for(c = stack; c && !isvisible(c); c = c->snext);
		focus(c);
	}
	restack();
}

void
focusnext(Arg *arg) {
	Client *c;
   
	if(!sel)
		return;

	if(!(c = getnext(sel->next)))
		c = getnext(clients);
	if(c) {
		focus(c);
		restack();
	}
}

void
focusprev(Arg *arg) {
	Client *c;

	if(!sel)
		return;

	if(!(c = getprev(sel->prev))) {
		for(c = clients; c && c->next; c = c->next);
		c = getprev(c);
	}
	if(c) {
		focus(c);
		restack();
	}
}

Bool
isvisible(Client *c) {
	unsigned int i;

	for(i = 0; i < ntags; i++)
		if(c->tags[i] &&