14 static Point prevmouse;
15 static Window *mousew;
18 cvttorunes(char *p, int n, Rune *r, int *nb, int *nr, int *nulls)
25 * Always guaranteed that n bytes may be interpreted
26 * without worrying about partial runes. This may mean
27 * reading up to UTFmax-1 more bytes than n; the caller
28 * knows this. If n is a firm limit, the caller should
38 w = chartorune(s, (char*)q);
53 fprint(2, "acme: %s: %r\n", s);
58 errorwin1(Rune *dir, int ndir, Rune **incl, int nincl)
63 static Rune Lpluserrors[] = { '+', 'E', 'r', 'r', 'o', 'r', 's', 0 };
65 r = runemalloc(ndir+7);
66 if(n = ndir) /* assign = */
67 runemove(r, dir, ndir);
68 runemove(r+n, Lpluserrors, 7);
73 if(rowadd(&row, nil, -1) == nil)
74 error("can't create column to make error window");
75 w = coladd(row.col[row.ncol-1], nil, nil, -1);
80 for(i=nincl; --i>=0; ){
81 n = runestrlen(incl[i]);
83 runemove(r, incl[i], n);
89 /* make new window, if necessary; return with it locked */
91 errorwin(Mntdir *md, int owner, Window *e)
97 w = errorwin1(nil, 0, nil, 0);
99 w = errorwin1(md->dir, md->ndir, md->incl, md->nincl);
104 /* window was deleted too fast */
112 printwarning(Window *ew, Mntdir *md, Rune *r)
119 error("runevsmprint failed");
122 if(row.ncol == 0){ /* really early error */
123 rowinit(&row, screen->clipr);
124 rowadd(&row, nil, -1);
125 rowadd(&row, nil, -1);
127 error("initializing columns in warning()");
130 w = errorwin(md, 'E', ew);
136 q0 = textbsinsert(t, t->file->b.nc, r, nr, TRUE, &nr);
137 textshow(t, q0, q0+nr, 1);
148 warning(Mntdir *md, char *s, ...)
154 r = runevsmprint(s, arg);
156 printwarning(nil, md, r);
160 * Warningew is like warning but avoids locking the error window
161 * if it's already locked by checking that ew!=error window.
164 warningew(Window *ew, Mntdir *md, char *s, ...)
170 r = runevsmprint(s, arg);
172 printwarning(ew, md, r);
176 runeeq(Rune *s1, uint n1, Rune *s2, uint n2)
180 return memcmp(s1, s2, n1*sizeof(Rune)) == 0;
200 runetobyte(Rune *r, int n)
206 s = emalloc(n*UTFmax+1);
207 setmalloctag(s, getcallerpc(&r));
208 snprint(s, n*UTFmax+1, "%.*S", n, r);
213 bytetorune(char *s, int *ip)
219 r = runemalloc(nb+1);
220 cvttorunes(s, nb, r, &nb, &nr, nil);
230 * Hard to get absolutely right. Use what we know about ASCII
231 * and assume anything above the Latin control characters is
232 * potentially an alphanumeric.
236 if(0x7F<=c && c<=0xA0)
238 if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))
244 rgetc(void *v, uint n)
246 return ((Rune*)v)[n];
250 tgetc(void *a, uint n)
255 if(n >= t->file->b.nc)
257 return textreadc(t, n);
261 skipbl(Rune *r, int n, int *np)
263 while(n>0 && *r==' ' || *r=='\t' || *r=='\n'){
272 findbl(Rune *r, int n, int *np)
274 while(n>0 && *r!=' ' && *r!='\t' && *r!='\n'){
285 prevmouse = mouse->xy;
290 restoremouse(Window *w)
292 if(mousew!=nil && mousew==w)
293 moveto(mousectl, prevmouse);
310 error("strdup failed");
311 setmalloctag(t, getcallerpc(&s));
322 fprint(2, "allocating %d from %lux: %r\n", n, getcallerpc(&n));
324 error("malloc failed");
326 setmalloctag(p, getcallerpc(&n));
332 erealloc(void *p, uint n)
336 fprint(2, "reallocating %d: %r\n", n);
337 error("realloc failed");
339 setmalloctag(p, getcallerpc(&n));
347 makenewwindow(Text *t)
350 Window *w, *bigw, *emptyw;
356 else if(seltext && seltext->col)
361 if(row.ncol==0 && rowadd(&row, nil, -1)==nil)
362 error("can't make column");
363 c = row.col[row.ncol-1];
366 if(t==nil || t->w==nil || c->nw==0)
367 return coladd(c, nil, nil, -1);
369 /* find biggest window and biggest blank spot */
372 for(i=1; i<c->nw; i++){
374 /* use >= to choose one near bottom of screen */
375 if(w->body.fr.maxlines >= bigw->body.fr.maxlines)
377 if(w->body.fr.maxlines-w->body.fr.nlines >= emptyw->body.fr.maxlines-emptyw->body.fr.nlines)
380 emptyb = &emptyw->body;
381 el = emptyb->fr.maxlines-emptyb->fr.nlines;
382 /* if empty space is big, use it */
383 if(el>15 || (el>3 && el>(bigw->body.fr.maxlines-1)/2))
384 y = emptyb->fr.r.min.y+emptyb->fr.nlines*font->height;
386 /* if this window is in column and isn't much smaller, split it */
387 if(t->col==c && Dy(t->w->r)>2*Dy(bigw->r)/3)
389 y = (bigw->r.min.y + bigw->r.max.y)/2;
391 w = coladd(c, nil, nil, y);
392 if(w->body.fr.maxlines < 2)
393 colgrow(w->col, w, 1);