2023-04-12 05:23:20 +02:00
|
|
|
|
local BINARY = vim.g.codemp_binary or "./codemp-client-nvim"
|
2023-04-11 06:20:40 +02:00
|
|
|
|
|
|
|
|
|
local M = {}
|
2023-04-12 16:58:28 +02:00
|
|
|
|
|
|
|
|
|
M.jobid = nil
|
|
|
|
|
M.create = function(path, content) return vim.rpcrequest(M.jobid, "create", path, content) end
|
|
|
|
|
M.insert = function(path, txt, pos) return vim.rpcrequest(M.jobid, "insert", path, txt, pos) end
|
|
|
|
|
M.delete = function(path, pos, count) return vim.rpcrequest(M.jobid, "delete", path, pos, count) end
|
|
|
|
|
M.replace = function(path, txt) return vim.rpcrequest(M.jobid, "replace", path, txt) end
|
2023-07-09 03:42:08 +02:00
|
|
|
|
M.cursor = function(path, cur) return vim.rpcrequest(M.jobid, "cursor", path, cur[1][1], cur[1][2], cur[2][1], cur[2][2]) end
|
2023-04-12 16:58:28 +02:00
|
|
|
|
M.attach = function(path) return vim.rpcrequest(M.jobid, "attach", path) end
|
|
|
|
|
M.listen = function(path) return vim.rpcrequest(M.jobid, "listen", path) end
|
|
|
|
|
M.detach = function(path) return vim.rpcrequest(M.jobid, "detach", path) end
|
2023-04-11 22:35:27 +02:00
|
|
|
|
|
|
|
|
|
local function cursor_offset()
|
|
|
|
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
|
|
|
|
return vim.fn.line2byte(cursor[1]) + cursor[2] - 1
|
|
|
|
|
end
|
|
|
|
|
|
2023-04-12 01:38:38 +02:00
|
|
|
|
local codemp_autocmds = vim.api.nvim_create_augroup("CodempAuGroup", { clear = true })
|
|
|
|
|
|
2023-07-09 03:42:08 +02:00
|
|
|
|
local function get_cursor_range()
|
|
|
|
|
local mode = vim.fn.mode()
|
|
|
|
|
if mode == "" or mode == "s" or mode == "Vs" or mode == "V" or mode == "vs" or mode == "v" then
|
|
|
|
|
local start = vim.fn.getpos("'<")
|
|
|
|
|
local finish = vim.fn.getpos("'>")
|
|
|
|
|
return {
|
|
|
|
|
{ start[2], start[3] },
|
|
|
|
|
{ finish[2], finish[3] }
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
|
|
|
|
return {
|
|
|
|
|
{ cursor[1], cursor[2] },
|
|
|
|
|
{ cursor[1], cursor[2] + 1 },
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2023-04-12 00:31:59 +02:00
|
|
|
|
local function hook_callbacks(path, buffer)
|
2023-04-11 06:20:40 +02:00
|
|
|
|
vim.api.nvim_create_autocmd(
|
|
|
|
|
{ "InsertCharPre" },
|
2023-04-12 00:31:59 +02:00
|
|
|
|
{
|
2023-04-12 16:58:28 +02:00
|
|
|
|
callback = function(_)
|
2023-04-13 03:23:57 +02:00
|
|
|
|
pcall(M.insert, path, vim.v.char, cursor_offset()) -- TODO log errors
|
2023-04-12 16:58:28 +02:00
|
|
|
|
end,
|
2023-04-12 00:31:59 +02:00
|
|
|
|
buffer = buffer,
|
2023-04-12 01:38:38 +02:00
|
|
|
|
group = codemp_autocmds,
|
2023-04-12 00:31:59 +02:00
|
|
|
|
}
|
2023-04-11 06:20:40 +02:00
|
|
|
|
)
|
2023-04-12 03:29:42 +02:00
|
|
|
|
vim.api.nvim_create_autocmd(
|
2023-04-13 03:23:57 +02:00
|
|
|
|
{ "CursorMoved", "CompleteDone", "InsertEnter", "InsertLeave" },
|
2023-04-12 03:29:42 +02:00
|
|
|
|
{
|
2023-04-12 16:58:28 +02:00
|
|
|
|
callback = function(args)
|
2023-04-13 03:23:57 +02:00
|
|
|
|
local lines = vim.api.nvim_buf_get_lines(args.buf, 0, -1, false)
|
|
|
|
|
pcall(M.replace, path, vim.fn.join(lines, "\n")) -- TODO log errors
|
2023-07-09 03:42:08 +02:00
|
|
|
|
pcall(M.cursor, path, get_cursor_range()) -- TODO log errors
|
2023-04-13 03:23:57 +02:00
|
|
|
|
end,
|
|
|
|
|
buffer = buffer,
|
|
|
|
|
group = codemp_autocmds,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
local last_line = 0
|
|
|
|
|
vim.api.nvim_create_autocmd(
|
|
|
|
|
{ "CursorMovedI" },
|
|
|
|
|
{
|
|
|
|
|
callback = function(args)
|
2023-07-09 03:42:08 +02:00
|
|
|
|
local cursor = get_cursor_range()
|
|
|
|
|
pcall(M.cursor, path, cursor) -- TODO log errors
|
|
|
|
|
if cursor[1][1] == last_line then
|
2023-04-13 03:23:57 +02:00
|
|
|
|
return
|
|
|
|
|
end
|
2023-07-09 03:42:08 +02:00
|
|
|
|
last_line = cursor[1][1]
|
2023-04-13 03:23:57 +02:00
|
|
|
|
local lines = vim.api.nvim_buf_get_lines(args.buf, 0, -1, false)
|
|
|
|
|
pcall(M.replace, path, vim.fn.join(lines, "\n")) -- TODO log errors
|
2023-04-12 03:29:42 +02:00
|
|
|
|
end,
|
|
|
|
|
buffer = buffer,
|
|
|
|
|
group = codemp_autocmds,
|
|
|
|
|
}
|
|
|
|
|
)
|
2023-04-13 03:23:57 +02:00
|
|
|
|
vim.keymap.set('i', '<BS>', function() pcall(M.delete, path, cursor_offset(), 1) return '<BS>' end, {expr = true, buffer = buffer}) -- TODO log errors
|
|
|
|
|
vim.keymap.set('i', '<Del>', function() pcall(M.delete, path, cursor_offset() + 1, 1) return '<Del>' end, {expr = true, buffer = buffer}) -- TODO log errors
|
2023-04-12 01:38:38 +02:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function unhook_callbacks(buffer)
|
|
|
|
|
vim.api.nvim_clear_autocmds({ group = codemp_autocmds, buffer = buffer })
|
|
|
|
|
vim.keymap.del('i', '<BS>', { buffer = buffer })
|
|
|
|
|
vim.keymap.del('i', '<Del>', { buffer = buffer })
|
2023-04-11 06:20:40 +02:00
|
|
|
|
end
|
|
|
|
|
|
2023-04-13 00:54:01 +02:00
|
|
|
|
local function auto_address(addr)
|
|
|
|
|
if not string.find(addr, "://") then
|
|
|
|
|
addr = string.format("http://%s", addr)
|
|
|
|
|
end
|
|
|
|
|
if not string.find(addr, ":", 7) then -- skip first 7 chars because 'https://'
|
|
|
|
|
addr = string.format("%s:50051", addr)
|
|
|
|
|
end
|
|
|
|
|
return addr
|
|
|
|
|
end
|
|
|
|
|
|
2023-04-12 01:38:38 +02:00
|
|
|
|
vim.api.nvim_create_user_command('Connect',
|
|
|
|
|
function(args)
|
2023-04-13 00:54:01 +02:00
|
|
|
|
if M.jobid ~= nil and M.jobid > 0 then
|
2023-04-12 01:38:38 +02:00
|
|
|
|
print("already connected, disconnect first")
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
local bin_args = { BINARY }
|
2023-04-12 16:58:28 +02:00
|
|
|
|
if #args.fargs > 0 then
|
2023-04-12 01:38:38 +02:00
|
|
|
|
table.insert(bin_args, "--host")
|
2023-04-13 00:54:01 +02:00
|
|
|
|
table.insert(bin_args, auto_address(args.fargs[1]))
|
2023-04-12 01:38:38 +02:00
|
|
|
|
end
|
2023-04-12 18:12:50 +02:00
|
|
|
|
if vim.g.codemp_remote_debug then
|
|
|
|
|
table.insert(bin_args, "--remote-debug")
|
|
|
|
|
table.insert(bin_args, vim.g.codemp_remote_debug)
|
|
|
|
|
end
|
2023-04-12 01:38:38 +02:00
|
|
|
|
if args.bang then
|
|
|
|
|
table.insert(bin_args, "--debug")
|
|
|
|
|
end
|
|
|
|
|
M.jobid = vim.fn.jobstart(
|
|
|
|
|
bin_args,
|
|
|
|
|
{
|
|
|
|
|
rpc = true,
|
2023-04-12 05:00:18 +02:00
|
|
|
|
on_stderr = function(_, data, _)
|
|
|
|
|
for _, line in pairs(data) do
|
|
|
|
|
print(line)
|
|
|
|
|
end
|
|
|
|
|
-- print(vim.fn.join(data, "\n"))
|
|
|
|
|
end,
|
|
|
|
|
stderr_buffered = false,
|
2023-04-19 04:18:22 +02:00
|
|
|
|
env = { RUST_BACKTRACE = 1 }
|
2023-04-12 01:38:38 +02:00
|
|
|
|
}
|
|
|
|
|
)
|
2023-04-12 04:21:02 +02:00
|
|
|
|
if M.jobid <= 0 then
|
|
|
|
|
print("[!] could not start codemp client")
|
|
|
|
|
end
|
2023-04-12 01:38:38 +02:00
|
|
|
|
end,
|
|
|
|
|
{ nargs='?', bang=true })
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_create_user_command('Stop',
|
|
|
|
|
function(_)
|
|
|
|
|
vim.fn.jobstop(M.jobid)
|
|
|
|
|
M.jobid = nil
|
|
|
|
|
end,
|
|
|
|
|
{ bang=true })
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_create_user_command('Share',
|
2023-04-11 22:35:27 +02:00
|
|
|
|
function(args)
|
2023-04-12 05:23:20 +02:00
|
|
|
|
if M.jobid == nil or M.jobid <= 0 then
|
2023-04-12 04:21:02 +02:00
|
|
|
|
print("[!] connect to codemp server first")
|
|
|
|
|
return
|
|
|
|
|
end
|
2023-04-11 22:35:27 +02:00
|
|
|
|
local path = args.fargs[1]
|
|
|
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
|
|
|
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
|
2023-04-19 18:18:13 +02:00
|
|
|
|
vim.opt.fileformat = "unix"
|
2023-04-11 22:35:27 +02:00
|
|
|
|
M.create(path, vim.fn.join(lines, "\n"))
|
2023-04-12 00:31:59 +02:00
|
|
|
|
hook_callbacks(path, bufnr)
|
2023-04-11 22:35:27 +02:00
|
|
|
|
M.attach(path)
|
2023-04-12 03:29:42 +02:00
|
|
|
|
M.listen(path)
|
2023-04-11 22:35:27 +02:00
|
|
|
|
end,
|
2023-04-12 01:38:38 +02:00
|
|
|
|
{ nargs=1 })
|
2023-04-11 22:35:27 +02:00
|
|
|
|
|
2023-04-12 01:38:38 +02:00
|
|
|
|
vim.api.nvim_create_user_command('Join',
|
2023-04-11 22:35:27 +02:00
|
|
|
|
function(args)
|
2023-04-12 05:23:20 +02:00
|
|
|
|
if M.jobid == nil or M.jobid <= 0 then
|
2023-04-12 04:21:02 +02:00
|
|
|
|
print("[!] connect to codemp server first")
|
|
|
|
|
return
|
|
|
|
|
end
|
2023-04-11 22:35:27 +02:00
|
|
|
|
local path = args.fargs[1]
|
2023-04-12 00:31:59 +02:00
|
|
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
2023-04-19 18:18:13 +02:00
|
|
|
|
vim.opt.fileformat = "unix"
|
2023-04-12 00:31:59 +02:00
|
|
|
|
hook_callbacks(path, bufnr)
|
2023-04-11 22:35:27 +02:00
|
|
|
|
M.attach(path)
|
2023-04-12 03:29:42 +02:00
|
|
|
|
M.listen(path)
|
2023-04-11 22:35:27 +02:00
|
|
|
|
end,
|
2023-04-12 01:38:38 +02:00
|
|
|
|
{ nargs=1 })
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_create_user_command('Detach',
|
|
|
|
|
function(args)
|
|
|
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
2023-04-20 03:47:35 +02:00
|
|
|
|
if M.detach(args.fargs[1]) then
|
|
|
|
|
unhook_callbacks(bufnr)
|
|
|
|
|
print("[/] detached from buffer")
|
|
|
|
|
else
|
|
|
|
|
print("[!] error detaching from buffer")
|
|
|
|
|
end
|
2023-04-12 01:38:38 +02:00
|
|
|
|
end,
|
|
|
|
|
{ nargs=1 })
|
2023-04-11 22:35:27 +02:00
|
|
|
|
|
2023-04-11 06:20:40 +02:00
|
|
|
|
return M
|