From c2372b7fd45ab87ef983ae5c847977b552f74ae4 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 30 Nov 2018 14:52:22 +1300 Subject: Remove redundant element from install scripts path --- Makefile | 4 ++-- install/conf.sh | 10 ++++++++++ install/install-conf.sh | 10 ---------- install/install-login-shell.sh | 10 ---------- install/login-shell.sh | 10 ++++++++++ 5 files changed, 22 insertions(+), 22 deletions(-) create mode 100644 install/conf.sh delete mode 100644 install/install-conf.sh delete mode 100644 install/install-login-shell.sh create mode 100644 install/login-shell.sh diff --git a/Makefile b/Makefile index 3093b96d..f9ed21ac 100644 --- a/Makefile +++ b/Makefile @@ -352,7 +352,7 @@ install: install-bin \ install-vim install-conf: - sh install/install-conf.sh + sh install/conf.sh install-abook: mkdir -p -- $(HOME)/.abook @@ -465,7 +465,7 @@ install-ksh: check-ksh install-sh cp -p -- ksh/kshrc.d/* $(HOME)/.kshrc.d install-login-shell: check-login-shell - sh install/install-login-shell.sh + sh install/login-shell.sh install-perlcritic: cp -p -- perlcritic/perlcriticrc $(HOME)/.perlcriticrc diff --git a/install/conf.sh b/install/conf.sh new file mode 100644 index 00000000..f50cde73 --- /dev/null +++ b/install/conf.sh @@ -0,0 +1,10 @@ +# Read extra targets from an optional ~/.dotfiles.conf file +if [ -e "$HOME"/.dotfiles.conf ] ; then + while read -r line ; do + case $line in + '#'*|'') ;; + *) set -- "$@" "$line" ;; + esac + done < "$HOME"/.dotfiles.conf +fi +make install "$@" diff --git a/install/install-conf.sh b/install/install-conf.sh deleted file mode 100644 index f50cde73..00000000 --- a/install/install-conf.sh +++ /dev/null @@ -1,10 +0,0 @@ -# Read extra targets from an optional ~/.dotfiles.conf file -if [ -e "$HOME"/.dotfiles.conf ] ; then - while read -r line ; do - case $line in - '#'*|'') ;; - *) set -- "$@" "$line" ;; - esac - done < "$HOME"/.dotfiles.conf -fi -make install "$@" diff --git a/install/install-login-shell.sh b/install/install-login-shell.sh deleted file mode 100644 index f38aa0c1..00000000 --- a/install/install-login-shell.sh +++ /dev/null @@ -1,10 +0,0 @@ -target=install-sh -case ${SHELL##*/} in - bash) - target=install-bash ;; - ksh|ksh88|ksh93|mksh|pdksh) - target=install-ksh ;; - zsh) - target=install-zsh ;; -esac -make "$target" diff --git a/install/login-shell.sh b/install/login-shell.sh new file mode 100644 index 00000000..f38aa0c1 --- /dev/null +++ b/install/login-shell.sh @@ -0,0 +1,10 @@ +target=install-sh +case ${SHELL##*/} in + bash) + target=install-bash ;; + ksh|ksh88|ksh93|mksh|pdksh) + target=install-ksh ;; + zsh) + target=install-zsh ;; +esac +make "$target" -- cgit v1.2.3 From 66c2c1e9218b53ee0000423561e7a8a4b7d5902b Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 30 Nov 2018 15:03:30 +1300 Subject: Check value of login shell more thoroughly Some old GNU make(1) implementations (and possibly others) force SHELL to /bin/sh, so let's check the value more directly. --- check/login-shell.sh | 6 ++++-- install/login-shell.sh | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/check/login-shell.sh b/check/login-shell.sh index 2972d98d..88eac59e 100644 --- a/check/login-shell.sh +++ b/check/login-shell.sh @@ -1,10 +1,12 @@ -target=check-sh -case ${SHELL##*/} in +shell=$(getent passwd "$USER" | cut -d: -f7) +case ${shell##*/} in bash) target=check-bash ;; ksh|ksh88|ksh93|mksh|pdksh) target=check-ksh ;; zsh) target=check-zsh ;; + *) + target=check-sh ;; esac make "$target" diff --git a/install/login-shell.sh b/install/login-shell.sh index f38aa0c1..54741fde 100644 --- a/install/login-shell.sh +++ b/install/login-shell.sh @@ -1,10 +1,12 @@ -target=install-sh -case ${SHELL##*/} in +shell=$(getent passwd "$USER" | cut -d: -f7) +case ${shell##*/} in bash) target=install-bash ;; ksh|ksh88|ksh93|mksh|pdksh) target=install-ksh ;; zsh) target=install-zsh ;; + *) + target=install-sh ;; esac make "$target" -- cgit v1.2.3 From e95d9579b8354640e52de0ff8056e7bb0bd38ba4 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 01:33:44 +1300 Subject: Add an issue with text filename completion --- ISSUES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ISSUES.md b/ISSUES.md index 4e70c0ed..b2601de9 100644 --- a/ISSUES.md +++ b/ISSUES.md @@ -28,3 +28,5 @@ Known issues it? * The b:undo\_indent definition for the perl filetype can probably be pushed upstream. +* The `_text_filenames` completion handler for Bash won't work on files with + newlines in their names. Can it be made to? -- cgit v1.2.3 From 31bd3ac2e6eec954eb8b2d429a4bd58a089964e7 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 01:34:03 +1300 Subject: Use more idiomatic short-circuit for -r in bashrc --- bash/bashrc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bash/bashrc b/bash/bashrc index dcf3df53..3b4c91bd 100644 --- a/bash/bashrc +++ b/bash/bashrc @@ -6,9 +6,7 @@ esac # Don't do anything if restricted, not even sourcing the ENV file # Testing $- for "r" doesn't work -if shopt -q restricted_shell >/dev/null 2>&1 ; then - return -fi +! shopt -q restricted_shell >/dev/null 2>&1 || return # Clear away all aliases; we do this here rather than in the $ENV file shared # between POSIX shells, because ksh relies on aliases to implement certain -- cgit v1.2.3 From a8aae547155d873dd0f94aa92b4fca524ce15797 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:00:56 +1300 Subject: Overhaul ssh_config hosts completion --- bash/bash_completion.d/_ssh_config_hosts.bash | 62 +++++++++++++++++++-------- 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/bash/bash_completion.d/_ssh_config_hosts.bash b/bash/bash_completion.d/_ssh_config_hosts.bash index 8f45c412..c26457cf 100644 --- a/bash/bash_completion.d/_ssh_config_hosts.bash +++ b/bash/bash_completion.d/_ssh_config_hosts.bash @@ -1,22 +1,48 @@ # Complete ssh_config(5) hostnames _ssh_config_hosts() { - # 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 - local host - for host in "${hosts[@]}" ; do - [[ $host == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$host - done + # Don't complete anything that wouldn't be in a valid hostname + case ${COMP_WORDS[COMP_CWORD]} in + *[!a-zA-Z0-9.-]*) return 1 ;; + esac + + # Iterate through words from a subshell + while read -r word ; do + [[ -n $word ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$word + done < <( + + # Check bind settings to see if we should match case insensitively + while read -r _ setting ; do + case $setting in + ('completion-ignore-case on') + shopt -qs nocasematch 2>/dev/null + break + ;; + esac + done < <(bind -v) + + # Iterate through SSH client config paths + for config in "$HOME"/.ssh/config /etc/ssh/ssh_config ; do + [[ -e $config ]] || continue + + # Read Host options and their first value from file + while read -r option value _ ; do + [[ $option == Host ]] || continue + + # Check host value + case $value in + + # Don't complete with wildcard characters + (*'*'*) ;; + + # Found a match; print it + ("${COMP_WORDS[COMP_CWORD]}"*) + printf '%s\n' "$value" + ;; + esac + + done < "$config" + done + ) } -- cgit v1.2.3 From 65e47bfe12f3fbc25da69e59c7af38e958c67688 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:02:14 +1300 Subject: Use full `if` condition for _text_filename source --- bash/bash_completion.d/awk.bash | 3 ++- bash/bash_completion.d/cat.bash | 3 ++- bash/bash_completion.d/ed.bash | 3 ++- bash/bash_completion.d/ex.bash | 3 ++- bash/bash_completion.d/grep.bash | 3 ++- bash/bash_completion.d/head.bash | 3 ++- bash/bash_completion.d/m4.bash | 3 ++- bash/bash_completion.d/mail.bash | 7 +++---- bash/bash_completion.d/mutt.bash | 5 +++-- 9 files changed, 20 insertions(+), 13 deletions(-) diff --git a/bash/bash_completion.d/awk.bash b/bash/bash_completion.d/awk.bash index 1e01381a..5f121d8a 100644 --- a/bash/bash_completion.d/awk.bash +++ b/bash/bash_completion.d/awk.bash @@ -1,4 +1,5 @@ # Completion for awk(1) with files that look editable -declare -F _text_filenames >/dev/null || +if ! declare -F _text_filenames >/dev/null ; then source "$HOME"/.bash_completion.d/_text_filenames.bash +fi complete -F _text_filenames -o filenames awk diff --git a/bash/bash_completion.d/cat.bash b/bash/bash_completion.d/cat.bash index 430cd58c..2da60ff0 100644 --- a/bash/bash_completion.d/cat.bash +++ b/bash/bash_completion.d/cat.bash @@ -1,4 +1,5 @@ # Completion for cat(1) with files that look editable -declare -F _text_filenames >/dev/null || +if ! declare -F _text_filenames >/dev/null ; then source "$HOME"/.bash_completion.d/_text_filenames.bash +fi complete -F _text_filenames -o filenames cat diff --git a/bash/bash_completion.d/ed.bash b/bash/bash_completion.d/ed.bash index c7fc6fde..b9651957 100644 --- a/bash/bash_completion.d/ed.bash +++ b/bash/bash_completion.d/ed.bash @@ -1,4 +1,5 @@ # Completion for ed(1) with files that look editable -declare -F _text_filenames >/dev/null || +if ! declare -F _text_filenames >/dev/null ; then source "$HOME"/.bash_completion.d/_text_filenames.bash +fi complete -F _text_filenames -o filenames ed diff --git a/bash/bash_completion.d/ex.bash b/bash/bash_completion.d/ex.bash index 6805b8b1..00875df5 100644 --- a/bash/bash_completion.d/ex.bash +++ b/bash/bash_completion.d/ex.bash @@ -1,4 +1,5 @@ # Completion for ex(1) with files that look editable -declare -F _text_filenames >/dev/null || +if ! declare -F _text_filenames >/dev/null ; then source "$HOME"/.bash_completion.d/_text_filenames.bash +fi complete -F _text_filenames -o filenames ex diff --git a/bash/bash_completion.d/grep.bash b/bash/bash_completion.d/grep.bash index 86c191cb..e9986b15 100644 --- a/bash/bash_completion.d/grep.bash +++ b/bash/bash_completion.d/grep.bash @@ -1,4 +1,5 @@ # Completion for grep(1) with files that look editable -declare -F _text_filenames >/dev/null || +if ! declare -F _text_filenames >/dev/null ; then source "$HOME"/.bash_completion.d/_text_filenames.bash +fi complete -F _text_filenames -o filenames grep diff --git a/bash/bash_completion.d/head.bash b/bash/bash_completion.d/head.bash index fa7cb878..0f4a7131 100644 --- a/bash/bash_completion.d/head.bash +++ b/bash/bash_completion.d/head.bash @@ -1,4 +1,5 @@ # Completion for head(1) with files that look editable -declare -F _text_filenames >/dev/null || +if ! declare -F _text_filenames >/dev/null ; then source "$HOME"/.bash_completion.d/_text_filenames.bash +fi complete -F _text_filenames -o filenames head diff --git a/bash/bash_completion.d/m4.bash b/bash/bash_completion.d/m4.bash index 5811fd5b..bb50f3b2 100644 --- a/bash/bash_completion.d/m4.bash +++ b/bash/bash_completion.d/m4.bash @@ -1,4 +1,5 @@ # Completion for m4(1) with files that look editable -declare -F _text_filenames >/dev/null || +if ! declare -F _text_filenames >/dev/null ; then source "$HOME"/.bash_completion.d/_text_filenames.bash +fi complete -F _text_filenames -o filenames m4 diff --git a/bash/bash_completion.d/mail.bash b/bash/bash_completion.d/mail.bash index 65c4ae80..5d1cdec0 100644 --- a/bash/bash_completion.d/mail.bash +++ b/bash/bash_completion.d/mail.bash @@ -1,6 +1,5 @@ # Completion for mail(1) with abook(1) email addresses -declare -F _abook_addresses >/dev/null || - source "$HOME"/.bash_completion.d/_abook_addresses.bash - -# bashdefault requires Bash >=3.0 +if ! declare -F _text_filenames >/dev/null ; then + source "$HOME"/.bash_completion.d/_text_filenames.bash +fi complete -F _abook_addresses -o bashdefault -o default mail diff --git a/bash/bash_completion.d/mutt.bash b/bash/bash_completion.d/mutt.bash index c7f02ac7..5fb13339 100644 --- a/bash/bash_completion.d/mutt.bash +++ b/bash/bash_completion.d/mutt.bash @@ -1,4 +1,5 @@ # Completion for mutt(1) with abook(1) email addresses -declare -F _abook_addresses >/dev/null || - source "$HOME"/.bash_completion.d/_abook_addresses.bash +if ! declare -F _text_filenames >/dev/null ; then + source "$HOME"/.bash_completion.d/_text_filenames.bash +fi complete -F _abook_addresses -o bashdefault -o default mutt -- cgit v1.2.3 From d7f8465d51306c2e1539117e0d7f1dc066bbe1e3 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:04:41 +1300 Subject: Use full `if` condition for SSH hostname comp src --- bash/bash_completion.d/sftp.bash | 3 ++- bash/bash_completion.d/ssh-copy-id.bash | 3 ++- bash/bash_completion.d/ssh.bash | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/bash/bash_completion.d/sftp.bash b/bash/bash_completion.d/sftp.bash index ad4d406f..b54b06b7 100644 --- a/bash/bash_completion.d/sftp.bash +++ b/bash/bash_completion.d/sftp.bash @@ -1,4 +1,5 @@ # Completion for sftp(1) with ssh_config(5) hostnames -declare -F _ssh_config_hosts >/dev/null || +if ! declare -F _ssh_config_hosts >/dev/null ; then source "$HOME"/.bash_completion.d/_ssh_config_hosts.bash +fi complete -F _ssh_config_hosts -o bashdefault -o default sftp diff --git a/bash/bash_completion.d/ssh-copy-id.bash b/bash/bash_completion.d/ssh-copy-id.bash index 336df4ea..cbecfa5f 100644 --- a/bash/bash_completion.d/ssh-copy-id.bash +++ b/bash/bash_completion.d/ssh-copy-id.bash @@ -1,4 +1,5 @@ # Completion for ssh-copy-id(1) with ssh_config(5) hostnames -declare -F _ssh_config_hosts >/dev/null || +if ! declare -F _ssh_config_hosts >/dev/null ; then source "$HOME"/.bash_completion.d/_ssh_config_hosts.bash +fi complete -F _ssh_config_hosts -o bashdefault -o default ssh-copy-id diff --git a/bash/bash_completion.d/ssh.bash b/bash/bash_completion.d/ssh.bash index 7ec82596..6d327c91 100644 --- a/bash/bash_completion.d/ssh.bash +++ b/bash/bash_completion.d/ssh.bash @@ -1,4 +1,5 @@ # Completion for ssh(1) with ssh_config(5) hostnames -declare -F _ssh_config_hosts >/dev/null || +if ! declare -F _ssh_config_hosts >/dev/null ; then source "$HOME"/.bash_completion.d/_ssh_config_hosts.bash +fi complete -F _ssh_config_hosts -o bashdefault -o default ssh -- cgit v1.2.3 From 8f84b03390c5ecd25a8e693d011283ee67a4a609 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:05:44 +1300 Subject: Overhaul text filename generation --- bash/bash_completion.d/_text_filenames.bash | 189 +++++++++++++++++++--------- 1 file changed, 132 insertions(+), 57 deletions(-) diff --git a/bash/bash_completion.d/_text_filenames.bash b/bash/bash_completion.d/_text_filenames.bash index a9d767b7..52bb80a1 100644 --- a/bash/bash_completion.d/_text_filenames.bash +++ b/bash/bash_completion.d/_text_filenames.bash @@ -14,11 +14,8 @@ _text_filenames() { # Exclude blanks [[ -n $item ]] || continue - # Accept directories - if [[ -d $item ]] ; then - COMPREPLY[${#COMPREPLY[@]}]=$item - continue - fi + # Exclude nonexistent (some sort of error) + [[ -e $item ]] || continue # Exclude files with block, character, pipe, or socket type [[ ! -b $item ]] || continue @@ -26,59 +23,137 @@ _text_filenames() { [[ ! -p $item ]] || continue [[ ! -S $item ]] || continue - # Check the filename extension to know what to exclude - case $item in - - # Binary image file formats - *.bmp|*.gif|*.ico|*.jpeg|*.jpg|*.png|*.tif|*.xcf) ;; - *.BMP|*.GIF|*.ICO|*.JPEG|*.JPG|*.PNG|*.TIF|*.XCF) ;; - - # Video file formats - *.avi|*.gifv|*.mkv|*.mov|*.mpg|*.rm|*.webm) ;; - *.AVI|*.GIFV|*.MKV|*.MOV|*.MPG|*.RM|*.WEBM) ;; - - # Lossy audio file formats - *.au|*.m4a|*.mp[34]|*.ogg|*.snd|*.wma) ;; - *.AU|*.M4A|*.MP[34]|*.OGG|*.SND|*.WMA) ;; - - # Lossless/source audio file formats - *.aup|*.flac|*.mid|*.h2song|*.nwc|*.s3m|*.wav) ;; - *.AUP|*.FLAC|*.MID|*.H2SONG|*.NWC|*.S3M|*.WAV) ;; - - # Compressed/archived file formats - *.cab|*.deb|*.lzm|*.pack|*.tar|*.tar.bz2|*.tar.gz|*.tar.xz|*.zip) ;; - *.CAB|*.DEB|*.LZM|*.PACK|*.TAR|*.TAR.BZ2|*.TAR.GZ|*.TAR.XZ|*.ZIP) ;; - - # Document formats - # (Not .doc, it's a plaintext format sometimes) - *.cbr|*.docx|*.epub|*.odp|*.odt|*.pdf|*.xls|*.xlsx) ;; - *.CBR|*.DOCX|*.EPUB|*.ODP|*.ODT|*.PDF|*.XLS|*.XLSX) ;; - - # Filesystems/disk images - *.bin|*.cue|*.hdf|*.img|*.iso|*.mdf|*.raw) ;; - *.BIN|*.CUE|*.HDF|*.IMG|*.ISO|*.MDF|*.RAW) ;; - - # Font files - *.ttf) ;; - *.TTF) ;; - - # Index file formats - *.idx) ;; - *.IDX) ;; - - # Encrypted file formats - *.gpg) ;; - *.GPG) ;; - - # Other known binary extensions - # (I haven't included .com; on UNIX, that's more likely to be - # something I saved from a website and named after the domain) - *.a|*.drv|*.exe|*.o|*.torrent|*.wad|*.rom) ;; - *.A|*.DRV|*.EXE|*.O|*.TORRENT|*.WAD|*.ROM) ;; + # Accept directories + if [[ -d $item ]] ; then + COMPREPLY[${#COMPREPLY[@]}]=$item + continue + fi - # Complete everything else; some of it will still be binary - *) COMPREPLY[${#COMPREPLY[@]}]=$item ;; + # Check the filename extension to know what to exclude + ( + # Case-insensitive matching available since 3.1-alpha + shopt -qs nocasematch 2>/dev/null + + # Match against known binary patterns + case $item in + + # Archives + (*.7z) ;; + (*.bz2) ;; + (*.gz) ;; + (*.jar) ;; + (*.rar) ;; + (*.tar) ;; + (*.xz) ;; + (*.zip) ;; + + # Bytecode + (*.class) ;; + (*.pyc) ;; + + # Databases + (*.db) ;; + (*.dbm) ;; + (*.sdbm) ;; + (*.sqlite) ;; + + # Disk + (*.adf) ;; + (*.bin) ;; + (*.hdf) ;; + (*.iso) ;; + + # Documents + (*.docx) ;; + (*.djvu) ;; + (*.odp) ;; + (*.ods) ;; + (*.odt) ;; + (*.pdf) ;; + (*.ppt) ;; + (*.xls) ;; + (*.xlsx) ;; + + # Encrypted + (*.asc) ;; + (*.gpg) ;; + + # Executables + (*.exe) ;; + + # Fonts + (*.ttf) ;; + + # Images + (*.bmp) ;; + (*.gd2) ;; + (*.gif) ;; + (*.ico) ;; + (*.jpeg) ;; + (*.jpg) ;; + (*.pbm) ;; + (*.png) ;; + (*.psd) ;; + (*.tga) ;; + (*.xbm) ;; + (*.xcf) ;; + (*.xpm) ;; + + # Incomplete + (*.filepart) ;; + + # Objects + (*.a) ;; + (*.o) ;; + + # Sound + (*.au) ;; + (*.aup) ;; + (*.flac) ;; + (*.mid) ;; + (*.m4a) ;; + (*.mp3) ;; + (*.ogg) ;; + (*.opus) ;; + (*.s3m) ;; + (*.wav) ;; + + # System-specific + (.DS_Store) ;; + + # Translation + (*.gmo) ;; + + # Version control + (.git) ;; + (.hg) ;; + (.svn) ;; + + # Video + (*.avi) ;; + (*.gifv) ;; + (*.mp4) ;; + (*.ogv) ;; + (*.rm) ;; + (*.swf) ;; + (*.webm) ;; + + # Vim + (*~) ;; + (*.swp) ;; + + # Not binary that we can tell; maybe editable + (*) exit 0 ;; + + esac + + # Known usually-binary extension; flag failure + exit 1 + + ) || continue + + # Complete everything else; some of it will still be binary + COMPREPLY[${#COMPREPLY[@]}]=$item - esac done < <(compgen -A file -- "${COMP_WORDS[COMP_CWORD]}") } -- cgit v1.2.3 From 51330a7d31bc0e3b90bc9ff04d1cc923a372ed66 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:06:43 +1300 Subject: Simplify an array operation in `bd` completion --- bash/bash_completion.d/bd.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bash/bash_completion.d/bd.bash b/bash/bash_completion.d/bd.bash index 86146a4e..1c1a40a8 100644 --- a/bash/bash_completion.d/bd.bash +++ b/bash/bash_completion.d/bd.bash @@ -10,7 +10,7 @@ _bd() { # Remove the last element in the array (the current directory) ((${#dirnames[@]})) || return 1 - dirnames=("${dirnames[@]:0:$((${#dirnames[@]}-1))}") + dirnames=("${dirnames[@]:0:${#dirnames[@]}-1}") # Add the matching dirnames to the reply local dirname -- cgit v1.2.3 From 1dc5cbd9a6070631883bfdf4a490405099ce3b90 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:07:19 +1300 Subject: Overhaul `keep` completion --- bash/bash_completion.d/keep.bash | 101 +++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 58 deletions(-) diff --git a/bash/bash_completion.d/keep.bash b/bash/bash_completion.d/keep.bash index 77b37059..00b1469e 100644 --- a/bash/bash_completion.d/keep.bash +++ b/bash/bash_completion.d/keep.bash @@ -2,71 +2,56 @@ # stuff that's already kept _keep() { - # Default is to complete with function and variable names + # Determine what we're doing based on first completion word local mode - mode=names - - # Iterate through the words up to the previous word to figure out how to - # complete this one - local i - for ((i = 0; i < COMP_CWORD; i++)) ; do - case ${COMP_WORDS[i]} in - --) - mode=names - break - ;; - -d) - mode=kept - break - ;; + mode=keep + if ((COMP_CWORD > 1)) ; then + case ${COMP_WORDS[1]} in + -h) return 1 ;; + -d) mode=delete ;; esac - done + fi - # Complete with appropriate mode - case $mode in - names) - local word - while IFS= read -r word ; do - [[ -n $word ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$word - done < <(compgen -A function -A variable \ - -- "${COMP_WORDS[COMP_CWORD]}") - ;; - kept) - local word - while IFS= read -r word ; do - [[ -n $word ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$word - done < <( - shopt -s dotglob nullglob + # Collect words from an appropriate type of completion + local word + while read -r word ; do + [[ -n $word ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$word + done < <( - # Make globbing case-insensitive if appropriate; is there a cleaner way - # to find this value? - while read -r _ option value ; do - case $option in - (completion-ignore-case) - case $value in - (on) - shopt -s nocaseglob - break - ;; - esac + # Switch on second word; is it a -d option? + case $mode in + + # Keepable names: all functions and variables + (keep) + compgen -A function -A variable \ + -- "${COMP_WORDS[COMP_CWORD]}" + ;; + + # Kept names: .bash-suffixed names in keep dir + (delete) + # Make globs behave correctly + shopt -s nullglob + while read -r _ setting ; do + case $setting in + ('completion-ignore-case on') + shopt -s nocaseglob + break ;; esac done < <(bind -v) - keep=${BASHKEEP:-"$HOME"/.bashkeep.d} - declare -a keeps - keeps=("$keep"/"${COMP_WORDS[COMP_CWORD]}"*.bash) - keeps=("${keeps[@]##*/}") - keeps=("${keeps[@]%.bash}") - if ((${#keeps[@]})) ; then - printf '%s\n' "${keeps[@]}" - else - printf '\n' - fi - ) - ;; - esac + # Build list of kept names + dir=${BASHKEEP:-"$HOME"/.bashkeep.d} + cword=${COMP_WORDS[COMP_CWORD]} + kept=("$dir"/"$cword"*.bash) + kept=("${kept[@]##*/}") + kept=("${kept[@]%.bash}") + + # Print kept names + printf '%s\n' "${kept[@]}" + ;; + esac + ) } complete -F _keep keep -- cgit v1.2.3 From e521cec24eb88b70cb15b5244e86a5d76032de99 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:13:23 +1300 Subject: Use simpler method of no case completion check --- bash/bash_completion.d/eds.bash | 17 ++++++----------- bash/bash_completion.d/man.bash | 17 ++++++----------- bash/bash_completion.d/mysql.bash | 17 ++++++----------- bash/bash_completion.d/pass.bash | 17 ++++++----------- bash/bash_completion.d/path.bash | 17 ++++++----------- bash/bash_completion.d/sd.bash | 17 ++++++----------- bash/bash_completion.d/ud.bash | 17 ++++++----------- 7 files changed, 42 insertions(+), 77 deletions(-) diff --git a/bash/bash_completion.d/eds.bash b/bash/bash_completion.d/eds.bash index ea6de618..c8a238f6 100644 --- a/bash/bash_completion.d/eds.bash +++ b/bash/bash_completion.d/eds.bash @@ -11,17 +11,12 @@ _eds() { done < <( shopt -s dotglob nullglob - # Make globbing case-insensitive if appropriate; is there a cleaner way - # to find this value? - while read -r _ option value ; do - case $option in - (completion-ignore-case) - case $value in - (on) - shopt -s nocaseglob - break - ;; - esac + # Make globbing case-insensitive if appropriate + while read -r _ setting ; do + case $setting in + ('completion-ignore-case on') + shopt -s nocaseglob + break ;; esac done < <(bind -v) diff --git a/bash/bash_completion.d/man.bash b/bash/bash_completion.d/man.bash index 1efa7c52..f92dda95 100644 --- a/bash/bash_completion.d/man.bash +++ b/bash/bash_completion.d/man.bash @@ -35,17 +35,12 @@ _man() { shopt -u dotglob shopt -s extglob nullglob - # Make globbing case-insensitive if appropriate; is there a cleaner way - # to find this value? - while read -r _ option value ; do - case $option in - (completion-ignore-case) - case $value in - (on) - shopt -s nocaseglob - break - ;; - esac + # Make globbing case-insensitive if appropriate + while read -r _ setting ; do + case $setting in + ('completion-ignore-case on') + shopt -s nocaseglob + break ;; esac done < <(bind -v) diff --git a/bash/bash_completion.d/mysql.bash b/bash/bash_completion.d/mysql.bash index ad153adc..d88219bf 100644 --- a/bash/bash_completion.d/mysql.bash +++ b/bash/bash_completion.d/mysql.bash @@ -19,17 +19,12 @@ _mysql() { # Set options so that globs expand correctly shopt -s dotglob nullglob - # Make globbing case-insensitive if appropriate; is there a cleaner way - # to find this value? - while read -r _ option value ; do - case $option in - (completion-ignore-case) - case $value in - (on) - shopt -s nocaseglob - break - ;; - esac + # Make globbing case-insensitive if appropriate + while read -r _ setting ; do + case $setting in + ('completion-ignore-case on') + shopt -s nocaseglob + break ;; esac done < <(bind -v) diff --git a/bash/bash_completion.d/pass.bash b/bash/bash_completion.d/pass.bash index ec5959be..5d507133 100644 --- a/bash/bash_completion.d/pass.bash +++ b/bash/bash_completion.d/pass.bash @@ -23,17 +23,12 @@ _pass() shopt -u dotglob shopt -s globstar nullglob - # Make globbing case-insensitive if appropriate; is there a cleaner way - # to find this value? - while read -r _ option value ; do - case $option in - (completion-ignore-case) - case $value in - (on) - shopt -s nocaseglob - break - ;; - esac + # Make globbing case-insensitive if appropriate + while read -r _ setting ; do + case $setting in + ('completion-ignore-case on') + shopt -s nocaseglob + break ;; esac done < <(bind -v) diff --git a/bash/bash_completion.d/path.bash b/bash/bash_completion.d/path.bash index 8b72a062..da867880 100644 --- a/bash/bash_completion.d/path.bash +++ b/bash/bash_completion.d/path.bash @@ -26,17 +26,12 @@ _path() { # Set options to glob correctly shopt -s dotglob nullglob - # Make globbing case-insensitive if appropriate; is there a cleaner way - # to find this value? - while read -r _ option value ; do - case $option in - (completion-ignore-case) - case $value in - (on) - shopt -s nocaseglob - break - ;; - esac + # Make globbing case-insensitive if appropriate + while read -r _ setting ; do + case $setting in + ('completion-ignore-case on') + shopt -s nocaseglob + break ;; esac done < <(bind -v) diff --git a/bash/bash_completion.d/sd.bash b/bash/bash_completion.d/sd.bash index 578a69fd..9694de1f 100644 --- a/bash/bash_completion.d/sd.bash +++ b/bash/bash_completion.d/sd.bash @@ -17,17 +17,12 @@ _sd() { # Set options to glob correctly shopt -s dotglob nullglob - # Make globbing case-insensitive if appropriate; is there a cleaner way - # to find this value? - while read -r _ option value ; do - case $option in - (completion-ignore-case) - case $value in - (on) - shopt -s nocaseglob - break - ;; - esac + # Make globbing case-insensitive if appropriate + while read -r _ setting ; do + case $setting in + ('completion-ignore-case on') + shopt -s nocaseglob + break ;; esac done < <(bind -v) diff --git a/bash/bash_completion.d/ud.bash b/bash/bash_completion.d/ud.bash index aa59a4fc..278fbbc3 100644 --- a/bash/bash_completion.d/ud.bash +++ b/bash/bash_completion.d/ud.bash @@ -13,17 +13,12 @@ _ud() { # Set options to glob correctly shopt -s dotglob nullglob - # Make globbing case-insensitive if appropriate; is there a cleaner way - # to find this value? - while read -r _ option value ; do - case $option in - (completion-ignore-case) - case $value in - (on) - shopt -s nocaseglob - break - ;; - esac + # Make globbing case-insensitive if appropriate + while read -r _ setting ; do + case $setting in + ('completion-ignore-case on') + shopt -s nocaseglob + break ;; esac done < <(bind -v) -- cgit v1.2.3 From 626593c3712531c251c69be2e561a34da98cdcdf Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:19:46 +1300 Subject: Remove null-result guard from completion gens I don't believe these are needed anymore, or possibly ever were. --- bash/bash_completion.d/eds.bash | 10 ++-------- bash/bash_completion.d/man.bash | 10 ++-------- bash/bash_completion.d/mysql.bash | 10 ++-------- bash/bash_completion.d/pass.bash | 10 ++-------- bash/bash_completion.d/path.bash | 10 ++-------- bash/bash_completion.d/sd.bash | 10 ++-------- bash/bash_completion.d/td.bash | 10 ++-------- 7 files changed, 14 insertions(+), 56 deletions(-) diff --git a/bash/bash_completion.d/eds.bash b/bash/bash_completion.d/eds.bash index c8a238f6..0b5e34ea 100644 --- a/bash/bash_completion.d/eds.bash +++ b/bash/bash_completion.d/eds.bash @@ -29,14 +29,8 @@ _eds() { executables[${#executables[@]}]=${file##*/} done - # Print quoted entries, null-delimited, if there was at least one; - # otherwise, just print a null character to stop this hanging in Bash - # 4.4 - if ((${#executables[@]})) ; then - printf '%q\0' "${executables[@]}" - else - printf '\0' - fi + # Print quoted entries, null-delimited + printf '%q\0' "${executables[@]}" ) } complete -F _eds eds diff --git a/bash/bash_completion.d/man.bash b/bash/bash_completion.d/man.bash index f92dda95..fcf26436 100644 --- a/bash/bash_completion.d/man.bash +++ b/bash/bash_completion.d/man.bash @@ -69,14 +69,8 @@ _man() { pages=("${pages[@]%.@([glx]z|bz2|lzma|Z)}") pages=("${pages[@]%.[0-9]*}") - # Print quoted entries, null-delimited, if there was at least one; - # otherwise, just print a null character to stop this hanging in Bash - # 4.4 - if ((${#pages[@]})) ; then - printf '%q\0' "${pages[@]}" - else - printf '\0' - fi + # Print quoted entries, null-delimited + printf '%q\0' "${pages[@]}" ) } complete -F _man -o bashdefault -o default man diff --git a/bash/bash_completion.d/mysql.bash b/bash/bash_completion.d/mysql.bash index d88219bf..413f3386 100644 --- a/bash/bash_completion.d/mysql.bash +++ b/bash/bash_completion.d/mysql.bash @@ -35,14 +35,8 @@ _mysql() { cnfs=("${cnfs[@]#"$dirname"/}") cnfs=("${cnfs[@]%.cnf}") - # Print quoted entries, null-delimited, if there was at least one; - # otherwise, just print a null character to stop this hanging in Bash - # 4.4 - if ((${#cnfs[@]})) ; then - printf '%q\0' "${cnfs[@]}" - else - printf '\0' - fi + # Print quoted entries, null-delimited + printf '%q\0' "${cnfs[@]}" ) } complete -F _mysql -o bashdefault -o default mysql diff --git a/bash/bash_completion.d/pass.bash b/bash/bash_completion.d/pass.bash index 5d507133..4a814412 100644 --- a/bash/bash_completion.d/pass.bash +++ b/bash/bash_completion.d/pass.bash @@ -40,14 +40,8 @@ _pass() entries=("${entries[@]#"$passdir"/}") entries=("${entries[@]%.gpg}") - # Print quoted entries, null-delimited, if there was at least one; - # otherwise, just print a null character to stop this hanging in Bash - # 4.4 - if ((${#entries[@]})) ; then - printf '%q\0' "${entries[@]}" - else - printf '\0' - fi + # Print quoted 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 index da867880..fcb57949 100644 --- a/bash/bash_completion.d/path.bash +++ b/bash/bash_completion.d/path.bash @@ -41,14 +41,8 @@ _path() { dirnames=("${COMP_WORDS[COMP_CWORD]}"*/) dirnames=("${dirnames[@]%/}") - # Print quoted entries, null-delimited, if there was at - # least one; otherwise, just print a null character to stop - # this hanging in Bash 4.4 - if ((${#dirnames[@]})) ; then - printf '%q\0' "${dirnames[@]}" - else - printf '\0' - fi + # Print quoted entries, null-delimited + printf '%q\0' "${dirnames[@]}" ) ;; diff --git a/bash/bash_completion.d/sd.bash b/bash/bash_completion.d/sd.bash index 9694de1f..2d2d8f22 100644 --- a/bash/bash_completion.d/sd.bash +++ b/bash/bash_completion.d/sd.bash @@ -41,14 +41,8 @@ _sd() { sibs[${#sibs[@]}]=$dirname done - # Print quoted sibs, null-delimited, if there was at least one; - # otherwise, just print a null character to stop this hanging in Bash - # 4.4 - if ((${#sibs[@]})) ; then - printf '%q\0' "${sibs[@]}" - else - printf '\0' - fi + # Print quoted sibling directories, null-delimited + printf '%q\0' "${sibs[@]}" ) } complete -F _sd sd diff --git a/bash/bash_completion.d/td.bash b/bash/bash_completion.d/td.bash index 377ef6ce..92927c28 100644 --- a/bash/bash_completion.d/td.bash +++ b/bash/bash_completion.d/td.bash @@ -29,14 +29,8 @@ _td() { fns=("$dir"/"${COMP_WORDS[COMP_CWORD]}"*) fns=("${fns[@]#"$dir"/}") - # Print quoted entries, null-delimited, if there was at least one; - # otherwise, just print a null character to stop this hanging in Bash - # 4.4 - if ((${#fns[@]})) ; then - printf '%q\0' "${fns[@]}" - else - printf '\0' - fi + # Print quoted entries, null-delimited + printf '%q\0' "${fns[@]}" ) } complete -F _td td -- cgit v1.2.3 From 1a5ad4bc42f558b26aacf56e7604a7740c454f2b Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:21:27 +1300 Subject: Use array+=() syntax in two Bash completion files Since these only load with Bash >=4.0, we may as well use the nicer method of adding to arrays. --- bash/bash_completion.d/find.bash | 2 +- bash/bash_completion.d/pass.bash | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bash/bash_completion.d/find.bash b/bash/bash_completion.d/find.bash index 007a83bd..85cadfaf 100644 --- a/bash/bash_completion.d/find.bash +++ b/bash/bash_completion.d/find.bash @@ -30,7 +30,7 @@ _find() { local item while read -r item ; do [[ -n $item ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$item + COMPREPLY+=("$item") done < <( # If the word being completed starts with a dash, just complete it as diff --git a/bash/bash_completion.d/pass.bash b/bash/bash_completion.d/pass.bash index 4a814412..1df8dfb1 100644 --- a/bash/bash_completion.d/pass.bash +++ b/bash/bash_completion.d/pass.bash @@ -16,7 +16,7 @@ _pass() local entry while IFS= read -rd '' entry ; do [[ -n $entry ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$entry + COMPREPLY+=("$entry") done < <( # Set shell options to expand globs the way we expect -- cgit v1.2.3 From 1f04fdd4b9a4c0df2a69e7b75c46eb73503b30f8 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:22:43 +1300 Subject: Remove stray comment no longer applicable --- bash/bash_completion.d/gpg.bash | 2 -- 1 file changed, 2 deletions(-) diff --git a/bash/bash_completion.d/gpg.bash b/bash/bash_completion.d/gpg.bash index f98cb193..2855a1a9 100644 --- a/bash/bash_completion.d/gpg.bash +++ b/bash/bash_completion.d/gpg.bash @@ -14,6 +14,4 @@ _gpg() { COMPREPLY[${#COMPREPLY[@]}]=$option done < <(gpg --dump-options 2>/dev/null) } - -# bashdefault requires Bash >=3.0 complete -F _gpg -o bashdefault -o default gpg -- cgit v1.2.3 From bd12134df6b92ad7efe192cc7191e648eb5706ab Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:26:50 +1300 Subject: Use inverting exclam mark outside conditional --- bash/bash_completion.d/_text_filenames.bash | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bash/bash_completion.d/_text_filenames.bash b/bash/bash_completion.d/_text_filenames.bash index 52bb80a1..9cc1c722 100644 --- a/bash/bash_completion.d/_text_filenames.bash +++ b/bash/bash_completion.d/_text_filenames.bash @@ -18,10 +18,10 @@ _text_filenames() { [[ -e $item ]] || continue # Exclude files with block, character, pipe, or socket type - [[ ! -b $item ]] || continue - [[ ! -c $item ]] || continue - [[ ! -p $item ]] || continue - [[ ! -S $item ]] || continue + ! [[ -b $item ]] || continue + ! [[ -c $item ]] || continue + ! [[ -p $item ]] || continue + ! [[ -S $item ]] || continue # Accept directories if [[ -d $item ]] ; then -- cgit v1.2.3 From 4f50c264d0def41faeb828c93330d720a5c459b6 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:27:32 +1300 Subject: Remove needless line breaks from git completion --- bash/bash_completion.d/git.bash | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/bash/bash_completion.d/git.bash b/bash/bash_completion.d/git.bash index 2fd1bb98..28313f76 100644 --- a/bash/bash_completion.d/git.bash +++ b/bash/bash_completion.d/git.bash @@ -19,9 +19,7 @@ _git() { COMPREPLY[${#COMPREPLY[@]}]=$ref ;; esac - done < <(git for-each-ref \ - --format '%(refname)' \ - 2>/dev/null) + done < <(git for-each-ref --format '%(refname)' 2>/dev/null) return ;; @@ -51,9 +49,7 @@ _git() { COMPREPLY[${#COMPREPLY[@]}]=$alias ;; esac - done < <(git config \ - --get-regexp '^alias\.' \ - 2>/dev/null) + done < <(git config --get-regexp '^alias\.' 2>/dev/null) return ;; -- cgit v1.2.3 From dcf821666fbe32735e220688956268ee40e2af17 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:27:55 +1300 Subject: Remove unneeded quoting in case statement --- bash/bash_completion.d/find.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bash/bash_completion.d/find.bash b/bash/bash_completion.d/find.bash index 85cadfaf..7e2ae9c3 100644 --- a/bash/bash_completion.d/find.bash +++ b/bash/bash_completion.d/find.bash @@ -64,7 +64,7 @@ _find() { # Otherwise, look at the word *before* this one to figure out what to # complete - case "${COMP_WORDS[COMP_CWORD-1]}" in + case ${COMP_WORDS[COMP_CWORD-1]} in # Args to -exec and -execdir should be commands (-exec|-execdir) -- cgit v1.2.3 From 0681de59778f82c9006de70ed9a9ee6644fd4a18 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:29:42 +1300 Subject: Adjust loop short circuits and pattern matches --- bash/bash_completion.d/bd.bash | 7 +++++-- bash/bash_completion.d/eds.bash | 4 +++- bash/bash_completion.d/git.bash | 5 +++-- bash/bash_completion.d/gpg.bash | 11 ++++++++--- bash/bash_completion.d/make.bash | 7 ++++--- bash/bash_completion.d/man.bash | 10 +++++++--- bash/bash_completion.d/mex.bash | 3 ++- bash/bash_completion.d/path.bash | 7 +++++-- bash/bash_completion.d/sd.bash | 10 +++++++--- bash/bash_completion.d/ud.bash | 1 + 10 files changed, 45 insertions(+), 20 deletions(-) diff --git a/bash/bash_completion.d/bd.bash b/bash/bash_completion.d/bd.bash index 1c1a40a8..120080c3 100644 --- a/bash/bash_completion.d/bd.bash +++ b/bash/bash_completion.d/bd.bash @@ -15,8 +15,11 @@ _bd() { # 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") + case $dirname in + "${COMP_WORDS[COMP_CWORD]}"*) + COMPREPLY[${#COMPREPLY[@]}]=$(printf %q "$dirname") + ;; + esac done } complete -F _bd bd diff --git a/bash/bash_completion.d/eds.bash b/bash/bash_completion.d/eds.bash index 0b5e34ea..1c5b2aa2 100644 --- a/bash/bash_completion.d/eds.bash +++ b/bash/bash_completion.d/eds.bash @@ -25,7 +25,9 @@ _eds() { files=("${EDSPATH:-"$HOME"/.local/bin}"/"${COMP_WORDS[COMP_CWORD]}"*) declare -a executables for file in "${files[@]}" ; do - [[ -f $file && -x $file ]] || continue + ! [[ -d $file ]] || continue + [[ -e $file ]] || continue + [[ -x $file ]] || continue executables[${#executables[@]}]=${file##*/} done diff --git a/bash/bash_completion.d/git.bash b/bash/bash_completion.d/git.bash index 28313f76..a2edb468 100644 --- a/bash/bash_completion.d/git.bash +++ b/bash/bash_completion.d/git.bash @@ -12,9 +12,9 @@ _git() { refs) local ref while IFS= read -r ref ; do - [[ -n $ref ]] || continue ref=${ref#refs/*/} case $ref in + '') continue ;; "${COMP_WORDS[COMP_CWORD]}"*) COMPREPLY[${#COMPREPLY[@]}]=$ref ;; @@ -59,7 +59,8 @@ _git() { execpath=$(git --exec-path) || return local path for path in "$execpath"/git-"${COMP_WORDS[COMP_CWORD]}"* ; do - [[ -f $path ]] || continue + ! [[ -d $path ]] || continue + [[ -e $path ]] || continue [[ -x $path ]] || continue COMPREPLY[${#COMPREPLY[@]}]=${path#"$execpath"/git-} done diff --git a/bash/bash_completion.d/gpg.bash b/bash/bash_completion.d/gpg.bash index 2855a1a9..0f6785f9 100644 --- a/bash/bash_completion.d/gpg.bash +++ b/bash/bash_completion.d/gpg.bash @@ -5,13 +5,18 @@ _gpg() { hash gpg 2>/dev/null || return 1 # Bail if not completing an option - [[ ${COMP_WORDS[COMP_CWORD]} == --* ]] || return 1 + case ${COMP_WORDS[COMP_CWORD]} in + --*) return 1 ;; + esac # Generate completion reply from gpg(1) options local option while read -r option ; do - [[ $option == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$option + case $option in + "${COMP_WORDS[COMP_CWORD]}"*) + COMPREPLY[${#COMPREPLY[@]}]=$option + ;; + esac done < <(gpg --dump-options 2>/dev/null) } complete -F _gpg -o bashdefault -o default gpg diff --git a/bash/bash_completion.d/make.bash b/bash/bash_completion.d/make.bash index c36a039a..0f39ef4b 100644 --- a/bash/bash_completion.d/make.bash +++ b/bash/bash_completion.d/make.bash @@ -5,9 +5,10 @@ _make() { # first, then "Makefile"). You may want to add "GNU-makefile" after this. local mf for mf in makefile Makefile '' ; do - [[ -f $mf ]] && break + [[ -e $mf ]] || continue + break done - [[ -n $mf ]] || return 1 + [[ -n $mf ]] || return # Iterate through the Makefile, line by line local line @@ -39,7 +40,7 @@ _make() { *[^[:word:]./-]*) ;; # Add targets that match what we're completing - ${COMP_WORDS[COMP_CWORD]}*) + "${COMP_WORDS[COMP_CWORD]}"*) COMPREPLY[${#COMPREPLY[@]}]=$target ;; esac diff --git a/bash/bash_completion.d/man.bash b/bash/bash_completion.d/man.bash index fcf26436..7574db40 100644 --- a/bash/bash_completion.d/man.bash +++ b/bash/bash_completion.d/man.bash @@ -17,9 +17,13 @@ _man() { # 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]*} + if ((COMP_CWORD > 1)) ; then + case ${COMP_WORDS[COMP_CWORD-1]} in + [0-9]*) + section=${COMP_WORDS[COMP_CWORD-1]} + subdir=man${section%%[^0-9]*} + ;; + esac fi # Read completion results from a subshell and add them to the COMPREPLY diff --git a/bash/bash_completion.d/mex.bash b/bash/bash_completion.d/mex.bash index d25f1824..bc3d2c7b 100644 --- a/bash/bash_completion.d/mex.bash +++ b/bash/bash_completion.d/mex.bash @@ -6,7 +6,8 @@ _mex() { for dir in "${path[@]}" ; do [[ -d $dir ]] || continue for name in "$dir"/* ; do - [[ -f $name ]] || continue + [[ -e $name ]] || continue + ! [[ -d $name ]] || continue ! [[ -x $name ]] || continue COMPREPLY[${#COMPREPLY[@]}]=${name##*/} done diff --git a/bash/bash_completion.d/path.bash b/bash/bash_completion.d/path.bash index fcb57949..9aab8488 100644 --- a/bash/bash_completion.d/path.bash +++ b/bash/bash_completion.d/path.bash @@ -52,8 +52,11 @@ _path() { IFS=: read -rd '' -a promptarr < <(printf '%s\0' "$PATH") local part for part in "${promptarr[@]}" ; do - [[ $part == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=$(printf '%q' "$part") + case $part in + "${COMP_WORDS[COMP_CWORD]}"*) + COMPREPLY[${#COMPREPLY[@]}]=$(printf '%q' "$part") + ;; + esac done ;; diff --git a/bash/bash_completion.d/sd.bash b/bash/bash_completion.d/sd.bash index 2d2d8f22..1194b33a 100644 --- a/bash/bash_completion.d/sd.bash +++ b/bash/bash_completion.d/sd.bash @@ -5,7 +5,9 @@ _sd() { ((COMP_CWORD == 1)) || return 1 # Current directory can't be root directory - [[ $PWD != / ]] || return 1 + case $PWD in + /) return 1 ;; + esac # Build list of matching sibling directories local dirname @@ -37,8 +39,10 @@ _sd() { local -a sibs local dirname for dirname in "${dirnames[@]}" ; do - [[ $dirname != "${PWD##*/}" ]] || continue - sibs[${#sibs[@]}]=$dirname + case $dirname in + "${PWD##*/}") ;; + *) sibs[${#sibs[@]}]=$dirname ;; + esac done # Print quoted sibling directories, null-delimited diff --git a/bash/bash_completion.d/ud.bash b/bash/bash_completion.d/ud.bash index 278fbbc3..9ded41e6 100644 --- a/bash/bash_completion.d/ud.bash +++ b/bash/bash_completion.d/ud.bash @@ -7,6 +7,7 @@ _ud() { # Iterate through directories, null-separated, add them to completions local dirname while IFS= read -rd '' dirname ; do + [[ -n "$dirname" ]] || continue COMPREPLY[${#COMPREPLY[@]}]=$dirname done < <( -- cgit v1.2.3 From c3af0c31efbc23472a103536280a4d839555e198 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:32:30 +1300 Subject: Remove redundant error code in short circuits --- bash/bash_completion.d/bd.bash | 4 ++-- bash/bash_completion.d/ftp.bash | 2 +- bash/bash_completion.d/gpg.bash | 2 +- bash/bash_completion.d/man.bash | 2 +- bash/bash_completion.d/mysql.bash | 4 ++-- bash/bash_completion.d/pass.bash | 2 +- bash/bash_completion.d/sd.bash | 2 +- bash/bash_completion.d/ud.bash | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bash/bash_completion.d/bd.bash b/bash/bash_completion.d/bd.bash index 120080c3..e67cdd09 100644 --- a/bash/bash_completion.d/bd.bash +++ b/bash/bash_completion.d/bd.bash @@ -2,14 +2,14 @@ _bd() { # Only makes sense for the first argument - ((COMP_CWORD == 1)) || return 1 + ((COMP_CWORD == 1)) || return # Build a list of dirnames in $PWD local -a dirnames IFS=/ read -rd '' -a dirnames < <(printf '%s\0' "${PWD#/}") # Remove the last element in the array (the current directory) - ((${#dirnames[@]})) || return 1 + ((${#dirnames[@]})) || return dirnames=("${dirnames[@]:0:${#dirnames[@]}-1}") # Add the matching dirnames to the reply diff --git a/bash/bash_completion.d/ftp.bash b/bash/bash_completion.d/ftp.bash index d7ee8963..a584dd81 100644 --- a/bash/bash_completion.d/ftp.bash +++ b/bash/bash_completion.d/ftp.bash @@ -4,7 +4,7 @@ _ftp() { # Bail if the .netrc file is illegible local netrc netrc=$HOME/.netrc - [[ -r $netrc ]] || return 1 + [[ -r $netrc ]] || return # Tokenize the file local -a tokens diff --git a/bash/bash_completion.d/gpg.bash b/bash/bash_completion.d/gpg.bash index 0f6785f9..697e4a65 100644 --- a/bash/bash_completion.d/gpg.bash +++ b/bash/bash_completion.d/gpg.bash @@ -2,7 +2,7 @@ _gpg() { # Bail if no gpg(1) - hash gpg 2>/dev/null || return 1 + hash gpg 2>/dev/null || return # Bail if not completing an option case ${COMP_WORDS[COMP_CWORD]} in diff --git a/bash/bash_completion.d/man.bash b/bash/bash_completion.d/man.bash index 7574db40..e4175837 100644 --- a/bash/bash_completion.d/man.bash +++ b/bash/bash_completion.d/man.bash @@ -2,7 +2,7 @@ _man() { # Don't even bother if we don't have manpath(1) - hash manpath 2>/dev/null || return 1 + hash manpath 2>/dev/null || return # Snarf the word local word diff --git a/bash/bash_completion.d/mysql.bash b/bash/bash_completion.d/mysql.bash index 413f3386..3ff97090 100644 --- a/bash/bash_completion.d/mysql.bash +++ b/bash/bash_completion.d/mysql.bash @@ -2,12 +2,12 @@ _mysql() { # Only makes sense for first argument - ((COMP_CWORD == 1)) || return 1 + ((COMP_CWORD == 1)) || return # Bail if directory doesn't exist local dirname dirname=$HOME/.mysql - [[ -d $dirname ]] || return 1 + [[ -d $dirname ]] || return # Return the names of the .cnf files sans prefix as completions local db diff --git a/bash/bash_completion.d/pass.bash b/bash/bash_completion.d/pass.bash index 1df8dfb1..176886dc 100644 --- a/bash/bash_completion.d/pass.bash +++ b/bash/bash_completion.d/pass.bash @@ -8,7 +8,7 @@ _pass() # If we can't read the password directory, just bail local passdir passdir=${PASSWORD_STORE_DIR:-"$HOME"/.password-store} - [[ -r $passdir ]] || return 1 + [[ -r $passdir ]] || return # Iterate through list of .gpg paths, extension stripped, null-delimited, # and filter them down to the ones matching the completing word (compgen diff --git a/bash/bash_completion.d/sd.bash b/bash/bash_completion.d/sd.bash index 1194b33a..e7e82f80 100644 --- a/bash/bash_completion.d/sd.bash +++ b/bash/bash_completion.d/sd.bash @@ -2,7 +2,7 @@ _sd() { # Only makes sense for the first argument - ((COMP_CWORD == 1)) || return 1 + ((COMP_CWORD == 1)) || return # Current directory can't be root directory case $PWD in diff --git a/bash/bash_completion.d/ud.bash b/bash/bash_completion.d/ud.bash index 9ded41e6..5170eb57 100644 --- a/bash/bash_completion.d/ud.bash +++ b/bash/bash_completion.d/ud.bash @@ -2,7 +2,7 @@ _ud() { # Only makes sense for the second argument - ((COMP_CWORD == 2)) || return 1 + ((COMP_CWORD == 2)) || return # Iterate through directories, null-separated, add them to completions local dirname -- cgit v1.2.3 From 59cdb7f73046054e779723dd6ca185ac2615081d Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:33:10 +1300 Subject: Remove unneeded empty result short circuit --- bash/bash_completion.d/ud.bash | 3 --- 1 file changed, 3 deletions(-) diff --git a/bash/bash_completion.d/ud.bash b/bash/bash_completion.d/ud.bash index 5170eb57..2311ae3c 100644 --- a/bash/bash_completion.d/ud.bash +++ b/bash/bash_completion.d/ud.bash @@ -29,9 +29,6 @@ _ud() { 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[@]}" ) -- cgit v1.2.3 From e66e52276df6cc1c0f91d0a3d955ef9860be1c94 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:33:18 +1300 Subject: Remove unneeded local array declaration --- bash/bash_completion.d/ud.bash | 1 - 1 file changed, 1 deletion(-) diff --git a/bash/bash_completion.d/ud.bash b/bash/bash_completion.d/ud.bash index 2311ae3c..c7dee582 100644 --- a/bash/bash_completion.d/ud.bash +++ b/bash/bash_completion.d/ud.bash @@ -25,7 +25,6 @@ _ud() { done < <(bind -v) # Collect directory names, strip trailing slashes - local -a dirnames dirnames=("${COMP_WORDS[COMP_CWORD]}"*/) dirnames=("${dirnames[@]%/}") -- cgit v1.2.3 From 18d31e8c13cf8ae97a16bfcf949dbae5391a47f2 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:33:33 +1300 Subject: Break up a couple of long lines --- bash/bash_completion.d/man.bash | 4 +++- bash/bash_completion.d/path.bash | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bash/bash_completion.d/man.bash b/bash/bash_completion.d/man.bash index e4175837..ffef48ec 100644 --- a/bash/bash_completion.d/man.bash +++ b/bash/bash_completion.d/man.bash @@ -58,7 +58,9 @@ _man() { for manpath in "${manpaths[@]}" ; do [[ -n $manpath ]] || continue if [[ -n $section ]] ; then - for page in "$manpath"/"$subdir"/"$word"*."$section"?(.[glx]z|.bz2|.lzma|.Z) ; do + for page in \ + "$manpath"/"$subdir"/"$word"*."$section"?(.[glx]z|.bz2|.lzma|.Z) + do pages[${#pages[@]}]=$page done else diff --git a/bash/bash_completion.d/path.bash b/bash/bash_completion.d/path.bash index 9aab8488..ce494bd4 100644 --- a/bash/bash_completion.d/path.bash +++ b/bash/bash_completion.d/path.bash @@ -49,7 +49,8 @@ _path() { # Complete with directories from PATH remove) local -a promptarr - IFS=: read -rd '' -a promptarr < <(printf '%s\0' "$PATH") + IFS=: read -rd '' -a promptarr < \ + <(printf '%s\0' "$PATH") local part for part in "${promptarr[@]}" ; do case $part in -- cgit v1.2.3 From d6ed64f18cfccf1e6ffb5e5609f758beaec21def Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:34:04 +1300 Subject: Use simpler keyword complete for `path` subcommand --- bash/bash_completion.d/path.bash | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/bash/bash_completion.d/path.bash b/bash/bash_completion.d/path.bash index ce494bd4..7143b448 100644 --- a/bash/bash_completion.d/path.bash +++ b/bash/bash_completion.d/path.bash @@ -6,10 +6,18 @@ _path() { # Complete operation as first word local cmd - for cmd in list insert append remove shift pop check help ; do - [[ $cmd == "${COMP_WORDS[COMP_CWORD]}"* ]] || continue + while read -r cmd ; do COMPREPLY[${#COMPREPLY[@]}]=$cmd - done + done < <(compgen -W ' + append + check + help + insert + list + pop + remove + shift + ' -- "${COMP_WORDS[COMP_CWORD]}") # Complete with either directories or $PATH entries as all other words else -- cgit v1.2.3 From 9af93d72284d22b24e27080e38231f32c2e45f54 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:44:17 +1300 Subject: Restore correct completion function for mutt(1) This was mistakenly changed to _text_filenames in 65e47bf. --- bash/bash_completion.d/mutt.bash | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bash/bash_completion.d/mutt.bash b/bash/bash_completion.d/mutt.bash index 5fb13339..002eb48e 100644 --- a/bash/bash_completion.d/mutt.bash +++ b/bash/bash_completion.d/mutt.bash @@ -1,5 +1,5 @@ # Completion for mutt(1) with abook(1) email addresses -if ! declare -F _text_filenames >/dev/null ; then - source "$HOME"/.bash_completion.d/_text_filenames.bash +if ! declare -F _abook_addresses >/dev/null ; then + source "$HOME"/.bash_completion.d/_abook_addresses.bash fi complete -F _abook_addresses -o bashdefault -o default mutt -- cgit v1.2.3 From 527b544538e7309ee0bd6a2108755bfd8e3c2bca Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:46:21 +1300 Subject: Overhaul and expand abook address Bash completion --- bash/bash_completion.d/_abook_addresses.bash | 37 ++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/bash/bash_completion.d/_abook_addresses.bash b/bash/bash_completion.d/_abook_addresses.bash index 8e341172..e79eef42 100644 --- a/bash/bash_completion.d/_abook_addresses.bash +++ b/bash/bash_completion.d/_abook_addresses.bash @@ -1,10 +1,33 @@ # Email addresses from abook(1) _abook_addresses() { - while IFS=$'\t' read -r address _ ; do - case $address in - "${COMP_WORDS[COMP_CWORD]}"*) - COMPREPLY[${#COMPREPLY[@]}]=$address - ;; - esac - done < <(abook --mutt-query \@) + + # Needs abook(1) + hash abook 2>/dev/null || return + + # Iterate through words produced by subshell + local word + while read -r word ; do + [[ -n $word ]] || continue + COMPREPLY[${#COMPREPLY[@]}]=$word + done < <( + + # Set case-insensitive matching if appropriate + while read -r _ setting ; do + case $setting in + ('completion-ignore-case on') + shopt -s nocasematch 2>/dev/null + break + ;; + esac + done < <(bind -v) + + # Generate list of email addresses from abook(1) + while IFS=$'\t' read -r address _ ; do + case $address in + ("${COMP_WORDS[COMP_CWORD]}"*) + printf '%s\n' "$address" + ;; + esac + done < <(abook --mutt-query \@) + ) } -- cgit v1.2.3 From 9bfab4f00574742e3aa25e3447776dd821714fce Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Dec 2018 02:48:02 +1300 Subject: Bump VERSION --- VERSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index a7367f3b..8e55d49a 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ -tejr dotfiles v2.5.0 -Fri Nov 30 01:30:00 UTC 2018 +tejr dotfiles v2.6.0 +Fri Nov 30 13:48:02 UTC 2018 -- cgit v1.2.3