lsp_signature.nvim: signature help for Neovim completion plugins that skip it
LSP signature hint as you type
At a glance
- What is it?
- A Lua plugin that shows the function signature while you type, for the many completion engines that do not implement signature help themselves.
- Who is it for?
- The gap this plugin fills is narrow and real: several popular Neovim completion engines never implemented signature help, so there was no way to see the parameters of a function you were in the middle of calling. lsp_signature.nvim answers that with an asynchronous buffer request, a floating window, and an optional virtual text hint naming the parameter you are currently on.
- Can I use it commercially?
- Yes. Apache-2.0 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 31 days ago.
- What is it written in?
- Mainly Lua, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 7, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The plugin exists because the completion engine said no
Most Neovim users assemble their editor from a completion engine and an LSP client, and those two are independent. Some engines implement signature help and some do not, which leaves a hole: you can see the completion list but not the parameter list of the function you have just inserted a call to. This plugin is described in one line as being made for completion plugins that do not support signature help, and it fills that hole by making the request itself.
The request is fully asynchronous and scoped to the buffer, so it does not block the editor while it waits on the language server. The plugin also rewrites the built in signature help in Neovim in order to allow the parameter you are on to be highlighted, which is the detail that makes the hint readable rather than just present.
Version requirements are stated plainly: Neovim 0.10 or newer, with separate branches named neovim-0.5, neovim-0.6 and neovim-0.9 for older versions. The plugin is written in Lua and Apache 2.0 licensed, has 2,365 stars and 83 forks, and was last pushed on 2026-09-07, so it sits well inside an active maintenance window from October 2026.
Installing with any of four plugin managers
The install section lists all four common managers, which is the usual sign of a plugin that expects a wide audience rather than a specific configuration. The Lazy.nvim form is the one most users end up with:
" Lazy
{
"ray-x/lsp_signature.nvim",
event = "InsertEnter",
opts = {
-- cfg options
},
}The `event = "InsertEnter"` trigger means the plugin loads when you enter insert mode rather than at startup, which keeps it out of your startup cost entirely. Passing configuration through `opts` means `setup()` is called for you. The other three managers take a bare repository name with no event or options, so on those you call `setup()` yourself.
There is a second way to attach, and it matters for people with several language servers. Instead of calling `setup()` in `init.lua`, you can call `on_attach(cfg, bufnr)` from inside the LSP client's own `on_attach` callback, which ties the plugin's lifetime to the language server attaching to a buffer:
local golang_setup = {
on_attach = function(client, bufnr)
require "lsp_signature".on_attach(signature_setup, bufnr) -- Note: add in lsp client on-attach
end,
}
require'lspconfig'.gopls.setup(golang_setup)The README shows both approaches because they solve slightly different problems. `setup()` is simpler, and `on_attach` gives you per language configuration, which is how you would give Go a different `max_width` from Rust.
Floating window versus virtual text, and how they combine
There are two display modes and they can be mixed. The floating window is the full signature with its documentation, and the documentation is capped: `doc_lines` defaults to 10 and shows two lines of doc if more are available, with the text truncated. Setting `doc_lines` to `0` disables API comments entirely. The README is careful to note that this affects insert mode only and not signature help in normal mode.
Virtual text is the lighter alternative, an inline hint after the cursor telling you which parameter you are currently on. The screenshots show a few variants, including a virtual text only mode contributed by someone else, and a mode where the plugin uses virtual text for the next parameter while keeping the floating window for the rest. The default `hint_prefix` is a panda emoji, with a note that terminals which cannot render emoji may crash, and the config accepts a table of three icons instead if you want something safer.
`floating_window` is the switch between the two: set it to `false` and you get virtual text only. The window geometry is configurable too, with `max_height` defaulting to 12 including borders, and a `max_width` that is a function of the current window width times 0.8, with a floor of 40 columns and text wrapping when it overflows. Position offsets can be numbers or functions, and `floating_window_above_cur_line` tries to place the window above the cursor to avoid overlapping the popup menu.
Keymaps and the bind setting that controls them
No default keymaps are provided, and the reason is the `bind` option rather than an omission. `bind` defaults to `true` and the README calls it mandatory, because when it is true the plugin registers its own handlers so that the border configuration applies. Setting it to `false` is the escape hatch for people who want to hook lspsaga or another signature handler instead.
Three keymap options exist in the config. `toggle_key` toggles the signature help window, which is described as manually toggling the floating window on and off. `select_signature_key` switches between signatures when the language allows overloads, which is the case the multiple signature screenshots cover. `move_cursor_key` is an array of two keymaps that move the floating window up and down, and it is `nil` by default rather than set to a default binding.
To get a toggle in normal mode you either define a keymap to `vim.lsp.buf.signature_help()` or call `toggle_float_win()`:
vim.keymap.set({ 'n' }, '<C-k>', function() require('lsp_signature').toggle_float_win()
end, { silent = true, noremap = true, desc = 'toggle signature' })
vim.keymap.set({ 'n' }, '<Leader>k', function()
vim.lsp.buf.signature_help()
end, { silent = true, noremap = true, desc = 'toggle signature' })That choice is the practical difference between driving the plugin's window and driving the native one in Neovim.
Auto close timing is the setting you will actually tune
Two options decide whether the window feels steady or distracting. `close_timeout` defaults to 4000, a count in milliseconds, and closes the floating window that long after the last parameter is entered. `fix_pos` defaults to `false`; setting it to `true` keeps the window open until all parameters have been filled in. If you find yourself typing a call with many arguments and losing the signature halfway through, `fix_pos = true` is the fix.
Error handling is configurable too. `ignore_error` takes a function called with the error and context, which the README describes as a way to silence errors, with details in `init.lua`. There are also two debugging switches: `debug` writes a log, and `log_path` says where, defaulting to a file under the Neovim log directory, while `verbose` shows debug line numbers.
The repository carries the tooling for all of this. The `Makefile` has a `lint` target that runs `luacheck` over `lua/lsp_signature`, and a `test` target that runs the test directory headlessly:
test:
nvim --headless --noplugin -u tests/minimal.vim -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/minimal.vim'}"
lint:
luacheck lua/lsp_signatureThere is a `tests/` directory and a `doc/` directory in the tree, plus `stylua.toml` and `selene.toml` for formatting and linting configuration, so the project is set up for contributors rather than only for users.
Active commits, but the last tagged release is from 2024
Here is the gap in the project's own record. The most recent tagged release is v0.3.1 from 2024-03-04, and its change list is a single fix: use `get_active_clients` when running on Neovim older than 0.10. The previous release, v0.3.0, landed the same day, thirteen hours earlier, so that pair was one focused piece of compatibility work.
GitHub reports the last push on 2026-09-07, more than two years after that release. Both facts are accurate at once, and what they mean for you is specific. The source tree contains changes that are in no tagged release, so if you install from a plugin manager you are probably running an untagged commit. If you pin a version deliberately, the last one available is v0.3.1 and it predates the current Neovim compatibility work.
There is a second number worth reading carefully: 87 open issues against 2,365 stars, which is a higher open issue count than a plugin of this size usually carries. Much of that is probably compatibility reports, since the plugin touches the LSP buffer request path and every language server behaves slightly differently, but it does mean the issue tracker is where you find out which servers people actually use it with. The version naming is also worth internalizing, because v0.3.x is pre 1.0 and options can change between now and a stable release.
Editorial conclusion
The gap this plugin fills is narrow and real: several popular Neovim completion engines never implemented signature help, so there was no way to see the parameters of a function you were in the middle of calling. lsp_signature.nvim answers that with an asynchronous buffer request, a floating window, and an optional virtual text hint naming the parameter you are currently on. Install it with a Lazy.nvim spec on the InsertEnter event, leave bind at its default unless you want to drive lspsaga's handler, and read the section on close_timeout and fix_pos, since those two settings decide whether the window feels helpful or flickery.
Frequently asked questions
What does lsp_signature.nvim do?
It shows the function signature while you type, for completion plugins that do not implement signature help themselves. It makes an asynchronous LSP buffer request and renders the result in a floating window, with an optional virtual text hint marking the parameter you are on.
How do I install lsp_signature.nvim in Neovim?
The README lists dein, vim-plug, Packer and Lazy.nvim. The common Lazy.nvim form sets event to InsertEnter so the plugin loads on insert mode, and passes options through the opts table so setup is called for you.
What is the bind option for in lsp_signature.nvim?
It defaults to true and is described as mandatory, because the plugin registers its own signature handlers when it is true so the border configuration takes effect. Set bind to false if you want to drive the signature display through lspsaga or another handler instead.
Which Neovim versions does lsp_signature.nvim support?
The current plugin requires Neovim 0.10 or newer. For older versions there are separate branches named neovim-0.5, neovim-0.6 and neovim-0.9, and the v0.3.1 release specifically fixed client detection for versions below 0.10.
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/ray-x-lsp-signature-nvim)