commit 76864eb6cd2759efd687f392ada4f1facbf06250 from: Russ Cox date: Tue Aug 02 11:44:11 2011 UTC acme: scrolling fixes + new home/end Home and End previously navigated between two different window locations: the top and the bottom of the text. Now they include a third waypoint: the location where typing last happened. Thus, in a win window, typing ls -l scrolls to the beginning of the ls -l output. A second continues to the top of the file. Makes Send scroll always, along with writes by external programs to +Errors. R=r CC=mccoyst http://codereview.appspot.com/4830051 commit - 67afaf385afa5a2bcc6b7640d7cec6cd5d17863e commit + 76864eb6cd2759efd687f392ada4f1facbf06250 blob - 300ba65f831c92a578836605616f3a6878180213 blob + 0da2a128603b0b94afb52dddd7b66ccd226f470e --- src/cmd/acme/dat.h +++ src/cmd/acme/dat.h @@ -186,6 +186,7 @@ struct Text Row *row; Column *col; + uint iq1; /* last input position */ uint eq0; /* start of typing for ESC */ uint cq0; /* cache position */ int ncache; /* storage for insert */ blob - ad4da0016f3c9eb3b96d97dbe3fd8da677386e83 blob + 8262be4abf262bbfd3a2a9dcb3ed3f707ae8d2aa --- src/cmd/acme/exec.c +++ src/cmd/acme/exec.c @@ -960,8 +960,9 @@ sendx(Text *et, Text *t, Text *_0, int _1, int _2, Run if(textreadc(t, t->file->b.nc-1) != '\n'){ textinsert(t, t->file->b.nc, Lnl, 1, TRUE); textsetselect(t, t->file->b.nc, t->file->b.nc); - textshow(t, t->q1, t->q1, 1); } + t->iq1 = t->q1; + textshow(t, t->q1, t->q1, 1); } void blob - 7ea4131cab3fd48eebb063f04b6bb57752654e9d blob + ed0fc0c9513cf8d1b886f431896c2999ae07337c --- src/cmd/acme/text.c +++ src/cmd/acme/text.c @@ -379,6 +379,8 @@ textinsert(Text *t, uint q0, Rune *r, uint n, int tofi } } + if(q0 < t->iq1) + t->iq1 += n; if(q0 < t->q1) t->q1 += n; if(q0 < t->q0) @@ -472,6 +474,8 @@ textdelete(Text *t, uint q0, uint q1, int tofile) } } } + if(t->iq1 < t->q0) + t->iq1 -= min(n, t->iq1-q0); if(q0 < t->q0) t->q0 -= min(n, t->q0-q0); if(q0 < t->q1) @@ -714,11 +718,19 @@ texttype(Text *t, Rune r) return; case Khome: typecommit(t); - textshow(t, 0, 0, FALSE); + 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); - textshow(t, t->file->b.nc, t->file->b.nc, FALSE); + if(t->iq1 > t->org+t->fr.nchars) { + 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); @@ -771,6 +783,7 @@ texttype(Text *t, Rune r) } cut(t, t, nil, TRUE, TRUE, nil, 0); textshow(t, t->q0, t->q0, 1); + t->iq1 = t->q0; return; case Kcmd+'v': /* %V: paste */ typecommit(t); @@ -780,6 +793,7 @@ texttype(Text *t, Rune r) } paste(t, t, nil, TRUE, FALSE, nil, 0); textshow(t, t->q0, t->q1, 1); + t->iq1 = t->q1; return; } if(t->q1 > t->q0){ @@ -802,6 +816,7 @@ texttype(Text *t, Rune r) textsetselect(t, t->eq0, t->q0); if(t->ncache > 0) typecommit(t); + t->iq1 = t->q0; return; case 0x08: /* ^H: erase character */ case 0x15: /* ^U: erase line */ @@ -844,6 +859,7 @@ texttype(Text *t, Rune r) } for(i=0; ifile->ntext; i++) textfill(t->file->text[i]); + t->iq1 = t->q0; return; case '\n': if(t->w->autoindent){ @@ -895,6 +911,7 @@ texttype(Text *t, Rune r) textsetselect(t, t->q0+nr, t->q0+nr); if(r=='\n' && t->w!=nil) wincommit(t->w, t); + t->iq1 = t->q0; } void blob - 18b06dd1c55202ce4c89e06d2a90f64dcafcfdfc blob + a1cc38484bc8688b46f6f6e11a08c8bdbf81fc28 --- src/cmd/acme/xfid.c +++ src/cmd/acme/xfid.c @@ -393,6 +393,14 @@ xfidread(Xfid *x) respond(x, &fc, nil); } winunlock(w); +} + +static int +shouldscroll(Text *t, uint q0, int qid) +{ + if(qid == Qcons) + return TRUE; + return t->org <= q0 && q0 <= t->org+t->fr.nchars; } void @@ -510,7 +518,7 @@ xfidwrite(Xfid *x) if(tq1 >= q0) tq1 += nr; textsetselect(t, tq0, tq1); - if(t->org <= q0 && q0 <= t->org+t->fr.nchars) + if(shouldscroll(t, q0, qid)) textshow(t, q0+nr, q0+nr, 0); textscrdraw(t); winsettag(w); @@ -568,7 +576,7 @@ xfidwrite(Xfid *x) } q0 = textbsinsert(t, q0, r, nr, TRUE, &nr); textsetselect(t, t->q0, t->q1); /* insert could leave it somewhere else */ - if(qid!=QWwrsel && t->org <= q0 && q0 < t->org+t->fr.nchars) + if(qid!=QWwrsel && shouldscroll(t, q0, qid)) textshow(t, q0+nr, q0+nr, 1); textscrdraw(t); }