[OT] mixed lang metaprogramming w/ vim?

Doug Kearns dougkearns at gmail.com
Thu Oct 26 11:47:35 EDT 2006


G'day Hugh,

On Wed, Oct 25, 2006 at 05:39:09PM +0100, Hugh Sasse wrote:
> I'm generating (not quite repetitive enough to refactor) C code from
> Ruby, so there are lots of strings with C code in them, but with
> Ruby 'escapes' #{@variable} in them.  I can't find much about how to
> get vim to highlight the C bits in a more C like way, and I'm not
> sure how to make vim flip between languages within a file  for the
> more general case.   Does anyone have any URLs that are "Not to be
> missed!" on this please?

Nope.

> I know that one's mileage will vary with 
> such an approach, but if I can reduce the errors by better highlighting
> that would be good.

This is a bit of a '2 AM solution' so I wish you luck with it. :-)

Add the following to your ~/.vim/after/syntax/ruby.vim

--------------------------------------------------------------------------------
unlet b:current_syntax
syn include @cTop syntax/c.vim
let b:current_syntax = "ruby"

syn region rubyCString start=+\%(\%(class\s*\|\%(\.\|::\)\)\_s*\)\@<!<<CSTRING\ze+hs=s+2    matchgroup=rubyStringDelimiter end=+^CSTRING$+ contains=rubyHeredocStart, at rubyStringSpecial, at cTop fold keepend
syn region rubyCString start=+\%(\%(class\s*\|\%(\.\|::\)\)\_s*\)\@<!<<"CSTRING"\ze+hs=s+2  matchgroup=rubyStringDelimiter end=+^CSTRING$+ contains=rubyHeredocStart, at rubyStringSpecial, at cTop fold keepend
syn region rubyCString start=+\%(\%(class\s*\|\%(\.\|::\)\)\_s*\)\@<!<<'CSTRING'\ze+hs=s+2  matchgroup=rubyStringDelimiter end=+^CSTRING$+ contains=rubyHeredocStart, at cTop		      fold keepend
syn region rubyCString start=+\%(\%(class\s*\|\%(\.\|::\)\)\_s*\)\@<!<<`CSTRING`\ze+hs=s+2  matchgroup=rubyStringDelimiter end=+^CSTRING$+ contains=rubyHeredocStart, at rubyStringSpecial, at cTop fold keepend

syn region rubyCString start=+\%(\%(class\s*\|\%(\.\|::\)\)\_s*\)\@<!<<-CSTRING\ze+hs=s+3    matchgroup=rubyStringDelimiter end=+^\s*\zsCSTRING$+ contains=rubyHeredocStart, at rubyStringSpecial, at cTop fold keepend
syn region rubyCString start=+\%(\%(class\s*\|\%(\.\|::\)\)\_s*\)\@<!<<-"CSTRING"\ze+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zsCSTRING$+ contains=rubyHeredocStart, at rubyStringSpecial, at cTop fold keepend
syn region rubyCString start=+\%(\%(class\s*\|\%(\.\|::\)\)\_s*\)\@<!<<-'CSTRING'\ze+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zsCSTRING$+ contains=rubyHeredocStart, at cTop		     fold keepend
syn region rubyCString start=+\%(\%(class\s*\|\%(\.\|::\)\)\_s*\)\@<!<<-`CSTRING`\ze+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zsCSTRING$+ contains=rubyHeredocStart, at rubyStringSpecial, at cTop fold keepend

syn cluster cCommentGroup contains=cTodo,rubyInterpolation
--------------------------------------------------------------------------------

and you'll be able to highlight C code and interpolated Ruby expressions
in 'heredocs' delimited with CSTRING.  For example:

--------------------------------------------------------------------------------
def generate_hello_world
  message = "Hello world\\n"
  header = "The old standard"
  exit_status = 0
  puts <<-CSTRING

/* [#{header}] */
#include <stdio.h>
int main(void) {
  printf("#{message}");
  return #{exit_status};
}

  CSTRING
end

if __FILE__ == $0
  generate_hello_world
end
--------------------------------------------------------------------------------

As you can see Ruby interpolation sequences aren't being highlighted in
C strings yet but hopefully this will get you started.

> Is there a better way to do this sort of thing which would avoid my
> having to torture Vim into doing this?

Not that I can think of...

Regards,
Doug


More information about the vim-ruby-devel mailing list