Вопрос

I have looked at how to embed HTML syntax in JavaScript string from HTML syntax highlighting in javascript strings in vim.

However, when I use CoffeeScript I cannot get the same thing working by editing coffee.vim syntax file in a similar way. I got recursive errors which said including html.vim make it too nested.

I have some HTML template in CoffeeScript like the following::

angular.module('m', [])
  .directive(
    'myDirective'
    [
      ->
        template: """
        <div>
          <div>This is <b>bold</b> text</div>
          <div><i>This should be italic.</i></div>
        </div>
        """
    ]
  )

How do I get the template HTML syntax in CoffeeScript string properly highlighted in VIM?

Это было полезно?

Решение

I would proceed as follows:

Find out the syntax groups that should be highlighted as pure html would be. Add html syntax highlighting to these groups.

To find the valid syntax group under the cursor you can follow the instructions here.

In your example the syntax group of interest is coffeeHereDoc.

To add html highlighting to this group execute the following commands

unlet b:current_syntax
syntax include @HTML syntax/html.vim
syn region HtmlEmbeddedInCoffeeScript start="" end=""
\    contains=@HTML containedin=coffeeHereDoc

Since vim complains about recursion if you add these lines to coffee.vim i would go with an autocommand:

function! Coffee_syntax()
    if !empty(b:current_syntax)
        unlet b:current_syntax
    endif
    syn include @HTML syntax/html.vim
    syn region HtmlEmbeddedInCoffeeScript start="" end="" contains=@HTML
\       containedin=coffeeHereDoc
endfunction

autocmd BufEnter *.coffee call Coffee_syntax()

Другие советы

I was also running into various issues while trying to get this to work. After some experimentation, here's what I came up with. Just create .vim/after/syntax/coffee.vim with the following contents:

unlet b:current_syntax
syntax include @HTML $VIMRUNTIME/syntax/html.vim
syntax region coffeeHtmlString matchgroup=coffeeHeredoc
\      start=+'''\\(\\_\\s*<\\w\\)\\@=+ end=+\\(\\w>\\_\\s*\\)\\@<='''+ 
\      contains=@HTML
syn sync minlines=300

The unlet b:current_syntax line disables the current syntax matching and lets the HTML syntax definition take over for matching regions.

Using an absolute path for the html.vim inclusion avoids the recursion problem (described more below).

The region definition matches heredoc strings that look like they contain HTML. Specifically, the start pattern looks for three single quotes followed by something that looks like the beginning of an HTML tag (there can be whitespace between the two), and the end pattern looks for the end of an HTML tag followed by three single quotes. Heredoc strings that don't look like they contain HTML are still matched using the coffeeHeredoc pattern. This works because this syntax file is being loaded after the syntax definitions from the coffeescript plugin, so we get a chance to make the more specific match (a heredoc containing HTML) before the more general match (the coffeeHeredoc region) happens.

The syn sync minlines=300 widens the matching region. My embedded HTML strings sometimes stretched over 50 lines, and Vim's syntax highlighter would get confused about how the string should be highlighted. For complete surety you could use syn sync fromstart, but for large files this could theoretically be slow (I didn't try it).

The recursion problem originally experienced by @heartbreaker was caused by the html.vim script that comes with the vim-coffeescript plugin (I'm assuming that was being used). That plugin's html.vim file includes the its coffee.vim syntax file to add coffeescript highlighting to HTML files. Using a relative syntax include, a la

syntax include @HTML syntax/html.vim

you get all the syntax/html.vim files in VIM's runtime path, including the one from the coffeescript plugin (which includes coffee.vim, hence the recursion). Using an absolute path will restrict you to only getting the particular syntax file you specify, but this seems like a reasonable tradeoff since the HTML one would embed in a coffeescript string is likely fairly simple.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top