diff options
| author | Anselm R Garbe <garbeam@gmail.com> | 2008-03-18 16:52:51 +0000 |
|---|---|---|
| committer | Anselm R Garbe <garbeam@gmail.com> | 2008-03-18 16:52:51 +0000 |
| commit | 745c46d8fa810bbf45ef16e79a0f84c787f1a670 (patch) | |
| tree | 1d87a0fd83e226d603e592e69a6f8625d287c288 | |
| parent | d058e835708d530d74f7e82d643f48d4ad62e3a4 (diff) | |
fixed match() to prefer prefix-matches to strstr-matches in the match list, extended the -y handling, next version is 3.6
| -rw-r--r-- | config.mk | 2 | ||||
| -rw-r--r-- | dmenu.1 | 4 | ||||
| -rw-r--r-- | dmenu.c | 70 |
3 files changed, 46 insertions, 30 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | # dmenu version | 1 | # dmenu version |
| 2 | VERSION = 3.5 | 2 | VERSION = 3.6 |
| 3 | 3 | ||
| 4 | # Customize below to fit your system | 4 | # Customize below to fit your system |
| 5 | 5 | ||
| @@ -26,7 +26,9 @@ efficiently. | |||
| 26 | defines the x coordinate dmenu appears at (0 by default). | 26 | defines the x coordinate dmenu appears at (0 by default). |
| 27 | .TP | 27 | .TP |
| 28 | .B \-y | 28 | .B \-y |
| 29 | defines the y coordinate dmenu appears at (0 by default). | 29 | defines the y coordinate dmenu appears at (0 by default). If it is negative, |
| 30 | dmenu will appear with the bottom at the given positive coordinate. It it is | ||
| 31 | -0, dmenu appears at the screen bottom. | ||
| 30 | .TP | 32 | .TP |
| 31 | .B \-w | 33 | .B \-w |
| 32 | defines the width of the dmenu window (screen width by default). | 34 | defines the width of the dmenu window (screen width by default). |
| @@ -34,14 +34,16 @@ typedef struct { | |||
| 34 | 34 | ||
| 35 | typedef struct Item Item; | 35 | typedef struct Item Item; |
| 36 | struct Item { | 36 | struct Item { |
| 37 | char *text; | ||
| 38 | Bool matched; | ||
| 37 | Item *next; /* traverses all items */ | 39 | Item *next; /* traverses all items */ |
| 38 | Item *left, *right; /* traverses items matching current search pattern */ | 40 | Item *left, *right; /* traverses items matching current search pattern */ |
| 39 | char *text; | ||
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 42 | /* forward declarations */ | 43 | /* forward declarations */ |
| 43 | Item *appenditem(Item *i, Item *last); | 44 | Item *appenditem(Item *i, Item *last); |
| 44 | void calcoffsets(void); | 45 | void calcoffsets(void); |
| 46 | char *cistrstr(const char *s, const char *sub); | ||
| 45 | void cleanup(void); | 47 | void cleanup(void); |
| 46 | void drawmenu(void); | 48 | void drawmenu(void); |
| 47 | void drawtext(const char *text, unsigned long col[ColLast]); | 49 | void drawtext(const char *text, unsigned long col[ColLast]); |
| @@ -56,7 +58,6 @@ void match(char *pattern); | |||
| 56 | void readstdin(void); | 58 | void readstdin(void); |
| 57 | void run(void); | 59 | void run(void); |
| 58 | void setup(int x, int y, int w); | 60 | void setup(int x, int y, int w); |
| 59 | char *cistrstr(const char *s, const char *sub); | ||
| 60 | unsigned int textnw(const char *text, unsigned int len); | 61 | unsigned int textnw(const char *text, unsigned int len); |
| 61 | unsigned int textw(const char *text); | 62 | unsigned int textw(const char *text); |
| 62 | 63 | ||
| @@ -130,6 +131,29 @@ calcoffsets(void) { | |||
| 130 | } | 131 | } |
| 131 | } | 132 | } |
| 132 | 133 | ||
| 134 | char * | ||
| 135 | cistrstr(const char *s, const char *sub) { | ||
| 136 | int c, csub; | ||
| 137 | unsigned int len; | ||
| 138 | |||
| 139 | if(!sub) | ||
| 140 | return (char *)s; | ||
| 141 | if((c = *sub++) != 0) { | ||
| 142 | c = tolower(c); | ||
| 143 | len = strlen(sub); | ||
| 144 | do { | ||
| 145 | do { | ||
| 146 | if((csub = *s++) == 0) | ||
| 147 | return (NULL); | ||
| 148 | } | ||
| 149 | while(tolower(csub) != c); | ||
| 150 | } | ||
| 151 | while(strncasecmp(s, sub, len) != 0); | ||
| 152 | s--; | ||
| 153 | } | ||
| 154 | return (char *)s; | ||
| 155 | } | ||
| 156 | |||
| 133 | void | 157 | void |
| 134 | cleanup(void) { | 158 | cleanup(void) { |
| 135 | Item *itm; | 159 | Item *itm; |
| @@ -505,8 +529,10 @@ match(char *pattern) { | |||
| 505 | item = j = NULL; | 529 | item = j = NULL; |
| 506 | nitem = 0; | 530 | nitem = 0; |
| 507 | for(i = allitems; i; i = i->next) | 531 | for(i = allitems; i; i = i->next) |
| 508 | if(!fstrncmp(pattern, i->text, plen) | 532 | if((i->matched = !fstrncmp(pattern, i->text, plen))) |
| 509 | || fstrstr(i->text, pattern)) | 533 | j = appenditem(i, j); |
| 534 | for(i = allitems; i; i = i->next) | ||
| 535 | if(!i->matched && fstrstr(i->text, pattern)) | ||
| 510 | j = appenditem(i, j); | 536 | j = appenditem(i, j); |
| 511 | curr = prev = next = sel = item; | 537 | curr = prev = next = sel = item; |
| 512 | calcoffsets(); | 538 | calcoffsets(); |
| @@ -587,6 +613,12 @@ setup(int x, int y, int w) { | |||
| 587 | wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; | 613 | wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; |
| 588 | mw = w ? w : DisplayWidth(dpy, screen); | 614 | mw = w ? w : DisplayWidth(dpy, screen); |
| 589 | mh = dc.font.height + 2; | 615 | mh = dc.font.height + 2; |
| 616 | if(y < 0) { | ||
| 617 | if(y == (int)(unsigned int)-1) | ||
| 618 | y = DisplayHeight(dpy, screen) - mh; | ||
| 619 | else | ||
| 620 | y = (-1 * y) - mh; | ||
| 621 | } | ||
| 590 | win = XCreateWindow(dpy, root, x, y, mw, mh, 0, | 622 | win = XCreateWindow(dpy, root, x, y, mw, mh, 0, |
| 591 | DefaultDepth(dpy, screen), CopyFromParent, | 623 | DefaultDepth(dpy, screen), CopyFromParent, |
| 592 | DefaultVisual(dpy, screen), | 624 | DefaultVisual(dpy, screen), |
| @@ -611,29 +643,6 @@ setup(int x, int y, int w) { | |||
| 611 | XMapRaised(dpy, win); | 643 | XMapRaised(dpy, win); |
| 612 | } | 644 | } |
| 613 | 645 | ||
| 614 | char * | ||
| 615 | cistrstr(const char *s, const char *sub) { | ||
| 616 | int c, csub; | ||
| 617 | unsigned int len; | ||
| 618 | |||
| 619 | if(!sub) | ||
| 620 | return (char *)s; | ||
| 621 | if((c = *sub++) != 0) { | ||
| 622 | c = tolower(c); | ||
| 623 | len = strlen(sub); | ||
| 624 | do { | ||
| 625 | do { | ||
| 626 | if((csub = *s++) == 0) | ||
| 627 | return (NULL); | ||
| 628 | } | ||
| 629 | while(tolower(csub) != c); | ||
| 630 | } | ||
| 631 | while(strncasecmp(s, sub, len) != 0); | ||
| 632 | s--; | ||
| 633 | } | ||
| 634 | return (char *)s; | ||
| 635 | } | ||
| 636 | |||
| 637 | unsigned int | 646 | unsigned int |
| 638 | textnw(const char *text, unsigned int len) { | 647 | textnw(const char *text, unsigned int len) { |
| 639 | XRectangle r; | 648 | XRectangle r; |
| @@ -683,7 +692,12 @@ main(int argc, char *argv[]) { | |||
| 683 | if(++i < argc) x = atoi(argv[i]); | 692 | if(++i < argc) x = atoi(argv[i]); |
| 684 | } | 693 | } |
| 685 | else if(!strcmp(argv[i], "-y")) { | 694 | else if(!strcmp(argv[i], "-y")) { |
| 686 | if(++i < argc) y = atoi(argv[i]); | 695 | if(++i < argc) { |
| 696 | if(!strcmp(argv[i], "-0")) | ||
| 697 | y = (int)(unsigned int)-1; | ||
| 698 | else | ||
| 699 | y = atoi(argv[i]); | ||
| 700 | } | ||
| 687 | } | 701 | } |
| 688 | else if(!strcmp(argv[i], "-w")) { | 702 | else if(!strcmp(argv[i], "-w")) { |
| 689 | if(++i < argc) w = atoi(argv[i]); | 703 | if(++i < argc) w = atoi(argv[i]); |
