aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/acme
diff options
context:
space:
mode:
authorPetter Rodhelind <petter.rodhelind@gmail.com>2017-11-06 15:19:40 +0100
committerPetter Rodhelind <petter.rodhelind@gmail.com>2017-11-06 15:19:40 +0100
commita8c75a106f5d6e283c6b23e2592207ee5d5bce29 (patch)
tree6869c3e18b920b2b71e0ad02430c0d0c50cac741 /src/cmd/acme
parentf25f90ea3332df18129558fd246f7b5d4c80b4d8 (diff)
parent3d6e5cb56a6249e7f3001091fe81c171cd501319 (diff)
downloadplan9port-a8c75a106f5d6e283c6b23e2592207ee5d5bce29.tar.gz
plan9port-a8c75a106f5d6e283c6b23e2592207ee5d5bce29.tar.bz2
plan9port-a8c75a106f5d6e283c6b23e2592207ee5d5bce29.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'src/cmd/acme')
-rw-r--r--src/cmd/acme/addr.c21
-rw-r--r--src/cmd/acme/ecmd.c66
-rw-r--r--src/cmd/acme/exec.c30
-rw-r--r--src/cmd/acme/fns.h2
-rw-r--r--src/cmd/acme/text.c2
5 files changed, 103 insertions, 18 deletions
diff --git a/src/cmd/acme/addr.c b/src/cmd/acme/addr.c
index 861e5e01..2ccae960 100644
--- a/src/cmd/acme/addr.c
+++ b/src/cmd/acme/addr.c
@@ -49,6 +49,27 @@ isregexc(int r)
return FALSE;
}
+// nlcounttopos starts at q0 and advances nl lines,
+// being careful not to walk past the end of the text,
+// and then nr chars, being careful not to walk past
+// the end of the current line.
+// It returns the final position.
+long
+nlcounttopos(Text *t, long q0, long nl, long nr)
+{
+ while(nl > 0 && q0 < t->file->b.nc) {
+ if(textreadc(t, q0++) == '\n')
+ nl--;
+ }
+ if(nl > 0)
+ return q0;
+ while(nr > 0 && q0 < t->file->b.nc && textreadc(t, q0) != '\n') {
+ q0++;
+ nr--;
+ }
+ return q0;
+}
+
Range
number(uint showerr, Text *t, Range r, int line, int dir, int size, int *evalp)
{
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;
}
diff --git a/src/cmd/acme/exec.c b/src/cmd/acme/exec.c
index 3a568f8a..fbc249d8 100644
--- a/src/cmd/acme/exec.c
+++ b/src/cmd/acme/exec.c
@@ -576,15 +576,27 @@ zeroxx(Text *et, Text *t, Text *_1, int _2, int _3, Rune *_4, int _5)
winunlock(t->w);
}
+typedef struct TextAddr TextAddr;
+struct TextAddr {
+ long lorigin; // line+rune for origin
+ long rorigin;
+ long lq0; // line+rune for q0
+ long rq0;
+ long lq1; // line+rune for q1
+ long rq1;
+};
+
void
get(Text *et, Text *t, Text *argt, int flag1, int _0, Rune *arg, int narg)
{
char *name;
Rune *r;
int i, n, dirty, samename, isdir;
+ TextAddr *addr, *a;
Window *w;
Text *u;
Dir *d;
+ long q0, q1;
USED(_0);
@@ -609,6 +621,14 @@ get(Text *et, Text *t, Text *argt, int flag1, int _0, Rune *arg, int narg)
return;
}
}
+ addr = emalloc((t->file->ntext)*sizeof(TextAddr));
+ for(i=0; i<t->file->ntext; i++) {
+ a = &addr[i];
+ u = t->file->text[i];
+ a->lorigin = nlcount(u, 0, u->org, &a->rorigin);
+ a->lq0 = nlcount(u, 0, u->q0, &a->rq0);
+ a->lq1 = nlcount(u, u->q0, u->q1, &a->rq1);
+ }
r = bytetorune(name, &n);
for(i=0; i<t->file->ntext; i++){
u = t->file->text[i];
@@ -634,8 +654,18 @@ get(Text *et, Text *t, Text *argt, int flag1, int _0, Rune *arg, int narg)
for(i=0; i<t->file->ntext; i++){
u = t->file->text[i];
textsetselect(&u->w->tag, u->w->tag.file->b.nc, u->w->tag.file->b.nc);
+ if(samename) {
+ a = &addr[i];
+ // warning(nil, "%d %d %d %d %d %d\n", a->lorigin, a->rorigin, a->lq0, a->rq0, a->lq1, a->rq1);
+ q0 = nlcounttopos(u, 0, a->lq0, a->rq0);
+ q1 = nlcounttopos(u, q0, a->lq1, a->rq1);
+ textsetselect(u, q0, q1);
+ q0 = nlcounttopos(u, 0, a->lorigin, a->rorigin);
+ textsetorigin(u, q0, FALSE);
+ }
textscrdraw(u);
}
+ free(addr);
xfidlog(w, "get");
}
diff --git a/src/cmd/acme/fns.h b/src/cmd/acme/fns.h
index 1cd35257..8dc02378 100644
--- a/src/cmd/acme/fns.h
+++ b/src/cmd/acme/fns.h
@@ -93,6 +93,8 @@ Rune* findbl(Rune*, int, int*);
char* edittext(Window*, int, Rune*, int);
void flushwarnings(void);
void startplumbing(void);
+long nlcount(Text*, long, long, long*);
+long nlcounttopos(Text*, long, long, long);
Runestr runestr(Rune*, uint);
Range range(int, int);
diff --git a/src/cmd/acme/text.c b/src/cmd/acme/text.c
index e47c97d2..5b87f820 100644
--- a/src/cmd/acme/text.c
+++ b/src/cmd/acme/text.c
@@ -1677,7 +1677,7 @@ textsetorigin(Text *t, uint org, int exact)
Rune *r;
uint n;
- if(org>0 && !exact){
+ if(org>0 && !exact && textreadc(t, org-1) != '\n'){
/* org is an estimate of the char posn; find a newline */
/* don't try harder than 256 chars */
for(i=0; i<256 && org<t->file->b.nc; i++){