From ac545940de58fbe0a77abcf0ca8eeaefc80c5852 Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Mon, 4 Jan 2016 15:27:15 +0100 Subject: [PATCH] Optimize and modernize abbr - Replace __fish_abbr_escape with `string escape` - Don't double-parse the key - Replace IFS magic with string Together, this seems to speed it up by a factor of about 2. --- share/functions/abbr.fish | 51 ++++++++++++--------------------------- 1 file changed, 15 insertions(+), 36 deletions(-) diff --git a/share/functions/abbr.fish b/share/functions/abbr.fish index 87cf3184e..4a3c4d2be 100644 --- a/share/functions/abbr.fish +++ b/share/functions/abbr.fish @@ -76,13 +76,11 @@ function abbr --description "Manage abbreviations" 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_" + if not string match -qr "\w" -- $key printf ( _ "%s: abbreviation must have a non-empty key\n" ) abbr >&2 return 1 end - if test -z "$value" + if not string match -qr "\w" -- $value printf ( _ "%s: abbreviation must have a value\n" ) abbr >&2 return 1 end @@ -111,8 +109,6 @@ function abbr --description "Manage abbreviations" case 'show' for i in $fish_user_abbreviations - # Disable newline splitting - set -lx IFS '' __fish_abbr_parse_entry $i key value # Check to see if either key or value has a leading dash @@ -120,7 +116,7 @@ function abbr --description "Manage abbreviations" set -l opt_double_dash '' switch $key ; case '-*'; set opt_double_dash ' --'; end switch $value ; case '-*'; set opt_double_dash ' --'; end - echo abbr$opt_double_dash (__fish_abbr_escape "$key") (__fish_abbr_escape "$value") + echo abbr$opt_double_dash (string escape -- $key $value) end return 0 @@ -134,20 +130,6 @@ function abbr --description "Manage abbreviations" end end -function __fish_abbr_escape - # Prettify the common case: if everything is alphanumeric, - # we do not need escapes. - # Do this by deleting alnum characters, and check if there's anything left. - # Note we need to preserve spaces, so spaces are not considered alnum - if test -z (echo -n "$argv" | tr -d '[:alnum:]_') - echo $argv - else - # Escape via single quotes - # printf is nice for stripping the newline that sed outputs - printf "'%s'" (echo -n $argv | sed -e s,\\\\,\\\\\\\\,g -e s,\',\\\\\',g) - end -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 @@ -155,9 +137,7 @@ function __fish_abbr_get_by_key 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 + set -l key $argv[1] # This assumes the key is valid and pre-parsed for i in (seq $count) set -l key_i __fish_abbr_parse_entry $fish_user_abbreviations[$i] key_i @@ -177,19 +157,18 @@ function __fish_abbr_parse_entry -S -a __input __key __value 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 '=' + case "*=*" + # No need for bounds-checking because we already matched before + set -l KV (string split "=" -m 1 -- $__input) + set $__key $KV[1] + set $__value $KV[2] + case "* *" + set -l KV (string split " " -m 1 -- $__input) + set $__key $KV[1] + set $__value $KV[2] + case "*" + set $__key $__input 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