Je travaille actuellement sur un projet Web où j’utilise des Web Components. C’est un excellent moyen de créer des éléments HTML personnalisés et de limiter la duplication du code. Cependant, cela signifie écrire beaucoup de code HTML dans des fichiers JavaScript classiques.

Le problème

Pour les utilisateurs de vim, cela peut être gênant car la coloration syntaxique n’est pas activée par défaut. Le code HTML est traité comme une simple string:

const template = document.createElement('template')
template.innerHTML = `
  <style>
    .my-component {
      color: red;
    }
  </style>
  <div class="my-component">
    Hello, World!
  </div>
`

class MyComponent extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({ mode: 'open' })
    this.shadowRoot.append(template.content.cloneNode(true))
  }
}

customElements.define('my-component', MyComponent)

La solution

Pour résoudre ce problème avec vim, vous pouvez simplement ajouter les lignes suivantes à votre .vimrc:

call plug#begin('~/.vim/plugged')
Plug 'inkarkat/vim-SyntaxRange'
call plug#end()

augroup SyntaxRangeHTML
  autocmd!
  autocmd BufRead,BufNewFile *.js silent! call SyntaxRange#Include('.*HTML.*`', '`', 'html')
  autocmd BufRead,BufNewFile *.js silent! call SyntaxRange#Include('<style>', '</style>', 'css')
augroup END

J’ai cherché un plugin capable de gérer directement la coloration syntaxique des composants web, mais il semble qu’il n’en existe un que pour VSCode. J’ai donc dû trouver un plugin permettant à un utilisateur de modifier partiellement la syntaxe d’un fichier.

Explication

Cette partie source le plugin vim-SyntaxRange en utilisant vim-plug. Après avoir modifié votre fichier .vimrc et l’avoir rechargé (en utilisant :source ~/.vimrc), exécutez :PlugInstall pour l’installer. Vous pouvez bien sûr utiliser un autre gestionnaire de plugins ou l’installer manuellement si vous préférez.

call plug#begin('~/.vim/plugged')
Plug 'inkarkat/vim-SyntaxRange'
call plug#end()

Cette partie de la configuration permettra la coloration syntaxique du code HTML dans les composants web:

augroup SyntaxRangeHTML
  autocmd!
  autocmd BufRead,BufNewFile *.js silent! call SyntaxRange#Include('.*HTML.*`', '`', 'html')
  autocmd BufRead,BufNewFile *.js silent! call SyntaxRange#Include('<style>', '</style>', 'css')
augroup END

L’autocmd se déclenche lors de l’ouverture d’un fichier .js et appelle la fonction SyntaxRange#Include avec les paramètres suivants:

  • .*HTML.*` et ` sont des paternes pour les délimiteurs de début et de fin du code HTML.
  • html est le groupe de syntaxe qui sera appliqué au code se trouvant entre les délimiteurs.

Ici cela fonctionne si la string HTML est trouvée avant le backtick ouvrant celle du template. Le backtick fermant est utilisé comme délimiteur de fin. Ainsi, dans l’exemple ci-dessus, la ligne template.innerHTML = ` déclenche la coloration syntaxique HTML.

Ces délimiteurs sont spécifiques à mon cas, vous devrez donc peut-être les ajuster en fonction de vos besoins. Cependant l’utilisation de la propriété innerHTML n’est pas obligatoire. Avec ce paterne là, un simple commentaire /* HTML */ ou /* html */ avant le backtick fonctionnera également.

Pendant que j’y étais, j’ai également ajouté la coloration syntaxique CSS. Ceci est simplement déclenché par la balise <style> et terminé par la balise de fermeture </style>.

Note

Le flag !silent est utilisé pour empêcher le plugin d’afficher des messages d’erreur lorsque la fonction SyntaxRange#Include est appelée. Une variable est indéfinie dans le script mais cela ne semble pas affecter les fonctionnalités du plugin.

Conclusion

Il s’agit d’une solution acceptable pour palier au problème de la coloration syntaxique HTML dans les composants web. Ce n’est pas parfait mais ça fonctionne. Bon codage !