rust-tools.nvim icon indicating copy to clipboard operation
rust-tools.nvim copied to clipboard

How to use rust-tools with mason-lspconfig?

Open Gremious opened this issue 2 years ago • 11 comments

Is there a minimal configuration example of setting up mason-lspconfig and rust-tools together anywhere? I checked both this repo and mason but I did not find it?

I just want to know the 'correct' way to setup a vim config with mason, where mason loads not exclusively just rust_analyzer, and rust_analyzer itself has a few custom settings + rust-tools. Codelldb/debugging optional but welcome, as I believe you can set it up pretty nicely?

Would love to see this actually written out somewhere, e.g. a readme or wiki.

Gremious avatar May 18 '23 16:05 Gremious

If you're fine with using nvim-lspconfig, you can refer to my setup: https://github.com/utkarshgupta137/nvim-lazy/blob/73a2a2f/lua/lvim/lsp.lua#L20 + https://github.com/utkarshgupta137/nvim-lazy/blob/73a2a2f/lua/lvim/lsp/rust-tools.lua

AFAIK, there is no benefit of setting up LSP using mason-lspconfig over nvim-lspconfig.

utkarshgupta137 avatar May 18 '23 16:05 utkarshgupta137

The trick I found was to avoid setting up anyting rust related in mason-lspconfig

            require("mason-lspconfig").setup_handlers {
                function(server_name)
                    require("lspconfig")[server_name].setup {}
                end,

                ["rust_analyzer"] = function() end
            }

I then have rust-tools setup everything using mason paths by it self

            local install_root_dir = vim.fn.stdpath "data" .. "/mason"
            local extension_path = install_root_dir .. "/packages/codelldb/extension/"
            local codelldb_path = extension_path .. "adapter/codelldb"
            local liblldb_path = extension_path .. "lldb/lib/liblldb.so"
            local rt = require("rust-tools")
            rt.setup({
                tools = {
                    hover_actions = {
                        -- whether the hover action window gets automatically focused
                        auto_focus = false,
                    },
                },
                server = {
                    on_attach = function(_, bufnr)
                        require("dap")
                        require("dapui")
                        -- Hover actions
                        vim.keymap.set("n", "K", rt.hover_actions.hover_actions, { buffer = bufnr })
                        -- Code action groups
                        -- vim.keymap.set("n", "<Space>a", rt.code_action_group.code_action_group, { buffer = bufnr })
                    end,
                    flags = {
                        debounce_text_changes = 150,
                    },
                    settings = {
                        ["rust-analyzer"] = {
                            checkOnSave = {
                                enable = true,
                                command = "clippy",
                            },
                            cargo = {
                                allFeatures = true,
                            },
                        },
                    },
                },
                dap = {
                    adapter = require("rust-tools.dap").get_codelldb_adapter(codelldb_path, liblldb_path),
                },
            })

I setup the keybindings on the LspAttach event (in the nvim-lspconifg in my lazy config), so they are common for all LSP

snaggen avatar May 22 '23 14:05 snaggen

@snaggen Thank you very much, that is nice!

After reading what that setup_handlers does in the mason lsp config docs, I noticed it actually explicitly mentions rust-tools as a handler itself: https://github.com/williamboman/mason-lspconfig.nvim/blob/main/doc/mason-lspconfig.txt#L163

So I guess that is the intended way, I will try that approach.

Would still like a mention of that at least in this repo perhaps, so I'm gonna keep the issue open. That or maybe this repo should have a disscussion board for questions like these.

Gremious avatar Jun 24 '23 17:06 Gremious

For anyone stumbling upon this in the future, this is the setup I went with:

local rust_tools_config = {
	-- rust-tools settings, etc.
	dap = function()
		local install_root_dir = vim.fn.stdpath "data" .. "/mason"
		local extension_path = install_root_dir .. "/packages/codelldb/extension/"
		local codelldb_path = extension_path .. "adapter/codelldb"
		local liblldb_path = extension_path .. "lldb/lib/liblldb.so"

		return {
			adapter = require("rust-tools.dap").get_codelldb_adapter(codelldb_path, liblldb_path)
		}
	end,
}

mason_lspconfig.setup_handlers({
	-- The first entry (without a key) will be the default handler
	-- and will be called for each installed server that doesn't have a dedicated handler.
	function(server_name)
		-- I use lsp-status which adds itself to the capabilities table
		require("lspconfig")[server_name].setup({ on_attach = on_attach, capabilities = capabilities })
	end,

	["lua_ls"] = function()
		require("lspconfig").lua_ls.setup({
			on_attach = on_attach,
			capabilities = capabilities,
			settings = {
				Lua = {
					diagnostics = {
						-- Get the language server to recognize the `vim` global
						globals = { "vim" },
					},
				},
			},
		})
	end,

	["rust_analyzer"] = function()
		require("rust-tools").setup({
			-- rust_tools specific settings
			tools = rust_tools_config,
			-- on_attach is actually bound in server for rust-tools
			server = rust_tools_rust_server,
			capabilities = capabilities,
		})
	end,
})

(full config here: https://github.com/Gremious/configs, though it's still a mess)

Gremious avatar Jun 24 '23 18:06 Gremious

(full config here: https://github.com/Gremious/configs, though it's still a mess)

It looks like that is a private repo or deleted

-- I use lsp-status which adds itself to the capabilities table

It looks like the capabilities variable doesn't exist, can you elaborate?

TheButlah avatar Jul 01 '23 22:07 TheButlah

It looks like that is a private repo or deleted

Oops, my bad! Public now.

It looks like the capabilities variable doesn't exist, can you elaborate?

If you mean variable doesn't exit in my little snippet - yeah, sorry. I believe you can ommit it if you're not doing anything special. But you can now see how I use it here: https://github.com/Gremious/configs/blob/main/lua/config/lsp.lua#L110 I create cmp_nvim_lsp ones from the lsp default ones, with the function cmp_nvim_lsp provides. Then, I extend the table with lsp_status ones as well.

If you mean Mason doesn't mention the capabilities table, then yeah, mason-lspconfig doesn't mention on_attach/capabilities anywhere at all, so I assume those are just the actual nvim-lspconfig tables, since nvim-lspconfig notes "You must pass on_attach and capabilities for each setup {} if you want these to take effect." in their readme https://github.com/neovim/nvim-lspconfig

Gremious avatar Jul 04 '23 11:07 Gremious

For anyone on macOS, you need to do two things:

  1. Use these instructions to symlink lldb-vscode onto your path without conflicting with the default lldb installation.
  2. Change the end of the liblldb_path to .dylib.

eikopf avatar Aug 07 '23 14:08 eikopf

Thanks a lot for the help!

This is what I decided to go with after getting the same error

require('mason-lspconfig').setup_handlers({
  function(server_name)
      require("lspconfig")[server_name].setup({ on_attach = on_attach, capabilities = capabilities })
    end,

    ["rust_analyzer"] = function ()
        require("rust-tools").setup()
    end
})

works well enough 😅

newtoallofthis123 avatar Oct 17 '23 15:10 newtoallofthis123

Thanks a lot for the help!

This is what I decided to go with after getting the same error

require('mason-lspconfig').setup_handlers({
  function(server_name)
      require("lspconfig")[server_name].setup({ on_attach = on_attach, capabilities = capabilities })
    end,

    ["rust_analyzer"] = function ()
        require("rust-tools").setup()
    end
})

works well enough 😅

This have the downside of always loading rust-tools, so to get it lazy loaded I instead uses

                ["rust_analyzer"] = function() end

in the mason-lspconfig. And then I just load it using a file type trigger in my Lazy config

 {
        -- Rust Programming Enhancements
        "simrat39/rust-tools.nvim",
        ft = "rust",
 
        ...
}

snaggen avatar Oct 18 '23 06:10 snaggen

that's actually quite smart 😄

newtoallofthis123 avatar Oct 18 '23 08:10 newtoallofthis123

Could someone add this to the README? Maybe in a spoilered/collapsible section

TheButlah avatar Oct 18 '23 18:10 TheButlah