From c9c765551f8a70615032006f9c36b4396116baba Mon Sep 17 00:00:00 2001 From: Jeremiah Kellick Date: Sat, 11 Aug 2018 01:18:07 -0400 Subject: [PATCH 1/3] add the rest of the block opener keywords --- plugin/textobj/rubyblock.vim | 3 ++- t/examples.rb | 16 ++++++++++++++++ t/rubyblock_test.vim | 17 +++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/plugin/textobj/rubyblock.vim b/plugin/textobj/rubyblock.vim index e0e5ad1..9e7ecf9 100644 --- a/plugin/textobj/rubyblock.vim +++ b/plugin/textobj/rubyblock.vim @@ -13,7 +13,8 @@ call textobj#user#plugin('rubyblock', { " Misc. "{{{1 let s:comment_escape = '\v^[^#]*' -let s:block_openers = '\zs(||||)' +let s:block_openers = '\zs(||||||' +let s:block_openers .= '||||)' let s:start_pattern = s:comment_escape . s:block_openers let s:end_pattern = s:comment_escape . '\zs' let s:skip_pattern = 'getline(".") =~ "\\v\\S\\s<(if|unless)>\\s\\S"' diff --git a/t/examples.rb b/t/examples.rb index 9dbd0ad..65a88d2 100644 --- a/t/examples.rb +++ b/t/examples.rb @@ -65,3 +65,19 @@ def hello bar end +def method_with_while + var1 = 1 + i = 0 + while i < 10 + i += 1 + end + var2 = 2 +end + +def method_with_unless + var1 = 1 + unless condition + puts 'foo' + end + var2 = 2 +end diff --git a/t/rubyblock_test.vim b/t/rubyblock_test.vim index dd55ffa..8b2ab0c 100644 --- a/t/rubyblock_test.vim +++ b/t/rubyblock_test.vim @@ -86,6 +86,23 @@ describe '(textobj-rubyblock-a)' end +describe 'nested while and unless blocks' + + before + silent tabnew t/examples.rb + end + + after + silent tabclose + end + + it 'ignores nested while and unless blocks' + Expect SelectAroundFrom(69, '^') ==# [69, 68, 75] + Expect SelectAroundFrom(78, '^') ==# [78, 77, 83] + end + +end + describe '(textobj-rubyblock-i)' before From 78f713270d24802dad8120f1e233db46f561c42e Mon Sep 17 00:00:00 2001 From: Jeremiah Kellick Date: Sat, 11 Aug 2018 02:22:23 -0400 Subject: [PATCH 2/3] add option to acknowledge mids --- README.md | 5 +++++ plugin/textobj/rubyblock.vim | 34 ++++++++++++++++++++++++++++++---- t/examples.rb | 9 +++++++++ t/rubyblock_test.vim | 24 ++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f15db09..bd8ecfb 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,11 @@ Note too that the `ar` and `ir` text objects always position your cursor on the `end` keyword. If you want to move to the top of the selection, you can do so with the `o` key. +By default `ir` ignores middle keywords like `else` and `when`, but if you +prefer you can have `ir` acknowledge them by putting this in your .vimrc + + g:textobj_rubyblock_mids = 1 + Limitations ----------- diff --git a/plugin/textobj/rubyblock.vim b/plugin/textobj/rubyblock.vim index 9e7ecf9..07520f1 100644 --- a/plugin/textobj/rubyblock.vim +++ b/plugin/textobj/rubyblock.vim @@ -16,9 +16,15 @@ let s:comment_escape = '\v^[^#]*' let s:block_openers = '\zs(||||||' let s:block_openers .= '||||)' let s:start_pattern = s:comment_escape . s:block_openers +let s:mid_pattern = s:comment_escape +let s:mid_pattern .= '\zs(||||)' let s:end_pattern = s:comment_escape . '\zs' let s:skip_pattern = 'getline(".") =~ "\\v\\S\\s<(if|unless)>\\s\\S"' +if !exists('g:textobj_rubyblock_mids') + let g:textobj_rubyblock_mids = 0 +endif + function! s:select_a() let s:flags = 'W' @@ -38,15 +44,35 @@ function! s:select_i() let s:flags = 'cW' endif - call searchpair(s:start_pattern,'',s:end_pattern, s:flags, s:skip_pattern) + let l:mid = '' + if g:textobj_rubyblock_mids + let l:mid = s:mid_pattern + endif + + call searchpair(s:start_pattern,l:mid,s:end_pattern, s:flags, s:skip_pattern) " Move up one line, and save position normal k^ let end_pos = getpos('.') - " Move down again, jump to match, then down one line and save position - normal j^%j - let start_pos = getpos('.') + if g:textobj_rubyblock_mids + " Move down again, find match right before, and save position + normal j^ + let l:last_position = getpos('.') + let l:start_line = l:last_position[1] + normal % + while getpos('.')[1] != l:start_line + let l:last_position = getpos('.') + normal % + endwhile + call setpos('.', l:last_position) + normal j^ + let start_pos = getpos('.') + else + " Move down again, jump to match, then down one line and save position + normal j^%j + let start_pos = getpos('.') + endif return ['V', start_pos, end_pos] endfunction diff --git a/t/examples.rb b/t/examples.rb index 65a88d2..fe5c03f 100644 --- a/t/examples.rb +++ b/t/examples.rb @@ -81,3 +81,12 @@ def method_with_unless end var2 = 2 end + +def method_with_if_else + if condition + foo = 'foo' + bar = 'bar' + else + baz = 'baz' + end +end diff --git a/t/rubyblock_test.vim b/t/rubyblock_test.vim index 8b2ab0c..4d2b355 100644 --- a/t/rubyblock_test.vim +++ b/t/rubyblock_test.vim @@ -103,6 +103,30 @@ describe 'nested while and unless blocks' end +describe 'g:textobj_rubyblock_mids' + before + silent tabnew t/examples.rb + end + + after + silent tabclose + end + + context '1' + it 'selects only between mids' + let g:textobj_rubyblock_mids = 1 + Expect SelectInsideFrom(87, '^') ==# [87, 87, 88] + end + end + + context '0' + it 'ignores mids' + let g:textobj_rubyblock_mids = 0 + Expect SelectInsideFrom(87, '^') ==# [87, 87, 90] + end + end +end + describe '(textobj-rubyblock-i)' before From b54a9396469b9e50eacdbf15de11505b10e4878f Mon Sep 17 00:00:00 2001 From: Jeremiah Kellick Date: Sat, 11 Aug 2018 13:45:32 -0400 Subject: [PATCH 3/3] fix error in README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bd8ecfb..e5f62a9 100644 --- a/README.md +++ b/README.md @@ -63,10 +63,10 @@ Note too that the `ar` and `ir` text objects always position your cursor on the `end` keyword. If you want to move to the top of the selection, you can do so with the `o` key. -By default `ir` ignores middle keywords like `else` and `when`, but if you -prefer you can have `ir` acknowledge them by putting this in your .vimrc +By default `ir` ignores middle keywords like `else` and `when`, but you can have +`ir` acknowledge them by putting this in your .vimrc - g:textobj_rubyblock_mids = 1 + let g:textobj_rubyblock_mids = 1 Limitations -----------