feat: improved Lua API for plugin

added commands to connect/disconnect, jobid is kept internally, commands
to hook/unhook callbacks, refactored stuff a little
This commit is contained in:
əlemi 2023-04-12 01:38:38 +02:00
parent c1b7073e89
commit 55c4ddb93a
3 changed files with 81 additions and 37 deletions

View file

@ -1,51 +1,74 @@
local BINARY = "/home/alemi/projects/codemp/target/debug/client-nvim --debug" local BINARY = vim.g.codemp_binary or "/home/alemi/projects/codemp/target/debug/client-nvim"
if vim.g.codemp_jobid == nil then
vim.g.codemp_jobid = vim.fn.jobstart(
BINARY,
{
rpc = true,
on_stderr = function(_, data, _) print(vim.fn.join(data, "\n")) end,
}
)
end
local M = {} local M = {}
M.create = function(path, content) return vim.rpcrequest(vim.g.codemp_jobid, "create", path, content) end M.jobid = nil
M.insert = function(path, txt, pos) return vim.rpcrequest(vim.g.codemp_jobid, "insert", path, txt, pos) end M.create = function(path, content) return vim.rpcrequest(M.jobid, "create", path, content) end
M.delete = function(path, pos, count) return vim.rpcrequest(vim.g.codemp_jobid, "delete", path, pos, count) end M.insert = function(path, txt, pos) return vim.rpcrequest(M.jobid, "insert", path, txt, pos) end
M.attach = function(path) return vim.rpcrequest(vim.g.codemp_jobid, "attach", path) end M.delete = function(path, pos, count) return vim.rpcrequest(M.jobid, "delete", path, pos, count) end
M.attach = function(path) return vim.rpcrequest(M.jobid, "attach", path) end
M.detach = function(path) return vim.rpcrequest(M.jobid, "detach", path) end
local function cursor_offset() local function cursor_offset()
local cursor = vim.api.nvim_win_get_cursor(0) local cursor = vim.api.nvim_win_get_cursor(0)
return vim.fn.line2byte(cursor[1]) + cursor[2] - 1 return vim.fn.line2byte(cursor[1]) + cursor[2] - 1
end end
local codemp_autocmds = vim.api.nvim_create_augroup("CodempAuGroup", { clear = true })
local function hook_callbacks(path, buffer) local function hook_callbacks(path, buffer)
vim.api.nvim_create_autocmd( vim.api.nvim_create_autocmd(
{ "InsertCharPre" }, { "InsertCharPre" },
{ {
callback = function(_) M.insert(path, vim.v.char, cursor_offset()) end, callback = function(_) M.insert(path, vim.v.char, cursor_offset()) end,
buffer = buffer, buffer = buffer,
group = codemp_autocmds,
} }
) )
vim.keymap.set('i', '<BS>', function() vim.keymap.set('i', '<BS>', function() M.delete(path, cursor_offset(), 1) return '<BS>' end, {expr = true, buffer = buffer})
local off = cursor_offset() vim.keymap.set('i', '<Del>', function() M.delete(path, cursor_offset() + 1, 1) return '<Del>' end, {expr = true, buffer = buffer})
M.delete(path, off, 1) vim.keymap.set('i', '<CR>', function() M.insert(path, "\n", cursor_offset()) return '<CR>'end, {expr = true, buffer = buffer})
return '<BS>'
end, {expr = true, buffer = buffer})
vim.keymap.set('i', '<Del>', function()
M.delete(path, cursor_offset(), 1)
return '<Del>'
end, {expr = true, buffer = buffer})
vim.keymap.set('i', '<CR>', function()
M.insert(path, "\n", cursor_offset())
return '<CR>'
end, {expr = true, buffer = buffer})
end end
vim.api.nvim_create_user_command( local function unhook_callbacks(buffer)
'Share', vim.api.nvim_clear_autocmds({ group = codemp_autocmds, buffer = buffer })
vim.keymap.del('i', '<BS>', { buffer = buffer })
vim.keymap.del('i', '<Del>', { buffer = buffer })
vim.keymap.del('i', '<CR>', { buffer = buffer })
end
vim.api.nvim_create_user_command('Connect',
function(args)
if M.jobid ~= nil then
print("already connected, disconnect first")
return
end
local bin_args = { BINARY }
if #args.args > 0 then
table.insert(bin_args, "--host")
table.insert(bin_args, args.args[1])
end
if args.bang then
table.insert(bin_args, "--debug")
end
M.jobid = vim.fn.jobstart(
bin_args,
{
rpc = true,
on_stderr = function(_, data, _) print(vim.fn.join(data, "\n")) end,
}
)
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',
function(args) function(args)
local path = args.fargs[1] local path = args.fargs[1]
local bufnr = vim.api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
@ -54,18 +77,23 @@ vim.api.nvim_create_user_command(
hook_callbacks(path, bufnr) hook_callbacks(path, bufnr)
M.attach(path) M.attach(path)
end, end,
{nargs=1} { nargs=1 })
)
vim.api.nvim_create_user_command( vim.api.nvim_create_user_command('Join',
'Join',
function(args) function(args)
local path = args.fargs[1] local path = args.fargs[1]
local bufnr = vim.api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
hook_callbacks(path, bufnr) hook_callbacks(path, bufnr)
M.attach(path) M.attach(path)
end, end,
{nargs=1} { nargs=1 })
)
vim.api.nvim_create_user_command('Detach',
function(args)
local bufnr = vim.api.nvim_get_current_buf()
unhook_callbacks(bufnr)
M.detach(args.fargs[1])
end,
{ nargs=1 })
return M return M

View file

@ -137,6 +137,16 @@ impl Handler for NeovimHandler {
} }
}, },
"detach" => {
if args.len() < 1 {
return Err(Value::from("no path given"));
}
let path = default_empty_str(&args, 0);
let mut c = self.client.clone();
c.detach(path);
Ok(Value::Nil)
},
_ => Err(Value::from("unimplemented")), _ => Err(Value::from("unimplemented")),
} }
} }

View file

@ -1,7 +1,7 @@
/// TODO better name for this file /// TODO better name for this file
use std::{sync::{Arc, RwLock}, collections::BTreeMap}; use std::{sync::{Arc, RwLock}, collections::BTreeMap};
use tracing::{error, warn}; use tracing::{error, warn, info};
use uuid::Uuid; use uuid::Uuid;
use crate::{ use crate::{
@ -104,6 +104,10 @@ impl CodempClient {
Ok(content) Ok(content)
} }
pub fn detach(&mut self, path: String) {
self.factories.write().unwrap().remove(&path);
}
async fn sync(&mut self, path: String) -> Result<String, Status> { async fn sync(&mut self, path: String) -> Result<String, Status> {
let res = self.client.sync( let res = self.client.sync(
BufferPayload { BufferPayload {
@ -115,6 +119,7 @@ impl CodempClient {
async fn worker<F>(mut stream: Streaming<RawOp>, factory: Arc<AsyncFactory>, callback: F) async fn worker<F>(mut stream: Streaming<RawOp>, factory: Arc<AsyncFactory>, callback: F)
where F : Fn(String) -> () { where F : Fn(String) -> () {
info!("|> buffer worker started");
loop { loop {
match stream.message().await { match stream.message().await {
Err(e) => break error!("error receiving change: {}", e), Err(e) => break error!("error receiving change: {}", e),
@ -130,5 +135,6 @@ impl CodempClient {
}, },
} }
} }
info!("[] buffer worker stopped");
} }
} }