aboutsummaryrefslogtreecommitdiffhomepage
path: root/share/functions/abbr.fish
diff options
context:
space:
mode:
Diffstat (limited to 'share/functions/abbr.fish')
-rw-r--r--share/functions/abbr.fish167
1 files changed, 167 insertions, 0 deletions
diff --git a/share/functions/abbr.fish b/share/functions/abbr.fish
new file mode 100644
index 00000000..ce104f12
--- /dev/null
+++ b/share/functions/abbr.fish
@@ -0,0 +1,167 @@
+function abbr --description "Manage abbreviations"
+ if not set -q argv[1]
+ __fish_print_help abbr
+ return 1
+ end
+
+ # parse arguments
+ set -l mode
+ set -l mode_flag # the flag that was specified, for better errors
+ set -l mode_arg
+ set -l needs_arg no
+ while set -q argv[1]
+ if test $needs_arg = yes
+ set mode_arg $argv[1]
+ set needs_arg no
+ else
+ set -l new_mode
+ switch $argv[1]
+ case '-h' '--help'
+ __fish_print_help abbr
+ return 0
+ case '-a' '--add'
+ set new_mode add
+ set needs_arg yes
+ case '-r' '--remove'
+ set new_mode remove
+ set needs_arg yes
+ case '-l' '--list'
+ set new_mode list
+ case '-s' '--show'
+ set new_mode show
+ case '--'
+ set -e argv[1]
+ break
+ case '-*'
+ printf ( _ "%s: invalid option -- %s\n" ) abbr $argv[1] >&2
+ return 1
+ case '*'
+ break
+ end
+ if test -n "$mode" -a -n "$new_mode"
+ # we're trying to set two different modes
+ printf ( _ "%s: %s cannot be specified along with %s\n" ) abbr $argv[1] $mode_flag >&2
+ return 1
+ end
+ set mode $new_mode
+ set mode_flag $argv[1]
+ end
+ set -e argv[1]
+ end
+ if test $needs_arg = yes
+ printf ( _ "%s: option requires an argument -- %s\n" ) abbr $mode_flag >&2
+ return 1
+ end
+
+ # none of our modes want any excess arguments
+ if set -q argv[1]
+ printf ( _ "%s: Unexpected argument -- %s\n" ) abbr $argv[1] >&2
+ return 1
+ end
+
+ switch $mode
+ case 'add'
+ set -l key
+ set -l value
+ __fish_abbr_parse_entry $mode_arg key value
+ # ensure the key contains at least one non-space character
+ set -l IFS \n\ \t
+ printf '%s' $key | read -lz key_ __
+ if test -z "$key_"
+ printf ( _ "%s: abbreviation must have a non-empty key\n" ) abbr >&2
+ return 1
+ end
+ if test -z "$value"
+ printf ( _ "%s: abbreviation must have a value\n" ) abbr >&2
+ return 1
+ end
+ if set -l idx (__fish_abbr_get_by_key $key)
+ # erase the existing abbreviation
+ set -e fish_user_abbreviations[$idx]
+ end
+ if not set -q fish_user_abbreviations
+ # initialize as a universal variable, so we can skip the -U later
+ # and therefore work properly if someone sets this as a global variable
+ set -U fish_user_abbreviations
+ end
+ set fish_user_abbreviations $fish_user_abbreviations $mode_arg
+ return 0
+
+ case 'remove'
+ set -l key
+ __fish_abbr_parse_entry $mode_arg key
+ if set -l idx (__fish_abbr_get_by_key $key)
+ set -e fish_user_abbreviations[$idx]
+ return 0
+ else
+ printf ( _ "%s: no such abbreviation '%s'\n" ) abbr $key >&2
+ return 2
+ end
+
+ case 'show'
+ for i in $fish_user_abbreviations
+ # Disable newline splitting
+ set -lx IFS ''
+ echo abbr -a \'(__fish_abbr_escape $i)\'
+ end
+ return 0
+
+ case 'list'
+ for i in $fish_user_abbreviations
+ set -l key
+ __fish_abbr_parse_entry $i key
+ printf "%s\n" $key
+ end
+ return 0
+ end
+end
+
+function __fish_abbr_escape
+ echo $argv | sed -e s,\\\\,\\\\\\\\,g -e s,\',\\\\\',g
+end
+
+function __fish_abbr_get_by_key
+ if not set -q argv[1]
+ echo "__fish_abbr_get_by_key: expected one argument, got none" >&2
+ return 2
+ end
+ set -l count (count $fish_user_abbreviations)
+ if test $count -gt 0
+ set -l key
+ __fish_abbr_parse_entry $argv[1] key
+ set -l IFS \n # ensure newline splitting is enabled
+ for i in (seq $count)
+ set -l key_i
+ __fish_abbr_parse_entry $fish_user_abbreviations[$i] key_i
+ if test "$key" = "$key_i"
+ echo $i
+ return 0
+ end
+ end
+ end
+ return 1
+end
+
+function __fish_abbr_parse_entry -S -a __input __key __value
+ if test -z "$__key"
+ set __key __
+ end
+ if test -z "$__value"
+ set __value __
+ end
+ set -l IFS '= '
+ switch $__input
+ case '=*'
+ # read will skip any leading ='s, but we don't want that
+ set __input " $__input"
+ set __key _
+ set IFS '='
+ case ' =*'
+ set __key _
+ set IFS '='
+ end
+ # use read -z to avoid splitting on newlines
+ # I think we can safely assume there will be no NULs in the input
+ printf "%s" $__input | read -z $__key $__value
+ return 0
+end