Don't mangle arguments in abbr

This now (rightly) throws an error if there's a space in the
key (because we can't store it).

Fixes #2997.
This commit is contained in:
Fabian Homborg 2016-05-19 16:48:45 +02:00
parent dc470bcad3
commit 309e10e7a2
3 changed files with 24 additions and 28 deletions

View file

@ -8,8 +8,8 @@ function abbr --description "Manage abbreviations"
if test $needs_arg = single if test $needs_arg = single
set mode_arg $argv[1] set mode_arg $argv[1]
set needs_arg no set needs_arg no
else if test $needs_arg = coalesce else if test $needs_arg = multi
set mode_arg "$argv" set mode_arg $argv
set needs_arg no set needs_arg no
set -e argv set -e argv
else else
@ -20,7 +20,7 @@ function abbr --description "Manage abbreviations"
return 0 return 0
case '-a' '--add' case '-a' '--add'
set new_mode add set new_mode add
set needs_arg coalesce set needs_arg multi
case '-e' '--erase' case '-e' '--erase'
set new_mode erase set new_mode erase
set needs_arg single set needs_arg single
@ -57,7 +57,7 @@ function abbr --description "Manage abbreviations"
if test -z "$mode" if test -z "$mode"
if set -q argv[1] if set -q argv[1]
set mode 'add' set mode 'add'
set mode_arg "$argv" set mode_arg $argv
set -e argv set -e argv
else else
set mode 'show' set mode 'show'
@ -72,24 +72,23 @@ function abbr --description "Manage abbreviations"
switch $mode switch $mode
case 'add' case 'add'
# Convert from old "key=value" to new "key value" syntax # Convert from old "key=value" syntax
if string match -qr '^[^ ]+=' -- $mode_arg # TODO: This should be removed later
set mode_arg (string replace "=" " " -- $mode_arg) if not set -q mode_arg[2]; and string match -qr '^[^ ]+=' -- $mode_arg
set mode_arg (string split "=" -- $mode_arg)
end end
# Bail out early if the exact abbr is already in # Bail out early if the exact abbr is already in
contains -- $mode_arg $fish_user_abbreviations; and return 0 contains -- "$mode_arg" $fish_user_abbreviations; and return 0
set -l key set -l key $mode_arg[1]
set -l value set -e mode_arg[1]
set -l kv (__fish_abbr_split $mode_arg) set -l value "$mode_arg"
set key $kv[1] # Because we later store "$key $value", there can't be any spaces in the key
set value $kv[2] if string match -q "* *" -- $key
# ensure the key contains at least one non-space character printf ( _ "%s: abbreviation cannot have spaces in the key\n" ) abbr >&2
if not string match -qr "[^\s]" -- $key
printf ( _ "%s: abbreviation must have a non-empty key\n" ) abbr >&2
return 1 return 1
end end
if not string match -qr "\w" -- $value if test -z "$value"
printf ( _ "%s: abbreviation must have a value\n" ) abbr >&2 printf ( _ "%s: abbreviation must have a value\n" ) abbr >&2
return 1 return 1
end end
@ -102,22 +101,21 @@ function abbr --description "Manage abbreviations"
# and therefore work properly if someone sets this as a global variable # and therefore work properly if someone sets this as a global variable
set -U fish_user_abbreviations set -U fish_user_abbreviations
end end
set fish_user_abbreviations $fish_user_abbreviations $mode_arg set fish_user_abbreviations $fish_user_abbreviations "$key $value"
return 0 return 0
case 'erase' case 'erase'
set -l key (__fish_abbr_split $mode_arg)[1] if set -l idx (__fish_abbr_get_by_key $mode_arg)
if set -l idx (__fish_abbr_get_by_key $key)
set -e fish_user_abbreviations[$idx] set -e fish_user_abbreviations[$idx]
return 0 return 0
else else
printf ( _ "%s: no such abbreviation '%s'\n" ) abbr $key >&2 printf ( _ "%s: no such abbreviation '%s'\n" ) abbr $mode_arg >&2
return 2 return 2
end end
case 'show' case 'show'
for i in $fish_user_abbreviations for i in $fish_user_abbreviations
set -l kv (__fish_abbr_split $i) set -l kv (string split " " -m 1 -- $i)
set -l key $kv[1] set -l key $kv[1]
set -l value $kv[2] set -l value $kv[2]
@ -130,7 +128,7 @@ function abbr --description "Manage abbreviations"
case 'list' case 'list'
for i in $fish_user_abbreviations for i in $fish_user_abbreviations
set -l key (__fish_abbr_split $i)[1] set -l key (string split " " -m 1 -- $i)[1]
printf "%s\n" $key printf "%s\n" $key
end end
return 0 return 0
@ -154,8 +152,3 @@ function __fish_abbr_get_by_key
end end
return 1 return 1
end end
function __fish_abbr_split -a input
# Because we always save space-separated, we can be certain that this will match
string split " " -m 1 -- $input
end

View file

@ -1 +1,2 @@
abbr: no such abbreviation 'NOT_AN_ABBR' abbr: no such abbreviation 'NOT_AN_ABBR'
abbr: abbreviation cannot have spaces in the key

View file

@ -35,3 +35,5 @@ abbr -e '--__abbr3'
# Ensure we are not recognizing later "=" as separators # Ensure we are not recognizing later "=" as separators
abbr d2 env a=b banana abbr d2 env a=b banana
abbr -l | string match -q d2; or echo "= test failed" abbr -l | string match -q d2; or echo "= test failed"
abbr "a b c" "d e f"; or true