ref: 342d92a22a97b02235abe83f4ec420c8aa6622ef
parent: fc299fdf45602f63cf16c939706abbfc276e69db
author: glenda <[email protected]>
date: Sun Sep 5 09:23:30 EDT 2021
implement rendering the buffer
--- a/linesel.c
+++ b/linesel.c
@@ -2,67 +2,17 @@
#include <libc.h>
#include <bio.h>
#include <draw.h>
-#include <thread.h>
+#include <event.h>
#include <keyboard.h>
-#include <mouse.h>
-int bflag;
+#define Ctl(c) ((c) - 64)
+
Image *fgcolor, *bgcolor;
-Font *font;
char **lines, **matches, *buffer, *selected;
usize nlines, nmatches;
-Rune kbdin[512];
-Keyboardctl *keyboard;
-Mousectl *mouse;
+Rune kbinput[512];
-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;
@@ -83,49 +33,100 @@
sysfatal("malloc: %r");
}
+#define PROMPT " > "
+
static void
-linesel(void)
+redraw(Image *screen)
{
- Rune r;
- Mouse m;
- Alt a[] = {
- [Ckeyboard] = {nil, &r, CHANRCV},
- [Cmouse] = {nil, &m, CHANRCV},
- [Cnum] = {nil, nil, CHANEND},
- };
+ short fh = font->height;
+ Point pt = screen->r.min;
+ usize i;
+ char buf[512];
- initgraphics(a);
- redraw();
+ draw(screen, screen->r, bgcolor, nil, ZP);
- for(;;){
- switch(alt(a)){
- case -1:
- sysfatal("watching channels: %r\n");
+ pt = addpt(pt, Pt(0, fh));
+ snprint(buf, sizeof buf, PROMPT"%S▏", kbinput);
+ string(screen, pt, fgcolor, ZP, font, buf);
+ pt = addpt(pt, Pt(stringwidth(font, PROMPT), fh));
- case Ckeyboard:
- switch(r){
- case '\n':
- return;
- }
+ for(i = 0; i < nmatches; i++){
+ if (pt.y > screen->r.max.y)
break;
-
- case Cmouse:
- break;
- }
+ string(screen, pt, fgcolor, ZP, font, matches[i]);
+ pt = addpt(pt, Pt(0, fh));
}
+}
+static void
+resetmatches(void)
+{
+ memmove(matches, lines, nlines * sizeof *lines);
+ nmatches = nlines;
}
static void
+kbadd(Rune r)
+{
+ usize len = runestrlen(kbinput);
+
+ if (len == sizeof kbinput / sizeof *kbinput)
+ return;
+ kbinput[len++] = r;
+ kbinput[len] = L'\0';
+}
+
+static void
+kbbackspace(void)
+{
+ usize len = runestrlen(kbinput);
+
+ if (len == 0)
+ return;
+ kbinput[len - 1] = L'\0';
+}
+
+static void
+kbdelword(void)
+{
+ usize len = runestrlen(kbinput);
+
+ if(len == 0)
+ return;
+ while(len > 0 && isspacerune(kbinput[len-1]))
+ len--;
+ while(len > 0 && !isspacerune(kbinput[len-1]))
+ len--;
+ kbinput[len] = L'\0';
+}
+
+static void
+kbclear(void)
+{
+ kbinput[0] = L'\0';
+}
+
+void
+eresized(int new)
+{
+ if(new && getwindow(display, Refnone) < 0)
+ sysfatal("resize failed: %r");
+ redraw(screen);
+}
+
+static void
usage(void)
{
print("usage: %s [-b] <choices\n", argv0);
- threadexitsall("usage");
+ exits("usage");
}
void
-threadmain(int argc, char **argv)
+main(int argc, char **argv)
{
+ Event e;
+ int bflag = 0;
+
ARGBEGIN{
case 'b':
bflag = 1;
@@ -137,7 +138,51 @@
readbuffer();
resetmatches();
selected = matches[0];
- linesel();
+
+ if(initdraw(nil, nil, "linesel") < 0)
+ sysfatal("initdraw: %r");
+ if(bflag){
+ fgcolor = display->white;
+ bgcolor = display->black;
+ }else{
+ fgcolor = display->black;
+ bgcolor = display->white;
+ }
+ einit(Emouse|Ekeyboard);
+ redraw(screen);
+
+ for(;;){
+ switch(event(&e)){
+ case -1:
+ sysfatal("watching channels: %r\n");
+
+ case Ekeyboard:
+ switch(e.kbdc){
+ case Kdel:
+ exits("interrupted with Del");
+ case '\n':
+ goto End;
+ case Kbs:
+ kbbackspace();
+ break;
+ case Ctl('W'):
+ kbdelword();
+ break;
+ case Ctl('U'):
+ kbclear();
+ break;
+ default:
+ kbadd(e.kbdc);
+ break;
+ }
+ redraw(screen);
+ break;
+
+ case Emouse:
+ break;
+ }
+ }
+End:
print("%s\n", selected);
- threadexitsall(nil);
+ exits(nil);
}