Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions lua/astroui/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@

---@alias StringMap table<string,string>
---@alias AstroUIIconHighlight (fun(self:table):boolean)|boolean
---@alias AstroUIHighlight vim.api.keyset.highlight
---@alias AstroUIHighlights table<string,vim.api.keyset.highlight>
---@class AstroUIHighlight: vim.api.keyset.highlight
---@field fg? integer|string
---@field bg? integer|string
---@field reverse? boolean
---@alias AstroUIHighlights table<string,AstroUIHighlight>

---@class AstroUIFileIconHighlights
---@field tabline AstroUIIconHighlight? enable or disabling file icon highlighting in the tabline
Expand Down
35 changes: 31 additions & 4 deletions lua/astroui/folding.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ function M.is_enabled(bufnr)
return enabled == true
end

--- Refresh LSP folding availability for a buffer
---@param bufnr? integer The buffer to refresh (defaults to the current buffer)
function M.refresh(bufnr)
bufnr = bufnr or vim.api.nvim_get_current_buf()
if not vim.api.nvim_buf_is_valid(bufnr) then return end
for _, client in pairs(vim.lsp.get_clients { bufnr = bufnr }) do
if client:supports_method("textDocument/foldingRange", bufnr) then
lsp_bufs[bufnr] = true
return
end
end
lsp_bufs[bufnr] = nil
end

--- A fold expression for doing LSP and Treesitter based folding
---@param lnum? integer the current line number
---@return string foldlevel the calculated fold level
Expand Down Expand Up @@ -96,10 +110,7 @@ function M.setup()
vim.api.nvim_create_autocmd("LspAttach", {
desc = "Monitor attached LSP clients with fold providers",
group = augroup,
callback = function(args)
local client = assert(vim.lsp.get_client_by_id(args.data.client_id))
if client:supports_method("textDocument/foldingRange", args.buf) then lsp_bufs[args.buf] = true end
end,
callback = function(args) M.refresh(args.buf) end,
})
vim.api.nvim_create_autocmd("LspDetach", {
group = augroup,
Expand All @@ -114,6 +125,22 @@ function M.setup()
lsp_bufs[args.buf] = nil
end,
})
vim.api.nvim_create_autocmd({ "BufDelete", "BufWipeout" }, {
group = augroup,
desc = "Remove LSP folding providers for deleted buffers",
callback = function(args) lsp_bufs[args.buf] = nil end,
})
vim.api.nvim_create_autocmd("User", {
pattern = "AstroLspCapability",
group = augroup,
desc = "Refresh folding providers after LSP capability changes",
callback = function(args)
local data = args.data
if type(data) == "table" and type(data.client_id) == "number" and type(data.bufnr) == "number" then
M.refresh(data.bufnr)
end
end,
})
is_setup = true
end

Expand Down
6 changes: 3 additions & 3 deletions lua/astroui/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ end
--- Get highlight properties for a given highlight name
---@param name string The highlight group name
---@param fallback? table The fallback highlight properties
---@return table properties # the highlight group properties
---@return AstroUIHighlight properties # the highlight group properties
function M.get_hlgroup(name, fallback)
if vim.fn.hlexists(name) == 1 then
local hl = vim.api.nvim_get_hl(0, { name = name, link = false })
local hl = vim.api.nvim_get_hl(0, { name = name, link = false }) --[[@as AstroUIHighlight]]
if not hl.fg then hl.fg = "NONE" end
if not hl.bg then hl.bg = "NONE" end
if hl.reverse then
Expand All @@ -70,7 +70,7 @@ end
function M.get_icon(kind, padding, no_fallback)
local icons_enabled = vim.g.icons_enabled ~= false
if not icons_enabled and no_fallback then return "" end
local icon_pack = assert(M.config[icons_enabled and "icons" or "text_icons"])
local icon_pack = assert(M.config[icons_enabled and "icons" or "text_icons"]) --[[@as StringMap]]
local icon = icon_pack[kind]
return icon and icon .. (" "):rep(padding or 0) or ""
end
Expand Down
75 changes: 53 additions & 22 deletions lua/astroui/lazygit.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,62 @@ local M = {}
local astroui = require "astroui"
local config = astroui.config.lazygit

local function yaml_scalar(value)
if type(value) == "string" then return vim.json.encode(value) end
if type(value) == "number" or type(value) == "boolean" then return tostring(value) end
if value == nil then return "null" end
error(("Cannot serialize %s as YAML"):format(type(value)))
end

local function yaml_key(key)
if type(key) == "number" then return tostring(key) end
if key:match "^[%a_][%w_-]*$" then return key end
return vim.json.encode(key)
end

local function yaml_keys(tbl)
local keys = vim.tbl_keys(tbl)
table.sort(keys, function(left, right) return tostring(left) < tostring(right) end)
return keys
end

local function yaml_empty_collection(tbl) return vim.islist(tbl) and "[]" or "{}" end

local function to_yaml(value, indent)
local lines = {}
local padding = string.rep(" ", indent)
if vim.islist(value) then
for _, item in ipairs(value) do
if type(item) ~= "table" then
table.insert(lines, padding .. "- " .. yaml_scalar(item))
elseif next(item) == nil then
table.insert(lines, padding .. "- " .. yaml_empty_collection(item))
else
table.insert(lines, padding .. "-")
vim.list_extend(lines, to_yaml(item, indent + 2))
end
end
else
for _, key in ipairs(yaml_keys(value)) do
local item = value[key]
if type(item) ~= "table" then
table.insert(lines, padding .. yaml_key(key) .. ": " .. yaml_scalar(item))
elseif next(item) == nil then
table.insert(lines, padding .. yaml_key(key) .. ": " .. yaml_empty_collection(item))
else
table.insert(lines, padding .. yaml_key(key) .. ":")
vim.list_extend(lines, to_yaml(item, indent + 2))
end
end
end
return lines
end

-- Build theme configuration file
function M.update_config()
if not config then return end
---@type table<string, string[]>
local theme = {}
local theme = vim.empty_dict()

-- Check if TUI is attached
-- TODO: REMOVE WHEN DROPPING SUPPORT FOR NEOVIM v0.11
Expand Down Expand Up @@ -42,27 +93,7 @@ function M.update_config()
end

local lg_config = vim.tbl_deep_extend("force", { gui = { theme = theme } }, config.config or {})

local function yaml_val(val) return type(val) == "string" and not val:find "^\"'`" and ("%q"):format(val) or val end

local function to_yaml(tbl, indent)
indent = indent or 0
local lines = {}
for k, v in pairs(tbl) do
table.insert(lines, string.rep(" ", indent) .. k .. (type(v) == "table" and ":" or ": " .. yaml_val(v)))
if type(v) == "table" then
if vim.islist(v) then
for _, item in ipairs(v) do
table.insert(lines, string.rep(" ", indent + 2) .. "- " .. yaml_val(item))
end
else
vim.list_extend(lines, to_yaml(v, indent + 2))
end
end
end
return lines
end
vim.fn.writefile(to_yaml(lg_config), config.theme_path)
vim.fn.writefile(to_yaml(lg_config, 0), config.theme_path)
end

function M.setup()
Expand Down
5 changes: 2 additions & 3 deletions lua/astroui/status/component.lua
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,13 @@ function M.lsp(opts)
))
end

--- A function to build a set of children components for a git branch section
--- A function to build a set of children components for a virtual environment section
---@param opts? AstroUIComponentVirtualEnvOpts provider options
---@return table # The Heirline component table
-- @usage local heirline_component = require("astroui.status").component.git_branch()
-- @usage local heirline_component = require("astroui.status").component.virtual_env()
function M.virtual_env(opts)
opts = extend_tbl(vim.tbl_get(config, "components", "virtual_env"), opts)
if opts.surround and opts.surround.condition == nil then
opts.surround = vim.tbl_extend("force", {}, opts.surround)
local virtual_env_opts = opts.virtual_env
and extend_tbl(vim.tbl_get(config, "providers", "virtual_env"), opts.virtual_env)
opts.surround.condition = function()
Expand Down
23 changes: 16 additions & 7 deletions lua/astroui/status/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,19 @@
---A collection of click handlers for internal heirline components such as `gitsigns`, `diagnostics`, and `dap`
---@field sign_handlers table<string,fun(args:table)>?

local function handle_sign_click(args)
if not args.sign then return false end
local config = assert(require("astroui").config.status)
local handler = args.sign.name ~= "" and config.sign_handlers[args.sign.name]
if not handler then handler = config.sign_handlers[args.sign.namespace] end
if not handler then handler = config.sign_handlers[args.sign.texthl] end
if handler then
handler(args)
return true
end
return false
end

---@type AstroUIStatusOpts
return {
attributes = {},
Expand Down Expand Up @@ -682,6 +695,8 @@ return {
if args.mods:find "c" then
local dap_avail, dap = pcall(require, "dap")
if dap_avail then dap.toggle_breakpoint() end
else
handle_sign_click(args)
end
end,
},
Expand All @@ -693,13 +708,7 @@ return {
name = "sign_click",
callback = function(...)
local args = require("astroui.status.utils").statuscolumn_clickargs(...)
local config = assert(require("astroui").config.status)
if args.sign then
local handler = args.sign.name ~= "" and config.sign_handlers[args.sign.name]
if not handler then handler = config.sign_handlers[args.sign.namespace] end
if not handler then handler = config.sign_handlers[args.sign.texthl] end
if handler then handler(args) end
end
handle_sign_click(args)
end,
},
},
Expand Down
53 changes: 36 additions & 17 deletions lua/astroui/status/heirline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ local status_utils = require "astroui.status.utils"
local buf_utils = require "astrocore.buffer"
local get_icon = require("astroui").get_icon

local picker_fallback_labels = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

--- A helper function to get the type a tab or buffer is
---@param self table the self table from a heirline component function
---@param prefix? string the prefix of the type, either "tab" or "buffer" (Default: "buffer")
Expand Down Expand Up @@ -66,7 +68,8 @@ function M.make_buflist(component)
condition = function(self) return self._show_picker end,
update = false,
init = function(self)
if not vim.tbl_get(self._picker_labels, self.label) then
if vim.tbl_get(self._picker_labels, self.label) ~= self.bufnr then
self.label = nil
local bufname = provider.filename()(self)
local label = bufname:sub(1, 1)
local i = 2
Expand All @@ -75,11 +78,25 @@ function M.make_buflist(component)
label = bufname:sub(i, i)
i = i + 1
end
self._picker_labels[label] = self.bufnr
self.label = label
if #label ~= 1 or self._picker_labels[label] then
for j = 1, #picker_fallback_labels do
local fallback_label = picker_fallback_labels:sub(j, j)
if not self._picker_labels[fallback_label] then
label = fallback_label
break
end
end
end
if #label == 1 and not self._picker_labels[label] then
self._picker_labels[label] = self.bufnr
self.label = label
end
end
end,
provider = function(self) return provider.str { str = self.label, padding = { left = 1, right = 1 } } end,
provider = function(self)
if not self.label then return "" end
return provider.str { str = self.label, padding = { left = 1, right = 1 } }
end,
hl = cached_func(hl.get_attributes, "buffer_picker"),
},
component, -- create buffer component
Expand All @@ -103,24 +120,26 @@ function M.make_tablist(...) return require("heirline.utils").make_tablist(...)
---@param callback function with a single parameter of the buffer number
function M.buffer_picker(callback)
local tabline = require("heirline").tabline
-- if buflist then
local prev_showtabline = vim.opt.showtabline:get()
if prev_showtabline ~= 2 then vim.opt.showtabline = 2 end
vim.cmd.redrawtabline()
---@diagnostic disable-next-line: undefined-field
local buflist = vim.tbl_get(tabline, "_buflist", 1)
if buflist then
buflist._picker_labels = {}
buflist._show_picker = true
local buflist
local ok, err = pcall(function()
vim.cmd.redrawtabline()
local char = vim.fn.getcharstr()
local bufnr = buflist._picker_labels[char]
if bufnr then callback(bufnr) end
buflist._show_picker = false
end
---@diagnostic disable-next-line: undefined-field
buflist = vim.tbl_get(tabline, "_buflist", 1)
if buflist then
buflist._picker_labels = {}
buflist._show_picker = true
vim.cmd.redrawtabline()
local char = vim.fn.getcharstr()
local bufnr = buflist._picker_labels[char]
if bufnr then callback(bufnr) end
end
end)
if buflist then buflist._show_picker = false end
if prev_showtabline ~= 2 then vim.opt.showtabline = prev_showtabline end
vim.cmd.redrawtabline()
-- end
if not ok then error(err, 0) end
end

--- Refresh heirline colors
Expand Down
2 changes: 1 addition & 1 deletion lua/astroui/status/hl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ end
---@return table # a table of highlight information
-- @usage local heirline_component = { provider = "Example Provider", hl = require("astroui.status").hl.get_attributes("treesitter") },
function M.get_attributes(name, include_bg)
local hl = vim.deepcopy(config.attributes[name] or {})
local hl = config.attributes[name] or {}
local loaded_colors = require("heirline.highlights").get_loaded_colors()
if loaded_colors[name .. "_fg"] then hl.fg = name .. "_fg" end
if include_bg and loaded_colors[name .. "_bg"] then hl.bg = name .. "_bg" end
Expand Down
Loading
Loading