7

I use Vim to edit LaTeX files frequently. I want to use % to jump between matching $ which can be used to delimit where mathematical expressions are written.

I have tried using matchit and, separately, I have tried using a filetype.vim (tex.vim) file to add a match to the matchpairs variable (au FileType tex setmps+=$:$). I have managed to get both attempts to jump from the $. However, the match that is found is for a different delimiter.

For example, considering the string $ { test text } $, placing my cursor over the first $ and pressing % would jump me to the closing }, not the last $. Continued use of % jumps me between { and }. Thus, I am stuck inside the match that I want to consider.

Does anyone know how I might accomplish a jump from the first $ to the last $?

muru
  • 24,838
  • 8
  • 82
  • 143
fuzzybear3965
  • 618
  • 4
  • 13

3 Answers3

6

What you ask is possible, but the solution is nontrivial. Both LaTeX-Box and vimtex has implemented solutions for this, see here:

These functions are run by autocommands whenever the cursor is moved, see here (LaTeX-Box) and here (vimtex). The original matchparen plugin is disabled, and the LaTeX-specific function, e.g. s:highlight_matching_pair, is enabled as a custom matchparen-plugin. Note that both these functions also enable matching of other LaTeX-delimiters such as begin/end pairs and pairs like \left(..\right).

Note: The links above are linked to line numbers in evolving codes. These line numbers might change in the future. The function names will probably stay the same.

Note: Other LaTeX-plugins might also implement this feature.

Disclaimer: I'm the author of vimtex.

Karl Yngve Lervåg
  • 9,494
  • 25
  • 35
  • Thanks, Karl, for your explanation. I understand, now, that I won't be adding a couple lines to my .vimrc to implement this functionality. I use vim-latex as my current vim plugin for editing LaTeX files. I'm considering forking vim-latex to improve it. If I do this, I might introduce something like your s:highlight_matching_pair or LaTeX-Box's s:FindMatchingPair. I see that both plugins require a separate logic branch (if statement) to process if the delimiter being matched is a '$', or not. It's special. – fuzzybear3965 Jun 08 '15 at 22:34
  • Personally I don't recommend forking vim-latex (aka LaTeX-Suite), instead I would suggest you open a pull request here. Personally I don't like vim-latex, mostly because it is huge and difficult to improve and customize. – Karl Yngve Lervåg Jun 09 '15 at 06:29
3

Your $ match is ignored, % searches forward for the first character in a pair that it knows about: so it finds { and then the matching }, and moves between them.

From :h mps:

Only character pairs are allowed that are different,
thus you cannot jump between two double quotes.

One solution would be: to use the 'matchit' plugin (which allows for regular expressions as pairs, but has the same start != end delimiter) AND use the LaTeX math delimiters \( \), which are different. Or, define two new TeX different commands for start & end inline math environment, that both resolve to $, and use them as pairs.

So, you can do in your vimrc:

runtime! macros/matchit.vim

And, for TeX files (e.g. in a function called from a BufEnter autocmd):

let b:match_words = '\\(:\\)'

If you have to use the $ sign, you can cheat a little and use this:

let b:match_words = '\s\$:\$\s'

... which will match a $ preceded by space as start delimiter with a $ followed by a space as end delimiter. But then you'll have to be consistent inside your formulas and use no space after the start delimiter, or before the end one. E.g.:

 ␣$\cos (2\theta) = \cos^2 \theta - \sin^2 \theta$␣ 
VanLaser
  • 9,700
  • 2
  • 24
  • 34
  • Vim already knows which $ characters are opening and which are closing because it highlights math segments. Could the information used by highlighting be leveraged for that improved % command? – Gilles 'SO- stop being evil' Jun 08 '15 at 21:53
  • If you open $VIMRUNTIME/syntax/tex.vim and search for \$s (heh), you'll see comments like this: «The $..$ and $$..$$ make for impossible sync patterns (one can't tell if a "$$" starts or stops a math zone by itself) The following grouptheres coupled with minlines above help improve the odds of good syncing.» and «4. There is no match-syncing for $...$ and $$...$$; hence large equation blocks constructed that way may exhibit syncing problems (there's no difference between begin/end patterns)». Maybe if you use text objects instead, e.g.: https://github.com/gibiansky/vim-latex-objects – VanLaser Jun 08 '15 at 22:24
  • To reuse existing syntax highlighting, but still with text-objects, you also have: https://github.com/kana/vim-textobj-syntax, which defines a textobj-syntax-i as "the syntax highlighted item under the cursor". Then, for example, you can visually select the $...$ as math object, and if you hit o, move cursor to the other end of the visual selection. But still doesn't answer your suggestion of implementing % from syntax highlight rules ... I would like to see a vim guru coming up with some idea. – VanLaser Jun 08 '15 at 22:31
  • Both vimtex and LaTeX-Box use the syntax group to determine the boundaries of $...$ as suggested by @Gilles. – Karl Yngve Lervåg Jun 09 '15 at 06:31
  • Another reason to use vimtex, then :) Thanks for the info. – VanLaser Jun 09 '15 at 08:41
2

Add the line

runtime! macros/matchit.vim

to your vimrc and into ~/.vim/after/ftplugin/tex.vim the lines

let b:match_words = get(b:, 'match_words', &l:matchpairs)
      \ ',' . '\%(^\|[ (/]\)\zs\\(' . ':' . '\\)\ze\%($\|[ )/.\,;\:?!\-]\)' .
      \ ',' . '\%(^\|[ (/]\)\zs\\\[' . ':' . '\\\]\ze\%($\|[ )/.\,;\:?!\-]\)' .
      \ ',' . '\%(^\|[ (/]\)\zs\$[^$ ]' . ':' . '[^$ ]\zs\$\ze\%($\|[ )/.\,;\:?!\-]\)' .
      \ ',' . '\%(^\|[ (/]\)\zs\$\$' . ':' . '\$\$\ze\%($\|[ )/.\,;\:?!\-]\)' .
      \ ',' . '\%(^\s*\)\zs\\begin{\(\w\+\*\?\)}' . ':' . '\%(^\s*\)\zs\\end{\1}' .

This lets you jump between TeX math and environment delimiters by % (but isn't yet entirely robust).

Enno
  • 211
  • 1
  • 2
  • Thanks, I'm actually using the vimtex plugin which is in active development and provides a lot of nice TeX features. You might check it out. – fuzzybear3965 Feb 23 '16 at 22:42