neotest icon indicating copy to clipboard operation
neotest copied to clipboard

Lazy load adapters

Open rokbot opened this issue 1 year ago • 2 comments

Question / Proposal:

Is there a way to lazy load the adapters based on the file type?

The problem is that all the adapters are loaded even when they are no required for the current neotest session.

The current implementation is:

require("neotest").setup({
    adapters = {
        require "neotest-python",
        require "neotest-go"
    }
}) 

I tried:

local neotest = require "neotest"

if vim.bo.ft == "python" then
  neotest.setup { adapters = require "neotest-python" }
elseif vim.bo.ft == "go" then
  neotest.setup { adapters = require "neotest-go" }
end

but does not work plus it has their own problems like there should be only one setup, thinking about the after/ftplugin directory but i feel it won't work either so i suppose, maybe can be implemented internally in neotest , probably create some table that can be passed to setup as an alternative to the adapters table to be able to lazy load by ft, something like adapters_by_ft that should look like this:

require("neotest").setup({
   adapters_by_ft = {
       python = require "neotest-python",
       go = require "neotest-go"
   }
}) 

I think it would be nice, maybe i will try to implement this by myself, and if it works submit a PR.

rokbot avatar Jun 27 '24 20:06 rokbot

I think it would be cool to have a mason like installer for them in addition to lazy loading them on demand

codymikol avatar Jul 05 '24 04:07 codymikol

It would be great to load the adapters according to the filetype. I am trying to get rid of my IDEs and to switch to Neovim for almost everything. But without neotest, it isn't interesting to get rid of my IDEs right now.

rsareth avatar Sep 13 '24 01:09 rsareth

I reported #466. It may be related - I too see both adapters to get loaded in random order and causing problems.

brablc avatar Nov 01 '24 13:11 brablc

I've hand-rolled my own lazy-loading for Neotest adapters. On startup I create a simple mapping of filetype→neotest adapter module and then load it from there on each of the entrypoints (keymaps) I have set up for Neotest.

Lazy.nvim plugins (shortened example, full config for ref)

{
    'nvim-neotest/neotest',
    keys = {
        {
            '<leader>tf',
            function()
                _ = require('conf.neotest.adapters')[vim.bo.filetype] -- load adapter based on filetype
                require('neotest').run.run {
                    suite = false,
                }
            end,
            desc = 'nearest function',
        },
    },
    dependencies = { { 'nvim-neotest/nvim-nio', lazy = true } },
    opts = { adapters = {} } -- no adapters registered on initial setup
},
{
    'nvim-neotest/neotest-python',
    lazy = true,
    dependencies = { 'nvim-neotest/neotest' },
    init = function()
        require('conf.neotest.adapters').python = 'neotest-python' -- register filetype
    end,
    opts = {
        dap = { justMyCode = true },
        runner = 'pytest',
        args = {
            '-s', -- don't capture console output
            '--log-level',
            'DEBUG',
            '-vv',
        },
    },
    config = function(_, opts)
        local adapter = require 'neotest-python'(opts)
        local adapters = require('neotest.config').adapters
        table.insert(adapters, adapter)
    end,
},
{
    'haydenmeade/neotest-jest',
    lazy = true,
    dependencies = { 'nvim-neotest/neotest' },
    init = function()
        for _, filetype in ipairs {
            'javascript',
            'typescript',
            'javascriptreact',
            'typescriptreact',
        } do
            require('conf.neotest.adapters')[filetype] = 'neotest-jest' -- register filetypes
        end
    end,
    opts = {},
    config = function(_, opts)
        local adapter = require 'neotest-jest'(opts)
        local adapters = require('neotest.config').adapters
        table.insert(adapters, adapter)
    end,
}

disrupted avatar Feb 22 '25 11:02 disrupted

The proposed alternative above seems effective but a bit hacky - using keystroke triggers to invoke certain adapters to lazy-load seems more like dancing around the problem rather than addressing it head-on. Has there been any progress on a more official method for filetype-specific adapter loading?

Numilani avatar Aug 03 '25 04:08 Numilani

I think a potential way to solve this would be to add a cache layer.

cache project root cache test root cache test file + hash + adapter + test cases and identifiers

then be a little predictive when trying to figure out the next applicable adapter

IE: this project only uses neotest-kotlin? lets start there, yep. add to cache. ( I think this is going to cover almost all cases )

That might mean a little extra work the first full scan of a project, but all subsequent runs should be able to only load the relevant adapters.

codymikol avatar Aug 03 '25 15:08 codymikol