diff --git a/autoload/vimtex.vim b/autoload/vimtex.vim index 019721153d..84ff1ba80f 100644 --- a/autoload/vimtex.vim +++ b/autoload/vimtex.vim @@ -253,6 +253,10 @@ function! s:init_default_mappings() abort " {{{1 call s:map(1, 'x', 'am', '(vimtex-am)') call s:map(1, 'o', 'im', '(vimtex-im)') call s:map(1, 'o', 'am', '(vimtex-am)') + call s:map(1, 'x', 'ix', '(vimtex-ix)') + call s:map(1, 'x', 'ax', '(vimtex-ax)') + call s:map(1, 'o', 'ix', '(vimtex-ix)') + call s:map(1, 'o', 'ax', '(vimtex-ax)') if vimtex#text_obj#targets#enabled() call vimtex#text_obj#targets#init() diff --git a/autoload/vimtex/text_obj.vim b/autoload/vimtex/text_obj.vim index 60c9995811..bd771e920f 100644 --- a/autoload/vimtex/text_obj.vim +++ b/autoload/vimtex/text_obj.vim @@ -15,6 +15,7 @@ function! vimtex#text_obj#init_buffer() abort " {{{1 \ ['$', 'delimited', 'env_math'], \ ['P', 'sections', ''], \ ['m', 'items', ''], + \ ['x', 'symbols', ''], \] let l:optional = empty(l:opt) ? '' : ',''' . l:opt . '''' execute printf('xnoremap (vimtex-i%s) :call vimtex#text_obj#%s(1, 1%s)', l:map, l:name, l:optional) @@ -229,6 +230,54 @@ function! vimtex#text_obj#items(is_inner, mode) abort " {{{1 call vimtex#pos#set_cursor(l:pos_end) endfunction +" }}}1 +function! vimtex#text_obj#symbols(is_inner, mode) abort " {{{1 + " Disable for now + return + + if a:is_inner + call vimtex#log#warning('Not implemented!') + return + endif + + " We are looking for constructs like this: + " + " a^{...}_{...} + " \cmd^{...}_{...} + + " Repeat the following until finished + + if !vimtex#syntax#in_mathzone() + \ || getline('.')[cursor] ==# '$' + return + endif + + " 1. Find beginning: \ or word boundary + " 1.1 move cursor backwards as long as it is over [ ^_{}] + " 1.2 note position of character (this is start if type=char) + " 1.3 move backwards to check if symbol is a command + " 1.4 register type: l:type = cmd|char + + " 2. Look for ^ or _ groups (finished if not found) + " 2.1 start from start position + " 2.2 go forward until [ ^_] + " 2.3 if white-space: set end position, go to 3 + " 2.4 match either single character or {...} group, then continue with + " search for next ^ or _ (sort of repeat from 2.2) + + " 3. Region from 1 to 2 is now a candidate region + " 3.1 reject if the region is trivial length (0 or 1) + " 3.2 reject if the region does not contain the cursor position + " 3.3 if rejected: move active cursor position to the position before the + " boundary detected in step 1 and repeat from step 0. + + " let l:pos_save = vimtex#pos#get_cursor() + + " call vimtex#pos#set_cursor(l:pos_start) + " normal! v + " call vimtex#pos#set_cursor(l:pos_end) +endfunction + " }}}1 function! s:get_sel_delimited_visual(is_inner, type, startpos) abort " {{{1 diff --git a/doc/vimtex.txt b/doc/vimtex.txt index a4c9d9b60c..e6751367af 100644 --- a/doc/vimtex.txt +++ b/doc/vimtex.txt @@ -175,6 +175,7 @@ FEATURE OVERVIEW *vimtex-features* - `i$` `a$` Inline math structures - `iP` `aP` Sections - `im` `am` Items + - `ix` `ax` Symbols with sub- and superscripts - Other mappings - Delete the surrounding command, environment or delimiter with `dsc`/`dse`/`ds$`/`dsd` @@ -812,6 +813,8 @@ This feature is explained in more detail later, see |vimtex-imaps|. iP |(vimtex-iP)| `xo` am |(vimtex-am)| `xo` im |(vimtex-im)| `xo` + ax |(vimtex-ax)| `xo` + ix |(vimtex-ix)| `xo` % |(vimtex-%)| `nxo` ]] |(vimtex-]])| `nxo` ][ |(vimtex-][)| `nxo` @@ -3316,6 +3319,8 @@ MAP DEFINITIONS *vimtex-mappings* *(vimtex-iP)* *(vimtex-am)* Items *(vimtex-im)* +*(vimtex-ax)* Symbol with sub- and superscripts (in math mode only) +*(vimtex-ix)* These are all text object mappings for the indicated types of objects , see |vimtex-text-objects| for more info. @@ -3664,26 +3669,32 @@ a simple table that shows the original text on the left, the keys that are typed in the middle, and the result on the right. The bar "|" indicates the cursor position before the operation. > - BEFORE KEYS AFTER - \comm|and{arg} dic \command{} - \command{a|rg} gUac \COMMAND{ARG} + BEFORE KEYS AFTER + \comm|and{arg} dic \command{} + \command{a|rg} gUac \COMMAND{ARG} - \lef|t( asd \right) cid \left(| \right) + \lef|t( asd \right) cid \left(| \right) - \begin{x} die \begin{x} - hello world| \end{x} + \begin{x} die \begin{x} + hello world| \end{x} \end{x} - $math | here$ da$ + $math | here$ da$ - \begin{itemize} \begin{itemize} - \item hello moon| cim \item | - \end{itemize} \end{itemize} + \begin{itemize} \begin{itemize} + \item hello moon| cim \item | + \end{itemize} \end{itemize} - \begin{itemize} \begin{itemize} - \item hello moon| dam \end{itemize} + \begin{itemize} \begin{itemize} + \item hello moon| dam \end{itemize} \end{itemize} + $C|x_0^{1/2} y$ dax $x_0^{1/2} y$ + $Cx|_0^{1/2} y$ dax $C y$ + $\left( as|d \right)^{...}$ dax $\left( ad \right)^{...}$ + $\left( asd \rig|ht)^{...}$ dax $$ + $e^{a x|^3}$ dax $e^{a }$ + Associated settings: * |g:vimtex_text_obj_enabled| * |g:vimtex_text_obj_linewise_operators| diff --git a/test/test-textobj/Makefile b/test/test-textobj/Makefile index 5d30acdc86..d910f549fb 100644 --- a/test/test-textobj/Makefile +++ b/test/test-textobj/Makefile @@ -8,7 +8,7 @@ TESTS := $(TESTS:.vim=) .PHONY: test $(TESTS) -test: $(TESTS) +test: $(filter-out test-symbols,$(TESTS)) $(TESTS): @$(MYVIM) -u $@.vim diff --git a/test/test-textobj/test-symbols.vim b/test/test-textobj/test-symbols.vim new file mode 100644 index 0000000000..06cdbfbe8a --- /dev/null +++ b/test/test-textobj/test-symbols.vim @@ -0,0 +1,27 @@ +set nocompatible +let &rtp = '../..,' . &rtp +filetype plugin on +syntax on + +set nomore + +setfiletype tex + +for [s:keys, s:input, s:expect] in [ + \ ['dax', '$Cx_0^{1/2} y$', '$x_0^{1/2} y$'], + \ ['ldax', '$Cx_0^{1/2} y$', '$x_0^{1/2} y$'], + \ ['lldax', '$Cx_0^{1/2} y$', '$C y$'], + \ ['dax', '$e^{a x^3}$', '$$'], + \ ['fadax', '$e^{a x^3}$', '$e^{ x^3}$'], + \ ['fxdax', '$e^{a x^3}$', '$e^{a }$'], + \ ['2ldax', '$\sin_k^{a x^3}$', '$$'], + \ ['fxdax', '$\sin_k^{a x^3}$', '$\sin_k^{a }$'], + \ ['fadax', '$( asd )^{...}$', '$( sd )^{...}$'], + \ ['f}dax', '$( asd )^{...}$', '$$'], + \ ['fsdax', '$\left( asd \right)^{...}$', '$\left( ad \right)^{...}$'], + \ ['fgdax', '$\left( asd \right)^{...}$', '$$'], + \] + call vimtex#test#keys(s:keys, s:input, s:expect) +endfor + +call vimtex#test#finished()