You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Neovim LSP on_init异步执行 解决EFM项目配置加载UI冻结问题

解决方案

你可以使用 Neovim 内置的 libuv 异步接口 vim.loop.spawn 替换原有的同步 systemlist 调用,无需修改核心配置逻辑即可解决UI阻塞问题。修改后的代码如下:

on_init = function(client)
  -- 异步执行pip list命令,完全不阻塞主UI线程
  local stdout = vim.loop.new_pipe(false)
  local stderr = vim.loop.new_pipe(false)

  -- 启动异步子进程执行poetry命令
  vim.loop.spawn('poetry', {
    args = { 'run', 'pip', 'list', '--disable-pip-version-check' },
    stdio = { nil, stdout, stderr },
  }, vim.schedule_wrap(function(code, signal)
    -- 进程退出后清理管道资源
    stdout:read_stop()
    stderr:read_stop()
    stdout:close()
    stderr:close()
  end))

  local matched_packages = {}
  -- 异步读取命令标准输出
  stdout:read_start(vim.schedule_wrap(function(err, data)
    if err then return end
    if data then
      -- 逐行匹配需要的工具包,替代grep逻辑
      for line in vim.gsplit(data, '\n', { plain = true, trimempty = true }) do
        local pkg_name = line:match('^(%w+)%s+')
        if pkg_name and vim.tbl_contains({'black', 'yapf', 'flake8', 'isort', 'mypy'}, pkg_name) then
          table.insert(matched_packages, pkg_name)
        end
      end
    else
      -- 输出读取完成后更新LSP配置
      for _, pkg in ipairs(matched_packages) do
        local pkg_config = M[pkg]
        if pkg_config then
          table.insert(client.config.settings.languages.python, pkg_config)
        end
      end
      -- 通知LSP配置更新
      client.notify("workspace/didChangeConfiguration")
    end
  end))

  return true
end

几个优化和注意事项:

  • 所有回调都用 vim.schedule_wrap 包裹,确保 Neovim 核心API调用运行在主线程,避免线程安全问题
  • 把原有的grep逻辑移到Lua层实现,减少额外子进程开销,执行效率更高
  • 异步逻辑不会阻塞on_init回调返回,LSP可以正常启动,配置更新完成后会自动生效

内容的提问来源于stack exchange,提问作者ddd111

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 15:06:01