Skip to content

Commit 9d7669f

Browse files
committed
Merge branch 'bugs' into dev
* bugs: Minor change {stopline} arg of searchpairpos call Fix sub_tag self-closing tag handling Describe sub_tag issue on self-closing tag Fix ambi_pair both sides match in '' phase search Describe ambi_pair end item bug in '' phase
2 parents d371829 + ab01ea5 commit 9d7669f

File tree

7 files changed

+107
-41
lines changed

7 files changed

+107
-41
lines changed

autoload/cycle.vim

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
" sub_pair
1111
" sub_pairs
1212
" ambi_pair
13+
" pair_id
1314
" end_with
1415
" begin_with
1516
" matcher
@@ -25,6 +26,7 @@
2526
" subp
2627

2728
let s:tick = 0
29+
let s:pair_id = 0
2830

2931
" }}} Constants
3032

@@ -140,6 +142,7 @@ function! cycle#search(class_name, ...) "{{{
140142
let direction = get(options, 'direction', 1)
141143
let l:count = get(options, 'count', 1)
142144
let matches = []
145+
let search_ctx = {}
143146
let cword = cycle#text#new_cword()
144147
let cchar = cycle#text#new_cchar()
145148

@@ -166,7 +169,7 @@ function! cycle#search(class_name, ...) "{{{
166169
endif
167170
endif
168171

169-
let phase_matches = s:phased_search(phase, groups, direction, l:count)
172+
let phase_matches = s:phased_search(phase, groups, direction, l:count, search_ctx)
170173

171174
if !empty(phase_matches)
172175
call extend(matches, phase_matches)
@@ -177,9 +180,8 @@ function! cycle#search(class_name, ...) "{{{
177180
endfunction "}}}
178181

179182

180-
function! s:phased_search(class_name, groups, direction, count) "{{{
183+
function! s:phased_search(class_name, groups, direction, count, search_ctx) "{{{
181184
let matches = []
182-
let search_ctx = {}
183185

184186
for group in a:groups
185187
if get(group, '_phase_matched', 0)
@@ -203,7 +205,7 @@ function! s:phased_search(class_name, groups, direction, count) "{{{
203205
break
204206
endif
205207

206-
let [index, ctext] = s:group_search(group, a:class_name, search_ctx)
208+
let [index, ctext] = s:group_search(group, a:class_name, a:search_ctx)
207209
if index >= 0
208210
if a:count == '*'
209211
" Grab all group items for CycleSelect
@@ -483,8 +485,9 @@ function! cycle#parse_group(group_attrs) "{{{
483485
endif
484486
" Note that the "end_items" (has `begin_with`) must go first, `ambi_pair`
485487
" relies on this order to make orphaned behave as the begin part.
486-
let end_group_attrs = [end_items, extend(deepcopy(options), {'begin_with': begin_items})]
487-
let begin_group_attrs = [begin_items, extend(deepcopy(options), {'end_with': end_items})]
488+
let s:pair_id += 1
489+
let end_group_attrs = [end_items, extend(deepcopy(options), {'begin_with': begin_items, 'pair_id': s:pair_id})]
490+
let begin_group_attrs = [begin_items, extend(deepcopy(options), {'end_with': end_items, 'pair_id': s:pair_id})]
488491
return [cycle#parse_group(end_group_attrs),
489492
\ cycle#parse_group(begin_group_attrs)]
490493
endif

autoload/cycle/callback/sub_tag.vim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ function! cycle#callback#sub_tag#sub(params) "{{{
33
let after = a:params.after
44
let options = a:params.options
55
let timeout = 600
6-
let pattern_till_tag_end = '\_[^>]*>'
6+
let pattern_till_tag_end = '\_[^>]*\%(\/\)\@<!>'
77
let ic_flag = get(options, 'match_case') ? '\C' : '\c'
88
let pos = cycle#util#getpos()
99

@@ -19,7 +19,7 @@ function! cycle#callback#sub_tag#sub(params) "{{{
1919
\ . (in_closing_tag ? '\zs' : '') . ic_flag,
2020
\ 'nW' . (in_closing_tag ? 'b' : ''),
2121
\ '',
22-
\ '',
22+
\ 0,
2323
\ timeout,
2424
\ )
2525

autoload/cycle/matcher/default.vim

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ function! cycle#matcher#default#test(group, class_name, ctx) abort "{{{
1010
let index = -1
1111
let ctext = cycle#text#new_ctext(a:class_name)
1212

13+
" Skip a sub_pair group if its opposite group has already found
14+
if get(options, 'sub_pair', 0)
15+
let found_pairs = get(a:ctx, 'found_pairs', [])
16+
if index(found_pairs, get(options, 'pair_id')) > -1
17+
return [index, ctext]
18+
endif
19+
endif
20+
1321
for item in a:group.items
1422
if get(options, 'match_word') && a:class_name != 'w'
1523
continue
@@ -44,14 +52,16 @@ function! cycle#matcher#default#test(group, class_name, ctx) abort "{{{
4452

4553
let ambi_pair = get(options, 'ambi_pair')
4654
if !empty(ambi_pair) && index(ambi_pair, text) > -1
47-
" For begin pair, if there was no end pair found, accept it as orphan.
48-
let accept_orphan = !empty(get(options, 'end_with')) && index(get(a:ctx, 'ambi_pair_found', []), text) < 0
55+
" For begin pair, if there was no end pair found, we can accept it as orphan.
56+
" This relies on the assumption that "end_items" were defined first.
57+
let accept_orphan = !empty(get(options, 'end_with'))
4958

5059
if cycle#matcher#default#ambi_pair#test(text, options)
51-
let founds = get(a:ctx, 'ambi_pair_found', [])
52-
let founds = uniq(founds + [text])
53-
call extend(a:ctx, {'ambi_pair_found': founds}, 'force')
60+
let founds = get(a:ctx, 'found_pairs', [])
61+
let founds = uniq(founds + [get(options, 'pair_id', -1)])
62+
call extend(a:ctx, {'found_pairs': founds}, 'force')
5463
elseif !accept_orphan
64+
" Still accept it
5565
continue
5666
endif
5767
endif

doc/cycle.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ By default no options are set.
389389
"before_sub" (List) ~
390390
"after_sub" (List) ~
391391
"ambi_pair" (List) ~
392+
"pair_id" (Number) ~
392393
"restrict_cursor" (Number) ~
393394

394395
Internal usage only, don't set them.

test/group_definition.vimspec

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,24 @@ Describe Group definition
8787
Assert Equals(group, #{items: ['Yes', 'No'], options: #{match_case: 1}})
8888

8989
let groups = cycle#parse_group([['a:b', 'c:d'], 'sub_pairs'])
90+
let [g1, g2] = groups
91+
9092
Assert IsList(groups)
91-
Assert Equals(groups[0], #{items: ['b', 'd'], options: #{sub_pair: 1, begin_with: ['a', 'c']}})
92-
Assert Equals(groups[1], #{items: ['a', 'c'], options: #{sub_pair: 1, end_with: ['b', 'd']}})
93+
Assert Includes(g1, ['items', 'options'])
94+
Assert Includes(g2, ['items', 'options'])
95+
Assert Equals(g1['options']['sub_pair'], 1)
96+
Assert Equals(g2['options']['sub_pair'], 1)
97+
98+
Assert Includes(g1['options'], ['sub_pair', 'pair_id', 'begin_with'])
99+
Assert Includes(g2['options'], ['sub_pair', 'pair_id', 'end_with'])
100+
101+
Assert Equals(g1['items'], ['b', 'd'])
102+
Assert Equals(g1['options']['begin_with'], ['a', 'c'])
103+
104+
Assert Equals(g2['items'], ['a', 'c'])
105+
Assert Equals(g2['options']['end_with'], ['b', 'd'])
106+
107+
Assert Equals(g1['options']['pair_id'], g2['options']['pair_id'])
93108
End
94109

95110
It takes one-time groups

test/group_options.vimspec

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,31 +53,53 @@ Describe Group options
5353
Assert Equals(getline(1), 'PlayStation')
5454
End
5555

56-
It respects "sub_tag"
57-
let lines =<< trim END
58-
<strong id='a'><img src="" />It's
59-
my<EM> DUTY
60-
</eM></strong > <eM>
61-
END
62-
call setline(1, lines)
63-
64-
call cursor(1, 4) " In first <strong>, on 'r'
65-
execute 'normal \a'
66-
let expected =<< trim END
67-
<em id='a'><img src="" />It's
68-
my<EM> DUTY
69-
</eM></em > <eM>
70-
END
71-
Assert Equals(getline(1, '$'), expected, 'Expect <strong> -> <em>')
72-
73-
call cursor(3, 6) " In line 3, first </eM>, on 'M'
74-
execute 'normal \a'
75-
let expected =<< trim END
76-
<em id='a'><img src="" />It's
77-
my<sTrong> DUTY
78-
</sTrong></em > <eM>
79-
END
80-
Assert Equals(getline(1, '$'), expected, 'Expect </eM> -> </sTrong>')
56+
Context respects "sub_tag"
57+
It usual case
58+
let lines =<< trim END
59+
<strong id='a'><img src="" />It's
60+
my<EM> DUTY
61+
</eM></strong > <eM>
62+
END
63+
call setline(1, lines)
64+
65+
call cursor(1, 4) " In first <strong>, on 'r'
66+
execute 'normal \a'
67+
let expected =<< trim END
68+
<em id='a'><img src="" />It's
69+
my<EM> DUTY
70+
</eM></em > <eM>
71+
END
72+
Assert Equals(getline(1, '$'), expected, 'Expect <strong> -> <em>')
73+
74+
call cursor(3, 6) " In line 3, first </eM>, on 'M'
75+
execute 'normal \a'
76+
let expected =<< trim END
77+
<em id='a'><img src="" />It's
78+
my<sTrong> DUTY
79+
</sTrong></em > <eM>
80+
END
81+
Assert Equals(getline(1, '$'), expected, 'Expect </eM> -> </sTrong>')
82+
End
83+
84+
It skips self-closing tags
85+
let lines =<< trim END
86+
<em>
87+
◯ <em>nested</em>
88+
✕ <em />
89+
</em>
90+
END
91+
call setline(1, lines)
92+
93+
call cursor(4, 4) " In last <em>, on 'm'
94+
execute 'normal \a'
95+
let expected =<< trim END
96+
<strong>
97+
◯ <em>nested</em>
98+
✕ <em />
99+
</strong>
100+
END
101+
Assert Equals(getline(1, '$'), expected)
102+
End
81103
End
82104

83105
Describe respects "match_word"

test/sub_pairs.vimspec

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,14 @@ Describe Sub pairs
1111
End
1212

1313
After each
14+
unlet! g:cycle_test_conflict
1415
bwipeout!
1516
End
1617

18+
After all
19+
let g:cycle_max_conflict = 1
20+
End
21+
1722
It respects "sub_pair" and "end_with"
1823
let line = '<= [1, 2, 3] < [a, b, c] -----> >'
1924
" B
@@ -134,6 +139,7 @@ Describe Sub pairs
134139
3 orphaned " land
135140
END
136141
call setline(1, lines)
142+
let g:cycle_max_conflict = 100
137143
End
138144

139145
It from begin, sub end
@@ -151,7 +157,7 @@ Describe Sub pairs
151157
Assert Equals(getline(1), '1 foo "bar \" " " baz')
152158
End
153159

154-
It from end, sub begin
160+
It from end, sub begin (no conflict in '' phase)
155161
call search('bar \\" "', 'eW')
156162

157163
execute 'normal \a'
@@ -166,6 +172,15 @@ Describe Sub pairs
166172
Assert Equals(getline(1), '1 foo "bar \" " " baz')
167173
End
168174

175+
It from end, sub begin (potentially conflict in '' phase)
176+
let line = '" foo "'
177+
call setline(1, line)
178+
normal! $
179+
180+
execute 'normal \a'
181+
Assert Equals(getline(1), '` foo `')
182+
End
183+
169184
It subs orphaned item even the opposite not found
170185
call cursor(3, 1)
171186
call search('"')

0 commit comments

Comments
 (0)