README.md |
Article
When using OmniSharp we are absolutely able to navigate to the definition of any Method that we wrote and that resides somewhere within our dotnet solution by using vim.lsp.buf.definition()
.
The Problem
Any method definition that we want to inspect that comes from libraries that we import to our project (e.g. the System
namespace or any NuGet package) has to be decompiled.
If we use vim.lsp.buf.definition()
on those methods but don't set up OmniSharp to properly decompile, we get this:
Error executing vim.schedule lua callback: /usr/share/nvim/runtime/lua/vim/lsp/buf.lua:220: Cursor position outside buffer
stack traceback:
[C]: in function 'nvim_win_set_cursor'
/usr/share/nvim/runtime/lua/vim/lsp/buf.lua:220: in function 'on_response'
/usr/share/nvim/runtime/lua/vim/lsp/buf.lua:239: in function 'handler'
/usr/share/nvim/runtime/lua/vim/lsp/client.lua:679: in function ''
vim/_editor.lua: in function <vim/_editor.lua:0>
This has already addressed on github
[OmniSharp] The Solution
When working with foreign libraries, we have to tell OmniSharp explicitly that it has to decompile those libraries, so we can look into it. A NeoVim plugin that makes this easy for us is Hoffs/omnisharp-extended-lsp.nvim
Installing omnisharp-extended-lsp.nvim
Assuming we use the LazyVim which automaticall comes with NvChad, we can simply add the following lines to our LazVim configuration to install and activate the plugin
-- "lua/plugins/init.lua"
return
{
-- ...
{
"Hoffs/omnisharp-extended-lsp.nvim"
}
-- ...
}
Setting up the key maps
-- lua/mappings.lua
-- ...
map("n", "gr", "<cmd>lua require('omnisharp_extended').telescope_lsp_references()<CR>", opts)
map("n", "gR", "<cmd>lua require('omnisharp_extended').telescope_lsp_references()<CR>", opts)
map("n", "<F12>", "<cmd>lua require('omnisharp_extended').telescope_lsp_definition()<CR>", opts)
-- default bindings if you want to use an LSP different to omnisharp
-- map("n", "gr", "<cmd>Telescope lsp_references<CR>", opts)
-- map("n", "gR", "<cmd>Telescope lsp_references<CR>", opts)
-- map("n", "<F12>", "<Cmd>lua vim.lsp.buf.definition()<CR>", opts)
-- ...
It works
After setting up NeoVim as described above, we can now also jump to the definition of system libraries and NuGet packages that we import:
A word on C# LSPs
The Problem with OmniSharp
-
OmniSharp is easy to install, it is fast and rich in configuration but it is not the most capable LSP.
-
Anything razor based is not supported.
-
It's neovim integration is limited (as proven in this article: we have to install an extra third party plugin to enable decompilation)
-
refactoring capabilities are limited as well (e.g.
export to method
doesn't seem to be implemented in omnisharp) -
formatting doesn't work properly and requires csharpier to be installed additionally
Alternatives
TBD