Skip to content

Commit d4df73c

Browse files
azdanovmehalter
andauthored
feat(copilot-lua-cmp): add blink.cmp support (#1350)
* feat(copilot-lua-cmp): add blink.cmp support * add missing c-j keymap * Use lowercase for keymap * Update lua/astrocommunity/completion/copilot-lua-cmp/init.lua Co-authored-by: Micah Halter <[email protected]> * Update README.md * refactor(copilot-lua-cmp): clean up implementation --------- Co-authored-by: Micah Halter <[email protected]> Co-authored-by: Micah Halter <[email protected]>
1 parent e2a3031 commit d4df73c

File tree

2 files changed

+59
-33
lines changed

2 files changed

+59
-33
lines changed

lua/astrocommunity/completion/copilot-lua-cmp/README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,16 @@ Fully featured & enhanced replacement for copilot.vim complete with API for inte
44

55
**Repository:** <https://github.com/zbirenbaum/copilot.lua>
66

7-
_Note_: This plugin will also reconfigure `cmp` in AstroNvim to make `<Tab>` work with both auto completion in `cmp` and `copilot`.
7+
## Key Features
8+
9+
- Seamless integration with nvim-cmp or blink.cmp
10+
- Enhanced keybindings for Copilot suggestions:
11+
- `<Tab>` - Accept suggestion/Navigate completion menu
12+
- `<C-x>` / `<C-z>` - Next/Previous suggestion
13+
- `<C-right>` / `<C-l>` - Accept word
14+
- `<C-down>` / `<C-j>` - Accept line
15+
- `<C-c>` - Dismiss suggestion
16+
17+
_Note_: This plugin will also reconfigure `<Tab>` in AstroNvim to work with both auto completion in `cmp` and `copilot`.
18+
19+
The configuration includes support for [nvim-cmp](https://github.com/hrsh7th/nvim-cmp) and [blink.cmp](https://github.com/Saghen/blink.cmp) for improved completion behavior.

lua/astrocommunity/completion/copilot-lua-cmp/init.lua

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
local function has_words_before()
2+
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
3+
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match "%s" == nil
4+
end
5+
6+
local function copilot_action(action)
7+
local copilot = require "copilot.suggestion"
8+
return function()
9+
if copilot.is_visible() then
10+
copilot[action]()
11+
return true -- doesn't run the next command
12+
end
13+
end
14+
end
15+
116
return {
217
"zbirenbaum/copilot.lua",
318
specs = {
@@ -9,10 +24,7 @@ return {
924
local cmp, copilot = require "cmp", require "copilot.suggestion"
1025
local snip_status_ok, luasnip = pcall(require, "luasnip")
1126
if not snip_status_ok then return end
12-
local function has_words_before()
13-
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
14-
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match "%s" == nil
15-
end
27+
1628
if not opts.mapping then opts.mapping = {} end
1729
opts.mapping["<Tab>"] = cmp.mapping(function(fallback)
1830
if copilot.is_visible() then
@@ -28,35 +40,37 @@ return {
2840
end
2941
end, { "i", "s" })
3042

31-
opts.mapping["<C-x>"] = cmp.mapping(function()
32-
if copilot.is_visible() then copilot.next() end
33-
end)
34-
35-
opts.mapping["<C-z>"] = cmp.mapping(function()
36-
if copilot.is_visible() then copilot.prev() end
37-
end)
38-
39-
opts.mapping["<C-right>"] = cmp.mapping(function()
40-
if copilot.is_visible() then copilot.accept_word() end
41-
end)
42-
43-
opts.mapping["<C-l>"] = cmp.mapping(function()
44-
if copilot.is_visible() then copilot.accept_word() end
45-
end)
46-
47-
opts.mapping["<C-down>"] = cmp.mapping(function()
48-
if copilot.is_visible() then copilot.accept_line() end
49-
end)
50-
51-
opts.mapping["<C-j>"] = cmp.mapping(function()
52-
if copilot.is_visible() then copilot.accept_line() end
53-
end)
54-
55-
opts.mapping["<C-c>"] = cmp.mapping(function()
56-
if copilot.is_visible() then copilot.dismiss() end
57-
end)
43+
opts.mapping["<C-X>"] = cmp.mapping(copilot_action "next")
44+
opts.mapping["<C-Z>"] = cmp.mapping(copilot_action "prev")
45+
opts.mapping["<C-Right>"] = cmp.mapping(copilot_action "accept_word")
46+
opts.mapping["<C-L>"] = cmp.mapping(copilot_action "accept_word")
47+
opts.mapping["<C-Down>"] = cmp.mapping(copilot_action "accept_line")
48+
opts.mapping["<C-J>"] = cmp.mapping(copilot_action "accept_line")
49+
opts.mapping["<C-C>"] = cmp.mapping(copilot_action "dismiss")
50+
end,
51+
},
52+
{
53+
"Saghen/blink.cmp",
54+
optional = true,
55+
opts = function(_, opts)
56+
if not opts.keymap then opts.keymap = {} end
5857

59-
return opts
58+
opts.keymap["<Tab>"] = {
59+
copilot_action "accept",
60+
"select_next",
61+
"snippet_forward",
62+
function(cmp)
63+
if has_words_before() or vim.api.nvim_get_mode().mode == "c" then return cmp.show() end
64+
end,
65+
"fallback",
66+
}
67+
opts.keymap["<C-X>"] = { copilot_action "next" }
68+
opts.keymap["<C-Z>"] = { copilot_action "prev" }
69+
opts.keymap["<C-Right>"] = { copilot_action "accept_word" }
70+
opts.keymap["<C-L>"] = { copilot_action "accept_word" }
71+
opts.keymap["<C-Down>"] = { copilot_action "accept_line" }
72+
opts.keymap["<C-J>"] = { copilot_action "accept_line", "select_next", "fallback" }
73+
opts.keymap["<C-C>"] = { copilot_action "dismiss" }
6074
end,
6175
},
6276
},

0 commit comments

Comments
 (0)