diff -r 5d06862f9b21 sys/man/1/acme
--- a/sys/man/1/acme	Thu Sep 01 11:46:44 2016 +0000
+++ b/sys/man/1/acme	Thu Sep 01 19:07:59 2016 -0400
@@ -1,6 +1,6 @@
 .TH ACME 1
 .SH NAME
-acme, win \- interactive text windows
+acme, win, awd \- interactive text windows
 .SH SYNOPSIS
 .B acme
 [
@@ -20,7 +20,7 @@
 ]
 [
 .B -l
-.I loadfile
+.I [loadfile]
 |
 .I file
 \&... ]
@@ -29,6 +29,11 @@
 [
 .I command
 ]
+.LP
+.B awd
+[
+.I label
+]
 .SH DESCRIPTION
 .I Acme
 manages windows of text that may be edited interactively or by external programs.
@@ -49,8 +54,10 @@
 .B -l
 option, the state of the entire system is loaded
 from
-.IR loadfile ,
-which should have been created by a
+.I loadfile 
+or 
+.B $home/lib/acme.$sysname.dump
+if no loadfile is specified, which should have been created by a
 .B Dump
 command (q.v.),
 and subsequent
@@ -66,8 +73,12 @@
 .RB ( -F )
 option sets the main font, usually variable-pitch (alternate, usually fixed-pitch);
 the default is
+.B $font
+(or, if
+.B $font
+is not set
 .B /lib/font/bit/lucidasans/euro.8.font
-.RB ( \&.../lucm/unicode.9.font ).
+.RB ( \&.../lucm/unicode.9.font )).
 Tab intervals are set to the width of 4 (or the value of
 .BR $tabstop )
 numeral zeros in the appropriate font.
@@ -619,6 +630,21 @@
 window with button
 2 is similar to using
 .BR Send .
+.PP
+.I Awd
+loads the tag line of its window with the directory in which it's running, suffixed
+.BI - label
+(default
+.BR rc );
+it is
+intended to be executed by a
+.B cd
+function for use in
+.I win
+windows.  An example definition is
+.EX
+	fn cd { builtin cd $1 && awd $sysname }
+.EE
 .SS "Applications and guide files
 In the directory
 .B /acme
@@ -657,6 +683,8 @@
 .IR acme -specific
 programs such as
 .I win
+and
+.I awd
 reside.
 .SH FILES
 .TF $home/acme.dump
@@ -685,6 +713,8 @@
 .B /sys/src/cmd/acme
 .br
 .B /acme/bin/source/win
+.br
+.B /sys/src/cmd/awd.c
 .SH SEE ALSO
 .IR acme (4)
 .br
diff -r 5d06862f9b21 sys/src/cmd/acme/acme.c
--- a/sys/src/cmd/acme/acme.c	Thu Sep 01 11:46:44 2016 +0000
+++ b/sys/src/cmd/acme/acme.c	Thu Sep 01 19:07:59 2016 -0400
@@ -52,7 +52,7 @@
 void
 threadmain(int argc, char *argv[])
 {
-	int i;
+	int i, noload;
 	char *p, *loadfile;
 	char buf[256];
 	Column *c;
@@ -65,6 +65,7 @@
 	ncol = -1;
 
 	loadfile = nil;
+	noload = 1;
 	ARGBEGIN{
 	case 'a':
 		globalautoindent = TRUE;
@@ -92,12 +93,11 @@
 		break;
 	case 'l':
 		loadfile = ARGF();
-		if(loadfile == nil)
-			goto Usage;
+		noload = 0;
 		break;
 	default:
 	Usage:
-		fprint(2, "usage: acme [-ab] [-c ncol] [-f font] [-F fixedfont] [-l loadfile | file...]\n");
+		fprint(2, "usage: acme [-abL] [-c ncol] [-f font] [-F fixedfont] [-l loadfile | file...]\n");
 		exits("usage");
 	}ARGEND
 
@@ -119,6 +119,14 @@
 	objtype = getenv("objtype");
 	home = getenv("home");
 	p = getenv("tabstop");
+	if(!noload)
+	if(loadfile == nil){
+		loadfile = smprint("%s/lib/acme.%s.dump", home, sysname());
+		if(access(loadfile, AEXIST)){
+			free(loadfile);
+			loadfile = nil;
+		}
+	}
 	if(p != nil){
 		maxtab = strtoul(p, nil, 0);
 		free(p);
diff -r 5d06862f9b21 sys/src/cmd/acme/buff.c
--- a/sys/src/cmd/acme/buff.c	Thu Sep 01 11:46:44 2016 +0000
+++ b/sys/src/cmd/acme/buff.c	Thu Sep 01 19:07:59 2016 -0400
@@ -276,13 +276,13 @@
 	return loadfile(fd, q0, nulls, bufloader, b);
 }
 
-void
+int
 bufread(Buffer *b, uint q0, Rune *s, uint n)
 {
 	uint m;
 
 	if(!(q0<=b->nc && q0+n<=b->nc))
-		error("bufread: internal error");
+		return -1;
 
 	while(n > 0){
 		setcache(b, q0);
@@ -292,6 +292,7 @@
 		s += m;
 		n -= m;
 	}
+	return 0;
 }
 
 void
diff -r 5d06862f9b21 sys/src/cmd/acme/dat.h
--- a/sys/src/cmd/acme/dat.h	Thu Sep 01 11:46:44 2016 +0000
+++ b/sys/src/cmd/acme/dat.h	Thu Sep 01 19:07:59 2016 -0400
@@ -83,12 +83,6 @@
 	Block	*free[Maxblock/Blockincr+1];
 };
 
-Disk*	diskinit(void);
-Block*	disknewblock(Disk*, uint);
-void		diskrelease(Disk*, Block*);
-void		diskread(Disk*, Block*, Rune*, uint);
-void		diskwrite(Disk*, Block**, Rune*, uint);
-
 struct Buffer
 {
 	uint	nc;
@@ -101,12 +95,6 @@
 	Block	**bl;		/* array of blocks */
 	uint	nbl;			/* number of blocks */
 };
-void		bufinsert(Buffer*, uint, Rune*, uint);
-void		bufdelete(Buffer*, uint, uint);
-uint		bufload(Buffer*, uint, int, int*);
-void		bufread(Buffer*, uint, Rune*, uint);
-void		bufclose(Buffer*);
-void		bufreset(Buffer*);
 
 struct Elog
 {
@@ -116,12 +104,6 @@
 	uint		nr;		/* # runes in string or file name */
 	Rune		*r;
 };
-void	elogterm(File*);
-void	elogclose(File*);
-void	eloginsert(File*, int, Rune*, int);
-void	elogdelete(File*, int, int);
-void	elogreplace(File*, int, int, Rune*, int);
-void	elogapply(File*);
 
 struct File
 {
@@ -145,20 +127,6 @@
 	int		ntext;
 	int		dumpid;	/* used in dumping zeroxed windows */
 };
-File*		fileaddtext(File*, Text*);
-void		fileclose(File*);
-void		filedelete(File*, uint, uint);
-void		filedeltext(File*, Text*);
-void		fileinsert(File*, uint, Rune*, uint);
-uint		fileload(File*, uint, int, int*);
-void		filemark(File*);
-void		filereset(File*);
-void		filesetname(File*, Rune*, int);
-void		fileundelete(File*, Buffer*, uint, uint);
-void		fileuninsert(File*, Buffer*, uint, uint);
-void		fileunsetname(File*, Buffer*);
-void		fileundo(File*, int, uint*, uint*);
-uint		fileredoseq(File*);
 
 enum	/* Text.what */
 {
@@ -194,36 +162,6 @@
 	int	needundo;
 };
 
-uint		textbacknl(Text*, uint, uint);
-uint		textbsinsert(Text*, uint, Rune*, uint, int, int*);
-int		textbswidth(Text*, Rune);
-int		textclickmatch(Text*, int, int, int, uint*);
-void		textclose(Text*);
-void		textcolumnate(Text*, Dirlist**, int);
-void		textcommit(Text*, int);
-void		textconstrain(Text*, uint, uint, uint*, uint*);
-void		textdelete(Text*, uint, uint, int);
-void		textdoubleclick(Text*, uint*, uint*);
-void		textfill(Text*);
-void		textframescroll(Text*, int);
-void		textinit(Text*, File*, Rectangle, Reffont*, Image**);
-void		textinsert(Text*, uint, Rune*, uint, int);
-uint		textload(Text*, uint, char*, int);
-Rune		textreadc(Text*, uint);
-void		textredraw(Text*, Rectangle, Font*, Image*, int);
-void		textreset(Text*);
-int		textresize(Text*, Rectangle);
-void		textscrdraw(Text*);
-void		textscroll(Text*, int);
-void		textselect(Text*);
-int		textselect2(Text*, uint*, uint*, Text**);
-int		textselect23(Text*, uint*, uint*, Image*, int);
-int		textselect3(Text*, uint*, uint*);
-void		textsetorigin(Text*, uint, int);
-void		textsetselect(Text*, uint, uint);
-void		textshow(Text*, uint, uint, int);
-void		texttype(Text*, Rune);
-
 struct Window
 {
 		QLock;
@@ -272,27 +210,6 @@
 	Rectangle	tagtop;
 };
 
-void	wininit(Window*, Window*, Rectangle);
-void	winlock(Window*, int);
-void	winlock1(Window*, int);
-void	winunlock(Window*);
-void	wintype(Window*, Text*, Rune);
-void	winundo(Window*, int);
-void	winsetname(Window*, Rune*, int);
-void	winsettag(Window*);
-void	winsettag1(Window*);
-void	wincommit(Window*, Text*);
-int	winresize(Window*, Rectangle, int);
-void	winclose(Window*);
-void	windelete(Window*);
-int	winclean(Window*, int);
-void	windirfree(Window*);
-void	winevent(Window*, char*, ...);
-void	winmousebut(Window*);
-void	winaddincl(Window*, Rune*, int);
-void	wincleartag(Window*);
-char	*winctlprint(Window*, char*, int);
-
 struct Column
 {
 	Rectangle r;
@@ -303,18 +220,6 @@
 	int		safe;
 };
 
-void		colinit(Column*, Rectangle);
-Window*	coladd(Column*, Window*, Window*, int);
-void		colclose(Column*, Window*, int);
-void		colcloseall(Column*);
-void		colresize(Column*, Rectangle);
-Text*	colwhich(Column*, Point);
-void		coldragwin(Column*, Window*, int);
-void		colgrow(Column*, Window*, int);
-int		colclean(Column*);
-void		colsort(Column*);
-void		colmousebut(Column*);
-
 struct Row
 {
 	QLock;
@@ -325,19 +230,6 @@
 
 };
 
-void		rowinit(Row*, Rectangle);
-Column*	rowadd(Row*, Column *c, int);
-void		rowclose(Row*, Column*, int);
-Text*	rowwhich(Row*, Point);
-Column*	rowwhichcol(Row*, Point);
-void		rowresize(Row*, Rectangle);
-Text*	rowtype(Row*, Rune, Point);
-void		rowdragcol(Row*, Column*, int but);
-int		rowclean(Row*);
-void		rowdump(Row*, char*);
-int		rowload(Row*, char*, int);
-void		rowloadfonts(char*);
-
 struct Timer
 {
 	int		dt;
@@ -404,27 +296,12 @@
 
 };
 
-void		xfidctl(void *);
-void		xfidflush(Xfid*);
-void		xfidopen(Xfid*);
-void		xfidclose(Xfid*);
-void		xfidread(Xfid*);
-void		xfidwrite(Xfid*);
-void		xfidctlwrite(Xfid*, Window*);
-void		xfideventread(Xfid*, Window*);
-void		xfideventwrite(Xfid*, Window*);
-void		xfidindexread(Xfid*);
-void		xfidutfread(Xfid*, Text*, uint, int);
-int		xfidruneread(Xfid*, Text*, uint, uint);
-
 struct Reffont
 {
 	Ref;
 	Font		*f;
 
 };
-Reffont	*rfget(int, int, int, char*);
-void		rfclose(Reffont*);
 
 struct Rangeset
 {
diff -r 5d06862f9b21 sys/src/cmd/acme/fns.h
--- a/sys/src/cmd/acme/fns.h	Thu Sep 01 11:46:44 2016 +0000
+++ b/sys/src/cmd/acme/fns.h	Thu Sep 01 19:07:59 2016 -0400
@@ -87,6 +87,127 @@
 char*	edittext(Window*, int, Rune*, int);
 void		flushwarnings(void);
 
+/* moved from dat.h */
+
+File*		fileaddtext(File*, Text*);
+void		fileclose(File*);
+void		filedelete(File*, uint, uint);
+void		filedeltext(File*, Text*);
+void		fileinsert(File*, uint, Rune*, uint);
+uint		fileload(File*, uint, int, int*);
+void		filemark(File*);
+void		filereset(File*);
+void		filesetname(File*, Rune*, int);
+void		fileundelete(File*, Buffer*, uint, uint);
+void		fileuninsert(File*, Buffer*, uint, uint);
+void		fileunsetname(File*, Buffer*);
+void		fileundo(File*, int, uint*, uint*);
+uint		fileredoseq(File*);
+Disk*	diskinit(void);
+Block*	disknewblock(Disk*, uint);
+void		diskrelease(Disk*, Block*);
+void		diskread(Disk*, Block*, Rune*, uint);
+void		diskwrite(Disk*, Block**, Rune*, uint);
+void		bufinsert(Buffer*, uint, Rune*, uint);
+void		bufdelete(Buffer*, uint, uint);
+uint		bufload(Buffer*, uint, int, int*);
+int		bufread(Buffer*, uint, Rune*, uint);
+void		bufclose(Buffer*);
+void		bufreset(Buffer*);
+void	elogterm(File*);
+void	elogclose(File*);
+void	eloginsert(File*, int, Rune*, int);
+void	elogdelete(File*, int, int);
+void	elogreplace(File*, int, int, Rune*, int);
+void	elogapply(File*);
+uint		textbacknl(Text*, uint, uint);
+uint		textbsinsert(Text*, uint, Rune*, uint, int, int*);
+int		textbswidth(Text*, Rune);
+int		textclickmatch(Text*, int, int, int, uint*);
+void		textclose(Text*);
+void		textcolumnate(Text*, Dirlist**, int);
+void		textcommit(Text*, int);
+void		textconstrain(Text*, uint, uint, uint*, uint*);
+void		textdelete(Text*, uint, uint, int);
+void		textdoubleclick(Text*, uint*, uint*);
+void		textfill(Text*);
+void		textframescroll(Text*, int);
+void		textinit(Text*, File*, Rectangle, Reffont*, Image**);
+void		textinsert(Text*, uint, Rune*, uint, int);
+uint		textload(Text*, uint, char*, int);
+Rune		textreadc(Text*, uint);
+void		textredraw(Text*, Rectangle, Font*, Image*, int);
+void		textreset(Text*);
+int		textresize(Text*, Rectangle);
+void		textscrdraw(Text*);
+void		textscroll(Text*, int);
+void		textselect(Text*);
+int		textselect2(Text*, uint*, uint*, Text**);
+int		textselect23(Text*, uint*, uint*, Image*, int);
+int		textselect3(Text*, uint*, uint*);
+void		textsetorigin(Text*, uint, int);
+void		textsetselect(Text*, uint, uint);
+void		textshow(Text*, uint, uint, int);
+void		texttype(Text*, Rune);
+void	wininit(Window*, Window*, Rectangle);
+void	winlock(Window*, int);
+void	winlock1(Window*, int);
+void	winunlock(Window*);
+void	wintype(Window*, Text*, Rune);
+void	winundo(Window*, int);
+void	winsetname(Window*, Rune*, int);
+void	winsettag(Window*);
+void	winsettag1(Window*);
+void	wincommit(Window*, Text*);
+int	winresize(Window*, Rectangle, int);
+void	winclose(Window*);
+void	windelete(Window*);
+int	winclean(Window*, int);
+void	windirfree(Window*);
+void	winevent(Window*, char*, ...);
+void	winmousebut(Window*);
+void	winaddincl(Window*, Rune*, int);
+void	wincleartag(Window*);
+char	*winctlprint(Window*, char*, int);
+void		colinit(Column*, Rectangle);
+Window*	coladd(Column*, Window*, Window*, int);
+void		colclose(Column*, Window*, int);
+void		colcloseall(Column*);
+void		colresize(Column*, Rectangle);
+Text*	colwhich(Column*, Point);
+void		coldragwin(Column*, Window*, int);
+void		colgrow(Column*, Window*, int);
+int		colclean(Column*);
+void		colsort(Column*);
+void		colmousebut(Column*);
+void		rowinit(Row*, Rectangle);
+Column*	rowadd(Row*, Column *c, int);
+void		rowclose(Row*, Column*, int);
+Text*	rowwhich(Row*, Point);
+Column*	rowwhichcol(Row*, Point);
+void		rowresize(Row*, Rectangle);
+Text*	rowtype(Row*, Rune, Point);
+void		rowdragcol(Row*, Column*, int but);
+int		rowclean(Row*);
+void		rowdump(Row*, char*);
+int		rowload(Row*, char*, int);
+void		rowloadfonts(char*);
+void		xfidctl(void *);
+void		xfidflush(Xfid*);
+void		xfidopen(Xfid*);
+void		xfidclose(Xfid*);
+void		xfidread(Xfid*);
+void		xfidwrite(Xfid*);
+void		xfidctlwrite(Xfid*, Window*);
+void		xfideventread(Xfid*, Window*);
+void		xfideventwrite(Xfid*, Window*);
+void		xfidindexread(Xfid*);
+void		xfidutfread(Xfid*, Text*, uint, int);
+int		xfidruneread(Xfid*, Text*, uint, uint);
+Reffont	*rfget(int, int, int, char*);
+void		rfclose(Reffont*);
+
+
 #define	runemalloc(a)		(Rune*)emalloc((a)*sizeof(Rune))
 #define	runerealloc(a, b)	(Rune*)erealloc((a), (b)*sizeof(Rune))
 #define	runemove(a, b, c)	memmove((a), (b), (c)*sizeof(Rune))
diff -r 5d06862f9b21 sys/src/cmd/acme/rows.c
--- a/sys/src/cmd/acme/rows.c	Thu Sep 01 11:46:44 2016 +0000
+++ b/sys/src/cmd/acme/rows.c	Thu Sep 01 19:07:59 2016 -0400
@@ -310,7 +310,7 @@
 			warning(nil, "can't find file for dump: $home not defined\n");
 			goto Rescue;
 		}
-		sprint(buf, "%s/acme.dump", home);
+		sprint(buf, "%s/lib/acme.%s.dump", home, sysname());
 		file = buf;
 	}
 	fd = create(file, OWRITE, 0600);
diff -r 5d06862f9b21 sys/src/cmd/acme/text.c
--- a/sys/src/cmd/acme/text.c	Thu Sep 01 11:46:44 2016 +0000
+++ b/sys/src/cmd/acme/text.c	Thu Sep 01 19:07:59 2016 -0400
@@ -498,7 +498,8 @@
 	if(t->cq0<=q && q<t->cq0+t->ncache)
 		r = t->cache[q-t->cq0];
 	else
-		bufread(t->file, q, &r, 1);
+		if(bufread(t->file, q, &r, 1) == -1)
+			return (Rune)0;
 	return r;
 }
 
@@ -1253,12 +1254,50 @@
 	nil
 };
 
+static int bracketrange = 50;
+
+uint
+findleftbracket(Text *t, uint q)
+{
+	int i;
+	Rune c;
+
+	for(i = 0; i < bracketrange; i++){
+		c = textreadc(t, q-(uint)i);
+		if(c == (Rune)0)
+			return q;
+		if(runestrchr(left1, c) != nil)
+			return q-(uint)i+1;
+		if (runestrchr(left3, c) != nil)
+			return q-(uint)i+1;
+		if (runestrchr(left2, c) != nil)
+			return q;
+	}
+	return q;
+}
+
 void
 textdoubleclick(Text *t, uint *q0, uint *q1)
 {
 	int c, i;
-	Rune *r, *l, *p;
+	Rune *r, *l, *p, rb;
 	uint q;
+	uint mq, oq0;
+
+/* double clicking in brackets -10,+25 away from one will select
+   all in between the brackets */
+	if((mq = findleftbracket(t, *q0)) != *q0){
+		oq0 = *q0;
+		*q0 = mq;
+		for(i = 0; i < bracketrange; i++){
+			rb = textreadc(t, mq+i);
+			if(runestrchr(right1, rb) != nil){
+				*q1 = mq+i;
+				return;
+			}
+		}
+		*q0 = oq0;
+	}
 
 	for(i=0; left[i]!=nil; i++){
 		q = *q0;
diff -r 5d06862f9b21 sys/src/cmd/acme/wind.c
--- a/sys/src/cmd/acme/wind.c	Thu Sep 01 11:46:44 2016 +0000
+++ b/sys/src/cmd/acme/wind.c	Thu Sep 01 19:07:59 2016 -0400
@@ -372,6 +372,8 @@
 	w->isscratch = FALSE;
 	if(n>=6 && runeeq(L"/guide", 6, name+(n-6), 6))
 		w->isscratch = TRUE;
+	if(n>=4 && runeeq(L"/man", 4, name, 4))
+		w->isscratch = TRUE;
 	else if(n>=7 && runeeq(L"+Errors", 7, name+(n-7), 7))
 		w->isscratch = TRUE;
 	filesetname(t->file, name, n);
