首页
/ 在fidget.nvim中实现LSP查询进度显示的技术方案

在fidget.nvim中实现LSP查询进度显示的技术方案

2025-07-03 04:34:17作者:钟日瑜

fidget.nvim作为Neovim的LSP进度通知插件,能够优雅地展示语言服务器的操作进度。本文将深入探讨如何在该插件中实现LSP查询进度的可视化显示,帮助开发者更好地监控长时间运行的LSP请求。

LSP请求进度显示的重要性

在大型项目中,某些LSP请求(如代码分析、文档高亮等)可能需要较长时间才能完成。传统方式下,用户在执行这些操作时往往得不到任何反馈,导致不确定请求是否正在处理或已经卡死。通过fidget.nvim实现进度显示,可以显著改善开发体验。

核心实现原理

fidget.nvim通过监听Neovim的LspRequest事件来捕获LSP请求的生命周期。每个LSP请求都会经历pending(挂起)、complete(完成)或error(错误)三种状态,我们可以利用这些状态变化来更新进度通知。

完整实现方案

以下是两种经过验证的实现方式,开发者可以根据需求选择或调整:

基础实现方案

vim.api.nvim_create_autocmd("LspRequest", {
  callback = function(args)
    -- 过滤掉频繁触发的高亮请求
    if args.data.request.method == "textDocument/documentHighlight" then return end

    if args.data.request.type == "pending" then
      -- 创建新的进度通知
      local handle = fgp.handle.create({
        title = "LSP query",
        message = args.data.request.method,
        lsp_client = { name = args.data.client_id },
      })
      -- 将请求ID与进度句柄关联
      lspu.progress_handle_add(args.data.request_id, handle)
    elseif args.data.request.type == "error" then
      -- 请求失败处理
      local handle = lspu.progress_handle_take(args.data.request_id)
      if handle then
        handle.message = handle.message .. " "  -- 添加错误图标
        handle:finish()
      end
    else
      -- 请求成功完成
      local handle = lspu.progress_handle_take(args.data.request_id)
      if handle then
        handle.message = handle.message .. " "  -- 添加成功图标
        handle:finish()
      end
    end
  end
})

增强版实现方案

vim.api.nvim_create_autocmd('LspRequest', {
  callback = function(args)
    local data = args.data
    -- 定义需要忽略的频繁请求类型
    local ignored_noisy_requests = {
      ['textDocument/documentHighlight'] = true,
      ['textDocument/semanticTokens/full'] = true,
      ['textDocument/semanticTokens/full/delta'] = true,
      ['textDocument/semanticTokens/range'] = true,
      ['textDocument/completion'] = true,
    }
    -- 跳过配置中忽略的请求类型
    if ignored_noisy_requests[data.request.method] then return end
    
    -- 状态到显示消息的映射
    local request_status_to_message = {
      pending = 'Requesting',
      error = 'Error',
      complete = 'Completed',
    }
    
    -- 构建进度消息对象
    local message = {
      title = data.request.method,  -- 使用LSP方法名作为标题
      message = request_status_to_message[data.request.type],
      lsp_client = assert(vim.lsp.get_client_by_id(data.client_id),
      cancellable = false,
      done = data.request.type ~= 'pending',
      token = data.request_id,
    }
    
    -- 加载配置并显示进度
    fidget_progress.load_config(message)
    fidget.notify(fidget_progress.format_progress(message))
  end,
})

技术要点解析

  1. 事件监听机制:通过Neovim的LspRequest自动命令捕获所有LSP请求事件

  2. 请求过滤:针对频繁触发但对用户不重要的请求(如文档高亮)进行过滤,避免通知干扰

  3. 状态管理

    • pending状态:创建新的进度通知
    • complete/error状态:更新现有通知并标记完成
  4. 视觉反馈:使用图标(✓/✗)直观显示请求结果

  5. 客户端关联:将进度通知与特定的LSP客户端关联,便于识别

实际应用建议

  1. 性能考量:对于小型项目,可能不需要显示所有请求进度,可以适当增加过滤条件

  2. 自定义扩展:可以根据团队需求添加更多信息,如请求耗时统计

  3. 主题适配:结合fidget.nvim的主题配置,使进度通知与编辑器主题风格一致

  4. 错误处理增强:可以扩展错误处理逻辑,显示更详细的错误信息

通过这种实现,开发者可以清晰了解后台LSP请求的执行情况,显著提升开发体验,特别是在处理大型代码库时效果尤为明显。

登录后查看全文
热门项目推荐
相关项目推荐