URI: 
       tacme: scrolling fixes + new home/end - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 76864eb6cd2759efd687f392ada4f1facbf06250
   DIR parent 67afaf385afa5a2bcc6b7640d7cec6cd5d17863e
  HTML Author: Russ Cox <rsc@swtch.com>
       Date:   Tue,  2 Aug 2011 07:44:11 -0400
       
       acme: scrolling fixes + new home/end
       
       Home and End previously navigated between
       ttwo different window locations: the top and
       tthe bottom of the text.  Now they include a
       tthird waypoint: the location where typing last
       happened.  Thus, in a win window, typing
               ls -l
               <home>
       scrolls to the beginning of the ls -l output.
       A second <home> 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
       
       Diffstat:
         M src/cmd/acme/dat.h                  |       1 +
         M src/cmd/acme/exec.c                 |       3 ++-
         M src/cmd/acme/text.c                 |      21 +++++++++++++++++++--
         M src/cmd/acme/xfid.c                 |      12 ++++++++++--
       
       4 files changed, 32 insertions(+), 5 deletions(-)
       ---
   DIR diff --git a/src/cmd/acme/dat.h b/src/cmd/acme/dat.h
       t@@ -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 */
   DIR diff --git a/src/cmd/acme/exec.c b/src/cmd/acme/exec.c
       t@@ -960,8 +960,9 @@ sendx(Text *et, Text *t, Text *_0, int _1, int _2, Rune *_3, int _4)
                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
   DIR diff --git a/src/cmd/acme/text.c b/src/cmd/acme/text.c
       t@@ -379,6 +379,8 @@ textinsert(Text *t, uint q0, Rune *r, uint n, int tofile)
                                }
                                                
                }
       +        if(q0 < t->iq1)
       +                t->iq1 += n;
                if(q0 < t->q1)
                        t->q1 += n;
                if(q0 < t->q0)
       t@@ -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)
       t@@ -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);
       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);
       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){
       t@@ -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 */
       t@@ -844,6 +859,7 @@ texttype(Text *t, Rune r)
                        }
                        for(i=0; i<t->file->ntext; i++)
                                textfill(t->file->text[i]);
       +                t->iq1 = t->q0;
                        return;
                case '\n':
                        if(t->w->autoindent){
       t@@ -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
   DIR diff --git a/src/cmd/acme/xfid.c b/src/cmd/acme/xfid.c
       t@@ -395,6 +395,14 @@ xfidread(Xfid *x)
                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
        xfidwrite(Xfid *x)
        {
       t@@ -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);
       t@@ -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);
                                }