Skip to content

Commit 37042d3

Browse files
committed
- Change EasyMotion#WBK regex. Should now matches the default Vim motions
b/w. - Add test to compare different motion algorithm. (WIP. Test trigger undetectable vim-vspec error)
1 parent b1acf67 commit 37042d3

File tree

3 files changed

+200
-5
lines changed

3 files changed

+200
-5
lines changed

autoload/EasyMotion.vim

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,12 @@ endfunction " }}}
187187
function! EasyMotion#WBK(visualmode, direction) " {{{
188188
" vim's iskeyword style word motion
189189
let s:current.is_operator = mode(1) ==# 'no' ? 1: 0
190-
call s:EasyMotion('\(\(\<\|\>\|\s\)\@<=\S\|^$\)', a:direction, a:visualmode ? visualmode() : '', 0)
190+
" Note: Previous regex for all directions was '\(\(\<\|\>\|\s\)\@<=\S\|^$\)'
191+
let l:regex_without_file_ends = '\v<|^\S|\s\zs\S|>\zs\S|^$'
192+
let l:regex = l:regex_without_file_ends
193+
\ . (a:direction == 1 ? '' : '|%$')
194+
\ . (a:direction == 0 ? '' : '|%^')
195+
call s:EasyMotion(l:regex, a:direction, a:visualmode ? visualmode() : '', 0)
191196
return s:EasyMotion_is_cancelled
192197
endfunction " }}}
193198
function! EasyMotion#E(visualmode, direction) " {{{

t/compare_movements_spec.vim

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
"=============================================================================
2+
" FILE: t/compare_movements_spec.vim
3+
" AUTHOR: YggdrasiI
4+
" Test: https://github.com/kana/vim-vspec
5+
" Description: EasyMotion keyword movement test with vim-vspec
6+
" License: MIT license {{{
7+
" Permission is hereby granted, free of charge, to any person obtaining
8+
" a copy of this software and associated documentation files (the
9+
" "Software"), to deal in the Software without restriction, including
10+
" without limitation the rights to use, copy, modify, merge, publish,
11+
" distribute, sublicense, and/or sell copies of the Software, and to
12+
" permit persons to whom the Software is furnished to do so, subject to
13+
" the following conditions:
14+
"
15+
" The above copyright notice and this permission notice shall be included
16+
" in all copies or substantial portions of the Software.
17+
"
18+
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19+
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20+
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21+
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22+
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23+
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24+
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25+
" }}}
26+
"=============================================================================
27+
28+
" Setup {{{
29+
let s:root_dir = matchstr(system('git rev-parse --show-cdup'), '[^\n]\+')
30+
execute 'set' 'rtp +=./'.s:root_dir
31+
runtime! plugin/EasyMotion.vim
32+
" }}}
33+
34+
" Functions for Test {{{
35+
function! AddLine(str)
36+
put! =a:str
37+
endfunction
38+
39+
function! CursorPos()
40+
return [line('.'), col('.'), getline('.')[col('.')-1]]
41+
endfunction
42+
43+
" Nested normal to avoid throwing readonly errors. They abort the testing.
44+
function TryNormal(str)
45+
try
46+
exec 'normal ' . a:str
47+
catch /^Vim\%((\a\+)\)\=:E21/
48+
endtry
49+
endfunction
50+
51+
let s:to_cursor = {}
52+
function! s:to_cursor.match(actual, expected)
53+
return a:actual == a:expected
54+
endfunction
55+
56+
" Add metadata about failure.
57+
function! s:to_cursor.failure_message_for_should(actual, expected)
58+
return ''
59+
Expect a:actual[0] > 0
60+
Expect a:expected[0] > 0
61+
Expect a:actual[0] <= getpos('$')[1]
62+
Expect a:expected[0] <= getpos('$')[1]
63+
Expect a:actual[1] > 0
64+
Expect a:expected[1] > 0
65+
66+
let l:line1 = getline(a:actual[0])
67+
let l:line2 = getline(a:expected[0])
68+
" Change char on cursor to '█'.
69+
let l:line1 = strpart(l:line1, 0, a:actual[1]-1)
70+
\ . ''
71+
\ . strpart(l:line1, a:actual[1])
72+
let line2 = strpart(l:line2, 0, a:expected[1]-1)
73+
\ . ''
74+
\ . strpart(l:line2, a:expected[1])
75+
let l:msg = 'Line ' . string(a:actual[0]) . ": '" . l:line1
76+
\ . "', Line " . string(a:expected[0]) . ": '" . l:line2 . "'"
77+
return l:msg
78+
endfunction
79+
80+
function! CompareMovements(movement1, movement2, backward)
81+
let l:jumpmarks = [
82+
\ [a:movement1, []],
83+
\ [a:movement2, []],
84+
\ ]
85+
86+
" Loop through current buffer in both variants {{
87+
for [l:handler, l:list] in l:jumpmarks
88+
if a:backward == 1
89+
call cursor(getpos('$')[1:2])
90+
else
91+
call cursor([1,1])
92+
endif
93+
94+
let l:lastpos = [0,0]
95+
96+
call TryNormal(l:handler)
97+
let l:curpos = getpos(".")[1:2]
98+
99+
while l:lastpos != l:curpos
100+
let l:list += [l:curpos]
101+
let l:lastpos = l:curpos
102+
call TryNormal(l:handler)
103+
let l:curpos = getpos(".")[1:2]
104+
endwhile
105+
endfor
106+
" }}
107+
108+
" The resulting lists are stored in l:jumpmarks[*][1], now.
109+
let [l:cursor_positions1, l:cursor_positions2] = [ l:jumpmarks[0][1], l:jumpmarks[1][1] ]
110+
111+
" Debug output for this script
112+
let g:dbg_msg = printf("(CompareMovements) '%s' vs '%s'\<CR>Length of both lists: %d, %d\r Content of lists:\r%s\r\r%s",
113+
\ string(l:jumpmarks[0][0]),
114+
\ string(l:jumpmarks[1][0]),
115+
\ len(l:cursor_positions1), len(l:cursor_positions2),
116+
\ string(l:cursor_positions1),
117+
\ string(l:cursor_positions2))
118+
Expect g:dbg_msg == v:errmsg
119+
120+
if l:cursor_positions1 == l:cursor_positions2
121+
return 0
122+
endif
123+
124+
" Search for first unmatching position. {{
125+
let l:index = 0
126+
let l:len = min([len(l:cursor_positions2), len(l:cursor_positions1)])
127+
while l:index < l:len
128+
Expect l:cursor_positions2[l:index] to_cursor l:cursor_positions1[l:index]
129+
let l:index += 1
130+
endwhile
131+
132+
" Collision with begin or end of file
133+
if a:backward == 1
134+
Expect join(['File begin reached after ', len(l:cursor_positions2), ' steps.'])
135+
\ == join(['File begin reached after ', len(l:cursor_positions1), ' steps.'])
136+
else
137+
Expect join(['File end reached after ', len(l:cursor_positions2), ' steps.'])
138+
\ == join(['File end reached after ', len(l:cursor_positions1), ' steps.'])
139+
endif
140+
" }}
141+
142+
return -1
143+
endfunction
144+
"}}}
145+
146+
"Keyword word motion {{{
147+
describe 'Keyword word motion'
148+
before
149+
new
150+
nmap a <Nop>
151+
let g:EasyMotion_keys = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
152+
nmap <Leader>w <Plug>(easymotion-iskeyword-w)
153+
nmap <Leader>b <Plug>(easymotion-iskeyword-b)
154+
call EasyMotion#init()
155+
156+
call vspec#customize_matcher('to_cursor', s:to_cursor)
157+
end
158+
159+
after
160+
close!
161+
end
162+
163+
it 'Simple test to check setup of this test'
164+
call AddLine('word')
165+
Expect CompareMovements('w', '\wa', 0) == 0
166+
"Expect CompareMovements('b', '\ba', 1) == 0
167+
end
168+
169+
"it 'Loop through hand crafted text with rare cases'
170+
" " Hand crafted text with rare cases
171+
" call AddLine('scriptencoding utf-8')
172+
" call AddLine('Test case [ ')
173+
" call AddLine('<!{}>s! ')
174+
" Expect CompareMovements('w', '\wa', 0) == 0
175+
" Expect CompareMovements('b', '\ba', 1) == 0
176+
"end
177+
178+
"it 'Loop through Vim help buffer and compare movements'
179+
" help motion.txt
180+
" Expect expand('%:t') ==# 'motion.txt'
181+
" "Expect CompareMovements('w', '\wa', 0) == 0
182+
" "Expect CompareMovements('b', '\ba', 1) == 0
183+
"end
184+
185+
end
186+
"}}}
187+
188+
" __END__ {{{
189+
" vim: fdm=marker:et:ts=4:sw=4:sts=4
190+
" }}}

t/easymotion_spec.vim

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ describe 'Default settings'
217217
"}}}
218218
end
219219

220-
it 'provide default <Plug> mappings for regrex motion'
220+
it 'provide default <Plug> mappings for regex motion'
221221
"(is_visual, direction)
222222
" direction:
223223
" - 0: forward
@@ -1411,8 +1411,8 @@ describe 'Word motion'
14111411
close!
14121412
end
14131413

1414-
" Default word motion {{
1415-
it 'Default word motion'
1414+
" Word motion {{
1415+
it 'Word motion'
14161416
normal! 0
14171417
let l = line('.')
14181418
Expect CursorPos() == [l,1,'p']
@@ -1430,7 +1430,7 @@ describe 'Word motion'
14301430
normal bh
14311431
Expect CursorPos() == [l,1,'p']
14321432
end
1433-
"}}}
1433+
"}}
14341434
end
14351435

14361436
describe 'Verbose'

0 commit comments

Comments
 (0)