Add ingo#regexp#split#AddPatternByProjectedMatchLength()

Using the (basic so far) implementation of ingo#regexp#length#Project().
This commit is contained in:
Ingo Karkat
2018-08-21 12:03:55 +02:00
parent 82743f2358
commit 0f949cc67f
2 changed files with 52 additions and 0 deletions
+35
View File
@@ -1,6 +1,7 @@
" ingo/regexp/split.vim: Functions to split a regular expression.
"
" DEPENDENCIES:
" - ingo/regexp/length.vim autoload script
"
" Copyright: (C) 2017-2018 Ingo Karkat
" The VIM LICENSE applies to this script; see ':help copyright'.
@@ -107,4 +108,38 @@ function! ingo#regexp#split#PrefixGroupsSuffix( pattern )
return l:result
endfunction
function! ingo#regexp#split#AddPatternByProjectedMatchLength( branches, pattern )
"******************************************************************************
"* PURPOSE:
" Add a:pattern to the List of regexp a:branches, in a position so that
" shorter earlier branches do not eclipse a following longer match.
"* ASSUMPTIONS / PRECONDITIONS:
" None.
"* EFFECTS / POSTCONDITIONS:
" None.
"* INPUTS:
" a:branches List of regular expression branches (e.g. split via
" ingo#regexp#split#TopLevelBranches()).
" a:pattern Regular expression to be added at the appropriate position in
" a:branches, depending on the projected length of the matches.
" Longer matches will come first, so that a shorter earlier match
" does not eclipse a following longer one.
"* RETURN VALUES:
" Modified a:branches List.
"******************************************************************************
let l:projectedPatternMinLength = ingo#regexp#length#Project(a:pattern)[0]
let l:i = 0
while l:i < len(a:branches)
let [l:min, l:max] = ingo#regexp#length#Project(a:branches[l:i])
let l:compare = (l:max < 0x7FFFFFFF ? l:max : l:min)
if l:compare < l:projectedPatternMinLength
break
endif
let l:i += 1
endwhile
return insert(a:branches, a:pattern, l:i)
endfunction
" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
@@ -0,0 +1,17 @@
" Test addition of literal patterns based on length.
call vimtest#StartTap()
call vimtap#Plan(8)
call vimtap#Is(ingo#regexp#split#AddPatternByProjectedMatchLength([], 'foo'), ['foo'], 'add literal pattern to empty list')
call vimtap#Is(ingo#regexp#split#AddPatternByProjectedMatchLength(['foo'], 'fo'), ['foo', 'fo'], 'add shorter literal pattern to one-element list')
call vimtap#Is(ingo#regexp#split#AddPatternByProjectedMatchLength(['foo'], 'fooy'), ['fooy', 'foo'], 'add longer literal pattern to one-element list')
call vimtap#Is(ingo#regexp#split#AddPatternByProjectedMatchLength(['foo'], 'fox'), ['foo', 'fox'], 'add same-length literal pattern to one-element list')
call vimtap#Is(ingo#regexp#split#AddPatternByProjectedMatchLength(['foo', 'fo'], 'f'), ['foo', 'fo', 'f'], 'add shorter literal pattern to two-element list')
call vimtap#Is(ingo#regexp#split#AddPatternByProjectedMatchLength(['fooxies', 'fo'], 'foox'), ['fooxies', 'foox', 'fo'], 'add literal pattern to middle of two-element list')
call vimtap#Is(ingo#regexp#split#AddPatternByProjectedMatchLength(['fooxies', 'foox', 'fo'], 'foo'), ['fooxies', 'foox', 'foo', 'fo'], 'add literal pattern to middle of three-element list')
call vimtap#Is(ingo#regexp#split#AddPatternByProjectedMatchLength(['fooxies', 'fo', 'boobies', 'bo'], 'boo'), ['fooxies', 'boo', 'fo', 'boobies', 'bo'], 'add literal pattern to middle of not fully sorted four-element list')
call vimtest#Quit()