Skip to content

Commit b24759c

Browse files
committed
initial commit
0 parents  commit b24759c

File tree

10 files changed

+184
-0
lines changed

10 files changed

+184
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
main.js
2+
test.js

.luacheckrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
globals = { "vim", "describe", "it", "before_each", "after_each", "assert", "async" }

.luarc.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"runtime": {
3+
"version": "LuaJIT",
4+
"pathStrict": true
5+
},
6+
"type": {
7+
"checkTableShape": true
8+
},
9+
"diagnostics.globals": [
10+
"describe",
11+
"it",
12+
"before_each",
13+
"after_each"
14+
]
15+
}

.stylua.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
column_width = 120
2+
line_endings = "Unix"
3+
indent_type = "Spaces"
4+
indent_width = 4
5+
quote_style = "AutoPreferDouble"

lsp/copilot.lua

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---@type vim.lsp.Config
2+
return {
3+
name = "copilot",
4+
cmd = {
5+
"copilot-language-server",
6+
"--stdio",
7+
},
8+
init_options = {
9+
editorInfo = { name = "neovim", version = "0.11" },
10+
editorPluginInfo = {
11+
name = "Github Copilot LSP for Neovim",
12+
version = "0.0.1",
13+
},
14+
},
15+
settings = {
16+
nextEditSuggestions = {
17+
enabled = true,
18+
},
19+
},
20+
root_markers = { ".git" },
21+
on_init = function(client)
22+
local nes = require("copilot-lsp.nes")
23+
local inline_completion = require("copilot-lsp.completion")
24+
25+
vim.keymap.set("i", "<c-i>", function()
26+
inline_completion.request_inline_completion(1)
27+
end)
28+
29+
vim.keymap.set("n", "<leader>x", function()
30+
nes.request_nes(client)
31+
end)
32+
33+
local au = vim.api.nvim_create_augroup("copilot-language-server", { clear = true })
34+
vim.api.nvim_create_autocmd("TextChangedI", {
35+
callback = function()
36+
inline_completion.request_inline_completion(2)
37+
end,
38+
group = au,
39+
})
40+
41+
vim.api.nvim_create_autocmd("BufEnter", {
42+
callback = function()
43+
local td_params = vim.lsp.util.make_text_document_params()
44+
client:notify("textDocument/didFocus", {
45+
textDocument = {
46+
uri = td_params.uri,
47+
},
48+
})
49+
end,
50+
group = au,
51+
})
52+
end,
53+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
local M = {}
2+
3+
---@param results table<integer, { err: lsp.ResponseError, result: lsp.InlineCompletionList}>
4+
---@param _ctx lsp.HandlerContext
5+
---@param _config table
6+
local function handle_inlineCompletion_response(results, _ctx, _config)
7+
-- Filter errors from results
8+
local results1 = {} --- @type table<integer,lsp.InlineCompletionList>
9+
10+
for client_id, resp in pairs(results) do
11+
local err, result = resp.err, resp.result
12+
if err then
13+
vim.lsp.log.error(err.code, err.message)
14+
elseif result then
15+
results1[client_id] = result
16+
end
17+
end
18+
19+
for _, result in pairs(results1) do
20+
-- This is where we show the completion results
21+
dd(result)
22+
end
23+
end
24+
25+
---@param type lsp.InlineCompletionTriggerKind
26+
function M.request_inline_completion(type)
27+
local params = vim.tbl_deep_extend("keep", vim.lsp.util.make_position_params(0, "utf-16"), {
28+
textDocument = vim.lsp.util.make_text_document_params(),
29+
position = vim.lsp.util.make_position_params(0, "utf-16"),
30+
context = {
31+
triggerKind = type,
32+
},
33+
formattingOptions = {
34+
tabSize = 4,
35+
insertSpaces = true,
36+
},
37+
})
38+
vim.lsp.buf_request_all(0, "textDocument/inlineCompletion", params, handle_inlineCompletion_response)
39+
end
40+
return M

lua/copilot-lsp/errors.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
return {
2+
ErrNotStarted = "Copilot LSP not started",
3+
}

lua/copilot-lsp/nes/init.lua

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
local errs = require("copilot-lsp.errors")
2+
local utils = require("copilot-lsp.util")
3+
4+
local M = {}
5+
6+
---@param err lsp.ResponseError?
7+
---@param result copilotInlineEditResponse
8+
local function handle_nes_response(err, result)
9+
if err then
10+
vim.notify(err.message)
11+
return
12+
end
13+
if #result.edits > 1 then
14+
vim.notify("more than 1 edit, dont know what to do yet")
15+
return
16+
end
17+
18+
if #result.edits == 0 then
19+
vim.notify("no edits")
20+
return
21+
end
22+
23+
local edit = result.edits[1]
24+
utils.apply_inline_edit(edit)
25+
end
26+
27+
---@param copilot_lss vim.lsp.Client?
28+
function M.request_nes(copilot_lss)
29+
local pos_params = vim.lsp.util.make_position_params(0, "utf-16")
30+
local version = vim.lsp.util.buf_versions[vim.api.nvim_get_current_buf()]
31+
assert(copilot_lss, errs.ErrNotStarted)
32+
---@diagnostic disable-next-line: inject-field
33+
pos_params.textDocument.version = version
34+
copilot_lss:request("textDocument/copilotInlineEdit", pos_params, handle_nes_response)
35+
end
36+
37+
return M

lua/copilot-lsp/types.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---@class copilotInlineEdit
2+
---@field command lsp.Command
3+
---@field range lsp.Range
4+
---@field text string
5+
---@field textDocument lsp.VersionedTextDocumentIdentifier
6+
7+
---@class copilotInlineEditResponse
8+
---@field edits copilotInlineEdit[]

lua/copilot-lsp/util.lua

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
local M = {}
2+
---@param edit copilotInlineEdit
3+
function M.apply_inline_edit(edit)
4+
local bufnr = vim.uri_to_bufnr(edit.textDocument.uri)
5+
local multi_line
6+
if edit.text:match("\n") then
7+
multi_line = vim.split(edit.text, "\n")
8+
end
9+
10+
vim.api.nvim_buf_set_text(
11+
bufnr,
12+
edit.range.start.line,
13+
edit.range.start.character,
14+
edit.range["end"].line,
15+
edit.range["end"].character,
16+
multi_line or { edit.text }
17+
)
18+
end
19+
20+
return M

0 commit comments

Comments
 (0)