Skip to content

Commit 78f7132

Browse files
add option to acknowledge mids
1 parent c9c7655 commit 78f7132

File tree

4 files changed

+68
-4
lines changed

4 files changed

+68
-4
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ Note too that the `ar` and `ir` text objects always position your cursor on
6363
the `end` keyword. If you want to move to the top of the selection, you can do
6464
so with the `o` key.
6565

66+
By default `ir` ignores middle keywords like `else` and `when`, but if you
67+
prefer you can have `ir` acknowledge them by putting this in your .vimrc
68+
69+
g:textobj_rubyblock_mids = 1
70+
6671
Limitations
6772
-----------
6873

plugin/textobj/rubyblock.vim

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,15 @@ let s:comment_escape = '\v^[^#]*'
1616
let s:block_openers = '\zs(<def>|<if>|<unless>|<do>|<module>|<class>|<case>'
1717
let s:block_openers .= '|<for>|<while>|<until>|<begin>)'
1818
let s:start_pattern = s:comment_escape . s:block_openers
19+
let s:mid_pattern = s:comment_escape
20+
let s:mid_pattern .= '\zs(<else>|<elsif>|<when>|<rescue>|<ensure>)'
1921
let s:end_pattern = s:comment_escape . '\zs<end>'
2022
let s:skip_pattern = 'getline(".") =~ "\\v\\S\\s<(if|unless)>\\s\\S"'
2123

24+
if !exists('g:textobj_rubyblock_mids')
25+
let g:textobj_rubyblock_mids = 0
26+
endif
27+
2228
function! s:select_a()
2329
let s:flags = 'W'
2430

@@ -38,15 +44,35 @@ function! s:select_i()
3844
let s:flags = 'cW'
3945
endif
4046

41-
call searchpair(s:start_pattern,'',s:end_pattern, s:flags, s:skip_pattern)
47+
let l:mid = ''
48+
if g:textobj_rubyblock_mids
49+
let l:mid = s:mid_pattern
50+
endif
51+
52+
call searchpair(s:start_pattern,l:mid,s:end_pattern, s:flags, s:skip_pattern)
4253

4354
" Move up one line, and save position
4455
normal k^
4556
let end_pos = getpos('.')
4657

47-
" Move down again, jump to match, then down one line and save position
48-
normal j^%j
49-
let start_pos = getpos('.')
58+
if g:textobj_rubyblock_mids
59+
" Move down again, find match right before, and save position
60+
normal j^
61+
let l:last_position = getpos('.')
62+
let l:start_line = l:last_position[1]
63+
normal %
64+
while getpos('.')[1] != l:start_line
65+
let l:last_position = getpos('.')
66+
normal %
67+
endwhile
68+
call setpos('.', l:last_position)
69+
normal j^
70+
let start_pos = getpos('.')
71+
else
72+
" Move down again, jump to match, then down one line and save position
73+
normal j^%j
74+
let start_pos = getpos('.')
75+
endif
5076

5177
return ['V', start_pos, end_pos]
5278
endfunction

t/examples.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,12 @@ def method_with_unless
8181
end
8282
var2 = 2
8383
end
84+
85+
def method_with_if_else
86+
if condition
87+
foo = 'foo'
88+
bar = 'bar'
89+
else
90+
baz = 'baz'
91+
end
92+
end

t/rubyblock_test.vim

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,30 @@ describe 'nested while and unless blocks'
103103

104104
end
105105

106+
describe 'g:textobj_rubyblock_mids'
107+
before
108+
silent tabnew t/examples.rb
109+
end
110+
111+
after
112+
silent tabclose
113+
end
114+
115+
context '1'
116+
it 'selects only between mids'
117+
let g:textobj_rubyblock_mids = 1
118+
Expect SelectInsideFrom(87, '^') ==# [87, 87, 88]
119+
end
120+
end
121+
122+
context '0'
123+
it 'ignores mids'
124+
let g:textobj_rubyblock_mids = 0
125+
Expect SelectInsideFrom(87, '^') ==# [87, 87, 90]
126+
end
127+
end
128+
end
129+
106130
describe '<Plug>(textobj-rubyblock-i)'
107131

108132
before

0 commit comments

Comments
 (0)