Olivier Pons
Olivier Pons

Reputation: 15778

vim: how to apply a *new* syntax highlighting (smarty) instead of html depending on file content?

I've installed (and it seems to work well) this "Smarty syntax highlighting" file here. The problem is that it's linked to *.tpl files. I've got the HTML syntax highlighting as well.

Here's what I'd like to do: when opening HTML files, just check if there are some special Smarty characters like { (alphanum) $xx (alphanum) } or {* *}. If so, use "Smarty syntax highlighting" otherwise use "HTML syntax highlighting". Any idea how I could do this?

Don't hesitate to change my subject to make it more generic, and my question as well.

Thank you very much!

Upvotes: 1

Views: 841

Answers (2)

kongo2002
kongo2002

Reputation: 1024

Since I am not too familiar with the smarty syntax you may want to adjust the regular expression of my example below.

function! s:CheckSmarty()
    for i in range(1, min([10, line('$')]))
        let line = getline(i)
        if line =~ '{\*.\{-}\*}'
            setl filetype=smarty
            return
        endif
    endfor
endfunction

au BufNewFile,BufRead *.html,*.htm call s:CheckSmarty()

You can easily modify the number of lines to check for the smarty tags in every html file. It's important to use setlocal here in order to just modify the current buffer.

Upvotes: 0

anon
anon

Reputation:

Placing this in you vimfiles as ftdetect/smarty.vim should work:

autocmd BufNewFile,BufRead *.html call s:CheckForSmarty()

function! s:CheckForSmarty()
  for n in range(1, line('$'))
    let line = getline(n)
    if line =~ '{.*$\k\+}' || line =~ '{\*.*\*}'
      set filetype=smarty
      return
    endif
  endfor
endfunction

Basically, every time you open an html file, the (script-local) function s:CheckForSmarty will be called. It will go through each line and test it against the two regular expressions you see. If one of them matches, the filetype is set to smarty and the function ends its execution. Otherwise, we let vim take care of the rest. You can tweak the regexes if they don't work well enough for you, I'm not really a smarty user, so I can't be sure if they cover all use cases.

This may be slow on large html files, I've only tested it on small ones. If it turns out to be a problem, you can limit the script to only check the first 10 lines (this is how the htmldjango filetype is detected):

function! s:CheckForSmarty()
  for n in range(1, line('$'))
    if n > 10
      return
    endif

    let line = getline(n)
    if line =~ '{.*$\k\+}' || line =~ '{\*.*\*}'
      set filetype=smarty
      return
    endif
  endfor
endfunction

Another way to manually fix a speed problem is by placing a comment at the top of the file, like {* smarty *}. Vim will see the comment on the very first line, so there will be no reason to iterate through the rest of the file.

Upvotes: 2

Related Questions