diff options
author | Petter Rodhelind <petter.rodhelind@gmail.com> | 2017-11-06 15:19:40 +0100 |
---|---|---|
committer | Petter Rodhelind <petter.rodhelind@gmail.com> | 2017-11-06 15:19:40 +0100 |
commit | a8c75a106f5d6e283c6b23e2592207ee5d5bce29 (patch) | |
tree | 6869c3e18b920b2b71e0ad02430c0d0c50cac741 /src/cmd/acme | |
parent | f25f90ea3332df18129558fd246f7b5d4c80b4d8 (diff) | |
parent | 3d6e5cb56a6249e7f3001091fe81c171cd501319 (diff) | |
download | plan9port-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.c | 21 | ||||
-rw-r--r-- | src/cmd/acme/ecmd.c | 66 | ||||
-rw-r--r-- | src/cmd/acme/exec.c | 30 | ||||
-rw-r--r-- | src/cmd/acme/fns.h | 2 | ||||
-rw-r--r-- | src/cmd/acme/text.c | 2 |
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++){ |