summaryrefslogtreecommitdiffstats
path: root/autoload/vimtex/text_obj.vim
diff options
context:
space:
mode:
Diffstat (limited to 'autoload/vimtex/text_obj.vim')
-rw-r--r--autoload/vimtex/text_obj.vim63
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