commit 8ba6c84f1c67dc5fb6a207adc9f1949b400f4b51
parent 717e770e72abcf5bbfa0c8d0d790b8120f5d5134
Author: Kris Maglione <jg@suckless.org>
Date: Sun, 20 Jan 2008 18:00:21 -0500
Several changes:
Filter comments out of ctl files.
Update util/genconfig.
Add a notification bar (I've had one for some time).
Make wmiirc more like rc.wmii.
Diffstat:
17 files changed, 563 insertions(+), 314 deletions(-)
diff --git a/DISTRIBUTORS b/DISTRIBUTORS
@@ -1,9 +1,9 @@
The following conditions apply to any distribution which
-uses the name wmii. These conditions apply only to wmii
+uses the name wmii. These conditions apply only to wmii
name, and not to its source code or any other materials.
When in doubt about any of these conditions or other matters
-of packaging or distrobution, , please contact the wmii
+of packaging or distribution, please contact the wmii
mailing lists <wmii-hackers@suckless.org> or
<wmii@suckless.org>, or Kris Maglione <fbsdaemon@gmail.com>.
@@ -13,23 +13,23 @@ version string. This string may normally be set in
revision number for builds from a Mercurial tree, so long as
the 'hg' command is present and properly functioning.
-Any version which not an official release or snapshot MUST
-be contain the hg revision number in its version string.
-This SHOULD be formated as hgXXXX, where XXXX is the decimal
-revision number.
+Any version which is not an official release or snapshot
+MUST be contain the hg revision number in its version
+string. This SHOULD be formatted as hgXXXX, where XXXX is
+the decimal revision number.
The version string of any snapshot release MUST contain the
date of the snapshot in the form YYYYMMDD, and SHOULD
-contain the word snap or snapshot. The version string of a
-snapshot MAY contain the version of a full release that the
-snapshot is expected to lead to, but it MUST be either
+contain the word snap or snapshot. The version string of a
+snapshot MAY contain the version name of a full release that
+the snapshot is expected to lead to, but it MUST be either
directly preceded, or directly followed by, the word 'pre',
optionally separated by a non-alphanumeric character,
-including -~_,./, the version.
+including -~_,./.
Any binary distribution which is modified in any non-trivial
way MUST signify the modifications in its name or version
-string. This includes patches to use Xft for font display,
+string. This includes patches to use Xft for font display,
but does NOT include minor patches to improve consistency
with the rest of the system, including changing the default
terminal emulator or changing any build flags as set in
diff --git a/NOTES b/NOTES
@@ -1,3 +1,6 @@
3.6 Release Notes
-wmiirc users: the semantics of WMII_MENU, WMII_9MENU and WMII_TERM have changed. If you're using them in custom scripts you'll need to change them to "eval $WMII_MENU" instead of just "$WMII_MENU".
+wmiirc users: the semantics of WMII_MENU, WMII_9MENU and WMII_TERM
+have changed. If you're using them in custom scripts you'll need to
+change them to "eval $WMII_MENU" instead of just "$WMII_MENU".
+
diff --git a/README b/README
@@ -3,7 +3,7 @@ Abstract
window manager improved-improved is a dynamic window manager for X11.
It supports classic and tiled window management with extended
keyboard, mouse, and 9P-based [1] remote control.
-It consists of the wmiiwm(1) window manager and the wmiir(1)
+It consists of the wmii(1) window manager and the wmiir(1)
the remote access utility.
@@ -12,6 +12,7 @@ Requirements
In order to build wmii you need the Xlib header files and libixp. xmessage
and dmenu are used by the default scripts. libixp and dmenu can be obtained
from http://suckless.org/. Either plan9port[2] or 9base is recommended.
+If you have the wmii+ixp distribution, libixp is already provided.
Installation
@@ -48,9 +49,9 @@ which remotely controls the window manager and handles various events.
The main rc.wmii script lives in PREFIX/etc/wmii-3.5/, while rc.wmii.local
goes in $HOME/.wmii-3.5/.
-rc.wmii.local should contain a line containing just: '# Overrides'. You must
-set your MODKEY and other configuration variables before this line, if you
-wish to change then, and define most functions after it.
+If you wish to unbind keys bound by rc.wmii in rc.wmii.local, you
+must do so inside the function Action-overridekeys. You may,
+however, define new keys or redefine keys anywhere.
Credits
-------
@@ -87,3 +88,4 @@ References
----------
[1] http://9p.cat-v.org
[2] http://plan9.us
+
diff --git a/cmd/Makefile b/cmd/Makefile
@@ -7,9 +7,9 @@ wmiir.c: $(ROOT)/mk/wmii.mk
DIRS = wmii
TARG = wihack \
wmii.rc \
+ wmii.sh \
wmii9menu \
wmii9rc \
- wmiiloop \
wmiir \
wmiistartrc
diff --git a/cmd/wmii.rc.rc b/cmd/wmii.rc.rc
@@ -1,7 +1,18 @@
+# For the time being, this file follows the lisp bracing
+# convention. i.e.:
+# if(frob this) {
+# frob that
+# if(frob theother) {
+# unfrob this
+# unfrob that}}
+
wmiiscript=$1
wmiikeys=()
+wi_nl='
+'
+
echo Start $wmiiscript | wmiir write /event >[2]/dev/null \
|| exit write
@@ -17,13 +28,6 @@ fn sigexit {
wi_atexit
}
-fn Event-Start {
- if(~ $1 $wmiiscript)
- exit
-}
-
-fn Event-Key { Key-$1 $1 }
-
fn wi_fatal {
echo $scriptname: Fatal: $*
exit fatal
@@ -51,6 +55,10 @@ fn wi_9menu {
-^(sf sb br)^$wmiifocuscol $*
}
+fn wi_fn-p {
+ rc -c 'whatis '$1 >[2]/dev/null | grep -s '^fn '
+}
+
fn wi_proglist {
/bin/ls -lL `{echo $* | sed 'y/:/ /'} >[2]/dev/null \
| awk '$1 ~ /^[^d].*x/ { print $NF }' \
@@ -64,9 +72,14 @@ fn wi_actions {
}
fn wi_script {
- prog = `{@{path=$confpath whatis $1} |
- grep -v '^fn|= ' || echo /dev/null}
- shift; echo $prog $*
+ noprog=true prog=() {
+ if(~ $1 -f) {
+ shift
+ noprog=/dev/null
+ }
+ prog = `{rc -c 'path=$confpath whatis '$1 >[2]/dev/null \
+ | grep -v '^fn|= ' || echo $noprog}
+ shift; echo $prog $*}
}
@@ -78,9 +91,7 @@ fn wi_initkeys {
<{echo $wmiikeys | sort | uniq}}
{echo $wmiikeys; wi_getfuns Key} \
| sort | uniq \
- | wmiir write /keys
- }
- }
+ | wmiir write /keys }}
fn wi_atexit {
wi_cleankeys
}
@@ -91,9 +102,7 @@ fn wi_cleankeys {
wmiikeys = `{wmiir read /keys} {
comm -23 <{echo $wmiikeys | sort | uniq} \
<{echo $mykeys} \
- | wmiir write /keys
- }
- }
+ | wmiir write /keys }}
}
fn wi_runcmd { @{
@@ -101,16 +110,19 @@ fn wi_runcmd { @{
path=$oldpath
if(~ $1 -t) {
shift
- * = (wihack -tags `{wmiir read /tag/sel/ctl | sed 1q} $*)
- }
- eval exec $* &
- }
+ * = (wihack -tags `{wmiir read /tag/sel/ctl | sed 1q} $*) }
+ eval exec $* & }
}
fn wi_getfuns {
env | sed -n 's/^fn#'^$1^'-([^=]+).*/\1/p'
}
+for(i in Key Event Action)
+ fns=`{wi_getfuns $i} {
+ if(! ~ $fns '')
+ fn $i-^$fns}
+
fn wi_tags {
wmiir ls /tag | sed 's,/,,; /^sel$/d'
}
@@ -119,9 +131,30 @@ fn wi_eventloop {
wi_initkeys
wmiir read /event |
- while(*=`{read}) {
- event = $1; shift
- Event-$event $*
- } >[2]/dev/null </dev/null
+ while(ifs=$wi_nl{wi_event=`{read}}) {
+ ifs=$wi_nl{
+ wi_arg=`{echo $wi_event | sed 's/^[^ ]+ //'}}
+ * = `{echo $wi_event}
+ event = $1; shift
+ Event-$event $*
+ } >[2]/dev/null </dev/null
+}
+
+fn Event-Key {
+ Key-$1 $1
+}
+
+fn Event-Start {
+ if(~ $1 $wmiiscript)
+ exit
+}
+
+fn Action {
+ cmd=$1 action=Action-$cmd { shift
+ if(wi_fn-p $action)
+ $action $*
+ if not
+ wi_runcmd `{wi_script $cmd} $*
+ } &
}
diff --git a/cmd/wmii.sh.sh b/cmd/wmii.sh.sh
@@ -0,0 +1,158 @@
+
+wmiiscript=$1
+if [ -z "$scriptname" ]; then
+ scriptname="$wmiiscript"; fi
+echo Start $wmiiscript | wmiir write /event 2>/dev/null ||
+ exit 1
+
+Keys=""
+Actions=""
+Events=""
+
+_wi_script() {
+ cat <<'!'
+ BEGIN {
+ arg[1] = "Nop"
+ body = "";
+ }
+ function addevent() {
+ if(arg[1] == "Key")
+ keys[arg[2]] = 1;
+
+ var = arg[1] "s"
+ printf "%s=\"$%s\n%s\"\n", var, var, arg[2]
+
+ gsub("[^a-zA-Z_0-9]", "_", arg[2]);
+ if(body != "")
+ printf "%s_%s() { %s\n }\n", arg[1], arg[2], body
+ }
+
+ /^(Event|Key|Action)[ \t]/ {
+ addevent()
+ split($0, arg)
+ body = ""
+ }
+ /^[ \t]/ {
+ body = body"\n"$0
+ }
+
+ END {
+ addevent()
+ }
+!
+}
+
+_wi_text() {
+ eval "cat <<!
+$(sed "$_sed" | sed '/^[ ]/s/\([$`]\)/\\\1/g')
+"
+}
+
+wi_events() {
+ _sed=""
+ if [ "$1" = -s ]; then
+ _sed="s/^$2//"
+ shift 2
+ fi
+ eval "$(_wi_text | awk "$(_wi_script)")"
+}
+
+wi_fatal() {
+ echo $scriptname: Fatal: $*
+ exit 1
+}
+
+wi_notice() {
+ xmessage $scriptname: Notice: $*
+}
+
+wi_readctl() {
+ wmiir read /ctl | sed -n 's/^'$1' //p'
+}
+
+wmiifont="$(wi_readctl font)"
+wmiinormcol="$(wi_readctl normcolors)"
+wmiifocuscol="$(wi_readctl focuscolors)"
+
+wi_menu() {
+ eval "wi_menu() { $WMII_MENU"' "$@"; }'
+ wi_menu "$@"
+}
+wi_9menu() {
+ eval "wi_9menu() { $WMII_9MENU"' "$@"; }'
+ wi_9menu "$@"
+}
+
+wi_proglist() {
+ ls -lL $(echo $* | sed 'y/:/ /') 2>/dev/null \
+ | awk '$1 ~ /^[^d].*x/ { print $NF }' \
+ | sort | uniq
+}
+
+wi_actions() {
+ { wi_proglist $WMII_CONFPATH
+ wi_getfuns Action
+ } | sort | uniq
+}
+
+conf_which() {
+ which=$(which which)
+ prog=$(PATH="$WMII_CONFPATH" $which $1); shift
+ [ -n "$prog" ] && $prog "$@"
+}
+
+wi_script() {
+ _noprog=true
+ if [ "$1" = -f ]; then
+ shift
+ _noprog=/dev/null
+ fi
+ which=$(which which)
+ _prog=$(PATH="$WMII_CONFPATH" $which $1 || echo $_noprog); shift
+ shift; echo "$_prog $*"
+}
+
+wi_runcmd() {
+ if [ "$1" = -t ]; then
+ shift
+ set -- wihack -tags $(wmiir read /tag/sel/ctl | sed 1q) "$*"
+ fi
+ eval exec $* &
+}
+
+wi_tags() {
+ wmiir ls /tag | sed 's,/,,; /^sel$/d'
+}
+
+wi_eventloop() {
+ echo "$Keys" | wmiir write /keys
+
+ wmiir read /event | while read wi_event
+ do
+ OIFS="$IFS"; IFS="$(echo)"
+ wi_args=$(echo "$wi_event" | sed 's/^[^ ]+ //')
+ IFS="$OIFS"
+ set -- $wi_event
+ event=$1; shift
+ Event_$event $@
+ done 2>/dev/null
+}
+
+wi_events <<'!'
+Event Start
+ if [ "$1" = "$wmiiscript" ]; then
+ exit
+ fi
+Event Key
+ fn=$(echo "$@" | sed 's/[^a-zA-Z_0-9]/_/g')
+ Key_$fn "$@"
+!
+
+Action() {
+ action=$1; shift
+ if [ -n "$action" ]; then
+ Action_$action "$@" \
+ || conf_which $action "$@"
+ fi
+}
+
diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h
@@ -172,6 +172,7 @@ char* msg_sendclient(View*, IxpMsg*, bool swap);
char* readctl_root(void);
char* readctl_view(View*);
Area* strarea(View*, const char*);
+void warning(const char*, ...);
/* mouse.c */
void mouse_resize(Client*, bool opaque, Align);
diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c
@@ -164,7 +164,15 @@ msg_getword(IxpMsg *m) {
m->pos += n;
eatrunes(m, isspacerune, true);
- if(ret == m->end)
+ /* Filter out comments. */
+ if(*ret == '#') {
+ *ret = '\0';
+ m->pos = m->end;
+ }
+ if(*ret == '\\')
+ if(ret[1] == '\\' || ret[1] == '#')
+ ret++;
+ if(*ret == '\0')
return nil;
return ret;
}
@@ -302,6 +310,8 @@ message_root(void *p, IxpMsg *m) {
USED(p);
ret = nil;
s = msg_getword(m);
+ if(s == nil)
+ return nil;
switch(getsym(s)) {
case LBORDER:
@@ -367,6 +377,8 @@ message_view(View *v, IxpMsg *m) {
int i;
s = msg_getword(m);
+ if(s == nil)
+ return nil;
switch(getsym(s)) {
case LCOLMODE:
@@ -400,18 +412,6 @@ message_view(View *v, IxpMsg *m) {
/* not reached */
}
-static void
-printdebug(void) {
- int i, j;
-
- for(i=0, j=0; i < nelem(debugtab); i++)
- Debug(1<<i) {
- if(j++ > 0)
- bufprint(" ");
- bufprint("%s", debugtab[i]);
- }
-}
-
static char*
msg_debug(IxpMsg *m) {
char *opt;
@@ -706,6 +706,18 @@ msg_sendframe(Frame *f, int sym, bool swap) {
return nil;
}
+static void
+printdebug(void) {
+ int i, j;
+
+ for(i=0, j=0; i < nelem(debugtab); i++)
+ Debug(1<<i) {
+ if(j++ > 0)
+ bufprint(" ");
+ bufprint("%s", debugtab[i]);
+ }
+}
+
char*
readctl_root(void) {
bufclear();
@@ -746,3 +758,17 @@ readctl_view(View *v) {
return buffer;
}
+void
+warning(const char *fmt, ...) {
+ va_list ap;
+ char *s;
+
+ va_start(ap, fmt);
+ s = vsmprint(fmt, ap);
+ va_end(ap);
+
+ event("Warning %s\n", s);
+ fprint(2, "%s: warning: %s\n", s);
+ free(s);
+}
+
diff --git a/cmd/wmii/printevent.c b/cmd/wmii/printevent.c
@@ -526,9 +526,9 @@ pevent(void *ev, ...) {
Bflush(b);
}
-/******************************************************************************/
-/**** Routines to print out readable values for the field of various events ***/
-/******************************************************************************/
+/*****************************************************************************/
+/*** Routines to print out readable values for the field of various events ***/
+/*****************************************************************************/
static void
VerbMotion(XEvent *e) {
diff --git a/cmd/wmii/utf.c b/cmd/wmii/utf.c
@@ -7,7 +7,7 @@
#include "fns.h"
char*
-toutf8n(char *str, size_t nstr) {
+toutf8n(const char *str, size_t nstr) {
static iconv_t cd;
static bool haveiconv;
char *buf, *pos;
diff --git a/cmd/wmii/xext.c b/cmd/wmii/xext.c
@@ -22,10 +22,8 @@ xext_init(void) {
void
xext_event(XEvent *e) {
- if(have_RandR && (ulong)(e->type - randr_eventbase) < RRNumberEvents) {
- e->type -= randr_eventbase;
+ if(have_RandR && (ulong)(e->type - randr_eventbase) < RRNumberEvents)
randr_event(e);
- }
}
void
@@ -61,7 +59,7 @@ randr_screenchange(XRRScreenChangeNotifyEvent *ev) {
void
randr_event(XEvent *e) {
- switch(e->type) {
+ switch(e->type-randr_eventbase) {
default:
break;
case RRScreenChangeNotify: /* Yuck. */
diff --git a/cmd/wmiiloop.sh b/cmd/wmiiloop.sh
@@ -1,43 +0,0 @@
-#!/bin/sh
-
-eval "text() {
- cat <<!
-$(sed '/^[[:blank:]]/s/\([$`]\)/\\\1/g')
-!
-}"
-
-script() {
- cat <<'!'
- BEGIN {
- arg[1] = "Nop"
- body = "";
- }
- function addevent() {
- if(arg[1] == "Key")
- keys[arg[2]] = 1;
-
- var = arg[1] "s"
- printf "%s=\"$%s %s\"\n", var, var, arg[2]
-
- gsub("[^a-zA-Z_0-9]", "_", arg[2]);
- if(body != "")
- printf "%s_%s() { %s\n }\n", arg[1], arg[2], body
- }
-
- /^(Event|Key|Action)[ \t]/ {
- addevent()
- split($0, arg)
- body = ""
- }
- /^[ \t]/ {
- body = body"\n"$0
- }
-
- END {
- addevent()
- }
-!
-}
-
-text | awk "`script`"
-
diff --git a/config.mk b/config.mk
@@ -1,6 +1,6 @@
# Customize below to fit your system
-# paths
+# Paths
PREFIX = /usr/local
BIN = $(PREFIX)/bin
MAN = $(PREFIX)/share/man
@@ -31,7 +31,6 @@ P9PATHS = ${PLAN9}:"'$${HOME}/plan9'":/usr/local/plan9:/usr/local/9:/opt/plan9:/
INCX11 = -I/usr/X11R6/include
LIBX11 = -L/usr/X11R6/lib -lX11
LIBICONV = # Leave blank if your libc includes iconv (glibc does)
-LIBIXP = $(ROOT)/libixp/libixp.a
LIBIXP = $(LIBDIR)/libixp.a
# Operating System Configurations
@@ -39,7 +38,7 @@ LIBIXP = $(LIBDIR)/libixp.a
# *BSD
#LIBICONV = -liconv
# +Darwin
-#STATIC = # Darwon doesn't like static linking
+#STATIC = # Darwin doesn't like static linking
# Solaris
#CFLAGS = -fast $(INCS)
diff --git a/mk/hdr.mk b/mk/hdr.mk
@@ -84,6 +84,13 @@ LINKSO= LD="$(LD)" LDFLAGS="$(SOLDFLAGS)" $(ROOT)/util/link
CLEANNAME=$(ROOT)/util/cleanname
include $(ROOT)/config.mk
+
+# I hate this.
+MKCFGSH=if test -f $(ROOT)/config.local.mk; then echo $(ROOT)/config.local.mk; else echo /dev/null; fi
+MKCFG:=${shell $(MKCFGSH)}
+MKCFG!=${MKCFGSH}
+include $(MKCFG)
+
CFLAGS += -I$$(echo $(INCPATH)|sed 's/:/ -I/g')
include $(ROOT)/mk/common.mk
diff --git a/rc/rc.wmii.rc b/rc/rc.wmii.rc
@@ -12,6 +12,10 @@ DOWN=j
LEFT=h
RIGHT=l
+# Bars
+noticetimeout=5
+noticebar=/rbar/!notice
+
# Theme
wmiifont='drift,-*-fixed-*-*-*-*-9-*-*-*-*-*-*-*'
wmiifont='-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*'
@@ -25,14 +29,12 @@ WMII_TERM=(xterm)
# Column Rules
wmiir write /colrules <<!
/gimp/ -> 17+83+41
-/./ -> 62+38 # Golden Ratio
+/.*/ -> 62+38 # Golden Ratio
!
# Tagging Rules
wmiir write /tagrules <<!
-/VLC/ -> ~
-/XMMS.*/ -> ~
-/MPlayer.*/ -> ~
+/MPlayer|VLC/ -> ~
!
# Status Bar Info
@@ -43,7 +45,15 @@ fn status {
# End Configuration
-ifs='' {nl=`{echo}}
+# For the time being, this file follows the lisp bracing
+# convention. i.e.:
+# if(frob this) {
+# frob that
+# if(frob theother) {
+# unfrob this
+# unfrob that}}
+# Comments welcome.
+
confpath=`{echo $WMII_CONFPATH | sed 'y/:/ /'}
# Events
@@ -52,12 +62,18 @@ fn sigexit {
wi_cleankeys
}
-fn Event-CreateTag { echo $wmiinormcol $* | wmiir create /lbar/$"* }
-fn Event-DestroyTag { wmiir remove /lbar/$"* }
-fn Event-FocusTag { wmiir xwrite /lbar/$"* $wmiifocuscol $* }
-fn Event-UnfocusTag { wmiir xwrite /lbar/$"* $wmiinormcol $* }
-fn Event-UrgentTag { shift; wmiir xwrite /lbar/$"* '*'$"* }
-fn Event-NotUrgentTag { shift; wmiir xwrite /lbar/$"* $"* }
+fn Event-CreateTag {
+ echo $wmiinormcol $* | wmiir create /lbar/$"*}
+fn Event-DestroyTag {
+ wmiir remove /lbar/$"*}
+fn Event-FocusTag {
+ wmiir xwrite /lbar/$"* $wmiifocuscol $*}
+fn Event-UnfocusTag {
+ wmiir xwrite /lbar/$"* $wmiinormcol $*}
+fn Event-UrgentTag {
+ shift; wmiir xwrite /lbar/$"* '*'$"*}
+fn Event-NotUrgentTag {
+ shift; wmiir xwrite /lbar/$"* $"*}
fn Event-Unresponsive {
client = $1; shift
@@ -65,13 +81,19 @@ fn Event-Unresponsive {
msg = 'The following client is not responding. What would you like to do?'
resp = `{wihack -transient $client \
xmessage -nearmouse -buttons Kill,Wait -print \
- $msg $nl '' `{wmiir read /client/sel/label}}
+ $msg $wi_nl '' `{wmiir read /client/sel/label}}
if(~ $resp Kill)
- wmiir xwrite /client/$client/ctl slay
- }&
-}
+ wmiir xwrite /client/$client/ctl slay }&}
+echo $wmiinormcol | wmiir create $noticebar
+fn Event-Notice {
+ wmiir xwrite $noticebar $wi_arg
-fn Event-LeftBarClick { shift; wmiir xwrite /ctl view $* }
+ /bin/kill $xpid >[2]/dev/null # Let's hope this isn't reused...
+ { sleep $noticetimeout; wmiir xwrite $noticebar ' ' }& # Bug...
+ xpid = $apid}
+
+fn Event-LeftBarClick {
+ shift; wmiir xwrite /ctl view $*}
fn Event-ClientMouseDown {
client = $1; button = $2
if(~ $button 3) {
@@ -83,33 +105,20 @@ fn Event-ClientMouseDown {
wmiir xwrite /client/$client/ctl Fullscreen on
}
if(! ~ $do '')
- menulast = $do;
- }
-}
+ menulast = $do;}}
menulast = Nop
-# Utility
-fn 'fn?' {rc -c 'whatis '$1 >[2]/dev/null | grep -s '^fn ' }
-
# Actions
-fn Action {
- cmd=$1 action=Action-$cmd { shift
- if('fn?' $action)
- $action $*
- if not
- wi_runcmd `{wi_script $cmd} $*
- } &
-}
-
fn Action-rehash {
comm -23 <{ls $WMII_NS_DIR/proglist.* >[2]/dev/null | awk -F'\.' '{print $NF}'} \
<{ps | awk '{print $2}'} |
while(id=`{read})
rm $WMII_NS_DIR/proglist.$id
- wi_proglist $PATH >$progs_file
-}
-fn Action-quit { wmiir xwrite /ctl quit }
-fn Action-exec { wmiir xwrite /ctl exec $* }
+ wi_proglist $PATH >$progs_file}
+fn Action-quit {
+ wmiir xwrite /ctl quit}
+fn Action-exec {
+ wmiir xwrite /ctl exec $*}
fn Action-status {
flag x -; flag r -
if(wmiir remove /rbar/status >[2]/dev/null)
@@ -123,14 +132,13 @@ fn Action-status {
if(~ $0 rc.wmii.local */rc.wmii.local)
wi_notice This file should not be named rc.wmii.local
if not
- . `{wi_script rc.wmii.local} /dev/null
+ . `{wi_script -f rc.wmii.local}
# Key Bindings
fn key {
key=()
- for(k in Key-$*) if(! 'fn?' $k) key = ($key $k)
- ~ $#key 0
-}
+ for(k in Key-$*) if(! wi_fn-p $k) key = ($key $k)
+ ~ $#key 0}
# This is... ugly.
@@ -143,47 +151,62 @@ key $MODKEY-Control-t || fn $key {
ifs=() { keys=`{wmiir read /keys} }
wmiir xwrite /keys $MODKEY-Control-t
wmiir xwrite /ctl grabmod Mod3
- }
-}
-
-key $MODKEY-$LEFT || fn $key { wmiir xwrite /tag/sel/ctl select left }
-key $MODKEY-$RIGHT || fn $key { wmiir xwrite /tag/sel/ctl select right }
-key $MODKEY-$DOWN || fn $key { wmiir xwrite /tag/sel/ctl select down }
-key $MODKEY-$UP || fn $key { wmiir xwrite /tag/sel/ctl select up }
-
-key $MODKEY-Shift-$LEFT || fn $key { wmiir xwrite /tag/sel/ctl send sel left }
-key $MODKEY-Shift-$RIGHT || fn $key { wmiir xwrite /tag/sel/ctl send sel right }
-key $MODKEY-Shift-$DOWN || fn $key { wmiir xwrite /tag/sel/ctl send sel down }
-key $MODKEY-Shift-$UP || fn $key { wmiir xwrite /tag/sel/ctl send sel up }
-
-key $MODKEY-f || fn $key { wmiir xwrite /client/sel/ctl Fullscreen toggle }
-
-key $MODKEY-space || fn $key { wmiir xwrite /tag/sel/ctl select toggle }
-key $MODKEY-Shift-space || fn $key { wmiir xwrite /tag/sel/ctl send sel toggle }
-key $MODKEY-d || fn $key { wmiir xwrite /tag/sel/ctl colmode sel default }
-key $MODKEY-s || fn $key { wmiir xwrite /tag/sel/ctl colmode sel stack }
-key $MODKEY-m || fn $key { wmiir xwrite /tag/sel/ctl colmode sel max }
-
-key $MODKEY-Shift-c || fn $key { wmiir xwrite /client/sel/ctl kill }
-
-key $MODKEY-a || fn $key { Action `{wi_actions | wi_menu} & }
-key $MODKEY-p || fn $key { ifs=() { wi_runcmd -t `{wi_menu <$progs_file} & } }
-key $MODKEY-Return || fn $key { wi_runcmd $WMII_TERM & }
-
-key $MODKEY-t || fn $key { wmiir xwrite /ctl view `{wi_tags | wi_menu} & }
+ }}
+
+key $MODKEY-$LEFT || fn $key {
+ wmiir xwrite /tag/sel/ctl select left}
+key $MODKEY-$RIGHT || fn $key {
+ wmiir xwrite /tag/sel/ctl select right}
+key $MODKEY-$DOWN || fn $key {
+ wmiir xwrite /tag/sel/ctl select down}
+key $MODKEY-$UP || fn $key {
+ wmiir xwrite /tag/sel/ctl select up}
+
+key $MODKEY-Shift-$LEFT || fn $key {
+ wmiir xwrite /tag/sel/ctl send sel left}
+key $MODKEY-Shift-$RIGHT || fn $key {
+ wmiir xwrite /tag/sel/ctl send sel right}
+key $MODKEY-Shift-$DOWN || fn $key {
+ wmiir xwrite /tag/sel/ctl send sel down}
+key $MODKEY-Shift-$UP || fn $key {
+ wmiir xwrite /tag/sel/ctl send sel up}
+
+key $MODKEY-f || fn $key {
+ wmiir xwrite /client/sel/ctl Fullscreen toggle}
+
+key $MODKEY-space || fn $key {
+ wmiir xwrite /tag/sel/ctl select toggle}
+key $MODKEY-Shift-space || fn $key {
+ wmiir xwrite /tag/sel/ctl send sel toggle}
+key $MODKEY-d || fn $key {
+ wmiir xwrite /tag/sel/ctl colmode sel default}
+key $MODKEY-s || fn $key {
+ wmiir xwrite /tag/sel/ctl colmode sel stack}
+key $MODKEY-m || fn $key {
+ wmiir xwrite /tag/sel/ctl colmode sel max}
+
+key $MODKEY-Shift-c || fn $key {
+ wmiir xwrite /client/sel/ctl kill}
+
+key $MODKEY-a || fn $key {
+ Action `{wi_actions | wi_menu} &}
+key $MODKEY-p || fn $key {
+ ifs=() { wi_runcmd -t `{wi_menu <$progs_file} & }}
+key $MODKEY-Return || fn $key {
+ wi_runcmd $WMII_TERM &}
+
+key $MODKEY-t || fn $key {
+ wmiir xwrite /ctl view `{wi_tags | wi_menu} &}
key $MODKEY-Shift-t || fn $key {
sel = `{wmiir read /client/sel/ctl | sed 1q} \
- wmiir xwrite /client/$sel/tags `{wi_tags | wi_menu} &
-}
+ wmiir xwrite /client/$sel/tags `{wi_tags | wi_menu} &}
key $MODKEY-^`{seq 0 9} || fn $key {
- wmiir xwrite /ctl view `{echo $1 | sed 's/.*-//'}
-}
+ wmiir xwrite /ctl view `{echo $1 | sed 's/.*-//'}}
key Shift-$MODKEY-^`{seq 0 9} || fn $key {
- wmiir xwrite /client/sel/tags `{echo $1 | sed 's/.*-//'}
-}
+ wmiir xwrite /client/sel/tags `{echo $1 | sed 's/.*-//'}}
-# WM Configuration
+#` WM Configuration
wmiir write /ctl <<!
view 1
grabmod $MODKEY
@@ -203,16 +226,16 @@ Action status
Action rehash
# Tag Bar Setup
-ifs=$nl{
- wmiir rm `{comm -23 <{wmiir ls /lbar} <{wi_tags}}
+ifs=$wi_nl{
+ oldbars=`{comm -23 <{wmiir ls /lbar} <{wi_tags}}
+ if(! ~ $oldbars '')
+ wmiir rm /lbar/^$oldbars
seltag=`{wmiir read /tag/sel/ctl | sed 1q}
for(tag in `{wi_tags}) {
if(~ $tag $seltag)
echo $wmiifocuscol $tag | wmiir create /lbar/$tag
if not
- echo $wmiinormcol $tag | wmiir create /lbar/$tag
- }
-}
+ echo $wmiinormcol $tag | wmiir create /lbar/$tag}}
wi_eventloop
diff --git a/rc/wmiirc.sh b/rc/wmiirc.sh
@@ -1,5 +1,6 @@
#!/bin/sh -f
# Configure wmii
+. wmii.sh wmiirc
# Configuration Variables
MODKEY=Mod1
@@ -9,28 +10,26 @@ LEFT=h
RIGHT=l
# Colors tuples: "<text> <background> <border>"
-WMII_NORMCOLORS='#222222 #5FBF77 #2A7F3F'
-WMII_FOCUSCOLORS='#ffffff #153F1F #2A7F3F'
+WMII_NORMCOLORS='#000000 #c1c48b #81654f'
+WMII_FOCUSCOLORS='#000000 #81654f #000000'
WMII_BACKGROUND='#333333'
WMII_FONT='-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*'
set -- $(echo $WMII_NORMCOLORS $WMII_FOCUSCOLORS)
-WMII_MENU='dmenu -b -fn "$WMII_FONT" -nf '"$1 -nb $2 -sf $4 -sb $5"
-WMII_9MENU='wmii9menu -font "$WMII_FONT" -nf '"$1 -nb $2 -sf $4 -sb $5 -br $6"
+WMII_MENU='dmenu -b -fn "$WMII_FONT" -nf '"'$1' -nb '$2' -sf '$4' -sb '$5'"
+WMII_9MENU='wmii9menu -font "$WMII_FONT" -nf '"'$1' -nb '$2' -sf '$4' -sb '$5' -br '$6'"
WMII_TERM="xterm"
# Column Rules
wmiir write /colrules <<!
-/.*/ -> 58+42
+/gimp/ -> 17+83+41
+/.*/ -> 62+38 # Golden Ratio
!
# Tagging Rules
wmiir write /tagrules <<!
-/XMMS.*/ -> ~
-/MPlayer.*/ -> ~
-/.*/ -> sel
-/.*/ -> 1
+/MPlayer|VLC/ -> ~
!
# Status Bar Info
@@ -39,19 +38,8 @@ status() {
}
# Event processing
-# Processed later by `wmiiloop' and evaled.
-# Uncomment the line before the eval and run for details.
-eventstuff() {
- cat <<'!'
+wi_events -s ' ' <<'!'
# Events
- Event Start
- case "$1" in
- wmiirc)
- exit;
- esac
- Event Key
- fn=$(echo "$@" | sed 's/[^a-zA-Z_0-9]/_/g')
- Key_$fn "$@"
Event CreateTag
echo "$WMII_NORMCOLORS" "$@" | wmiir create "/lbar/$@"
Event DestroyTag
@@ -89,7 +77,7 @@ eventstuff() {
client=$1; button=$2
case "$button" in
3)
- do=$(eval $WMII_9MENU -initial "${menulast:-SomeRandomName}" Nop Delete Fullscreen)
+ do=$(wi_9menu -initial "${menulast:-SomeRandomName}" Nop Delete Fullscreen)
case "$do" in
Delete)
wmiir xwrite /client/$client/ctl kill;;
@@ -102,7 +90,7 @@ eventstuff() {
Key $MODKEY-Control-t
case $(wmiir read /keys | wc -l | tr -d ' \t\n') in
0|1)
- echo -n $Keys | tr ' ' '\012' | wmiir write /keys
+ echo -n "$Keys" | wmiir write /keys
wmiir xwrite /ctl grabmod $MODKEY;;
*)
wmiir xwrite /keys $MODKEY-Control-t
@@ -117,11 +105,11 @@ eventstuff() {
Key $MODKEY-m
wmiir xwrite /tag/sel/ctl colmode sel max
Key $MODKEY-a
- Action $(actionlist | eval $WMII_MENU) &
+ Action $(wi_actions | wi_menu) &
Key $MODKEY-p
- sh -c "$(eval $WMII_MENU <$progsfile)" &
+ sh -c "$(wi_menu <$progsfile)" &
Key $MODKEY-t
- wmiir xwrite /ctl "view $(tagsmenu)" &
+ wmiir xwrite /ctl "view $(wi_tags | wi_menu)" &
Key $MODKEY-Return
eval $WMII_TERM &
Key $MODKEY-Shift-space
@@ -131,7 +119,7 @@ eventstuff() {
Key $MODKEY-Shift-c
wmiir xwrite /client/sel/ctl kill
Key $MODKEY-Shift-t
- wmiir xwrite "/client/$(wmiir read /client/sel/ctl)/tags" "$(tagsmenu)" &
+ wmiir xwrite "/client/$(wmiir read /client/sel/ctl)/tags" "$(wi_tags | wi_menu)" &
Key $MODKEY-$LEFT
wmiir xwrite /tag/sel/ctl select left
Key $MODKEY-$RIGHT
@@ -150,59 +138,37 @@ eventstuff() {
wmiir xwrite /tag/sel/ctl send sel up
!
for i in 0 1 2 3 4 5 6 7 8 9; do
- cat <<!
+ wi_events -s ' ' <<!
Key $MODKEY-$i
wmiir xwrite /ctl view "$i"
Key $MODKEY-Shift-$i
wmiir xwrite /client/sel/tags "$i"
!
done
-}
# WM Configuration
-wmiir write /ctl << EOF
-font $WMII_FONT
-focuscolors $WMII_FOCUSCOLORS
-normcolors $WMII_NORMCOLORS
-grabmod $MODKEY
-border 1
-EOF
+wmiir write /ctl <<!
+ view 1
+ font $WMII_FONT
+ focuscolors $WMII_FOCUSCOLORS
+ normcolors $WMII_NORMCOLORS
+ grabmod $MODKEY
+ border 1
+!
+xsetroot -solid "$WMII_BACKGROUND" &
export WMII_MENU WMII_9MENU WMII_FONT WMII_TERM
export WMII_FOCUSCOLORS WMII_SELCOLORS WMII_NORMCOLORS
-# Feed events to `wmiiloop' for processing
-eval "$(eventstuff | sed 's/^[ ]//' | { . wmiiloop; })"
-
-echo "$Keys" | tr ' ' '\n' | wmiir write /keys
-
-# Functions
-Action() {
- action=$1; shift
- if [ -n "$action" ]; then
- Action_$action "$@" \
- || conf_which $action "$@"
- fi
-}
-
-proglist() {
- paths=$(echo "$@" | sed 'y/:/ /')
- ls -lL $paths 2>/dev/null \
- | awk '$1 ~ /^[^d].*x/ { print $NF }' \
- | sort | uniq
-}
-
# Misc
progsfile="$WMII_NS_DIR/.proglist"
Action status &
-proglist $PATH >$progsfile &
-
-xsetroot -solid "$WMII_BACKGROUND" &
+wi_proglist $PATH >$progsfile &
# Setup Tag Bar
-(IFS="$(echo)"; wmiir rm $(wmiir ls /lbar))
+(IFS="$(echo)"; wmiir rm $(wmiir ls /lbar | sed 's,^,/lbar/,'))
seltag="$(wmiir read /tag/sel/ctl | sed 1q)"
-wmiir ls /tag | sed -e 's|/||; /^sel$/d' | while read tag
+wi_tags | while read tag
do
if [ "$tag" = "$seltag" ]; then
echo "$WMII_FOCUSCOLORS" "$tag"
@@ -211,30 +177,5 @@ do
fi | wmiir create "/lbar/$tag"
done
-# More functions
-tagsmenu() {
- wmiir ls /tag | sed 's|/||; /^sel$/d' | eval $WMII_MENU
-}
-
-actionlist() {
- { proglist $WMII_CONFPATH
- echo -n $Actions | tr ' ' '\012'
- } | sort | uniq
-}
-
-conf_which() {
- which=$(which which)
- prog=$(PATH="$WMII_CONFPATH" $which $1); shift
- [ -n "$prog" ] && $prog "$@"
-}
-
-# Stop any running instances of wmiirc
-echo Start wmiirc | wmiir write /event || exit 1
-
-wmiir read /event | while read event
-do
- set -- $event
- event=$1; shift
- Event_$event $@
-done 2>/dev/null
+wi_eventloop
diff --git a/util/genconfig b/util/genconfig
@@ -1,21 +1,52 @@
#!/bin/sh -f
+# What I wouldn't do for rc...
+# Well... it's better than m4shgmake.
+
CONFIG="$ROOT/config.mk"
CONFSTR='# Generated by "make config"'
+# ==================== The Messy Part ====================
+
#XXX Ignores lines ending in \
parseconfig() {
- cat <<!
- /^$CONFSTR/ {exit}
+ cat <<'!' | sed "s/CONFSTR/$CONFSTR/"
+ /^CONFSTR/ {exit}
/^( *#| )/ {next}
-!
- cat <<'!'
- /=/ {
+ function fixup() {
+ sub(/ #.*/, "")
+ sub(/^ */, "")
gsub(/'/, "'\"'\"'")
- sub(/[ ]*=[ ]*/, "='")
- print $0"'"
- sub(/=.*/, "")
- print $0"_orig=\"$"$0"\""
+ sub(/[ ]*\+?=[ ]*/, "='")
+ sub(/[ ]*$/, "'")
+ var = $0
+ val = $0
+ sub(/\+?=.*/, "", var)
+ sub(/^[^=]+=/, "", val)
+ }
+ /\+=/ && !/^ / {
+ fixup()
+ if(!set[var]) {
+ print var"=''"
+ append[var]++
+ }
+ print var"=\"$" var " \"" val
+ print var"_orig=\"$" var "\""
+ next
+ }
+ /=/ && !/^ / {
+ fixup()
+ delete append[var]
+ set[var]++
+
+ print var"="val
+ print var"_orig=\"$" var "\""
+ }
+ END{
+ for(v in set)
+ print v "_append=''"
+ for(v in append)
+ print v "_append=true"
}
!
}
@@ -24,38 +55,63 @@ findinc() {
var="$1"; file="$2"; shift 2
for d in "$@"; do
if [ -d "$d" -a -f "$d/$file" ]; then
- eval "$var=\"-I$d\""; break; fi
- done
+ eval "$var=\"-I$d\""
+ break; fi; done
}
+soext=.so
+aext=.a
findlib() {
var="$1"; lib="$2"; shift 2
for d in "$@"; do
if [ -d "$d" -a -f "$d/$lib.so" -o -f "$d/lib$lib.a" ]; then
- eval "$var=\"-L$d -l$lib\""; break; fi
- done
+ _libdir="$d"; _libname="$lib"
+ eval "$var=\"-L$d -l$lib\""
+ break; fi; done
+}
+
+expand() {
+ _expand="$@"; _expand_old=''
+ while [ "$_expand" != "$_expand_old" ]; do
+ _expand_old="$_expand"
+ eval "_expand=\"$_expand\""; done
+ echo -n "$_expand"
+}
+
+cfg() {
+ CFG="$CFG
+$@"
+}
+
+equals() {
+ if [ -z "$append" ]; then
+ echo -n "=";
+ else
+ echo -n "+="; fi
}
prompt() {
var=$1; shift
- eval "def=\$$var; orig=\$${var}_orig"
+ eval "def=\$$var; orig=\$${var}_orig; append=\$${var}_append"
unset val
if [ -z "$def" -o -n "$force" ]; then
echo "$@"
- read -p "$var[$def]= " val
+ read -p "$var[$def]$(equals) " val
echo
fi
if [ -z "$val" ]; then
val="$def"; fi
- if [ "$val" != "$orig" ]; then
- CFG="$CFG
-$var=$val"; fi
+ if [ "$(expand $val)" != "$(expand "$orig")" ]; then
+ cfg "$var$(equals)$val"; fi
}
-eval "$(awk "`parseconfig`" <"$CONFIG")"
+# The messy sed... Turns $(VAR) into ${VAR}, but not $$(VAR) into $${VAR}
+eval "$(sed 's/\([^$]\)\$(\([A-Za-z_]*\))/\1${\2}/g' <"$CONFIG" | awk "`parseconfig`")"
CFG="$(sed -n "/^$CONFSTR/q; p" "$CONFIG"; echo "$CONFSTR")"
+# ==================== The Fun Part ====================
+
cat <<!
Configuring for the wmii build.
@@ -66,7 +122,7 @@ in which case, you may simply press return to accept them.
!
# Guess...
-AWKPATH=`which awk`
+AWKPATH=$(which awk 2>/dev/null)
prompt AWKPATH "Full path to your system's 'awk' program"
prompt PLAN9 "Path of a Plan 9 Port or 9base installation"
@@ -74,57 +130,101 @@ prompt PLAN9 "Path of a Plan 9 Port or 9base installation"
force=1
prompt PREFIX Installation prefix
+echo
echo "Compilation details (if you don't understand these, just leave the defaults)"
+echo
prompt CC C object compiler
prompt LD 'Linker (this should normally not be "ld")'
+set -- $CC
+if $1 -v 2>&1 | grep 'gcc version' >/dev/null; then
+ echo -n You appear to be using gcc. Is this correct? '[yes] '
+ while :; do
+ read resp
+ case "$resp" in
+ [Yy][Ee][Ss]|'')
+ cfg 'include $(ROOT)/mk/gcc.mk'
+ break;;
+ [Nn][Oo])
+ cfg 'CFLAGS=""'
+ # Not perfect. Botches system cflags, but we
+ # need to ditch the gcc ones.
+ break;;
+ *)
+ echo -n 'Please answer yes or no: '
+ esac
+ done
+ echo
+fi
+
prompt INCPATH Search path for include files
prompt LIBS Libraries to be linked with every executable
prompt CFLAGS Flags for the C compiler
prompt LDFLAGS Flags for the linker
-prompt STATIC Extra linker flags to produce a static executable
+case $(uname -s) in
+ [Dd]arwin) cfg 'STATIC=""';;
+ *) prompt STATIC Extra linker flags to produce a static executable;;
+esac
unset force
# Make some guesses
-#for i in LIBX11 LIBICONV LIBIXP INCX11; do
-# eval "unset $i ${i}_orig"; done
+# Extract the -L paths from ldflags.
+ldlibs="$(awk 'BEGIN{
+ for(i=1; i <= ARGC; i++)
+ if(ARGV[i] ~ /-L/)
+ print ":" substr(ARGV[i], 3)
+ }' $LDFLAGS)"
+# Turn include paths into ../lib paths.
+inclibs="$(expand "$INCPATH"|sed 's,/include:,/lib:,g; s,/include$,/lib,')"
+# Lace them all together, and expand them.
+libs="$(expand "$LIBDIR:$ldlibs:$inclibs:/usr/local/lib:/opt/local/lib")"
-libs="$LIBDIR:$(echo "$INCPATH"|sed 's,/include\(:\|$\),/lib\1,g')"
-libs="$libs$(echo "$LDFLAGS"|sed 's,-L\([^ ]*\),:\1,g')"
-libs="$libs:/usr/local/lib:/opt/local/lib"
-eval "libs=\"$libs\""
LIBIXP=${LIBIXP%/libixp.a}
INCPATH="$INCPATH:/usr/local/include:/opt/local/include"
+incpath="$(expand "$INCPATH")"
-oifs="$IFS"
-IFS=:
-findinc INCX11 X11/Xlib.h $INCPATH \
+oifs="$IFS"; IFS=:
+findinc INCX11 X11/Xlib.h $incpath \
/usr/X11R6/include /usr/x11/include /usr/x11/include /usr/X11/include \
/usr/openwin/include /opt/x11/include /opt/X11/include
-findinc INCICONV iconv.h $INCPATH
+findinc INCICONV iconv.h $incpath
findlib LIBX11 X11 $libs \
/usr/X11R6/lib /usr/X11/lib /usr/openwin/lib /usr/x11/lib \
/opt/X11 /opt/x11 /usr/local/lib /opt/local/lib
findlib LIBICONV iconv $libs
-findlib LIBIXP ixp "$ROOT/lib" $libs
-[ -e "$ROOT/libixp" ] && LIBIXP="$ROOT/lib/libixp.a"
-LIBIXP=$(echo "$LIBIXP"|sed 's,^-L\([^ ]*\) -l\([^ ]*\)$,\1/lib\2.a,')
+
+if [ -d "$ROOT/libixp" ]; then
+ _libdir="$ROOT/lib"; else
+ soext=.a findlib LIBIXP ixp "$ROOT/lib" $libs; fi
+LIBIXP="$_libdir/libixp.a"
IFS="$oifs"
# Back to prompting
echo Library paths...
prompt INCX11 Compiler flags to find X11 includes
prompt LIBX11 Linker flags to link against libX11
-# Yuck...
-if nm -D `ldd /bin/sh | awk '$1 ~ /^libc\.so/ {print $3}'` |
- awk '$2 == "T" && $3 == "iconv" {exit 0}; END {exit 1}'
+
+# Find out if the system libc includes iconv...
+# GNU systems tend to make /usr/lib/libc.so or /lib/libc.so
+# linker scripts rather than libraries, so I can't parse them.
+# As a kludge, I ask ldd what actual libc.so /bin/sh links to,
+# which is pretty reliable. It's very unlikely that anyone will
+# actually be prompted for this.
+# I suppose the auto*hell way would be to just compile
+# something against libc. Perhaps another day.
+if nm -D $(ldd /bin/sh | awk '$1 ~ /^libc\.so/ {print $3}') |
+ awk -ve=1 '$2 == "T" && $3 == "iconv" {e=0; exit}; END {exit e}'
then
- echo "Your system's libc appears to contain iconv"
+ echo
+ echo "Your system's libc appears to include iconv."
+ echo
+else
+ prompt LIBICONV Linker flags to link agains libiconv \
+ '(may be left blank if iconv is part of your system libc)'
fi
-prompt LIBICONV Linker flags to link agains libiconv '(may be left blank if iconv is part of your system libc)'
prompt INCICONV Compiler flags to find iconv.h
prompt LIBIXP Path to libixp.a
@@ -132,3 +232,4 @@ echo Writing config.mk
echo "$CFG
" >config.mk
echo Done.
+