aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/acme/ecmd.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2017-11-02 11:58:07 -0400
committerRuss Cox <rsc@swtch.com>2017-11-02 12:01:14 -0400
commit3d6e5cb56a6249e7f3001091fe81c171cd501319 (patch)
treea59c7110ff800a3c83694928e4a16f089d19aa38 /src/cmd/acme/ecmd.c
parent805d91d359d67676a89edc9789ee8267bb7da6e1 (diff)
downloadplan9port-3d6e5cb56a6249e7f3001091fe81c171cd501319.tar.gz
plan9port-3d6e5cb56a6249e7f3001091fe81c171cd501319.tar.bz2
plan9port-3d6e5cb56a6249e7f3001091fe81c171cd501319.zip
acme: preserve window position and selection during Get
Before, executing Get in a file rewound the window offset and selection to the start of the file. After this CL, Get preserves the window offset and selection, where preserve is defined as "the same line number and rune offset within the line". So if the window started at line 10 before and the selection was line 13 chars 5-7, then that will still be true after Get, provided the new content is large enough. This should help the common situation of plumbing a compiler error, realizing the window is out of date, clicking Get, and then losing the positioning from the plumb operation.
Diffstat (limited to 'src/cmd/acme/ecmd.c')
-rw-r--r--src/cmd/acme/ecmd.c66
1 files changed, 49 insertions, 17 deletions
diff --git a/src/cmd/acme/ecmd.c b/src/cmd/acme/ecmd.c
index 9bedae4c..ef92e339 100644
--- a/src/cmd/acme/ecmd.c
+++ b/src/cmd/acme/ecmd.c
@@ -661,15 +661,16 @@ pipe_cmd(Text *t, Cmd *cp)
}
long
-nlcount(Text *t, long q0, long q1)
+nlcount(Text *t, long q0, long q1, long *pnr)
{
- long nl;
+ long nl, start;
Rune *buf;
int i, nbuf;
buf = fbufalloc();
nbuf = 0;
i = nl = 0;
+ start = q0;
while(q0 < q1){
if(i == nbuf){
nbuf = q1-q0;
@@ -678,24 +679,44 @@ nlcount(Text *t, long q0, long q1)
bufread(&t->file->b, q0, buf, nbuf);
i = 0;
}
- if(buf[i++] == '\n')
+ if(buf[i++] == '\n') {
+ start = q0+1;
nl++;
+ }
q0++;
}
fbuffree(buf);
+ if(pnr != nil)
+ *pnr = q0 - start;
return nl;
}
+enum {
+ PosnLine = 0,
+ PosnChars = 1,
+ PosnLineChars = 2,
+};
+
void
-printposn(Text *t, int charsonly)
+printposn(Text *t, int mode)
{
- long l1, l2;
+ long l1, l2, r1, r2;
if (t != nil && t->file != nil && t->file->name != nil)
warning(nil, "%.*S:", t->file->nname, t->file->name);
- if(!charsonly){
- l1 = 1+nlcount(t, 0, addr.r.q0);
- l2 = l1+nlcount(t, addr.r.q0, addr.r.q1);
+
+ switch(mode) {
+ case PosnChars:
+ warning(nil, "#%d", addr.r.q0);
+ if(addr.r.q1 != addr.r.q0)
+ warning(nil, ",#%d", addr.r.q1);
+ warning(nil, "\n");
+ return;
+
+ default:
+ case PosnLine:
+ l1 = 1+nlcount(t, 0, addr.r.q0, nil);
+ l2 = l1+nlcount(t, addr.r.q0, addr.r.q1, nil);
/* check if addr ends with '\n' */
if(addr.r.q1>0 && addr.r.q1>addr.r.q0 && textreadc(t, addr.r.q1-1)=='\n')
--l2;
@@ -704,32 +725,43 @@ printposn(Text *t, int charsonly)
warning(nil, ",%lud", l2);
warning(nil, "\n");
return;
+
+ case PosnLineChars:
+ l1 = 1+nlcount(t, 0, addr.r.q0, &r1);
+ l2 = l1+nlcount(t, addr.r.q0, addr.r.q1, &r2);
+ if(l2 == l1)
+ r2 += r1;
+ warning(nil, "%lud+#%d", l1, r1);
+ if(l2 != l1)
+ warning(nil, ",%lud+#%d", l2, r2);
+ warning(nil, "\n");
+ return;
}
- warning(nil, "#%d", addr.r.q0);
- if(addr.r.q1 != addr.r.q0)
- warning(nil, ",#%d", addr.r.q1);
- warning(nil, "\n");
}
int
eq_cmd(Text *t, Cmd *cp)
{
- int charsonly;
+ int mode;
switch(cp->u.text->n){
case 0:
- charsonly = FALSE;
+ mode = PosnLine;
break;
case 1:
if(cp->u.text->r[0] == '#'){
- charsonly = TRUE;
+ mode = PosnChars;
+ break;
+ }
+ if(cp->u.text->r[0] == '+'){
+ mode = PosnLineChars;
break;
}
default:
- SET(charsonly);
+ SET(mode);
editerror("newline expected");
}
- printposn(t, charsonly);
+ printposn(t, mode);
return TRUE;
}