Dalius's blog

Tuesday, July 30, 2019

Vim and Svelte

UPDATE 2019-12-30: documented more Vim and Svelte things.

While looking how to configure Vim for Svelte development I have found an article by Sophia Brandt (here: https://www.rockyourcode.com/vim-and-svelte-js/). While it is good I found it not enough in my situation.

I am using Vim with Ale and Deoplete. You can find my full .vimrc here: https://github.com/daliusd/cfg/blob/master/.vimrc

For proper syntax highlighting I have used evanleck plugin:

Plug 'evanleck/vim-svelte'

In order to have proper Ale configuration I have added following:

let g:ale_linter_aliases = {'svelte': ['css', 'javascript']}
let g:ale_linters = {'svelte': ['stylelint', 'eslint']}
let g:ale_fixers = {
...
\   'svelte': ['prettier', 'eslint'],
\}

This not only lints my code but automatically formats and fixes it.

The last part was to configure Deoplete (so I could have proper autocomplete).

For this I have to add context_filetype.vim plugin:

Plug 'Shougo/context_filetype.vim'

… and configure it …

if !exists('g:context_filetype#same_filetypes')
    let g:context_filetype#filetypes = {}
endif
let g:context_filetype#filetypes.svelte =
            \ [
            \    {'filetype' : 'javascript', 'start' : '<script>', 'end' : '</script>'},
            \    {'filetype' : 'css', 'start' : '<style>', 'end' : '</style>'},
            \ ]

For CSS auto-completion to work you need to add this:

call deoplete#custom#var('omni', 'functions', {
\ 'css': ['csscomplete#CompleteCSS']
\})

Read more about this in context_types issue 39. Now I have full development environment for Svelte :relaxed:

Typescript

I have not followed what’s current Typescript state in Svelte but there is one good reason to use Typescript tools even if we don’t use Typescript in Svelte: Typescript understands Javascript files. As well Svelte itself is written in Typescript and sometimes you will get more autocompletion information. We need to do following.

Install typescript globally if you have not done that yet:

npm install -g typescript

Install svelte-ts-plugin globally:

npm install -g svelte-ts-plugin

Create jsconfig.json in your project folder so Typescript would understand js and svelte files. Add svelte-ts-plugin into it:

{
  "compilerOptions": {
    "plugins": [{ "name": "svelte-ts-plugin" }]
  }
}

Enable tsserver in ALE linters for svelte:

let g:ale_linters = {'svelte': ['stylelint', 'eslint', 'tsserver']}

You will get better autocomplete at least. As well you can use JSDoc in js files. Unfortunately JSDoc seems to be not working in .svelte files. I assume this might be fixed in svelte-ts-plugin (written by me) but I don’t know yet how to do that.

Universal Ctags

If you are using Universtal Ctags with vim-gutentags plugin then you might want to use custom rules for Svelte files. I have added following line to my .ctags.d/svelte.ctags:

--extras=+g
--langdef=csssimple
--regex-csssimple=/^[ \t]*([A-Za-z]*)\.([A-Za-z0-9_]+[A-Za-z0-9_-]+)/\2/c,class,classes/
--langdef=svelte
--map-svelte=.svelte
--_tabledef-svelte=svelte
--_mtable-regex-svelte=svelte/(^<script>).*(^<\/script>)//{_guest=JavaScript,1end,2start}
--_mtable-regex-svelte=svelte/.*(^<style>).*(^<\/style>)//{_guest=csssimple,1end,2start}

Note: this requires newest Ctags version so you might need to build it from source.

Tern

If you are using deoplete-ternjs plugin you might want to create .tern-project file with following content to improve completions returned by Tern:

{
  "libs": [
    "browser"
  ],
  "plugins": {
    "es_modules": {}
  }
}