Commit Diff


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; i<t->file->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);
 			}