diff options
Diffstat (limited to 'autoload/vimtex/text_obj.vim')
-rw-r--r-- | autoload/vimtex/text_obj.vim | 63 |
1 files changed, 55 insertions, 8 deletions
diff --git a/autoload/vimtex/text_obj.vim b/autoload/vimtex/text_obj.vim index 27d1a8b6..3b9105ff 100644 --- a/autoload/vimtex/text_obj.vim +++ b/autoload/vimtex/text_obj.vim @@ -385,23 +385,70 @@ endfunction " }}}1 function! s:get_sel_items(is_inner) abort " {{{1 let l:pos_cursor = vimtex#pos#get_cursor() + let l:val_cursor = vimtex#pos#val(l:pos_cursor) " Find previous \item - call vimtex#pos#set_cursor(l:pos_cursor[0], 1) - let l:pos_start = searchpos('^\s*\\item\S*', 'bcnWz') - if l:pos_start == [0, 0] | return [[], []] | endif + let l:depth = 0 + let l:pos_cur = vimtex#pos#next(l:pos_cursor) + while 1 + call vimtex#pos#set_cursor(vimtex#pos#prev(l:pos_cur)) + if l:depth > 5 | return [[], []] | endif + + let l:pos_start = searchpos( + \ l:depth > 0 ? '\\begin{\w\+}' : '^\s*\\item\S*', + \ 'bcnW') + let l:val_start = vimtex#pos#val(l:pos_start) + if l:val_start == 0 | return [[], []] | endif + + let l:pos_endenv = searchpos('\%(^\s*\)\?\\end{\w\+}', 'bcnW') + let l:val_endenv = vimtex#pos#val(l:pos_endenv) + + if l:val_endenv == 0 || l:val_start > l:val_endenv + if l:depth == 0 | break | endif + let l:pos_cur = l:pos_start + let l:depth -= 1 + else + let l:pos_cur = l:pos_endenv + let l:depth += 1 + endif + endwhile " Find end of current \item - call vimtex#pos#set_cursor(l:pos_start) - let l:pos_end = searchpos('\ze\n\s*\%(\\item\|\\end{itemize}\)', 'nW') - if l:pos_end == [0, 0] - \ || vimtex#pos#val(l:pos_cursor) > vimtex#pos#val(l:pos_end) + let l:depth = 0 + let l:pos_cur = l:pos_start + while 1 + call vimtex#pos#set_cursor(vimtex#pos#next(l:pos_cur)) + + let l:re = l:depth > 0 + \ ? '\\end{\w\+}' + \ : '\n\s*\%(\\item\|\\end{\(itemize\|enumerate\)}\)' + let l:pos_end = searchpos(l:re, 'nW') + let l:val_end = vimtex#pos#val(l:pos_end) + if l:depth == 0 && l:val_end == 0 + return [[], []] + endif + + let l:pos_beginenv = searchpos('\\begin{\w\+}', 'cnW') + let l:val_beginenv = vimtex#pos#val(l:pos_beginenv) + + if l:val_beginenv == 0 || l:val_end < l:val_beginenv + if l:depth == 0 | break | endif + let l:pos_cur = l:pos_end + let l:depth -= 1 + else + let l:pos_cur = l:pos_beginenv + let l:depth += 1 + endif + endwhile + + " The region must include the cursor + if l:val_cursor > l:val_end return [[], []] endif " Adjust for outer text object if a:is_inner - let l:pos_start[1] = searchpos('^\s*\\item\S*\s\?', 'cne')[1] + 1 + let l:pos_start[1] = searchpos('^\s*\\item\S*\s', 'cne')[1] + 1 let l:pos_end[1] = col([l:pos_end[0], '$']) - 1 endif |