diff --git a/README.md b/README.md index 5d7e62b..4294f91 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,31 @@ The default options (as defined in [lua/config.lua](./blob/main/lua/gh-actions/c ``` +## lualine integration + +```lua +require('lualine').setup({ + sections = { + lualine_a = { + { 'gh-actions' }, + }, + } +}) +``` + +or with options: + +```lua +require('lualine').setup({ + sections = { + lualine_a = { + -- with default options + { 'gh-actions', icon = ' ' }, + }, + } +}) +``` + ## Credits - [folke/lazy.nvim](https://github.com/folke/lazy.nvim) for the rendering approach diff --git a/lua/gh-actions/init.lua b/lua/gh-actions/init.lua index b533cf5..4cb79d4 100644 --- a/lua/gh-actions/init.lua +++ b/lua/gh-actions/init.lua @@ -3,6 +3,7 @@ local M = { init_root = '', ---@type uv_timer_t|nil timer = nil, + timers = 0, } ---@param opts? GhActionsConfig @@ -74,6 +75,29 @@ local function fetch_data() }) end +function M.start_polling() + M.timers = M.timers + 1 + + if not M.timer then + M.timer = vim.loop.new_timer() + M.timer:start( + 0, + require('gh-actions.config').options.refresh_interval * 1000, + vim.schedule_wrap(fetch_data) + ) + end +end + +function M.stop_polling() + M.timers = M.timers - 1 + + if M.timers == 0 then + M.timer:stop() + M.timer:close() + M.timer = nil + end +end + local function now() return os.time() end @@ -304,12 +328,7 @@ function M.open() end end, { noremap = true }) - M.timer = vim.loop.new_timer() - M.timer:start( - 0, - require('gh-actions.config').options.refresh_interval * 1000, - vim.schedule_wrap(fetch_data) - ) + M.start_polling() --TODO: This might get called after rendering.. store.on_update(M.update_workflow_configs) @@ -320,9 +339,7 @@ function M.close() local store = require('gh-actions.store') ui.close() - M.timer:stop() - M.timer:close() - M.timer = nil + M.stop_polling() store.off_update(M.update_workflow_configs) end diff --git a/lua/gh-actions/utils/icons.lua b/lua/gh-actions/utils/icons.lua new file mode 100644 index 0000000..5c32eaa --- /dev/null +++ b/lua/gh-actions/utils/icons.lua @@ -0,0 +1,28 @@ +local function Config() + return require('gh-actions.config') +end + +local M = {} + +---@return GhActionsIcons +function M.get_icons() + return Config().options.icons +end + +---@param run { status: string, conclusion: string } +---@return string +function M.get_workflow_run_icon(run) + local icons = M.get_icons() + + if not run then + return icons.status.unknown + end + + if run.status == 'completed' then + return icons.conclusion[run.conclusion] or run.conclusion + end + + return icons.status[run.status] or icons.status.unknown +end + +return M diff --git a/lua/lualine/components/gh-actions.lua b/lua/lualine/components/gh-actions.lua new file mode 100644 index 0000000..97f4bde --- /dev/null +++ b/lua/lualine/components/gh-actions.lua @@ -0,0 +1,57 @@ +local function store() + return require('gh-actions.store') +end + +local function icons() + return require('gh-actions.utils.icons') +end + +local function gh() + return require('gh-actions.github') +end + +local component = require('lualine.component'):extend() + +---@class GhActionsComponent +local default_options = { + icon = ' ', +} + +---@override +---@param options GhActionsComponent +function component:init(options) + component.super.init(self, options) + + self.options = vim.tbl_deep_extend('force', default_options, options or {}) + + local server, repo = gh().get_current_repository() + + if not server or not repo then + return + end + + require('gh-actions').start_polling() + + store().on_update(function() + require('lualine').refresh() + end) +end + +---@override +function component:update_status() + local state = store().get_state() + + local latest_workflow_run = state.workflow_runs and state.workflow_runs[1] + or {} + + if not latest_workflow_run.status then + return '' + end + + return self.options.icon + .. icons().get_workflow_run_icon(latest_workflow_run) + .. ' ' + .. latest_workflow_run.name +end + +return component