@Anselm
I am curious, will you be committing this patch?

-steve


On 18:25 Wed 28 Jan, Jeremy Jay wrote:
>
>On Wed 28 Jan 2009 - 12:38PM, bill lam wrote:
>> It is very useful!
>> Can it be extended to handle <tab><tab> ?
>
>request granted =)  first tab will do longest
>completion, subsequent tabs will cycle through
>all choices.
>
>I dont know if others tried or not, but my
>example didnt work...  OpenOffice (and a few
>other apps I noticed) doesn't like the escaped
>spaces, so I tweaked the dmenu_run script so
>it'll work now (assuming the filename is the
>only argument... YMMV)
>
>This patch makes the functionality optional
>through a "-c" command line argument, in the
>interests of keeping dmenu generic and hoping
>this will get committed to the main line.  So
>you'll want to add it to your dwm config.h or
>whatever you call it through.  I've also
>added some info to the man page too.
>
>Jeremy

>diff -r 13402291bc76 dmenu.1
>--- a/dmenu.1  Fri Dec 12 19:58:52 2008 +0000
>+++ b/dmenu.1  Wed Jan 28 18:15:59 2009 -0500
>@@ -12,6 +12,7 @@
> .RB [ \-sb " <color>"]
> .RB [ \-sf " <color>"]
> .RB [ \-v ]
>+.RB [ \-c ]
> .SH DESCRIPTION
> .SS Overview
> dmenu is a generic menu for X, originally designed for
>@@ -46,6 +47,9 @@
> .TP
> .B \-v
> prints version information to standard output, then exits.
>+.TP
>+.B \-c
>+enables filename completion for text after a space (useful with the dmenu_run 
>script).
> .SH USAGE
> dmenu reads a list of newline-separated items from standard input and creates 
> a
> menu.  When the user selects an item or enters any text and presses Return, 
> his/her
>@@ -67,7 +71,9 @@
> Select the first/last item.
> .TP
> .B Tab (Control\-i)
>-Copy the selected item to the input field.
>+Copy the selected item to the input field.  Also, if the -c option is given 
>and there
>+is a space in the input, will try to expand and complete text after the space 
>into a
>+valid filename. (First Tab - Longest Completion, Multiple Tabs - cycle 
>through files)
> .TP
> .B Return (Control\-j)
> Confirm selection and quit (print the selected item to standard output). 
> Returns
>diff -r 13402291bc76 dmenu.c
>--- a/dmenu.c  Fri Dec 12 19:58:52 2008 +0000
>+++ b/dmenu.c  Wed Jan 28 18:15:59 2009 -0500
>@@ -8,6 +8,7 @@
> #include <string.h>
> #include <strings.h>
> #include <unistd.h>
>+#include <wordexp.h>
> #include <X11/keysym.h>
> #include <X11/Xlib.h>
> #include <X11/Xutil.h>
>@@ -59,6 +60,7 @@
> static void initfont(const char *fontstr);
> static void kpress(XKeyEvent * e);
> static void match(char *pattern);
>+static void matchfile(char *filestart, Bool cycling);
> static void readstdin(void);
> static void run(void);
> static void setup(Bool topbar);
>@@ -77,7 +79,7 @@
> static int screen;
> static unsigned int mw, mh;
> static unsigned int numlockmask = 0;
>-static Bool running = True;
>+static Bool running = True, filecomplete = False;
> static Display *dpy;
> static DC dc;
> static Item *allitems = NULL; /* first of all items */
>@@ -311,6 +313,7 @@
> 
> void
> kpress(XKeyEvent * e) {
>+      static KeySym lastkey=0;
>       char buf[32];
>       int i, num;
>       unsigned int len;
>@@ -396,7 +399,10 @@
>       default:
>               if(num && !iscntrl((int) buf[0])) {
>                       buf[num] = 0;
>-                      strncpy(text + len, buf, sizeof text - len);
>+                      if(len > 0)
>+                              strncat(text, buf, sizeof text);
>+                      else
>+                              strncpy(text, buf, sizeof text);
>                       match(text);
>               }
>               break;
>@@ -467,12 +473,17 @@
>               }
>               break;
>       case XK_Tab:
>+              if( filecomplete && strchr(text, ' ')!=NULL ) {
>+                      matchfile( strchr(text, ' ')+1, lastkey==XK_Tab );
>+                      break;
>+              }
>               if(!sel)
>                       return;
>               strncpy(text, sel->text, sizeof text);
>               match(text);
>               break;
>       }
>+      lastkey=ksym;
>       drawmenu();
> }
> 
>@@ -518,6 +529,44 @@
> }
> 
> void
>+matchfile(char *filestart, Bool cycling ) {
>+      static int try=0, p=0;
>+      wordexp_t exp;
>+      int i, j, k;
>+
>+      if( !cycling ) { 
>+              p = strlen(filestart);
>+              try=0;
>+      }
>+      filestart[ p+1 ] = 0;
>+      filestart[ p ] = '*';
>+
>+      wordexp(filestart, &exp, 0);
>+      if( exp.we_wordc > 0 ) {
>+              for(j=0,i=0; exp.we_wordv[try][i]!=0; i++,j++) {
>+                      if( exp.we_wordv[try][i]==' ' ) filestart[j++]='\\';
>+                      filestart[j]=exp.we_wordv[try][i];
>+              }
>+              filestart[j]=0;
>+
>+              if( cycling )
>+                      try = (try+1)%exp.we_wordc;
>+              else
>+                      for(k=1; k<exp.we_wordc; k++)
>+                              for(j=0, i=0; exp.we_wordv[k][i]; i++,j++) {
>+                                      if( filestart[j]=='\\' ) j++;
>+                                      if( filestart[j]!=exp.we_wordv[k][i] ) {
>+                                              filestart[j]=0;
>+                                              break;
>+                                      }
>+                              }
>+      } else {
>+              filestart[ p ] = 0;
>+      }
>+      wordfree(&exp);
>+}
>+
>+void
> readstdin(void) {
>       char *p, buf[1024];
>       unsigned int len = 0, max = 0;
>@@ -677,6 +726,8 @@
>               }
>               else if(!strcmp(argv[i], "-b"))
>                       topbar = False;
>+              else if(!strcmp(argv[i], "-c"))
>+                      filecomplete = True;
>               else if(!strcmp(argv[i], "-fn")) {
>                       if(++i < argc) font = argv[i];
>               }
>@@ -699,7 +750,7 @@
>                       eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, 
> see LICENSE for details\n");
>               else
>                       eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb 
> <color>] [-nf <color>]\n"
>-                             "             [-p <prompt>] [-sb <color>] [-sf 
><color>] [-v]\n");
>+                             "             [-p <prompt>] [-sb <color>] [-sf 
><color>] [-v] [-c]\n");
>       if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
>               fprintf(stderr, "warning: no locale support\n");
>       if(!(dpy = XOpenDisplay(0)))
>diff -r 13402291bc76 dmenu_run
>--- a/dmenu_run        Fri Dec 12 19:58:52 2008 +0000
>+++ b/dmenu_run        Wed Jan 28 18:15:59 2009 -0500
>@@ -1,2 +1,2 @@
>-#!/bin/sh
>-exe=`dmenu_path | dmenu ${1+"$@"}` && exec $exe
>+#!/bin/zsh
>+exe=`dmenu_path | dmenu ${1+"$@"}` && exe2=${exe//\\ / } && exec ${exe2%% *} 
>"${exe2#* }"


Reply via email to