From f56eb6de318893bae3c84e42fd20f40f649716a9 Mon Sep 17 00:00:00 2001 From: deb0ch Date: Mon, 22 Nov 2021 18:47:02 +0100 Subject: [PATCH] feat(expressvpn): add plugin for ExpressVPN This fix makes the autocompletion script also work on zsh without changing how it works for Bash. The expression "${COMP_WORDS[@]:2:$COMP_CWORD-2}" does not behave the same on Bash and Zsh when the command has only zero or one arguments, e.g. typing "expressvpn conne" or "expressvpn " would print the error "autocomplete:8: substring expression: 1 < 2". This fixes it by handling the case of the short command separately in a simpler way and handling the rest of the cases the same way as before. With this fix, zsh users just have to use the command "source /usr/share/bash-completion/completions/expressvpn" to get the same auto-completion as bash users. File : /usr/share/bash-completion/completions/expressvpn Diff to the original file (using the `diff` command) : 9a10,12 > opts=$( ${COMP_WORDS[0]} "$cmd" "${COMP_WORDS[@]:2:$COMP_CWORD-2}" --generate-bash-completion ) > else > opts=$( ${COMP_WORDS[0]} --generate-bash-completion ) 11d13 < opts=$( ${COMP_WORDS[0]} "$cmd" "${COMP_WORDS[@]:2:$COMP_CWORD-2}" --generate-bash-completion ) --- plugins/expressvpn/README.md | 14 ++++++++++ plugins/expressvpn/_expressvpn | 49 ++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 plugins/expressvpn/README.md create mode 100644 plugins/expressvpn/_expressvpn diff --git a/plugins/expressvpn/README.md b/plugins/expressvpn/README.md new file mode 100644 index 000000000..b34586801 --- /dev/null +++ b/plugins/expressvpn/README.md @@ -0,0 +1,14 @@ +# ExpressVPN + +This plugin provides completion support for [`ExpressVPN`](https://www.expressvpn.com/vpn-software/vpn-linux) +command line interface on Linux. + +To use it, add expressvpn to the plugins array in your zshrc file. + +```zsh +plugins=(... expressvpn) +``` + +## INSTALLATION NOTES + +Besides oh-my-zsh, `expressvpn` needs to be installed by following these steps: https://www.expressvpn.com/support/vpn-setup/app-for-linux/. diff --git a/plugins/expressvpn/_expressvpn b/plugins/expressvpn/_expressvpn new file mode 100644 index 000000000..b8f497e91 --- /dev/null +++ b/plugins/expressvpn/_expressvpn @@ -0,0 +1,49 @@ +#compdef expressvpn + +# bash completion for expressvpn -*- shell-script -*- + +_expressvpn_bash_autocomplete() { + local cur cmd opts + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + + if [ "$COMP_CWORD" -gt 1 ]; then + cmd="${COMP_WORDS[1]}" + opts=$( ${COMP_WORDS[0]} "$cmd" "${COMP_WORDS[@]:2:$COMP_CWORD-2}" --generate-bash-completion ) + else + opts=$( ${COMP_WORDS[0]} --generate-bash-completion ) + fi + + local IFS=$'\n' + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + + local escaped_single_qoute="\\'" + local i=0 + for entry in ${COMPREPLY[*]} + do + if [[ "${cur:0:1}" == "'" ]] + then + # started with single quote, escaping only other single quotes + # [']bla'bla"bla\bla bla --> [']bla'\''bla"bla\bla bla + COMPREPLY[$i]="${entry//\'/${escaped_single_qoute}}" + elif [[ "${cur:0:1}" == "\"" ]] + then + # started with double quote, escaping all double quotes and all backslashes + # ["]bla'bla"bla\bla bla --> ["]bla'bla\"bla\\bla bla + entry="${entry//\\/\\\\}" + COMPREPLY[$i]="${entry//\"/\\\"}" + else + # no quotes in front, escaping _everything_ + # [ ]bla'bla"bla\bla bla --> [ ]bla\'bla\"bla\\bla\ bla + entry="${entry//\\/\\\\}" + entry="${entry//\'/\'}" + entry="${entry//\"/\\\"}" + COMPREPLY[$i]="${entry// /\\ }" + fi + (( i++ )) + done + + return 0 +} + +complete -F _expressvpn_bash_autocomplete expressvpn