Skip to content

Neovim 插件

MyDeskBot Neovim 插件为 Vim/Neovim 用户带来强大的 AI 辅助开发能力。

目录

功能特性

核心功能

  • 智能补全 - 集成 nvim-cmp 的智能补全
  • 代码生成 - 自然语言生成代码
  • 代码审查 - 快速代码质量检查
  • 代码解释 - 理解复杂代码
  • 文档生成 - 自动生成注释

Neovim 特有功能

  • 🌟 终端集成 - 在终端中与 AI 对话
  • 🌟 浮动窗口 - 优雅的浮动窗口界面
  • 🌟 LSP 集成 - 与 Language Server Protocol 集成
  • 🌟 异步执行 - 不阻塞编辑的异步操作
  • 🌟 高度可配置 - Lua 配置完全可定制

安装

前置要求

  • Neovim 0.9.0 或更高版本
  • nvim-lspconfig (推荐)
  • nvim-cmp (用于补全功能)
  • plenary.nvim (必需依赖)
  • nui.nvim (UI 组件)

使用 packer.nvim

lua
use {
  'mydeskbot/mydeskbot.nvim',
  requires = {
    'nvim-lua/plenary.nvim',
    'MunifTanjim/nui.nvim',
    -- 可选:用于补全
    'hrsh7th/nvim-cmp',
  },
  config = function()
    require('mydeskbot').setup({})
  end
}

使用 lazy.nvim

lua
{
  'mydeskbot/mydeskbot.nvim',
  dependencies = {
    'nvim-lua/plenary.nvim',
    'MunifTanjim/nui.nvim',
    'hrsh7th/nvim-cmp',
  },
  config = function()
    require('mydeskbot').setup({})
  end
}

使用 vim-plug

vim
Plug 'nvim-lua/plenary.nvim'
Plug 'MunifTanjim/nui.nvim'
Plug 'mydeskbot/mydeskbot.nvim'

" 在 init.vim 中配置
lua << EOF
require('mydeskbot').setup({})
EOF

快速开始

1. 基础配置

lua
-- init.lua
require('mydeskbot').setup({
  api_key = 'sk-your-api-key-here',
  model = 'gpt-4',
})

2. API 密钥安全

推荐方式:使用环境变量

bash
# 在 ~/.bashrc 或 ~/.zshrc 中添加
export MYDESKBOT_API_KEY="sk-your-api-key-here"
lua
-- init.lua
require('mydeskbot').setup({
  api_key = os.getenv('MYDESKBOT_API_KEY'),
  model = 'gpt-4',
})

3. 第一次使用

  1. 打开 Neovim
  2. 编辑一个文件(或创建新文件)
  3. 在 Normal 模式下按 <leader>ma 打开 Chat 面板
  4. 输入:"帮我创建一个 Python 函数来计算斐波那契数列"
  5. 查看生成的代码
  6. 使用 :MyDeskBotApply 应用代码

使用指南

Chat 对话

打开 Chat

  • 命令: :MyDeskBotChat
  • 快捷键: <leader>ma (需要配置)
  • Lua: require('mydeskbot.chat').open()

Chat 窗口操作

vim
" 在 Chat 窗口中
<Enter>     - 发送消息
<C-c>       - 取消当前请求
<Esc>       - 关闭窗口
q           - 关闭窗口

示例对话

你: 创建一个 Rust 结构体表示用户信息

MyDeskBot: 这是用户结构体:

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct User {
    pub id: Uuid,
    pub username: String,
    pub email: String,
    pub created_at: DateTime<Utc>,
    pub updated_at: Option<DateTime<Utc>>,
}

impl User {
    pub fn new(username: String, email: String) -> Self {
        let now = Utc::now();
        Self {
            id: Uuid::new_v4(),
            username,
            email,
            created_at: now,
            updated_at: None,
        }
    }
}

代码生成

命令生成

vim
" Visual 模式选中代码
:MyDeskBotGenerate 创建一个排序函数

Lua API

lua
-- 在 Lua 脚本中使用
local mydeskbot = require('mydeskbot')

-- 生成代码
mydeskbot.generate({
  prompt = "创建一个 React 组件",
  callback = function(code)
    -- 处理生成的代码
    print(code)
  end
})

代码审查

触发审查

vim
" Normal 模式:审查当前行
:MyDeskBotReview

" Visual 模式:审查选中的代码块
:MyDeskBotReview

" Lua 调用
require('mydeskbot').review()

审查结果

审查结果会在浮动窗口中显示:

===============================================
代码审查结果
===============================================

🔴 高优先级问题:

1. 空指针风险 (line 23)
   问题:user.getName() 可能为 null
   建议:添加 Optional 处理

💡 改进建议:

1. 性能优化 (line 45-52)
   建议:使用 StringBuilder 替代字符串连接

2. 代码风格 (line 67)
   建议:函数名应使用 camelCase
===============================================

代码解释

解释代码

vim
" 选中代码
:MyDeskBotExplain

示例

选中这段代码:

python
def memoize(func):
    cache = {}
    def wrapper(*args):
        if args not in cache:
            cache[args] = func(*args)
        return cache[args]
    return wrapper

解释结果:

这是一个装饰器函数,用于实现函数结果缓存(记忆化)。

工作原理:
1. 创建一个空字典 cache 来存储缓存结果
2. 定义内部函数 wrapper,它接收任意参数
3. 如果参数已存在于 cache 中,直接返回缓存结果
4. 如果参数不存在,调用原函数并将结果存入 cache
5. 返回 wrapper 函数作为装饰器

效果:被装饰的函数会缓存其调用结果,对于相同参数的调用
      直接返回缓存值,避免重复计算,提高性能。

文档生成

生成文档

vim
" Normal 模式:为当前函数生成文档
:MyDeskbotDoc

" Visual 模式:为选中代码生成文档
:MyDeskbotDoc

生成示例

输入函数:

lua
function calculate_discount(price, quantity)
  if quantity > 10 then
    return price * 0.9
  else
    return price
  end
end

生成的文档:

lua
--- 计算折扣后的价格
-- @param price number 原始价格
-- @param quantity number 购买数量
-- @return number 折扣后的价格
--
-- 当购买数量超过 10 时,给予 10% 的折扣
--
-- @example
-- local discounted = calculate_discount(100, 15)  -- 返回 90
function calculate_discount(price, quantity)
  if quantity > 10 then
    return price * 0.9
  else
    return price
  end
end

终端集成

在终端中使用

vim
:MyDeskBotTerminal

这会打开一个交互式终端,您可以像在命令行中使用 AI 助手一样对话。

示例

$ mydeskbot

> 如何在 Vim 中快速跳转到函数定义?
您可以使用以下方法跳转到函数定义:

1. 如果配置了 LSP:
   - gd  跳转到定义
   - gD  跳转到声明

2. 使用 ctags:
   - Ctrl+]  跳转到标签
   - Ctrl+T  返回

3. 使用内置搜索:
   - :grep /pattern/
   - :cnext  跳转到下一个结果

> 继续询问...

配置

基础配置

lua
require('mydeskbot').setup({
  -- API 密钥(推荐使用环境变量)
  api_key = os.getenv('MYDESKBOT_API_KEY'),

  -- 模型选择
  model = 'gpt-4',

  -- API 基础 URL
  api_base = 'https://api.openai.com/v1',
})

完整配置示例

lua
require('mydeskbot').setup({
  -- API 设置
  api_key = os.getenv('MYDESKBOT_API_KEY'),
  api_base = 'https://api.openai.com/v1',
  model = 'gpt-4',
  temperature = 0.7,
  max_tokens = 2000,

  -- UI 设置
  ui = {
    -- Chat 窗口设置
    chat = {
      width = 80,
      height = 20,
      border = 'rounded',  -- 'single', 'double', 'rounded', 'none'
      position = 'right',  -- 'left', 'right', 'bottom', 'top'
    },

    -- 浮动窗口设置
    float = {
      border = 'rounded',
      padding = { 1, 2, 1, 2 },
    },

    -- 主题
    theme = 'dark',
  },

  -- 补全设置
  completion = {
    enabled = true,
    model = 'gpt-3.5-turbo',
    max_suggestions = 3,
    debounce = 200,
  },

  -- 上下文设置
  context = {
    max_files = 5,
    max_lines = 500,
    exclude_patterns = {
      'node_modules',
      '.git',
      'dist',
      'build',
    },
  },

  -- 代理设置
  proxy = {
    enabled = false,
    host = '127.0.0.1',
    port = 7890,
  },

  -- 行为设置
  behavior = {
    auto_trigger = false,
    show_inline = true,
    save_history = true,
    history_limit = 100,
  },
})

LSP 集成

lua
require('lspconfig').pyright.setup({
  on_attach = function(client, bufnr)
    -- MyDeskBot 与 LSP 集成
    require('mydeskbot.lsp').attach(client, bufnr)
  end,
})

nvim-cmp 集成

lua
local cmp = require('cmp')

cmp.setup({
  sources = {
    { name = 'nvim_lsp' },
    { name = 'buffer' },
    { name = 'path' },
    { name = 'mydeskbot' },  -- MyDeskBot 补全源
  },
})

-- 可选:配置 MyDeskBot 补全源
require('cmp_mydeskbot').setup({
  max_suggestions = 3,
  model = 'gpt-3.5-turbo',
})

快捷键

默认快捷键

lua
require('mydeskbot').setup({
  -- 自定义快捷键
  keymaps = {
    -- Chat 相关
    chat = '<leader>ma',
    close_chat = 'q',
    send_message = '<CR>',

    -- 代码生成
    generate = '<leader>mg',
    generate_visual = '<leader>mg',

    -- 代码审查
    review = '<leader>mr',
    review_visual = '<leader>mr',

    -- 代码解释
    explain = '<leader>me',
    explain_visual = '<leader>me',

    -- 文档生成
    doc = '<leader>md',
    doc_visual = '<leader>md',

    -- 应用代码
    apply = '<leader>ma',
    discard = '<leader>md',

    -- 终端
    terminal = '<leader>mt',
  },
})

Which-key 集成

lua
local which_key = require('which-key')

which_key.register({
  m = {
    name = 'MyDeskBot',
    a = { ':MyDeskBotChat<CR>', 'Open Chat' },
    g = { ':MyDeskBotGenerate<CR>', 'Generate' },
    r = { ':MyDeskBotReview<CR>', 'Review' },
    e = { ':MyDeskBotExplain<CR>', 'Explain' },
    d = { ':MyDeskBotDoc<CR>', 'Generate Doc' },
    t = { ':MyDeskBotTerminal<CR>', 'Terminal' },
  },
}, { prefix = '<leader>' })

高级功能

自定义提示词模板

lua
require('mydeskbot').setup({
  templates = {
    -- 代码审查模板
    review = [[请审查以下代码:

    语言:{filetype}

    代码:
    ```{filetype}
    {selection}
    ```

    请检查:
    1. 代码质量
    2. 潜在问题
    3. 性能优化
    4. 安全问题
    ]],

    -- 文档模板
    doc = [[为以下代码生成文档:

    ```{filetype}
    {selection}
    ```

    使用标准的文档注释格式。
    ]],
  },
})

异步操作

lua
-- 异步生成代码
require('mydeskbot').generate_async({
  prompt = "创建一个排序算法",
  on_progress = function(progress)
    vim.notify("生成中: " .. progress .. "%")
  end,
  on_complete = function(code)
    -- 在新缓冲区中打开代码
    vim.cmd('vnew')
    vim.api.nvim_buf_set_lines(0, 0, -1, false, vim.split(code, '\n'))
  end,
  on_error = function(err)
    vim.notify("错误: " .. err, vim.log.levels.ERROR)
  end,
})

自定义命令

lua
-- 创建自定义命令
vim.api.nvim_create_user_command('MyAIGen', function(opts)
  local prompt = opts.args
  require('mydeskbot').generate({
    prompt = prompt,
    callback = function(code)
      vim.api.nvim_put(vim.split(code, '\n'), 'l', true, true)
    end,
  })
end, { nargs = '*' })

-- 使用
:MyAIGen 创建一个快速排序函数

与其他插件集成

telescope.nvim

lua
local telescope = require('telescope')

telescope.setup({
  extensions = {
    mydeskbot = {
      theme = 'ivy',
    },
  },
})

telescope.load_extension('mydeskbot')

-- 使用
:Telescope mydeskbot

nvim-treesitter

lua
require('nvim-treesitter.configs').setup({
  -- MyDeskBot 可以利用 treesitter 解析的代码结构
  highlight = {
    enable = true,
  },
})

故障排除

插件无法加载

  1. 检查 Neovim 版本 (nvim --version 需要 >= 0.9.0)
  2. 确认依赖已安装 (plenary.nvim, nui.nvim)
  3. 查看错误信息 (:messages)
  4. 检查插件管理器配置

API 调用失败

vim
" 检查 API 密钥
:lua print(vim.inspect(require('mydeskbot').config.api_key))

" 测试连接
:lua require('mydeskbot').test_connection()

浮动窗口不显示

检查终端是否支持真色:

vim
" 检查颜色支持
:lua print(vim.fn.has('termguicolors'))

" 启用真色
set termguicolors

性能问题

如果响应缓慢:

lua
-- 减少上下文
require('mydeskbot').setup({
  context = {
    max_files = 3,
    max_lines = 300,
  },

  -- 使用更快的模型
  model = 'gpt-3.5-turbo',
})

示例配置文件

完整的 init.lua 配置

lua
-- init.lua

-- 1. 安装插件管理器(如果还没有)
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    'git',
    'clone',
    '--filter=blob:none',
    'https://github.com/folke/lazy.nvim.git',
    '--branch=stable',
    lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)

-- 2. 配置插件
require('lazy').setup({
  -- MyDeskBot
  {
    'mydeskbot/mydeskbot.nvim',
    dependencies = {
      'nvim-lua/plenary.nvim',
      'MunifTanjim/nui.nvim',
      'hrsh7th/nvim-cmp',
    },
    config = function()
      require('mydeskbot').setup({
        api_key = os.getenv('MYDESKBOT_API_KEY'),
        model = 'gpt-4',
        ui = {
          chat = {
            width = 80,
            height = 20,
            border = 'rounded',
          },
        },
        keymaps = {
          chat = '<leader>ma',
          generate = '<leader>mg',
          review = '<leader>mr',
          explain = '<leader>me',
        },
      })
    end,
  },

  -- 其他插件...
})

-- 3. 配置 MyDeskBot 补全源
local cmp = require('cmp')

cmp.setup({
  sources = {
    { name = 'nvim_lsp' },
    { name = 'mydeskbot' },
    { name = 'buffer' },
  },
})

下一步

获取帮助