Hello! @Arian Kuschki: Thank you too, for the .inputrc trick.
On Sun, 15 Aug 2010 18:51:55 -0400, Kris Maglione wrote: > Yes, I already fixed that problem when I made it into an example > file for distribution. Attached. I have a few unessential remarks, if you allow me: - Although I don't understand this, it seems that the last 'tail -1' is no longer needed. - Since you replaced the call to dirname by a 'sub' command just after the comment '# Strip the trailing filename', it happens that when I type 'ls /' in the input area, it is the content of the $HOME directory instead of / which is displayed by wimenu. Here is a fix: # Strip the trailing filename if(match(str, "^/[^/]*$")) str = "/" str sub("(/|^)[^/]*$", "", str) - I have read somewhere that /dev/shm was a good place to put files used by programs to discuss one with each others. This would apply to "fifo" in this case. I don't know if you have an opinion on this. - I liked more the previous behaviour, when the script ends by sending the input string to stdout (like wimenu does) so that it can can be processed by some independent script like for example this one: cmd=$1 shift args="$@" noterm=$(grep Exec= /usr/share/applications/*.desktop /usr/local/share/applications/*.desktop | sed -e 's:.*Exec=\s*::' -e 's:^[^\ ]*/::' | grep -E "^$cmd(\ |$)") if [ "$args" != "${args% &}" -o "$noterm" != "" ]; then exec $cmd $args & elif [ "$cmd" != "" ]; then Terminal -e "${SHELL:-sh} -c \"$cmd $args ; ${SHELL:-sh}\"" & fi In addition I enjoyed adding another minor feature: when a list of options has been declared in the script for the initial command of the input line, every time a '-' is typed at the beginning of a new argument in a line starting with that command, this list of options is displayed instead of a list of files. I find it convenient for some commands, like 'lp' or 'pdfnup' which accept many options, useful to me but that I do not use to remember. In case other people would be interested I attach the code below with my favourite options for lp, as an example. Note: It would be better to declare the 'opt' array outside this script, in a sort of configuration file, but I don't know how to do this. Regards, LuX. ---------------- #!/bin/sh # This script will launch wimenu and provide command # completion for the first argument and filename completion # for each following argument, and pass the result to stdout. # Program name completion requires that a program list already # exist in $(wmiir namespace)/.proglist fifo="/dev/shm/wim_$USER" mkfifo $fifo 2>/dev/null script=$(cat <<'!' BEGIN { progs = "cat $(wmiir namespace)/.proglist" # Favorite options for some programs opt["lp"] = "-o media=a4\n-o landscape\n-o sides=two-sided-long-edge\nsides=two-sided-short-edge\n-o number-up=N\n" # Print the first set of completions to wimenu’s fifo print read(progs) >fifo fflush(fifo) } # Process the input and provide the completions { # Skip the trailing part of the command. # If there is none, this is the result. if (!getline rest) { print exit } if (!match($0, /.*[ \t]/)) # First argument, provide the program list update(0, progs) else { # Set the offset to the location of the last # space, and save that part of the completion offset = RLENGTH str = substr($0, offset + 1) # If we are completing a sub-directory, adjust # the offset to the position of the last / if (match(str, ".*/")) offset += RLENGTH # If the last component of the path begins with # a ., include hidden files arg = "" if(match(str, "(^|/)\\.[^/]*$")) arg = "-A" # Substitute ~/ for $HOME/ sub("^~/", ENVIRON["HOME"] "/", str) # Strip the trailing filename if(match(str, "^/[^/]*$")) str = "/" str sub("(/|^)[^/]*$", "", str) # If the last argument starts with a -, list # options declared in opt instead of files lscmd = "ls " arg quote(str) if(match($0, "\\ -[^\\ ]*$")) { lsopt = opt[gensub(/\ .*/, "", 1)] lscmd = "echo -n \"" lsopt "\"" } update(offset, lscmd) } } # Push out a new set of completions function update(offset, cmd) { # Only push out the completion if the offset or the # ls command has changed. The behavior will be the # same regardless, but this is a minor optimization if (offset != loffset || cmd != lcmd) { loffset = offset lcmd = cmd cmpl = read(cmd) print offset >fifo print cmpl >fifo fflush(fifo) } } # Quote a string. This should work in any Bourne # or POSIX compatible shell. function quote(str) { if (!match(str, /[\[\](){}$'"^#~!&;*?|<>]/)) return str gsub(/\\/, "'\\\\'", str) gsub(/'/, "'\\''", str) return "'" str "'" } # Read the output of a command and return it function read(cmd) { if (cmd in cache) return cache[cmd] res = "" while (cmd | getline) res = res quote($0) "\n" close(cmd) return cache[cmd] = res } ! ) wimenu -h "$HOME/.bash_history" -n 5000 -c "$@" <$fifo | awk -v "fifo=$fifo" "$script"