A bash completion script for mpw.

This commit is contained in:
Maarten Billemont 2015-03-12 01:03:02 -04:00
parent f31f7b91ee
commit 1f10109481
3 changed files with 118 additions and 0 deletions

61
bashcomplib Normal file
View file

@ -0,0 +1,61 @@
#!/usr/bin/env bash
# FIXME
# partials are currently readline words, but these can't be reliably compared against literal data. We need to make them literal first.. in a safe way. Currently using xargs' quote parser as a hack.
# Process literal completion options in COMPREPLY
#
# 1. Filter COMPREPLY by excluding the options that do not match the word that is being completed.
# 2. Shell-escape the COMPREPLY words so they remain syntactical words when injected into the completed command.
# 3. Add a space after the words so successful completions advance to the next word
# (we disabled this default behavior with -o nospace so we can do completions that don't want this, eg. directory names)
_comp_finish_completions() {
local partial=$(xargs <<< "${COMP_WORDS[COMP_CWORD]}") # FIXME
local word words=( "${COMPREPLY[@]}" )
COMPREPLY=()
for word in "${words[@]}"; do
( shopt -s nocasematch; [[ $word = $partial* ]] ) && COMPREPLY+=( "$(printf '%q ' "$word")" )
done
if (( ${#COMPREPLY[@]} > 1 )) && [[ $_comp_title ]]; then
printf '\n%s:' "$_comp_title"
unset _comp_title
fi
}
# Perform pathname completion.
#
# 1. Populate COMPREPLY with pathnames.
# 2. Shell-escape the COMPREPLY words so they remain syntactical words when injected into the completed command.
# 3. Add a space after file names so successful completions advance to the next word.
# Directory names are suffixed with a / instead so we can keep completing the files inside.
_comp_complete_path() {
local partial=$(xargs <<< "${COMP_WORDS[COMP_CWORD]}")
local path
COMPREPLY=()
for path in "$partial"*; do
if [[ -d $path ]]; then
COMPREPLY+=( "$(printf '%q/' "$path")" )
elif [[ -e $path ]]; then
COMPREPLY+=( "$(printf '%q ' "$path")" )
fi
done
}
_show_args() {
echo
local i=0
for arg; do
printf "arg %d: %s\n" "$((i++))" "$arg"
done
i=0
for word in "${COMP_WORDS[@]}"; do
printf "word %d: %s -> %s %s\n" "$i" "$word" "$(xargs <<< "$word")" "$( ((i == $COMP_CWORD)) && echo '<CWORD>' )"
let i++
done
}

56
mpw.completion.bash Normal file
View file

@ -0,0 +1,56 @@
#!/usr/bin/env bash
source bashcomplib
# completing the 'mpw' command.
_comp_mpw() {
local optarg= cword=${COMP_WORDS[COMP_CWORD]} pcword
if (( COMP_CWORD > 0 )); then
pcword=${COMP_WORDS[COMP_CWORD - 1]}
case $pcword in
-u) optarg=user ;;
-t) optarg=type ;;
-c) optarg=counter ;;
-V) optarg=version ;;
-v) optarg=variant ;;
-C) optarg=context ;;
esac
fi
case $optarg in
user) # complete full names.
COMPREPLY=( ~/.mpw.d/*.mpsites ) COMPREPLY=( "${COMPREPLY[@]##*/}" ) COMPREPLY=( "${COMPREPLY[@]%.mpsites}" )
;;
type) # complete types.
COMPREPLY=( maximum long medium basic short pin name phrase )
;;
counter) # complete counter.
COMPREPLY=( 1 )
;;
version) # complete versions.
COMPREPLY=( 0 1 2 3 )
;;
variant) # complete variants.
COMPREPLY=( password login answer )
;;
context) # complete context.
;;
*)
# previous word is not an option we can complete, complete site name (or option if leading -)
if [[ $cword = -* ]]; then
COMPREPLY=( -u -t -c -V -v -C )
else
local w fullName=$MP_FULLNAME
for (( w = 0; w < ${#COMP_WORDS[@]}; ++w )); do
[[ ${COMP_WORDS[w]} = -u ]] && fullName=$(xargs <<< "${COMP_WORDS[w + 1]}") && break
done
IFS=$'\n' read -d '' -ra COMPREPLY < <(awk -F$'\t' '!/^ *#/{sub(/^ */, "", $2); print $2}' ~/.mpw.d/"$fullName.mpsites")
printf -v _comp_title 'Sites for %s' "$fullName"
fi ;;
esac
_comp_finish_completions
}
#complete -F _show_args mpw
complete -o nospace -F _comp_mpw mpw

View file

@ -6,6 +6,7 @@
// Copyright (c) 2014 Lyndir. All rights reserved.
//
// NOTE: mpw is currently NOT thread-safe.
#include "mpw-types.h"
typedef enum(unsigned int, MPAlgorithmVersion) {