vim-lsp: Async Language Server Protocol Plugin for Vim 8 and Neovim
async language server protocol plugin for vim and neovim
At a glance
- What is it?
- vim-lsp brings LSP-driven code intelligence to Vim 8 and Neovim through an asynchronous Vim Script layer that requires manual server registration but ships with over thirty ready-to-use commands. It is the only LSP client that covers both Vim 8 and Neovim under a single plugin.
- Who is it for?
- vim-lsp is the right choice for Vim 8 users and for teams that mix Vim 8 and Neovim. Developers on Neovim only who prefer Lua configuration will find nvim-lspconfig more concise, since it ships pre-written server definitions and does not require a lsp#register_server block per language.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 29 days ago.
- What is it written in?
- Mainly Vim Script, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
LSP Features for Vim 8 and Neovim Without the Built-In Client
The Language Server Protocol defines a standard wire format for editors to query language tooling: go-to-definition, symbol search, inline diagnostics, rename, hover documentation, and more. Vim 8 gained async job control in 2016 but never shipped a native LSP client. Neovim added one in version 0.5.0, but it covers only Neovim and requires Lua-based configuration. vim-lsp fills the gap for Vim 8 users and provides a Vim Script alternative for Neovim users who prefer not to write Lua.
The plugin targets engineers who already have a Vim Script-based configuration and want code intelligence without switching to a different editor or learning a new configuration language. It registers as an autocmd-based system: servers attach per-buffer when the filetype matches, and keybindings are set inside the lsp_buffer_enabled event.
The Async Architecture and the Lua Performance Path
vim-lsp submits language server requests through Vim's asynchronous job mechanism, so the editor does not block while the server processes large codebases. JSON-RPC messages travel over stdin/stdout to the language server process. Responses arrive as callbacks that update the buffer, the quickfix list, or the sign column.
Certain bottlenecks in the Vim Script layer have been reimplemented in Lua. The README states that to take advantage of these gains, you need Vim compiled with Lua support or Neovim v0.4.0 or later. Without Lua, vim-lsp falls back to the pure Vim Script path, which is functional but slower on files with dense completions or large diagnostic payloads.
Server registration uses a callable definition. The cmd key takes a funcref that receives a server_info dictionary and returns a list of command-line arguments, giving you full control over how the process launches and what flags it receives.
Installing vim-lsp and Connecting a Language Server
Add vim-lsp using vim-plug:
Plug 'prabirshrestha/vim-lsp'For automatic server installation and configuration, the README recommends adding vim-lsp-settings alongside it:
Plug 'prabirshrestha/vim-lsp'
Plug 'mattn/vim-lsp-settings'Without vim-lsp-settings, each server requires a manual registration block. The README shows a Python example using pylsp:
if executable('pylsp')
" pip install python-lsp-server
au User lsp_setup call lsp#register_server({
\ 'name': 'pylsp',
\ 'cmd': {server_info->['pylsp']},
\ 'allowlist': ['python'],
\ })
endifThe executable() guard means the server only activates when the binary is present on PATH. The allowlist restricts the server to matching filetypes. Buffer-level setup (omnifunc, keymaps, tagfunc) is typically placed in a function triggered by the lsp_buffer_enabled autocmd event.
After setup, run :LspStatus to confirm the server attached to the current buffer. A server that fails the executable() check is silently skipped.
Thirty-Plus Commands from Jump-to-Definition to Call Hierarchy
vim-lsp maps LSP capabilities to named commands. Navigation includes :LspDefinition, :LspDeclaration, and :LspTypeDefinition. Each has a Peek variant (for example :LspPeekDefinition) that opens the result in a preview window rather than the current window. :LspReferences finds all usages of the symbol under the cursor. :LspRename performs a workspace-wide rename.
Diagnostic commands let you step through problems without leaving the keyboard: :LspNextError, :LspPreviousError, :LspNextWarning, and :LspNextDiagnostic, which covers all severity levels. :LspDocumentDiagnostics dumps diagnostics for the current file.
Call hierarchy is available through :LspCallHierarchyIncoming and :LspCallHierarchyOutgoing. :LspTypeHierarchy shows type relationships. :LspCodeAction presents a list of quick fixes the server can apply. :LspCodeLens lists executable commands on the current document.
One important constraint documented in the README: when multiple servers are registered for the same filetype, commands like :LspRename and :LspDocumentFormat use only the first server that reports support for that capability. There is no mechanism to pick a different server for a specific operation.
Features That Require Companion Plugins
Snippet expansion is not built into vim-lsp. Three integration paths exist, each requiring two plugins. The README lists them: vim-vsnip paired with vim-vsnip-integ, UltiSnips paired with vim-lsp-ultisnips, or neosnippet paired with vim-lsp-neosnippet.
Completion comes from setting omnifunc=lsp#complete in a buffer setup function, which routes LSP completions through Vim's native omnicompletion trigger. For automatic popup completion, asyncomplete.vim is the documented companion.
Diagnostics are enabled by default and appear in the sign column. Teams that already use ALE or Neomake for diagnostics can disable vim-lsp's output to avoid duplicate signs:
let g:lsp_diagnostics_enabled = 0 " disable diagnostics supportReference highlighting (marking all occurrences of the symbol under the cursor) is also on by default. The highlight group that controls its appearance is lspReference.
Folding, Semantic Highlighting, and Debugging Configuration
LSP-driven folding uses Vim's fold expression system. The README gives the configuration:
set foldmethod=expr
\ foldexpr=lsp#ui#vim#folding#foldexpr()
\ foldtext=lsp#ui#vim#folding#foldtext()To disable it globally: `let g:lsp_fold_enabled = 0`.
Semantic highlighting is supported through an unofficial protocol extension. The README notes explicitly that this feature is based on a draft extension in the vscode-languageserver-node repository. It requires Neovim highlights or Vim compiled with the textprop feature. Support varies by language server and could break as the draft evolves.
When a server misbehaves, verbose logging is available:
let g:lsp_log_verbose = 1
let g:lsp_log_file = expand('~/vim-lsp.log')The `:CheckHealth` command can report server status when a compatible health-check plugin is present.
Where vim-lsp Falls Short and When to Use nvim-lspconfig Instead
Snippets and popup completion both require additional plugins, while Neovim's native client handles both through nvim-lspconfig and a companion completion plugin. The manual lsp#register_server approach is also more verbose than nvim-lspconfig, which ships pre-written server configurations for dozens of language servers and requires only a single function call per server.
nvim-lspconfig is Neovim-only and written in Lua. It is the more ergonomic choice for developers who use only Neovim. vim-lsp remains the only option for Vim 8 users and remains a valid choice for Neovim users who prefer to configure everything in Vim Script.
The semantic highlighting feature depends on a draft protocol extension, which is a concrete risk for projects that need predictable highlighting behavior across server updates. The multi-server-per-filetype limitation (only the first capable server handles rename and format) is also a constraint for mixed-language or polyglot projects.
Maintenance Status and License
The last push to the repository was on 2026-09-02. The repository is not archived. Dependency updates are managed through Renovate, whose configuration lives at the repository root. The codebase includes a test/ directory and a .vintrc.yaml file for Vim Script linting.
The project is released under the MIT license. A separate LICENSE-THIRD-PARTY file covers other code included in the repository. There are no GitHub releases; the plugin is installed directly from the master branch via a plugin manager.
Editorial conclusion
vim-lsp is the right choice for Vim 8 users and for teams that mix Vim 8 and Neovim. Developers on Neovim only who prefer Lua configuration will find nvim-lspconfig more concise, since it ships pre-written server definitions and does not require a lsp#register_server block per language. Before relying on :LspDefinition or :LspRename in a project, confirm the language server is attached by running :LspStatus and verify that the allowlist entry matches the filetype Vim assigns to your files.
Frequently asked questions
What is vim-lsp?
vim-lsp is an asynchronous Language Server Protocol plugin for Vim 8 and Neovim, written in Vim Script. It connects editors to language servers over JSON-RPC and exposes capabilities like go-to-definition, rename, hover, and diagnostics through a set of :Lsp* commands.
How do I install vim-lsp?
Add `Plug 'prabirshrestha/vim-lsp'` to your vim-plug configuration and run :PlugInstall. For automatic server setup, also add `Plug 'mattn/vim-lsp-settings'`. Without vim-lsp-settings, each language server must be registered manually with lsp#register_server.
Can I use a Python language server with vim-lsp?
Yes. The README shows registering pylsp (python-lsp-server) using an executable() guard and an lsp#register_server call with 'allowlist': ['python']. The server only activates for Python filetypes when pylsp is on PATH.
How does vim-lsp compare to coc.nvim?
vim-lsp is a lighter plugin that delegates completion and snippets to separate plugins, while coc.nvim is a full IDE-like framework with built-in completion, snippet, and extension support. vim-lsp works on Vim 8 and Neovim; coc.nvim targets both but requires Node.js.
What is the difference between vim-lsp and nvim-lspconfig?
vim-lsp is a Vim Script plugin that supports Vim 8 and Neovim, requiring you to write lsp#register_server blocks for each server. nvim-lspconfig is Lua-based, works only in Neovim, and ships pre-written per-server configurations that reduce setup to a single function call.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/prabirshrestha-vim-lsp)