mirror of
https://github.com/hexedtech/codemp-nvim.git
synced 2024-11-22 15:34:53 +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 session = require('codemp.session')
|
||||||
local utils = require('codemp.utils')
|
local utils = require('codemp.utils')
|
||||||
local buffers = require('codemp.buffers')
|
local buffers = require('codemp.buffers')
|
||||||
|
@ -144,6 +158,4 @@ return {
|
||||||
open = open_window,
|
open = open_window,
|
||||||
update = update_window,
|
update = update_window,
|
||||||
toggle = toggle_window,
|
toggle = toggle_window,
|
||||||
buffer = buffer_id,
|
|
||||||
id = window_id,
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,25 @@ local window = require('codemp.window')
|
||||||
|
|
||||||
local user_hl = {}
|
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
|
---@param ws Workspace
|
||||||
local function register_cursor_callback(ws)
|
local function register_cursor_callback(ws)
|
||||||
local controller = ws.cursor
|
local controller = ws.cursor
|
||||||
|
@ -97,4 +116,5 @@ return {
|
||||||
join = join,
|
join = join,
|
||||||
leave = leave,
|
leave = leave,
|
||||||
map = user_hl,
|
map = user_hl,
|
||||||
|
list = fetch_workspaces_list,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue