Last active
August 29, 2015 14:23
-
-
Save haya14busa/25af8128aa1f9a5ec536 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let s:TRUE = !0 | |
let s:FALSE = 0 | |
let s:escaped_backslash = '\m\%(^\|[^\\]\)\%(\\\\\)*\zs' | |
function! s:regexp_join(ps) abort | |
let rs = map(filter(copy(a:ps), 's:_is_valid_regexp(v:val)'), 's:escape_unbalanced_left_r(v:val)') | |
return printf('\m\%%(%s\m\)', join(rs, '\m\|')) | |
endfunction | |
function! s:_is_valid_regexp(pattern) abort | |
try | |
if '' =~# a:pattern | |
endif | |
return s:TRUE | |
catch | |
return s:FALSE | |
endtry | |
endfunction | |
" \m,\v: [ -> \[ | |
" \M,\V: \[ -> [ | |
function! s:escape_unbalanced_left_r(pattern) abort | |
let rs = [] | |
let cs = split(a:pattern, '\zs') | |
" escape backslash (\, \\\, \\\\\, ...) | |
let escape_bs = s:FALSE | |
let flag = &magic ? 'm' : 'M' | |
let i = 0 | |
while i < len(cs) | |
let c = cs[i] | |
" characters to add to rs | |
let addcs = [c] | |
if escape_bs && s:_is_flag(c) | |
let flag = c | |
elseif c is# '[' && s:_may_replace_left_r_cond(escape_bs, flag) | |
let idx = s:_find_right_r(cs, i) | |
if idx is# -1 | |
if s:_is_flag(flag, 'MV') | |
" Remove `\` before unbalanced `[` | |
let rs = rs[:-2] | |
else | |
" Escape unbalanced `[` | |
let addcs = ['\' . c] | |
endif | |
else | |
let addcs = cs[(i):(i+idx)] | |
let i += idx | |
endif | |
endif | |
let escape_bs = (escape_bs || c isnot# '\') ? s:FALSE : s:TRUE | |
let rs += addcs | |
let i += 1 | |
endwhile | |
return join(rs, '') | |
endfunction | |
" @ return boolean | |
function! s:_is_flag(flag, ...) abort | |
let chars = get(a:, 1, 'mMvV') | |
return a:flag =~# printf('\m[%s]', chars) | |
endfunction | |
" @ return boolean | |
function! s:_may_replace_left_r_cond(escape_bs, flag) abort | |
return (a:escape_bs && s:_is_flag(a:flag, 'MV')) || (!a:escape_bs && s:_is_flag(a:flag, 'mv')) | |
endfunction | |
" @return index | |
function! s:_find_right_r(cs, i) abort | |
return match(join(a:cs[(a:i+1):], ''), s:escaped_backslash . ']') | |
endfunction | |
echo '###### s:regexp_join()' | |
echo '===1' | |
let r = s:regexp_join(['[a', '[bcd]']) | |
echo r ==# '\m\%(\[a\m\|[bcd]\)' | |
echo '[a' =~# r | |
echo '[' !~# r | |
echo '\' !~# r | |
echo '###### s:escape_unbalanced_left_r()' | |
echo '===1' | |
echo s:escape_unbalanced_left_r('[') == '\[' | |
echo s:escape_unbalanced_left_r('\[') == '\[' | |
echo s:escape_unbalanced_left_r('\\[') == '\\\[' | |
echo s:escape_unbalanced_left_r('\\\[') == '\\\[' | |
echo '===2' | |
echo s:escape_unbalanced_left_r('[]') == '[]' | |
echo s:escape_unbalanced_left_r('\[]') == '\[]' | |
echo s:escape_unbalanced_left_r('\\[]') == '\\[]' | |
echo s:escape_unbalanced_left_r('\\\[]') == '\\\[]' | |
echo '===3' | |
echo s:escape_unbalanced_left_r('[][') == '[]\[' | |
echo s:escape_unbalanced_left_r('\[][') == '\[]\[' | |
echo s:escape_unbalanced_left_r('\\[][') == '\\[]\[' | |
echo s:escape_unbalanced_left_r('\\\[][') == '\\\[]\[' | |
echo '===4' | |
echo s:escape_unbalanced_left_r('[]...[') == '[]...\[' | |
echo s:escape_unbalanced_left_r('\[]...[') == '\[]...\[' | |
echo s:escape_unbalanced_left_r('\\[]...[') == '\\[]...\[' | |
echo s:escape_unbalanced_left_r('\\\[]...[') == '\\\[]...\[' | |
echo '===5' | |
echo s:escape_unbalanced_left_r('\m[') == '\m\[' | |
echo s:escape_unbalanced_left_r('\m\[') == '\m\[' | |
echo s:escape_unbalanced_left_r('\m\\[') == '\m\\\[' | |
echo s:escape_unbalanced_left_r('\m\\\[') == '\m\\\[' | |
echo s:escape_unbalanced_left_r('\v[') == '\v\[' | |
echo s:escape_unbalanced_left_r('\v\[') == '\v\[' | |
echo s:escape_unbalanced_left_r('\v\\[') == '\v\\\[' | |
echo s:escape_unbalanced_left_r('\v\\\[') == '\v\\\[' | |
echo '===6' | |
echo s:escape_unbalanced_left_r('\M[') == '\M[' | |
echo s:escape_unbalanced_left_r('\M\[') == '\M[' | |
echo s:escape_unbalanced_left_r('\M\\[') == '\M\\[' | |
echo s:escape_unbalanced_left_r('\M\\\[') == '\M\\[' | |
echo s:escape_unbalanced_left_r('\V[') == '\V[' | |
echo s:escape_unbalanced_left_r('\V\[') == '\V[' | |
echo s:escape_unbalanced_left_r('\V\\[') == '\V\\[' | |
echo s:escape_unbalanced_left_r('\V\\\[') == '\V\\[' | |
echo '===7' | |
echo s:escape_unbalanced_left_r('[\M\[\v[') == '\[\M[\v\[' | |
echo s:escape_unbalanced_left_r('[\M\[\v[]') == '[\M\[\v[]' | |
echo s:escape_unbalanced_left_r('[[]') == '[[]' | |
echo s:escape_unbalanced_left_r('[\[]') == '[\[]' | |
echo s:escape_unbalanced_left_r('\M\[[]') == '\M\[[]' | |
echo '===8' | |
let p = '[' . repeat('[', 10000) . ']' | |
echo s:escape_unbalanced_left_r(p) == p | |
let p = '[' . repeat('\[', 10000) . ']' | |
echo s:escape_unbalanced_left_r(p) == p |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment