On Fri, Aug 13, 2010 at 12:15:41PM +0200, LuX wrote:
On Thu, Aug 12, 2010 at 09:19:52PM -0400, Kris Maglione wrote:
You'll need to replace the // line with { print; fllush() }. I'm
afraid that if you use mawk it's hopeless.

I'm using awk. Your first variant, modified as above, works perfectly.
Thank you so much for your very kind and detailed answer!

Sure, no problem. I wouldn't have known that the man page was broken otherwise.

Message de LuX: ven. 13/08/10, 12:15:41 +0200
Which language is it, perl?

Please forget about this… :-(

Good. I was trying to think of a way to ignore it politely. :)

I completely support this point on POSIX utilities (although I only
very vaguely know what POSIX means). For end users like me it's easier
to learn the basics of any common language like perl than to master
shell programming with fancy pipes and redirections (this is
incredibly smart and subtle, in my opinion). This makes such example,
although very hard to understand, extraordinary valuable: I would be
completely unable to find them by myself.

I don't know. See the attached perl version. I think it's considerably more arcane than the awk version (but, then again, perl is the bastard child of awk). Perl is a hard language to love, but for some reason, it's my go-to language for text processing.

By the way, how did you guess that 'complete a command and then files
in the current directory' is precisely the kind of utilities I was
looking for? Would that mean that other people, even in this list, are
considering this as a useful alternative to opening a terminal? (Or at
least a fancy alternative, let's be honest.) No, I can't believe it…
please look at this:

I didn't. ;) But it is the main reason that I added the completion facility to wimenu.

On Wed, Jan 17, 2007 at 02:15:01PM +0100, Martin Stubenschrott insisted:
What I wanted to suggest was adding completion for arguments. I meant,
after pressing tab someone obviously wants to add arguments. And why not
help the user also with argument completion.

On Wed, 17 Jan 2007 15:08:06 +0100, Anselm R. Garbe closed the debate:
I think the right place to achieve what you want is the shell,
which supports this task already. dmenu is designed to run
simple commands only.

Well, this might be today the main difference between dmenu and
wimenu, except if A.R. Garbe has changed his mind in the mean time. As
we say in France: « il n'y a que les imbéciles qui ne changent pas
d'avis » (only idiots never change their mind).

Normally I make it a point to disagree with Martin (some of our disagreements have been epic). But in the case of dmenu, I don't especially care what it was intended for, so much as what I found myself using it for. I wrote wimenu because I tended to rely heavily on dmenu for commands that I wanted to launch without keeping a terminal around. Its lack of caret support and command history caused me no end of headaches, when I would type out a moderately long command and realize I'd made a mistake at the begining and have to start over, or realize after I'd submitted it and have no history to go back and edit. It's actually gotten a lot better since Connor took over, but wimenu still fits my needs (and aesthetic) better.

I do agree, though, that a program like wimenu or dmenu has no place providing builtin completion. They're meant to be simple, and to serve a lot of purposes, and trying to shoehorn anything other than basic 1-level completion into them is messy and feels wrong. Even the basic file completion plugin feels wrong to me. For any use other than launching commands, the results make no sense. It also just doesn't feel like the Unix way. 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.

--
Kris Maglione

Learning is not compulsory.  Neither is survival.
        --W. Edwards Deming

#!/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;
    }
}

# vim:se sts=4 sw=4 et:

Reply via email to