How to setup Vim for Svelte development

Learn how to configure Vim as the ultimate IDE for Svelte and TypeScript development

· 6 min

I like Vim. I like its simplicity, its ugliness. There is something appealing about its GUI constraints too.

Let's be honest. Trend sensitivity in tech is a big problem. Developers are jumping from editor to editor whenever something new, hot and trendy comes out. Always searching for the Holy Grail. Sublime, Atom, VSCode. What comes next?

Vim is a very old editor. It's 25 years old. That's ancient in the tech world. What can possibly justify this piece of software's existence? Something must be good if it still lives, right? What are the benefits?

One of Vim's powers is its simplicity and extensibility. It's a very extensible editor. It's also scriptable. It has macros and tons of other useful features. It's small, doesn't hog your CPU and make your computer fans go crazy. It often comes prepackaged with almost every Unix-like operating system.

It's also a powerful editor for Javascript, TypesScript and Svelte development.

Vim with Svelte and TypeScript

Neovimpermalink

Neovim is the modern fork of Vim. Its goal is to clean and extend Vim with modern features. Personally, I don't use Neovim. I tried it, but I can't honestly tell what makes it better than the original Vim. The gains are not obvious to me. I am sticking to original Vim for now, currently version 8.2.

Ever Heard of Emacs?permalink

You might say "But what about Emacs?" I tried Emacs too for a while after getting inspired from watching Emacs Rocks videos. Tried only to realize that I was spending most of my working time configuring Emacs instead of doing the actual work. Also, I already have an operating system, thank you.

Oh, and you know, all those people who just have to crack a joke about exiting Vim, why don't you ask them to try and exit Emacs next time? Look who is laughing now!

Side note: Vim + Tmux = Powerpermalink

I always use Tmux and Vim together. What it Tmux? I would describe it as a tiling window manager for the terminal. You have to tweak it a bit to you liking, but once you master it, windows will start flying.

This is out of scope for the article. I just wanted to mention it.

Svelte Syntax Highlightingpermalink

First things first, we have to configure Vim syntax highlighting for Svelte, Javascript and TypeScript.

For Svelte, vim-svelte is the plugin to use. It provides indentation and syntax highlighting for Svelte components. There is also vim-svelte-plugin that does the same thing.

For Javascript language highlighting, you have a few different options. The most popular seem to be vim-javascript and this is what I use.

There is also vim-js and jats. If you are feeling adventurous check out vim-polyglot, a plugin with more language syntax hightlights that you probably will ever need.

When it comes to TypeScript, I settled on yats.vim. I find it the best, but typescript-vim is another good option.

I am using vim-plug as my Vim plugin manager and if you do too, this is how to add them to Vim config file.

Plug 'evanleck/vim-svelte'
Plug 'pangloss/vim-javascript'
Plug 'HerringtonDarkholme/yats.vim'

Syntax highlighting is a nice to have, but autocomplete is essential for a good coding session. Let's tackle that next.

Svelte Autocomplete with Coc.nvim - Conquer of Completionpermalink

Honestly, how did I write code in Vim before this extension existed? Apparently I did, but I bet it was painful.

Coc.nvim is a must-have if you are a Vim user. It's an "Intellisense engine for Vim8 & Neovim, full language server protocol support as VSCode" according to their website.

What does it mean? It means it supports the same language protocol standard as VScode, which in turn means you can easily implement an autocompletion for a language if that language has a language server. Crystal clear, right?

Here is Svelte's language server for example.

Installing Coc.nvim is straight forward. Add the line below to your .vimrc in the right place and run :PlugInstall.

Plug 'neoclide/coc.nvim', {'branch': 'release'}

Coc.nvim has many extensions and we will install one for Svelte next, along with a few others we will need too.

coc-sveltepermalink

If you are coding Svelte in Vim coc-svelte is a must. Unfortunately, the original extension's Svelte dependencies are lagging behind, so I keep my own fork of it where I try to keep upstream dependencies in sync.

Add it to your .vimrc with the line below.

Plug 'codechips/coc-svelte', {'do': 'npm install'}

Beside Svelte extension we also need to install TypeScript Coc extension. It will help us with autocompletion for TypeScript and JavaScript. Install it in Vim by running :CocInstall coc⁠-⁠tsserver command.

Coc.nvim autoupdates dependencies in the background, but you can always update them manually by running :CocUpdate command.

Setting up svelte.config.jspermalink

If you are using TypeScript, SASS or PostCSS in your Svelte components you have to create a svelte.config.js file in the root of your project. That file is needed by coc.nvim in order to interpret those parts of the Svelte files correctly. Read my TypeScript and Svelte article on how to do that - How to use Typescript with Svelte.

Formatting Files with Prettierpermalink

We also want our files to look nice and therefore we need to format them. There is a coc-prettier extension that does that, but for some reason it breaks Svelte files for me instead. Sometimes it doubles the lines at the end of the file. For that reason I decided to go with vim-prettier extension instead.

For Prettier extension to work properly it needs to find a prettier CLI and Prettier configuration. There are multiple ways of configuring and setting it up, but I always do it locally for every of my projects. It's the easiest.

$ npm add -D prettier prettier-plugin-svelte

You also need to add Prettier vim plugin to your Vim config and tweak some of its settings.

Plug 'prettier/vim-prettier', { 'do': 'npm install' }

" Prettier Settings
let g:prettier#quickfix_enabled = 0
let g:prettier#autoformat_require_pragma = 0
au BufWritePre *.css,*.svelte,*.pcss,*.html,*.ts,*.js,*.json PrettierAsync

One drawback of Prettier is that you have to install Prettier and prettier Svelte plugin in every Svelte project. It might be possible to use a global Prettier config, because it will search for Prettier configs up the tree.

However, I strongly advice against doing it, because you might want to share same config with your team.

My prettier config usually looks something like this.

module.exports = {
arrowParens: 'avoid',
printWidth: 90,
singleQuote: true,
svelteBracketNewLine: true,
svelteStrictMode: false,
trailingComma: 'none',
plugins: ['prettier-plugin-svelte'],
};

Prettier uses cosmiconfig. That means you can use any name and format it supports.

Configuring Coc.nvimpermalink

If you need to configure Coc.nvim and its extensions you can open the config file directly in Vim by running :CocConfig command. You can also edit the coc⁠-⁠settings.json file directly. You will find it in your ~/.vim folder or ~/.config/nvim if you are using Neovim.

Here is what mine looks like.

{
"diagnostic.messageTarget": "echo",
"signature.target": "echo",
"coc.preferences.hoverTarget": "echo",
"javascript.suggestionActions.enabled": true,
"typescript.suggestionActions.enabled": true,
"prettier.printWidth": 120,
"prettier.singleQuote": true
}

All those "echo" values force Coc to display diagnostic messages in Vim's command line instead of a popup. I don't like distracting popups.

These are Coc.nvim settings in my .vimrc.

" COC
let g:coc_node_path = '$HOME/.nvm/versions/node/v12.16.3/bin/node'

nmap ff (coc-format-selected)
nmap rn (coc-rename)
nmap gd (coc-definition)
nmap gy (coc-type-definition)
nmap gi (coc-implementation)
nmap gr (coc-references)

set updatetime=300
set shortmess+=c " don't give |ins-completion-menu| messages.

" Use K to show documentation in preview window
nnoremap K :call show_documentation()

function! s:show_documentation()
if (index(['vim','help'], &filetype) >= 0)
execute 'h '.expand('')
else
call CocAction('doHover')
endif
endfunction

Maybe you can get some inspiration from reading them.

A Few More Tipspermalink

It's not sure that Vim will recognize that your Svelte file consists of different sections and languages (JavaScript, CSS) and might comment them out using HTML comments when you try to comment them out.

It happened to me, and if it happens to you, here is how to solve it.

Install the context_filetype Vim plugin. It will help us set the filetype based on the file section.

Plug 'Shougo/context_filetype.vim'

Add the following code to your Vim config.

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': 'typescript',
\ 'start': '<script\%( [^>]*\)\? \%(ts\|lang="\%(ts\|typescript\)"\)\%( [^>]*\)\?>',
\ 'end': '',
\ },
\ {'filetype' : 'css', 'start' : '<style \?.*>', 'end' : '</style>'},
\ ]

let g:ft = ''

Now your comments should behave correctly.

I am using NERDCommenter, a Vim commenting plugin with the best punchline - "Comment functions so powerful - no comment necessary."

For it to work properly with Svelte I had to tweak its settings a bit.

" NERDCommenter settings

let g:NERDSpaceDelims = 1
let g:NERDCompactSexyComs = 1
let g:NERDCustomDelimiters = { 'html': { 'left': '' } }

" Align comment delimiters to the left instead of following code indentation
let g:NERDDefaultAlign = 'left'

fu! NERDCommenter_before()
if (&ft == 'html') || (&ft == 'svelte')
let g:ft = &ft
let cfts = context_filetype#get_filetypes()
if len(cfts) > 0
if cfts[0] == 'svelte'
let cft = 'html'
elseif cfts[0] == 'scss'
let cft = 'css'
else
let cft = cfts[0]
endif
exe 'setf ' . cft
endif
endif
endfu

fu! NERDCommenter_after()
if (g:ft == 'html') || (g:ft == 'svelte')
exec 'setf ' . g:ft
let g:ft = ''
endif
endfu

There are plenty of other useful tips and tricks, but I will stop here.

If you stuck with me this far you should have a fully functional Vim setup ready for Svelte development.

Plugins Mentionedpermalink

https://github.com/evanleck/vim-svelte
https://github.com/leafOfTree/vim-svelte-plugin
https://github.com/pangloss/vim-javascript
https://github.com/yuezk/vim-js
https://github.com/junegunn/vim-plug
https://github.com/leafgarland/typescript-vim
https://github.com/HerringtonDarkholme/yats.vim
https://github.com/sheerun/vim-polyglot
https://github.com/neoclide/coc-prettier
https://github.com/prettier/vim-prettier
https://github.com/preservim/nerdcommenter
https://github.com/Shougo/context_filetype.vim
https://github.com/davidtheclark/cosmiconfig

Final Wordspermalink

My goal has always been to shorten the time between an idea, a thought, and its final implementation on screen. I think I've come pretty close by now by using Vim as my main editor.

However, learning Vim comes with a price. I can barely write anything outside Vim now. Short texts, no problem. Longer texts, forget it. The muscle memory is strong!

One big reason I like Vim is that it's never in my way. I don't like being distracted. It's just me, a black computer screen and my thoughts.

My final advice:

  • Stop jumping around, always looking for something better, and invest your time and energy into something that has proven its value by now - Vim.
  • Very few people can master Vim fully, but many will increase their productivity from learning just a bit of Vim and by just start using it in their daily work. Try to stick to it and miracles will happen!
  • Never copy someone else's config. Start with sensible defaults and build it up as you go.

If you want to learn Vim, Vimcasts is a good starting point. Godspeed.


If you liked what you read, it would make me really happy if you could share it on Twitter.