From ec27f2b02813eceff156db32101442ef1c1b57ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tautvydas=20S=CC=8Cidlauskas?= Date: Thu, 6 Aug 2026 14:44:39 +0300 Subject: [PATCH] fix(lsp): attach dartls to the buffer that requested it `M.attach()` validates the path of the current buffer, but `vim.lsp.start()` was called without `opts`, so the client attached to whichever buffer happened to be current when the callback ran. With `flutter_lookup_cmd` configured that callback is scheduled off a job's output, so switching buffers right after opening a dart file attached dartls to the wrong buffer and left the dart file unattached. Pass the captured `bufnr` through, and bail out if the buffer is gone by the time the callback runs. Also cache the paths resolved via `flutter_lookup_cmd`, matching the `fvm` and `flutter_path` branches. That branch was the only one leaving `cached_paths` unset, so it re-ran the external lookup command on every `attach()` - now once per `FileType` event since #527. --- lua/flutter-tools/executable.lua | 4 ++-- lua/flutter-tools/lsp/init.lua | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lua/flutter-tools/executable.lua b/lua/flutter-tools/executable.lua index 48f3de4f..1f74f844 100644 --- a/lua/flutter-tools/executable.lua +++ b/lua/flutter-tools/executable.lua @@ -174,13 +174,13 @@ function M.get(callback) if config.flutter_lookup_cmd then return path_from_lookup_cmd(config.flutter_lookup_cmd, function(paths) - paths = { + cached_paths = { flutter_bin = paths.flutter_bin, flutter_sdk = paths.flutter_sdk, dart_bin = paths.dart_bin, dart_sdk = dart_sdk_root(paths), } - callback(paths) + callback(cached_paths) end) end diff --git a/lua/flutter-tools/lsp/init.lua b/lua/flutter-tools/lsp/init.lua index 2f5e7dd4..e95672d5 100644 --- a/lua/flutter-tools/lsp/init.lua +++ b/lua/flutter-tools/lsp/init.lua @@ -287,12 +287,15 @@ function M.attach() if not is_valid_path(buffer_path) then return end get_server_config(user_config, function(c) + -- This callback can run asynchronously, by which point the user may have + -- switched to or deleted the buffer we were asked to attach to. + if not api.nvim_buf_is_valid(buf) then return end c.root_dir = M.get_project_root_dir() or fs.dirname(fs.find(conf.root_patterns, { path = buffer_path, upward = true, })[1]) - vim.lsp.start(c) + vim.lsp.start(c, { bufnr = buf }) end) end