Return to repo list

suckless-gf-dmenu

Gentoo-friendly patches for Suckless's dmenu.
Return to HMagellan.com

navhistorysearch-nodoc.patch (5019B)


      1 diff --git a/dmenu.c b/dmenu.c
      2 index 65f25ce..4242eb4 100644
      3 --- a/dmenu.c
      4 +++ b/dmenu.c
      5 @@ -40,7 +40,7 @@ static int bh, mw, mh;
      6  static int inputw = 0, promptw;
      7  static int lrpad; /* sum of left and right padding */
      8  static size_t cursor;
      9 -static struct item *items = NULL;
     10 +static struct item *items = NULL, *backup_items;
     11  static struct item *matches, *matchend;
     12  static struct item *prev, *curr, *next, *sel;
     13  static int mon = -1, screen;
     14 @@ -53,6 +53,10 @@ static XIC xic;
     15  static Drw *drw;
     16  static Clr *scheme[SchemeLast];
     17 
     18 +static char *histfile;
     19 +static char **history;
     20 +static size_t histsz, histpos;
     21 +
     22  #include "config.h"
     23 
     24  static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
     25 @@ -304,11 +308,134 @@ movewordedge(int dir)
     26  	}
     27  }
     28 
     29 +static void
     30 +loadhistory(void)
     31 +{
     32 +	FILE *fp = NULL;
     33 +	static size_t cap = 0;
     34 +	size_t llen;
     35 +	char *line;
     36 +
     37 +	if (!histfile) {
     38 +		return;
     39 +	}
     40 +
     41 +	fp = fopen(histfile, "r");
     42 +	if (!fp) {
     43 +		return;
     44 +	}
     45 +
     46 +	for (;;) {
     47 +		line = NULL;
     48 +		llen = 0;
     49 +		if (-1 == getline(&line, &llen, fp)) {
     50 +			if (ferror(fp)) {
     51 +				die("failed to read history");
     52 +			}
     53 +			free(line);
     54 +			break;
     55 +		}
     56 +
     57 +		if (cap == histsz) {
     58 +			cap += 64 * sizeof(char*);
     59 +			history = realloc(history, cap);
     60 +			if (!history) {
     61 +				die("failed to realloc memory");
     62 +			}
     63 +		}
     64 +		strtok(line, "\n");
     65 +		history[histsz] = line;
     66 +		histsz++;
     67 +	}
     68 +	histpos = histsz;
     69 +
     70 +	if (fclose(fp)) {
     71 +		die("failed to close file %s", histfile);
     72 +	}
     73 +}
     74 +
     75 +static void
     76 +navhistory(int dir)
     77 +{
     78 +	static char def[BUFSIZ];
     79 +	char *p = NULL;
     80 +	size_t len = 0;
     81 +
     82 +	if (!history || histpos + 1 == 0)
     83 +		return;
     84 +
     85 +	if (histsz == histpos) {
     86 +		strncpy(def, text, sizeof(def));
     87 +	}
     88 +
     89 +	switch(dir) {
     90 +	case 1:
     91 +		if (histpos < histsz - 1) {
     92 +			p = history[++histpos];
     93 +		} else if (histpos == histsz - 1) {
     94 +			p = def;
     95 +			histpos++;
     96 +		}
     97 +		break;
     98 +	case -1:
     99 +		if (histpos > 0) {
    100 +			p = history[--histpos];
    101 +		}
    102 +		break;
    103 +	}
    104 +	if (p == NULL) {
    105 +		return;
    106 +	}
    107 +
    108 +	len = MIN(strlen(p), BUFSIZ - 1);
    109 +	strncpy(text, p, len);
    110 +	text[len] = '\0';
    111 +	cursor = len;
    112 +	match();
    113 +}
    114 +
    115 +static void
    116 +savehistory(char *input)
    117 +{
    118 +	unsigned int i;
    119 +	FILE *fp;
    120 +
    121 +	if (!histfile ||
    122 +	    0 == maxhist ||
    123 +	    0 == strlen(input)) {
    124 +		goto out;
    125 +	}
    126 +
    127 +	fp = fopen(histfile, "w");
    128 +	if (!fp) {
    129 +		die("failed to open %s", histfile);
    130 +	}
    131 +	for (i = histsz < maxhist ? 0 : histsz - maxhist; i < histsz; i++) {
    132 +		if (0 >= fprintf(fp, "%s\n", history[i])) {
    133 +			die("failed to write to %s", histfile);
    134 +		}
    135 +	}
    136 +	if (!histnodup || (histsz > 0 && strcmp(input, history[histsz-1]) != 0)) { /* TODO */
    137 +		if (0 >= fputs(input, fp)) {
    138 +			die("failed to write to %s", histfile);
    139 +		}
    140 +	}
    141 +	if (fclose(fp)) {
    142 +		die("failed to close file %s", histfile);
    143 +	}
    144 +
    145 +out:
    146 +	for (i = 0; i < histsz; i++) {
    147 +		free(history[i]);
    148 +	}
    149 +	free(history);
    150 +}
    151 +
    152  static void
    153  keypress(XKeyEvent *ev)
    154  {
    155  	char buf[32];
    156 -	int len;
    157 +	int len, i;
    158  	KeySym ksym = NoSymbol;
    159  	Status status;
    160 
    161 @@ -359,6 +486,27 @@ keypress(XKeyEvent *ev)
    162  			XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
    163  			                  utf8, utf8, win, CurrentTime);
    164  			return;
    165 +		case XK_r:
    166 +			if (histfile) {
    167 +				if (!backup_items) {
    168 +					backup_items = items;
    169 +					items = calloc(histsz + 1, sizeof(struct item));
    170 +					if (!items) {
    171 +						die("cannot allocate memory");
    172 +					}
    173 +
    174 +					for (i = 0; i < histsz; i++) {
    175 +						items[i].text = history[i];
    176 +					}
    177 +				} else {
    178 +					free(items);
    179 +					items = backup_items;
    180 +					backup_items = NULL;
    181 +				}
    182 +			}
    183 +			match();
    184 +			ksym = NoSymbol;
    185 +           break;
    186  		case XK_Left:
    187  			movewordedge(-1);
    188             ksym = NoSymbol;
    189 @@ -388,6 +535,14 @@ keypress(XKeyEvent *ev)
    190  		case XK_j: ksym = XK_Next;  break;
    191  		case XK_k: ksym = XK_Prior; break;
    192  		case XK_l: ksym = XK_Down;  break;
    193 +		case XK_p:
    194 +			navhistory(-1);
    195 +			buf[0]=0;
    196 +			break;
    197 +		case XK_n:
    198 +			navhistory(1);
    199 +			buf[0]=0;
    200 +			break;
    201  		default:
    202  			return;
    203  		}
    204 @@ -466,6 +621,8 @@ insert:
    205  	case XK_KP_Enter:
    206  		puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
    207  		if (!(ev->state & ControlMask)) {
    208 +			savehistory((sel && !(ev->state & ShiftMask))
    209 +				    ? sel->text : text);
    210  			cleanup();
    211  			exit(0);
    212  		}
    213 @@ -715,6 +873,8 @@ main(int argc, char *argv[])
    214  		} else if (i + 1 == argc)
    215  			usage();
    216  		/* these options take one argument */
    217 +		else if (!strcmp(argv[i], "-H"))
    218 +			histfile = argv[++i];
    219  		else if (!strcmp(argv[i], "-l"))   /* number of lines in vertical list */
    220  			lines = atoi(argv[++i]);
    221  		else if (!strcmp(argv[i], "-m"))
    222 @@ -757,6 +897,8 @@ main(int argc, char *argv[])
    223         die("no fonts could be loaded.");
    224     lrpad = drw->fonts->h;
    225 
    226 +	loadhistory();
    227 +
    228  	if (fast) {
    229  		grabkeyboard();
    230  		readstdin();
    231 diff --git a/dmenu_run b/dmenu_run
    232 index 834ede5..59ec622 100755
    233 --- a/dmenu_run
    234 +++ b/dmenu_run
    235 @@ -1,2 +1,2 @@
    236  #!/bin/sh
    237 -dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
    238 +dmenu_path | dmenu -H "${XDG_CACHE_HOME:-$HOME/.cache/}/dmenu_run.hist" "$@" | ${SHELL:-"/bin/sh"} &