[hackers] [wmii] [menu] Add history search, and the ability to write history while removing dups within a 20 item sliding window. || Kris Maglione

From: <hg_AT_suckless.org>
Date: Thu, 16 Oct 2008 03:16:02 +0000 (UTC)

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