jonsmithers / vim-html-template-literals

Syntax highlighting for html template literals in javascript (as in lit-html and polymer 3)
MIT License
69 stars 9 forks source link

Support for CSS template literals #15

Open RageCage64 opened 4 years ago

RageCage64 commented 4 years ago

Hi there! Thanks for this awesome plugin, it's been invaluable at my job.

I've just started using LitElement, and the standard (at least at our company) for that is to return the styles separate from the render function. There would be a method like this:

static get styles() {
        return css`
            :host {
                display: inline-block;
            }
            :host([hidden]) {
                display: none;
            }
        `;
    }

Is it possible and/or not too difficult to be able to have CSS syntax highlighting in there?

jonsmithers commented 4 years ago

That's great to hear...I appreciate the words!

The syntax highlighting isn't hard. Auto-indent is what's difficult.

I haven't been using lit-html at my day job, so I might need some enlightenment: are css literals a common use case? It doesn't seem like css is exported by lit-html. Does it belong in this plugin if there's no official definition for it?

That said, I got syntax highlighting working with a little bit of copy-paste. Adding this in your vimrc should do it:

augroup vimrc_css_literals
  au!
  autocmd FileType javascript,javascript.jsx call s:css_literals({'typescript': 0})
  autocmd FileType typescript                call s:css_literals({'typescript': 1})
augroup END
function! s:css_literals(options)
  if exists('b:current_syntax')
    let s:current_syntax=b:current_syntax
    unlet b:current_syntax
  endif
  syn include @CSSSyntax syntax/css.vim
  if exists('s:current_syntax')
    let b:current_syntax=s:current_syntax
  endif

  exec 'syntax region cssLiteral 
        \ contains=@CSSSyntax,' . (a:options.typescript ? 'typescriptInterpolation' : 'jsTemplateExpression') . '
        \ start=+css`+
        \ skip=+\\`+
        \ end=+`+
        \ extend
        \ keepend
        \ '

  if (a:options.typescript)
    syn cluster typescriptExpression add=cssLiteral
  else
    syn cluster jsExpression         add=cssLiteral
  endif

  " allow js interpolation (${...}) inside css attributes
  if (a:options.typescript)
    syntax region cssTemplateExpressionWrapper contained start=+${+ end=+}+ contains=typescriptInterpolation keepend containedin=cssAttrRegion
  else
    syntax region cssTemplateExpressionWrapper contained start=+${+ end=+}+ contains=jsTemplateExpression    keepend containedin=cssAttrRegion
  endif
endfunction
lkraav commented 4 years ago

css lives in LitElement

https://lit-element.polymer-project.org/guide/styles

jonsmithers commented 4 years ago

Wow. I'm pretty sure that did not exist when I was working with lit-html. I feel out of the loop.

I'll add this capability to the plugin.

RageCage64 commented 4 years ago

That's awesome thank you! I tried adding the code you suggested to my vimrc but I wasn't able to get it to work. The code does look right to me though in comparison to what is done in the plugin code, so I'm fine to chock it up to some issue with being on WSL1 or some kind of error on my part. I'm happy to wait for this work to be done on the plugin! Thank you!

AugustNagro commented 4 years ago

@jonsmithers just wanted to add that this plugin is great! I'm not even using LitElement, just plain templates and web-components, so I forked and replaced all instances of html<backtick> with just <backtick>

jonsmithers commented 4 years ago

I pushed some work to the dev branch to support syntax highlighting for css-tagged templates (enabled with let g:htl_css_templates = 1 in vimrc) . Implementing auto-indent behavior is going to take a while longer.

Plug 'jonsmithers/vim-html-template-literals', { 'branch': 'dev' }

@AugustNagro thanks! That's definitely one way to do it, haha. It's interesting to see a variety of ways that this plugin gets used. There is a flag hidden away (g:htl_all_templates) which enables html syntax highlighting on all template literals. It forces html syntax unconditionally into ALL template literals, which seems less than ideal. It might be worth a mention in the readme.

AugustNagro commented 4 years ago

Oh very nice, yes that is better 😂

dzintars commented 4 years ago

Thank you for your job! Works like a charm from the first sight! :) One more happy LitElement'r. :1st_place_medal:

dman777 commented 4 years ago

Hi, is it possible to get auto indent to work also?

Matsuuu commented 4 years ago

Hi there,

First, thanks for the great plugin! Really nicely functioning.

But one thing I've noticed is that (at least I think it's because of it) the css template highlighting breaks at points, causing the colors of the whole file to mess up.

image

The highlighting is fixed as I scroll upwards so that vim sees the `css`` tag, but it's frustrating to get the whole file messed up by this :(

jonsmithers commented 4 years ago

@Matsuuu Hmm. I just noticed that vim's syntax/css.vim overrides the syn-sync setting set by syntax/javascript.vim or syntax/typescript.vim. I think I can push a fix for that.

@dman777 sorry for the delay on css indentation. There's a very buggy start on the indent-css branch. This should be doable, it's just going to take some time.

Matsuuu commented 4 years ago

Hey @jonsmithers . Tried out the latest update, and it seems like it fixed the problem. Thank you so much ! <3

RageCage64 commented 4 years ago

Awesome! I've been dealing with that highlighting bug intermittently, happy to see it fixed!

tamis-laan commented 3 years ago

Not working for me:

call plug#begin('~/.vim/plugged')
    Plug 'jonsmithers/vim-html-template-literals', {'for':'js'}
call plug#end()

let g:htl_css_templates = 1

Something I'm missing? I also tried: Plug 'jonsmithers/vim-html-template-literals', {'for':'js','branch':'dev'}

jonsmithers commented 3 years ago

@tamis-laan I think 'js' is the wrong filetype. To use with vim-plug's on-demand loading, it should be something like Plug 'jonsmithers/vim-html-template-literals', {'for':['javascript','typescript']}.

tamis-laan commented 3 years ago

@tamis-laan I think 'js' is the wrong filetype. To use with vim-plug's on-demand loading, it should be something like Plug 'jonsmithers/vim-html-template-literals', {'for':['javascript','typescript']}.

That worked! Although strange the plugin did work for html not for css with 'for':'js'. Thanks!