From c76d23b42aa5ab30d6049544b12033919acc35a4 Mon Sep 17 00:00:00 2001 From: Will Hopkins Date: Sun, 2 Jul 2023 09:39:15 -0700 Subject: [PATCH] feat: sidebars on rhs of editor --- lua/cokeline/hover.lua | 18 +++++++++-- lua/cokeline/rendering.lua | 19 +++++++----- lua/cokeline/sidebar.lua | 62 +++++++++++++++++++++++++++----------- 3 files changed, 73 insertions(+), 26 deletions(-) diff --git a/lua/cokeline/hover.lua b/lua/cokeline/hover.lua index 232911e..cce906f 100644 --- a/lua/cokeline/hover.lua +++ b/lua/cokeline/hover.lua @@ -39,10 +39,10 @@ function M.get_current(col) local cx = rendering.prepare(bufs) local current_width = 0 - for _, component in ipairs(cx.sidebar) do + for _, component in ipairs(cx.sidebar_left) do current_width = current_width + component.width if current_width >= col then - return component, cx.sidebar + return component, cx.sidebar_left end end if @@ -81,6 +81,12 @@ function M.get_current(col) end end end + for _, component in ipairs(cx.sidebar_right) do + current_width = current_width + component.width + if current_width >= col then + return component, cx.sidebar_right + end + end end local function mouse_leave(hovered) @@ -89,6 +95,10 @@ local function mouse_leave(hovered) cx = buffers.get_buffer(hovered.bufnr) elseif hovered.kind == "tab" then cx = tabs.get_tabpage(hovered.bufnr) + elseif hovered.kind == "sidebar" then + cx = { number = hovered.bufnr, side = hovered.sidebar } + else + cx = {} end if cx then cx.is_hovered = false @@ -107,6 +117,10 @@ local function mouse_enter(component, current) cx = buffers.get_buffer(component.bufnr) elseif component.kind == "tab" then cx = tabs.get_tabpage(component.bufnr) + elseif component.kind == "sidebar" then + cx = { number = component.bufnr, side = component.sidebar } + else + cx = {} end if cx then cx.is_hovered = true diff --git a/lua/cokeline/rendering.lua b/lua/cokeline/rendering.lua index 6e1ca53..43b8573 100644 --- a/lua/cokeline/rendering.lua +++ b/lua/cokeline/rendering.lua @@ -97,11 +97,12 @@ end ---@param visible_buffers Buffer[] ---@return table|string local prepare = function(visible_buffers) - local sidebar_components = sidebar.get_components() + local sidebar_components_l = sidebar.get_components("left") + local sidebar_components_r = sidebar.get_components("right") local rhs_components = rhs.get_components() - local available_width = o.columns - components.width(sidebar_components) + local available_width = o.columns - components.width(sidebar_components_l) if available_width == 0 then - return components.render(sidebar_components) + return components.render(sidebar_components_l) end local tab_placement @@ -113,7 +114,7 @@ local prepare = function(visible_buffers) tabs_width = components.width(tab_components) available_width = available_width - tabs_width if available_width == 0 then - return components.render(sidebar_components) + return components.render(sidebar_components_l) .. components.render(tab_components) end end @@ -135,7 +136,8 @@ local prepare = function(visible_buffers) end return { - sidebar = sidebar_components, + sidebar_left = sidebar_components_l, + sidebar_right = sidebar_components_r, buffers = current_components, rhs = rhs_components, tabs = tab_components, @@ -159,6 +161,7 @@ local prepare = function(visible_buffers) }, _G.cokeline.components) local rhs_width = components.width(rhs_components) + + components.width(sidebar_components_r) local available_width_left, available_width_right = _G.cokeline.config.rendering.slider( available_width @@ -194,7 +197,8 @@ local prepare = function(visible_buffers) local bufs_width = components.width(buffer_components) return { - sidebar = sidebar_components, + sidebar_left = sidebar_components_l, + sidebar_right = sidebar_components_r, buffers = buffer_components, rhs = rhs_components, tabs = tab_components, @@ -210,7 +214,7 @@ end ---@return string local render = function(visible_buffers, fill_hl) local cx = prepare(visible_buffers) - local rendered = components.render(cx.sidebar) .. "%#" .. fill_hl .. "#" + local rendered = components.render(cx.sidebar_left) .. "%#" .. fill_hl .. "#" if _G.cokeline.config.tabs and _G.cokeline.config.tabs.placement == "left" then @@ -228,6 +232,7 @@ local render = function(visible_buffers, fill_hl) then rendered = rendered .. "%#" .. fill_hl .. "#" .. components.render(cx.tabs) end + rendered = rendered .. components.render(cx.sidebar_right) return rendered end diff --git a/lua/cokeline/sidebar.lua b/lua/cokeline/sidebar.lua index 0a494c6..0750f2f 100644 --- a/lua/cokeline/sidebar.lua +++ b/lua/cokeline/sidebar.lua @@ -12,19 +12,13 @@ local bo = vim.bo local fn = vim.fn local o = vim.o ----@return Component[] -local get_components = function() - if not _G.cokeline.config.sidebar then - return {} - end - - local hover = require("cokeline/hover").hovered() +local get_win = function(side) local layout = fn.winlayout() -- If the first split level is not given by vertically split windows we -- return early. if layout[1] ~= "row" then - return {} + return nil end -- The second element of the `layout` table is a nested list representing the @@ -48,16 +42,45 @@ local get_components = function() -- -- However, with edgy.nvim, a sidebar can contain multiple splits nested one level in. -- So if the first window found is a leaf, we check the first window of the container. - local first_split = window_tree[1] - local winid = first_split[2] - if first_split[1] ~= "leaf" then - local win = first_split[2][1] - if win and win[1] == "leaf" then - winid = win[2] - else - return {} + local first_split + local winid + if side == nil or side == "left" then + first_split = window_tree[1] + winid = first_split[2] + if first_split[1] ~= "leaf" then + local win = first_split[2][1] + if win and win[1] == "leaf" then + winid = win[2] + else + return nil + end + end + else + first_split = window_tree[#window_tree] + winid = first_split[2] + if first_split[1] ~= "leaf" then + local win = first_split[2][#first_split[2]] + if win and win[1] == "leaf" then + winid = win[2] + else + return nil + end end end + return winid +end + +---@param side "left" | "right" +---@return Component[] +local get_components = function(side) + if not _G.cokeline.config.sidebar then + return {} + end + + local winid = get_win(side) + if not winid then + return {} + end local bufnr = api.nvim_win_get_buf(winid) @@ -85,8 +108,12 @@ local get_components = function() local sidebar_components = {} local width = 0 local id = #_G.cokeline.components + #_G.cokeline.rhs + 1 + local hover = require("cokeline/hover").hovered() for _, c in ipairs(_G.cokeline.sidebar) do - buffer.is_hovered = hover and hover.index == id + c.sidebar = side + buffer.is_hovered = hover ~= nil + and hover.index == id + and hover.bufnr == buffer.number local component = c:render(RenderContext:buffer(buffer)) buffer.is_hovered = false -- We need at least one component, otherwise we can't add padding to the @@ -117,5 +144,6 @@ local get_components = function() end return { + get_win = get_win, get_components = get_components, }