From 79e86494b86be3b5a8602a1494ae132cc0e481ad Mon Sep 17 00:00:00 2001 From: simrat39 Date: Mon, 19 Jul 2021 16:39:57 -0700 Subject: [PATCH] feat: Standalone file support Closes #25 --- README.md | 8 +++++++ ftplugin/rust.vim | 1 + lua/rust-tools.lua | 25 ++++++++++++++++++++++ lua/rust-tools/standalone.lua | 39 ++++++++++++++++++++++++++++++++++ lua/rust-tools/utils/utils.lua | 4 ++++ 5 files changed, 77 insertions(+) create mode 100644 ftplugin/rust.vim create mode 100644 lua/rust-tools/standalone.lua diff --git a/README.md b/README.md index 7877644..6ec0c72 100644 --- a/README.md +++ b/README.md @@ -118,8 +118,16 @@ RustJoinLines RustHoverActions RustMoveItemDown RustMoveItemUp +RustStartStandaloneServerForBuffer ``` +#### Standalone File Support +rust-tools supports rust analyzer for standalone files (not in a cargo project). +The language server is automatically started when you start a rust file which is +not in a cargo file (nvim abc.rs). If you want to attach some other buffer to +the standalone client (after opening nvim and switching to a new rust file), +then use the ```RustStartStandaloneServerForBuffer``` command. + #### Inlay Hints ![inlay hints](https://github.com/simrat39/rust-tools-demos/raw/master/inlay_hints.png) ```lua diff --git a/ftplugin/rust.vim b/ftplugin/rust.vim new file mode 100644 index 0000000..c29bf9d --- /dev/null +++ b/ftplugin/rust.vim @@ -0,0 +1 @@ +command RustStartStandaloneServerForBuffer :lua require('rust-tools.standalone').start_standalone_client() diff --git a/lua/rust-tools.lua b/lua/rust-tools.lua index d4fc07c..f06a3fc 100644 --- a/lua/rust-tools.lua +++ b/lua/rust-tools.lua @@ -1,6 +1,8 @@ local vim = vim local nvim_lsp = require 'lspconfig' local config = require 'rust-tools.config' +local utils = require('rust-tools.utils.utils') +local lspconfig_utils = require('lspconfig.util') local M = {} @@ -73,6 +75,25 @@ end local function setup_lsp() nvim_lsp.rust_analyzer.setup(config.options.server) end +local function get_root_dir() + local fname = vim.api.nvim_buf_get_name(0) + local cargo_crate_dir = lspconfig_utils.root_pattern 'Cargo.toml'(fname) + local cmd = 'cargo metadata --no-deps --format-version 1' + if cargo_crate_dir ~= nil then + cmd = cmd .. ' --manifest-path ' .. + lspconfig_utils.path.join(cargo_crate_dir, 'Cargo.toml') + end + local cargo_metadata = vim.fn.system(cmd) + local cargo_workspace_dir = nil + if vim.v.shell_error == 0 then + cargo_workspace_dir = + vim.fn.json_decode(cargo_metadata)['workspace_root'] + end + return cargo_workspace_dir or cargo_crate_dir or + lspconfig_utils.root_pattern 'rust-project.json'(fname) or + lspconfig_utils.find_git_ancestor(fname) +end + function M.setup(opts) config.setup(opts) @@ -88,6 +109,10 @@ function M.setup(opts) if config.options.tools.autoSetHints then require'rust-tools.inlay_hints'.setup_autocmd() end + + if utils.is_bufnr_rust(0) and (get_root_dir() == nil) then + require('rust-tools.standalone').start_standalone_client(config.options.server.handlers) + end end return M diff --git a/lua/rust-tools/standalone.lua b/lua/rust-tools/standalone.lua new file mode 100644 index 0000000..27852c5 --- /dev/null +++ b/lua/rust-tools/standalone.lua @@ -0,0 +1,39 @@ +local ra_config = require 'rust-tools.config' + +local M = {} + +function M.start_standalone_client(handlers) + local config = { + root_dir = require('lspconfig.util').path.dirname( + vim.api.nvim_buf_get_name(0)), + capabilities = ra_config.options.server.capabilities, + cmd = {'rust-analyzer'}, + init_options = {detachedFiles = {vim.api.nvim_buf_get_name(0)}}, + on_init = function(client) + vim.lsp.buf_attach_client(0, client.id) + vim.cmd "command! RustSetInlayHints :lua require('rust-tools.inlay_hints').set_inlay_hints()" + vim.cmd "command! RustDisableInlayHints :lua require('rust-tools.inlay_hints').disable_inlay_hints()" + vim.cmd "command! RustToggleInlayHints :lua require('rust-tools.inlay_hints').toggle_inlay_hints()" + vim.cmd "command! RustExpandMacro :lua require('rust-tools.expand_macro').expand_macro()" + vim.cmd "command! RustJoinLines :lua require('rust-tools.join_lines').join_lines()" + vim.cmd "command! RustHoverActions :lua require('rust-tools.hover_actions').hover_actions()" + vim.cmd "command! RustMoveItemDown :lua require('rust-tools.move_item').move_item()" + vim.cmd "command! RustMoveItemUp :lua require('rust-tools.move_item').move_item(true)" + end, + on_exit = function() + vim.cmd "delcommand RustSetInlayHints" + vim.cmd "delcommand RustDisableInlayHints" + vim.cmd "delcommand RustToggleInlayHints" + vim.cmd "delcommand RustExpandMacro" + vim.cmd "delcommand RustJoinLines" + vim.cmd "delcommand RustHoverActions" + vim.cmd "delcommand RustMoveItemDown" + vim.cmd "delcommand RustMoveItemUp" + end, + handlers = handlers + } + + vim.lsp.start_client(config) +end + +return M diff --git a/lua/rust-tools/utils/utils.lua b/lua/rust-tools/utils/utils.lua index 6c779fc..12207b0 100644 --- a/lua/rust-tools/utils/utils.lua +++ b/lua/rust-tools/utils/utils.lua @@ -29,4 +29,8 @@ function M.snippet_text_edits_to_text_edits(spe) end end +function M.is_bufnr_rust(bufnr) + return vim.api.nvim_buf_get_option(bufnr, 'ft') == 'rust' +end + return M