diff --git a/lua/codemp/buffers.lua b/lua/codemp/buffers.lua index 2284251..22a237e 100644 --- a/lua/codemp/buffers.lua +++ b/lua/codemp/buffers.lua @@ -8,19 +8,38 @@ local buffer_id_map = {} local user_buffer_name = {} local ticks = {} +---@class AttachOptions +---@field content? string if provided, set this as content after attaching +---@field nowait? boolean skip waiting for initial content sync +---@field window? integer if given, open attached buffer in this window +---@field buffer? integer if given, use provided buffer instead of creating a new one +---@field skip_exists_check? boolean skip vim.fn.bufexists check, used for recursive call +--- ---@param name string name of buffer to attach to ----@param buffer? integer buffer to use for attaching (will clear content) ----@param content? string if provided, set this content after attaching ----@param nowait? boolean skip waiting for initial content sync -local function attach(name, buffer, content, nowait) - if vim.fn.bufexists(name) == 1 then - error("buffer '" .. name .. "' already exists!") +---@param opts AttachOptions options for attaching +local function attach(name, opts) + if not opts.skip_exists_check and vim.fn.bufexists(name) == 1 then + vim.ui.select( + { "download content", "upload content" }, + { prompt = "buffer is already open" }, + function (choice) + if choice == nil then return end + opts.buffer = vim.fn.bufnr(name) + opts.skip_exists_check = true + if choice == "upload content" then + opts.content = utils.buffer.get_content(opts.buffer) + end + attach(name, opts) + end + ) + return end if buffer_id_map[name] ~= nil then - error("already attached to buffer " .. name) + return print(" !! already attached to buffer " .. name) end + local buffer = opts.buffer if buffer == nil then buffer = vim.api.nvim_get_current_buf() end @@ -29,7 +48,7 @@ local function attach(name, buffer, content, nowait) vim.api.nvim_buf_set_name(buffer, name) CODEMP.workspace:attach(name):and_then(function (controller) -- TODO disgusting! but poll blocks forever on empty buffers... - if not nowait then + if not opts.nowait then local promise = controller:poll() for i=1, 20, 1 do if promise.ready then break end @@ -37,6 +56,11 @@ local function attach(name, buffer, content, nowait) end end + if opts.window ~= nil then + vim.api.nvim_win_set_buf(opts.window, buffer) + vim.api.nvim_set_current_win(opts.window) + end + -- TODO map name to uuid id_buffer_map[buffer] = name @@ -115,10 +139,10 @@ local function attach(name, buffer, content, nowait) end)) local remote_content = controller:content():await() - if content ~= nil then + if opts.content ~= nil then -- TODO this may happen too soon!! local _ = controller:send({ - start = 0, finish = #remote_content, content = content + start = 0, finish = #remote_content, content = opts.content }) -- no need to await else local current_content = utils.buffer.get_content(buffer) diff --git a/lua/codemp/command.lua b/lua/codemp/command.lua index e60a0e2..7e44a39 100644 --- a/lua/codemp/command.lua +++ b/lua/codemp/command.lua @@ -136,7 +136,7 @@ local joined_actions = { buffer = vim.api.nvim_create_buf(true, false) vim.api.nvim_set_current_buf(buffer) end - buffers.attach(p, buffer) + buffers.attach(p, { buffer = buffer }) end if path == nil then local filetree = CODEMP.workspace:filetree(nil, false) diff --git a/lua/codemp/neo-tree/commands.lua b/lua/codemp/neo-tree/commands.lua index 179ebee..64cb147 100644 --- a/lua/codemp/neo-tree/commands.lua +++ b/lua/codemp/neo-tree/commands.lua @@ -42,14 +42,13 @@ M.open = function(state, path, extra) end if selected.type == "buffer" then local window = utils.get_appropriate_window(state) - vim.api.nvim_set_current_win(window) if buf_manager.map_rev[selected.name] ~= nil then + vim.api.nvim_set_current_win(window) vim.api.nvim_win_set_buf(window, buf_manager.map_rev[selected.name]) - return + else + local buf = vim.api.nvim_create_buf(true, false) + buf_manager.attach(selected.name, { buffer = buf, window = window }) end - local buf = vim.api.nvim_create_buf(true, false) - vim.api.nvim_win_set_buf(window, buf) - buf_manager.attach(selected.name, buf) return end if selected.type == "user" then