changeset: 2373:093bc132f974
tag: tip
user: Kris Maglione <jg_AT_suckless.org>
date: Wed Oct 15 23:15:42 2008 -0400
files: cmd/menu/Makefile cmd/menu/dat.h cmd/menu/fns.h cmd/menu/history.c cmd/menu/main.c cmd/menu/menu.c cmd/wmii.rc.rc rc/rc.wmii.rc
description:
[menu] Add history search, and the ability to write history while removing dups within a 20 item sliding window.
diff -r 9e090634b6ca -r 093bc132f974 cmd/menu/Makefile
--- a/cmd/menu/Makefile Wed Oct 15 21:34:15 2008 -0400
+++ b/cmd/menu/Makefile Wed Oct 15 23:15:42 2008 -0400
@@ -14,6 +14,7 @@
-DIXP_NEEDAPI=86
OBJ = main \
caret \
+ history \
event \
menu \
../wmii/geom \
diff -r 9e090634b6ca -r 093bc132f974 cmd/menu/dat.h
--- a/cmd/menu/dat.h Wed Oct 15 21:34:15 2008 -0400
+++ b/cmd/menu/dat.h Wed Oct 15 23:15:42 2008 -0400
@@ -61,10 +61,14 @@
EXTERN Item* matchend;
EXTERN Item* matchidx;
+EXTERN Item hist;
EXTERN Item* histidx;
EXTERN int maxwidth;
EXTERN int result;
+
+EXTERN char* (*find)(const char*, const char*);
+EXTERN int (*compare)(const char*, const char*, size_t);
EXTERN char buffer[8092];
EXTERN char* _buffer;
diff -r 9e090634b6ca -r 093bc132f974 cmd/menu/fns.h
--- a/cmd/menu/fns.h Wed Oct 15 21:34:15 2008 -0400
+++ b/cmd/menu/fns.h Wed Oct 15 23:15:42 2008 -0400
@@ -9,6 +9,9 @@
Item* filter_list(Item*, char*);
uint flushenterevents(void);
uint flushevents(long, bool);
+void history_dump(const char*, int);
+char* history_search(int, char*, int);
+char* histtext(Item*);
void init_screens(void);
void menu_init(void);
void menu_show(void);
diff -r 9e090634b6ca -r 093bc132f974 cmd/menu/history.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cmd/menu/history.c Wed Oct 15 23:15:42 2008 -0400
@@ -0,0 +1,87 @@
+#include "dat.h"
+#include <assert.h>
+#include <bio.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "fns.h"
+
+static void
+splice(Item *i) {
+ i->next->prev = i->prev;
+ i->prev->next = i->next;
+}
+
+char*
+history_search(int dir, char *string, int n) {
+ Item *i;
+
+ if(dir == FORWARD) {
+ if(histidx == &hist)
+ return hist.string;
+ for(i=histidx->next; i != hist.next; i=i->next)
+ if(!i->string || !compare(i->string, string, n)) {
+ histidx = i;
+ return i->string;
+ }
+ return string;
+ }
+ assert(dir == BACKWARD);
+
+ if(histidx == &hist) {
+ free(hist.string);
+ hist.string = estrdup(input.string);
+ }
+
+ for(i=histidx->prev; i != &hist; i=i->prev)
+ if(!compare(i->string, string, n)) {
+ histidx = i;
+ return i->string;
+ }
+ return string;
+}
+
+void
+history_dump(const char *path, int max) {
+ static char *items[20];
+ static char *tmp;
+ Biobuf b;
+ Item *h, *first;
+ int i, n, fd;
+
+ if(fork() != 0)
+ return;
+
+ tmp = smprint("%s.XXXXXX", path);
+ fd = mkstemp(tmp);
+ if(fd < 0) {
+ fprint(2, "%s: Can't create temporary history file %q: %r\n", argv0, path);
+ return;
+ }
+
+ hist.string = input.string;
+ n = 0;
+ hist.next->prev = nil;
+ for(h=&hist; h; h=h->prev) {
+ for(i=0; i < nelem(items); i++)
+ if(items[i] && !strcmp(h->string, items[i])) {
+ splice(h);
+ goto next;
+ }
+ items[n++ % nelem(items)] = h->string;
+ first = h;
+ if(!max || n >= max)
+ break;
+ next:
+ continue;
+ }
+
+ Binit(&b, fd, OWRITE);
+ hist.next = nil;
+ for(h=first; h; h=h->next)
+ Bprint(&b, "%s\n", h->string);
+ Bterm(&b);
+ rename(tmp, path);
+ exit(0);
+}
+
diff -r 9e090634b6ca -r 093bc132f974 cmd/menu/main.c
--- a/cmd/menu/main.c Wed Oct 15 21:34:15 2008 -0400
+++ b/cmd/menu/main.c Wed Oct 15 23:15:42 2008 -0400
@@ -20,8 +20,6 @@
static Biobuf* inbuf;
static char ctl[1024];
static char* ectl;
-
-static char* (*find)(const char*, const char*);
static void
usage(void) {
@@ -208,17 +206,21 @@
int
main(int argc, char *argv[]) {
- static Item hist;
Item *item;
char *address;
char *histfile;
int i;
+ long ndump;
quotefmtinstall();
fmtinstall('r', errfmt);
address = getenv("WMII_ADDRESS");
histfile = nil;
+
find = strstr;
+ compare = strncmp;
+
+ ndump = -1;
ARGBEGIN{
case 'a':
@@ -227,8 +229,12 @@
case 'h':
histfile = EARGF(usage());
break;
+ case 'n':
+ ndump = strtol(EARGF(usage()), nil, 10);
+ break;
case 'i':
find = strcasestr;
+ compare = strncasecmp;
break;
default:
usage();
@@ -272,16 +278,17 @@
Bterm(inbuf);
histidx = &hist;
+ link(&hist, &hist);
if(histfile) {
inbuf = Bopen(histfile, OREAD);
- if(!inbuf)
- fatal("Can't open history file %q: %r", histfile);
- item = populate_list(inbuf, true);
- if(item) {
- link(item->prev, &hist);
- item->prev = nil;
+ if(inbuf) {
+ item = populate_list(inbuf, true);
+ if(item) {
+ link(item->prev, &hist);
+ link(&hist, item);
+ }
+ Bterm(inbuf);
}
- Bterm(inbuf);
}
init_screens();
@@ -290,6 +297,10 @@
if(i)
fprint(2, "%s: error: %r\n", argv0);
XCloseDisplay(display);
+
+ if(ndump >= 0 && histfile && result == 0)
+ history_dump(histfile, ndump);
+
return result;
}
diff -r 9e090634b6ca -r 093bc132f974 cmd/menu/menu.c
--- a/cmd/menu/menu.c Wed Oct 15 21:34:15 2008 -0400
+++ b/cmd/menu/menu.c Wed Oct 15 23:15:42 2008 -0400
@@ -14,8 +14,7 @@
enum {
ACCEPT = CARET_LAST,
REJECT,
- HIST_NEXT,
- HIST_PREV,
+ HIST,
KILL,
CMPL_NEXT,
CMPL_PREV,
@@ -49,32 +48,15 @@
XFlush(display);
}
-static char*
-histtext(Item *i) {
- static char *orig;
-
- if(!histidx->string) {
- free(orig);
- orig = strdup(input.string);
- }
- return i->string ? i->string : orig;
-}
-
static void
menu_cmd(int op, int motion) {
+ int n;
switch(op) {
- case HIST_NEXT:
- if(histidx->next) {
- caret_insert(histtext(histidx->next), true);
- histidx = histidx->next;
- }
- break;
- case HIST_PREV:
- if(histidx->prev) {
- caret_insert(histtext(histidx->prev), true);
- histidx = histidx->prev;
- }
+ case HIST:
+ n = input.pos - input.string;
+ caret_insert(history_search(motion, input.string, n), true);
+ input.pos = input.string + n;
break;
case KILL:
caret_delete(BACKWARD, motion);
@@ -190,7 +172,7 @@
r2.max.x = inputw;
drawstring(ibuf, font, r2, West, input.string, cnorm.fg);
- r2.min.x = textwidth_l(font, input.string, input.pos - input.string) + pad/2;
+ r2.min.x = textwidth_l(font, input.string, input.pos - input.string) + pad/2 - 1;
r2.max.x = r2.min.x + 2;
r2.min.y++;
r2.max.y--;
@@ -266,11 +248,11 @@
return;
case XK_n:
case XK_N:
- menu_cmd(HIST_NEXT, 0);
+ menu_cmd(HIST, FORWARD);
return;
case XK_p:
case XK_P:
- menu_cmd(HIST_PREV, 0);
+ menu_cmd(HIST, BACKWARD);
return;
case XK_h:
case XK_H:
@@ -349,10 +331,10 @@
menu_cmd(FORWARD, CHAR);
return;
case XK_Up:
- menu_cmd(HIST_PREV, 0);
+ menu_cmd(HIST, BACKWARD);
return;
case XK_Down:
- menu_cmd(HIST_NEXT, 0);
+ menu_cmd(HIST, FORWARD);
return;
case XK_Home:
menu_cmd(CMPL_FIRST, 0);
diff -r 9e090634b6ca -r 093bc132f974 cmd/wmii.rc.rc
--- a/cmd/wmii.rc.rc Wed Oct 15 21:34:15 2008 -0400
+++ b/cmd/wmii.rc.rc Wed Oct 15 23:15:42 2008 -0400
@@ -48,12 +48,6 @@
-^(nf nb br)^$wmiinormcol \
-^(sf sb br)^$wmiifocuscol $*
}
-
-fn wi_addhist {
- file = $1 len=$2 { shift 2
- { cat $file; echo $*; } | uniq | sed '/^$/d' \
- | tail -$len >$file.$pid
- mv $file.$pid $file}}
fn wi_fnmenu {
group=$1^Menu-$2 last=$group^_last fns=`{wi_getfuns $group} {
diff -r 9e090634b6ca -r 093bc132f974 rc/rc.wmii.rc
--- a/rc/rc.wmii.rc Wed Oct 15 21:34:15 2008 -0400
+++ b/rc/rc.wmii.rc Wed Oct 15 23:15:42 2008 -0400
@@ -215,19 +215,18 @@
wmiir xwrite /client/sel/ctl kill}
key $MODKEY-a || fn $key {
- Action `{wi_actions | wimenu} &}
+ Action `{wi_actions | wimenu -h $hist.action -n $histlen} &}
key $MODKEY-p || fn $key {
- ifs=() { cmd = `{wimenu -h $progs_hist <$progs_file} }
- wi_runcmd $cmd &
- wi_addhist $hist.prog $histlen $cmd}
+ ifs=() { wi_runcmd `{wimenu -h $hist.prog -n $histlen <$progs_file} & }}
+
key $MODKEY-Return || fn $key {
wi_runcmd $WMII_TERM &}
key $MODKEY-t || fn $key {
- wmiir xwrite /ctl view `{wi_tags | wimenu} &}
+ wmiir xwrite /ctl view `{wi_tags | wimenu -h $hist.tag -n 50} &}
key $MODKEY-Shift-t || fn $key {
sel = `{wmiir read /client/sel/ctl | sed 1q} \
- wmiir xwrite /client/$sel/tags `{wi_tags | wimenu} &}
+ wmiir xwrite /client/$sel/tags `{wi_tags | wimenu -h $hist.tag -n 50} &}
key $MODKEY-^`{seq 0 9} || fn $key {
wmiir xwrite /ctl view `{echo $1 | sed 's/.*-//'}}
Received on Thu Oct 16 2008 - 03:16:02 UTC
This archive was generated by hypermail 2.2.0 : Thu Oct 16 2008 - 03:24:05 UTC