24 draw(w->im, rectaddpt(Rect(0, 0, SCRBSIZ+1, h), w->inner.min), w->tab->cols[BORD], nil, ZP);
26 t1 = (w->toprune + w->fr.nchars) * h;
34 draw(w->im, rectaddpt(Rect(0, t0, SCRBSIZ, t1), w->inner.min), w->tab->cols[BACK], nil, ZP);
43 r = insetrect(w->inner, 1);
46 frinit(&w->fr, r, display->defaultfont, w->im, w->tab->cols);
47 frinsert(&w->fr, w->runes + w->toprune, w->runes + w->nrunes, 0);
51 cmdscroll(Win *w, int l)
58 for(r = w->toprune; r < w->nrunes && l != 0; r++)
59 if(w->runes[r] == '\n')
63 for(r = w->toprune; r > 0; r--)
64 if(w->runes[r] == '\n' && ++l == 0){
71 frdelete(&w->fr, 0, w->fr.nchars);
72 frinsert(&w->fr, w->runes + w->toprune, w->runes + w->nrunes, 0);
77 cmdclick(Win *w, Mousectl *mc)
79 if(mc->xy.x <= w->inner.min.x + SCRBSIZ){
87 cmdrmb(Win *w, Mousectl *mc)
89 if(mc->xy.x > w->inner.min.x + SCRBSIZ)
96 cmdinsert(Win *w, Rune *r, int nr, int rp)
101 for(nr = 0, s = r; *s++ != 0; nr++)
103 if(rp < 0 || rp > w->nrunes)
105 if(w->nrunes + nr > w->arunes){
106 w->runes = realloc(w->runes, w->arunes = w->arunes + (nr + RUNEBLK - 1) & ~(RUNEBLK - 1));
108 sysfatal("realloc: %r");
111 memmove(w->runes + rp, w->runes + rp + nr, (w->nrunes - rp) * sizeof(Rune));
112 memmove(w->runes + rp, r, nr * sizeof(Rune));
117 frinsert(&w->fr, w->runes + rp, w->runes + rp + nr, rp - w->toprune);
118 if(rp == w->nrunes - nr){
119 if(w->fr.lastlinefull)
129 cmddel(Win *w, int a, int b)
133 memmove(w->runes + a, w->runes + b, w->nrunes - b);
138 frdelete(&w->fr, a - w->toprune, b - w->toprune);
142 if(a <= w->opoint && w->opoint < b)
144 else if(w->opoint >= b)
149 setsel(Win *w, int p0, int p1)
151 frdrawsel(&w->fr, frptofchar(&w->fr, w->fr.p0), w->fr.p0, w->fr.p1, 0);
154 frdrawsel(&w->fr, frptofchar(&w->fr, p0), p0, p1, 1);
160 static char buf[4096];
164 q = w->runes + w->opoint;
166 while(q < w->runes + w->nrunes && p < buf + nelem(buf) + 1)
167 p += runetochar(p, q++);
169 w->opoint = w->nrunes;
174 cmdkey(Win *w, Rune r)
186 setsel(w, w->fr.p0 - 1, w->fr.p0 - 1);
189 if(w->toprune + w->fr.p1 == w->nrunes)
191 setsel(w, w->fr.p1 + 1, w->fr.p1 + 1);
194 if(w->fr.p0 < w->fr.p1)
195 cmddel(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1);
201 if(w->fr.p0 > 0 && w->toprune + w->fr.p0 != w->opoint)
202 cmddel(w, w->toprune + w->fr.p0 - 1, w->toprune + w->fr.p0);
205 cmdinsert(w, &r, 1, w->fr.p0 + w->toprune);
206 if(w->toprune + w->fr.p0 == w->nrunes)
210 cmdinsert(w, &r, 1, w->fr.p0 + w->toprune);
215 tosnarf(Win *w, int p0, int p1)
218 static char buf[512];
224 fd = open("/dev/snarf", OWRITE|OTRUNC);
226 cmdprint("tosnarf: %r");
230 ce = buf + sizeof(buf);
233 for(; rp < re; rp++){
235 write(fd, buf, c - buf);
238 c += runetochar(c, rp);
241 write(fd, buf, c - buf);
247 fromsnarf(Win *w, int p0)
254 fd = open("/dev/snarf", OREAD);
256 cmdprint("fromsnarf: %r");
262 buf = realloc(buf, nc + 4096);
263 rc = readn(fd, buf + nc, nc + 4096);
271 rbuf = emalloc(sizeof(Rune) * nc);
273 for(p = buf; p < buf + nc; r++)
274 p += chartorune(r, p);
275 end = p0 == w->nrunes;
276 cmdinsert(w, rbuf, r - rbuf, p0);
277 if(end && r > rbuf && r[-1] == '\n')
283 cmdmenu(Win *w, Mousectl *mc)
290 static char *ms[] = {
296 static Menu m = {ms};
298 switch(menuhit(2, mc, &m, nil)){
300 if(tosnarf(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1) >= 0)
301 cmddel(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1);
304 tosnarf(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1);
307 if(w->fr.p0 < w->fr.p1)
308 cmddel(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1);
309 fromsnarf(w, w->toprune + w->fr.p0);
315 cmdprint(char *fmt, ...)
321 r = runevsmprint(fmt, va);
324 cmdw->opoint += cmdinsert(cmdw, r, -1, cmdw->opoint);
338 [HIGH] DPalegreygreen