From fcf2468d0e63b51bb260e1969a70cc0975815fc7 Mon Sep 17 00:00:00 2001
From: Steven Arcangeli <506791+stevearc@users.noreply.github.com>
Date: Tue, 21 Jun 2022 00:10:17 -0700
Subject: [PATCH] feat(client): allow disabling directory crawling (#30)

---
 doc/neotest.txt                 | 11 +++++++++++
 lua/neotest/client/init.lua     | 28 ++++++++++++++++++++++------
 lua/neotest/config/init.lua     |  7 +++++++
 tests/unit/client/init_spec.lua | 31 +++++++++++++++++++++++++++++++
 4 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/doc/neotest.txt b/doc/neotest.txt
index 180a7078..266276e0 100644
--- a/doc/neotest.txt
+++ b/doc/neotest.txt
@@ -49,6 +49,9 @@ neotest.setup({user_config})                                 *neotest.setup()*
         diagnostic = {
           enabled = true
         },
+        discovery = {
+          enabled = true
+        },
         floating = {
           border = "rounded",
           max_height = 0.6,
@@ -133,6 +136,7 @@ neotest.Config                                                *neotest.Config*
 
     Fields: ~
         {adapters}   (neotest.Adapter[])
+        {discovery}  (neotest.Config.discovery)
         {icons}      (table<string, string>)
         {highlights} (table<string, string>)
         {floating}   (neotest.Config.floating)
@@ -141,6 +145,13 @@ neotest.Config                                                *neotest.Config*
         {output}     (neotest.Config.output)
 
 
+neotest.Config.discovery                            *neotest.Config.discovery*
+
+
+    Fields: ~
+        {enabled} (boolean)
+
+
 neotest.Config.floating                              *neotest.Config.floating*
 
 
diff --git a/lua/neotest/client/init.lua b/lua/neotest/client/init.lua
index 4822541e..9f67af72 100644
--- a/lua/neotest/client/init.lua
+++ b/lua/neotest/client/init.lua
@@ -537,7 +537,9 @@ function NeotestClient:_start()
         if not adapter_id then
           return
         end
-        self:_update_positions(lib.files.parent(file_path), { adapter = adapter_id })
+        if config.discovery.enabled then
+          self:_update_positions(lib.files.parent(file_path), { adapter = adapter_id })
+        end
       end
       self:_update_positions(file_path, { adapter = adapter_id })
     end)
@@ -552,9 +554,11 @@ function NeotestClient:_start()
 
   autocmd({ "BufAdd", "BufDelete" }, function()
     local updated_dir = vim.fn.expand("<afile>:p:h")
-    async.run(function()
-      self:_update_positions(updated_dir)
-    end)
+    if config.discovery.enabled then
+      async.run(function()
+        self:_update_positions(updated_dir)
+      end)
+    end
   end)
 
   autocmd("BufEnter", function()
@@ -572,6 +576,14 @@ function NeotestClient:_start()
   end)
 
   self:_update_adapters(async.fn.getcwd())
+  -- If discovery is not enabled, we need to update positions for all open
+  -- buffers on startup
+  if not config.discovery.enabled then
+    for _, bufnr in ipairs(async.api.nvim_list_bufs()) do
+      local file_path = async.api.nvim_buf_get_name(bufnr)
+      self:_update_positions(file_path)
+    end
+  end
   local end_time = async.fn.localtime()
   logger.info("Initialisation finished in", end_time - start, "seconds")
   self:_set_focused_file(async.fn.expand("%:p"))
@@ -595,7 +607,9 @@ function NeotestClient:_update_adapters(path)
       table.insert(self._adapters, adapter)
       found[adapter.name] = true
     end
-    self:_update_positions(root, { adapter = adapter.name })
+    if config.discovery.enabled then
+      self:_update_positions(root, { adapter = adapter.name })
+    end
   end
   local root = lib.files.is_dir(path) and path or async.fn.getcwd()
   for _, adapter in ipairs(adapters_with_bufs) do
@@ -603,7 +617,9 @@ function NeotestClient:_update_adapters(path)
       table.insert(self._adapters, adapter)
       found[adapter.name] = true
     end
-    self:_update_positions(root, { adapter = adapter.name })
+    if config.discovery.enabled then
+      self:_update_positions(root, { adapter = adapter.name })
+    end
   end
 end
 
diff --git a/lua/neotest/config/init.lua b/lua/neotest/config/init.lua
index bad30d71..380ca903 100644
--- a/lua/neotest/config/init.lua
+++ b/lua/neotest/config/init.lua
@@ -17,12 +17,16 @@ vim.cmd([[
 
 ---@class neotest.Config
 ---@field adapters neotest.Adapter[]
+---@field discovery neotest.Config.discovery
 ---@field icons table<string, string>
 ---@field highlights table<string, string>
 ---@field floating neotest.Config.floating
 ---@field strategies neotest.Config.strategies
 ---@field summary neotest.Config.summary
 ---@field output neotest.Config.output
+--
+---@class neotest.Config.discovery
+---@field enabled boolean
 
 ---@class neotest.Config.floating
 ---@field border string: Border style
@@ -65,6 +69,9 @@ vim.cmd([[
 ---@type neotest.Config
 local default_config = {
   adapters = {},
+  discovery = {
+    enabled = true,
+  },
   icons = {
     passed = "✔",
     running = "🗘",
diff --git a/tests/unit/client/init_spec.lua b/tests/unit/client/init_spec.lua
index f576ad84..9f3c3b8f 100644
--- a/tests/unit/client/init_spec.lua
+++ b/tests/unit/client/init_spec.lua
@@ -136,6 +136,37 @@ describe("neotest client", function()
         assert.Not.same(file_tree:children(), {})
       end)
     end)
+
+    describe("discovery.enabled = false", function()
+      a.it("doesn't scan directories by default", function()
+        require("neotest.config").setup({
+          adapters = { mock_adapter },
+          discovery = { enabled = false },
+        })
+        local tree = client:get_position(dir)
+        assert.Nil(tree)
+        tree = client:get_position(dir .. "/test_file_1")
+        assert.Nil(tree)
+      end)
+
+      a.it("only scans buffers that are open when client starts", function()
+        require("neotest.config").setup({
+          adapters = { mock_adapter },
+          discovery = { enabled = false },
+        })
+        local bufnr = async.fn.bufadd(dir .. "/test_file_1")
+        async.fn.bufload(bufnr)
+        local tree = client:get_position(dir)
+        assert.Not.Nil(tree)
+        assert.Not.same(tree, {})
+        tree = client:get_position(dir .. "/test_file_1")
+        assert.Not.Nil(tree)
+        assert.Not.same(tree, {})
+        tree = client:get_position(dir .. "/test_file_2")
+        assert.Nil(tree)
+        async.api.nvim_buf_delete(bufnr, {})
+      end)
+    end)
   end)
 
   describe("running tests", function()