diff --git a/lua/lazyvim/plugins/extras/util/octo.lua b/lua/lazyvim/plugins/extras/util/octo.lua index 69ea3d97..317e6850 100644 --- a/lua/lazyvim/plugins/extras/util/octo.lua +++ b/lua/lazyvim/plugins/extras/util/octo.lua @@ -48,6 +48,53 @@ return { else LazyVim.error("`octo.nvim` requires `telescope.nvim` or `fzf-lua`") end + local Signs = require("octo.ui.signs") + + ---@type {buf: number, from: number, to: number, dirty: boolean}[] + local signs = {} + + local unplace = Signs.unplace + function Signs.unplace(bufnr) + signs = vim.tbl_filter(function(s) + return s.buf ~= bufnr + end, signs) + return unplace(bufnr) + end + + function Signs.place_signs(bufnr, start_line, end_line, is_dirty) + signs[#signs + 1] = { buf = bufnr, from = start_line, to = end_line, dirty = is_dirty } + end + -- stylua: ignore + local corners = { + top = "┌╴", + middle = "│ ", + last = "└╴", + single = "[ ", + } + + --- Fixes octo's comment rendering to take wrapping into account + ---@param buf number + ---@param lnum number + ---@param vnum number + ---@param win number + table.insert(LazyVim.ui.virtual, function(buf, lnum, vnum, win) + lnum = lnum - 1 + for _, s in ipairs(signs) do + if buf == s.buf and lnum >= s.from and lnum <= s.to then + local height = vim.api.nvim_win_text_height(win, { start_row = s.from, end_row = s.to }).all + local height_end = vim.api.nvim_win_text_height(win, { start_row = s.to, end_row = s.to }).all + local corner = corners.middle + if height == 1 then + corner = corners.single + elseif lnum == s.from and vnum == 0 then + corner = corners.top + elseif lnum == s.to and vnum == height_end - 1 then + corner = corners.last + end + return { { text = corner, texthl = s.dirty and "OctoDirty" or "IblScope" } } + end + end + end) end, }, } diff --git a/lua/lazyvim/util/ui.lua b/lua/lazyvim/util/ui.lua index d1a68ced..978a7079 100644 --- a/lua/lazyvim/util/ui.lua +++ b/lua/lazyvim/util/ui.lua @@ -1,6 +1,9 @@ ---@class lazyvim.util.ui local M = {} +---@type (fun(buf:number, lnum:number, vnum:number, win:number):Sign[]?)[] +M.virtual = {} + ---@alias Sign {name:string, text:string, texthl:string, priority:number} -- Returns a list of regular and extmark signs sorted by priority (low to high) @@ -103,9 +106,20 @@ function M.statuscolumn() local use_githl = vim.g.lazyvim_statuscolumn and vim.g.lazyvim_statuscolumn.folds_githl if show_signs then + local signs = M.get_signs(buf, vim.v.lnum) + + local has_virtual = false + for _, fn in ipairs(M.virtual) do + local virtual = fn(buf, vim.v.lnum, vim.v.virtnum, win) + if virtual then + has_virtual = true + vim.list_extend(signs, virtual) + end + end + ---@type Sign?,Sign?,Sign? local left, right, fold, githl - for _, s in ipairs(M.get_signs(buf, vim.v.lnum)) do + for _, s in ipairs(signs) do if s.name and s.name:lower():find("^octo_clean") then s.texthl = "IblScope" end @@ -118,7 +132,7 @@ function M.statuscolumn() left = s end end - if vim.v.virtnum ~= 0 and vim.bo[buf].filetype ~= "octo" then + if vim.v.virtnum ~= 0 and not has_virtual then left = nil end