Re: [dwm] dmenu filename tab-completion patch

From: Anselm R Garbe <garbeam_AT_gmail.com>
Date: Fri, 27 Mar 2009 15:07:05 +0000

Hi Steven,

sorry for getting back so late, I think it might be worth considering
it after the 4.0 release which I plan to do very soon.

Kind regards,
Anselm

2009/3/27 Steven Blatchford <dollarsignfoo_AT_gmail.com>:
> @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#* }"
Received on Fri Mar 27 2009 - 15:07:05 UTC

This archive was generated by hypermail 2.2.0 : Fri Mar 27 2009 - 15:12:07 UTC