如何配置Neovim仅首次插入启动LSP并闲置自动关闭?
配置方案:延迟启动+闲置自动关闭LSP
核心思路
- 禁用LSP自动启动,仅在首次进入插入模式(InsertEnter)时触发对应buffer的LSP启动
- 跟踪用户活动状态,闲置30分钟后关闭所有活跃LSP,重置启动标记,下次进入插入模式重新启动
具体配置(Lua)
1. 修改LSP默认启动行为
首先在你的LSP配置中,将所有需要控制的LSP设置为禁止自动启动:
local lspconfig = require('lspconfig') -- 替换为你实际使用的LSP服务列表 local servers = { 'lua_ls', 'pyright', 'tsserver', 'gopls' } for _, server in ipairs(servers) do lspconfig[server].setup({ autostart = false, -- 关键:禁止会话恢复时自动启动LSP -- 保留你原有的其他配置(如on_attach、capabilities等) }) end
2. 首次InsertEnter触发LSP启动
添加自动命令,在首次进入插入模式时启动当前buffer对应的LSP:
-- 监听InsertEnter事件,启动对应LSP vim.api.nvim_create_autocmd('InsertEnter', { pattern = '*', callback = function() local buf = vim.api.nvim_get_current_buf() -- 避免重复启动同一buffer的LSP if vim.b[buf].lsp_started then return end local ft = vim.bo[buf].filetype -- 根据文件类型匹配对应LSP服务,需和你的servers列表对应 local server_map = { lua = 'lua_ls', python = 'pyright', typescript = 'tsserver', javascript = 'tsserver', go = 'gopls' } local target_server = server_map[ft] if target_server and require('lspconfig')[target_server] then -- 启动LSP require('lspconfig')[target_server].launch() -- 标记该buffer已启动LSP vim.b[buf].lsp_started = true -- 更新用户最后活动时间 vim.g.last_activity_time = vim.fn.localtime() end end })
3. 闲置超时自动关闭LSP
添加闲置检测逻辑,30分钟无活动时关闭所有LSP并重置标记:
-- 初始化用户最后活动时间 vim.g.last_activity_time = vim.fn.localtime() -- 监听用户活动事件,实时更新最后活动时间 local activity_triggers = { 'CursorMoved', 'CursorMovedI', 'InsertEnter', 'InsertLeave', 'BufEnter', 'BufWritePost', 'KeyPress' } for _, event in ipairs(activity_triggers) do vim.api.nvim_create_autocmd(event, { pattern = '*', callback = function() vim.g.last_activity_time = vim.fn.localtime() end }) end -- 定时检查闲置状态(每分钟检查一次) local idle_threshold = 30 * 60 -- 30分钟,单位:秒 local idle_check_timer = vim.loop.new_timer() idle_check_timer:start(0, 60 * 1000, function() vim.schedule(function() local now = vim.fn.localtime() -- 超过闲置阈值则关闭LSP if now - vim.g.last_activity_time > idle_threshold then -- 关闭所有活跃的LSP客户端 local active_clients = vim.lsp.get_active_clients() for _, client in ipairs(active_clients) do client.stop() end -- 重置所有buffer的LSP启动标记 for _, buf in ipairs(vim.api.nvim_list_bufs()) do if vim.api.nvim_buf_is_valid(buf) then vim.b[buf].lsp_started = false end end -- 更新活动时间,避免重复触发关闭 vim.g.last_activity_time = now end end) end) -- 退出Neovim时清理定时器 vim.api.nvim_create_autocmd('VimLeave', { callback = function() if idle_check_timer then idle_check_timer:stop() idle_check_timer:close() end end })
注意事项
- 需根据你实际使用的LSP服务,修改
servers列表和server_map的文件类型映射 - 定时器每分钟检查一次闲置状态,平衡性能消耗与检测精度
- 活动触发事件覆盖了光标移动、输入、文件写入等常见操作,确保闲置检测的准确性
内容的提问来源于stack exchange,提问作者Dylanthepiguy
相关产品推荐
相关产品推荐

