diff --git a/src/cmd/acme/exec.c b/src/cmd/acme/exec.c index 1dd022889..184ee8833 100644 --- a/src/cmd/acme/exec.c +++ b/src/cmd/acme/exec.c @@ -83,6 +83,7 @@ static Rune LKill[] = { 'K', 'i', 'l', 'l', 0 }; static Rune LLoad[] = { 'L', 'o', 'a', 'd', 0 }; static Rune LLocal[] = { 'L', 'o', 'c', 'a', 'l', 0 }; static Rune LLook[] = { 'L', 'o', 'o', 'k', 0 }; +static Rune LKool[] = { 'K', 'o', 'o', 'l', 0 }; static Rune LNew[] = { 'N', 'e', 'w', 0 }; static Rune LNewcol[] = { 'N', 'e', 'w', 'c', 'o', 'l', 0 }; static Rune LPaste[] = { 'P', 'a', 's', 't', 'e', 0 }; @@ -113,7 +114,8 @@ Exectab exectab[] = { { LKill, xkill, FALSE, XXX, XXX }, { LLoad, dump, FALSE, FALSE, XXX }, { LLocal, local, FALSE, XXX, XXX }, - { LLook, look, FALSE, XXX, XXX }, + { LLook, look, FALSE, FALSE, XXX }, + { LKool, look, FALSE, TRUE, XXX }, { LNew, new, FALSE, XXX, XXX }, { LNewcol, newcol, FALSE, XXX, XXX }, { LPaste, paste, TRUE, TRUE, XXX }, @@ -1072,18 +1074,17 @@ paste(Text *et, Text *t, Text *_0, int selectall, int tobody, Rune *_1, int _2) } void -look(Text *et, Text *t, Text *argt, int _0, int _1, Rune *arg, int narg) +look(Text *et, Text *t, Text *argt, int rev, int _1, Rune *arg, int narg) { Rune *r; int n; - USED(_0); USED(_1); if(et && et->w){ t = &et->w->body; if(narg > 0){ - search(t, arg, narg); + rev ? rsearch(t, arg, narg) : search(t, arg, narg); return; } getarg(argt, FALSE, FALSE, &r, &n); @@ -1092,7 +1093,7 @@ look(Text *et, Text *t, Text *argt, int _0, int _1, Rune *arg, int narg) r = runemalloc(n); bufread(&t->file->b, t->q0, r, n); } - search(t, r, n); + rev ? rsearch(t, r, n) : search(t, r, n); free(r); } } diff --git a/src/cmd/acme/fns.h b/src/cmd/acme/fns.h index 969db417f..424fd2e5f 100644 --- a/src/cmd/acme/fns.h +++ b/src/cmd/acme/fns.h @@ -64,6 +64,7 @@ void fontx(Text*, Text*, Text*, int, int, Rune*, int); int isalnum(Rune); void execute(Text*, uint, uint, int, Text*); int search(Text*, Rune*, uint); +int rsearch(Text*, Rune*, uint); void look3(Text*, uint, uint, int); void editcmd(Text*, Rune*, uint); uint min(uint, uint); diff --git a/src/cmd/acme/look.c b/src/cmd/acme/look.c index a7172b505..fcbf7785d 100644 --- a/src/cmd/acme/look.c +++ b/src/cmd/acme/look.c @@ -302,12 +302,69 @@ plumbshow(Plumbmsg *m) xfidlog(w, "new"); } +int +rsearch(Text *ct, Rune *r, uint n) +{ + int q, nb; + int around; + Rune *s, *b; + + if(n==0 || n>ct->file->b.nc) + return FALSE; + if(2*n > RBUFSIZE){ + warning(nil, "string too long\n"); + return FALSE; + } + s = fbufalloc(); + b = s; + nb = 0; + b[nb] = 0; + around = 0; + q = ct->q0; + for(;;){ + if(q < 0){ + q = ct->file->b.nc; + around = 1; + b = s; + nb = 0; + b[nb] = 0; + } + /* reload if buffer covers neither string nor rest of file */ + if(nbfile->b, q-nb, s, nb); + b = s+nb; + *b = 0; + } + /* this runeeq is fishy but the null at b[nb] makes it safe */ + if(runeeq(b, n, r, n)==TRUE){ + if(ct->w){ + textshow(ct, q, q+n, 1); + winsettag(ct->w); + }else{ + ct->q0 = q; + ct->q1 = q+n; + } + seltext = ct; + fbuffree(s); + return TRUE; + } + --nb; + --b; + --q; + if(around && q<=ct->q0) + break; + } + fbuffree(s); + return FALSE; +} + int search(Text *ct, Rune *r, uint n) { - uint q, nb, maxn; + uint q, nb; int around; - Rune *s, *b, *c; + Rune *s, *b; if(n==0 || n>ct->file->b.nc) return FALSE; @@ -315,7 +372,6 @@ search(Text *ct, Rune *r, uint n) warning(nil, "string too long\n"); return FALSE; } - maxn = max(2*n, RBUFSIZE); s = fbufalloc(); b = s; nb = 0; @@ -329,25 +385,9 @@ search(Text *ct, Rune *r, uint n) nb = 0; b[nb] = 0; } - if(nb > 0){ - c = runestrchr(b, r[0]); - if(c == nil){ - q += nb; - nb = 0; - b[nb] = 0; - if(around && q>=ct->q1) - break; - continue; - } - q += (c-b); - nb -= (c-b); - b = c; - } /* reload if buffer covers neither string nor rest of file */ if(nbfile->b.nc-q){ - nb = ct->file->b.nc-q; - if(nb >= maxn) - nb = maxn-1; + nb = min(ct->file->b.nc-q, RBUFSIZE-1); bufread(&ct->file->b, q, s, nb); b = s; b[nb] = '\0';