From 4cbbd121c012b3962f12fdff0f1820c3b8636a44 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 30 Jul 2016 01:17:09 +1200 Subject: Move bash completion setup into separate dir --- bash/bash_completion.d/bash.bash | 38 +++++++++++++++++++++++ bash/bash_completion.d/bd.bash | 22 +++++++++++++ bash/bash_completion.d/ftp.bash | 33 ++++++++++++++++++++ bash/bash_completion.d/git.bash | 27 ++++++++++++++++ bash/bash_completion.d/gpg.bash | 17 ++++++++++ bash/bash_completion.d/keep.bash | 2 ++ bash/bash_completion.d/make.bash | 44 ++++++++++++++++++++++++++ bash/bash_completion.d/man.bash | 63 ++++++++++++++++++++++++++++++++++++++ bash/bash_completion.d/mkcd.bash | 1 + bash/bash_completion.d/mysql.bash | 34 ++++++++++++++++++++ bash/bash_completion.d/pass.bash | 39 +++++++++++++++++++++++ bash/bash_completion.d/path.bash | 60 ++++++++++++++++++++++++++++++++++++ bash/bash_completion.d/prompt.bash | 2 ++ bash/bash_completion.d/sd.bash | 39 +++++++++++++++++++++++ bash/bash_completion.d/ssh.bash | 22 +++++++++++++ bash/bash_completion.d/td.bash | 18 +++++++++++ bash/bash_completion.d/ud.bash | 28 +++++++++++++++++ bash/bash_completion.d/vared.bash | 1 + bash/bash_completion.d/vis.bash | 22 +++++++++++++ bash/bash_completion.d/vr.bash | 1 + bash/bashrc | 10 ++++++ bash/bashrc.d/bd.bash | 23 -------------- bash/bashrc.d/cf.bash | 1 - bash/bashrc.d/completion.bash | 38 ----------------------- bash/bashrc.d/ftp.bash | 33 -------------------- bash/bashrc.d/git.bash | 27 ---------------- bash/bashrc.d/gpg.bash | 18 ----------- bash/bashrc.d/keep.bash | 3 -- bash/bashrc.d/make.bash | 44 -------------------------- bash/bashrc.d/man.bash | 63 -------------------------------------- bash/bashrc.d/mkcd.bash | 1 - bash/bashrc.d/mysql.bash | 35 --------------------- bash/bashrc.d/pass.bash | 39 ----------------------- bash/bashrc.d/path.bash | 61 ------------------------------------ bash/bashrc.d/prompt.bash | 3 -- bash/bashrc.d/sd.bash | 42 +------------------------ bash/bashrc.d/ssh.bash | 22 ------------- bash/bashrc.d/td.bash | 18 ----------- bash/bashrc.d/ud.bash | 29 ------------------ bash/bashrc.d/vared.bash | 1 - bash/bashrc.d/vis.bash | 22 ------------- bash/bashrc.d/vr.bash | 1 - 42 files changed, 524 insertions(+), 523 deletions(-) create mode 100644 bash/bash_completion.d/bash.bash create mode 100644 bash/bash_completion.d/bd.bash create mode 100644 bash/bash_completion.d/ftp.bash create mode 100644 bash/bash_completion.d/git.bash create mode 100644 bash/bash_completion.d/gpg.bash create mode 100644 bash/bash_completion.d/keep.bash create mode 100644 bash/bash_completion.d/make.bash create mode 100644 bash/bash_completion.d/man.bash create mode 100644 bash/bash_completion.d/mkcd.bash create mode 100644 bash/bash_completion.d/mysql.bash create mode 100644 bash/bash_completion.d/pass.bash create mode 100644 bash/bash_completion.d/path.bash create mode 100644 bash/bash_completion.d/prompt.bash create mode 100644 bash/bash_completion.d/sd.bash create mode 100644 bash/bash_completion.d/ssh.bash create mode 100644 bash/bash_completion.d/td.bash create mode 100644 bash/bash_completion.d/ud.bash create mode 100644 bash/bash_completion.d/vared.bash create mode 100644 bash/bash_completion.d/vis.bash create mode 100644 bash/bash_completion.d/vr.bash delete mode 100644 bash/bashrc.d/completion.bash delete mode 100644 bash/bashrc.d/ftp.bash delete mode 100644 bash/bashrc.d/git.bash delete mode 100644 bash/bashrc.d/make.bash delete mode 100644 bash/bashrc.d/man.bash delete mode 100644 bash/bashrc.d/pass.bash delete mode 100644 bash/bashrc.d/ssh.bash delete mode 100644 bash/bashrc.d/td.bash delete mode 100644 bash/bashrc.d/vis.bash (limited to 'bash') diff --git a/bash/bash_completion.d/bash.bash b/bash/bash_completion.d/bash.bash new file mode 100644 index 00000000..5d944b9b --- /dev/null +++ b/bash/bash_completion.d/bash.bash @@ -0,0 +1,38 @@ +# Various easy completions + +# Bash builtins +complete -A builtin builtin + +# Bash options +complete -A setopt set + +# Commands +complete -A command command complete coproc exec hash type + +# Directories +complete -A directory cd pushd mkdir rmdir + +# Functions +complete -A function function + +# Help topics +complete -A helptopic help + +# Jobspecs +complete -A job disown fg jobs +complete -A stopped bg + +# Readline bindings +complete -A binding bind + +# Shell options +complete -A shopt shopt + +# Signal names +complete -A signal trap + +# Variables +complete -A variable declare export readonly typeset + +# Both functions and variables +complete -A function -A variable unset diff --git a/bash/bash_completion.d/bd.bash b/bash/bash_completion.d/bd.bash new file mode 100644 index 00000000..68589dff --- /dev/null +++ b/bash/bash_completion.d/bd.bash @@ -0,0 +1,22 @@ +# Completion setup for bd +_bd() { + + # Only makes sense for the first argument + ((COMP_CWORD == 1)) || return 1 + + # Build a list of dirnames in $PWD + local -a dirnames + IFS=/ read -d '' -a dirnames < <(printf '%s\0' "${PWD#/}") + + # Remove the last element in the array (the current directory) + ((${#dirnames[@]})) || return 1 + dirnames=("${dirnames[@]:0:"$((${#dirnames[@]}-1))"}") + + # Add the matching dirnames to the reply + local dirname + for dirname in "${dirnames[@]}" ; do + [[ $dirname == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue + COMPREPLY=("${COMPREPLY[@]}" "$(printf %q "$dirname")") + done +} +complete -F _bd bd diff --git a/bash/bash_completion.d/ftp.bash b/bash/bash_completion.d/ftp.bash new file mode 100644 index 00000000..5770f137 --- /dev/null +++ b/bash/bash_completion.d/ftp.bash @@ -0,0 +1,33 @@ +# Completion for ftp with .netrc machines +_ftp() { + + # Bail if the .netrc file is illegible + local netrc + netrc=$HOME/.netrc + [[ -r $netrc ]] || return 1 + + # Tokenize the file + local -a tokens + read -a tokens -d '' -r < "$netrc" + + # Iterate through tokens and collect machine names + local -a machines + local -i nxm + local token + for token in "${tokens[@]}" ; do + if ((nxm)) ; then + machines[${#machines[@]}]=$token + nxm=0 + elif [[ $token == machine ]] ; then + nxm=1 + fi + done + + # Generate completion reply + local machine + for machine in "${machines[@]}" ; do + [[ $machine == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$machine + done +} +complete -F _ftp -o default ftp diff --git a/bash/bash_completion.d/git.bash b/bash/bash_completion.d/git.bash new file mode 100644 index 00000000..496712ae --- /dev/null +++ b/bash/bash_completion.d/git.bash @@ -0,0 +1,27 @@ +# Completion for git local branch names +_git() { + + # Bail if not a git repo (or no git!) + git rev-parse --git-dir >/dev/null 2>&1 || return 1 + + # Switch on the previous word + case ${COMP_WORDS[1]} in + + # If the first word is appropriate, complete with branch/tag names + checkout|merge|rebase) + local branch + while read -r _ _ branch ; do + branch=${branch##*/} + [[ $branch == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$branch + done < <(git for-each-ref refs/heads refs/tags 2>/dev/null) + return + ;; + + # Bail if it isn't + *) + return 1 + ;; + esac +} +complete -F _git -o default git diff --git a/bash/bash_completion.d/gpg.bash b/bash/bash_completion.d/gpg.bash new file mode 100644 index 00000000..c2f08415 --- /dev/null +++ b/bash/bash_completion.d/gpg.bash @@ -0,0 +1,17 @@ +# Completion for gpg with long options +_gpg() { + + # Bail if no gpg(1) + hash gpg 2>/dev/null || return 1 + + # Bail if not completing an option + [[ ${COMP_WORDS[COMP_CWORD]} == --* ]] || return 1 + + # Generate completion reply from gpg(1) options + local option + while read -r option ; do + [[ $option == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$option + done < <(gpg --dump-options 2>/dev/null) +} +complete -F _gpg -o default gpg diff --git a/bash/bash_completion.d/keep.bash b/bash/bash_completion.d/keep.bash new file mode 100644 index 00000000..bfe5dd2f --- /dev/null +++ b/bash/bash_completion.d/keep.bash @@ -0,0 +1,2 @@ +# Complete calls to keep with existing function names and variable names +complete -A function -A variable keep diff --git a/bash/bash_completion.d/make.bash b/bash/bash_completion.d/make.bash new file mode 100644 index 00000000..ca209e8e --- /dev/null +++ b/bash/bash_completion.d/make.bash @@ -0,0 +1,44 @@ +# Completion setup for Make, completing targets +_make() { + + # Bail if no legible Makefile + [[ -r Makefile ]] || return 1 + + # Iterate through the Makefile, line by line + while IFS= read -r line ; do + case $line in + + # We're looking for targets but not variable assignments + $'\t'*) ;; + *:=*) ;; + *:*) + + # Break the target up with space delimiters + local -a targets + IFS=' ' read -a targets -d '' < \ + <(printf '%s\0' "${line%%:*}") + + # Iterate through the targets and add suitable ones + local target + for target in "${targets[@]}" ; do + case $target in + + # Don't complete special targets beginning with a + # period + .*) ;; + + # Don't complete targets with names that have + # characters outside of the POSIX spec (plus slashes) + *[^[:word:]./-]*) ;; + + # Add targets that match what we're completing + ${COMP_WORDS[COMP_CWORD]}*) + COMPREPLY[${#COMPREPLY[@]}]=$target + ;; + esac + done + ;; + esac + done < Makefile +} +complete -F _make -o default make diff --git a/bash/bash_completion.d/man.bash b/bash/bash_completion.d/man.bash new file mode 100644 index 00000000..f1762a01 --- /dev/null +++ b/bash/bash_completion.d/man.bash @@ -0,0 +1,63 @@ +# Autocompletion for man(1) +_man() { + + # Don't even bother if we don't have manpath(1) + hash manpath || return 1 + + # Snarf the word + local word + word=${COMP_WORDS[COMP_CWORD]} + + # If this is the second word, and the previous word started with a number, + # we'll assume that's the section to search + local section subdir + if ((COMP_CWORD > 1)) && [[ ${COMP_WORDS[COMP_CWORD-1]} == [0-9]* ]] ; then + section=${COMP_WORDS[COMP_CWORD-1]} + subdir=man${section%%[^0-9]*} + fi + + # Read completion results from a subshell and add them to the COMPREPLY + # array individually + while IFS= read -rd '' page ; do + COMPREPLY[${#COMPREPLY[@]}]=$page + done < <( + + # Do not return dotfiles, give us extended globbing, and expand empty + # globs to just nothing + shopt -u dotglob + shopt -s extglob nullglob + + # Start an array of pages + declare -a pages + + # Break manpath(1) output into an array of paths + IFS=: read -a manpaths -r < <(manpath 2>/dev/null) + + # Iterate through the manual page paths and add every manual page we find + for manpath in "${manpaths[@]}" ; do + [[ $manpath ]] || continue + if [[ $section ]] ; then + for page in "$manpath"/"$subdir"/"$word"*."$section"?(.[glx]z|.bz2|.lzma|.Z) ; do + pages[${#pages[@]}]=$page + done + else + for page in "$manpath"/man[0-9]*/"$word"*.* ; do + pages[${#pages[@]}]=$page + done + fi + done + + # Strip paths, .gz suffixes, and finally .
suffixes + pages=("${pages[@]##*/}") + pages=("${pages[@]%.@([glx]z|bz2|lzma|Z)}") + pages=("${pages[@]%.[0-9]*}") + + # Bail out if we ended up with no pages somehow to prevent us from + # printing + ((${#pages[@]})) || exit 1 + + # Print the pages array to stdout, quoted and null-delimited + printf '%q\0' "${pages[@]}" + ) +} +complete -F _man -o default man diff --git a/bash/bash_completion.d/mkcd.bash b/bash/bash_completion.d/mkcd.bash new file mode 100644 index 00000000..0db967d8 --- /dev/null +++ b/bash/bash_completion.d/mkcd.bash @@ -0,0 +1 @@ +complete -A directory mkcd diff --git a/bash/bash_completion.d/mysql.bash b/bash/bash_completion.d/mysql.bash new file mode 100644 index 00000000..f64b6f32 --- /dev/null +++ b/bash/bash_completion.d/mysql.bash @@ -0,0 +1,34 @@ +# Completion setup for MySQL for configured databases +_mysql() { + + # Only makes sense for first argument + ((COMP_CWORD == 1)) || return 1 + + # Bail if directory doesn't exist + local dirname + dirname=$HOME/.mysql + [[ -d $dirname ]] || return 1 + + # Return the names of the .cnf files sans prefix as completions + local db + while IFS= read -rd '' db ; do + COMPREPLY[${#COMPREPLY[@]}]=$db + done < <( + + # Set options so that globs expand correctly + shopt -s dotglob nullglob + + # Collect all the config file names, strip off leading path and .cnf + local -a cnfs + cnfs=("$dirname"/"${COMP_WORDS[COMP_CWORD]}"*.cnf) + cnfs=("${cnfs[@]#"$dirname"/}") + cnfs=("${cnfs[@]%.cnf}") + + # Bail if no files to prevent empty output + ((${#cnfs[@]})) || exit 1 + + # Print the conf names, null-delimited + printf '%q\0' "${cnfs[@]}" + ) +} +complete -F _mysql -o default mysql diff --git a/bash/bash_completion.d/pass.bash b/bash/bash_completion.d/pass.bash new file mode 100644 index 00000000..28941952 --- /dev/null +++ b/bash/bash_completion.d/pass.bash @@ -0,0 +1,39 @@ +# Requires Bash >= 4.0 for globstar +((BASH_VERSINFO[0] >= 4)) || return + +# Custom completion for pass(1), because I don't like the one included with the +# distribution +_pass() +{ + # If we can't read the password directory, just bail + local passdir + passdir=${PASSWORD_STORE_DIR:-"$HOME"/.password-store} + [[ -r $passdir ]] || return 1 + + # Iterate through list of .gpg paths, extension stripped, null-delimited, + # and filter them down to the ones matching the completing word (compgen + # doesn't seem to do this properly with a null delimiter) + local entry + while IFS= read -rd '' entry ; do + COMPREPLY[${#COMPREPLY[@]}]=$entry + done < <( + + # Set shell options to expand globs the way we expect + shopt -u dotglob + shopt -s globstar nullglob + + # Gather the entries and remove their .gpg suffix + declare -a entries + entries=("$passdir"/"${COMP_WORDS[COMP_CWORD]}"*/**/*.gpg \ + "$passdir"/"${COMP_WORDS[COMP_CWORD]}"*.gpg) + entries=("${entries[@]#"$passdir"/}") + entries=("${entries[@]%.gpg}") + + # Bail if no entries to prevent empty output + ((${#entries[@]})) || exit 1 + + # Print all the entries, null-delimited + printf '%q\0' "${entries[@]}" + ) +} +complete -F _pass pass diff --git a/bash/bash_completion.d/path.bash b/bash/bash_completion.d/path.bash new file mode 100644 index 00000000..fd94b7c4 --- /dev/null +++ b/bash/bash_completion.d/path.bash @@ -0,0 +1,60 @@ +# Completion for path +_path() { + + # What to do depends on which word we're completing + if ((COMP_CWORD == 1)) ; then + + # Complete operation as first word + local cmd + for cmd in help list insert append remove set check ; do + [[ $cmd == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$cmd + done + + # Complete with either directories or $PATH entries as all other words + else + case ${COMP_WORDS[1]} in + + # Complete with a directory + insert|i|append|add|a|check|c|set|s) + local dirname + while IFS= read -rd '' dirname ; do + COMPREPLY[${#COMPREPLY[@]}]=$dirname + done < <( + + # Set options to glob correctly + shopt -s dotglob nullglob + + # Collect directory names, strip trailing slash + local -a dirnames + dirnames=("${COMP_WORDS[COMP_CWORD]}"*/) + dirnames=("${dirnames[@]%/}") + + # Bail if no results to prevent empty output + ((${#dirnames[@]})) || exit 1 + + # Print results, quoted and null-delimited + printf '%q\0' "${dirnames[@]}" + ) + ;; + + # Complete with directories from PATH + remove|rm|r) + local -a promptarr + IFS=: read -d '' -a promptarr < <(printf '%s\0' "$PATH") + local part + for part in "${promptarr[@]}" ; do + [[ $part == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$(printf '%q\0' "$part") + done + ;; + + # No completion + *) + return 1 + ;; + esac + fi +} + +complete -F _path path diff --git a/bash/bash_completion.d/prompt.bash b/bash/bash_completion.d/prompt.bash new file mode 100644 index 00000000..b114b7bb --- /dev/null +++ b/bash/bash_completion.d/prompt.bash @@ -0,0 +1,2 @@ +# Complete words +complete -W 'on off git hg svn vcs ret job' prompt diff --git a/bash/bash_completion.d/sd.bash b/bash/bash_completion.d/sd.bash new file mode 100644 index 00000000..f8017591 --- /dev/null +++ b/bash/bash_completion.d/sd.bash @@ -0,0 +1,39 @@ +# Completion function for sd; any sibling directories, excluding the self +_sd() { + + # Only makes sense for the first argument + ((COMP_CWORD == 1)) || return 1 + + # Current directory can't be root directory + [[ $PWD != / ]] || return 1 + + # Build list of matching sibiling directories + while IFS= read -rd '' dirname ; do + COMPREPLY[${#COMPREPLY[@]}]=$dirname + done < <( + + # Set options to glob correctly + shopt -s dotglob nullglob + + # Collect directory names, strip leading ../ and trailing / + local -a dirnames + dirnames=(../"${COMP_WORDS[COMP_CWORD]}"*/) + dirnames=("${dirnames[@]#../}") + dirnames=("${dirnames[@]%/}") + + # Iterate again, but exclude the current directory this time + local -a sibs + local dirname + for dirname in "${dirnames[@]}" ; do + [[ $dirname != "${PWD##*/}" ]] || continue + sibs[${#sibs[@]}]=$dirname + done + + # Bail if no results to prevent empty output + ((${#sibs[@]})) || exit 1 + + # Print results, null-delimited + printf '%q\0' "${sibs[@]}" + ) +} +complete -F _sd sd diff --git a/bash/bash_completion.d/ssh.bash b/bash/bash_completion.d/ssh.bash new file mode 100644 index 00000000..bbb9b246 --- /dev/null +++ b/bash/bash_completion.d/ssh.bash @@ -0,0 +1,22 @@ +# Completion for ssh/sftp/ssh-copy-id with config hostnames +_ssh() { + + # Read hostnames from existent config files, no asterisks + local -a hosts + local config option value + for config in "$HOME"/.ssh/config /etc/ssh/ssh_config ; do + [[ -e $config ]] || continue + while read -r option value _ ; do + [[ $option == Host ]] || continue + [[ $value != *'*'* ]] || continue + hosts[${#hosts[@]}]=$value + done < "$config" + done + + # Generate completion reply + for host in "${hosts[@]}" ; do + [[ $host == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$host + done +} +complete -F _ssh -o default ssh sftp ssh-copy-id diff --git a/bash/bash_completion.d/td.bash b/bash/bash_completion.d/td.bash new file mode 100644 index 00000000..ffb9c973 --- /dev/null +++ b/bash/bash_completion.d/td.bash @@ -0,0 +1,18 @@ +# Complete filenames for td(1) +_td() { + local dir + dir=${TODO_DIR:-"$HOME"/Todo} + while IFS= read -rd '' fn ; do + COMPREPLY[${#COMPREPLY[@]}]=$fn + done < <( + shopt -s extglob nullglob + shopt -u dotglob + local -a fns + fns=("$dir"/"${COMP_WORDS[COMP_CWORD]}"*) + fns=("${fns[@]#"$dir"/}") + ((${#fns[@]})) || exit 1 + printf '%s\0' "${fns[@]##"$dir"/}" + ) + return +} +complete -F _td td diff --git a/bash/bash_completion.d/ud.bash b/bash/bash_completion.d/ud.bash new file mode 100644 index 00000000..47171b78 --- /dev/null +++ b/bash/bash_completion.d/ud.bash @@ -0,0 +1,28 @@ +# Completion setup for ud +_ud() { + + # Only makes sense for the second argument + ((COMP_CWORD == 2)) || return 1 + + # Iterate through directories, null-separated, add them to completions + local dirname + while IFS= read -rd '' dirname ; do + COMPREPLY[${#COMPREPLY[@]}]=$dirname + done < <( + + # Set options to glob correctly + shopt -s dotglob nullglob + + # Collect directory names, strip trailing slashes + local -a dirnames + dirnames=("${COMP_WORDS[COMP_CWORD]}"*/) + dirnames=("${dirnames[@]%/}") + + # Bail if no results to prevent empty output + ((${#dirnames[@]})) || exit 1 + + # Print results null-delimited + printf '%s\0' "${dirnames[@]}" + ) +} +complete -F _ud -o filenames ud diff --git a/bash/bash_completion.d/vared.bash b/bash/bash_completion.d/vared.bash new file mode 100644 index 00000000..ea8cefd1 --- /dev/null +++ b/bash/bash_completion.d/vared.bash @@ -0,0 +1 @@ +complete -A variable vared diff --git a/bash/bash_completion.d/vis.bash b/bash/bash_completion.d/vis.bash new file mode 100644 index 00000000..f84cb702 --- /dev/null +++ b/bash/bash_completion.d/vis.bash @@ -0,0 +1,22 @@ +# Complete args to vis(1) with existing executables in $VISPATH, defaulting to +# ~/.local/bin +_vis() { + local vispath + vispath=${VISPATH:-"$HOME"/.local/bin} + [[ -d $vispath ]] || return + while IFS= read -rd '' executable ; do + COMPREPLY[${#COMPREPLY[@]}]=$executable + done < <( + shopt -s dotglob nullglob + declare -a files + files=("${VISPATH:-"$HOME"/.local/bin}"/"${COMP_WORDS[COMP_CWORD]}"*) + declare -a executables + for file in "${files[@]}" ; do + [[ -f $file && -x $file ]] || continue + executables[${#executables[@]}]=${file##*/} + done + ((${#executables[@]})) || exit 1 + printf '%q\0' "${executables[@]}" + ) +} +complete -F _vis vis diff --git a/bash/bash_completion.d/vr.bash b/bash/bash_completion.d/vr.bash new file mode 100644 index 00000000..2d5120f0 --- /dev/null +++ b/bash/bash_completion.d/vr.bash @@ -0,0 +1 @@ +complete -A directory vr diff --git a/bash/bashrc b/bash/bashrc index facdd7eb..7338b64c 100644 --- a/bash/bashrc +++ b/bash/bashrc @@ -114,3 +114,13 @@ if [[ -d $HOME/.bashrc.d ]] ; then done unset -v bashrc fi + +# Load any completion files +if [[ -d $HOME/.bash_completion.d ]] ; then + for bashcmp in "$HOME"/.bash_completion.d/*.bash ; do + if [[ -e $bashcmp ]] ; then + source "$bashcmp" + fi + done + unset -v bashcmp +fi diff --git a/bash/bashrc.d/bd.bash b/bash/bashrc.d/bd.bash index b7fbe77e..23a2d380 100644 --- a/bash/bashrc.d/bd.bash +++ b/bash/bashrc.d/bd.bash @@ -76,26 +76,3 @@ bd() { # Try to change into the determined directory builtin cd "${opts[@]}" -- "$dirname" } - -# Completion setup for bd -_bd() { - - # Only makes sense for the first argument - ((COMP_CWORD == 1)) || return 1 - - # Build a list of dirnames in $PWD - local -a dirnames - IFS=/ read -d '' -a dirnames < <(printf '%s\0' "${PWD#/}") - - # Remove the last element in the array (the current directory) - ((${#dirnames[@]})) || return 1 - dirnames=("${dirnames[@]:0:"$((${#dirnames[@]}-1))"}") - - # Add the matching dirnames to the reply - local dirname - for dirname in "${dirnames[@]}" ; do - [[ $dirname == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue - COMPREPLY=("${COMPREPLY[@]}" "$(printf %q "$dirname")") - done -} -complete -F _bd bd diff --git a/bash/bashrc.d/cf.bash b/bash/bashrc.d/cf.bash index 9d6db7dd..50308fa3 100644 --- a/bash/bashrc.d/cf.bash +++ b/bash/bashrc.d/cf.bash @@ -27,4 +27,3 @@ cf() { printf '%u\t%s\n' "${#files[@]}" "$dirname" ) } -complete -A directory cf diff --git a/bash/bashrc.d/completion.bash b/bash/bashrc.d/completion.bash deleted file mode 100644 index 5d944b9b..00000000 --- a/bash/bashrc.d/completion.bash +++ /dev/null @@ -1,38 +0,0 @@ -# Various easy completions - -# Bash builtins -complete -A builtin builtin - -# Bash options -complete -A setopt set - -# Commands -complete -A command command complete coproc exec hash type - -# Directories -complete -A directory cd pushd mkdir rmdir - -# Functions -complete -A function function - -# Help topics -complete -A helptopic help - -# Jobspecs -complete -A job disown fg jobs -complete -A stopped bg - -# Readline bindings -complete -A binding bind - -# Shell options -complete -A shopt shopt - -# Signal names -complete -A signal trap - -# Variables -complete -A variable declare export readonly typeset - -# Both functions and variables -complete -A function -A variable unset diff --git a/bash/bashrc.d/ftp.bash b/bash/bashrc.d/ftp.bash deleted file mode 100644 index 5770f137..00000000 --- a/bash/bashrc.d/ftp.bash +++ /dev/null @@ -1,33 +0,0 @@ -# Completion for ftp with .netrc machines -_ftp() { - - # Bail if the .netrc file is illegible - local netrc - netrc=$HOME/.netrc - [[ -r $netrc ]] || return 1 - - # Tokenize the file - local -a tokens - read -a tokens -d '' -r < "$netrc" - - # Iterate through tokens and collect machine names - local -a machines - local -i nxm - local token - for token in "${tokens[@]}" ; do - if ((nxm)) ; then - machines[${#machines[@]}]=$token - nxm=0 - elif [[ $token == machine ]] ; then - nxm=1 - fi - done - - # Generate completion reply - local machine - for machine in "${machines[@]}" ; do - [[ $machine == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$machine - done -} -complete -F _ftp -o default ftp diff --git a/bash/bashrc.d/git.bash b/bash/bashrc.d/git.bash deleted file mode 100644 index 496712ae..00000000 --- a/bash/bashrc.d/git.bash +++ /dev/null @@ -1,27 +0,0 @@ -# Completion for git local branch names -_git() { - - # Bail if not a git repo (or no git!) - git rev-parse --git-dir >/dev/null 2>&1 || return 1 - - # Switch on the previous word - case ${COMP_WORDS[1]} in - - # If the first word is appropriate, complete with branch/tag names - checkout|merge|rebase) - local branch - while read -r _ _ branch ; do - branch=${branch##*/} - [[ $branch == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$branch - done < <(git for-each-ref refs/heads refs/tags 2>/dev/null) - return - ;; - - # Bail if it isn't - *) - return 1 - ;; - esac -} -complete -F _git -o default git diff --git a/bash/bashrc.d/gpg.bash b/bash/bashrc.d/gpg.bash index 28c5b722..62d123ea 100644 --- a/bash/bashrc.d/gpg.bash +++ b/bash/bashrc.d/gpg.bash @@ -8,21 +8,3 @@ gpg() { esac command gpg "$@" } - -# Completion for gpg with long options -_gpg() { - - # Bail if no gpg(1) - hash gpg 2>/dev/null || return 1 - - # Bail if not completing an option - [[ ${COMP_WORDS[COMP_CWORD]} == --* ]] || return 1 - - # Generate completion reply from gpg(1) options - local option - while read -r option ; do - [[ $option == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$option - done < <(gpg --dump-options 2>/dev/null) -} -complete -F _gpg -o default gpg diff --git a/bash/bashrc.d/keep.bash b/bash/bashrc.d/keep.bash index 585dd189..b1c8bea4 100644 --- a/bash/bashrc.d/keep.bash +++ b/bash/bashrc.d/keep.bash @@ -144,9 +144,6 @@ EOF ) } -# Complete calls to keep with existing function names and variable names -complete -A function -A variable keep - # Load any existing scripts in bashkeep if [[ -d ${BASHKEEP:-"$HOME"/.bashkeep.d} ]] ; then for bashkeep in "${BASHKEEP:-"$HOME"/.bashkeep.d}"/*.bash ; do diff --git a/bash/bashrc.d/make.bash b/bash/bashrc.d/make.bash deleted file mode 100644 index ca209e8e..00000000 --- a/bash/bashrc.d/make.bash +++ /dev/null @@ -1,44 +0,0 @@ -# Completion setup for Make, completing targets -_make() { - - # Bail if no legible Makefile - [[ -r Makefile ]] || return 1 - - # Iterate through the Makefile, line by line - while IFS= read -r line ; do - case $line in - - # We're looking for targets but not variable assignments - $'\t'*) ;; - *:=*) ;; - *:*) - - # Break the target up with space delimiters - local -a targets - IFS=' ' read -a targets -d '' < \ - <(printf '%s\0' "${line%%:*}") - - # Iterate through the targets and add suitable ones - local target - for target in "${targets[@]}" ; do - case $target in - - # Don't complete special targets beginning with a - # period - .*) ;; - - # Don't complete targets with names that have - # characters outside of the POSIX spec (plus slashes) - *[^[:word:]./-]*) ;; - - # Add targets that match what we're completing - ${COMP_WORDS[COMP_CWORD]}*) - COMPREPLY[${#COMPREPLY[@]}]=$target - ;; - esac - done - ;; - esac - done < Makefile -} -complete -F _make -o default make diff --git a/bash/bashrc.d/man.bash b/bash/bashrc.d/man.bash deleted file mode 100644 index f1762a01..00000000 --- a/bash/bashrc.d/man.bash +++ /dev/null @@ -1,63 +0,0 @@ -# Autocompletion for man(1) -_man() { - - # Don't even bother if we don't have manpath(1) - hash manpath || return 1 - - # Snarf the word - local word - word=${COMP_WORDS[COMP_CWORD]} - - # If this is the second word, and the previous word started with a number, - # we'll assume that's the section to search - local section subdir - if ((COMP_CWORD > 1)) && [[ ${COMP_WORDS[COMP_CWORD-1]} == [0-9]* ]] ; then - section=${COMP_WORDS[COMP_CWORD-1]} - subdir=man${section%%[^0-9]*} - fi - - # Read completion results from a subshell and add them to the COMPREPLY - # array individually - while IFS= read -rd '' page ; do - COMPREPLY[${#COMPREPLY[@]}]=$page - done < <( - - # Do not return dotfiles, give us extended globbing, and expand empty - # globs to just nothing - shopt -u dotglob - shopt -s extglob nullglob - - # Start an array of pages - declare -a pages - - # Break manpath(1) output into an array of paths - IFS=: read -a manpaths -r < <(manpath 2>/dev/null) - - # Iterate through the manual page paths and add every manual page we find - for manpath in "${manpaths[@]}" ; do - [[ $manpath ]] || continue - if [[ $section ]] ; then - for page in "$manpath"/"$subdir"/"$word"*."$section"?(.[glx]z|.bz2|.lzma|.Z) ; do - pages[${#pages[@]}]=$page - done - else - for page in "$manpath"/man[0-9]*/"$word"*.* ; do - pages[${#pages[@]}]=$page - done - fi - done - - # Strip paths, .gz suffixes, and finally .
suffixes - pages=("${pages[@]##*/}") - pages=("${pages[@]%.@([glx]z|bz2|lzma|Z)}") - pages=("${pages[@]%.[0-9]*}") - - # Bail out if we ended up with no pages somehow to prevent us from - # printing - ((${#pages[@]})) || exit 1 - - # Print the pages array to stdout, quoted and null-delimited - printf '%q\0' "${pages[@]}" - ) -} -complete -F _man -o default man diff --git a/bash/bashrc.d/mkcd.bash b/bash/bashrc.d/mkcd.bash index 2d596641..6342d4a6 100644 --- a/bash/bashrc.d/mkcd.bash +++ b/bash/bashrc.d/mkcd.bash @@ -2,4 +2,3 @@ mkcd() { mkdir -p -- "$1" && builtin cd -- "$1" } -complete -A directory mkcd diff --git a/bash/bashrc.d/mysql.bash b/bash/bashrc.d/mysql.bash index dd9ffe73..0d5ddb86 100644 --- a/bash/bashrc.d/mysql.bash +++ b/bash/bashrc.d/mysql.bash @@ -19,38 +19,3 @@ mysql() { fi command mysql "$@" } - -# Completion setup for MySQL for configured databases -_mysql() { - - # Only makes sense for first argument - ((COMP_CWORD == 1)) || return 1 - - # Bail if directory doesn't exist - local dirname - dirname=$HOME/.mysql - [[ -d $dirname ]] || return 1 - - # Return the names of the .cnf files sans prefix as completions - local db - while IFS= read -rd '' db ; do - COMPREPLY[${#COMPREPLY[@]}]=$db - done < <( - - # Set options so that globs expand correctly - shopt -s dotglob nullglob - - # Collect all the config file names, strip off leading path and .cnf - local -a cnfs - cnfs=("$dirname"/"${COMP_WORDS[COMP_CWORD]}"*.cnf) - cnfs=("${cnfs[@]#"$dirname"/}") - cnfs=("${cnfs[@]%.cnf}") - - # Bail if no files to prevent empty output - ((${#cnfs[@]})) || exit 1 - - # Print the conf names, null-delimited - printf '%q\0' "${cnfs[@]}" - ) -} -complete -F _mysql -o default mysql diff --git a/bash/bashrc.d/pass.bash b/bash/bashrc.d/pass.bash deleted file mode 100644 index 28941952..00000000 --- a/bash/bashrc.d/pass.bash +++ /dev/null @@ -1,39 +0,0 @@ -# Requires Bash >= 4.0 for globstar -((BASH_VERSINFO[0] >= 4)) || return - -# Custom completion for pass(1), because I don't like the one included with the -# distribution -_pass() -{ - # If we can't read the password directory, just bail - local passdir - passdir=${PASSWORD_STORE_DIR:-"$HOME"/.password-store} - [[ -r $passdir ]] || return 1 - - # Iterate through list of .gpg paths, extension stripped, null-delimited, - # and filter them down to the ones matching the completing word (compgen - # doesn't seem to do this properly with a null delimiter) - local entry - while IFS= read -rd '' entry ; do - COMPREPLY[${#COMPREPLY[@]}]=$entry - done < <( - - # Set shell options to expand globs the way we expect - shopt -u dotglob - shopt -s globstar nullglob - - # Gather the entries and remove their .gpg suffix - declare -a entries - entries=("$passdir"/"${COMP_WORDS[COMP_CWORD]}"*/**/*.gpg \ - "$passdir"/"${COMP_WORDS[COMP_CWORD]}"*.gpg) - entries=("${entries[@]#"$passdir"/}") - entries=("${entries[@]%.gpg}") - - # Bail if no entries to prevent empty output - ((${#entries[@]})) || exit 1 - - # Print all the entries, null-delimited - printf '%q\0' "${entries[@]}" - ) -} -complete -F _pass pass diff --git a/bash/bashrc.d/path.bash b/bash/bashrc.d/path.bash index e16e6a4a..61bf73c0 100644 --- a/bash/bashrc.d/path.bash +++ b/bash/bashrc.d/path.bash @@ -178,64 +178,3 @@ EOF ;; esac } - -# Completion for path -_path() { - - # What to do depends on which word we're completing - if ((COMP_CWORD == 1)) ; then - - # Complete operation as first word - local cmd - for cmd in help list insert append remove set check ; do - [[ $cmd == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$cmd - done - - # Complete with either directories or $PATH entries as all other words - else - case ${COMP_WORDS[1]} in - - # Complete with a directory - insert|i|append|add|a|check|c|set|s) - local dirname - while IFS= read -rd '' dirname ; do - COMPREPLY[${#COMPREPLY[@]}]=$dirname - done < <( - - # Set options to glob correctly - shopt -s dotglob nullglob - - # Collect directory names, strip trailing slash - local -a dirnames - dirnames=("${COMP_WORDS[COMP_CWORD]}"*/) - dirnames=("${dirnames[@]%/}") - - # Bail if no results to prevent empty output - ((${#dirnames[@]})) || exit 1 - - # Print results, quoted and null-delimited - printf '%q\0' "${dirnames[@]}" - ) - ;; - - # Complete with directories from PATH - remove|rm|r) - local -a promptarr - IFS=: read -d '' -a promptarr < <(printf '%s\0' "$PATH") - local part - for part in "${promptarr[@]}" ; do - [[ $part == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$(printf '%q\0' "$part") - done - ;; - - # No completion - *) - return 1 - ;; - esac - fi -} - -complete -F _path path diff --git a/bash/bashrc.d/prompt.bash b/bash/bashrc.d/prompt.bash index b6847a92..bef80733 100644 --- a/bash/bashrc.d/prompt.bash +++ b/bash/bashrc.d/prompt.bash @@ -280,8 +280,5 @@ prompt() { esac } -# Complete words -complete -W 'on off git hg svn vcs ret job' prompt - # Start with full-fledged prompt prompt on diff --git a/bash/bashrc.d/sd.bash b/bash/bashrc.d/sd.bash index 9d1063d6..ad4a0deb 100644 --- a/bash/bashrc.d/sd.bash +++ b/bash/bashrc.d/sd.bash @@ -30,7 +30,7 @@ # $ pwd # /tmp/tmp.ZSunna5Eup/a # -# Seems to work for symbolic links. Completion included. +# Seems to work for symbolic links. # sd() { @@ -107,43 +107,3 @@ sd() { # Try to change into the determined directory builtin cd "${opts[@]}" ../"$dirname" } - -# Completion function for sd; any sibling directories, excluding the self -_sd() { - - # Only makes sense for the first argument - ((COMP_CWORD == 1)) || return 1 - - # Current directory can't be root directory - [[ $PWD != / ]] || return 1 - - # Build list of matching sibiling directories - while IFS= read -rd '' dirname ; do - COMPREPLY[${#COMPREPLY[@]}]=$dirname - done < <( - - # Set options to glob correctly - shopt -s dotglob nullglob - - # Collect directory names, strip leading ../ and trailing / - local -a dirnames - dirnames=(../"${COMP_WORDS[COMP_CWORD]}"*/) - dirnames=("${dirnames[@]#../}") - dirnames=("${dirnames[@]%/}") - - # Iterate again, but exclude the current directory this time - local -a sibs - local dirname - for dirname in "${dirnames[@]}" ; do - [[ $dirname != "${PWD##*/}" ]] || continue - sibs[${#sibs[@]}]=$dirname - done - - # Bail if no results to prevent empty output - ((${#sibs[@]})) || exit 1 - - # Print results, null-delimited - printf '%q\0' "${sibs[@]}" - ) -} -complete -F _sd sd diff --git a/bash/bashrc.d/ssh.bash b/bash/bashrc.d/ssh.bash deleted file mode 100644 index bbb9b246..00000000 --- a/bash/bashrc.d/ssh.bash +++ /dev/null @@ -1,22 +0,0 @@ -# Completion for ssh/sftp/ssh-copy-id with config hostnames -_ssh() { - - # Read hostnames from existent config files, no asterisks - local -a hosts - local config option value - for config in "$HOME"/.ssh/config /etc/ssh/ssh_config ; do - [[ -e $config ]] || continue - while read -r option value _ ; do - [[ $option == Host ]] || continue - [[ $value != *'*'* ]] || continue - hosts[${#hosts[@]}]=$value - done < "$config" - done - - # Generate completion reply - for host in "${hosts[@]}" ; do - [[ $host == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$host - done -} -complete -F _ssh -o default ssh sftp ssh-copy-id diff --git a/bash/bashrc.d/td.bash b/bash/bashrc.d/td.bash deleted file mode 100644 index ffb9c973..00000000 --- a/bash/bashrc.d/td.bash +++ /dev/null @@ -1,18 +0,0 @@ -# Complete filenames for td(1) -_td() { - local dir - dir=${TODO_DIR:-"$HOME"/Todo} - while IFS= read -rd '' fn ; do - COMPREPLY[${#COMPREPLY[@]}]=$fn - done < <( - shopt -s extglob nullglob - shopt -u dotglob - local -a fns - fns=("$dir"/"${COMP_WORDS[COMP_CWORD]}"*) - fns=("${fns[@]#"$dir"/}") - ((${#fns[@]})) || exit 1 - printf '%s\0' "${fns[@]##"$dir"/}" - ) - return -} -complete -F _td td diff --git a/bash/bashrc.d/ud.bash b/bash/bashrc.d/ud.bash index a1792968..e23de1fa 100644 --- a/bash/bashrc.d/ud.bash +++ b/bash/bashrc.d/ud.bash @@ -48,32 +48,3 @@ ud() { # Try to change into it cd "${opts[@]}" -- "$dirname" } - -# Completion setup for ud -_ud() { - - # Only makes sense for the second argument - ((COMP_CWORD == 2)) || return 1 - - # Iterate through directories, null-separated, add them to completions - local dirname - while IFS= read -rd '' dirname ; do - COMPREPLY[${#COMPREPLY[@]}]=$dirname - done < <( - - # Set options to glob correctly - shopt -s dotglob nullglob - - # Collect directory names, strip trailing slashes - local -a dirnames - dirnames=("${COMP_WORDS[COMP_CWORD]}"*/) - dirnames=("${dirnames[@]%/}") - - # Bail if no results to prevent empty output - ((${#dirnames[@]})) || exit 1 - - # Print results null-delimited - printf '%s\0' "${dirnames[@]}" - ) -} -complete -F _ud -o filenames ud diff --git a/bash/bashrc.d/vared.bash b/bash/bashrc.d/vared.bash index 510631ca..66250a3f 100644 --- a/bash/bashrc.d/vared.bash +++ b/bash/bashrc.d/vared.bash @@ -28,4 +28,3 @@ vared() { IFS= read -e -i "${!name}" -p "${prompt:-"$name"=}" -r -- "$name" done } -complete -A variable vared diff --git a/bash/bashrc.d/vis.bash b/bash/bashrc.d/vis.bash deleted file mode 100644 index f84cb702..00000000 --- a/bash/bashrc.d/vis.bash +++ /dev/null @@ -1,22 +0,0 @@ -# Complete args to vis(1) with existing executables in $VISPATH, defaulting to -# ~/.local/bin -_vis() { - local vispath - vispath=${VISPATH:-"$HOME"/.local/bin} - [[ -d $vispath ]] || return - while IFS= read -rd '' executable ; do - COMPREPLY[${#COMPREPLY[@]}]=$executable - done < <( - shopt -s dotglob nullglob - declare -a files - files=("${VISPATH:-"$HOME"/.local/bin}"/"${COMP_WORDS[COMP_CWORD]}"*) - declare -a executables - for file in "${files[@]}" ; do - [[ -f $file && -x $file ]] || continue - executables[${#executables[@]}]=${file##*/} - done - ((${#executables[@]})) || exit 1 - printf '%q\0' "${executables[@]}" - ) -} -complete -F _vis vis diff --git a/bash/bashrc.d/vr.bash b/bash/bashrc.d/vr.bash index 04a86835..adabb395 100644 --- a/bash/bashrc.d/vr.bash +++ b/bash/bashrc.d/vr.bash @@ -57,4 +57,3 @@ vr() { "$FUNCNAME" >&2 return 1 } -complete -A directory vr -- cgit v1.2.3