ref: fc299fdf45602f63cf16c939706abbfc276e69db
dir: /linesel.c/
#include <u.h> #include <libc.h> #include <bio.h> #include <draw.h> #include <thread.h> #include <keyboard.h> #include <mouse.h> int bflag; Image *fgcolor, *bgcolor; Font *font; char **lines, **matches, *buffer, *selected; usize nlines, nmatches; Rune kbdin[512]; Keyboardctl *keyboard; Mousectl *mouse; enum { Ckeyboard, Cmouse, Cresize, Cnum }; static void redraw(void) { draw(screen, screen->r, bgcolor, nil, ZP); string(screen, Pt(10, 10), fgcolor, ZP, font, "test"); flushimage(display, 1); } static void resetmatches(void) { memmove(matches, lines, nlines * sizeof *lines); nmatches = nlines; } static void initgraphics(Alt *a) { if(initdraw(nil, nil, "linesel") == -1) sysfatal("initdraw: %r"); if(bflag){ fgcolor = display->white; bgcolor = display->black; }else{ fgcolor = display->black; bgcolor = display->white; } font = display->defaultfont; if((keyboard = initkeyboard(nil)) == nil) sysfatal("initkeyboard: %r"); if((mouse = initmouse(nil, screen)) == nil) sysfatal("initmouse: %r"); a[Ckeyboard].c = keyboard->c; a[Cmouse].c = mouse->c; } static void readbuffer(void) { Biobuf *bp; char *line, *s; if((bp = Bfdopen(0, OREAD)) == nil) sysfatal("setting buffering on fd0: %r"); if ((buffer = Brdstr(bp, '\0', 1)) == nil) sysfatal("reading input lines: %r"); for(line = s = buffer; s = strchr(s, '\n'); line = ++s){ *s = '\0'; if((lines = realloc(lines, ++nlines * sizeof *lines)) == nil) sysfatal("malloc: %r"); lines[nlines-1] = line; } if((matches = malloc(nlines * sizeof *lines)) == nil) sysfatal("malloc: %r"); } static void linesel(void) { Rune r; Mouse m; Alt a[] = { [Ckeyboard] = {nil, &r, CHANRCV}, [Cmouse] = {nil, &m, CHANRCV}, [Cnum] = {nil, nil, CHANEND}, }; initgraphics(a); redraw(); for(;;){ switch(alt(a)){ case -1: sysfatal("watching channels: %r\n"); case Ckeyboard: switch(r){ case '\n': return; } break; case Cmouse: break; } } } static void usage(void) { print("usage: %s [-b] <choices\n", argv0); threadexitsall("usage"); } void threadmain(int argc, char **argv) { ARGBEGIN{ case 'b': bflag = 1; break; default: usage(); }ARGEND; readbuffer(); resetmatches(); selected = matches[0]; linesel(); print("%s\n", selected); threadexitsall(nil); }