[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-zbirenbaum--copilot.lua":3,"tool-zbirenbaum--copilot.lua":64},[4,17,26,36,44,56],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":16},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",144730,2,"2026-04-07T23:26:32",[13,14,15],"开发框架","Agent","语言模型","ready",{"id":18,"name":19,"github_repo":20,"description_zh":21,"stars":22,"difficulty_score":10,"last_commit_at":23,"category_tags":24,"status":16},4721,"markitdown","microsoft\u002Fmarkitdown","MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具，专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片（含 OCR）、音频（含语音转录）、HTML 乃至 YouTube 链接等多种格式的解析，能够精准提取文档中的标题、列表、表格和链接等关键结构信息。\n\n在人工智能应用日益普及的今天，大语言模型（LLM）虽擅长处理文本，却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点，它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式，成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外，它还提供了 MCP（模型上下文协议）服务器，可无缝集成到 Claude Desktop 等 LLM 应用中。\n\n这款工具特别适合开发者、数据科学家及 AI 研究人员使用，尤其是那些需要构建文档检索增强生成（RAG）系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性，但其核心优势在于为机器",93400,"2026-04-06T19:52:38",[25,13],"插件",{"id":27,"name":28,"github_repo":29,"description_zh":30,"stars":31,"difficulty_score":32,"last_commit_at":33,"category_tags":34,"status":16},4487,"LLMs-from-scratch","rasbt\u002FLLMs-from-scratch","LLMs-from-scratch 是一个基于 PyTorch 的开源教育项目，旨在引导用户从零开始一步步构建一个类似 ChatGPT 的大型语言模型（LLM）。它不仅是同名技术著作的官方代码库，更提供了一套完整的实践方案，涵盖模型开发、预训练及微调的全过程。\n\n该项目主要解决了大模型领域“黑盒化”的学习痛点。许多开发者虽能调用现成模型，却难以深入理解其内部架构与训练机制。通过亲手编写每一行核心代码，用户能够透彻掌握 Transformer 架构、注意力机制等关键原理，从而真正理解大模型是如何“思考”的。此外，项目还包含了加载大型预训练权重进行微调的代码，帮助用户将理论知识延伸至实际应用。\n\nLLMs-from-scratch 特别适合希望深入底层原理的 AI 开发者、研究人员以及计算机专业的学生。对于不满足于仅使用 API，而是渴望探究模型构建细节的技术人员而言，这是极佳的学习资源。其独特的技术亮点在于“循序渐进”的教学设计：将复杂的系统工程拆解为清晰的步骤，配合详细的图表与示例，让构建一个虽小但功能完备的大模型变得触手可及。无论你是想夯实理论基础，还是为未来研发更大规模的模型做准备",90106,3,"2026-04-06T11:19:32",[15,35,14,13],"图像",{"id":37,"name":38,"github_repo":39,"description_zh":40,"stars":41,"difficulty_score":10,"last_commit_at":42,"category_tags":43,"status":16},3704,"NextChat","ChatGPTNextWeb\u002FNextChat","NextChat 是一款轻量且极速的 AI 助手，旨在为用户提供流畅、跨平台的大模型交互体验。它完美解决了用户在多设备间切换时难以保持对话连续性，以及面对众多 AI 模型不知如何统一管理的痛点。无论是日常办公、学习辅助还是创意激发，NextChat 都能让用户随时随地通过网页、iOS、Android、Windows、MacOS 或 Linux 端无缝接入智能服务。\n\n这款工具非常适合普通用户、学生、职场人士以及需要私有化部署的企业团队使用。对于开发者而言，它也提供了便捷的自托管方案，支持一键部署到 Vercel 或 Zeabur 等平台。\n\nNextChat 的核心亮点在于其广泛的模型兼容性，原生支持 Claude、DeepSeek、GPT-4 及 Gemini Pro 等主流大模型，让用户在一个界面即可自由切换不同 AI 能力。此外，它还率先支持 MCP（Model Context Protocol）协议，增强了上下文处理能力。针对企业用户，NextChat 提供专业版解决方案，具备品牌定制、细粒度权限控制、内部知识库整合及安全审计等功能，满足公司对数据隐私和个性化管理的高标准要求。",87618,"2026-04-05T07:20:52",[13,15],{"id":45,"name":46,"github_repo":47,"description_zh":48,"stars":49,"difficulty_score":10,"last_commit_at":50,"category_tags":51,"status":16},2268,"ML-For-Beginners","microsoft\u002FML-For-Beginners","ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程，旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周，包含 26 节精炼课程和 52 道配套测验，内容涵盖从基础概念到实际应用的完整流程，有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。\n\n无论是希望转型的开发者、需要补充算法背景的研究人员，还是对人工智能充满好奇的普通爱好者，都能从中受益。课程不仅提供了清晰的理论讲解，还强调动手实践，让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持，通过自动化机制提供了包括简体中文在内的 50 多种语言版本，极大地降低了全球不同背景用户的学习门槛。此外，项目采用开源协作模式，社区活跃且内容持续更新，确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路，ML-For-Beginners 将是理想的起点。",85013,"2026-04-06T11:09:19",[35,52,53,25,14,54,15,13,55],"数据工具","视频","其他","音频",{"id":57,"name":58,"github_repo":59,"description_zh":60,"stars":61,"difficulty_score":32,"last_commit_at":62,"category_tags":63,"status":16},3128,"ragflow","infiniflow\u002Fragflow","RAGFlow 是一款领先的开源检索增强生成（RAG）引擎，旨在为大语言模型构建更精准、可靠的上下文层。它巧妙地将前沿的 RAG 技术与智能体（Agent）能力相结合，不仅支持从各类文档中高效提取知识，还能让模型基于这些知识进行逻辑推理和任务执行。\n\n在大模型应用中，幻觉问题和知识滞后是常见痛点。RAGFlow 通过深度解析复杂文档结构（如表格、图表及混合排版），显著提升了信息检索的准确度，从而有效减少模型“胡编乱造”的现象，确保回答既有据可依又具备时效性。其内置的智能体机制更进一步，使系统不仅能回答问题，还能自主规划步骤解决复杂问题。\n\n这款工具特别适合开发者、企业技术团队以及 AI 研究人员使用。无论是希望快速搭建私有知识库问答系统，还是致力于探索大模型在垂直领域落地的创新者，都能从中受益。RAGFlow 提供了可视化的工作流编排界面和灵活的 API 接口，既降低了非算法背景用户的上手门槛，也满足了专业开发者对系统深度定制的需求。作为基于 Apache 2.0 协议开源的项目，它正成为连接通用大模型与行业专有知识之间的重要桥梁。",77062,"2026-04-04T04:44:48",[14,35,13,15,54],{"id":65,"github_repo":66,"name":67,"description_en":68,"description_zh":69,"ai_summary_zh":69,"readme_en":70,"readme_zh":71,"quickstart_zh":72,"use_case_zh":73,"hero_image_url":74,"owner_login":75,"owner_name":76,"owner_avatar_url":77,"owner_bio":78,"owner_company":79,"owner_location":80,"owner_email":81,"owner_twitter":82,"owner_website":82,"owner_url":83,"languages":84,"stars":105,"forks":106,"last_commit_at":107,"license":108,"difficulty_score":10,"env_os":109,"env_gpu":110,"env_ram":110,"env_deps":111,"category_tags":118,"github_topics":119,"view_count":10,"oss_zip_url":82,"oss_zip_packed_at":82,"status":16,"created_at":126,"updated_at":127,"faqs":128,"releases":158},5485,"zbirenbaum\u002Fcopilot.lua","copilot.lua","Fully featured & enhanced replacement for copilot.vim complete with API for interacting with Github Copilot","copilot.lua 是一款专为 NeoVim 打造的高性能 GitHub Copilot 插件，旨在完全替代官方的 copilot.vim。它通过纯 Lua 重写核心逻辑，不仅保留了完整的代码补全功能，还提供了便捷的 API 以便与其他现代插件深度集成。\n\n这款工具主要解决了原版插件在运行时可能导致设备过热、资源占用过高的问题。同时，它优化了“幽灵文本”（即灰色建议代码）的渲染机制，避免了建议内容与现有补全插件（如 cmp）的显示冲突，让编码界面更加清爽流畅。得益于 Lua 语言的高效特性，copilot.lua 在启动速度和运行稳定性上均有显著提升。\n\ncopilot.lua 非常适合追求极致编辑体验的 NeoVim 重度用户、软件开发者以及热衷于定制个人开发环境的极客。其独特的技术亮点包括支持延迟加载以进一步优化启动性能，提供灵活的认证管理（支持多账号切换及私有 GitHub 实例），并允许用户精细配置高亮样式、文件类型过滤及日志记录等细节。如果你希望在享受 AI 辅助编程便利的同时，保持编辑器的轻量与响应速度，copilot.lua 是一个值得尝试的专业选择。","# copilot.lua\n\nThis plugin is the pure lua replacement for [github\u002Fcopilot.vim](https:\u002F\u002Fgithub.com\u002Fgithub\u002Fcopilot.vim).\nA huge thank you to @tris203 for the code behind the nes functionality ([copilot-lsp](https:\u002F\u002Fgithub.com\u002Fcopilotlsp-nvim\u002Fcopilot-lsp)).\n\n\u003Cdetails>\n\u003Csummary>Motivation behind `copilot.lua`\u003C\u002Fsummary>\n\nWhile using `copilot.vim`, for the first time since I started using neovim my laptop began to overheat. Additionally,\nI found the large chunks of ghost text moving around my code, and interfering with my existing cmp ghost text disturbing.\nAs lua is far more efficient and makes things easier to integrate with modern plugins, this repository was created.\n\n\u003C\u002Fdetails>\n\n## Table Of Contents\n\n\u003C!--toc:start-->\n\n- [Requirements](#requirements)\n- [Install](#install)\n  - [Authentication](#authentication)\n    - [Authentication with Alternate GitHub Instances](#authentication-with-alternate-github-instances)\n- [Setup and Configuration](#setup-and-configuration)\n  - [panel](#panel)\n  - [suggestion](#suggestion)\n  - [Highlight Groups](#highlight-groups)\n  - [filetypes](#filetypes)\n  - [logger](#logger)\n  - [copilot_node_command](#copilot_node_command)\n  - [server_opts_overrides](#server_opts_overrides)\n  - [workspace_folders](#workspace_folders)\n  - [root_dir](#root_dir)\n  - [should_attach](#should_attach)\n  - [server](#server)\n- [Commands](#commands)\n- [Integrations](#integrations)\n- [FAQ](#faq)\n\n\u003C!--toc:end-->\n\n## Requirements\n\n- Curl\n- NeoVim 0.11.0 or higher\n- NodeJS v22 or higher if using the default nodejs LSP version\n\n## Install\n\nInstall the plugin with your preferred plugin manager.\nFor example, with [packer.nvim](https:\u002F\u002Fgithub.com\u002Fwbthomason\u002Fpacker.nvim):\n\n```lua\nuse { \"zbirenbaum\u002Fcopilot.lua\"\n  requires = {\n    \"copilotlsp-nvim\u002Fcopilot-lsp\", -- (optional) for NES functionality\n  },\n}\n```\n\n### Authentication\n\nYou can authenticate using one of the following methods:\n\n\u003Cdetails>\n\u003Csummary>Permanent sign-in (Recommended)\u003C\u002Fsummary>\n\nOnce copilot is running, run `:Copilot auth` to start the authentication process.\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Token (not officially supported)\u003C\u002Fsummary>\n\nTokens given by `gh auth token` do not support Copilot, you therefore need to first generate a token through the LSP by:\n\n- Authenticating using the `Permanent sign-in` method\n- Grab the token by running `:Copilot auth info`\n- You can then safely delete the `github-copilot` folder created in your NeoVim base data directory.\n\nSet either the environment variable `GITHUB_COPILOT_TOKEN` or `GH_COPILOT_TOKEN` to that token.\nNote that if you have the variable set, even empty, the LSP will attempt to use it to log in.\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Sign out \u002F Switch accounts\u003C\u002Fsummary>\n\nTo sign out of your current GitHub account:\n\n```\n:Copilot auth signout\n```\n\nTo sign in with a different account:\n\n```\n:Copilot auth signin\n```\n\nTo view your current authentication token information:\n\n```\n:Copilot auth info\n```\n\nCredentials are stored in:\n- **Linux\u002FmacOS:** `~\u002F.config\u002Fgithub-copilot\u002Fapps.json` (or `$XDG_CONFIG_HOME\u002Fgithub-copilot\u002Fapps.json`)\n- **Windows:** `~\u002FAppData\u002FLocal\u002Fgithub-copilot\u002Fapps.json`\n\n\u003C\u002Fdetails>\n\n#### Authentication with Alternate GitHub Instances\n\nIf your access to Copilot is not provided by the public GitHub instance, you can set your\nauthentication provider to a custom URL with the corresponding config key e.g.\n`auth_provider_url = \"https:\u002F\u002Fmycorp.ghe.com\u002F\"`.\n\n## Setup and Configuration\n\nYou have to run the `require(\"copilot\").setup(options)` function in order to start Copilot.\nIf no options are provided, the defaults are used.\n\nBecause the copilot server takes some time to start up, it is recommended that you lazy load copilot.\nFor example:\n\n```lua\nuse {\n  \"zbirenbaum\u002Fcopilot.lua\",\n  requires = {\n    \"copilotlsp-nvim\u002Fcopilot-lsp\", -- (optional) for NES functionality\n  },\n  cmd = \"Copilot\",\n  event = \"InsertEnter\",\n  config = function()\n    require(\"copilot\").setup({})\n  end,\n}\n```\n\n\u003Cdetails>\n\u003Csummary>Default configuration\u003C\u002Fsummary>\n\n```lua\nrequire('copilot').setup({\n  panel = {\n    enabled = true,\n    auto_refresh = false,\n    keymap = {\n      jump_prev = \"[[\",\n      jump_next = \"]]\",\n      accept = \"\u003CCR>\",\n      refresh = \"gr\",\n      open = \"\u003CM-CR>\"\n    },\n    layout = {\n      position = \"bottom\", -- | top | left | right | bottom |\n      ratio = 0.4\n    },\n  },\n  suggestion = {\n    enabled = true,\n    auto_trigger = false,\n    hide_during_completion = true,\n    debounce = 15,\n    trigger_on_accept = true,\n    keymap = {\n      accept = \"\u003CM-l>\",\n      accept_word = false,\n      accept_line = false,\n      next = \"\u003CM-]>\",\n      prev = \"\u003CM-[>\",\n      dismiss = \"\u003CC-]>\",\n      toggle_auto_trigger = false,\n    },\n  },\n  nes = {\n    enabled = false, -- requires copilot-lsp as a dependency\n    auto_trigger = false,\n    keymap = {\n      accept_and_goto = false,\n      accept = false,\n      dismiss = false,\n    },\n  },\n  auth_provider_url = nil, -- URL to authentication provider, if not \"https:\u002F\u002Fgithub.com\u002F\"\n  logger = {\n    file = vim.fn.stdpath(\"log\") .. \"\u002Fcopilot-lua.log\",\n    file_log_level = vim.log.levels.OFF,\n    print_log_level = vim.log.levels.WARN,\n    trace_lsp = \"off\", -- \"off\" | \"debug\" | \"verbose\"\n    trace_lsp_progress = false,\n    log_lsp_messages = false,\n  },\n  copilot_node_command = 'node', -- Node.js version must be > 22\n  workspace_folders = {},\n  copilot_model = \"\",\n  disable_limit_reached_message = false,  -- Set to `true` to suppress completion limit reached popup\n  root_dir = function()\n    return vim.fs.dirname(vim.fs.find(\".git\", { upward = true })[1])\n  end,\n  should_attach = function(buf_id, _)\n    if not vim.bo[buf_id].buflisted then\n      logger.debug(\"not attaching, buffer is not 'buflisted'\")\n      return false\n    end\n\n    if vim.bo[buf_id].buftype ~= \"\" then\n      logger.debug(\"not attaching, buffer 'buftype' is \" .. vim.bo[buf_id].buftype)\n      return false\n    end\n\n    return true\n  end,\n  server = {\n    type = \"nodejs\", -- \"nodejs\" | \"binary\"\n    custom_server_filepath = nil,\n  },\n  server_opts_overrides = {},\n})\n```\n\n\u003C\u002Fdetails>\n\n### panel\n\nPanel can be used to preview suggestions in a split window. You can run the\n`:Copilot panel` command to open it.\n\nIf `auto_refresh` is `true`, the suggestions are refreshed as you type in the buffer.\n\nThe `copilot.panel` module exposes the following functions:\n\n```lua\nrequire(\"copilot.panel\").accept()\nrequire(\"copilot.panel\").jump_next()\nrequire(\"copilot.panel\").jump_prev()\nrequire(\"copilot.panel\").open({position, ratio})\nrequire(\"copilot.panel\").close()\nrequire(\"copilot.panel\").toggle()\nrequire(\"copilot.panel\").refresh()\nrequire(\"copilot.panel\").is_open()\n```\nThese can also be accessed through the `:Copilot panel \u003Cfunction>` command (eg. `:Copilot panel accept`).\n\n### suggestion\n\nWhen `auto_trigger` is `true`, copilot starts suggesting as soon as you enter insert mode.\nWhen `auto_trigger` is `false`, use the `next`, `prev` or `accept` keymap to trigger copilot suggestion.\nWhen `trigger_on_accept` is `false`, the keypress will be passed to the buffer as-is, instead of triggering completion.\n\nTo toggle auto trigger for the current buffer, use `require(\"copilot.suggestion\").toggle_auto_trigger()`.\n\nCopilot suggestion is automatically hidden when `popupmenu-completion` is open. In case you use a custom\nmenu for completion, you can set the `copilot_suggestion_hidden` buffer variable to `true` to have the\nsame behavior.\n\n\u003Cdetails>\n\u003Csummary>Example using nvim-cmp\u003C\u002Fsummary>\n\n```lua\ncmp.event:on(\"menu_opened\", function()\n  vim.b.copilot_suggestion_hidden = true\nend)\n\ncmp.event:on(\"menu_closed\", function()\n  vim.b.copilot_suggestion_hidden = false\nend)\n```\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Example using blink.cmp\u003C\u002Fsummary>\n\n```lua\nvim.api.nvim_create_autocmd(\"User\", {\n  pattern = \"BlinkCmpMenuOpen\",\n  callback = function()\n    vim.b.copilot_suggestion_hidden = true\n  end,\n})\n\nvim.api.nvim_create_autocmd(\"User\", {\n  pattern = \"BlinkCmpMenuClose\",\n  callback = function()\n    vim.b.copilot_suggestion_hidden = false\n  end,\n})\n\n```\n\n\u003C\u002Fdetails>\n\nThe `copilot.suggestion` module exposes the following functions:\n\n```lua\nrequire(\"copilot.suggestion\").is_visible()\nrequire(\"copilot.suggestion\").accept(modifier)\nrequire(\"copilot.suggestion\").accept_word()\nrequire(\"copilot.suggestion\").accept_line()\nrequire(\"copilot.suggestion\").next()\nrequire(\"copilot.suggestion\").prev()\nrequire(\"copilot.suggestion\").clear_preview()\nrequire(\"copilot.suggestion\").update_preview()\nrequire(\"copilot.suggestion\").dismiss()\nrequire(\"copilot.suggestion\").toggle_auto_trigger()\n```\nThese can also be accessed through the `:Copilot suggestion \u003Cfunction>` command (eg. `:Copilot suggestion accept`).\n\n### Highlight Groups\n\nCopilot uses two highlight groups to style its suggestions:\n\n| Highlight Group | Used For | Default Link |\n|---|---|---|\n| `CopilotSuggestion` | Inline ghost text suggestions | `Comment` |\n| `CopilotAnnotation` | Annotations in the panel and inline suggestions | `Comment` |\n\nIf these highlight groups are not defined by your colorscheme, they will default to linking to `Comment`. To customize them, set the highlights **after** your colorscheme loads, or use a `ColorScheme` autocmd:\n\n```lua\nvim.api.nvim_create_autocmd(\"ColorScheme\", {\n  callback = function()\n    vim.api.nvim_set_hl(0, \"CopilotSuggestion\", { fg = \"#83a598\", italic = true })\n    vim.api.nvim_set_hl(0, \"CopilotAnnotation\", { fg = \"#83a598\" })\n  end,\n})\n```\n\n### nes (next edit suggestion)\n\n>[!WARNING]\n> This feature is still experimental and may not work as expected in all scenarios, please report any issues you encounter.\n\nWhen `enabled` is `true`, copilot will provide suggestions based on the next edit you are likely to make, through [copilot-lsp](https:\u002F\u002Fgithub.com\u002Fcopilotlsp-nvim\u002Fcopilot-lsp).\nIf there is no suggestion, the keymaps will pass through the original keymap.\n\n`copilot-lsp` has a few configurations built-in as well, for additional configurations, please refer to the [copilot-lsp documentation](https:\u002F\u002Fgithub.com\u002Fcopilotlsp-nvim\u002Fcopilot-lsp\u002Fblob\u002Fmain\u002FREADME.md).\nThese configurations should be set in the `init` function of the `copilot-lsp` dependency.\n\n```lua\nuse {\n  \"zbirenbaum\u002Fcopilot.lua\",\n  requires = {\n    \"copilotlsp-nvim\u002Fcopilot-lsp\",\n    init = function()\n      vim.g.copilot_nes_debounce = 500\n    end,\n  },\n  cmd = \"Copilot\",\n  event = \"InsertEnter\",\n  config = function()\n    require(\"copilot\").setup({\n      nes = {\n        enabled = true,\n        keymap = {\n          accept_and_goto = \"\u003Cleader>p\",\n          accept = false,\n          dismiss = \"\u003CEsc>\",\n        },\n      },\n    })\n  end,\n}\n```\n\n### filetypes\n\nSpecify filetypes for attaching copilot.\n\nExample:\n\n```lua\nrequire(\"copilot\").setup {\n  filetypes = {\n    markdown = true, -- overrides default\n    terraform = false, -- disallow specific filetype\n    sh = function ()\n      if string.match(vim.fs.basename(vim.api.nvim_buf_get_name(0)), '^%.env.*') then\n        -- disable for .env files\n        return false\n      end\n      return true\n    end,\n  },\n}\n```\n\nIf you add `\"*\"` as a filetype, the default configuration for `filetypes` won't be used anymore. e.g.\n\n```lua\nrequire(\"copilot\").setup {\n  filetypes = {\n    javascript = true, -- allow specific filetype\n    typescript = true, -- allow specific filetype\n    [\"*\"] = false, -- disable for all other filetypes and ignore default `filetypes`\n  },\n}\n```\n\n### logger\n\nLogs will be written to the `file` for anything of `file_log_level` or higher.\nLogs will be printed to NeoVim (using `notify`) for anything of `print_log_level` or higher.\nTo turn either off, simply set its level to `vim.log.levels.OFF`.\nFile logging is done asynchronously to minimize performance impacts, however there is still some overhead.\n\nLog levels used are the ones defined in `vim.log`:\n\n```lua\nvim.log = {\n  levels = {\n    TRACE = 0,\n    DEBUG = 1,\n    INFO = 2,\n    WARN = 3,\n    ERROR = 4,\n    OFF = 5,\n  },\n}\n```\n\n`trace_lsp` controls logging of LSP trace messages (`$\u002FlogTrace`) can either be:\n\n- `off`\n- `messages` which will output the LSP messages\n- `verbose` which adds additional information to the message.\n\nWhen `trace_lsp_progress` is true, LSP progress messages (`$\u002Fprogress`) will also be logged.\nWhen `log_lsp_messages` is true, LSP log messages (`window\u002FlogMessage`) events will be logged.\n\nCareful turning on all logging features as the log files may get very large over time, and are not pruned by the application.\n\n### copilot_node_command\n\nUse this field to provide the path to a specific node version such as one installed by nvm. Node.js version must be 22 or newer.\n\nExample:\n\n```lua\ncopilot_node_command = vim.fn.expand(\"$HOME\") .. \"\u002F.config\u002Fnvm\u002Fversions\u002Fnode\u002Fv22.0.0\u002Fbin\u002Fnode\", -- Node.js version must be > 22\n```\n\n### server_opts_overrides\n\nOverride copilot lsp client settings. See `:h vim.lsp.start` for the list of options.\nEnsure that the `name` field is not overridden as it is used for efficiency reasons in numerous checks to verify copilot is actually running.\n\nThe `settings` field is where you can customize the copilot lsp behavior. See [SettingsOpts.md](.\u002FSettingsOpts.md) for the full list of available settings and their keys.\n\nExample:\n\n```lua\nrequire(\"copilot\").setup {\n  server_opts_overrides = {\n    trace = \"verbose\",\n    settings = {\n      advanced = {\n        listCount = 10, -- #completions for panel\n        inlineSuggestCount = 3, -- #completions for getCompletions\n      }\n    },\n  }\n}\n```\n\n> [!NOTE]\n> The `settings` values follow a nested table structure matching the keys in [SettingsOpts.md](.\u002FSettingsOpts.md).\n> For example, `InlineSuggestCount: [\"advanced\", \"inlineSuggestCount\"]` becomes `settings = { advanced = { inlineSuggestCount = 3 } }`.\n\n### workspace_folders\n\nWorkspace folders improve Copilot's suggestions.\nBy default, the root_dir is used as a workspace_folder.\n\nAdditional folders can be added through the configuration as such:\n\n```lua\nworkspace_folders = {\n  \"\u002Fhome\u002Fuser\u002Fgits\",\n  \"\u002Fhome\u002Fuser\u002Fprojects\",\n}\n```\n\nThey can also be added runtime, using the command `:Copilot workspace add [folderpath]` where `[folderpath]` is the workspace folder.\n\n### root_dir\n\nThis allows changing the function that gets the root folder, the default looks for a parent folder that contains the folder `.git`.\nIf none is found, it will use the current working directory.\n\n### should_attach\n\nThis function is called to determine if copilot should attach to the buffer or not.\nIt is useful if you would like to go beyond the filetypes and have more control over when copilot should attach.\nYou can also use it to attach to buflisted buffers by simply omitting that portion from the function.\nSince this happens before attaching to the buffer, it is good to prevent Copilot from reading sensitive files.\n\nAn example of this would be:\n\n```lua\nrequire(\"copilot\").setup {\n  should_attach = function(_, bufname)\n    if string.match(bufname, \"env\") then\n      return false\n    end\n\n    return true\n  end\n}\n```\n\n### server\n\n> [!CAUTION]\n> `\"binary\"` mode is still very much experimental, please report any issues you encounter.\n\n`type` can be either `\"nodejs\"` or `\"binary\"`. The binary version will be downloaded if used.\n\n`custom_server_filepath` is used to specify the server path (filename included) of either the `js` file if using `\"nodejs\"` or to the binary if using `\"binary\"`.\nThe filename on its own can also be set if accessible through your PATH.\nWhen using `\"binary\"`, the download process will be disabled and the binary will be used directly.\nexample:\n\n```lua\nrequire(\"copilot\").setup {\n  server = {\n    type = \"nodejs\",\n    custom_server_filepath = \"\u002Fhome\u002Fuser\u002Fcopilot-lsp\u002Flanguage-server.js\",\n  },\n}\n```\n\n## Commands\n\n`copilot.lua` defines the `:Copilot` command that can perform various actions. It has completion support, so try it out.\n\n## Integrations\n\nThe `copilot.api` module can be used to build integrations on top of `copilot.lua`.\n\n- [zbirenbaum\u002Fcopilot-cmp](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot-cmp): Integration with [`nvim-cmp`](https:\u002F\u002Fgithub.com\u002Fhrsh7th\u002Fnvim-cmp).\n- [giuxtaposition\u002Fblink-cmp-copilot](https:\u002F\u002Fgithub.com\u002Fgiuxtaposition\u002Fblink-cmp-copilot): Integration with [`blink.cmp`](https:\u002F\u002Fgithub.com\u002FSaghen\u002Fblink.cmp).\n- [fang2hou\u002Fblink-copilot](https:\u002F\u002Fgithub.com\u002Ffang2hou\u002Fblink-copilot): Integration with [`blink.cmp`](https:\u002F\u002Fgithub.com\u002FSaghen\u002Fblink.cmp), with some differences.\n- [AndreM222\u002Fcopilot-lualine](https:\u002F\u002Fgithub.com\u002FAndreM222\u002Fcopilot-lualine): Integration with [`lualine.nvim`](https:\u002F\u002Fgithub.com\u002Fnvim-lualine\u002Flualine.nvim).\n\n## FAQ\n\n> Certificate Parsing Error\n\nThis is an issue with the copilot lsp itself as described in [this discussion](https:\u002F\u002Fgithub.com\u002Forgs\u002Fcommunity\u002Fdiscussions\u002F136273#discussioncomment-10433527). Please update the plugin to the latest version to solve this issue.\nIf updating does not help, some users have reported that updating the `\u002Fusr\u002Fbin\u002Fupdate-ca-trust` and removing the --comment option from the trust extract commands solves the issue.\nHowever this has not been verified by the author of this plugin and may have unintended consequences so thread with care.\n\n> Multiple offset encodings warning\n\nAs discussed in #247, the problem arises because two or more clients are using different offset encodings. To solve this, in lspconfig:\n\n```lua\nlocal capabilities = vim.lsp.protocol.make_client_capabilities() -- Get The capabilities\ncapabilities.general.positionEncodings = { \"utf-16\" } -- Set the offset encoding, see `:h vim.lsp.start` for more info\nrequire(\"lspconfig\")[server].setup({ capabilities = capabilities }) -- Setup the server\n```\n\nSet the same for copilot in `server_opts_overrides`:\n\n```lua\nserver_opts_overrides = {\n  offset_encoding = \"utf-16\" -- Set the offset encoding same as above, see `:h vim.lsp.start` for more info\n}\n```\n\nRefer to your plugins documentation for changes.\n","# copilot.lua\n\n此插件是 [github\u002Fcopilot.vim](https:\u002F\u002Fgithub.com\u002Fgithub\u002Fcopilot.vim) 的纯 Lua 替代方案。\n非常感谢 @tris203 提供的 NES 功能背后的代码（[copilot-lsp](https:\u002F\u002Fgithub.com\u002Fcopilotlsp-nvim\u002Fcopilot-lsp)）。\n\n\u003Cdetails>\n\u003Csummary>`copilot.lua` 的开发动机\u003C\u002Fsummary>\n\n在使用 `copilot.vim` 时，自从我开始使用 Neovim 以来，我的笔记本电脑首次出现了过热现象。此外，我发现大量幽灵文本在我的代码中四处移动，干扰了现有的 cmp 幽灵文本，这让我感到非常困扰。由于 Lua 效率更高，并且更容易与现代插件集成，因此创建了这个仓库。\n\n\u003C\u002Fdetails>\n\n## 目录\n\n\u003C!--toc:start-->\n\n- [要求](#requirements)\n- [安装](#install)\n  - [认证](#authentication)\n    - [使用其他 GitHub 实例进行认证](#authentication-with-alternate-github-instances)\n- [设置与配置](#setup-and-configuration)\n  - [面板](#panel)\n  - [建议](#suggestion)\n  - [高亮组](#highlight-groups)\n  - [文件类型](#filetypes)\n  - [日志记录器](#logger)\n  - [copilot_node_command](#copilot_node_command)\n  - [server_opts_overrides](#server_opts_overrides)\n  - [工作区文件夹](#workspace_folders)\n  - [根目录](#root_dir)\n  - [should_attach](#should_attach)\n  - [服务器](#server)\n- [命令](#commands)\n- [集成](#integrations)\n- [常见问题解答](#faq)\n\n\u003C!--toc:end-->\n\n## 要求\n\n- Curl\n- NeoVim 0.11.0 或更高版本\n- 如果使用默认的 Node.js LSP 版本，则需要 NodeJS v22 或更高版本\n\n## 安装\n\n使用你喜欢的插件管理器安装该插件。\n例如，使用 [packer.nvim](https:\u002F\u002Fgithub.com\u002Fwbthomason\u002Fpacker.nvim)：\n\n```lua\nuse { \"zbirenbaum\u002Fcopilot.lua\"\n  requires = {\n    \"copilotlsp-nvim\u002Fcopilot-lsp\", -- (可选) 用于 NES 功能\n  },\n}\n```\n\n### 认证\n\n你可以使用以下方法之一进行认证：\n\n\u003Cdetails>\n\u003Csummary>永久登录（推荐）\u003C\u002Fsummary>\n\nCopilot 运行后，运行 `:Copilot auth` 开始认证过程。\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>Token（非官方支持）\u003C\u002Fsummary>\n\n通过 `gh auth token` 获取的 Token 不支持 Copilot，因此你需要先通过 LSP 生成一个 Token：\n\n- 使用“永久登录”方法进行认证\n- 运行 `:Copilot auth info` 获取 Token\n- 然后可以安全地删除在 Neovim 基础数据目录中创建的 `github-copilot` 文件夹。\n\n将环境变量 `GITHUB_COPILOT_TOKEN` 或 `GH_COPILOT_TOKEN` 设置为该 Token。\n请注意，即使该变量为空，LSP 也会尝试使用它来登录。\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>登出\u002F切换账号\u003C\u002Fsummary>\n\n要登出当前的 GitHub 账号：\n\n```\n:Copilot auth signout\n```\n\n要用另一个账号登录：\n\n```\n:Copilot auth signin\n```\n\n查看当前认证 Token 信息：\n\n```\n:Copilot auth info\n```\n\n凭据存储位置：\n- **Linux\u002FmacOS:** `~\u002F.config\u002Fgithub-copilot\u002Fapps.json`（或 `$XDG_CONFIG_HOME\u002Fgithub-copilot\u002Fapps.json`）\n- **Windows:** `~\u002FAppData\u002FLocal\u002Fgithub-copilot\u002Fapps.json`\n\n\u003C\u002Fdetails>\n\n#### 使用其他 GitHub 实例进行认证\n\n如果你的 Copilot 访问权限不是由公共 GitHub 实例提供的，你可以将认证提供商设置为自定义 URL，并使用相应的配置键，例如：\n`auth_provider_url = \"https:\u002F\u002Fmycorp.ghe.com\u002F\"`。\n\n## 设置与配置\n\n你需要运行 `require(\"copilot\").setup(options)` 函数才能启动 Copilot。\n如果没有提供选项，则使用默认值。\n\n由于 Copilot 服务器需要一些时间才能启动，建议你延迟加载 Copilot。\n例如：\n\n```lua\nuse {\n  \"zbirenbaum\u002Fcopilot.lua\",\n  requires = {\n    \"copilotlsp-nvim\u002Fcopilot-lsp\", -- (可选) 用于 NES 功能\n  },\n  cmd = \"Copilot\",\n  event = \"InsertEnter\",\n  config = function()\n    require(\"copilot\").setup({})\n  end,\n}\n```\n\n\u003Cdetails>\n\u003Csummary>默认配置\u003C\u002Fsummary>\n\n```lua\nrequire('copilot').setup({\n  panel = {\n    enabled = true,\n    auto_refresh = false,\n    keymap = {\n      jump_prev = \"[[\",\n      jump_next = \"]]\",\n      accept = \"\u003CCR>\",\n      refresh = \"gr\",\n      open = \"\u003CM-CR>\"\n    },\n    layout = {\n      position = \"bottom\", -- | top | left | right | bottom |\n      ratio = 0.4\n    },\n  },\n  suggestion = {\n    enabled = true,\n    auto_trigger = false,\n    hide_during_completion = true,\n    debounce = 15,\n    trigger_on_accept = true,\n    keymap = {\n      accept = \"\u003CM-l>\",\n      accept_word = false,\n      accept_line = false,\n      next = \"\u003CM-]>\",\n      prev = \"\u003CM-[>\",\n      dismiss = \"\u003CC-]>\",\n      toggle_auto_trigger = false,\n    },\n  },\n  nes = {\n    enabled = false, -- 需要 copilot-lsp 作为依赖\n    auto_trigger = false,\n    keymap = {\n      accept_and_goto = false,\n      accept = false,\n      dismiss = false,\n    },\n  },\n  auth_provider_url = nil, -- 认证提供商的 URL，如果不是 \"https:\u002F\u002Fgithub.com\u002F\"\n  logger = {\n    file = vim.fn.stdpath(\"log\") .. \"\u002Fcopilot-lua.log\",\n    file_log_level = vim.log.levels.OFF,\n    print_log_level = vim.log.levels.WARN,\n    trace_lsp = \"off\", -- \"off\" | \"debug\" | \"verbose\"\n    trace_lsp_progress = false,\n    log_lsp_messages = false,\n  },\n  copilot_node_command = 'node', -- Node.js 版本必须大于 22\n  workspace_folders = {},\n  copilot_model = \"\",\n  disable_limit_reached_message = false,  -- 设置为 `true` 可以抑制完成次数达到上限的弹出窗口\n  root_dir = function()\n    return vim.fs.dirname(vim.fs.find(\".git\", { upward = true })[1])\n  end,\n  should_attach = function(buf_id, _)\n    if not vim.bo[buf_id].buflisted then\n      logger.debug(\"不附加，缓冲区未列出\")\n      return false\n    end\n\n    if vim.bo[buf_id].buftype ~= \"\" then\n      logger.debug(\"不附加，缓冲区类型为 \" .. vim.bo[buf_id].buftype)\n      return false\n    end\n\n    return true\n  end,\n  server = {\n    type = \"nodejs\", -- \"nodejs\" | \"binary\"\n    custom_server_filepath = nil,\n  },\n  server_opts_overrides = {},\n})\n```\n\n\u003C\u002Fdetails>\n\n### 面板\n\n面板可用于在分屏窗口中预览建议。你可以运行 `:Copilot panel` 命令来打开它。\n\n如果 `auto_refresh` 设置为 `true`, 则会在你输入内容时自动刷新建议。\n\n`copilot.panel` 模块提供了以下函数：\n\n```lua\nrequire(\"copilot.panel\").accept()\nrequire(\"copilot.panel\").jump_next()\nrequire(\"copilot.panel\").jump_prev()\nrequire(\"copilot.panel\").open({position, ratio})\nrequire(\"copilot.panel\").close()\nrequire(\"copilot.panel\").toggle()\nrequire(\"copilot.panel\").refresh()\nrequire(\"copilot.panel\").is_open()\n```\n这些函数也可以通过 `:Copilot panel \u003Cfunction>` 命令访问（例如：`:Copilot panel accept`）。\n\n### 建议\n\n当 `auto_trigger` 为 `true` 时，Copilot 会在您进入插入模式后立即开始提供建议。  \n当 `auto_trigger` 为 `false` 时，您可以使用 `next`、`prev` 或 `accept` 键映射来触发 Copilot 的建议。  \n当 `trigger_on_accept` 为 `false` 时，按键输入将原样传递到缓冲区，而不会触发补全。\n\n要切换当前缓冲区的自动触发功能，可以使用 `require(\"copilot.suggestion\").toggle_auto_trigger()`。\n\n当 `popupmenu-completion` 打开时，Copilot 的建议会自动隐藏。如果您使用自定义的补全菜单，可以通过将 `copilot_suggestion_hidden` 缓冲区变量设置为 `true` 来实现相同的行为。\n\n\u003Cdetails>\n\u003Csummary>使用 nvim-cmp 的示例\u003C\u002Fsummary>\n\n```lua\ncmp.event:on(\"menu_opened\", function()\n  vim.b.copilot_suggestion_hidden = true\nend)\n\ncmp.event:on(\"menu_closed\", function()\n  vim.b.copilot_suggestion_hidden = false\nend)\n```\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>使用 blink.cmp 的示例\u003C\u002Fsummary>\n\n```lua\nvim.api.nvim_create_autocmd(\"User\", {\n  pattern = \"BlinkCmpMenuOpen\",\n  callback = function()\n    vim.b.copilot_suggestion_hidden = true\n  end,\n})\n\nvim.api.nvim_create_autocmd(\"User\", {\n  pattern = \"BlinkCmpMenuClose\",\n  callback = function()\n    vim.b.copilot_suggestion_hidden = false\n  end,\n})\n```\n\n\u003C\u002Fdetails>\n\n`copilot.suggestion` 模块提供了以下函数：\n\n```lua\nrequire(\"copilot.suggestion\").is_visible()\nrequire(\"copilot.suggestion\").accept(modifier)\nrequire(\"copilot.suggestion\").accept_word()\nrequire(\"copilot.suggestion\").accept_line()\nrequire(\"copilot.suggestion\").next()\nrequire(\"copilot.suggestion\").prev()\nrequire(\"copilot.suggestion\").clear_preview()\nrequire(\"copilot.suggestion\").update_preview()\nrequire(\"copilot.suggestion\").dismiss()\nrequire(\"copilot.suggestion\").toggle_auto_trigger()\n```\n这些函数也可以通过 `:Copilot suggestion \u003Cfunction>` 命令访问（例如：`:Copilot suggestion accept`）。\n\n### 高亮组\n\nCopilot 使用两个高亮组来样式化其建议：\n\n| 高亮组 | 用途 | 默认链接 |\n|---|---|---|\n| `CopilotSuggestion` | 行内幽灵文本建议 | `Comment` |\n| `CopilotAnnotation` | 面板和行内建议中的注释 | `Comment` |\n\n如果您的颜色方案未定义这些高亮组，它们将默认链接到 `Comment`。要自定义它们，请在颜色方案加载 **之后** 设置高亮，或使用 `ColorScheme` 自动命令：\n\n```lua\nvim.api.nvim_create_autocmd(\"ColorScheme\", {\n  callback = function()\n    vim.api.nvim_set_hl(0, \"CopilotSuggestion\", { fg = \"#83a598\", italic = true })\n    vim.api.nvim_set_hl(0, \"CopilotAnnotation\", { fg = \"#83a598\" })\n  end,\n})\n```\n\n### nes（下一个编辑建议）\n\n>[!警告]  \n此功能仍处于实验阶段，在某些场景下可能无法正常工作，请报告您遇到的任何问题。\n\n当 `enabled` 为 `true` 时，Copilot 将通过 [copilot-lsp](https:\u002F\u002Fgithub.com\u002Fcopilotlsp-nvim\u002Fcopilot-lsp) 根据您接下来可能进行的编辑提供建议。如果没有建议，键映射将直接传递原始按键。\n\n`copilot-lsp` 还内置了一些配置项，更多配置请参考 [copilot-lsp 文档](https:\u002F\u002Fgithub.com\u002Fcopilotlsp-nvim\u002Fcopilot-lsp\u002Fblob\u002Fmain\u002FREADME.md)。这些配置应在 `copilot-lsp` 依赖的 `init` 函数中设置。\n\n```lua\nuse {\n  \"zbirenbaum\u002Fcopilot.lua\",\n  requires = {\n    \"copilotlsp-nvim\u002Fcopilot-lsp\",\n    init = function()\n      vim.g.copilot_nes_debounce = 500\n    end,\n  },\n  cmd = \"Copilot\",\n  event = \"InsertEnter\",\n  config = function()\n    require(\"copilot\").setup({\n      nes = {\n        enabled = true,\n        keymap = {\n          accept_and_goto = \"\u003Cleader>p\",\n          accept = false,\n          dismiss = \"\u003CEsc>\",\n        },\n      },\n    })\n  end,\n}\n```\n\n### 文件类型\n\n指定要附加 Copilot 的文件类型。\n\n示例：\n\n```lua\nrequire(\"copilot\").setup {\n  filetypes = {\n    markdown = true, -- 覆盖默认值\n    terraform = false, -- 禁用特定文件类型\n    sh = function ()\n      if string.match(vim.fs.basename(vim.api.nvim_buf_get_name(0)), '^%.env.*') then\n        -- 对 .env 文件禁用\n        return false\n      end\n      return true\n    end,\n  },\n}\n```\n\n如果您添加 `\"*\"` 作为文件类型，则不再使用 `filetypes` 的默认配置。例如：\n\n```lua\nrequire(\"copilot\").setup {\n  filetypes = {\n    javascript = true, -- 允许特定文件类型\n    typescript = true, -- 允许特定文件类型\n    [\"*\"] = false, -- 禁用所有其他文件类型，并忽略默认的 `filetypes`\n  },\n}\n```\n\n### 日志记录\n\n日志级别达到或高于 `file_log_level` 的内容将被写入 `file`。  \n日志级别达到或高于 `print_log_level` 的内容将通过 NeoVim 的 `notify` 功能打印出来。  \n要关闭其中任一项，只需将其级别设置为 `vim.log.levels.OFF`。  \n文件日志是异步进行的，以尽量减少对性能的影响，但仍会带来一定的开销。\n\n日志级别采用 `vim.log` 中定义的级别：\n\n```lua\nvim.log = {\n  levels = {\n    TRACE = 0,\n    DEBUG = 1,\n    INFO = 2,\n    WARN = 3,\n    ERROR = 4,\n    OFF = 5,\n  },\n}\n```\n\n`trace_lsp` 控制 LSP 跟踪消息（`$\u002FlogTrace`）的日志记录，可设置为：\n\n- `off`\n- `messages`：输出 LSP 消息\n- `verbose`：在消息中添加更多信息。\n\n当 `trace_lsp_progress` 为 `true` 时，LSP 进度消息（`$\u002Fprogress`）也会被记录。  \n当 `log_lsp_messages` 为 `true` 时，LSP 日志消息（`window\u002FlogMessage`）事件会被记录。\n\n请注意，开启所有日志功能可能会导致日志文件随着时间推移变得非常庞大，且应用程序不会对其进行清理。\n\n### copilot_node_command\n\n使用此字段指定特定 Node.js 版本的路径，例如由 nvm 安装的版本。Node.js 版本必须为 22 或更高。\n\n示例：\n\n```lua\ncopilot_node_command = vim.fn.expand(\"$HOME\") .. \"\u002F.config\u002Fnvm\u002Fversions\u002Fnode\u002Fv22.0.0\u002Fbin\u002Fnode\", -- Node.js 版本必须 > 22\n```\n\n### server_opts_overrides\n\n覆盖 Copilot LSP 客户端设置。有关选项列表，请参阅 `:h vim.lsp.start`。  \n请确保不要覆盖 `name` 字段，因为该字段用于效率优化，在多项检查中用于验证 Copilot 是否正在运行。\n\n`settings` 字段可用于自定义 Copilot LSP 的行为。完整可用设置及其键名请参阅 [SettingsOpts.md](.\u002FSettingsOpts.md)。\n\n示例：\n\n```lua\nrequire(\"copilot\").setup {\n  server_opts_overrides = {\n    trace = \"verbose\",\n    settings = {\n      advanced = {\n        listCount = 10, -- 面板中的补全数量\n        inlineSuggestCount = 3, -- getCompletions 中的补全数量\n      }\n    },\n  }\n}\n```\n\n> [!注意]  \n`settings` 的值遵循与 [SettingsOpts.md](.\u002FSettingsOpts.md) 中键名匹配的嵌套表结构。  \n例如，`InlineSuggestCount: [\"advanced\", \"inlineSuggestCount\"]` 将变为 `settings = { advanced = { inlineSuggestCount = 3 } }`。\n\n### workspace_folders\n\n工作区文件夹可以提升 Copilot 的代码建议质量。\n默认情况下，`root_dir` 会被用作 `workspace_folder`。\n\n可以通过配置添加额外的文件夹，如下所示：\n\n```lua\nworkspace_folders = {\n  \"\u002Fhome\u002Fuser\u002Fgits\",\n  \"\u002Fhome\u002Fuser\u002Fprojects\",\n}\n```\n\n也可以在运行时通过命令 `:Copilot workspace add [folderpath]` 添加，其中 `[folderpath]` 是要添加的工作区文件夹路径。\n\n### root_dir\n\n此选项允许更改用于获取根目录的函数。默认行为是查找包含 `.git` 文件夹的父目录；如果未找到，则使用当前工作目录。\n\n### should_attach\n\n此函数用于决定 Copilot 是否应附加到当前缓冲区。如果你希望超越仅基于文件类型的判断，而对 Copilot 的附加时机有更精细的控制，这个选项会非常有用。你还可以通过省略该函数中的相关部分，使 Copilot 附加到已列出的缓冲区。由于此检查发生在 Copilot 附加到缓冲区之前，因此可以有效防止 Copilot 读取敏感文件。\n\n例如：\n\n```lua\nrequire(\"copilot\").setup {\n  should_attach = function(_, bufname)\n    if string.match(bufname, \"env\") then\n      return false\n    end\n\n    return true\n  end\n}\n```\n\n### server\n\n> [!CAUTION]\n> `\"binary\"` 模式目前仍处于实验阶段，请报告你遇到的任何问题。\n\n`type` 可以是 `\"nodejs\"` 或 `\"binary\"`。如果选择 `\"binary\"`，系统将自动下载对应的二进制文件。\n\n`custom_server_filepath` 用于指定服务器路径（包括文件名），如果是 `\"nodejs\"` 模式，则指向 JavaScript 文件；如果是 `\"binary\"` 模式，则指向二进制文件。如果该文件可通过你的 PATH 访问，也可以直接指定文件名。\n\n当使用 `\"binary\"` 模式时，下载过程将被禁用，直接使用二进制文件。示例：\n\n```lua\nrequire(\"copilot\").setup {\n  server = {\n    type = \"nodejs\",\n    custom_server_filepath = \"\u002Fhome\u002Fuser\u002Fcopilot-lsp\u002Flanguage-server.js\",\n  },\n}\n```\n\n## 命令\n\n`copilot.lua` 定义了 `:Copilot` 命令，可用于执行各种操作。该命令支持自动补全，请尝试使用。\n\n## 集成\n\n`copilot.api` 模块可用于在 `copilot.lua` 的基础上构建集成。\n\n- [zbirenbaum\u002Fcopilot-cmp](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot-cmp)：与 [`nvim-cmp`](https:\u002F\u002Fgithub.com\u002Fhrsh7th\u002Fnvim-cmp) 的集成。\n- [giuxtaposition\u002Fblink-cmp-copilot](https:\u002F\u002Fgithub.com\u002Fgiuxtaposition\u002Fblink-cmp-copilot)：与 [`blink.cmp`](https:\u002F\u002Fgithub.com\u002FSaghen\u002Fblink.cmp) 的集成。\n- [fang2hou\u002Fblink-copilot](https:\u002F\u002Fgithub.com\u002Ffang2hou\u002Fblink-copilot)：与 [`blink.cmp`](https:\u002F\u002Fgithub.com\u002FSaghen\u002Fblink.cmp) 的集成，但有一些差异。\n- [AndreM222\u002Fcopilot-lualine](https:\u002F\u002Fgithub.com\u002FAndreM222\u002Fcopilot-lualine)：与 [`lualine.nvim`](https:\u002F\u002Fgithub.com\u002Fnvim-lualine\u002Flualine.nvim) 的集成。\n\n## 常见问题解答\n\n> 证书解析错误\n\n这是 Copilot LSP 本身的问题，详情请参阅 [此讨论](https:\u002F\u002Fgithub.com\u002Forgs\u002Fcommunity\u002Fdiscussions\u002F136273#discussioncomment-10433527)。请将插件更新至最新版本以解决此问题。如果更新后问题仍未解决，有用户反馈称更新 `\u002Fusr\u002Fbin\u002Fupdate-ca-trust` 并移除信任提取命令中的 `--comment` 选项可以解决问题。不过，此方法尚未经过本插件作者验证，可能存在意外后果，请谨慎操作。\n\n> 多个偏移编码警告\n\n如 #247 中所述，该问题出现的原因是两个或多个客户端使用了不同的偏移编码。要解决这个问题，在 lspconfig 中进行如下设置：\n\n```lua\nlocal capabilities = vim.lsp.protocol.make_client_capabilities() -- 获取能力\ncapabilities.general.positionEncodings = { \"utf-16\" } -- 设置偏移编码，更多信息请参考 `:h vim.lsp.start`\nrequire(\"lspconfig\")[server].setup({ capabilities = capabilities }) -- 设置服务器\n```\n\n同样地，在 Copilot 的 `server_opts_overrides` 中也进行设置：\n\n```lua\nserver_opts_overrides = {\n  offset_encoding = \"utf-16\" -- 设置与上述相同的偏移编码，更多信息请参考 `:h vim.lsp.start`\n}\n```\n\n具体操作请参考你的插件文档。","# copilot.lua 快速上手指南\n\n`copilot.lua` 是 `github\u002Fcopilot.vim` 的纯 Lua 重构版本，专为 Neovim 设计。相比原版，它性能更高、发热更低，且能更好地与现代插件（如 cmp）集成，避免幽灵文本冲突。\n\n## 环境准备\n\n在开始之前，请确保您的系统满足以下要求：\n\n*   **Neovim**: 版本 0.11.0 或更高。\n*   **Curl**: 用于网络请求。\n*   **Node.js**: 若使用默认的 Node.js LSP 版本，需安装 v22 或更高版本。\n    *   *国内用户提示*：建议使用 `nvm` 管理 Node 版本，或通过国内镜像源（如淘宝镜像）安装，以避免下载超时。\n\n## 安装步骤\n\n推荐使用插件管理器进行安装。以下以 `lazy.nvim` 和 `packer.nvim` 为例。\n\n### 1. 配置插件管理器\n\n**使用 lazy.nvim:**\n\n```lua\n{\n  \"zbirenbaum\u002Fcopilot.lua\",\n  cmd = \"Copilot\",\n  event = \"InsertEnter\", -- 建议在进入插入模式时懒加载\n  dependencies = {\n    \"copilotlsp-nvim\u002Fcopilot-lsp\", -- 可选：用于 NES (Next Edit Suggestion) 功能\n  },\n  config = function()\n    require(\"copilot\").setup({})\n  end,\n}\n```\n\n**使用 packer.nvim:**\n\n```lua\nuse {\n  \"zbirenbaum\u002Fcopilot.lua\",\n  requires = {\n    \"copilotlsp-nvim\u002Fcopilot-lsp\", -- 可选\n  },\n  cmd = \"Copilot\",\n  event = \"InsertEnter\",\n  config = function()\n    require(\"copilot\").setup({})\n  end,\n}\n```\n\n### 2. 身份认证\n\n安装完成后，重启 Neovim 并执行以下命令进行登录：\n\n```vim\n:Copilot auth\n```\n\n系统将引导您完成浏览器验证流程。验证成功后，凭证将自动保存在本地配置目录中。\n\n*   **切换账号\u002F登出**: `:Copilot auth signout`\n*   **查看认证信息**: `:Copilot auth info`\n*   **自定义 GitHub 实例**: 如果您使用的是企业版 GitHub，可在 setup 配置中设置 `auth_provider_url = \"https:\u002F\u002Fyour-corp.ghe.com\u002F\"`。\n\n## 基本使用\n\n### 默认行为\n\n安装并认证成功后，`copilot.lua` 即可工作：\n\n*   **幽灵文本建议**：在插入模式下，代码建议会以灰色幽灵文本形式显示。\n*   **接受建议**：默认按键为 `\u003CM-l>` (Alt + l)。\n*   **切换建议**：使用 `\u003CM-]>` (下一个) 或 `\u003CM-[>` (上一个)。\n*   **拒绝建议**：继续正常打字或按 `\u003CC-]>`  dismiss。\n\n### 面板模式 (Panel Mode)\n\n如果您更喜欢在侧边栏预览多个建议方案，可以使用面板模式：\n\n1.  打开面板：\n    ```vim\n    :Copilot panel\n    ```\n2.  在面板中使用快捷键：\n    *   `]]` \u002F `[[` : 跳转下一条\u002F上一条建议\n    *   `\u003CCR>` : 接受当前选中的建议\n    *   `gr` : 刷新建议\n\n### 基础配置示例\n\n您可以将以下配置放入 `init.lua` 或专门的配置文件中，以自定义按键映射和行为：\n\n```lua\nrequire(\"copilot\").setup({\n  suggestion = {\n    enabled = true,\n    auto_trigger = false, -- 设为 true 可进入插入模式即自动触发\n    keymap = {\n      accept = \"\u003CM-l>\",       -- 接受整行建议\n      accept_word = false,    -- 接受单词 (可自定义按键)\n      accept_line = false,    -- 接受单行 (可自定义按键)\n      next = \"\u003CM-]>\",         -- 下一条建议\n      prev = \"\u003CM-[>\",         -- 上一条建议\n      dismiss = \"\u003CC-]>\",      -- 关闭建议\n    },\n  },\n  panel = {\n    enabled = true,\n    keymap = {\n      jump_prev = \"[[\",\n      jump_next = \"]]\",\n      accept = \"\u003CCR>\",\n      open = \"\u003CM-CR>\"\n    },\n  },\n  -- 自定义高亮组 (可选)\n  -- 建议在 colorscheme 加载后设置\n})\n```\n\n### 与其他补全插件集成 (如 nvim-cmp)\n\n为了避免 Copilot 的幽灵文本与 cmp 的弹出菜单冲突，可以添加以下自动命令：\n\n```lua\ncmp.event:on(\"menu_opened\", function()\n  vim.b.copilot_suggestion_hidden = true\nend)\n\ncmp.event:on(\"menu_closed\", function()\n  vim.b.copilot_suggestion_hidden = false\nend)\n```\n\n现在您已经完成了 `copilot.lua` 的基础配置，可以开始享受高效的 AI 编码辅助了。","一位后端工程师正在使用 Neovim 重构一个高并发的微服务模块，需要频繁编写复杂的异步逻辑和样板代码。\n\n### 没有 copilot.lua 时\n- 笔记本风扇狂转甚至过热降频，因为原版 `copilot.vim` 基于 Vimscript 运行效率低下，严重拖慢编辑器响应。\n- 屏幕上的灰色幽灵文本（Ghost Text）大块闪烁且位置跳动，经常遮挡视线，干扰现有的自动补全插件显示。\n- 难以与现代 Lua 编写的插件生态深度集成，无法灵活定制建议面板或调整高亮样式，工作流显得割裂。\n- 每次启动项目时 Copilot 服务加载缓慢，导致进入编码状态前需要无谓等待，打断心流。\n\n### 使用 copilot.lua 后\n- 设备运行冷静流畅，纯 Lua 重写的高性能内核消除了资源瓶颈，让老款笔记本也能轻松承载实时 AI 辅助。\n- 幽灵文本渲染稳定且柔和，不再与 cmp 等补全插件冲突，代码预览清晰自然，阅读体验大幅提升。\n- 通过丰富的 API 轻松将 Copilot 融入现有配置，自定义了专属的建议面板和高亮主题，实现了无缝的工作流整合。\n- 支持懒加载机制，仅在输入时唤醒服务，显著缩短了启动时间，确保开发者能即刻进入专注编码状态。\n\ncopilot.lua 通过极致的性能优化和现代化的架构设计，将 GitHub Copilot 从一个消耗资源的负担转变为 Neovim 中丝滑高效的智能编程伙伴。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fzbirenbaum_copilot.lua_fd10ffcf.png","zbirenbaum","Zach Birenbaum","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Fzbirenbaum_66261f77.png","Veteran of the editor wars","CoreWeave","San Francisco, CA","zacharyobirenbaum@gmail.com",null,"https:\u002F\u002Fgithub.com\u002Fzbirenbaum",[85,89,93,97,101],{"name":86,"color":87,"percentage":88},"Lua","#000080",97.7,{"name":90,"color":91,"percentage":92},"PowerShell","#012456",1.4,{"name":94,"color":95,"percentage":96},"JavaScript","#f1e05a",0.5,{"name":98,"color":99,"percentage":100},"Makefile","#427819",0.3,{"name":102,"color":103,"percentage":104},"Shell","#89e051",0,4042,155,"2026-04-07T20:16:27","MIT","Linux, macOS, Windows","未说明",{"notes":112,"python":113,"dependencies":114},"该工具是纯 Lua 编写的 Neovim 插件，无需 Python 环境。若使用默认的 Node.js LSP 版本，需安装 Node.js v22 或更高版本。支持通过永久登录或令牌方式进行 GitHub 认证。可选依赖 'copilot-lsp' 以启用实验性的下一编辑建议 (NES) 功能。","不需要",[115,116,117],"NeoVim >= 0.11.0","NodeJS >= v22","Curl",[15,54,25],[120,121,122,123,124,125],"copilot","github-copilot","lsp-server","lua","neovim","nvim-cmp","2026-03-27T02:49:30.150509","2026-04-08T19:00:03.916585",[129,134,139,144,149,154],{"id":130,"question_zh":131,"answer_zh":132,"source_url":133},24899,"为什么每次启动 Neovim 都需要手动运行 `:Copilot toggle` 才能启用插件？","这是一个已知的行为变更。维护者已提交新代码将默认行为更改为“自动附加”（auto-attach）。如果您遇到此问题，请确保更新到最新版本的 copilot.lua。更新后，插件应在启动时自动激活，无需手动切换。如果仍有问题，可以检查配置中是否限制了自动附加的行为。","https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F547",{"id":135,"question_zh":136,"answer_zh":137,"source_url":138},24900,"遇到 'Agent service not initialized' 错误怎么办？","该错误通常与 Node.js 版本兼容性或特定发行版环境有关。解决方案包括：\n1. 降级 Node.js 版本：有用户反馈将 Node.js 从 24.x 降级到 22.21.0 后问题解决。\n2. 回退插件版本：尝试回退到之前的稳定提交（例如 `30b98a4c25d6152c14084020f703b6d56e1f1122`）。\n3. 环境差异：在某些精简版 Linux 发行版（如 Alpine WSL）上可能出现此问题，建议在 Ubuntu 等标准环境下测试或重新安装插件。","https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F321",{"id":140,"question_zh":141,"answer_zh":142,"source_url":143},24901,"LSP 服务器下载失败，提示 'Cookies must be enabled to use GitHub' 如何解决？","这通常是因为自动下载二进制文件时被 GitHub 的反爬虫机制拦截，导致下载的文件实际上是 HTML 错误页面而非二进制包。\n解决方案：\n1. 暂时使用 Node.js 版本：目前默认推荐使用 Node.js 版本而非二进制版本，可在配置中指定 `server = { type = \"nodejs\" }`（如果支持）。\n2. 手动指定路径：如果您已通过其他包管理器（如 Nixpkgs）安装了 `copilot-language-server`，可以使用 `custom_server_path` 选项指向该二进制文件，避免插件自动下载。\n3. 等待修复：维护者表示二进制下载问题较为复杂，建议优先使用 Node.js 版本或手动管理二进制文件。","https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F408",{"id":145,"question_zh":146,"answer_zh":147,"source_url":148},24902,"启动时出现 'error starting LSP client: nil' 错误如何修复？","此问题可能与插件的懒加载（lazy loading）配置冲突有关。\n解决方案：\n1. 移除懒加载：尝试在插件配置中移除 `event` 或 `cmd` 等懒加载触发条件，让插件在启动时直接加载。\n2. 检查分支：确保您使用的是 `master` 分支而非 `beta` 分支，或者反之，不同分支在不同 Neovim 版本（如 0.10 vs 0.11）上的表现可能不同。\n3. 更新插件：维护者近期修改了加载逻辑，更新至最新版本可能已解决该问题。","https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F428",{"id":150,"question_zh":151,"answer_zh":152,"source_url":153},24903,"自定义按键映射（如 `accept_line`, `accept_word`）突然失效了怎么办？","这通常是由于插件更新引入了破坏性变更或 Bug。\n解决方案：\n1. 回退版本：暂时回退到上一个正常工作的提交版本（例如 `f7732213e41995439171f35bdd2bf1c809f8e8e7`）。\n2. 检查配置语法：确认您的配置中 `keymap` 部分没有使用已被废弃的选项。\n3. 关注修复：查看 Issue 评论区是否有社区提供的临时补丁（diff），应用该补丁或等待官方发布修复版本。","https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F577",{"id":155,"question_zh":156,"answer_zh":157,"source_url":143},24904,"如何在 NixOS 或其他包管理环境中配置 copilot.lua 以避免重复下载？","如果您使用 Nixpkgs 或其他包管理器已经安装了 `copilot-language-server`，可以通过配置 `custom_server_path` 来复用系统已有的二进制文件，从而跳过插件的自动下载步骤。\n注意：目前的 `custom_server_path` 可能需要绝对路径。社区建议改进验证逻辑以支持直接从 `$PATH` 中查找二进制文件。在此之前，您可能需要手动获取二进制文件的绝对路径并填入配置。",[159,164],{"id":160,"version":161,"summary_zh":162,"released_at":163},154388,"v2.0.1","## [2.0.1](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcompare\u002Fv2.0.0...v2.0.1) (2026-03-24)\n\n\n### 错误修复\n\n* 防止孤悬的 Copilot 服务器出现（[8e2a918](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002F8e2a91828210d6043744468f6d7027d256a41f42)），关闭 [#667](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F667)\n* Tab 键透传（[9204088](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002F9204088a47485f06a59f73cfa8dcf3d542dac4d8)），关闭 [#670](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F670)","2026-03-24T01:08:59",{"id":165,"version":166,"summary_zh":167,"released_at":168},154389,"v2.0.0","## [2.0.0](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcompare\u002Fv1.0.0...v2.0.0) (2026-03-06)\n\n\n### ⚠ 破坏性变更\n\n* 按照预告移除对 Neovim 0.10 的支持\n* 提高 LSP 依赖的 Node.js 版本要求\n* 大幅重写项目结构\n* 移除已弃用的函数和配置，要求使用 Neovim 0.10 或更高版本\n\n### 新特性\n\n* 可在 JavaScript（默认）和二进制服务器类型之间切换 ([f96d8e6](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002Ff96d8e6d8f1a2de565657b6f4cd184c38a97e56d))\n* 添加 `Copilot panel close` 和 `is_open` 命令 ([fc5d6a1](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002Ffc5d6a12968aadd334d66d5d8f558020d85a7373))，关闭 [#241](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F241)\n* 添加包含缓冲区逻辑的默认 `should_attach` 函数 ([99654fe](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002F99654fe9ad6cb2500c66b178a03326f75c95f176))，关闭 [#279](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F279) 和 [#239](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F239)\n* 添加使用环境变量进行认证的功能 ([d296017](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002Fd296017e588215df3f7b5796d1172f0d690fa13c))，关闭 [#316](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F316)\n* 添加设置自定义 Copilot 二进制文件的功能 ([0e3585b](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002F0e3585bb9d482336aeb43811e9d7cd09e33edada))，关闭 [#407](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F407)\n* 添加切换面板显示状态的功能 ([865f40f](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002F865f40fb4e9dfe037ab01b144e6448bfd13f4bb0))\n* 在应用建议前添加撤销断点 ([d661d65](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002Fd661d65b4cab20a5c164f6d9081d91ed324fe4d8))，关闭 [#235](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F235)\n* 在 `:Copilot toggle` 中添加强制启用指令 ([dd79629](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002Fdd79629280b36f067c540d752595fa46bd6e2d76))\n* 为建议添加 `has_next()` 函数 ([0753a44](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002F0753a440b0eed13ff32366ef5e21c215012fd1d8))\n* 将日志文件路径添加到 `:checkhealth` 中 ([4c98663](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002F4c98663ba12db653bc1127ed4c124cdde89f8ca8))\n* 添加日志记录器，并将现有打印和通知重定向到该记录器中 ([#383](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F383)) ([256393d](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002F256393d0737741c460726716cac3a605c45d1c3f))，关闭 [#356](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F356)\n* 添加抑制“达到限制”弹出窗口的选项 ([#528](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F528)) ([4869bff](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002F4869bff01618750d9f15bc9868234e9a400f88b2))，关闭 [#349](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fissues\u002F349)\n* 添加 `should_attach` 函数 ([4a557e7](https:\u002F\u002Fgithub.com\u002Fzbirenbaum\u002Fcopilot.lua\u002Fcommit\u002F4a557e74514fd5918e8aabb55b8cfd10535a9a33))，关闭 [#74](https:\u002F\u002Fgithub.com\u002Fzbire","2026-03-06T00:14:50"]