Surrounding a latex equation in vim

1k views Asked by At

I use vim (and the vim latex-suite) to edit latex documents. Something that occurs frequently is the need to change an inline equation into a displayed equation, as follows. I start with:

The most important equation is \(f(x)=x^2,\) but most disagree.

and end with:

The most important equation is 
  \begin{equation*}
    f(x)=x^2,
    \end{equation*}
  but most disagree.

With the cursor on the "=" I'm happy to call a function to achieve the result, and I can probably figure out how to edit the indentation and spacing on my own, so it would be sufficient to output

The most important equation is 
\begin{equation*}
f(x)=x^2,
\end{equation*}
but most disagree.

Ideally, a function that works in the opposite direction (displayed equation to inline equation) would be great too, but first things first. FWIW, I'm using the surround.vim plugin, which seems great for surrounding text in \( \), but I'm not sure if it can be used to detect/highlight a latex equation. It seems to have this feature for HTML tags, but I haven't seen it implemented for latex. Any help would be greatly appreciated.

[EDIT:]

To clarify what I'm looking for, I'd say it's whether or not surround.vim can be used for custom asymmetric quote/bracket detection. Here's what I know how to do. In my ~/.vimrc file, I have the line

autocmd FileType tex let b:surround_101 = "\\(\r\\)"

Then when I'm editing a tex file and I have the following:

This is a $word in$ a some text.
            [ ]

I can type in normal mode:

cs$e

and I get

This is a \(word in\) a some text.
         [ ]

Similarly, if I have

This is a <p>word in</p> a some text.
              [ ]

I can type in normal mode:

cste

and I get

This is a \(word in\) a some text.
         [ ]

What I'd like to do is go from this:

This is a \(word in\) a some text.
             [ ]

to this:

This is a \foo word in \bar a some text.
         [ ]

I'd like to know if this is possible with surround.vim. For example, on this:

This is a \(word in\) a some text.
             [ ]

I tried

cse$

but that didn't change \(word in\) to $word in$ as I had hoped. If this is not possible to do with surround.vim, it would be a shame, since it already has the exact functionality for HTML tags that I want for latex equations, so it seems like I'd have to recode the same functionality for latex equations from scratch.

3

There are 3 answers

0
Ingo Karkat On

You can make surround.vim enclose text with \foo ... \bar with this:

let b:surround_102 = "\\foo \r \\bar"

Now, ys2wf will surround the next 2 words; f is the (arbitrarily) chosen replacement symbol and corresponds to :echo char2nr('f') => 102.

This is documented under :help surround-customizing. It defines a custom replacement. In order to convert \(...\) to \foo ... \bar (or vice versa), you also would have to define a custom target (cp. :help surround-targets). Unfortunately, that currently isn't supported by the plugin; only a fixed set of targets is supported, the tags are implemented as a special case inside the plugin. At least for literal replacements as in this case, I see no reason why the plugin couldn't also support those. Oh look, someone already opened an issue for exactly this!

There are also alternative plugins like vim-sandwich. I have only briefly looked at that plugin so far, but it seems to have far superior customizability, so it might work there.

0
Sam On

If you use vimtex rather than vim-latex-suite, I think it has what you're looking for. cse for change surrounding environment will ask you to input an environment name and then change the surrounding $'s to \begin{...} \end{...}, and it looks pretty straightforward to create custom bindings for commonly used environments. It can also toggle delimiters from ( ) to \left( \right), instantly toggle between equation and equation* environments.

0
D. Ben Knoble On

Note that recent versions of surround.vim provide a \ replace target, such that

yss\equation*<CR>

surrounds the line in an equation environment. l is a synonym.