From 46fb09cc871544e654e88fc6b3ab8e537d2faa68 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Sun, 3 Mar 2024 16:25:12 +0100 Subject: [PATCH] feat(lsp): don't auto-attach to buffers that aren't files --- CHANGELOG.md | 6 +++++- doc/rustaceanvim.txt | 2 +- ftplugin/rust.lua | 14 +++++++------- lua/rustaceanvim/config/init.lua | 2 +- lua/rustaceanvim/config/internal.lua | 12 ++++++++++-- lua/rustaceanvim/lsp.lua | 2 +- lua/rustaceanvim/os.lua | 18 +++++++++++++++--- lua/rustaceanvim/rust_analyzer.lua | 2 +- 8 files changed, 41 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72532c0c..e38baef2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [4.11.0] - 2024-03-03 + +### Added + +- LSP: By default, don't auto-attach to buffers that aren't files [[#268](https://github.com/mrcjkb/rustaceanvim/issues/268)]. ### Fixed diff --git a/doc/rustaceanvim.txt b/doc/rustaceanvim.txt index f4797a7e..56567c8a 100644 --- a/doc/rustaceanvim.txt +++ b/doc/rustaceanvim.txt @@ -209,7 +209,7 @@ RustcOpts *RustcOpts* RustaceanLspClientOpts *RustaceanLspClientOpts* Fields: ~ - {auto_attach?} (boolean|fun():boolean) Whether to automatically attach the LSP client. Defaults to `true` if the `rust-analyzer` executable is found. + {auto_attach?} (boolean|fun(bufnr:integer):boolean) Whether to automatically attach the LSP client. Defaults to `true` if the `rust-analyzer` executable is found. {cmd?} (string[]|fun():string[]) Command and arguments for starting rust-analyzer {settings?} (table|fun(project_root:string|nil):table) Setting passed to rust-analyzer. Defaults to a function that looks for a `rust-analyzer.json` file or returns an empty table. See https://rust-analyzer.github.io/manual.html#configuration. {standalone?} (boolean) Standalone file support (enabled by default). Disabling it may improve rust-analyzer's startup time. diff --git a/ftplugin/rust.lua b/ftplugin/rust.lua index cb274e65..b8d2ff4d 100644 --- a/ftplugin/rust.lua +++ b/ftplugin/rust.lua @@ -1,7 +1,5 @@ ---@type RustaceanConfig local config = require('rustaceanvim.config.internal') -local types = require('rustaceanvim.types.internal') -local lsp = require('rustaceanvim.lsp') if not vim.g.did_rustaceanvim_initialize then vim.lsp.commands['rust-analyzer.runSingle'] = function(command) @@ -45,10 +43,12 @@ end vim.g.did_rustaceanvim_initialize = true -local auto_attach = types.evaluate(config.server.auto_attach) - -if not auto_attach then - return +local auto_attach = config.server.auto_attach +if type(auto_attach) == 'function' then + local bufnr = vim.api.nvim_get_current_buf() + auto_attach = auto_attach(bufnr) end -lsp.start() +if auto_attach then + require('rustaceanvim.lsp').start() +end diff --git a/lua/rustaceanvim/config/init.lua b/lua/rustaceanvim/config/init.lua index f344b064..cdd3201f 100644 --- a/lua/rustaceanvim/config/init.lua +++ b/lua/rustaceanvim/config/init.lua @@ -100,7 +100,7 @@ vim.g.rustaceanvim = vim.g.rustaceanvim ---@field edition string The edition to use. See https://rustc-dev-guide.rust-lang.org/guides/editions.html. Default '2021'. ---@class RustaceanLspClientOpts ----@field auto_attach? boolean | fun():boolean Whether to automatically attach the LSP client. Defaults to `true` if the `rust-analyzer` executable is found. +---@field auto_attach? boolean | fun(bufnr: integer):boolean Whether to automatically attach the LSP client. Defaults to `true` if the `rust-analyzer` executable is found. ---@field cmd? string[] | fun():string[] Command and arguments for starting rust-analyzer ---@field settings? table | fun(project_root:string|nil):table Setting passed to rust-analyzer. Defaults to a function that looks for a `rust-analyzer.json` file or returns an empty table. See https://rust-analyzer.github.io/manual.html#configuration. ---@field standalone? boolean Standalone file support (enabled by default). Disabling it may improve rust-analyzer's startup time. diff --git a/lua/rustaceanvim/config/internal.lua b/lua/rustaceanvim/config/internal.lua index 965362f5..76b4ebe8 100644 --- a/lua/rustaceanvim/config/internal.lua +++ b/lua/rustaceanvim/config/internal.lua @@ -2,6 +2,7 @@ local types = require('rustaceanvim.types.internal') local compat = require('rustaceanvim.compat') local config = require('rustaceanvim.config') local executors = require('rustaceanvim.executors') +local os = require('rustaceanvim.os') local RustaceanConfig @@ -228,9 +229,16 @@ local RustaceanDefaultConfig = { ---@diagnostic disable-next-line: undefined-doc-class ---@class RustaceanLspClientConfig: vim.lsp.ClientConfig server = { - ---@type boolean | fun():boolean Whether to automatically attach the LSP client. + ---@type boolean | fun(bufnr: integer):boolean Whether to automatically attach the LSP client. ---Defaults to `true` if the `rust-analyzer` executable is found. - auto_attach = function() + auto_attach = function(bufnr) + if #vim.bo[bufnr].buftype > 0 then + return false + end + local path = vim.api.nvim_buf_get_name(bufnr) + if not os.is_valid_file_path(path) then + return false + end local cmd = types.evaluate(RustaceanConfig.server.cmd) ---@cast cmd string[] local rs_bin = cmd[1] diff --git a/lua/rustaceanvim/lsp.lua b/lua/rustaceanvim/lsp.lua index 4f5a62eb..079c5c82 100644 --- a/lua/rustaceanvim/lsp.lua +++ b/lua/rustaceanvim/lsp.lua @@ -57,7 +57,7 @@ M.start = function(bufnr) ---@type LspStartConfig local lsp_start_config = vim.tbl_deep_extend('force', {}, client_config) local root_dir = cargo.get_root_dir(vim.api.nvim_buf_get_name(bufnr)) - root_dir = root_dir and os.normalize_path(root_dir) + root_dir = root_dir and os.normalize_path_on_windows(root_dir) lsp_start_config.root_dir = root_dir if not root_dir then --- No project root found. Start in detached/standalone mode. diff --git a/lua/rustaceanvim/os.lua b/lua/rustaceanvim/os.lua index b4d520c3..3742244f 100644 --- a/lua/rustaceanvim/os.lua +++ b/lua/rustaceanvim/os.lua @@ -3,6 +3,7 @@ local os = {} local compat = require('rustaceanvim.compat') +local shell = require('rustaceanvim.shell') ---@param url string function os.open_url(url) @@ -35,12 +36,23 @@ end ---Normalize path for Windows, which is case insensitive ---@param path string ----@return string normalize_path -function os.normalize_path(path) - if require('rustaceanvim.shell').is_windows() then +---@return string normalized_path +function os.normalize_path_on_windows(path) + if shell.is_windows() then return path:lower() end return path end +---@param path string +---@return boolean +function os.is_valid_file_path(path) + local normalized_path = vim.fs.normalize(path, { expand_env = false }) + if shell.is_windows() then + local starts_with_drive_letter = normalized_path:match('^%a:') ~= nil + return starts_with_drive_letter + end + return vim.startswith(normalized_path, '/') +end + return os diff --git a/lua/rustaceanvim/rust_analyzer.lua b/lua/rustaceanvim/rust_analyzer.lua index 48f75623..3077b728 100644 --- a/lua/rustaceanvim/rust_analyzer.lua +++ b/lua/rustaceanvim/rust_analyzer.lua @@ -75,7 +75,7 @@ M.file_request = function(file_path, method, params, handler) local client_found = false for _, client in ipairs(M.get_active_rustaceanvim_clients(nil, { method = method })) do local root_dir = client.config.root_dir - if root_dir and vim.startswith(os.normalize_path(file_path), root_dir) then + if root_dir and vim.startswith(os.normalize_path_on_windows(file_path), root_dir) then local bufnr = find_buffer_by_name(file_path) if not params then params = {