mirror of
https://github.com/jimeh/dotfiles.git
synced 2026-02-19 07:46:39 +00:00
fix(shell/1password): automatically resolve shell completion issues
1Password's shell plugin integration is nice, but it currently uses aliases to run various CLI tools through `op plugin run -- <tool>`. This leads to shell completion for those tools not working correctly in bash and zsh. While zsh can work around that with `setopt completealiases`, it causes shorthand aliases to break instead. Hence the only reasonable solution is to replace the aliases with shell functions. Previously I had manually been editing ~/.config/op/plugins.sh replacing the aliases with functions. This is an automated solution that generates unalias calls and function definitions for all 1Password aliases. It is also efficient by means of writing the generated functions to a cache file which is only updated when needed.
This commit is contained in:
@@ -2,7 +2,86 @@
|
||||
# 1Password CLI integration
|
||||
#
|
||||
|
||||
# Load 1Password CLI plugins if available.
|
||||
if [ -f "$HOME/.config/op/plugins.sh" ]; then
|
||||
source "$HOME/.config/op/plugins.sh"
|
||||
fi
|
||||
# Setup 1Password CLI shell plugin integration using functions instead of
|
||||
# aliases. This is necessary for shell completion to work correctly with aliases
|
||||
# to commands which have 1Password integration enabled.
|
||||
#
|
||||
# This function a hacky-ish workaround to the issue described here:
|
||||
# https://github.com/1Password/shell-plugins/issues/433
|
||||
#
|
||||
# It loads the 1Password CLI plugin script file, then finds all aliases that are
|
||||
# 1Password shell plugin aliases and converts them to functions. The functions
|
||||
# are then stored in a cache file, which is sourced every time the shell is
|
||||
# started.
|
||||
#
|
||||
# The cache file is only updated if the plugins script file is newer than the
|
||||
# cache file. This is to prevent the cache file from being updated every time
|
||||
# the shell is started.
|
||||
#
|
||||
# To use this function, simply call it once during shell startup, and it will
|
||||
# take care of the rest.
|
||||
#
|
||||
# Arguments:
|
||||
# $1: The script file containing the 1Password CLI plugin aliases. Default is
|
||||
# $HOME/.config/op/plugins.sh.
|
||||
# $2: The cache file to store the converted functions. Default is
|
||||
# $HOME/.config/op/plugins_as_functions.cache.sh.
|
||||
setup_op_shell_plugins_using_functions() {
|
||||
local script_file="${1:-$HOME/.config/op/plugins.sh}"
|
||||
local cache_file="${2:-$HOME/.config/op/plugins_as_functions.cache.sh}"
|
||||
|
||||
# Silently return if the script file doesn't exist.
|
||||
if [ ! -f "$script_file" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Source the script file.
|
||||
source "$script_file"
|
||||
|
||||
# If cache file exists, and is newer than the plugin script file, just source
|
||||
# the cache file and return.
|
||||
if [ -f "$cache_file" ] && [ "$script_file" -ot "$cache_file" ]; then
|
||||
source "$cache_file"
|
||||
return
|
||||
fi
|
||||
|
||||
# Get all aliases that use "op plugin run --".
|
||||
local aliases="$(alias | grep 'op plugin run --')"
|
||||
|
||||
# If no aliases are found, just clear the cache file and return.
|
||||
if [ -z "$aliases" ]; then
|
||||
echo -n "" > "$cache_file"
|
||||
return
|
||||
fi
|
||||
|
||||
# Loop through each alias, convert it to a function, and store it in the cache
|
||||
# file.
|
||||
local command
|
||||
local alias_name
|
||||
local raw_command
|
||||
while IFS= read -r line; do
|
||||
# Remove Bash's "alias " prefix if present.
|
||||
line="${line#alias }"
|
||||
|
||||
# Extract the alias name and the raw command.
|
||||
alias_name="$(echo "$line" | cut -d'=' -f1)"
|
||||
raw_command="$(echo "$line" | cut -d'=' -f2)"
|
||||
|
||||
# Evaluate the raw command to ensure we get the correct command, with any
|
||||
# quotes or shell escape characters handled correctly.
|
||||
eval "command=$raw_command"
|
||||
|
||||
# Skip if command is empty or does not start with "op plugin run --".
|
||||
if [ -z "$command" ] || [[ "$command" != "op plugin run --"* ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Print the unalias command and the function definition.
|
||||
echo -e "unalias ${alias_name}"
|
||||
echo -e "${alias_name}() {\n ${command} \"\$@\"\n}"
|
||||
done <<< "$aliases" > "$cache_file"
|
||||
}
|
||||
|
||||
# Setup 1Password CLI shell plugin integration with custom function that makes
|
||||
# it play nicer with shell completion.
|
||||
setup_op_shell_plugins_using_functions
|
||||
|
||||
Reference in New Issue
Block a user