|
|
@ -25,8 +25,8 @@ struct Item { |
|
|
|
|
|
|
|
static void appenditem(Item *item, Item **list, Item **last); |
|
|
|
static void calcoffsets(void); |
|
|
|
static char *cistrstr(const char *s, const char *sub); |
|
|
|
static void drawmenu(void); |
|
|
|
static char *fstrstr(const char *s, const char *sub); |
|
|
|
static void grabkeyboard(void); |
|
|
|
static void insert(const char *str, ssize_t n); |
|
|
|
static void keypress(XKeyEvent *ev); |
|
|
@ -60,6 +60,7 @@ static Item *prev, *curr, *next, *sel; |
|
|
|
static Window win; |
|
|
|
|
|
|
|
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; |
|
|
|
static char *(*fstrstr)(const char *, const char *) = strstr; |
|
|
|
|
|
|
|
int |
|
|
|
main(int argc, char *argv[]) { |
|
|
@ -76,8 +77,10 @@ main(int argc, char *argv[]) { |
|
|
|
topbar = False; |
|
|
|
else if(!strcmp(argv[i], "-f")) |
|
|
|
fast = True; |
|
|
|
else if(!strcmp(argv[i], "-i")) |
|
|
|
else if(!strcmp(argv[i], "-i")) { |
|
|
|
fstrncmp = strncasecmp; |
|
|
|
fstrstr = cistrstr; |
|
|
|
} |
|
|
|
else if(i+1 == argc) |
|
|
|
usage(); |
|
|
|
/* double flags */ |
|
|
@ -112,7 +115,7 @@ main(int argc, char *argv[]) { |
|
|
|
setup(); |
|
|
|
run(); |
|
|
|
|
|
|
|
return EXIT_FAILURE; /* should not reach */ |
|
|
|
return EXIT_FAILURE; /* unreachable */ |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
@ -121,6 +124,7 @@ appenditem(Item *item, Item **list, Item **last) { |
|
|
|
*list = item; |
|
|
|
else |
|
|
|
(*last)->right = item; |
|
|
|
|
|
|
|
item->left = *last; |
|
|
|
item->right = NULL; |
|
|
|
*last = item; |
|
|
@ -143,6 +147,16 @@ calcoffsets(void) { |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
char * |
|
|
|
cistrstr(const char *s, const char *sub) { |
|
|
|
size_t len; |
|
|
|
|
|
|
|
for(len = strlen(sub); *s; s++) |
|
|
|
if(!strncasecmp(s, sub, len)) |
|
|
|
return (char *)s; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
drawmenu(void) { |
|
|
|
int curpos; |
|
|
@ -188,16 +202,6 @@ drawmenu(void) { |
|
|
|
mapdc(dc, win, mw, mh); |
|
|
|
} |
|
|
|
|
|
|
|
char * |
|
|
|
fstrstr(const char *s, const char *sub) { |
|
|
|
size_t len; |
|
|
|
|
|
|
|
for(len = strlen(sub); *s; s++) |
|
|
|
if(!fstrncmp(s, sub, len)) |
|
|
|
return (char *)s; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
grabkeyboard(void) { |
|
|
|
int i; |
|
|
@ -233,58 +237,37 @@ keypress(XKeyEvent *ev) { |
|
|
|
|
|
|
|
XConvertCase(ksym, &lower, &upper); |
|
|
|
switch(lower) { |
|
|
|
default: |
|
|
|
return; |
|
|
|
case XK_a: |
|
|
|
ksym = XK_Home; |
|
|
|
break; |
|
|
|
case XK_b: |
|
|
|
ksym = XK_Left; |
|
|
|
break; |
|
|
|
case XK_c: |
|
|
|
ksym = XK_Escape; |
|
|
|
break; |
|
|
|
case XK_d: |
|
|
|
ksym = XK_Delete; |
|
|
|
break; |
|
|
|
case XK_e: |
|
|
|
ksym = XK_End; |
|
|
|
break; |
|
|
|
case XK_f: |
|
|
|
ksym = XK_Right; |
|
|
|
break; |
|
|
|
case XK_h: |
|
|
|
ksym = XK_BackSpace; |
|
|
|
break; |
|
|
|
case XK_i: |
|
|
|
ksym = XK_Tab; |
|
|
|
break; |
|
|
|
case XK_j: |
|
|
|
case XK_m: |
|
|
|
ksym = XK_Return; |
|
|
|
break; |
|
|
|
case XK_k: /* delete right */ |
|
|
|
case XK_a: ksym = XK_Home; break; |
|
|
|
case XK_b: ksym = XK_Left; break; |
|
|
|
case XK_c: ksym = XK_Escape; break; |
|
|
|
case XK_d: ksym = XK_Delete; break; |
|
|
|
case XK_e: ksym = XK_End; break; |
|
|
|
case XK_f: ksym = XK_Right; break; |
|
|
|
case XK_h: ksym = XK_BackSpace; break; |
|
|
|
case XK_i: ksym = XK_Tab; break; |
|
|
|
case XK_j: ksym = XK_Return; break; |
|
|
|
case XK_m: ksym = XK_Return; break; |
|
|
|
case XK_n: ksym = XK_Up; break; |
|
|
|
case XK_p: ksym = XK_Down; break; |
|
|
|
|
|
|
|
case XK_k: /* delete right */ |
|
|
|
text[cursor] = '\0'; |
|
|
|
match(False); |
|
|
|
break; |
|
|
|
case XK_n: |
|
|
|
ksym = XK_Next; |
|
|
|
break; |
|
|
|
case XK_p: |
|
|
|
ksym = XK_Prior; |
|
|
|
break; |
|
|
|
case XK_u: /* delete left */ |
|
|
|
case XK_u: /* delete left */ |
|
|
|
insert(NULL, 0 - cursor); |
|
|
|
break; |
|
|
|
case XK_w: /* delete word */ |
|
|
|
case XK_w: /* delete word */ |
|
|
|
while(cursor > 0 && text[nextrune(-1)] == ' ') |
|
|
|
insert(NULL, nextrune(-1) - cursor); |
|
|
|
while(cursor > 0 && text[nextrune(-1)] != ' ') |
|
|
|
insert(NULL, nextrune(-1) - cursor); |
|
|
|
break; |
|
|
|
case XK_y: /* paste selection */ |
|
|
|
case XK_y: /* paste selection */ |
|
|
|
XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); |
|
|
|
return; |
|
|
|
default: |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
switch(ksym) { |
|
|
@ -297,8 +280,9 @@ keypress(XKeyEvent *ev) { |
|
|
|
return; |
|
|
|
cursor = nextrune(+1); |
|
|
|
case XK_BackSpace: |
|
|
|
if(cursor > 0) |
|
|
|
insert(NULL, nextrune(-1) - cursor); |
|
|
|
if(cursor == 0) |
|
|
|
return; |
|
|
|
insert(NULL, nextrune(-1) - cursor); |
|
|
|
break; |
|
|
|
case XK_End: |
|
|
|
if(text[cursor] != '\0') { |
|
|
@ -351,7 +335,7 @@ keypress(XKeyEvent *ev) { |
|
|
|
break; |
|
|
|
case XK_Return: |
|
|
|
case XK_KP_Enter: |
|
|
|
fputs((sel && !(ev->state & ShiftMask)) ? sel->text : text, stdout); |
|
|
|
puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); |
|
|
|
exit(EXIT_SUCCESS); |
|
|
|
case XK_Right: |
|
|
|
if(text[cursor] != '\0') { |
|
|
@ -468,7 +452,7 @@ run(void) { |
|
|
|
switch(ev.type) { |
|
|
|
case Expose: |
|
|
|
if(ev.xexpose.count == 0) |
|
|
|
drawmenu(); |
|
|
|
mapdc(dc, win, mw, mh); |
|
|
|
break; |
|
|
|
case KeyPress: |
|
|
|
keypress(&ev.xkey); |
|
|
|