FIX: Number of 0-padding is wrong in 0-prefixed number sequences

Align the behavior with Bash: If either start or end number is 0-padded, use the _longest source number width_ as overall width (not longest resulting number, as previously implemented).
FIX: Need to base-10 convert l:sequenceElements (to l:numberElements) to avoid Vim converting into octal number.
Add tests for 0-padded sequences.
This commit is contained in:
Ingo Karkat
2017-09-30 09:18:01 +02:00
parent 39e2c8fa47
commit 41ca29c8d6
3 changed files with 25 additions and 7 deletions
+7 -5
View File
@@ -69,19 +69,21 @@ function! s:ExpandOneLevel( TailCall, text, level )
endif
let l:isNumericSequence = (len(filter(copy(l:sequenceElements), 'v:val !~# "^[+-]\\?\\d\\+$"')) == 0)
if l:isNumericSequence
let l:step = ingo#compat#abs(get(l:sequenceElements, 2, 1))
let l:numberElements = map(copy(l:sequenceElements), 'str2nr(v:val)')
let l:step = ingo#compat#abs(get(l:numberElements, 2, 1))
if l:step == 0 | let l:step = 1 | endif
let l:isZeroPadding = (l:sequenceElements[0] =~# '^0\d' || l:sequenceElements[1] =~# '^0\d')
if l:sequenceElements[0] > l:sequenceElements[1]
if l:numberElements[0] > l:numberElements[1]
let l:step = l:step * -1
endif
let l:braceElements = range(l:sequenceElements[0], l:sequenceElements[1], l:step)
let l:braceElements = range(l:numberElements[0], l:numberElements[1], l:step)
if l:isZeroPadding
call map(l:braceElements, 'printf("%0" . strlen(max(l:braceElements)) . "d", v:val)')
let l:digitNum = max(map(l:sequenceElements[0:1], 'len(v:val)'))
call map(l:braceElements, 'printf("%0" . l:digitNum . "d", v:val)')
endif
else
let l:step = ingo#compat#abs(get(l:sequenceElements, 2, 1))
let l:step = ingo#compat#abs(str2nr(get(l:sequenceElements, 2, 1)))
if l:step == 0 | let l:step = 1 | endif
let [l:nrParameter0, l:nrParameter1] = [char2nr(l:sequenceElements[0]), char2nr(l:sequenceElements[1])]
if l:nrParameter0 > l:nrParameter1
@@ -11,7 +11,6 @@ call vimtap#Is(s:Call('fo{!,X,o}'), 'fo! foX foo', 'same prefix, different suffi
call vimtap#Is(s:Call('fo{x,oy,obar}'), 'fox fooy foobar', 'same prefix, different length suffixes')
call vimtap#Is(s:Call('{my,their,our}foo'), 'myfoo theirfoo ourfoo', 'different prefixes, same suffix')
call vimtap#Is(s:Call('{my,their,our}fo{!,X,o}'), 'myfo! myfoX myfoo theirfo! theirfoX theirfoo ourfo! ourfoX ourfoo', 'different prefixes, different suffixes')
"call vimtap#Is(s:Call('{my,their,our}fo{!,X,o}'), 'myfo! theirfoX ourfoo', 'different prefixes, different suffixes')
call vimtap#Is(s:Call('foo{1..3}'), 'foo1 foo2 foo3', 'same prefix, number sequence')
call vimtap#Is(s:Call('foo{1,2}'), 'foo1 foo2', 'same prefix, short number sequence')
@@ -25,7 +24,6 @@ call vimtap#Is(s:Call('foo{{X..Z},{1..5..2}}'), 'fooX fooY fooZ foo1 foo3 foo5',
call vimtap#Is(s:Call('Foo{Has,Is,Can}Boo'), 'FooHasBoo FooIsBoo FooCanBoo', 'two commons in outside')
call vimtap#Is(s:Call('{my,their,our}Foo{Has,Is,Can}Boo{Here,Now,More}'), 'myFooHasBooHere myFooHasBooNow myFooHasBooMore myFooIsBooHere myFooIsBooNow myFooIsBooMore myFooCanBooHere myFooCanBooNow myFooCanBooMore theirFooHasBooHere theirFooHasBooNow theirFooHasBooMore theirFooIsBooHere theirFooIsBooNow theirFooIsBooMore theirFooCanBooHere theirFooCanBooNow theirFooCanBooMore ourFooHasBooHere ourFooHasBooNow ourFooHasBooMore ourFooIsBooHere ourFooIsBooNow ourFooIsBooMore ourFooCanBooHere ourFooCanBooNow ourFooCanBooMore', 'two commons in the middle')
"call vimtap#Is(s:Call('{my,their,our}Foo{Has,Is,Can}Boo{Here,Now,More}'), 'myFooHasBooHere theirFooIsBooNow ourFooCanBooMore', 'two commons in the middle')
call vimtap#Is(s:Call('foo{\,bar\,,xy}'), 'foo,bar, fooxy', 'embedded commas')
call vimtap#Is(s:Call('foo{bar,\{O\},xy}'), 'foobar foo{O} fooxy', 'embedded braces in one word')
@@ -0,0 +1,18 @@
" Test brace expansion of sequences.
function! s:Call( text )
return join(ingo#subs#BraceExpansion#ExpandStrict(a:text), ' ')
endfunction
call vimtest#StartTap()
call vimtap#Plan(6)
call vimtap#Is(s:Call('foo{1..10}'), 'foo1 foo2 foo3 foo4 foo5 foo6 foo7 foo8 foo9 foo10', 'same prefix, number sequence')
call vimtap#Is(s:Call('foo{01..10}'), 'foo01 foo02 foo03 foo04 foo05 foo06 foo07 foo08 foo09 foo10', 'same prefix, 0-padded start number')
call vimtap#Is(s:Call('foo{001..10}'), 'foo001 foo002 foo003 foo004 foo005 foo006 foo007 foo008 foo009 foo010', 'same prefix, 00-padded start number')
call vimtap#Is(s:Call('foo{1..010}'), 'foo001 foo002 foo003 foo004 foo005 foo006 foo007 foo008 foo009 foo010', 'same prefix, 0-padded end number')
call vimtap#Is(s:Call('foo{01..010}'), 'foo001 foo002 foo003 foo004 foo005 foo006 foo007 foo008 foo009 foo010', 'same prefix, 0-padded start and end number')
call vimtap#Is(s:Call('foo{00..100..010}'), 'foo000 foo010 foo020 foo030 foo040 foo050 foo060 foo070 foo080 foo090 foo100', 'same prefix, 00-padded start number, 0-padded step')
call vimtest#Quit()