From 94c1ac7e32549714b40cd91825b2e0ae44b214ae Mon Sep 17 00:00:00 2001 From: Micah Halter Date: Fri, 28 Feb 2025 10:41:07 -0500 Subject: [PATCH 1/3] feat(recipes): start working on an AI recipes section --- src/content/docs/recipes/ai.mdx | 115 ++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/content/docs/recipes/ai.mdx diff --git a/src/content/docs/recipes/ai.mdx b/src/content/docs/recipes/ai.mdx new file mode 100644 index 000000000..b9a41150d --- /dev/null +++ b/src/content/docs/recipes/ai.mdx @@ -0,0 +1,115 @@ +--- +id: ai +title: AI Completion +--- + +There are many AI plugins out there which provide completion through various mechanisms. This page goes over how to build onto an AstroNvim configuration in order to easily hook up and configure different AI completion plugins. + +### Completion Engine Integration + +In order to make AI plugins play nicely with AstroNvim it's important to set up an integration point with completion engines in Neovim in order to accept AI recommended code. Depending on which completion plugin you are using, you may need to modify the configuration of the mappings to account for interacting with normal completion as well as AI recommended code. By default AstroNvim utilizes a "super-tab" like configuration where the `` key is used for triggering completion, navigating through snippets, and navigating through completion items. These code snippets change this configuration so that the `` key is only used for snippet navigation and AI completion. To navigate through the completion lists, it would then be recommended to use `` and ``. + +These configurations set up the completion engines to look for a function stored in `vim.g.ai_accept` which can be later configured by an AI completion plugin to choose what action should be taken when attempting to accept an AI suggestion if available. + +#### [nvim-cmp](https://github.com/hrsh7th/nvim-cmp) Integration + +By default AstroNvim comes with [`nvim-cmp`](https://github.com/hrsh7th/nvim-cmp) for completion. This modifies the default configuration to set up the `` key as described above: + +```lua title="lua/plugins/cmp_ai.lua" +return { + "hrsh7th/nvim-cmp", + optional = true, + opts = function(_, opts) + local cmp = require("cmp") + if not opts.mapping then + opts.mapping = {} + end + opts.mapping[""] = cmp.mapping(function(fallback) + -- Snippet jump next (with support for several popular snippet plugins) + local mini_snippets_avail, mini_snippets = pcall(require, "mini.snippets") + local luasnip_avail, luasnip = pcall(require, "luasnip") + if mini_snippets_avail then + if mini_snippets.session.get(false) then + mini_snippets.session.jump("next") + return + end + elseif luasnip_avail then + if luasnip.locally_jumpable(1) then + luasnip.jump(1) + return + end + elseif vim.snippet and vim.snippet.active({ direction = 1 }) then + vim.schedule(function() + vim.snippet.jump(1) + end) + return + end + -- AI accept + if vim.g.ai_accept and vim.g.ai_accept() then + return + end + -- Fallback + fallback() + end, { "i", "s" }) + opts.mapping[""] = cmp.mapping(function(fallback) + -- Snippet jump previous + local mini_snippets_avail, mini_snippets = pcall(require, "mini.snippets") + local luasnip_avail, luasnip = pcall(require, "luasnip") + if mini_snippets_avail then + if mini_snippets.session.get(false) then + mini_snippets.session.jump("prev") + return + end + elseif luasnip_avail then + if luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + return + end + elseif vim.snippet and vim.snippet.active({ direction = -1 }) then + vim.schedule(function() + vim.snippet.jump(-1) + end) + return + end + -- Fallback + fallback() + end, { "i", "s" }) + end, +} +``` + +#### [blink.cmp](https://github.com/Saghen/blink.cmp) Integration + +[blink.cmp](https://github.com/Saghen/blink.cmp) is another popular completion plugin. This configures the `` key as described above: + +```lua title="lua/plugins/cmp_ai.lua" +return { + "Saghen/blink.cmp", + optional = true, + opts = function(_, opts) + if not opts.keymap then + opts.keymap = {} + end + opts.keymap[""] = { + "snippet_forward", + function() + if vim.g.ai_accept then + return vim.g.ai_accept() + end + end, + "fallback", + } + opts.keymap[""] = { "snippet_backward", "fallback" } + end, +} +``` + +### AI Plugin Integration + +Once our completion engine is configured, we can start choosing and adding in an AI plugin from the Neovim plugin ecosystem, and setting up the `vim.g.ai_accept` function appropriately to hook into the completion engine mappings that we previously set up. + +#### [copilot.lua](https://github.com/zbirenbaum/copilot.lua) + +#### [codeium.nvim](https://github.com/Exafunction/codeium.nvim) + +#### [supermaven-nvim](https://github.com/supermaven-inc/supermaven-nvim) From caf4be638ffebf46138a3ec5b80e732597c5a228 Mon Sep 17 00:00:00 2001 From: Micah Halter Date: Fri, 28 Feb 2025 11:19:40 -0500 Subject: [PATCH 2/3] feat(ai): add basic configuration code for various AI plugins --- src/content/docs/recipes/ai.mdx | 106 +++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/src/content/docs/recipes/ai.mdx b/src/content/docs/recipes/ai.mdx index b9a41150d..977352bab 100644 --- a/src/content/docs/recipes/ai.mdx +++ b/src/content/docs/recipes/ai.mdx @@ -106,10 +106,114 @@ return { ### AI Plugin Integration -Once our completion engine is configured, we can start choosing and adding in an AI plugin from the Neovim plugin ecosystem, and setting up the `vim.g.ai_accept` function appropriately to hook into the completion engine mappings that we previously set up. +Once our completion engine is configured, we can start choosing and adding in an AI plugin from the Neovim plugin ecosystem, and setting up the `vim.g.ai_accept` function appropriately to hook into the completion engine mappings that we previously set up. Please note that further configuration may be necessary if you want to use completion sources rather than inline suggestions or change other behavior of the AI plugins. For that setup, please refer to the documentation of the plugins themselves. #### [copilot.lua](https://github.com/zbirenbaum/copilot.lua) +```lua title="lua/plugins/copilot.lua" +return { + "zbirenbaum/copilot.lua", + cmd = "Copilot", + build = ":Copilot auth", + event = "BufReadPost", + opts = { + suggestion = { + keymap = { + accept = false, -- handled by completion engine + }, + }, + }, + specs = { + { + "AstroNvim/astrocore", + opts = { + options = { + g = { + -- set the ai_accept function + ai_accept = function() + if require("copilot.suggestion").is_visible() then + require("copilot.suggestion").accept() + return true + end + end, + }, + }, + }, + }, + }, +} +``` + #### [codeium.nvim](https://github.com/Exafunction/codeium.nvim) +```lua title="lua/plugins/codeium.lua" +return { + "Exafunction/codeium.nvim", + cmd = "Codeium", + event = "InsertEnter", + build = ":Codeium Auth", + opts = { + virtual_text = { + key_bindings = { + accept = false, -- handled by completion engine + }, + }, + }, + specs = { + { + "AstroNvim/astrocore", + opts = { + options = { + g = { + -- set the ai_accept function + ai_accept = function() + if + require("codeium.virtual_text").get_current_completion_item() + then + vim.api.nvim_input(require("codeium.virtual_text").accept()) + return true + end + end, + }, + }, + }, + }, + }, +} +``` + #### [supermaven-nvim](https://github.com/supermaven-inc/supermaven-nvim) + +```lua title="lua/plugins/supermaven.lua" +return { + "supermaven-inc/supermaven-nvim", + event = "InsertEnter", + cmd = { "SupermavenUseFree", "SupermavenUsePro" }, + opts = { + keymaps = { + accept_suggestion = nil, -- handled by completion engine + }, + }, + specs = { + { + "AstroNvim/astrocore", + opts = { + options = { + g = { + -- set the ai_accept function + ai_accept = function() + local suggestion = require("supermaven-nvim.completion_preview") + if suggestion.has_suggestion() then + vim.schedule(function() + suggestion.on_accept_suggestion() + end) + return true + end + end, + }, + }, + }, + }, + }, +} +``` From 0e6046a6510009a0e5f82625ab8872097903a75b Mon Sep 17 00:00:00 2001 From: Micah Halter Date: Fri, 28 Feb 2025 11:50:27 -0500 Subject: [PATCH 3/3] feat(ai): add link to AstroCommunity AI entry --- src/content/docs/recipes/ai.mdx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/content/docs/recipes/ai.mdx b/src/content/docs/recipes/ai.mdx index 977352bab..c0fc2653c 100644 --- a/src/content/docs/recipes/ai.mdx +++ b/src/content/docs/recipes/ai.mdx @@ -5,6 +5,19 @@ title: AI Completion There are many AI plugins out there which provide completion through various mechanisms. This page goes over how to build onto an AstroNvim configuration in order to easily hook up and configure different AI completion plugins. +:::tip + +This is available in the [AstroCommunity](https://github.com/AstroNvim/astrocommunity/tree/main/lua/astrocommunity/recipes/ai) and the AI completion plugins within AstroCommunity utilize the configuration it sets up. + +```lua title="lua/community.lua" ins={3} +return { + "AstroNvim/astrocommunity", + { import = "astrocommunity.recipes.ai" }, +} +``` + +::: + ### Completion Engine Integration In order to make AI plugins play nicely with AstroNvim it's important to set up an integration point with completion engines in Neovim in order to accept AI recommended code. Depending on which completion plugin you are using, you may need to modify the configuration of the mappings to account for interacting with normal completion as well as AI recommended code. By default AstroNvim utilizes a "super-tab" like configuration where the `` key is used for triggering completion, navigating through snippets, and navigating through completion items. These code snippets change this configuration so that the `` key is only used for snippet navigation and AI completion. To navigate through the completion lists, it would then be recommended to use `` and ``.