aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/9term/rcstart.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2010-09-03 10:21:16 -0400
committerRuss Cox <rsc@swtch.com>2010-09-03 10:21:16 -0400
commitef5c6a6edaf3dcf2cddd46841dc0dd8fce2bf967 (patch)
treee984e781353aa989307b53056ea664185317fc60 /src/cmd/9term/rcstart.c
parenta208917e7a935c019095acd1acd8165f08a54b7a (diff)
downloadplan9port-ef5c6a6edaf3dcf2cddd46841dc0dd8fce2bf967.tar.gz
plan9port-ef5c6a6edaf3dcf2cddd46841dc0dd8fce2bf967.tar.bz2
plan9port-ef5c6a6edaf3dcf2cddd46841dc0dd8fce2bf967.zip
9term, win: better echo cancellation
Also just drop \r from output. It's a losing battle to keep turning it off. R=rsc http://codereview.appspot.com/2128042
Diffstat (limited to 'src/cmd/9term/rcstart.c')
-rw-r--r--src/cmd/9term/rcstart.c72
1 files changed, 70 insertions, 2 deletions
diff --git a/src/cmd/9term/rcstart.c b/src/cmd/9term/rcstart.c
index 4d64349c..6b91c869 100644
--- a/src/cmd/9term/rcstart.c
+++ b/src/cmd/9term/rcstart.c
@@ -87,8 +87,6 @@ rcstart(int argc, char **argv, int *pfd, int *tfd)
dup(sfd, 2);
sys("stty tabs -onlcr icanon echo erase '^h' intr '^?'", 0);
sys("stty onocr", 1); /* not available on mac */
- if(noecho)
- sys("stty -echo", 0);
for(i=3; i<100; i++)
close(i);
signal(SIGINT, SIG_DFL);
@@ -111,3 +109,73 @@ rcstart(int argc, char **argv, int *pfd, int *tfd)
return pid;
}
+struct {
+ Lock l;
+ char buf[1<<20];
+ int r, w;
+} echo;
+
+void
+echoed(char *p, int n)
+{
+ lock(&echo.l);
+ if(echo.r > 0) {
+ memmove(echo.buf, echo.buf+echo.r, echo.w-echo.r);
+ echo.w -= echo.r;
+ echo.r = 0;
+ }
+ if(echo.w+n > sizeof echo.buf)
+ echo.r = echo.w = 0;
+ if(echo.w+n > sizeof echo.buf)
+ n = 0;
+ memmove(echo.buf+echo.w, p, n);
+ echo.w += n;
+ unlock(&echo.l);
+}
+
+int
+echocancel(char *p, int n)
+{
+ int i;
+
+ lock(&echo.l);
+ for(i=0; i<n; i++) {
+ if(echo.r < echo.w) {
+ if(echo.buf[echo.r] == p[i]) {
+ echo.r++;
+ continue;
+ }
+ if(echo.buf[echo.r] == '\n' && p[i] == '\r')
+ continue;
+ if(p[i] == 0x08) {
+ if(i+2 <= n && p[i+1] == ' ' && p[i+2] == 0x08)
+ i += 2;
+ continue;
+ }
+ }
+ echo.r = echo.w;
+ break;
+ }
+ unlock(&echo.l);
+ if(i > 0)
+ memmove(p, p+i, n-i);
+ return n-i;
+}
+
+int
+dropcrnl(char *p, int n)
+{
+ char *r, *w;
+
+ for(r=w=p; r<p+n; r++) {
+ if(r+1<p+n && *r == '\r' && *(r+1) == '\n')
+ continue;
+ if(*r == 0x08) {
+ if(r+2<=p+n && *(r+1) == ' ' && *(r+2) == 0x08)
+ r += 2;
+ continue;
+ }
+ *w++ = *r;
+ }
+ return w-p;
+}