On Mon, Aug 16, 2010 at 12:37:54AM +0200, LuX wrote:
On Thu, 12 Aug 2010 21:19:52 -0400, Kris Maglione wrote:But if you're looking for a start, this is the above modified to (crudely) complete a command and then files in the currentdirectory:I have an issue with this second variant, which I didn't notice first and am unable to solve. Whether I quit it with Return or Esc, the result is the same: the input string is sent to stdout. If you stillwant to help… I'm stuck here.
Yes, I already fixed that problem when I made it into an example file for distribution. Attached.
This is why I left completion up to the program executing the menu.It knows what it's running it for better than I do.---> I think that this is very clever! Bash completion is excellent, but not customizable (as far as I know). Thus I do agree that it is a good thing that wimenu comes with a much more elementary completion (it is not intended to duplicate bash), but fully customizable (it allows to do other things, even those that bashcan not).
Bash completion is actually written in bash, so it's very customizable. This is also why it can in theory be used to provide completion results for wimenu, if someone well enough acquainted with its internals puts his mind to it.
Example: In bash I have always been missing a history behaving like in vim. Let me explain this. If you have typed a long command 'cmd' at some moment and want to repeat it, you will probably want to use the history. Bash will then display successively all the (possibly numerous) other commands that you typed in the mean time, while vim while jump directly to 'cmd' provided you type only the beginning of it. Using bash history inside wimenu with your script (the 'second variant' mentioned above, which I called 'wim' in another post) allows to recover this nice behaviour of vim, which eventually makes wim a significantly BETTER way (in my opinion) of typing commands than to use a terminal.
Just add this to ~/.inputrc: C-w: backward-kill-word C-p: history-search-backward C-n: history-search-forwardAlthough I believe C-r brings up some kind of incrimental search dialog. I don't use bash though, so I'm a bit rusty.
PS: I haven't been able to accesshttp://lists.suckless.org/dev/att-5538/menu.pl I take you at your word if you say that it is 'considerably morearcane than the awk version'. Anyway this is one more reason to 'make a point of only using POSIX utilities in examples' as you said.
Hm. Silly pipermail. I take it you're not subscribed to the list, then? I'll paste it inline below, although I've a much more sophisticated version now (attached).
#!/usr/bin/env perl use warnings; use strict; use IPC::Open2; my $proglist = `wmiir namespace|tr -d "\n"` . "/.proglist"; open2 my $procout, my $procin, "wimenu", "-c"; sub quote(_) { local ($_) = @_; return $_ unless m/[\[\](){}\$'^#~!&;*?|<>\s]/; s/'/''/g; "'$_'"; } my $oldoffset; sub update(&;$) { my ($choices, $offset) = @_; if(not defined $offset or $offset != $oldoffset) { $oldoffset = $offset || 0; print $procin $offset, "\n" if defined $offset; print $procin $choices->(), "\n\n"; } } sub readout(@) { my ($mode, $expr, @rest) = @_; open(my $fd, $mode, $expr, @rest); join "\n", map {chomp; quote} <$fd> } update {readout "<", $proglist}; while(local $_ = <$procout>) { chomp; unless(<$procout>) { print; exit; } if(not /.*\s/) { update {readout "<", $proglist} 0; } else { my $offset = length $&; $_ = substr $_, $offset; my @args = m{(/|^)\.[^/]*$} && ("-A") || (); $offset += length $& if m{.*/}; s,/.*?$,,; update {readout "-|", "ls", @args, $_ || "."} $offset; } } -- Kris Maglione When a religion is good, I conceive it will support itself; and when it does not support itself, and God does not take care to support it so that its professors are obliged to call for help of the civil power, 'tis a sign, I apprehend, of its being a bad one. --Benjamin Franklin
wimenu-file-completion.sh
Description: Bourne shell script
#!/usr/bin/env perl use warnings; use strict; use File::Glob qw(:glob); use IPC::Open2; sub dequote(_); sub quote(_); sub readout(@); sub update(&;$$); open2 my $procout, my $procin, ("wimenu", "-c", @ARGV); sub main() { my $proglist = `wmiir namespace` . "/.proglist"; $proglist =~ s/\n//; update {readout "<", $proglist}; while(local $_ = <$procout>) { chomp; exec $ENV{SHELL} || "sh", "-c", "exec $_" unless <$procout>; if(not m{^(?: (?:[^\s\\'] | \\. | '[^']*')+ \s+ )+}x) { update {readout "<", $proglist} 0, ""; } else { my $offset = length $&; $_ = substr $_, $offset; $offset += length $& if m{.*/}; s{ ((?:^|/) \.?) [^[\]{}~?*/]* $ }{$1*}x; update {map {...@.*/(?!$)@@; quote} bsd_glob dequote($_ || "*"), GLOB_MARK|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE} $offset, $_; } } } sub dequote(_) { local ($_) = @_; s{ ((?:[^\\'] | \\. | \\$)*) (?: ' (.*?) (?:'|$) )? }{ my ($a, $b) = ($1, $2 || ""); $a =~ s{ (\\.) | \$(\w+) | \$\{\w+\} }{ $1 || $ENV{$2 || $3} }gex; $b =~ s/[[\]{}~?*\\]/\\$&/g; "$a$b" }gex; $_ } sub quote(_) { local ($_) = @_; return $_ unless m/[[\](){}<>\$'"^#~!&;*?|\s]/; s/['\\]/'\\$&'/g; s{^ (.*?) (/?) $}{'$1'$2}x; $_ } sub readout(@) { my ($mode, $expr, @rest) = @_; open(my $fd, $mode, $expr, @rest); map {chomp; quote} <$fd> } my ($oldoffset, $oldpattern); sub update(&;$$) { my ($choices, $offset, $pattern) = @_; if(not defined $offset or $offset != $oldoffset or $pattern ne $oldpattern) { $oldoffset = $offset || 0; $oldpattern = $pattern || ""; print $procin $offset, "\n" if defined $offset; print $procin join "\n", $choices->(), "\n"; } } main; # vim:se sts=4 sw=4 et: