Thanks to Microsoft and the standardization of the Language Server Protocol (often abbreviated as LSP) we can nowadays easily get access to features like:
- code completion
- go to implementation
- diagnostics (warnings, errors,...)
- display reference on hover
- formatting
- and many more...
The LSP works as a client-server protocol. This allows us to code one implementation for a given language and then use it for multiple clients. The clients here being our different editors. To mention some examples, we can use lsp implementations in:
- vim
- vscode
- emacs
- sublime
- atom
- etc...
We can easily have multiple language servers for different languages running at the same time
Breaking it down, all we have to do is:
- install the binary (server) implementing the lsp
- let our editor (the client) know where to find the binary
- perhaps configure our client to disable specific features we don't want
CoC - handling language servers in vim
A somewhat famous tool for handling language servers in vim is Coc (Conquerer of Completion). It allows us to install language servers for many languages by just issuing a single command.
- Typescript?
CocInstall coc-tsserver
- Json?
CocInstall coc-json
- Vue with Typescript?
CocInstall coc-volar
- etc...
There are situations where no coc plugin does exist yet. Or old ones not working accordingly or at all because they are unmaintained and breaking changes happened.
Therefore I will provide you a quick hands on guide for integrating a lsp binary into an editor. Since I am using vim, the example will cover vim.
Hands on scenario - tailwindcss vim lsp
Since I am using tailwindcss as my go to tool for styling anything nowadays, I wanted to get these features for the tailwindcss syntax.
The problem
At the time of writing this post, I have found (and tried) two tailwindcss repos which claim to install tailwindcss for coc. Each having above 100 stars.
However (having tried both of them) they did either not work at all or did only partially work. (E.g. throwing weird errors, only supporting old directives, etc..) After looking around in the issues, I noticed people having similar experiences.
The Solution
Whenever there is no handy CocInstall lspNameHere
command existing or working,
we can just grab the implementation of the lsp. The implementation is most of
the time freely available. Partly since this is what is often being used for
extensions in the currently really famous (120k github stars) open source editor
vscode.
The official lsp for tailwindcss can be found here.
All we have to do is make the specific lsp binary available to Coc and configure Coc to use it.
- Make it available by installing the binary globally.
npm install -g @tailwindcss/language-server
NOTE: This step will vary depending on the language the server was written in.
- Configure Coc to use the language server
vim ~/.vim/coc-settings.json
The base of this config is from [here](https://github.com/rodrigore/coc-tailwind-intellisense/issues/29).
"languageserver": {
"tailwind-lsp": {
"command": "tailwindcss-language-server",
"args": [
"--stdio"
],
"filetypes": [
"vue",
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
"rootPatterns": [
"tailwind.config.js",
"tailwind.config.ts",
"postcss.config.js",
"postcss.config.ts",
"package.json",
"node_modules",
".git"
],
"settings": {
"tailwindCSS": {
"validate": true,
"lint": {
"cssConflict": "warning",
"invalidApply": "error",
"invalidScreen": "error",
"invalidVariant": "error",
"invalidConfigPath": "error",
"invalidTailwindDirective": "error",
"recommendedVariantOrder": "warning"
},
"classAttributes": [
"class",
"className",
"classList",
"ngClass"
],
"experimental": {}
}
}
}
}
Start hacking away with your lsp installed :]
