Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for abbreviations #133

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 107 additions & 11 deletions you-should-use.plugin.zsh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/zsh

export YSU_VERSION='1.7.3'
export YSU_VERSION='1.7.4'

if ! type "tput" > /dev/null; then
printf "WARNING: tput command not found on your PATH.\n"
Expand All @@ -17,7 +17,7 @@ function check_alias_usage() {
# Optional parameter that limits how far back history is checked
# I've chosen a large default value instead of bypassing tail because it's simpler
# TODO: this should probably be cleaned up
local limit="${1:-9000000000000000}"
local limit="${1:-$HISTSIZE}"
local key

declare -A usage
Expand All @@ -40,7 +40,7 @@ function check_alias_usage() {
for entry in ${(@s/|/)line}; do
# Remove leading whitespace
# TODO: This is extremely slow
entry="$(echo "$entry" | sed -e 's/^ *//')"
entry="${entry## }"

# We only care about the first word because that's all aliases work with
# (this does not count global and git aliases)
Expand Down Expand Up @@ -89,13 +89,29 @@ function _flush_ysu_buffer() {
}

function ysu_message() {
local DEFAULT_MESSAGE_FORMAT="${BOLD}${YELLOW}\
Found existing %alias_type for ${PURPLE}\"%command\"${YELLOW}. \
You should use: ${PURPLE}\"%alias\"${NONE}"

local alias_type_arg="${1}"
local command_arg="${2}"
local alias_arg="${3}"
DEFAULT_MESSAGE_FORMAT=""
# Determine message format based on message type and whether it's enabled
case "$alias_type_arg" in
"abbreviation")
if zstyle -t ':you-should-use:*' you_should_use_abbreviation_enabled; then
DEFAULT_MESSAGE_FORMAT="${BOLD} ${PURPLE}\"$command_arg\"${YELLOW} -> ${PURPLE}\"$alias_arg\"${NONE}"
fi
;;
"alias")
if zstyle -t ':you-should-use:*' you_should_use_alias_enabled; then
local DEFAULT_MESSAGE_FORMAT="${BOLD}${YELLOW}\
Found existing %alias_type for ${PURPLE}\"%command\"${YELLOW}. \
You should use: ${PURPLE}\"%alias\"${NONE}"
fi
;;
*)
local DEFAULT_MESSAGE_FORMAT="${BOLD}${YELLOW}\
Found existing %alias_type for ${PURPLE}\"%command\"${YELLOW}. \
You should use: ${PURPLE}\"%alias\"${NONE}"
esac

# Escape arguments which will be interpreted by printf incorrectly
# unfortunately there does not seem to be a nice way to put this into
Expand All @@ -111,7 +127,6 @@ You should use: ${PURPLE}\"%alias\"${NONE}"
_write_ysu_buffer "$MESSAGE\n"
}


# Prevent command from running if hardcore mode enabled
function _check_ysu_hardcore() {
if [[ "$YSU_HARDCORE" = 1 ]]; then
Expand All @@ -120,7 +135,6 @@ function _check_ysu_hardcore() {
fi
}


function _check_git_aliases() {
local typed="$1"
local expanded="$2"
Expand All @@ -135,6 +149,13 @@ function _check_git_aliases() {
git config --get-regexp "^alias\..+$" | sort | while read key value; do
key="${key#alias.}"

# if for some reason, read does not split correctly, we
# detect that and manually split the key and value
if [[ -z "$value" ]]; then
value="${key#* }"
key="${key%% *}"
fi

if [[ "$expanded" = "git $value" || "$expanded" = "git $value "* ]]; then
ysu_message "git alias" "$value" "git $key"
found=true
Expand Down Expand Up @@ -166,7 +187,6 @@ function _check_global_aliases() {
alias -g | sort | while read entry; do
tokens=("${(@s/=/)entry}")
key="${tokens[1]}"
# Need to remove leading and trailing ' if they exist
value="${(Q)tokens[2]}"

# Skip ignored global aliases
Expand All @@ -188,7 +208,6 @@ function _check_global_aliases() {
fi
}


function _check_aliases() {
local typed="$1"
local expanded="$2"
Expand Down Expand Up @@ -260,11 +279,79 @@ function _check_aliases() {
fi
}

function load_abbrs() {
# Check if abbreviation feature is enabled
if ! zstyle -T ':you-should-use:*' you_should_use_abbreviation_enabled; then
return
fi

# Check if zsh-abbr is installed
if ! type abbr >/dev/null 2>&1; then
echo "zsh-abbr is not installed or enabled. Install it from https://zsh-abbr.olets.dev/ to use this feature."
# Attempt to load from file if abbr command is not available
load_abbrs_from_file
return
fi

# Load abbreviations using abbr command
typeset -gA abbrs
abbr list | while IFS="=" read -r abbr_cmd abbr_expansion; do
# Process and remove outer quotes and extra spaces
abbr_cmd="${abbr_cmd//\"/}"
abbr_cmd="${abbr_cmd## }"
abbr_cmd="${abbr_cmd%% }"
abbr_expansion="${abbr_expansion//\"/}"
abbr_expansion="${abbr_expansion## }"
abbr_expansion="${abbr_expansion%% }"

# Store in associative array with command as key and abbreviation as value
abbrs[$abbr_expansion]=$abbr_cmd
done
}

function load_abbrs_from_file() {
local abbr_file="$ABBR_USER_ABBREVIATIONS_FILE"
if [[ -z ${ABBR_USER_ABBREVIATIONS_FILE:-} && ! -f ${ABBR_USER_ABBREVIATIONS_FILE:-} ]]; then
echo "zsh-abbr is not installed or enabled. Install it from https://zsh-abbr.olets.dev/ to use this feature."
zstyle ':you-should-use:*' you_should_use_abbreviation_enabled false
return
fi
declare -gA abbrs # Ensure 'abbrs' is declared as a global associative array
local line abbr_cmd abbr_expansion

while IFS="" read -r line || [[ -n $line ]]; do
if [[ "$line" =~ ^abbr\ \"([^\"]+)\"\=\"([^\"]+)\" ]]; then
abbr_cmd=${BASH_REMATCH[1]}
abbr_expansion=${BASH_REMATCH[2]}
abbrs[$abbr_expansion]=$abbr_cmd
fi
done < "$abbr_file"
}

function _check_abbrs() {
if ! zstyle -T ':you-should-use:*' you_should_use_abbreviation_enabled; then
return
fi
local typed="$1"
local abbr_match="${abbrs[$typed]}"

if [[ -n "$abbr_match" ]]; then
ysu_message "abbreviation" "$typed" "$abbr_match"
if [[ "$YSU_HARDCORE" = 1 ]]; then
_write_ysu_buffer "${BOLD}${RED}You Should Use abbreviation mode enabled. Use your abbreviation!${NONE}\n"
kill -s INT $$
fi
fi
}

function disable_you_should_use() {
add-zsh-hook -D preexec _check_aliases
add-zsh-hook -D preexec _check_global_aliases
add-zsh-hook -D preexec _check_git_aliases
add-zsh-hook -D precmd _flush_ysu_buffer
if zstyle -T ':you-should-use:*' you_should_use_abbreviation_enabled; then
add-zsh-hook -D preexec _check_abbrs
fi
}

function enable_you_should_use() {
Expand All @@ -273,7 +360,16 @@ function enable_you_should_use() {
add-zsh-hook preexec _check_global_aliases
add-zsh-hook preexec _check_git_aliases
add-zsh-hook precmd _flush_ysu_buffer
if zstyle -T ':you-should-use:*' you_should_use_abbreviation_enabled; then
add-zsh-hook preexec _check_abbrs
fi
}

zstyle ':you-should-use:*' you_should_use_alias_enabled true
zstyle ':you-should-use:*' you_should_use_abbreviation_enabled false

autoload -Uz add-zsh-hook
enable_you_should_use
if zstyle -T ':you-should-use:*' you_should_use_abbreviation_enabled; then
load_abbrs
fi