Search code examples
fish

fish abbreviation for range expansion


I want a fish shell abbreviation which will convert {218..220} to (seq 218 220).

I have written the abbreviation till:

function range_expansion
    # $argv
    # echo (seq 218 220) 
end

abbr --add range_expansion --position anywhere --regex "{\d+\.\.\d+}" --function range_expansion

I have a hunch that the regex is not working. Not understanding how to proceed from here.


Solution

  • This will do what you want:

    function range_expansion
        # Replace all non-digits with spaces, then split on whitespace.
        set -l values (echo $argv | tr -cs '[:digit:]' ' ' | string split ' ' --no-empty)
        echo "(seq $values[1] $values[2])"
    end
    
    abbr --add range_expand_abbr --position anywhere --regex "\{\d+\.\.\d+\}" --function range_expansion
    

    As Glenn Jackman observes, almost everything you want to match is a regex special character, so needs escaping. There are hardly any escapes in fish quoted strings, so these backslashes are passed to the regex engine.

    There's multiple ways to extract the numbers from a string like {123..456}; here I've used tr and string split but there are certainly others.