Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions lua/flutter-tools/lsp/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,16 @@ function M.restart()
end
end

---@param buffer_path string? defaults to the current buffer's path
---@return string?
function M.get_project_root_dir()
function M.get_project_root_dir(buffer_path)
local conf = require("flutter-tools.config")
local current_buffer_path = path.current_buffer_path()
buffer_path = buffer_path or path.current_buffer_path()
-- Check if path is flutter dependency. For dependencies we do not
-- search for a root directory as they are not projects.
if not path.is_flutter_dependency_path(current_buffer_path) then
local root_path = lsp_utils.is_valid_path(current_buffer_path)
and path.find_root(conf.root_patterns, current_buffer_path)
if not path.is_flutter_dependency_path(buffer_path) then
local root_path = lsp_utils.is_valid_path(buffer_path)
and path.find_root(conf.root_patterns, buffer_path)
or nil
if root_path ~= nil then return root_path end
end
Expand Down Expand Up @@ -284,7 +285,7 @@ function M.attach()
-- 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()
c.root_dir = M.get_project_root_dir(buffer_path)
or fs.dirname(fs.find(conf.root_patterns, {
path = buffer_path,
upward = true,
Expand Down
25 changes: 20 additions & 5 deletions lua/flutter-tools/utils/path.lua
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,29 @@ function M.pub_cache_dir()
return vim.env.HOME and M.join(vim.env.HOME, ".pub-cache")
end

---@param dir string
---@return boolean
local function is_flutter_sdk_root(dir)
return M.is_file(M.join(dir, "bin", "flutter"))
and M.is_dir(M.join(dir, "bin", "cache", "dart-sdk"))
end

---@param full_path string
---@return boolean
local function is_inside_flutter_sdk(full_path)
for dir in vim.fs.parents(full_path) do
if is_flutter_sdk_root(dir) then return true end
end
return false
end

function M.is_flutter_dependency_path(full_path)
if not full_path or full_path == "" then return false end
local path_parts = { [[.pub-cache]], [[Pub\Cache]], [[/fvm/versions/]] }
if full_path then
for _, path_part in ipairs(path_parts) do
if full_path:find(path_part, nil, true) then return true end
end
for _, path_part in ipairs(path_parts) do
if full_path:find(path_part, nil, true) then return true end
end
return false
return is_inside_flutter_sdk(full_path)
end

return M
47 changes: 47 additions & 0 deletions tests/path_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,50 @@ describe("path.pub_cache_dir", function()
assert.are.equal(expected, path.pub_cache_dir())
end)
end)

describe("path.is_flutter_dependency_path", function()
local test_dir
local sdk
local project

before_each(function()
local temp_base = vim.fn.tempname()
vim.fn.mkdir(temp_base, "p")
test_dir = vim.uv.fs_realpath(temp_base)
sdk = test_dir .. "/mise/installs/flutter/3.47.1"
project = test_dir .. "/my_app"

vim.fn.mkdir(sdk .. "/bin/cache/dart-sdk", "p")
vim.fn.writefile({}, sdk .. "/bin/flutter")
vim.fn.mkdir(sdk .. "/packages/flutter/lib/src/widgets", "p")
vim.fn.mkdir(project .. "/lib", "p")
end)

after_each(function() vim.fn.delete(test_dir, "rf") end)

it("should detect files inside a Flutter SDK installed anywhere", function()
local file_path = sdk .. "/packages/flutter/lib/src/widgets/basic.dart"
assert.is_true(path.is_flutter_dependency_path(file_path))
end)

it("should not detect a directory without a Dart SDK as a Flutter SDK", function()
vim.fn.delete(sdk .. "/bin/cache", "rf")
local file_path = sdk .. "/packages/flutter/lib/src/widgets/basic.dart"
assert.is_false(path.is_flutter_dependency_path(file_path))
end)

it(
"should not detect project files",
function() assert.is_false(path.is_flutter_dependency_path(project .. "/lib/main.dart")) end
)

it("should detect pub cache files", function()
local file_path = "/home/user/.pub-cache/hosted/pub.dev/http-1.2.0/lib/http.dart"
assert.is_true(path.is_flutter_dependency_path(file_path))
end)

it("should handle missing paths", function()
assert.is_false(path.is_flutter_dependency_path(nil))
assert.is_false(path.is_flutter_dependency_path(""))
end)
end)
Loading