If anyone is interested, here are two approaches to do something similar in ConTeXt with the vim module.
First approach
The vim module (actually, the filter module on which it is based), provides two features that can be combined to ensure that the external syntax highlighter is not called multiple times.
The first feature is buffers which gets around the limitation that \start<vimtyping> ... \stop<vimtyping> cannot be used in a macro. buffers are meant for display listings, so it inserts a newline after the buffer is typeset. To avoid that, simply wrap it around a \hbox (This means that the text will not be broken across lines).
\startbuffer[while]while\stopbuffer
\def\FIRSTWHILE{\hbox{\processCbuffer[while]}}
The second feature is the state=stop option which ensures that the syntax highlighting program is not run. (This option is meant for the situations when you want to send your files to a colleague who does not have the syntax highlighting program).
\def\SECONDWHILE{\hbox{\processCbuffer[state=stop][while]}}
Now all that remains to be done is to define a macro that calls \FIRSTWHILE the first time it is called and \SECONDWHILE after that:
\def\WHILE
{\FIRSTWHILE
\glet\WHILE\SECONDWHILE}
Combining everything together:
\usemodule[vim]
\definevimtyping[C][syntax=c]
\startbuffer[while]while\stopbuffer
\def\FIRSTWHILE{\hbox{\processCbuffer[while]}}
\def\SECONDWHILE{\hbox{\processCbuffer[state=stop][while]}}
\def\WHILE
{\FIRSTWHILE
\glet\WHILE\SECONDWHILE}
\starttext
\dorecurse{10}{what \WHILE{} something }
\stoptext
Note that with this approach, the buffer is still written to file each time the macro is called (but file IO is relatively fast); just the syntax highlighting program is not called.
Second approach
The second approach is to simply save the string to a file using \savebuffer, and typeset it using \typeset<vim>file. This has the advantage that the data is written to the file only once (at the beginning of each multi-run compile), and the syntax highlighter is run only when the md5 sum of the string changes (which effectively means, only when the string changes).
\usemodule[vim]
\definevimtyping[C][syntax=c]
\startbuffer[while]while\stopbuffer
\savebuffer[while][whatever] %Saved in \jobname-whatever.tmp
\def\FIRSTWHILE{\hbox{\typeCfile{\jobname-whatever.tmp}}}
\def\SECONDWHILE{\hbox{\typeCfile[state=stop]{\jobname-whatever.tmp}}}
\def\WHILE
{\FIRSTWHILE
\glet\WHILE\SECONDWHILE}
\starttext
\dorecurse{10}{what \WHILE{} something }
\stoptext
This approach can also be used in LaTeX (but the syntax highlighter will be run once every run since minted package does not cache the results).
\lstinlinefrom thelistingspackage do as well? – egreg Sep 19 '12 at 22:43