【期間限定】HHKBスターターキットが特別価格 3/28 13時まで

【Mac】avante.nvimでNeovimをCursor AI IDE化する

13 min

こんにちは。ナミレリです。今回はNeovimをCursor AI IDE化するavante.nvimの特徴や設定方法と使い方を紹介します。avante.nvimはAIによるコード補完や生成を可能にする強力なプラグインです。

avante.nvimの画面:右側にサイドバー

既存のコードとavante.nvimでAIが提案したコードを自動的に反映
既存のコードとavante.nvimでAIが提案したコードを自動的に反映

この記事はこんな人にオススメ

  • AIによるコード補完やリファクタリングを活用したい方
  • CursorのようなAI支援機能をNeovimで再現したい方
  • AIと対話しながらコードの生成や修正を行いたい方
  • NeovimをAI支援のIDEとして進化させたい方
この記事のMac環境
  • M3 MacBook Air 15インチ
  • macOS Sequoia 15.3
  • NVIM v0.10.4
  • avante.nvim v0.0.18
  • Parallels Desktop 20 for Mac バージョン 20.2.0 (55872)
Parallels Desktop 20 for Macの無料トライアル もありますので、ぜひダウンロードして試してみてください。M1/M2/M3のMac上で快適にMacやUbuntu、Windowsが動作します。

avante.nvimについて

AI技術の進化に伴って様々なエディタ内でAI支援が注目されているように思います。Neovimユーザーにとってavante.nvimはAIによるコード補完や生成を可能にする強力なプラグインです。以前の記事で紹介したChagGPT.nvimも素晴らしいですが、avante.nvimはさらに使いやすく革新的なプラグインとなっています。

avanta.nvimのコード自動反映のgif

<leader>aaでavante.nvimのサイドバーを表示して、指示や質問を入力しctrl + sで送信。下の動画のように結果をneovimのエリアに自動反映することもできます。

選択範囲にコメントを追加のgif

avante.nvimの主な機能
  • Ask機能:特定のキーマップ(デフォルトでは<leader>aa)でサイドバーを表示してAIとの対話を開始できます。フローティングウィンドウでの表示も可能で、コードに関する質問や生成ができます。
  • サイドバー<leader>atでサイドバーの表示をトグルできます。サイドバーの下部でAIにプロンプトを送信し、その結果が上部に表示されます。
  • オートサジェスション: コード入力時にAIが自動的に補完候補をしてくれます。
  • カスタムプロンプト: ユーザーが独自のプロンプトを設定することもできます。

モデルはClaude-3.5-Sonnetを使うことを奨励していますが、私はOpenAIのgpt-4oで使っています。ClaudeやOpenAI以外にもAzure OpenAI、 Amazon Bedrock、copilot、geminiなどがbuiltinされています。

builtinで用意されている以外に、perplexity、deepseek、ローカルLLMでのollamaなども使えます。

https://github.com/yetone/avante.nvim/tree/main/lua/avante/providers

https://github.com/yetone/avante.nvim/wiki/Custom-providers

avante.nvimのインストール

このブログではLazy.nvim用に下のような構成にします。

avante_cfg.luaにavante.nvimの設定をしていきます。

~/.config/nvim/
├── init.lua
└─lua/
       ├── plugins/
       │       ├── plugins_lazy.lua
       │       ├── lualine_cfg.lua
       │       ├── neo-tree_cfg.lua
       │       ├── lsp_cfg.lua
       │       └── avante_cfg.lua<= 追加
       ├── core/
       │       ├── autocmds.lua
       │       ├── keymaps.lua
       │       └── options.lua
       └── user/
               ├── icons.lua
               ── ui.lua

ほぼ公式の設定のままで設定します。17行目から19行目のauto_apply_diff_after_generationtrueをすることで、AIのコードをneovimのエリアに自動反映します。

avante_cfg.lua


return {
    "yetone/avante.nvim",
    event = "VeryLazy",
    lazy = true,
    version = false, -- Set this to "*" to always pull the latest release version, or set it to false to update to the latest code changes.
    opts = {
        -- add any opts here
        -- for example
        provider = "openai",
        openai = {
            endpoint = "https://api.openai.com/v1",
            model = "gpt-4o",  -- your desired model (or use gpt-4o, etc.)
            timeout = 30000,   -- timeout in milliseconds
            temperature = 0.3, -- adjust if needed
            max_tokens = 4096,
        },
        behaviour = {
            auto_apply_diff_after_generation = true,
        },
    },
    -- if you want to build from source then do `make BUILD_FROM_SOURCE=true`
    build = "make",
    -- build = "powershell -ExecutionPolicy Bypass -File Build.ps1 -BuildFromSource false" -- for windows
    dependencies = {
        "stevearc/dressing.nvim",
        "nvim-lua/plenary.nvim",
        "MunifTanjim/nui.nvim",
        --- The below dependencies are optional,
        "echasnovski/mini.pick",         -- for file_selector provider mini.pick
        "nvim-telescope/telescope.nvim", -- for file_selector provider telescope
        "hrsh7th/nvim-cmp",              -- autocompletion for avante commands and mentions
        "ibhagwan/fzf-lua",              -- for file_selector provider fzf
        "nvim-tree/nvim-web-devicons",   -- or echasnovski/mini.icons
        "zbirenbaum/copilot.lua",        -- for providers='copilot'
        {
            -- support for image pasting
            "HakonHarnes/img-clip.nvim",
            event = "VeryLazy",
            opts = {
                -- recommended settings
                default = {
                    embed_image_as_base64 = false,
                    prompt_for_file_name = false,
                    drag_and_drop = {
                        insert_mode = true,
                    },
                    use_absolute_path = false,
                },
            },
        },
        {
            -- Make sure to set this up properly if you have lazy=true
            "MeanderingProgrammer/render-markdown.nvim",
            opts = {
                file_types = { "markdown", "Avante" },
            },
            ft = { "markdown", "Avante" },
        },
    },
}

もちろんAIが提案したコードを勝手に反映されるのではなく、差分(diff)モードとなり以下のキーマップで自分で判断していきます。

差分モードのキーマップ

キーマップ詳細
cochoose ours現在のコード(自分のコード)を選択
ctchoose theirsAIが提案したコードを選択
cachoose all theirsAIの提案したすべての変更を適用
c0choose noneAIが提案したすべての変更を適用しない
cbchoose both自分のコードとAIの提案を両方適用
ccchoose cursorカーソル位置の変更をAIの提案を適用
]xmove to previous conflict次の差分箇所に移動
[xmove to next conflict前の差分箇所に移動
[[jump to previous codeblocks前のコードブロックにジャンプ
]]jump to next codeblocks次のコードブロックにジャンプ

avante.nvimの使い方

avante.nvimの使い方はシンプルです。以下の9個のコマンドがあります。

avante.nvimの使い方はシンプル、9個のコマンドがあります
avante.nvimの使い方はシンプル、9個のコマンドがあります

主には<leader>aa<leader>aeの2つを使うことになると思います。私はその他のコマンドはほぼ使っていません。

コマンドデフォルトのキーマップ詳細
:AvanteAsk<leader>aa現在のコードに対してAIに指示する
:AvanteBuildプロジェクトの依存関係をビルドする
:AvanteChatチャットセッションの開始
:AvanteEdit<leader>ae選択したコードブロックに対してAIに指示する
:AvanteFocusサイドバーへのフォーカスを切り替える
:AvanteRefreshavant.nvimの全ウィンドウをリフレッシュする
:AvanteSwitchProviderAIを変更する
:AvanteShowRepoMapRepoMapの表示
:AvanteToggleサイドバーをトグルする

<leader>aa:AvanteAsk)の使い方

もっともよく使う<leader>aa:AvanteAskの使い方です。

Neovimでコードを開いている状態で<leader>aaを押すと、AI とのチャットインターフェースであるサイドバーが表示されます。このチャットインタフェースで現在のコードに関する質問や、特定のコードブロックの改善提案など、何でもAIに聞くことができます。

上でも書きましたが、auto_apply_diff_after_generation = trueを設定している場合は、AIのコードがNeovim側に差分モードで反映されとても便利です。

リファクトリングしてもらった結果の差分モード

リファクトリングしてもらった結果の差分モード
リファクトリングしてもらった結果の差分モード

avanta.nvimのコード自動反映のgif

差分モードではこれも上で書きましたが、以下のキーでAI提案のコードを適用するかしないかを決定することができます。

差分モードのキーマップ

キーマップ詳細
cochoose ours現在のコード(自分のコード)を選択
ctchoose theirsAIが提案したコードを選択
cachoose all theirsAIの提案したすべての変更を適用
c0choose noneAIが提案したすべての変更を適用しない
cbchoose both自分のコードとAIの提案を両方適用
ccchoose cursorカーソル位置の変更をAIの提案を適用
]xmove to previous conflict次の差分箇所に移動
[xmove to next conflict前の差分箇所に移動
[[jump to previous codeblocks前のコードブロックにジャンプ
]]jump to next codeblocks次のコードブロックにジャンプ

<leader>ae:AvanteEdit)の使い方

次によく使う<leader>ae:AvanteEditの使い方です。

ビジュアルモードでコードブロックを選択して <leader>aeを押すと、選択したコードブロックに対してAI とのチャットインターフェースが表示されます。このチャットインタフェースで現在のコードに関する質問など何でもAIに指示することができます。

選択範囲にコメントを追加のgif

便利な使い方:アクションを実行するキーマップを設定

ChatGPT.nvimChatGPTRun [action]で特定のアクションを実行することができて便利ですが、avante.nvimでも同じようなことを実現するレシピがwikiに掲載されていました。

https://github.com/yetone/avante.nvim/wiki/Recipe-and-Tricks

いくつか抜粋して以下のようにキーマップに設定して使っています。

~/.config/nvim/
├── init.lua
└─lua/
       ├── core/
       │       ├── autocmds.lua
       │       ├── keymaps.lua
       │       ├── keymaps_avante.lua<= 追加
       │       └── options.lua
       └── user/
               ├── icons.lua
               ── ui.lua

keymaps_avante.lua


-- prefil edit window with common scenarios to avoid repeating query and submit immediately
local prefill_edit_window = function(request)
    require("avante.api").edit()
    local code_bufnr = vim.api.nvim_get_current_buf()
    local code_winid = vim.api.nvim_get_current_win()
    if code_bufnr == nil or code_winid == nil then
        return
    end
    vim.api.nvim_buf_set_lines(code_bufnr, 0, -1, false, { request })
    -- Optionally set the cursor position to the end of the input
    vim.api.nvim_win_set_cursor(code_winid, { 1, #request + 1 })
    -- Simulate Ctrl+S keypress to submit
    vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<C-s>", true, true, true), "v", true)
end

-- NOTE: most templates are inspired from ChatGPT.nvim -> chatgpt-actions.json
local avante_code_readability_analysis = [[
  以下の点を考慮しコードの可読性の問題を特定してください。
  考慮すべき可読性の問題:
  - 不明瞭な命名
  - 不明瞭な目的
  - 冗長なコメント
  - コメントの欠如
  - 長いまたは複雑な一行のコード
  - ネストが多すぎる
  - 長すぎる変数名
  - 命名とコードスタイルの不一致
  - コードの繰り返し
  上記以外の問題を特定しても構いません。
]]
local avante_optimize_code = "次のコードを最適化してください。"
local avante_fix_bugs = "次のコード内のバグを修正してください。"
local avante_add_tests = "次のコードのテストを実装してください。"
local avante_add_docstring = "次のコードにdocstringを追加してください。"

-- avante.nvim
local avante_ask = require("avante.api").ask

vim.keymap.set("n", "<leader>al", function()
    avante_ask({ question = avante_code_readability_analysis })
end, { noremap = true, silent = true, desc = "[avante]可読性" })

vim.keymap.set("n", "<leader>aL", function()
    prefill_edit_window(avante_code_readability_analysis)
end, { noremap = true, silent = true, desc = "[avante]可読性(Edit)" })

vim.keymap.set("n", "<leader>ao", function()
    avante_ask({ question = avante_optimize_code })
end, { noremap = true, silent = true, desc = "[avante]最適化" })

vim.keymap.set("n", "<leader>aO", function()
    prefill_edit_window(avante_optimize_code)
end, { noremap = true, silent = true, desc = "[avante]最適化(Edit)" })

vim.keymap.set("n", "<leader>ab", function()
    avante_ask({ question = avante_fix_bugs })
end, { noremap = true, silent = true, desc = "[avante]バグ修正" })

vim.keymap.set("n", "<leader>aB", function()
    prefill_edit_window(avante_fix_bugs)
end, { noremap = true, silent = true, desc = "[avante]バグ修正(Edit)" })

vim.keymap.set("n", "<leader>au", function()
    avante_ask({ question = avante_add_tests })
end, { noremap = true, silent = true, desc = "[avante]テスト実装" })

vim.keymap.set("n", "<leader>aU", function()
    prefill_edit_window(avante_add_tests)
end, { noremap = true, silent = true, desc = "[avante]テスト実装(Edit)" })

vim.keymap.set("n", "<leader>ad", function()
    avante_ask({ question = avante_add_docstring })
end, { noremap = true, silent = true, desc = "[avante]docstring" })

vim.keymap.set("n", "<leader>aD", function()
    prefill_edit_window(avante_add_docstring)
end, { noremap = true, silent = true, desc = "[avante]docstring(Edit)" })

以下のように作成したkeymaps_avante.luainit.luaからrequireして読み込みます。

init.lua


require("core.keymaps_avante")

追加したキーマップを以下にまとめます。

追加したキーマッププロンプト
<leader>alAvanteAsk以下の点を考慮しコードの可読性の問題を特定してください。(省略)
<leader>aLAvanteEdit以下の点を考慮しコードの可読性の問題を特定してください。(省略)
<leader>aoAvanteAsk次のコードを最適化してください。
<leader>aOAvanteEdit次のコードを最適化してください。
<leader>abAvanteAsk次のコード内のバグを修正してください。
<leader>aBAvanteEdit次のコード内のバグを修正してください。
<leader>auAvanteAsk次のコードのテストを実装してください。
<leader>aUAvanteEdit次のコードのテストを実装してください。

便利な使い方:__inherited_fromフィールドで継承する

複数のモデルを登録したい場合には、__inherited_fromを使うと簡単にモデルを登録することができます。

https://github.com/yetone/avante.nvim/wiki/Custom-providers#openai-compatible-providers

下の例では、ビルトインされているプロバイダーであるopenaiを継承して、o1o3-miniなどを設定しています。また、openai互換であるperplexitydeepseekなども設定できます。


return {
    "yetone/avante.nvim",
    event = "VeryLazy",
    lazy = true,
    version = false,
    opts = {
        provider = "openai",
        openai = {
            endpoint = "https://api.openai.com/v1",
            model = "gpt-4o",
            timeout = 30000,
            temperature = 0.3,
            max_tokens = 4096,
        },
        vendors = {
            ["gpt-4o"] = {
                __inherited_from = "openai",
                model = "gpt-4o",
            },
            ["o1"] = {
                __inherited_from = "openai",
                model = "o1",
            },
            ["o1-mini"] = {
                __inherited_from = "openai",
                model = "o1-mini",
            },
            ["o3-mini"] = {
                __inherited_from = "openai",
                model = "o3-mini",
            },
            ["o3-mini-hight"] = {
                __inherited_from = "openai",
                model = "o3-mini-hight",
            },
        },
        behaviour = {
            auto_apply_diff_after_generation = true,
        },
    },
}

最後に

最後まで読んでいただきありがとうございます。avante.nvimでNeovimをCursor AI IDE化するはいかがでしたでしょうか。Neovimユーザーにとってavante.nvimはAIによるコード補完や生成を可能にする強力で未来の体験ができるプラグインになっていて今後の発展も楽しみです。

自分好みのNeovim環境をカスタマイズして構築すること自体もモチベが上がりますのでぜひいろいろ試してください。

【期間限定】HHKBスターターキットが特別価格 3/28 13時まで

おすすめ記事

Neovimをかっこ良くクールに使う設定

関連記事