More csh completions

I made some (minor) git completions:

Code:
complete git 'p/1/(add merge-recursive add--interactive merge-resolve am \
    [...snip ludicrously long list of git commands ... ]/' \
    'n@checkout@`git branch -a | sed -r "s|^[\* ]+(remotes/origin/)?||; /^HEAD/d" | sort -u`@' \
    'n@branch@`git branch -a | sed -r "s|^[\* ]+(remotes/origin/)?||" /^HEAD/d | sort -u`@'

... there are probably other useful completions as well.

Open question:
git branch <tab> works, but git branch -d <tab> doesn't ...
 
Yesterday, I thought the make(1) completions would benefit from being able to complete -V, showing all known variables. Variables are shown in -dg1 output between
Code:
#*** Global Variables:
and
Code:
#*** Directory Cache:
However, sed(1) and awk(1) are so weak as to require substantial work to filter out all the trash, and even with Perl it is non-trivial.
 
So here's my "full" make completions, which is "Linux-safe" and works with GNU make:

Code:
[noparse]
if ( $uname == FreeBSD ) then
    set backslash_quote
    complete gmake 'n@*@`make -qp | awk -F: \'/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ { split($1,A,/ /); for(i in A)print A[i] }\' | sort -u`@'
    unset backslash_quote

    if ( `uname -r | cut -d. -f1` < 10 ) then
        complete make 'n@*@`make -pn | sed -n -E "/^[#_.\/[:blank:]]+/d; /=/d; s/[[:blank:]]*:.*//gp;"`@'
    else
        complete make 'n/*/`make -V .ALLTARGETS`/'
    endif
else if ( $uname == Linux ) then
    set backslash_quote
    complete make 'n@*@`make -qp | awk -F: \'/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ { split($1,A,/ /); for(i in A)print A[i] }\' | sort -u`@'
    unset backslash_quote
endif
[/noparse]


Another thing I've been using for a while is adding the mercurial or git branch name in my prompt, like:
Code:
[/data/code/nordavind](default)% hg branch
default

[~/the_silver_searcher](colors)% git branch
* colors
  master

In my main tcsh rc file I do:
Code:
if ( $uname != win32 && -f ~/.tcsh/cwdcmd.tcsh ) then
    alias cwdcmd source ~/.tcsh/cwdcmd.tcsh
else
    unalias cwdcmd
endif

& the contents of cwdcmd.tcsh:

Code:
# Show the directory in the xterm title
echo -n "\033]2;tcsh: $cwd\007"

# Interferes with running commands
unset printexitvalue

# For sanity
set backslash_quote

# stat would be better/faster, but stat is about as unportable as it gets
alias __pstat 'perl -e \'print((stat($ARGV[0]))[9])\''

# Some games for the sake of efficiency
if ( $?reporoot ) then
    if ( "$cwd" =~ "$reporoot*" ) then
        if ( $repotype == 'git' && $repochanged == `__pstat "$reporoot"/.git/HEAD` ) then
            goto end
        endif
        if ( $repotype == 'hg' && $repochanged == `__pstat "$reporoot"/.hg/branch` ) then
            goto end
        endif
    else
        unset repotype
        unset reporoot
        unset repochanged
    endif
endif

if ( ! $?repotype ) set repotype = ''
# Mercurial
if ( ! $?reporoot || $repotype == 'hg' ) then
    hg branch >& /dev/null
    if ( $? == 0 ) then
        set reporoot = `hg root`
        set repotype = 'hg'
        set repochanged = `__pstat "$reporoot"/.hg/branch`
        set prompt = "[%~](`cat $reporoot/.hg/branch`)%# "

        goto end
    endif
endif


# Git
if ( ! $?reporoot || $repotype == 'git' ) then
    git rev-parse --abbrev-ref HEAD >& /dev/null
    if ( $? == 0 ) then
        set reporoot = `git rev-parse --show-toplevel`
        set repotype = 'git'
        set repochanged = `__pstat "$reporoot"/.git/HEAD`
        set prompt = "[%~](`git rev-parse --abbrev-ref HEAD`)%# "

        goto end
    endif
endif


# We're not in a repo anymore; reset.
set prompt = "[%~]%# "
unset repotype
unset reporoot
unset repochanged


# Cleanup
end:
    set printexitvalue
    unset backslash_quote
    unalias __pstat

It's a bit ugly, and I feel I've really hit the limits on what one can do with tcsh while still preserving once's sanity... But I've been using this for a while, and it works...
Tested on FreeBSD 9 & Ubuntu.[/i][/i]
 
Last edited:
Finally got around to making a working make -V completion:
Code:
  alias __makevars  'make -ndv |& perl -ne '\''print "$1\n" if /^(?:Command|Global|Internal):(\S+?)\s+/;'\'' | sort -u'

  complete make  'C/F/(FORMATS= FORMATS=html FORMATS=html-split FORMATS=pdf)/' \
  'p/1/`make -V .ALLTARGETS`/' \
  'n/-V/`__makevars`/'

Perl could do the sort -u internally to avoid a fork, but the clarity is far better this way.
 
Back
Top