34

If I use the inline version of lstlisting as shown:

\lstinline{!$omp parallel for}

the syntax highlighting in vim goes wrong, and the remainder of the latex file is coloured red as if it is all part of the code listing. It's the dollar $ which causes the problem. How can I avoid this?

Conner
  • 30,144
  • 8
  • 52
  • 73
user2023370
  • 10,488
  • 6
  • 50
  • 83
  • 6
    This seems to be a bug in the general vim syntax highlighting for tex as `\verb{!$omp}` produces the same result. You can try the newest syntax file from http://mysite.verizon.net/astronaut/vim/syntax/tex.vim.gz and contact its author Charles E. Campbell, Jr. – Jakob Jul 25 '11 at 11:36
  • 2
    50 rep for whoever answers with a **fix** for tex.vim. – ThiefMaster Aug 27 '11 at 15:48

8 Answers8

29

Let's finally solve this issue once and for all!

I mailed Charles E. Campbell, the maintainer of tex.vim, suggesting he'd add highlighting rules for the listings package. However it turns out lacking support for the listings package in tex.vim is actually intentional. The reasoning can be found :h tex-package. In short, you're supposed to create your own extended syntax highlighting rules (see bottom of post):

Tex: Want To Highlight More Commands?

LaTeX is a programmable language, and so there are thousands of packages full of specialized LaTeX commands, syntax, and fonts. If you're using such a package you'll often wish that the distributed syntax/tex.vim would support it. However, clearly this is impractical. So please consider using the techniques in mysyntaxfile-add to extend or modify the highlighting provided by syntax/tex.vim. Please consider uploading any extensions that you write, which typically would go in $HOME/after/syntax/tex/[pkgname].vim, to http://vim.sf.net/.

Personally I think it's a little unfortunate that it's not going to be included, as it surely increases the threshold for the average user to write his or hers LaTeX using Vim. Finding and adding syntax highlighting for lstlisting, lstinline etc. isn't too easy. It does not look like it's going to change anytime soon either when looking at this thread.

DevSolar seems to have already found it (and I appreciate the credit!), but Campbell offers a couple of example LaTeX package support vimballs. The first one, lstlisting.vba.gz, includes highlighting rules for lstlisting and lstinputlisting. It does however lack lstinline, which this topic is about.

Finally, here's my listings.vim resided in $HOME/.vim/after/syntax/tex/

syn region texZone start="\\begin{lstlisting}" end="\\end{lstlisting}\|%stopzone\>"
syn region texZone  start="\\lstinputlisting" end="{\s*[a-zA-Z/.0-9_^]\+\s*}"
syn match texInputFile "\\lstinline\s*\(\[.*\]\)\={.\{-}}" contains=texStatement,texInputCurlies,texInputFileOpt

-

Proper highlighting of verbatim, lstlisting and lstinline environments.

This seems to be the preferred solution. It does not require one to alter system wide files in /usr/share/vim/.., you don't have to download and source a vimball or alter environments rather than fixing the syntax highlighting itself. I might into look into releasing this as a simple plugin to make it more accessible.

Lastly, remember to check that you're actually running the tex filetype and not plaintex which lacks far too much to be viable. Already posted this in a comment above, but some more information can be found in a ticket I added to LaTeX-Box.

timss
  • 9,982
  • 4
  • 34
  • 56
  • “As is shown in other answers, Konrad Rudolph's theory that Vim's syntax highlighter is not up for the job is also a little off.” – Wrong. You seem not to understand how LaTeX works. If you “fix” the problem, a simple `\let\foo\verb` reintroduces it. You **cannot** solve this problem in a general way, as I’ve explained in my answer. All you can ever hope to achieve are highly limited solutions (which is obviously fine if you customise it for your purposes; but providing a default is impractical if you use LaTeX correctly, i.e. when writing semantic code). – Konrad Rudolph Feb 08 '14 at 21:10
  • @KonradRudolph Sorry if I misunderstood your answer. In what context would `\let\foo\verb` reintroduce the problem? I tried playing around with it, but to no avail. In what way would the minor changes to the tex syntax highlighting I have in my answer not work for "semantic code"? – timss Feb 08 '14 at 22:09
  • Well once you use your own macros rather than predefined ones, the syntax highlighter doesn’t recognise verbatim code any more. You need to make explicitly aware of your macros. – Konrad Rudolph Feb 08 '14 at 23:08
  • @KonradRudolph Hmm, I can't really see how. All the changes I've done is the three lines in my answer, and it's my understanding that it's working as intended (shown in picture). Not trying to deny anything, but can't really see what is the downside with adding those additional syntax rules. – timss Feb 09 '14 at 01:28
  • 4
    To repeat, your changes of course work *as long as* you use bare `\begin{lstlisting}`. But often you wouldn’t do this, you would instead use `lstlisting` within a macro called, say, `\terminal`. If you then used `\terminal{$ uname -a}` this would screw up your highlighting. Of course you can now add a special syntax rule for `\terminal`. I’m just saying that this is not a *general* solution (although it may work well enough in practice) because `\terminal` might well be redefined during the execution of the script. And no, this is not just a theoretical problem, I have had this situation. – Konrad Rudolph Feb 09 '14 at 10:54
  • @KonradRudolph That's a fair point, didn't think of it that way. I guess it's bothersome to have to into account macros based off `lstlisting`, but if you don't use said macros, or have a set you usually use, adding those wouldn't be too much of a problem. – timss Feb 09 '14 at 14:59
7

The initial Problem seemed to me, that the rest of the tex-File is shown with messed-up syntax highlighting. So maybe the easy and practicable Solution could be to use a

%stopzone

after the lstlisting-Region.

6

This isn’t really a bug – it’s by design. In order to highlight this correctly, Vim would have to parse and interpret the whole TeX document up until the point where this code occurs, since TeX is a context-sensitive language. This is both too complex and too time-consuming for a syntax highlighting plugin.

The only acceptable fix would be to rewrite the syntax highlighter from scratch, using a complete implementation of TeX that emits meta information for each token in the source code. This is a huge project. As far as I know, no currently available TeX implementation gives such information, which means that one would really have to write this oneself.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 6
    Well it would be sufficient if it handled `\lstinline{...}` blocks just like e.g. `\begin{lstlisting}...\end{lstlisting}` where everything works fine. – ThiefMaster Aug 27 '11 at 16:03
4

This works for me:

\lstinline[mathescape]{!$\$$omp parallel for}

As far as I understand, it typesets the dollar symbol in math mode, but I couldn't see any visible difference.

3

I had a similar problem with inserting R commands for knitr in tex files. I had a lot of $ and other special characters within \rinline{}. And I fixed it so that Vim ignores text within this command.

You want to edit tex.vim file, on my distribution it is sudo vim /usr/share/vim/vim73/syntax/tex.vim

At ca. line line 228:

syn match texInputFile      "\\\(epsfig\|input\|usepackage\)\s*\(\[.*\]\)\={.\{-}}"     contains=texStatement,texInputCurlies,texInputFileOpt

Change to:

syn match texInputFile      "\\\(epsfig\|input\|usepackage\|rinline\)\s*\(\[.*\]\)\={.\{-}}"        contains=texStatement,texInputCurlies,texInputFileOpt

... or for lstinline:

syn match texInputFile      "\\\(epsfig\|input\|usepackage\|lstinline\)\s*\(\[.*\]\)\={.\{-}}"      contains=texStatement,texInputCurlies,texInputFileOpt
timss
  • 9,982
  • 4
  • 34
  • 56
cmbarbu
  • 4,354
  • 25
  • 45
  • Optionally add `syn match texInputFile "\\lstinline\s*\(\[.*\]\)\={.\{-}}" contains=texStatement,texInputCurlies,texInputFileOpt` to `$HOME/.vim/after/syntax/tex/lstinline.vim` (or similar). For more information see https://github.com/LaTeX-Box-Team/LaTeX-Box/issues/124 – timss Sep 19 '13 at 17:23
1

Based on timss' answer, create a file named ~/.vim/after/syntax/tex/listings.tex and add the following rule. Replace YOURENV with the environment you want to make the highlighting exception for!

syn region texZone start="\\begin{YOURENV}" end="\\end{YOURENV}\|%stopzone\>"

This rule should now automatically be loaded next time you open Vim with an existing .tex file.

screenshot of the highlighting before and after adding the rule

Luc
  • 5,339
  • 2
  • 48
  • 48
  • I think the syntax file should be named `tex.vim` not listings.vim, don't you? – SergioAraujo Dec 04 '20 at 23:16
  • 1
    @SergioAraujo For me it worked like this, though I can double check and edit the answer if you say it doesn't work for you with a filename other than `tex.vim`. It might also just depend on if you have a custom file there for (la)tex already, you can append to that file instead of creating a new one to keep the directory cleaner. – Luc Dec 05 '20 at 01:03
0

Going through the link posted by timss on user1174052's answer, I found Dr Chip's Vim Page, which provides the lstlisting.vba.gz Vimball plugin. Download, open in Vim...

vim lstlisting.vba.gz

...execute the vimball...

:so %

...and the next time you open a LaTeX file, contents of lstlisting environments are completely ignored by the syntax highlighting.

Credit goes to user timss, who posted the link to the LaTeX-Box ticket, where he also posted the link to Dr Chip's page. I added this answer merely as a "direct link" shortcut.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • Thanks for the credit! I think I finally concluded this issue so please take a look at my new (big) post. – timss Feb 08 '14 at 20:20
0

I don't have this issue. I am running Vim 7.3.46 with filetype=tex. (Mine defaults to "plaintex" on .tex files; you might want to check filetype with :set ft?)

Kristoff vdH
  • 224
  • 2
  • 4