suckless-gf-dmenu

Gentoo-friendly patches for Suckless's dmenu.
Log | Files | Refs | README | LICENSE

navhistory-nodoc.patch (3883B)


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