diff --git a/doc/neotest.txt b/doc/neotest.txt index 9ef95f81..2b8cc33d 100644 --- a/doc/neotest.txt +++ b/doc/neotest.txt @@ -104,6 +104,7 @@ Default values: jump = { enabled = true }, + log_level = 3, output = { enabled = true, open_on_run = "short" @@ -173,6 +174,7 @@ Fields~ Class~ {neotest.Config:} neotest.CoreConfig Fields~ +{log_level} `(number)` Minimum log levels, one of vim.log.levels {consumers} `(table)` {icons} `(table)` {highlights} `(table)` @@ -181,13 +183,18 @@ Fields~ {summary} neotest.Config.summary {output} neotest.Config.output {status} neotest.Config.status -{projects} `(table)` Project specific settings, keys are project root directories (e.g "~/Dev/my_project") +{projects} `(table)` Project specific settings, keys +are project root directories (e.g "~/Dev/my_project") Class~ {neotest.Config.discovery} Fields~ {enabled} `(boolean)` -{concurrent} `(integer)` Number of workers to parse files concurrently. 0 automatically assigns number based on CPU. Set to 1 if experiencing lag. +{concurrent} `(integer)` Number of workers to parse files concurrently. 0 +automatically assigns number based on CPU. Set to 1 if experiencing lag. +{filter_dir} `(nil)` | fun(name: string, rel_path: string, root: string): boolean +A function to filter directories when searching for test files. Receives the name, +path relative to project root and project root path Class~ {neotest.Config.running} diff --git a/lua/neotest/client/init.lua b/lua/neotest/client/init.lua index 8f7dd8e1..34b0a868 100644 --- a/lua/neotest/client/init.lua +++ b/lua/neotest/client/init.lua @@ -244,7 +244,11 @@ function NeotestClient:_update_positions(path, args) end end logger.info("Searching", path, "for test files") - local files = lib.func_util.filter_list(adapter.is_test_file, lib.files.find(path)) + local root_path = existing_root and existing_root:data().path or path + local files = lib.func_util.filter_list( + adapter.is_test_file, + lib.files.find(path, { filter_dir = config.projects[root_path].discovery.filter_dir }) + ) local positions = lib.files.parse_dir_from_files(path, files) logger.debug("Found", positions) self._state:update_positions(adapter_id, positions) diff --git a/lua/neotest/config/init.lua b/lua/neotest/config/init.lua index 7b60c96b..493a91df 100644 --- a/lua/neotest/config/init.lua +++ b/lua/neotest/config/init.lua @@ -42,11 +42,16 @@ define_highlights() ---@field summary neotest.Config.summary ---@field output neotest.Config.output ---@field status neotest.Config.status ----@field projects table Project specific settings, keys are project root directories (e.g "~/Dev/my_project") +---@field projects table Project specific settings, keys +--- are project root directories (e.g "~/Dev/my_project") ---@class neotest.Config.discovery ---@field enabled boolean ----@field concurrent integer Number of workers to parse files concurrently. 0 automatically assigns number based on CPU. Set to 1 if experiencing lag. +---@field concurrent integer Number of workers to parse files concurrently. 0 +--- automatically assigns number based on CPU. Set to 1 if experiencing lag. +---@field filter_dir nil | fun(name: string, rel_path: string, root: string): boolean +--- A function to filter directories when searching for test files. Receives the name, +--- path relative to project root and project root path ---@class neotest.Config.running ---@field concurrent boolean Run tests concurrently when an adapter provides multiple commands to run @@ -104,6 +109,7 @@ local default_config = { discovery = { enabled = true, concurrent = 0, + filter_dir = nil, }, running = { concurrent = true, diff --git a/lua/neotest/lib/file/find.lua b/lua/neotest/lib/file/find.lua index 1b01a174..77fe4d90 100644 --- a/lua/neotest/lib/file/find.lua +++ b/lua/neotest/lib/file/find.lua @@ -4,29 +4,35 @@ local M = {} --- Find all files under the given directory. --- Does not search hidden directories. ---@async ----@param dir_path string +---@param root string ---@return string[] @Absolute paths of all files within directories to search -function M.find(dir_path) +function M.find(root, opts) + opts = opts or {} + local filter_dir = opts.filter_dir local sep = require("neotest.lib").files.sep - local dirs_to_scan = { dir_path } + local dirs_to_scan = {} local paths = {} - local dir, dir_handle + local dir, dir_handle = "", uv.fs_scandir(root) while dir_handle or #dirs_to_scan > 0 do if not dir_handle then dir = table.remove(dirs_to_scan, 1) dir_handle = uv.fs_scandir(dir) end - local next_path, path_type = uv.fs_scandir_next(dir_handle) + local name, path_type = uv.fs_scandir_next(dir_handle) + local rel_path = name and (dir == "" and name or (dir .. sep .. name)) - if not next_path then + if not name then dir_handle = nil - elseif path_type == "directory" and next_path:sub(1, 1) ~= "." then - local i = #dirs_to_scan + 1 - dirs_to_scan[i] = dir .. sep .. next_path + elseif + path_type == "directory" + and name:sub(1, 1) ~= "." + and (not filter_dir or filter_dir(name, rel_path, root)) + then + dirs_to_scan[#dirs_to_scan + 1] = rel_path elseif path_type == "file" then - paths[#paths + 1] = dir .. sep .. next_path + paths[#paths + 1] = (root .. sep .. rel_path) end end return paths