Change split logic to allow advanced patterns

- \v  (Fix #67)
- \zs (Fix #55)
This commit is contained in:
Junegunn Choi
2015-10-01 19:26:46 +09:00
parent 98e0b493ac
commit 504eab0f59
2 changed files with 45 additions and 10 deletions

View File

@@ -264,11 +264,8 @@ function! s:split_line(line, nth, modes, cycle, fc, lc, pattern, stick_to_left,
\ strpart(getline(a:line), a:fc - 1, a:lc - a:fc + 1) :
\ strpart(getline(a:line), a:fc - 1)
let idx = 0
" Do not allow \zs
" 1: whole match
" 2: token
" 3: delimiter
let pattern = '^\(\(.\{-}\s*\)\(' .a:pattern. '\)\s' . (a:stick_to_left ? '*' : '\{-}') . '\)'
let nomagic = match(a:pattern, '\\v') > match(a:pattern, '\C\\[mMV]')
let pattern = '^.\{-}\s*\zs\('.a:pattern.(nomagic ? ')' : '\)')
let tokens = []
let delims = []
@@ -277,18 +274,22 @@ function! s:split_line(line, nth, modes, cycle, fc, lc, pattern, stick_to_left,
let token = ''
let phantom = 0
while 1
let matches = matchlist(string, pattern, idx)
let matchidx = match(string, pattern, idx)
" No match
if empty(matches) | break | endif
if matchidx < 0 | break | endif
let matchend = matchend(string, pattern, idx)
let spaces = matchstr(string, '\s'.(a:stick_to_left ? '*' : '\{-}'), matchend + (matchidx == matchend))
" Match, but empty delimiter
if empty(matches[1])
" Match, but empty
if len(spaces) + matchend - idx == 0
let char = strpart(string, idx, 1)
if empty(char) | break | endif
let [match, part, delim] = [char, char, '']
" Match
else
let [match, part, delim] = matches[1 : 3]
let match = strpart(string, idx, matchend - idx + len(spaces))
let part = strpart(string, idx, matchidx - idx)
let delim = strpart(string, matchidx, matchend - matchidx)
endif
let ignorable = s:highlighted_as(a:line, idx + len(part) + a:fc, a:ignore_groups)

View File

@@ -212,4 +212,38 @@ Expect:
aa -= bb
aaa ?= bbb
* #67 \v
Given c:
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Execute (#67 \v breaks surrounding regex):
%EasyAlign/\v(\=\s)@<=</
Expect:
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Execute (#67 \V followed by \v shouldn't matter):
%EasyAlign/\v(\=\s)@<=<\V/
Expect:
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Execute (#67 \zs is now allowed):
%EasyAlign/=\zs/
Expect:
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Include: include/teardown.vader