chore: global CODEMP object

i dont really like global state but it seems to be necessary when
working with callbacks
This commit is contained in:
əlemi 2024-09-17 17:26:23 +02:00
parent 45231e3eb8
commit d524076412
Signed by: alemi
GPG key ID: A4895B84D311642C
9 changed files with 80 additions and 94 deletions

View file

@ -1,5 +1,4 @@
local utils = require('codemp.utils') local utils = require('codemp.utils')
local session = require('codemp.session')
---@type table<integer, string> ---@type table<integer, string>
local id_buffer_map = {} local id_buffer_map = {}
@ -24,7 +23,7 @@ local function attach(name, buffer, content, nowait)
vim.api.nvim_set_option_value('fileformat', 'unix', { buf = buffer }) vim.api.nvim_set_option_value('fileformat', 'unix', { buf = buffer })
vim.api.nvim_buf_set_name(buffer, name) vim.api.nvim_buf_set_name(buffer, name)
session.workspace:attach(name):and_then(function (controller) CODEMP.workspace:attach(name):and_then(function (controller)
if not nowait then if not nowait then
local promise = controller:poll() local promise = controller:poll()
for i=1, 20, 1 do for i=1, 20, 1 do
@ -139,7 +138,7 @@ local function detach(name)
local buffer = buffer_id_map[name] local buffer = buffer_id_map[name]
id_buffer_map[buffer] = nil id_buffer_map[buffer] = nil
buffer_id_map[name] = nil buffer_id_map[name] = nil
session.workspace:detach(name) CODEMP.workspace:detach(name)
vim.api.nvim_buf_delete(buffer, {}) vim.api.nvim_buf_delete(buffer, {})
print(" -- detached from buffer " .. name) print(" -- detached from buffer " .. name)
@ -153,7 +152,7 @@ local function sync(buffer)
end end
local name = id_buffer_map[buffer] local name = id_buffer_map[buffer]
if name ~= nil then if name ~= nil then
local controller = session.workspace:get_buffer(name) local controller = CODEMP.workspace:get_buffer(name)
if controller ~= nil then if controller ~= nil then
local real_content = controller:content():await() local real_content = controller:content():await()
local my_content = utils.buffer.get_content(buffer) local my_content = utils.buffer.get_content(buffer)
@ -175,10 +174,10 @@ local function create(buffer)
if buffer == nil then if buffer == nil then
buffer = vim.fn.expand("%p") buffer = vim.fn.expand("%p")
end end
if session.workspace == nil then if CODEMP.workspace == nil then
error("join a workspace first") error("join a workspace first")
end end
session.workspace:create(buffer):and_then(function () CODEMP.workspace:create(buffer):and_then(function ()
print(" ++ created buffer " .. buffer) print(" ++ created buffer " .. buffer)
require('codemp.window').update() require('codemp.window').update()
end) end)

View file

@ -1,14 +1,16 @@
local workspace = require("codemp.workspace") local workspace = require("codemp.workspace")
local function connect() local function connect()
if CODEMP.config.username == nil then ---@type Config
CODEMP.config.username = vim.g.codemp_username or vim.fn.input("username > ", "") local tmp_cfg = vim.tbl_extend('force', {}, CODEMP.config)
if not tmp_cfg.username then
tmp_cfg.username = vim.g.codemp_username or vim.fn.input("username > ", "")
end end
if CODEMP.config.password == nil then if not tmp_cfg.password then
CODEMP.config.password = vim.g.codemp_password or vim.fn.input("password > ", "") tmp_cfg.password = vim.g.codemp_password or vim.fn.input("password > ", "")
end end
CODEMP.native.connect(CODEMP.config):and_then(function (client) CODEMP.native.connect(tmp_cfg):and_then(function (client)
require('codemp.session').client = client CODEMP.client = client
require('codemp.window').update() require('codemp.window').update()
workspace.list() workspace.list()
end) end)

View file

@ -1,4 +1,3 @@
local session = require('codemp.session')
local buffers = require('codemp.buffers') local buffers = require('codemp.buffers')
local workspace = require('codemp.workspace') local workspace = require('codemp.workspace')
local utils = require('codemp.utils') local utils = require('codemp.utils')
@ -33,15 +32,15 @@ local base_actions = {
-- only available if state.client is not nil -- only available if state.client is not nil
local connected_actions = { local connected_actions = {
id = function() id = function()
print("> codemp::" .. session.client.id) print("> codemp::" .. CODEMP.client.id)
end, end,
join = function(ws) join = function(ws)
if ws == nil then if ws == nil then
local opts = { prompt = "Select workspace to join:", format_item = function (x) return x.name end } local opts = { prompt = "Select workspace to join:", format_item = function (x) return x.name end }
return vim.ui.select(session.available, opts, function (choice) return vim.ui.select(CODEMP.available, opts, function (choice)
if choice == nil then return end -- action canceled by user if choice == nil then return end -- action canceled by user
workspace.join(session.available[choice].name) workspace.join(CODEMP.available[choice].name)
end) end)
else else
workspace.join(ws) workspace.join(ws)
@ -50,36 +49,36 @@ local connected_actions = {
start = function(ws) start = function(ws)
if ws == nil then error("missing workspace name") end if ws == nil then error("missing workspace name") end
session.client:create_workspace(ws):and_then(function () CODEMP.client:create_workspace(ws):and_then(function ()
print(" <> created workspace " .. ws) print(" <> created workspace " .. ws)
workspace.list() workspace.list()
end) end)
end, end,
available = function() available = function()
for _, ws in ipairs(session.client:list_workspaces(true, false):await()) do for _, ws in ipairs(CODEMP.client:list_workspaces(true, false):await()) do
print(" ++ " .. ws) print(" ++ " .. ws)
end end
for _, ws in ipairs(session.client:list_workspaces(false, true):await()) do for _, ws in ipairs(CODEMP.client:list_workspaces(false, true):await()) do
print(" -- " .. ws) print(" -- " .. ws)
end end
end, end,
invite = function(user) invite = function(user)
local ws local ws
if session.workspace ~= nil then if CODEMP.workspace ~= nil then
ws = session.workspace.name ws = CODEMP.workspace.name
else else
ws = vim.fn.input("workspace > ", "") ws = vim.fn.input("workspace > ", "")
end end
session.client:invite_to_workspace(ws, user):and_then(function () CODEMP.client:invite_to_workspace(ws, user):and_then(function ()
print(" :: invited " .. user .. " to workspace " .. ws) print(" :: invited " .. user .. " to workspace " .. ws)
end) end)
end, end,
disconnect = function() disconnect = function()
print(" xx disconnecting client " .. session.client.id) print(" xx disconnecting client " .. CODEMP.client.id)
session.client = nil -- should drop and thus close everything CODEMP.client = nil -- should drop and thus close everything
end, end,
} }
@ -110,13 +109,13 @@ local joined_actions = {
delete = function(path) delete = function(path)
if path == nil then error("missing buffer name") end if path == nil then error("missing buffer name") end
session.workspace:delete(path):and_then(function() CODEMP.workspace:delete(path):and_then(function()
print(" xx deleted buffer " .. path) print(" xx deleted buffer " .. path)
end) end)
end, end,
buffers = function() buffers = function()
for _, buf in ipairs(session.workspace:filetree()) do for _, buf in ipairs(CODEMP.workspace:filetree()) do
if buffers.map_rev[buf] ~= nil then if buffers.map_rev[buf] ~= nil then
print(" +- " .. buf) print(" +- " .. buf)
else else
@ -141,7 +140,7 @@ local joined_actions = {
buffers.attach(p, buffer) buffers.attach(p, buffer)
end end
if path == nil then if path == nil then
local filetree = session.workspace:filetree(nil, false) local filetree = CODEMP.workspace:filetree(nil, false)
return vim.ui.select(filetree, { prompt = "Select buffer to attach to:" }, function (choice) return vim.ui.select(filetree, { prompt = "Select buffer to attach to:" }, function (choice)
if choice == nil then return end -- action canceled by user if choice == nil then return end -- action canceled by user
doit(filetree[choice]) doit(filetree[choice])
@ -173,11 +172,11 @@ vim.api.nvim_create_user_command(
fn = base_actions[action] fn = base_actions[action]
end end
if session.client ~= nil and connected_actions[action] ~= nil then if CODEMP.client ~= nil and connected_actions[action] ~= nil then
fn = connected_actions[action] fn = connected_actions[action]
end end
if session.workspace ~= nil and joined_actions[action] ~= nil then if CODEMP.workspace ~= nil and joined_actions[action] ~= nil then
fn = joined_actions[action] fn = joined_actions[action]
end end
@ -203,13 +202,13 @@ vim.api.nvim_create_user_command(
n = n + 1 n = n + 1
suggestions[n] = sugg suggestions[n] = sugg
end end
if session.client ~= nil then if CODEMP.client ~= nil then
for sugg, _ in pairs(connected_actions) do for sugg, _ in pairs(connected_actions) do
n = n + 1 n = n + 1
suggestions[n] = sugg suggestions[n] = sugg
end end
end end
if session.workspace ~= nil then if CODEMP.workspace ~= nil then
for sugg, _ in pairs(joined_actions) do for sugg, _ in pairs(joined_actions) do
n = n + 1 n = n + 1
suggestions[n] = sugg suggestions[n] = sugg
@ -218,11 +217,11 @@ vim.api.nvim_create_user_command(
return filter(lead, suggestions) return filter(lead, suggestions)
elseif stage == 3 then elseif stage == 3 then
if args[#args-1] == 'attach' or args[#args-1] == 'detach' then if args[#args-1] == 'attach' or args[#args-1] == 'detach' then
if session.client ~= nil and session.workspace ~= nil then if CODEMP.client ~= nil and CODEMP.workspace ~= nil then
return filter(lead, session.workspace:filetree()) return filter(lead, CODEMP.workspace:filetree())
end end
elseif args[#args-1] == 'join' then elseif args[#args-1] == 'join' then
return filter(lead, session.available, function(ws) return ws.name end) return filter(lead, CODEMP.available, function(ws) return ws.name end)
end end
return {} return {}

View file

@ -1,14 +1,26 @@
---@class WorkspaceReference
---@field name string
---@field owned boolean
if CODEMP == nil then if CODEMP == nil then
---@class CodempGlobal ---@class CodempGlobal
---@field rt? RuntimeDriver background codemp runtime
---@field client? Client currently connected client
---@field workspace? Workspace current active workspace
---@field available? WorkspaceReference[] available workspaces to connect to
---@field timer? any libuv timer
---@field config Config codemp configuration
---@field setup fun(opts: Config): nil update codemp configuration
CODEMP = { CODEMP = {
rt = nil, rt = nil,
session = nil,
native = nil, native = nil,
timer = nil, timer = nil,
config = { config = {
neo_tree = false, neo_tree = false,
timer_interval = 20, timer_interval = 20,
debug = false, debug = false,
username = "",
password = "",
}, },
setup = function (opts) setup = function (opts)
CODEMP.config = vim.tbl_extend('force', CODEMP.config, opts) CODEMP.config = vim.tbl_extend('force', CODEMP.config, opts)
@ -26,19 +38,15 @@ if CODEMP.native == nil then
--end, true) --end, true)
end end
if CODEMP.session == nil then
CODEMP.session = require('codemp.session')
end
if CODEMP.rt == nil then if CODEMP.rt == nil then
CODEMP.rt = CODEMP.native.spawn_runtime_driver() -- spawn thread to drive tokio runtime CODEMP.rt = CODEMP.native.spawn_runtime_driver() -- spawn thread to drive tokio runtime
vim.api.nvim_create_autocmd( vim.api.nvim_create_autocmd(
{"ExitPre"}, {"ExitPre"},
{ {
callback = function (_ev) callback = function (_ev)
if CODEMP.session.client ~= nil then if CODEMP.client ~= nil then
print(" xx disconnecting codemp client") print(" xx disconnecting codemp client")
CODEMP.session.client = nil CODEMP.client = nil
end end
CODEMP.rt:stop() CODEMP.rt:stop()
end end

View file

@ -1,5 +1,4 @@
local renderer = require("neo-tree.ui.renderer") local renderer = require("neo-tree.ui.renderer")
local codemp = require("codemp.session")
local buf_manager = require("codemp.buffers") local buf_manager = require("codemp.buffers")
---@module 'nui.tree' ---@module 'nui.tree'
@ -125,15 +124,15 @@ M.update_state = function(state)
} }
} }
if codemp.workspace ~= nil then if CODEMP.workspace ~= nil then
local ws_section = new_root("#" .. codemp.workspace.name) local ws_section = new_root("#" .. CODEMP.workspace.name)
for i, path in ipairs(codemp.workspace:filetree()) do for i, path in ipairs(CODEMP.workspace:filetree()) do
table.insert(ws_section.children, new_item(codemp.workspace.name, path)) table.insert(ws_section.children, new_item(CODEMP.workspace.name, path))
end end
local usr_section = new_root("users") local usr_section = new_root("users")
for user, buffer in pairs(buf_manager.users) do for user, buffer in pairs(buf_manager.users) do
table.insert(usr_section.children, new_user(codemp.workspace.name, user)) table.insert(usr_section.children, new_user(CODEMP.workspace.name, user))
end end
table.insert(ws_section.children, spacer()) table.insert(ws_section.children, spacer())
table.insert(ws_section.children, usr_section) table.insert(ws_section.children, usr_section)
@ -142,23 +141,23 @@ M.update_state = function(state)
table.insert(root, ws_section) table.insert(root, ws_section)
end end
if codemp.client ~= nil then if CODEMP.client ~= nil then
local ws_section = new_root("workspaces") local ws_section = new_root("workspaces")
for _, ws in ipairs(codemp.available) do for _, ws in ipairs(CODEMP.available) do
table.insert(ws_section.children, new_workspace(ws.name, ws.owned)) table.insert(ws_section.children, new_workspace(ws.name, ws.owned))
end end
table.insert(root, spacer()) table.insert(root, spacer())
table.insert(root, ws_section) table.insert(root, ws_section)
local status_section = new_root("client") local status_section = new_root("client")
table.insert(status_section.children, new_entry("id", codemp.client.id)) table.insert(status_section.children, new_entry("id", CODEMP.client.id))
table.insert(status_section.children, new_entry("name", codemp.client.username)) table.insert(status_section.children, new_entry("name", CODEMP.client.username))
table.insert(root, spacer()) table.insert(root, spacer())
table.insert(root, status_section) table.insert(root, status_section)
end end
if codemp.client == nil then if CODEMP.client == nil then
table.insert(root, spacer()) table.insert(root, spacer())
table.insert(root, new_button("[connect]")) table.insert(root, new_button("[connect]"))
end end
@ -166,8 +165,8 @@ M.update_state = function(state)
renderer.show_nodes(root, state) renderer.show_nodes(root, state)
local new_state = "disconnected" local new_state = "disconnected"
if codemp.client ~= nil then new_state = "connected" end if CODEMP.client ~= nil then new_state = "connected" end
if codemp.workspace ~= nil then new_state = "joined" end if CODEMP.workspace ~= nil then new_state = "joined" end
if last_state ~= new_state then expand(state.tree) end if last_state ~= new_state then expand(state.tree) end
last_state = new_state last_state = new_state

View file

@ -2,7 +2,6 @@ local cc = require("neo-tree.sources.common.commands")
local utils = require("neo-tree.utils") local utils = require("neo-tree.utils")
local codemp_utils = require("codemp.utils") local codemp_utils = require("codemp.utils")
local manager = require("neo-tree.sources.manager") local manager = require("neo-tree.sources.manager")
local session = require("codemp.session")
local buf_manager = require("codemp.buffers") local buf_manager = require("codemp.buffers")
local ws_manager = require("codemp.workspace") local ws_manager = require("codemp.workspace")
local client_manager = require("codemp.client") local client_manager = require("codemp.client")
@ -27,16 +26,16 @@ M.open = function(state, path, extra)
if selected.type == "entry" then return end if selected.type == "entry" then return end
if selected.type == "root" then return toggle(selected) end if selected.type == "root" then return toggle(selected) end
if selected.type == "button" then if selected.type == "button" then
if selected.name == "[connect]" and session.client == nil then if selected.name == "[connect]" and CODEMP.client == nil then
client_manager.connect() client_manager.connect()
end end
return return
end end
if selected.type == "workspace" then if selected.type == "workspace" then
if session.workspace ~= nil and session.workspace.name ~= selected.name then if CODEMP.workspace ~= nil and CODEMP.workspace.name ~= selected.name then
error("must leave current workspace first") error("must leave current workspace first")
end end
if session.workspace == nil then if CODEMP.workspace == nil then
ws_manager.join(selected.name) ws_manager.join(selected.name)
end end
manager.refresh("codemp") manager.refresh("codemp")
@ -112,21 +111,21 @@ M.delete = function(state, path, extra)
manager.refresh("codemp") manager.refresh("codemp")
end) end)
elseif selected.type == "buffer" then elseif selected.type == "buffer" then
if session.workspace == nil then error("join a workspace first") end if CODEMP.workspace == nil then error("join a workspace first") end
vim.ui.input({ prompt = "delete buffer '" .. selected.name .. "'?" }, function (input) vim.ui.input({ prompt = "delete buffer '" .. selected.name .. "'?" }, function (input)
if input == nil then return end if input == nil then return end
if not vim.startswith("y", string.lower(input)) then return end if not vim.startswith("y", string.lower(input)) then return end
session.workspace:delete(selected.name):and_then(function () CODEMP.workspace:delete(selected.name):and_then(function ()
print("deleted buffer " .. selected.name) print("deleted buffer " .. selected.name)
manager.refresh("codemp") manager.refresh("codemp")
end) end)
end) end)
elseif selected.type == "workspace" then elseif selected.type == "workspace" then
if session.client == nil then error("connect to server first") end if CODEMP.client == nil then error("connect to server first") end
vim.ui.input({ prompt = "delete buffer '" .. selected.name .. "'?" }, function (input) vim.ui.input({ prompt = "delete buffer '" .. selected.name .. "'?" }, function (input)
if input == nil then return end if input == nil then return end
if not vim.startswith("y", string.lower(input)) then return end if not vim.startswith("y", string.lower(input)) then return end
session.client:delete_workspace(selected.name):and_then(function () CODEMP.client:delete_workspace(selected.name):and_then(function ()
print("deleted workspace " .. selected.name) print("deleted workspace " .. selected.name)
manager.refresh("codemp") manager.refresh("codemp")
end) end)
@ -140,14 +139,14 @@ M.add = function(state, path, extra)
if vim.startswith(selected.name, "#") then if vim.startswith(selected.name, "#") then
vim.ui.input({ prompt = "new buffer path" }, function(input) vim.ui.input({ prompt = "new buffer path" }, function(input)
if input == nil or input == "" then return end if input == nil or input == "" then return end
session.workspace:create(input):and_then(function () CODEMP.workspace:create(input):and_then(function ()
manager.refresh("codemp") manager.refresh("codemp")
end) end)
end) end)
elseif selected.name == "workspaces" then elseif selected.name == "workspaces" then
vim.ui.input({ prompt = "new workspace name" }, function(input) vim.ui.input({ prompt = "new workspace name" }, function(input)
if input == nil or input == "" then return end if input == nil or input == "" then return end
session.client:create_workspace(input):and_then(function () CODEMP.client:create_workspace(input):and_then(function ()
require('codemp.workspace').list() require('codemp.workspace').list()
end) end)
end) end)
@ -155,7 +154,7 @@ M.add = function(state, path, extra)
elseif selected.type == "workspace" then elseif selected.type == "workspace" then
vim.ui.input({ prompt = "user name to invite" }, function(input) vim.ui.input({ prompt = "user name to invite" }, function(input)
if input == nil or input == "" then return end if input == nil or input == "" then return end
session.client:invite_to_workspace(selected.name, input):and_then(function () CODEMP.client:invite_to_workspace(selected.name, input):and_then(function ()
print("invited user " .. input .. " to workspace " .. selected.name) print("invited user " .. input .. " to workspace " .. selected.name)
end) end)
end) end)

View file

@ -1,18 +0,0 @@
---@type Workspace
local workspace
---@type Client
local client
---@class WorkspaceReference
---@field name string
---@field owned boolean
---@type WorkspaceReference[]
local available_workspaces = {}
return {
workspace = workspace,
client = client,
available = available_workspaces,
}

View file

@ -9,7 +9,6 @@ end
-- legacy crude filetree if neo-tree is not available -- legacy crude filetree if neo-tree is not available
local session = require('codemp.session')
local utils = require('codemp.utils') local utils = require('codemp.utils')
local buffers = require('codemp.buffers') local buffers = require('codemp.buffers')
@ -41,10 +40,10 @@ local function update_window()
local buffer_to_row = {} local buffer_to_row = {}
local user_to_row = {} local user_to_row = {}
local off = {} local off = {}
local tree = session.workspace:filetree() local tree = CODEMP.workspace:filetree()
vim.api.nvim_set_option_value('modifiable', true, { buf = buffer_id }) vim.api.nvim_set_option_value('modifiable', true, { buf = buffer_id })
local tmp = ">| codemp\n" local tmp = ">| codemp\n"
tmp = tmp .. " |: " .. session.workspace.name .. "\n" tmp = tmp .. " |: " .. CODEMP.workspace.name .. "\n"
tmp = tmp .. " |\n" tmp = tmp .. " |\n"
local base_row = 3 local base_row = 3
for n, path in pairs(tree) do for n, path in pairs(tree) do

View file

@ -1,6 +1,5 @@
local utils = require('codemp.utils') local utils = require('codemp.utils')
local buffers = require('codemp.buffers') local buffers = require('codemp.buffers')
local session = require('codemp.session')
---@class UserHighlight ---@class UserHighlight
---@field ns integer namespace to use for this user ---@field ns integer namespace to use for this user
@ -12,21 +11,21 @@ local user_hl = {}
local function fetch_workspaces_list() local function fetch_workspaces_list()
local new_list = {} local new_list = {}
session.client:list_workspaces(true, false):and_then(function (owned) CODEMP.client:list_workspaces(true, false):and_then(function (owned)
for _, ws in pairs(owned) do for _, ws in pairs(owned) do
table.insert(new_list, { table.insert(new_list, {
name = ws, name = ws,
owned = true, owned = true,
}) })
end end
session.client:list_workspaces(false, true):and_then(function (invited) CODEMP.client:list_workspaces(false, true):and_then(function (invited)
for _, ws in pairs(invited) do for _, ws in pairs(invited) do
table.insert(new_list, { table.insert(new_list, {
name = ws, name = ws,
owned = false, owned = false,
}) })
end end
session.available = new_list CODEMP.available = new_list
require('codemp.window').update() require('codemp.window').update()
end) end)
end) end)
@ -109,7 +108,7 @@ end
---@param workspace string workspace name to join ---@param workspace string workspace name to join
---join a workspace and register event handlers ---join a workspace and register event handlers
local function join(workspace) local function join(workspace)
session.client:join_workspace(workspace):and_then(function (ws) CODEMP.client:join_workspace(workspace):and_then(function (ws)
print(" >< joined workspace " .. ws.name) print(" >< joined workspace " .. ws.name)
register_cursor_callback(ws) register_cursor_callback(ws)
register_cursor_handler(ws) register_cursor_handler(ws)
@ -138,15 +137,15 @@ local function join(workspace)
end end
) )
session.workspace = ws CODEMP.workspace = ws
require('codemp.window').update() require('codemp.window').update()
end) end)
end end
local function leave() local function leave()
session.client:leave_workspace(session.workspace.name) CODEMP.client:leave_workspace(CODEMP.workspace.name)
print(" -- left workspace") print(" -- left workspace")
session.workspace = nil CODEMP.workspace = nil
end end
return { return {