mirror of
https://github.com/hexedtech/codemp-nvim.git
synced 2024-12-23 22:04:52 +01:00
feat: use neo-tree if available for tree view
must also add it to registered sources: add `codemp.neo-tree` and done
This commit is contained in:
parent
3e26103064
commit
db24f06633
6 changed files with 364 additions and 2 deletions
132
src/neo-tree/bridge.lua
Normal file
132
src/neo-tree/bridge.lua
Normal file
|
@ -0,0 +1,132 @@
|
|||
local renderer = require("neo-tree.ui.renderer")
|
||||
local codemp = require("codemp.session")
|
||||
local cc = require("neo-tree.sources.common.commands")
|
||||
local buf_manager = require("codemp.buffers")
|
||||
|
||||
local M = {}
|
||||
|
||||
---@class Item
|
||||
---@field id string
|
||||
---@field name string
|
||||
---@field type string
|
||||
---@field loaded any
|
||||
---@field filtered_by any
|
||||
---@field extra table
|
||||
---@field is_nested any
|
||||
---@field skip_node any
|
||||
---@field is_empty_with_hidden_root any
|
||||
---@field stat any
|
||||
---@field stat_provider any
|
||||
---@field is_link any
|
||||
---@field link_to any
|
||||
---@field path any
|
||||
---@field ext any
|
||||
---@field search_pattern any
|
||||
|
||||
---@param workspace string workspace name
|
||||
---@param path string buffer relative path
|
||||
---@return Item
|
||||
local function new_item(workspace, path)
|
||||
return {
|
||||
id = string.format("codemp://%s/%s", workspace, path),
|
||||
name = path,
|
||||
type = "buffer",
|
||||
extra = {},
|
||||
children = {},
|
||||
}
|
||||
end
|
||||
|
||||
---@param workspace string workspace name
|
||||
---@param username string user display name
|
||||
---@return Item
|
||||
local function new_user(workspace, username)
|
||||
return {
|
||||
id = string.format("codemp://%s@%s", username, workspace),
|
||||
name = username,
|
||||
type = "user",
|
||||
extra = {},
|
||||
children = {},
|
||||
}
|
||||
end
|
||||
|
||||
---@param name string workspace name
|
||||
---@param owned boolean true if this workspace is owned by us
|
||||
---@param expanded? boolean if node should be pre-expanded
|
||||
---@return Item
|
||||
local function new_workspace(name, owned, expanded)
|
||||
return {
|
||||
id = "codemp://" .. name,
|
||||
name = name,
|
||||
type = "workspace",
|
||||
['_is_expanded'] = expanded, -- TODO this is nasty can we do better?
|
||||
extra = {
|
||||
owned = owned,
|
||||
},
|
||||
children = {},
|
||||
}
|
||||
end
|
||||
|
||||
local function spacer()
|
||||
return {
|
||||
id = "codemp-ws-spacer-" .. vim.fn.rand() % 1024,
|
||||
name = "",
|
||||
type = "spacer",
|
||||
}
|
||||
end
|
||||
|
||||
M.update_state = function(state)
|
||||
---@type Item
|
||||
local root
|
||||
|
||||
if codemp.workspace ~= nil then
|
||||
root = {
|
||||
id = "codemp",
|
||||
name = codemp.client.username .. "@" .. codemp.workspace.name,
|
||||
type = "root",
|
||||
extra = {},
|
||||
children = {}
|
||||
}
|
||||
table.insert(root.children, spacer())
|
||||
for i, path in ipairs(codemp.workspace:filetree()) do
|
||||
table.insert(root.children, new_item(codemp.workspace.name, path))
|
||||
end
|
||||
table.insert(root.children, spacer())
|
||||
for user, buffer in pairs(buf_manager.users) do
|
||||
table.insert(root.children, new_user(codemp.workspace.name, user))
|
||||
end
|
||||
elseif codemp.client ~= nil then
|
||||
root = {
|
||||
id = "codemp",
|
||||
name = codemp.client.username .. "@codemp",
|
||||
type = "root",
|
||||
extra = {},
|
||||
children = {}
|
||||
}
|
||||
for _, ws in ipairs(codemp.available) do
|
||||
local workspace = new_workspace(ws.name, ws.owned)
|
||||
|
||||
if codemp.workspace ~= nil and codemp.workspace.name == ws.name then
|
||||
end
|
||||
|
||||
table.insert(root.children, workspace)
|
||||
end
|
||||
else
|
||||
root = {
|
||||
id = "codemp",
|
||||
name = "codemp",
|
||||
type = "root",
|
||||
extra = {},
|
||||
children = {}
|
||||
}
|
||||
end
|
||||
|
||||
renderer.show_nodes({ root }, state)
|
||||
|
||||
if codemp.workspace ~= nil then
|
||||
for _, node in ipairs(state.tree:get_nodes()) do
|
||||
node:expand()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
69
src/neo-tree/commands.lua
Normal file
69
src/neo-tree/commands.lua
Normal file
|
@ -0,0 +1,69 @@
|
|||
local cc = require("neo-tree.sources.common.commands")
|
||||
local utils = require("neo-tree.utils")
|
||||
local manager = require("neo-tree.sources.manager")
|
||||
local session = require("codemp.session")
|
||||
local renderer = require("neo-tree.ui.renderer")
|
||||
local ws_manager = require("codemp.workspace")
|
||||
local buf_manager = require("codemp.buffers")
|
||||
local client_manager = require("codemp.client")
|
||||
|
||||
local M = {}
|
||||
|
||||
M.refresh = require("neo-tree.utils").wrap(manager.refresh, "codemp")
|
||||
|
||||
M.open = function(state, path, extra)
|
||||
local selected = state.tree:get_node()
|
||||
if selected.type == "spacer" then return end
|
||||
if selected.type == "root" then
|
||||
if session.client ~= nil then
|
||||
print(" +-+ connected to codemp as " .. session.client.username)
|
||||
else
|
||||
client_manager.connect()
|
||||
end
|
||||
return
|
||||
end
|
||||
if selected.type == "workspace" then
|
||||
if selected:is_expanded() then
|
||||
vim.ui.input({ prompt = "disconnect from workspace?" }, function (input)
|
||||
if input == nil then return end
|
||||
if input ~= "y" then return end
|
||||
ws_manager.leave()
|
||||
selected:collapse()
|
||||
manager.refresh("codemp")
|
||||
end)
|
||||
else
|
||||
if session.workspace ~= nil and session.workspace.name ~= selected.name then
|
||||
error("must leave current workspace first")
|
||||
end
|
||||
if session.workspace == nil then
|
||||
ws_manager.join(selected.name)
|
||||
end
|
||||
selected:expand()
|
||||
manager.refresh("codemp")
|
||||
end
|
||||
return
|
||||
end
|
||||
if selected.type == "buffer" then
|
||||
local window = utils.get_appropriate_window(state)
|
||||
vim.api.nvim_set_current_win(window)
|
||||
buf_manager.attach(selected.name)
|
||||
return
|
||||
end
|
||||
if selected.type == "user" then
|
||||
print("another remote user")
|
||||
return
|
||||
end
|
||||
error("unrecognized node type")
|
||||
end
|
||||
|
||||
M.add = function(_state)
|
||||
if session.workspace == nil then error("not in a workspace") end
|
||||
vim.ui.input({ prompt = "name" }, function(input)
|
||||
if input == nil or input == "" then return end
|
||||
session.workspace:create_buffer(input):await()
|
||||
manager.refresh("codemp")
|
||||
end)
|
||||
end
|
||||
|
||||
cc._add_common_commands(M)
|
||||
return M
|
84
src/neo-tree/components.lua
Normal file
84
src/neo-tree/components.lua
Normal file
|
@ -0,0 +1,84 @@
|
|||
-- This file contains the built-in components. Each componment is a function
|
||||
-- that takes the following arguments:
|
||||
-- config: A table containing the configuration provided by the user
|
||||
-- when declaring this component in their renderer config.
|
||||
-- node: A NuiNode object for the currently focused node.
|
||||
-- state: The current state of the source providing the items.
|
||||
--
|
||||
-- The function should return either a table, or a list of tables, each of which
|
||||
-- contains the following keys:
|
||||
-- text: The text to display for this item.
|
||||
-- highlight: The highlight group to apply to this text.
|
||||
|
||||
local highlights = require("neo-tree.ui.highlights")
|
||||
local common = require("neo-tree.sources.common.components")
|
||||
local codemp_utils = require("codemp.utils")
|
||||
local codemp_buffers = require("codemp.buffers")
|
||||
|
||||
local M = {}
|
||||
|
||||
M.icon = function(config, node, state)
|
||||
local icon, highlight
|
||||
if node.type == "buffer" then
|
||||
icon = "- "
|
||||
highlight = highlights.FILE_ICON
|
||||
elseif node.type == "directory" then
|
||||
icon = "= "
|
||||
highlight = highlights.DIRECTORY_ICON
|
||||
elseif node.type == "root" then
|
||||
icon = "> "
|
||||
highlight = highlights.FILE_STATS_HEADER
|
||||
elseif node.type == "workspace" then
|
||||
if node:is_expanded() then
|
||||
icon = "| "
|
||||
else
|
||||
icon = "+ "
|
||||
end
|
||||
highlight = highlights.SYMBOLIC_LINK_TARGET
|
||||
elseif node.type == "user" then
|
||||
icon = ":"
|
||||
highlight = codemp_utils.color(node.name)
|
||||
end
|
||||
|
||||
return {
|
||||
text = icon,
|
||||
highlight = highlight,
|
||||
}
|
||||
end
|
||||
|
||||
M.name = function(config, node, state)
|
||||
local highlight = config.highlight or highlights.FILE_NAME
|
||||
if node.type == "root" then
|
||||
highlight = highlights.ROOT_NAME
|
||||
elseif node.type == "workspace" then
|
||||
highlight = highlights.SYMBOLIC_LINK_TARGET
|
||||
end
|
||||
return {
|
||||
text = node.name,
|
||||
highlight = highlight,
|
||||
}
|
||||
end
|
||||
|
||||
M.spacer = function(config, node, state)
|
||||
return {
|
||||
text = " ",
|
||||
highlight = highlights.NORMAL,
|
||||
}
|
||||
end
|
||||
|
||||
M.users = function(config, node, state)
|
||||
local out = {}
|
||||
-- TODO this is rather inefficient, maybe store reverse map precalculated?
|
||||
for user, buf in pairs(codemp_buffers.users) do
|
||||
if buf == node.name then
|
||||
table.insert(out, {
|
||||
text = " ",
|
||||
highlight = codemp_utils.color(user),
|
||||
align = "right",
|
||||
})
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
return vim.tbl_deep_extend("force", common, M)
|
45
src/neo-tree/init.lua
Normal file
45
src/neo-tree/init.lua
Normal file
|
@ -0,0 +1,45 @@
|
|||
local bridge = require("codemp.neo-tree.bridge")
|
||||
|
||||
local M = { name = "codemp" }
|
||||
|
||||
M.navigate = function(state, path)
|
||||
if path == nil then
|
||||
path = vim.fn.getcwd()
|
||||
end
|
||||
state.path = path
|
||||
bridge.update_state(state)
|
||||
end
|
||||
|
||||
M.setup = function(config, global_config)
|
||||
end
|
||||
|
||||
M.default_config = {
|
||||
renderers = {
|
||||
spacer = {
|
||||
{ "indent" },
|
||||
},
|
||||
root = {
|
||||
{ "icon" },
|
||||
{ "name" },
|
||||
},
|
||||
workspace = {
|
||||
{ "indent" },
|
||||
{ "icon" },
|
||||
{ "name" },
|
||||
},
|
||||
user = {
|
||||
{ "indent" },
|
||||
{ "icon" },
|
||||
{ "name" },
|
||||
},
|
||||
buffer = {
|
||||
{ "indent" },
|
||||
{ "icon" },
|
||||
{ "name" },
|
||||
{ "spacer" },
|
||||
{ "users" },
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return M
|
|
@ -1,3 +1,17 @@
|
|||
local success, manager = pcall(require, "neo-tree.sources.manager")
|
||||
if success then
|
||||
-- we have Neotree installed! use it for cool tree view
|
||||
return {
|
||||
update = function () manager.refresh("codemp") end,
|
||||
init = function () end,
|
||||
open = function () vim.cmd(":Neotree open source=codemp<CR>") end,
|
||||
toggle = function () vim.cmd(":Neotree toggle source=codemp<CR>") end,
|
||||
}
|
||||
end
|
||||
|
||||
-- we don't have Neotree installed, cook a rough window
|
||||
|
||||
|
||||
local session = require('codemp.session')
|
||||
local utils = require('codemp.utils')
|
||||
local buffers = require('codemp.buffers')
|
||||
|
@ -144,6 +158,4 @@ return {
|
|||
open = open_window,
|
||||
update = update_window,
|
||||
toggle = toggle_window,
|
||||
buffer = buffer_id,
|
||||
id = window_id,
|
||||
}
|
||||
|
|
|
@ -5,6 +5,25 @@ local window = require('codemp.window')
|
|||
|
||||
local user_hl = {}
|
||||
|
||||
local function fetch_workspaces_list(client)
|
||||
local new_list = {}
|
||||
local owned = client:list_workspaces(true, false):await()
|
||||
for _, ws in pairs(owned) do
|
||||
table.insert(new_list, {
|
||||
name = ws,
|
||||
owned = true,
|
||||
})
|
||||
end
|
||||
local invited = client:list_workspaces(false, true):await()
|
||||
for _, ws in pairs(invited) do
|
||||
table.insert(new_list, {
|
||||
name = ws,
|
||||
owned = false,
|
||||
})
|
||||
end
|
||||
return new_list
|
||||
end
|
||||
|
||||
---@param ws Workspace
|
||||
local function register_cursor_callback(ws)
|
||||
local controller = ws.cursor
|
||||
|
@ -97,4 +116,5 @@ return {
|
|||
join = join,
|
||||
leave = leave,
|
||||
map = user_hl,
|
||||
list = fetch_workspaces_list,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue