From 5100b165ea37229cbdc9d2614ae0be248ddf3a30 Mon Sep 17 00:00:00 2001 From: Ethan Morgan Date: Fri, 13 Feb 2026 15:06:35 +0000 Subject: init --- bin/9 | 2 +- bin/9.rc | 4 +- bin/9fs | 2 +- bin/Getdir | 2 +- bin/adict | 2 +- bin/doctype | 2 +- bin/ipso | 2 +- bin/lookman | 2 +- bin/macedit | 2 +- bin/man | 2 +- bin/mount | 2 +- bin/quote1 | 2 +- bin/quote2 | 2 +- bin/sig | 2 +- bin/soelim | 2 +- bin/spell | 2 +- bin/src | 2 +- bin/ssam | 2 +- bin/stack | 2 +- bin/troff2png | 2 +- bin/u.rc | 2 +- bin/unmount | 2 +- bin/upas/isspam | 2 +- bin/upas/msgcat | 2 +- bin/upas/spam | 2 +- bin/upas/spambox | 2 +- bin/upas/unspam | 2 +- bin/upas/unspambox | 2 +- bin/vmount | 2 +- bin/vwhois | 2 +- bin/wintext | 2 +- bin/yesterday | 2 +- dist/debian/mkpkg | 6 +- dist/debian/mkrep | 6 +- dist/manweb | 2 +- dist/mkdirlist | 2 +- dist/mkfilelist | 2 +- dist/publish | 6 +- dist/troff/tfont | 8 +- fix.patch | 291 +++++++++++++++++++++++++++++++++++++ lp/bin/UNLOCK | 2 +- lp/bin/lpsend.rc | 2 +- lp/daemon/generic | 2 +- lp/daemon/gsdev | 2 +- lp/daemon/psdev | 2 +- lp/kill/generic | 2 +- lp/process/dvipost | 2 +- lp/process/g3post | 2 +- lp/process/generic | 2 +- lp/process/gifpost | 2 +- lp/process/hpost | 2 +- lp/process/jpgpost | 2 +- lp/process/noproc | 2 +- lp/process/p9bitpost | 2 +- lp/process/pdfgs | 2 +- lp/process/pdfpost | 2 +- lp/process/post | 2 +- lp/process/ppost | 2 +- lp/process/psextract | 2 +- lp/process/tr2post | 2 +- lp/sched/FIFO | 2 +- lp/spooler/generic | 2 +- lp/spooler/lpdspool | 2 +- lp/spooler/nospool | 2 +- lp/stat/generic | 2 +- lp/stat/lpd | 2 +- mac/9term.app/Contents/MacOS/9term | 2 +- mac/Plumb.app/Contents/MacOS/plumb | 2 +- mail/lib/qmail | 2 +- mail/lib/remotemail | 2 +- mail/lib/validateattachment | 2 +- man/mkindex | 2 +- man/secindex | 2 +- src/cmd/acme/acme.c | 97 ++++++------- src/cmd/acme/scrl.c | 14 +- src/cmd/acme/text.c | 82 +++++++---- tmac/tmac.an | 2 +- tmac/tmac.anhtml | 2 +- tmac/tmac.pm | 4 +- 79 files changed, 483 insertions(+), 173 deletions(-) create mode 100644 fix.patch diff --git a/bin/9 b/bin/9 index 04a942af..cd71c889 100755 --- a/bin/9 +++ b/bin/9 @@ -1,6 +1,6 @@ #!/bin/sh -PLAN9=${PLAN9:-/usr/local/plan9} +PLAN9=${PLAN9:-/Users/ethan/plan9port} export PLAN9 case "$PATH" in diff --git a/bin/9.rc b/bin/9.rc index 8a6cea9b..36ca5a95 100755 --- a/bin/9.rc +++ b/bin/9.rc @@ -1,7 +1,7 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc if(~ $#PLAN9 0) - PLAN9=/usr/local/plan9 + PLAN9=/Users/ethan/plan9port if(! ~ $path(1) $PLAN9/bin) path=($PLAN9/bin $path) diff --git a/bin/9fs b/bin/9fs index 467b3191..4746aed5 100755 --- a/bin/9fs +++ b/bin/9fs @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc if(! ~ $#* 1){ echo 'usage: 9fs sysname' diff --git a/bin/Getdir b/bin/Getdir index 5e40dc4f..4e704a03 100755 --- a/bin/Getdir +++ b/bin/Getdir @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc # Click on an acme directory window and then execute Getdir diff --git a/bin/adict b/bin/adict index 0b1e1a25..52c1696d 100755 --- a/bin/adict +++ b/bin/adict @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc . 9.rc . $PLAN9/lib/acme.rc diff --git a/bin/doctype b/bin/doctype index 05e3cba4..5f129e39 100755 --- a/bin/doctype +++ b/bin/doctype @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc # doctype: synthesize proper command line for troff diff --git a/bin/ipso b/bin/ipso index 9de10933..7a7889b2 100755 --- a/bin/ipso +++ b/bin/ipso @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc . 9.rc name = secstore diff --git a/bin/lookman b/bin/lookman index 72d093c3..2c17bb1d 100755 --- a/bin/lookman +++ b/bin/lookman @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc . 9.rc diff --git a/bin/macedit b/bin/macedit index 23a17a25..cc6c6550 100755 --- a/bin/macedit +++ b/bin/macedit @@ -1,6 +1,6 @@ #!/bin/bash -PLAN9=${PLAN9:-/usr/local/plan9} +PLAN9=${PLAN9:-/Users/ethan/plan9port} bin=$PLAN9/bin file=$1 diff --git a/bin/man b/bin/man index 3401738b..e958b4b1 100755 --- a/bin/man +++ b/bin/man @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc . 9.rc . $PLAN9/man/fonts diff --git a/bin/mount b/bin/mount index e29cc201..9fe26c3b 100755 --- a/bin/mount +++ b/bin/mount @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc if(! ~ $#* 2){ echo 'usage: mount addr mtpt' >[1=2] diff --git a/bin/quote1 b/bin/quote1 index f52480fd..53f3ad4c 100755 --- a/bin/quote1 +++ b/bin/quote1 @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc . 9.rc diff --git a/bin/quote2 b/bin/quote2 index e31e3de1..fffedead 100755 --- a/bin/quote2 +++ b/bin/quote2 @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc cmd = `{quote1 $* | tail -1} if (~ $#cmd 0) { diff --git a/bin/sig b/bin/sig index ed4c983a..97304073 100755 --- a/bin/sig +++ b/bin/sig @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc # Usage: sig key ... # prints out function signatures by grepping the manual diff --git a/bin/soelim b/bin/soelim index 2ba3de99..f99910a8 100755 --- a/bin/soelim +++ b/bin/soelim @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc # joyless reimplementation of soelim # the $0 recursion is a bit ugly diff --git a/bin/spell b/bin/spell index eea05ca4..6838519f 100755 --- a/bin/spell +++ b/bin/spell @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc . 9.rc spellflags=() diff --git a/bin/src b/bin/src index bedb9f9a..a5fd8819 100755 --- a/bin/src +++ b/bin/src @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc . 9.rc sym = 'threadmain?z diff --git a/bin/ssam b/bin/ssam index 7b479ea5..2ef11efb 100755 --- a/bin/ssam +++ b/bin/ssam @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc # ssam - stream interface to sam flagfmt='n,e script,f sfile' diff --git a/bin/stack b/bin/stack index 5744cef9..84192d30 100755 --- a/bin/stack +++ b/bin/stack @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc if(~ $#* 0) pid=core diff --git a/bin/troff2png b/bin/troff2png index f97ab26e..5adc4579 100755 --- a/bin/troff2png +++ b/bin/troff2png @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc 9 troff -ms $* | tr2post | gs -g1000x1000 -r144 -dNOPAUSE -dQUIET \ diff --git a/bin/u.rc b/bin/u.rc index e0827a05..c1415c58 100755 --- a/bin/u.rc +++ b/bin/u.rc @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc if(~ $#PLAN9 1) opath=$path i=() { path=() diff --git a/bin/unmount b/bin/unmount index 46976f16..38d9486e 100755 --- a/bin/unmount +++ b/bin/unmount @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc if(! ~ $#* 1){ echo 'usage: unmount mtpt' >[1=2] diff --git a/bin/upas/isspam b/bin/upas/isspam index 03be23f7..eb84c82c 100755 --- a/bin/upas/isspam +++ b/bin/upas/isspam @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc rfork en diff --git a/bin/upas/msgcat b/bin/upas/msgcat index 7067a435..4ca996de 100755 --- a/bin/upas/msgcat +++ b/bin/upas/msgcat @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc fn read9p { srv=$1; shift diff --git a/bin/upas/spam b/bin/upas/spam index d7d44852..ab840640 100755 --- a/bin/upas/spam +++ b/bin/upas/spam @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc rfork en diff --git a/bin/upas/spambox b/bin/upas/spambox index b34cd300..390cc724 100755 --- a/bin/upas/spambox +++ b/bin/upas/spambox @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc if (~ $#* 0) echo usage: spambox mailfs/mbox && exit "usage" diff --git a/bin/upas/unspam b/bin/upas/unspam index 1d056d52..64161cf0 100755 --- a/bin/upas/unspam +++ b/bin/upas/unspam @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc rfork en diff --git a/bin/upas/unspambox b/bin/upas/unspambox index bfa70531..4ec9dff6 100755 --- a/bin/upas/unspambox +++ b/bin/upas/unspambox @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc if (~ $#* 0) echo usage: unspambox mailfs/mbox && exit "usage" diff --git a/bin/vmount b/bin/vmount index 103ce07c..5b3f7446 100755 --- a/bin/vmount +++ b/bin/vmount @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc if(! ~ $#* 2){ echo 'usage: vmount server mtpt' >[1=2] diff --git a/bin/vwhois b/bin/vwhois index ab5addf2..f1d57d35 100755 --- a/bin/vwhois +++ b/bin/vwhois @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc for(i) plumb -dseemail -a 'filetype=vwhois digest='$i.$pid' mailtype=new sender='$i Mail/mbox/XXXvwhois diff --git a/bin/wintext b/bin/wintext index 1f36a05c..ed81fa7b 100755 --- a/bin/wintext +++ b/bin/wintext @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc if(~ $winid [0-9]*) { 9p read acme/$winid/body diff --git a/bin/yesterday b/bin/yesterday index 04ef31c7..8012f464 100755 --- a/bin/yesterday +++ b/bin/yesterday @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc . 9.rc diff --git a/dist/debian/mkpkg b/dist/debian/mkpkg index 830d8b2c..96d64d73 100755 --- a/dist/debian/mkpkg +++ b/dist/debian/mkpkg @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc nl=' ' @@ -55,11 +55,11 @@ for(i)@{ dir=$1 sub("/[^/]+$", "/", dir) if(dir != lastdir){ - printf("mkdir -p ''%s''\n", pkg "/usr/local/plan9/" dir); + printf("mkdir -p ''%s''\n", pkg "/Users/ethan/plan9port/" dir); lastdir = dir } if($1 !~ /\/$/) - printf("cp ''%s'' ''%s''\n", plan9 "/" $1, pkg "/usr/local/plan9/" $1) + printf("cp ''%s'' ''%s''\n", plan9 "/" $1, pkg "/Users/ethan/plan9port/" $1) }' $TREE9/dist/filelist | rc size=`{du -sk $i | awk '{print $1}'} { diff --git a/dist/debian/mkrep b/dist/debian/mkrep index 17ca1ee7..ad82bccc 100755 --- a/dist/debian/mkrep +++ b/dist/debian/mkrep @@ -1,10 +1,10 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc cd /scratch/rsc/plan9 cvs up -dAP cd dist; ./mkfilelist >filelist -cp filelist /usr/local/plan9/dist -cd /usr/local/plan9/dist/debian +cp filelist /Users/ethan/plan9port/dist +cd /Users/ethan/plan9port/dist/debian rm -rf dists pool mkdir -p dists pool diff --git a/dist/manweb b/dist/manweb index ce455dad..7494902b 100755 --- a/dist/manweb +++ b/dist/manweb @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc verbose=no if(~ $1 -v) diff --git a/dist/mkdirlist b/dist/mkdirlist index 8f43fc8a..e776303c 100755 --- a/dist/mkdirlist +++ b/dist/mkdirlist @@ -1,4 +1,4 @@ -#!/usr/local/plan9/bin/rc +#!/Users/ethan/plan9port/bin/rc echo '
'
 echo 'Plan 9 from User Space '$2
diff --git a/dist/mkfilelist b/dist/mkfilelist
index eaea8933..348300c5 100755
--- a/dist/mkfilelist
+++ b/dist/mkfilelist
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 @{cd $PLAN9; find . -type f -print; find . -type d -print | sed 's;$;/;'} | 
 	sort | sed 's;^./;;' | grep . |
diff --git a/dist/publish b/dist/publish
index a9b50b88..295ec2aa 100755
--- a/dist/publish
+++ b/dist/publish
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 dir=$9fansweb
 if (~ $#dir 0) {
@@ -21,8 +21,8 @@ cp ss.html $root/screenshots/index.html
 @{cd ../unix/man && mk push}
 @{cd ../unix && mk push}
 
-rm -rf $root/../usr/local/plan9
-mkdir -p $root/../usr/local/plan9
+rm -rf $root/../Users/ethan/plan9port
+mkdir -p $root/../Users/ethan/plan9port
 @{cd ..; git archive HEAD} | @{cd $root/../usr/local/plan9 && u tar xf -}
 for(d in `{find $root/../usr/local/plan9 -type d}) {
 	9 rc ./mkdirlist $d `{echo $d | sed 's;.*/usr;/usr;'} >t1 && mv t1 $d/index.html
diff --git a/dist/troff/tfont b/dist/troff/tfont
index 3b3e862d..6f9fa507 100755
--- a/dist/troff/tfont
+++ b/dist/troff/tfont
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 rm *.tpost *.troff *.pfb *.pfa *.afm map.sfd
 
@@ -60,7 +60,7 @@ f.generate("'$font^%s.pfb'", "", ("afm",), 72, "map.sfd")
 	for(h in $hex){
 		if(test -f $font$h.pfb){
 			pfb2pfa $font$h.pfb
-			mv $font$h.pfa /usr/local/plan9/postscript/font/$font$h
+			mv $font$h.pfa /Users/ethan/plan9port/postscript/font/$font$h
 			afm2troff -h -o 0x$h^00 $font$h.afm >>$font.troff
 			echo 0x$h^00 0x$h^FF $font$h >>$font.tpost
 		}
@@ -73,6 +73,6 @@ f.generate("'$font^%s.pfb'", "", ("afm",), 72, "map.sfd")
 	sam -d $font.troff <$PLAN9/dist/troff/devutf.sam
 	if(~ $font *Mono*)
 		sam -d $font.troff <$PLAN9/dist/troff/mono.sam
-	cp $font.troff /usr/local/plan9/troff/font/devutf/$font
-	cp $font.tpost /usr/local/plan9/postscript/troff/$font
+	cp $font.troff /Users/ethan/plan9port/troff/font/devutf/$font
+	cp $font.tpost /Users/ethan/plan9port/postscript/troff/$font
 }
diff --git a/fix.patch b/fix.patch
new file mode 100644
index 00000000..c04b906a
--- /dev/null
+++ b/fix.patch
@@ -0,0 +1,291 @@
+diff --git a/src/cmd/acme/acme.c b/src/cmd/acme/acme.c
+index bb7741536..b4968fc0d 100644
+--- a/src/cmd/acme/acme.c
++++ b/src/cmd/acme/acme.c
+@@ -1033,63 +1033,58 @@ Cursor2 boxcursor2 = {
+ 	 0x00, 0x00, 0x00, 0x00}
+ };
+ 
+-void
+-iconinit(void)
+-{
+-	Rectangle r;
+-	Image *tmp;
+-
+-	if(tagcols[BACK] == nil) {
+-		/* Blue */
+-		tagcols[BACK] = allocimagemix(display, DPalebluegreen, DWhite);
+-		tagcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreygreen);
+-		tagcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
+-		tagcols[TEXT] = display->black;
+-		tagcols[HTEXT] = display->black;
+-
+-		/* Yellow */
+-		textcols[BACK] = allocimagemix(display, DPaleyellow, DWhite);
+-		textcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DDarkyellow);
+-		textcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DYellowgreen);
+-		textcols[TEXT] = display->black;
+-		textcols[HTEXT] = display->black;
+-	}
+-
+-	r = Rect(0, 0, Scrollwid, font->height+1);
+-	if(button && eqrect(r, button->r))
+-		return;
+-
+-	if(button){
+-		freeimage(button);
+-		freeimage(modbutton);
+-		freeimage(colbutton);
+-	}
+-
+-	button = allocimage(display, r, screen->chan, 0, DNofill);
+-	draw(button, r, tagcols[BACK], nil, r.min);
+-	border(button, r, ButtonBorder, tagcols[BORD], ZP);
+-
+-	r = button->r;
+-	modbutton = allocimage(display, r, screen->chan, 0, DNofill);
+-	draw(modbutton, r, tagcols[BACK], nil, r.min);
+-	border(modbutton, r, ButtonBorder, tagcols[BORD], ZP);
+-	r = insetrect(r, ButtonBorder);
+-	tmp = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DMedblue);
+-	draw(modbutton, r, tmp, nil, ZP);
+-	freeimage(tmp);
+-
+-	r = button->r;
+-	colbutton = allocimage(display, r, screen->chan, 0, DPurpleblue);
+-
+-	but2col = allocimage(display, r, screen->chan, 1, 0xAA0000FF);
+-	but3col = allocimage(display, r, screen->chan, 1, 0x006600FF);
+-}
+ 
+ /*
+  * /dev/snarf updates when the file is closed, so we must open our own
+  * fd here rather than use snarffd
+  */
+ 
++void
++iconinit(void)
++{
++  Rectangle r;
++  Image *tmp;
++
++  /* Blue */
++  tagcols[BACK] = display->white;
++  tagcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x72DEC2FF);
++  tagcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x72DEC2FF);
++  tagcols[TEXT] = display->black;
++  tagcols[HTEXT] = display->white;
++
++  /* Yellow */
++  textcols[BACK] = allocimagemix(display, DWhite, DWhite);
++  textcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x72DEC2FF);
++  /* Halftone */
++  textcols[BORD] = allocimage(display, Rect(0,0,2,2), CMAP8, 1, 0x000000FF);
++  draw(textcols[BORD], Rect(1,1,2,2), display->white, nil, ZP);
++  draw(textcols[BORD], Rect(0,0,1,1), display->white, nil, ZP);
++  textcols[TEXT] = display->black;
++  textcols[HTEXT] = display->black;
++
++  if(button){
++    freeimage(button);
++    freeimage(modbutton);
++    freeimage(colbutton);
++  }
++  /* Button */
++  r = Rect(0, 0, Scrollwid, font->height+1);
++  button = allocimage(display, r, screen->chan, 0, DNofill);
++  draw(button, r, tagcols[BORD], nil, r.min);
++  r.max.x -= 4;
++  fillellipse(button, (Point){r.min.x + 5, r.min.y + 7}, 3, 3, display->white, ZP);
++  /* Mod Button */
++  r = button->r;
++  modbutton = allocimage(display, r, screen->chan, 0, DNofill);
++  draw(modbutton, r, tagcols[BORD], nil, r.min);
++  r = insetrect(r, 2);
++  fillellipse(modbutton, (Point){r.min.x + 3, r.min.y + 5}, 3, 3, display->black, ZP);
++  r = button->r;
++  colbutton = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x72DEC2FF);
++  but2col = allocimage(display, r, screen->chan, 1, 0x000000FF);
++  but3col = allocimage(display, r, screen->chan, 1, 0x72DEC2FF);
++}
++
+ /* rio truncates larges snarf buffers, so this avoids using the
+  * service if the string is huge */
+ 
+diff --git a/src/cmd/acme/scrl.c b/src/cmd/acme/scrl.c
+index 6504699da..ab489ea59 100644
+--- a/src/cmd/acme/scrl.c
++++ b/src/cmd/acme/scrl.c
+@@ -69,13 +69,13 @@ textscrdraw(Text *t)
+ 	r1.max.x = Dx(r);
+ 	r2 = scrpos(r1, t->org, t->org+t->fr.nchars, t->file->b.nc);
+ 	if(!eqrect(r2, t->lastsr)){
+-		t->lastsr = r2;
+-		draw(b, r1, t->fr.cols[BORD], nil, ZP);
+-		draw(b, r2, t->fr.cols[BACK], nil, ZP);
+-		r2.min.x = r2.max.x-1;
+-		draw(b, r2, t->fr.cols[BORD], nil, ZP);
+-		draw(t->fr.b, r, b, nil, Pt(0, r1.min.y));
+-/*flushimage(display, 1); // BUG? */
++  		t->lastsr = r2;
++  		draw(b, r1, t->fr.cols[BORD], nil, ZP);
++  		r2.max.x = r2.max.x+1;
++  		draw(b, r2, t->fr.cols[TEXT], nil, ZP);
++  		r2.min.x = r2.max.x-1;
++  		draw(b, r2, t->fr.cols[BORD], nil, ZP);
++  		draw(t->fr.b, r, b, nil, Pt(0, r1.min.y));
+ 	}
+ }
+ 
+diff --git a/src/cmd/acme/text.c b/src/cmd/acme/text.c
+index 09422dda0..4f70867ed 100644
+--- a/src/cmd/acme/text.c
++++ b/src/cmd/acme/text.c
+@@ -692,10 +692,27 @@ texttype(Text *t, Rune r)
+ 			textshow(t, t->q1+1, t->q1+1, TRUE);
+ 		return;
+ 	case Kdown:
+-		if(t->what == Tag)
+-			goto Tagdown;
+-		n = t->fr.maxlines/3;
+-		goto case_Down;
++		typecommit(t);
++		q0 = t->q0;
++		nnb = 0;
++		if(t->q0>0 && textreadc(t, t->q0-1)!='\n')
++			nnb = textbswidth(t, 0x15);
++		while(q0file->b.nc && textreadc(t, q0)!='\n')
++			q0++;
++		if (q0 == t->file->b.nc) {
++			textshow(t, q0, q0, TRUE);
++			return;
++		}
++		q0++;
++		while(nnb>=0 && q0file->b.nc) {
++			if (textreadc(t, q0)=='\n')
++				break;
++			nnb--;
++			if (nnb >= 0)
++				q0++;
++		}
++		textshow(t, q0, q0, TRUE);
++		return;
+ 	case Kscrollonedown:
+ 		if(t->what == Tag)
+ 			goto Tagdown;
+@@ -710,10 +727,26 @@ texttype(Text *t, Rune r)
+ 		textsetorigin(t, q0, TRUE);
+ 		return;
+ 	case Kup:
+-		if(t->what == Tag)
+-			goto Tagup;
+-		n = t->fr.maxlines/3;
+-		goto case_Up;
++		typecommit(t);
++		nnb = 0;
++		if(t->q0>0 && textreadc(t, t->q0-1)!='\n')
++			nnb = textbswidth(t, 0x15);
++		q1 = nnb;
++		if(t->q0-nnb > 1  && textreadc(t, t->q0-nnb-1)=='\n')
++			nnb++;
++    q0 = t->q0-nnb;
++	  textshow(t, q0, q0, TRUE);
++
++    nnb = textbswidth(t, 0x15);
++    if (nnb <= 1)
++      return;
++    q0  = q0-nnb;
++    while (q1>0 && textreadc(t, q0)!='\n') {
++      q1--;
++      q0++;
++    }
++    textshow(t, q0, q0, TRUE);
++		return;
+ 	case Kscrolloneup:
+ 		if(t->what == Tag)
+ 			goto Tagup;
+@@ -726,25 +759,6 @@ texttype(Text *t, Rune r)
+ 		textsetorigin(t, q0, TRUE);
+ 		return;
+ 	case Khome:
+-		typecommit(t);
+-		if(t->org > t->iq1) {
+-			q0 = textbacknl(t, t->iq1, 1);
+-			textsetorigin(t, q0, TRUE);
+-		} else
+-			textshow(t, 0, 0, FALSE);
+-		return;
+-	case Kend:
+-		typecommit(t);
+-		if(t->iq1 > t->org+t->fr.nchars) {
+-			if(t->iq1 > t->file->b.nc) {
+-				// should not happen, but does. and it will crash textbacknl.
+-				t->iq1 = t->file->b.nc;
+-			}
+-			q0 = textbacknl(t, t->iq1, 1);
+-			textsetorigin(t, q0, TRUE);
+-		} else
+-			textshow(t, t->file->b.nc, t->file->b.nc, FALSE);
+-		return;
+ 	case 0x01:	/* ^A: beginning of line */
+ 		typecommit(t);
+ 		/* go to where ^U would erase, if not already at BOL */
+@@ -753,6 +767,7 @@ texttype(Text *t, Rune r)
+ 			nnb = textbswidth(t, 0x15);
+ 		textshow(t, t->q0-nnb, t->q0-nnb, TRUE);
+ 		return;
++	case Kend:
+ 	case 0x05:	/* ^E: end of line */
+ 		typecommit(t);
+ 		q0 = t->q0;
+@@ -760,19 +775,26 @@ texttype(Text *t, Rune r)
+ 			q0++;
+ 		textshow(t, q0, q0, TRUE);
+ 		return;
++	case 0x03: /* Ctrl-c: copy */
+ 	case Kcmd+'c':	/* %C: copy */
+ 		typecommit(t);
+ 		cut(t, t, nil, TRUE, FALSE, nil, 0);
+ 		return;
++	case 0x1a: /* Ctrl-z: undo */
+ 	case Kcmd+'z':	/* %Z: undo */
+ 	 	typecommit(t);
+ 		undo(t, nil, nil, TRUE, 0, nil, 0);
+ 		return;
++	case 0x19: /* Ctrl-y: redo */
+ 	case Kcmd+'Z':	/* %-shift-Z: redo */
+ 	 	typecommit(t);
+ 		undo(t, nil, nil, FALSE, 0, nil, 0);
+ 		return;
+-
++	case 0x13: /* Ctrl-S: put file */
++	case Kcmd+'s':
++		typecommit(t);
++		put(&(t->w)->body, nil, nil, XXX, XXX, nil, 0);
++		return;
+ 	Tagdown:
+ 		/* expand tag to show all text */
+ 		if(!t->w->tagexpand){
+@@ -796,6 +818,7 @@ texttype(Text *t, Rune r)
+ 	}
+ 	/* cut/paste must be done after the seq++/filemark */
+ 	switch(r){
++	case 0x18: /* Ctrl-X: cut */
+ 	case Kcmd+'x':	/* %X: cut */
+ 		typecommit(t);
+ 		if(t->what == Body){
+@@ -806,6 +829,7 @@ texttype(Text *t, Rune r)
+ 		textshow(t, t->q0, t->q0, 1);
+ 		t->iq1 = t->q0;
+ 		return;
++	case 0x16: /* Ctrl-V: paste */
+ 	case Kcmd+'v':	/* %V: paste */
+ 		typecommit(t);
+ 		if(t->what == Body){
+@@ -1661,4 +1685,4 @@ textreset(Text *t)
+ 	t->q1 = 0;
+ 	filereset(t->file);
+ 	bufreset(&t->file->b);
+-}
++}
+\ No newline at end of file
diff --git a/lp/bin/UNLOCK b/lp/bin/UNLOCK
index fadddf76..e5834254 100755
--- a/lp/bin/UNLOCK
+++ b/lp/bin/UNLOCK
@@ -1,3 +1,3 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 >$1/LOCK && rm -f $1/LOCK
diff --git a/lp/bin/lpsend.rc b/lp/bin/lpsend.rc
index bf64787c..34f93f05 100755
--- a/lp/bin/lpsend.rc
+++ b/lp/bin/lpsend.rc
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 if (! ~ $DEBUG '') { flag x + }
 if (test -e /net/tcp/clone) {
 	dialstring=`{ndb/query sys $1 dom}
diff --git a/lp/daemon/generic b/lp/daemon/generic
index 938c40a0..628c872a 100755
--- a/lp/daemon/generic
+++ b/lp/daemon/generic
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 rfork s	
 
diff --git a/lp/daemon/gsdev b/lp/daemon/gsdev
index bb48edd9..78b45ffe 100755
--- a/lp/daemon/gsdev
+++ b/lp/daemon/gsdev
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 fn local {
 	GSDEVICE=`{echo $LPCLASS | 9 sed 's/(.*\+)?gs!([^+]*)(\+.*)?/\2/'}
diff --git a/lp/daemon/psdev b/lp/daemon/psdev
index 895db8a3..b152a5bd 100755
--- a/lp/daemon/psdev
+++ b/lp/daemon/psdev
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 fn local {
 	psdownload -f -H$PLAN9/postscript/font -mfontmap -plw+ \
diff --git a/lp/kill/generic b/lp/kill/generic
index f6c472b9..34725a4c 100755
--- a/lp/kill/generic
+++ b/lp/kill/generic
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 if (! ~ $DEBUG '') flag x +
 
 cd $LPSPOOL
diff --git a/lp/process/dvipost b/lp/process/dvipost
index 520aa395..bf4af65d 100755
--- a/lp/process/dvipost
+++ b/lp/process/dvipost
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 if (~ $DEBUG 1) flag x +
 # convert Tex dvi to PostScript
 PATCH='%!PS-Adobe-2.0'
diff --git a/lp/process/g3post b/lp/process/g3post
index 64063fed..748d3b2c 100755
--- a/lp/process/g3post
+++ b/lp/process/g3post
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 # convert CCITT G3 Fax format to PostScript
 if (! ~ $DEBUG '') flag x +
 PATCH='%%Patch from lp'
diff --git a/lp/process/generic b/lp/process/generic
index 3b793d2f..9b9fbdfc 100755
--- a/lp/process/generic
+++ b/lp/process/generic
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 # Tries to determine what type of file you are printing and do the correct
 # thing with it.
 # It currently knows about images, troff intermediate, and ascii files.
diff --git a/lp/process/gifpost b/lp/process/gifpost
index d6afee29..570b89de 100755
--- a/lp/process/gifpost
+++ b/lp/process/gifpost
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 # convert CCITT G3 Fax format to PostScript
 if (! ~ $DEBUG '') flag x +
 PATCH='%%Patch from lp'
diff --git a/lp/process/hpost b/lp/process/hpost
index 169cb2ac..a905a218 100755
--- a/lp/process/hpost
+++ b/lp/process/hpost
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 if (! ~ $DEBUG '') flag x +
 REVFLAG=''
 if (~ $LPCLASS *reverse*) {
diff --git a/lp/process/jpgpost b/lp/process/jpgpost
index 0212ce89..a55175ce 100755
--- a/lp/process/jpgpost
+++ b/lp/process/jpgpost
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 # convert JPG to PostScript
 if (! ~ $DEBUG '') flag x +
 PATCH='%%Patch from lp'
diff --git a/lp/process/noproc b/lp/process/noproc
index c5cf1a8c..bef6c7bc 100755
--- a/lp/process/noproc
+++ b/lp/process/noproc
@@ -1,3 +1,3 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 # No processing, copy file from input to output
 cat
diff --git a/lp/process/p9bitpost b/lp/process/p9bitpost
index 78b7de56..9cc93a98 100755
--- a/lp/process/p9bitpost
+++ b/lp/process/p9bitpost
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 # convert plan 9 image to PostScript
 if (~ $DEBUG 1) flag x +
 PATCH='%%Patch from lp'
diff --git a/lp/process/pdfgs b/lp/process/pdfgs
index 90c00c07..1f73e0ad 100755
--- a/lp/process/pdfgs
+++ b/lp/process/pdfgs
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 #
 # we don't go through postscript, because to
diff --git a/lp/process/pdfpost b/lp/process/pdfpost
index 3abde800..c7fa896e 100755
--- a/lp/process/pdfpost
+++ b/lp/process/pdfpost
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 # convert PDF output to PostScript
 if (! ~ $DEBUG '') flag x +
 PATCH='%!PS
diff --git a/lp/process/post b/lp/process/post
index 63bf036b..9f285f60 100755
--- a/lp/process/post
+++ b/lp/process/post
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 if (! ~ $DEBUG '') flag x +
 PATCH='%!PS
 %%Patch from lp'
diff --git a/lp/process/ppost b/lp/process/ppost
index 67436d3c..93dd7fce 100755
--- a/lp/process/ppost
+++ b/lp/process/ppost
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 # converts a regular ascii file to PostScript
 if (! ~ $DEBUG '') flag x +
 PATCH='%%Patch from lp'
diff --git a/lp/process/psextract b/lp/process/psextract
index 55695a1c..8a762733 100755
--- a/lp/process/psextract
+++ b/lp/process/psextract
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 # extract pages $OLIST from postscript on stdin
 
diff --git a/lp/process/tr2post b/lp/process/tr2post
index 23d45ad3..4efd2c73 100755
--- a/lp/process/tr2post
+++ b/lp/process/tr2post
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 if (~ $DEBUG 1) flag x +
 # convert troff output to PostScript
 PATCH='%%Patch from lp'
diff --git a/lp/sched/FIFO b/lp/sched/FIFO
index 702e9155..1e7667c0 100755
--- a/lp/sched/FIFO
+++ b/lp/sched/FIFO
@@ -1,2 +1,2 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 9 ls -ptr $* | 9 sed -n -e '/^[0-9][0-9]*\.[1-9][0-9]*$/p'
diff --git a/lp/spooler/generic b/lp/spooler/generic
index 83ee13ff..9d6e9229 100755
--- a/lp/spooler/generic
+++ b/lp/spooler/generic
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 # fn sigexit { rm -f $LPSPOOL/$LPDEST/.$pid.* $LPSPOOL/$LPDEST/$pid.* $LPSPOOL/$LPDEST }
 if (! ~ $DEBUG '') flag x +
 
diff --git a/lp/spooler/lpdspool b/lp/spooler/lpdspool
index 3f14eaed..25b89da2 100755
--- a/lp/spooler/lpdspool
+++ b/lp/spooler/lpdspool
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 if (! ~ $DEBUG '') flag x +
 
diff --git a/lp/spooler/nospool b/lp/spooler/nospool
index 4d019983..389bdb72 100755
--- a/lp/spooler/nospool
+++ b/lp/spooler/nospool
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 if (! ~ $DEBUG '') flag x +
 
 if (~ $LPCLASS *sendEOT*) SENDEOT=1
diff --git a/lp/stat/generic b/lp/stat/generic
index c1b1ba25..2a168ba2 100755
--- a/lp/stat/generic
+++ b/lp/stat/generic
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 if (! ~ $DEBUG '') flag x +
 
 if (~ $THIS_HOST $DEST_HOST) {
diff --git a/lp/stat/lpd b/lp/stat/lpd
index 3bea23e1..e89008a3 100755
--- a/lp/stat/lpd
+++ b/lp/stat/lpd
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 if (! ~ $DEBUG '') flag x +
 
diff --git a/mac/9term.app/Contents/MacOS/9term b/mac/9term.app/Contents/MacOS/9term
index 04eb042c..17a0615d 100755
--- a/mac/9term.app/Contents/MacOS/9term
+++ b/mac/9term.app/Contents/MacOS/9term
@@ -1,7 +1,7 @@
 #!/bin/bash
 fshell=$(finger $(whoami) | sed -n 's/.*Shell: //p' | sed 1q)
 SHELL=${fshell:-$SHELL}
-PLAN9=${PLAN9:-/usr/local/plan9}
+PLAN9=${PLAN9:-/Users/ethan/plan9port}
 cd $HOME
 arch=x86_64
 if arch -arch arm64 date >/dev/null 2>&1; then
diff --git a/mac/Plumb.app/Contents/MacOS/plumb b/mac/Plumb.app/Contents/MacOS/plumb
index b3f15330..0b01876c 100755
--- a/mac/Plumb.app/Contents/MacOS/plumb
+++ b/mac/Plumb.app/Contents/MacOS/plumb
@@ -7,7 +7,7 @@ arch=x86_64
 if arch -arch arm64 date >/dev/null 2>&1; then
 	arch=arm64
 fi
-PLAN9=${PLAN9:-/usr/local/plan9}
+PLAN9=${PLAN9:-/Users/ethan/plan9port}
 
 bin=$PLAN9/bin
 IFS=$'\n'
diff --git a/mail/lib/qmail b/mail/lib/qmail
index c63f2b36..861560c2 100755
--- a/mail/lib/qmail
+++ b/mail/lib/qmail
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 # qmail sender machine user...
 rfork s
 upas/vf | upas/qer $PLAN9/mail/queue smtp $* || exit 'qer failed'
diff --git a/mail/lib/remotemail b/mail/lib/remotemail
index 028642e9..a57315f1 100755
--- a/mail/lib/remotemail
+++ b/mail/lib/remotemail
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 shift
 sender=$1
 shift
diff --git a/mail/lib/validateattachment b/mail/lib/validateattachment
index 74018d0e..84200224 100755
--- a/mail/lib/validateattachment
+++ b/mail/lib/validateattachment
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 rfork n
 
 . 9.rc
diff --git a/man/mkindex b/man/mkindex
index 543bf1a5..ac3e8a9c 100755
--- a/man/mkindex
+++ b/man/mkindex
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 
 . 9.rc
 
diff --git a/man/secindex b/man/secindex
index d042ac10..8eb5b70a 100755
--- a/man/secindex
+++ b/man/secindex
@@ -1,4 +1,4 @@
-#!/usr/local/plan9/bin/rc
+#!/Users/ethan/plan9port/bin/rc
 builtin cd $1
 for (i in [a-z0-9:]*.[0-9]*) {
 	b=`{echo $i | sed 's/\..*//'}
diff --git a/src/cmd/acme/acme.c b/src/cmd/acme/acme.c
index bb774153..b4968fc0 100644
--- a/src/cmd/acme/acme.c
+++ b/src/cmd/acme/acme.c
@@ -1033,63 +1033,58 @@ Cursor2 boxcursor2 = {
 	 0x00, 0x00, 0x00, 0x00}
 };
 
-void
-iconinit(void)
-{
-	Rectangle r;
-	Image *tmp;
-
-	if(tagcols[BACK] == nil) {
-		/* Blue */
-		tagcols[BACK] = allocimagemix(display, DPalebluegreen, DWhite);
-		tagcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreygreen);
-		tagcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
-		tagcols[TEXT] = display->black;
-		tagcols[HTEXT] = display->black;
-
-		/* Yellow */
-		textcols[BACK] = allocimagemix(display, DPaleyellow, DWhite);
-		textcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DDarkyellow);
-		textcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DYellowgreen);
-		textcols[TEXT] = display->black;
-		textcols[HTEXT] = display->black;
-	}
-
-	r = Rect(0, 0, Scrollwid, font->height+1);
-	if(button && eqrect(r, button->r))
-		return;
-
-	if(button){
-		freeimage(button);
-		freeimage(modbutton);
-		freeimage(colbutton);
-	}
-
-	button = allocimage(display, r, screen->chan, 0, DNofill);
-	draw(button, r, tagcols[BACK], nil, r.min);
-	border(button, r, ButtonBorder, tagcols[BORD], ZP);
-
-	r = button->r;
-	modbutton = allocimage(display, r, screen->chan, 0, DNofill);
-	draw(modbutton, r, tagcols[BACK], nil, r.min);
-	border(modbutton, r, ButtonBorder, tagcols[BORD], ZP);
-	r = insetrect(r, ButtonBorder);
-	tmp = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DMedblue);
-	draw(modbutton, r, tmp, nil, ZP);
-	freeimage(tmp);
-
-	r = button->r;
-	colbutton = allocimage(display, r, screen->chan, 0, DPurpleblue);
-
-	but2col = allocimage(display, r, screen->chan, 1, 0xAA0000FF);
-	but3col = allocimage(display, r, screen->chan, 1, 0x006600FF);
-}
 
 /*
  * /dev/snarf updates when the file is closed, so we must open our own
  * fd here rather than use snarffd
  */
 
+void
+iconinit(void)
+{
+  Rectangle r;
+  Image *tmp;
+
+  /* Blue */
+  tagcols[BACK] = display->white;
+  tagcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x72DEC2FF);
+  tagcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x72DEC2FF);
+  tagcols[TEXT] = display->black;
+  tagcols[HTEXT] = display->white;
+
+  /* Yellow */
+  textcols[BACK] = allocimagemix(display, DWhite, DWhite);
+  textcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x72DEC2FF);
+  /* Halftone */
+  textcols[BORD] = allocimage(display, Rect(0,0,2,2), CMAP8, 1, 0x000000FF);
+  draw(textcols[BORD], Rect(1,1,2,2), display->white, nil, ZP);
+  draw(textcols[BORD], Rect(0,0,1,1), display->white, nil, ZP);
+  textcols[TEXT] = display->black;
+  textcols[HTEXT] = display->black;
+
+  if(button){
+    freeimage(button);
+    freeimage(modbutton);
+    freeimage(colbutton);
+  }
+  /* Button */
+  r = Rect(0, 0, Scrollwid, font->height+1);
+  button = allocimage(display, r, screen->chan, 0, DNofill);
+  draw(button, r, tagcols[BORD], nil, r.min);
+  r.max.x -= 4;
+  fillellipse(button, (Point){r.min.x + 5, r.min.y + 7}, 3, 3, display->white, ZP);
+  /* Mod Button */
+  r = button->r;
+  modbutton = allocimage(display, r, screen->chan, 0, DNofill);
+  draw(modbutton, r, tagcols[BORD], nil, r.min);
+  r = insetrect(r, 2);
+  fillellipse(modbutton, (Point){r.min.x + 3, r.min.y + 5}, 3, 3, display->black, ZP);
+  r = button->r;
+  colbutton = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x72DEC2FF);
+  but2col = allocimage(display, r, screen->chan, 1, 0x000000FF);
+  but3col = allocimage(display, r, screen->chan, 1, 0x72DEC2FF);
+}
+
 /* rio truncates larges snarf buffers, so this avoids using the
  * service if the string is huge */
 
diff --git a/src/cmd/acme/scrl.c b/src/cmd/acme/scrl.c
index 6504699d..ab489ea5 100644
--- a/src/cmd/acme/scrl.c
+++ b/src/cmd/acme/scrl.c
@@ -69,13 +69,13 @@ textscrdraw(Text *t)
 	r1.max.x = Dx(r);
 	r2 = scrpos(r1, t->org, t->org+t->fr.nchars, t->file->b.nc);
 	if(!eqrect(r2, t->lastsr)){
-		t->lastsr = r2;
-		draw(b, r1, t->fr.cols[BORD], nil, ZP);
-		draw(b, r2, t->fr.cols[BACK], nil, ZP);
-		r2.min.x = r2.max.x-1;
-		draw(b, r2, t->fr.cols[BORD], nil, ZP);
-		draw(t->fr.b, r, b, nil, Pt(0, r1.min.y));
-/*flushimage(display, 1); // BUG? */
+  		t->lastsr = r2;
+  		draw(b, r1, t->fr.cols[BORD], nil, ZP);
+  		r2.max.x = r2.max.x+1;
+  		draw(b, r2, t->fr.cols[TEXT], nil, ZP);
+  		r2.min.x = r2.max.x-1;
+  		draw(b, r2, t->fr.cols[BORD], nil, ZP);
+  		draw(t->fr.b, r, b, nil, Pt(0, r1.min.y));
 	}
 }
 
diff --git a/src/cmd/acme/text.c b/src/cmd/acme/text.c
index 09422dda..4f70867e 100644
--- a/src/cmd/acme/text.c
+++ b/src/cmd/acme/text.c
@@ -692,10 +692,27 @@ texttype(Text *t, Rune r)
 			textshow(t, t->q1+1, t->q1+1, TRUE);
 		return;
 	case Kdown:
-		if(t->what == Tag)
-			goto Tagdown;
-		n = t->fr.maxlines/3;
-		goto case_Down;
+		typecommit(t);
+		q0 = t->q0;
+		nnb = 0;
+		if(t->q0>0 && textreadc(t, t->q0-1)!='\n')
+			nnb = textbswidth(t, 0x15);
+		while(q0file->b.nc && textreadc(t, q0)!='\n')
+			q0++;
+		if (q0 == t->file->b.nc) {
+			textshow(t, q0, q0, TRUE);
+			return;
+		}
+		q0++;
+		while(nnb>=0 && q0file->b.nc) {
+			if (textreadc(t, q0)=='\n')
+				break;
+			nnb--;
+			if (nnb >= 0)
+				q0++;
+		}
+		textshow(t, q0, q0, TRUE);
+		return;
 	case Kscrollonedown:
 		if(t->what == Tag)
 			goto Tagdown;
@@ -710,10 +727,26 @@ texttype(Text *t, Rune r)
 		textsetorigin(t, q0, TRUE);
 		return;
 	case Kup:
-		if(t->what == Tag)
-			goto Tagup;
-		n = t->fr.maxlines/3;
-		goto case_Up;
+		typecommit(t);
+		nnb = 0;
+		if(t->q0>0 && textreadc(t, t->q0-1)!='\n')
+			nnb = textbswidth(t, 0x15);
+		q1 = nnb;
+		if(t->q0-nnb > 1  && textreadc(t, t->q0-nnb-1)=='\n')
+			nnb++;
+    q0 = t->q0-nnb;
+	  textshow(t, q0, q0, TRUE);
+
+    nnb = textbswidth(t, 0x15);
+    if (nnb <= 1)
+      return;
+    q0  = q0-nnb;
+    while (q1>0 && textreadc(t, q0)!='\n') {
+      q1--;
+      q0++;
+    }
+    textshow(t, q0, q0, TRUE);
+		return;
 	case Kscrolloneup:
 		if(t->what == Tag)
 			goto Tagup;
@@ -726,25 +759,6 @@ texttype(Text *t, Rune r)
 		textsetorigin(t, q0, TRUE);
 		return;
 	case Khome:
-		typecommit(t);
-		if(t->org > t->iq1) {
-			q0 = textbacknl(t, t->iq1, 1);
-			textsetorigin(t, q0, TRUE);
-		} else
-			textshow(t, 0, 0, FALSE);
-		return;
-	case Kend:
-		typecommit(t);
-		if(t->iq1 > t->org+t->fr.nchars) {
-			if(t->iq1 > t->file->b.nc) {
-				// should not happen, but does. and it will crash textbacknl.
-				t->iq1 = t->file->b.nc;
-			}
-			q0 = textbacknl(t, t->iq1, 1);
-			textsetorigin(t, q0, TRUE);
-		} else
-			textshow(t, t->file->b.nc, t->file->b.nc, FALSE);
-		return;
 	case 0x01:	/* ^A: beginning of line */
 		typecommit(t);
 		/* go to where ^U would erase, if not already at BOL */
@@ -753,6 +767,7 @@ texttype(Text *t, Rune r)
 			nnb = textbswidth(t, 0x15);
 		textshow(t, t->q0-nnb, t->q0-nnb, TRUE);
 		return;
+	case Kend:
 	case 0x05:	/* ^E: end of line */
 		typecommit(t);
 		q0 = t->q0;
@@ -760,19 +775,26 @@ texttype(Text *t, Rune r)
 			q0++;
 		textshow(t, q0, q0, TRUE);
 		return;
+	case 0x03: /* Ctrl-c: copy */
 	case Kcmd+'c':	/* %C: copy */
 		typecommit(t);
 		cut(t, t, nil, TRUE, FALSE, nil, 0);
 		return;
+	case 0x1a: /* Ctrl-z: undo */
 	case Kcmd+'z':	/* %Z: undo */
 	 	typecommit(t);
 		undo(t, nil, nil, TRUE, 0, nil, 0);
 		return;
+	case 0x19: /* Ctrl-y: redo */
 	case Kcmd+'Z':	/* %-shift-Z: redo */
 	 	typecommit(t);
 		undo(t, nil, nil, FALSE, 0, nil, 0);
 		return;
-
+	case 0x13: /* Ctrl-S: put file */
+	case Kcmd+'s':
+		typecommit(t);
+		put(&(t->w)->body, nil, nil, XXX, XXX, nil, 0);
+		return;
 	Tagdown:
 		/* expand tag to show all text */
 		if(!t->w->tagexpand){
@@ -796,6 +818,7 @@ texttype(Text *t, Rune r)
 	}
 	/* cut/paste must be done after the seq++/filemark */
 	switch(r){
+	case 0x18: /* Ctrl-X: cut */
 	case Kcmd+'x':	/* %X: cut */
 		typecommit(t);
 		if(t->what == Body){
@@ -806,6 +829,7 @@ texttype(Text *t, Rune r)
 		textshow(t, t->q0, t->q0, 1);
 		t->iq1 = t->q0;
 		return;
+	case 0x16: /* Ctrl-V: paste */
 	case Kcmd+'v':	/* %V: paste */
 		typecommit(t);
 		if(t->what == Body){
@@ -1661,4 +1685,4 @@ textreset(Text *t)
 	t->q1 = 0;
 	filereset(t->file);
 	bufreset(&t->file->b);
-}
+}
\ No newline at end of file
diff --git a/tmac/tmac.an b/tmac/tmac.an
index 28c6f6f1..f52afb4d 100644
--- a/tmac/tmac.an
+++ b/tmac/tmac.an
@@ -3,7 +3,7 @@
 .fp 3 B LuxiSans-Bold
 .fp 4 BI LuxiSans-BoldOblique
 .fp 5 L LuxiMono
-.ds 9 /usr/local/plan9
+.ds 9 /Users/ethan/plan9port
 .if n .uf 4
 .if n .bd 3
 .if n .rm bd
diff --git a/tmac/tmac.anhtml b/tmac/tmac.anhtml
index 5e3782b0..579a6792 100644
--- a/tmac/tmac.anhtml
+++ b/tmac/tmac.anhtml
@@ -1,4 +1,4 @@
-.so /usr/local/plan9/tmac/tmac.an
+.so /Users/ethan/plan9port/tmac/tmac.an
 .de }H
 ..
 .de }F
diff --git a/tmac/tmac.pm b/tmac/tmac.pm
index 1333a31c..19fa81a6 100644
--- a/tmac/tmac.pm
+++ b/tmac/tmac.pm
@@ -1,5 +1,5 @@
 .\" 10/22/92 activate next line before installing
-.pi /usr/local/plan9/bin/auxpm
+.pi /Users/ethan/plan9port/bin/auxpm
 .
 .		\" IZ - initialization
 .de IZ
@@ -963,4 +963,4 @@ Naperville, Illinois 60540
 ..
 .IZ
 .rm IZ
-.so /usr/local/plan9/tmac/tmac.srefs
+.so /Users/ethan/plan9port/tmac/tmac.srefs
-- 
cgit v1.2.3