Re: [dev][wmii] wimenu custom completion

From: LuX <lux.onthenet_AT_free.fr>
Date: Sat, 14 Aug 2010 00:34:41 +0200

Hello!

On Thu, 12 Aug 2010 21:19:52 -0400, Kris Maglione wrote:
> if you're looking for a start, this is the above modified to (crudely)
> complete a command and then files in the current directory

This second variant is fantastic! It allows me to select a command
with wimenu, add some options, find a file in the directory tree… it
does everything. In addition I used for the -h option of wimenu simply
$HOME/bash_history, so that the bash history is available from wimenu
and conversely.

The only little thing it was missing, in my opinion, was the ability
to display hidden files when I put a '.' at the beginning of a file
name. Thus I modified it in order to do so (see below).

Thank you very, very much.
LuX.

---------

#/bin/sh

script=$(cat <<'!'
    # Push out a new set of completions
    function update(offset, cmd) {
        # Only push out the completion if the offset or the
        # option of ls has changed. The behavior will be the
        # same regardless, but this is a minor optimization
        if (offset != loffset || opt != lopt) {
            loffset = offset
            lopt = opt

            print offset >fifo
            print read(cmd) >fifo
            fflush(fifo)
        }
    }

    # Quote a string. This requires that your shell supports
    # rc quoting syntax (zsh with 'setopt rcquotes' or rc, namely)
    function quote(str) {
        if (!match(str, /[\[\](){}$'"^#~!&;*?|<>]/))
            return str
        gsub(/'/, "''", str)
        return "'" str "'"
    }

    # Read the output of a command and return it
    function read(cmd) {
        # We need to use a cache since every use of an
        # input command refers to the same process, which
        # means it can only be run once.
        if (cmd in cache)
            return cache[cmd]

        res = ""
        while (cmd | getline)
            res = res quote($0) "\n"
        return cache[cmd] = res
    }

    BEGIN {
        fifo = "fifo"
        progs = ". wmii.sh; wi_proglist $PATH"

        # Print the first set of completions to wimenu’s fifo
        print read(progs) >fifo
        fflush(fifo)
    }

    //

    # Process the input and provide the completions
    {
        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 # Set by match() above
            str = substr($0, offset + 1)

            # If we're completing a sub-directory, adjust
            # the offset to the position of the last /
            if (match(str, ".*/"))
                offset += RLENGTH

            opt = ""
            if (match(str, "(^|/)\\.[^/]*$"))
                # Use option -A of ls if the last directory
                # component starts with a dot.
                opt = "-A "
                    
            cmd = "ls " opt quote(str)
            if (str && !match(cmd, "/$"))
                # Use dirname to chop off the end of the
                # last directory component
                cmd = "ls " opt "\"$(dirname " quote(str) ")\""

            update(offset, cmd)
        }

# system("true")
        # Skip the trailing part of the command
        getline rest
    }
!
)

exec `wimenu -h "$HOME/.bash_history" -n 5000 -c <fifo | awk "$script" | tail -1`
Received on Sat Aug 14 2010 - 00:34:41 CEST

This archive was generated by hypermail 2.2.0 : Sat Aug 14 2010 - 00:36:02 CEST