#!/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 {s@.*/(?!$)@@; 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: