Skip to content

Commit

Permalink
Merge pull request #7 from al1-ce/main
Browse files Browse the repository at this point in the history
fix #6
  • Loading branch information
2KAbhishek authored Oct 24, 2024
2 parents de4a54e + 1781dc7 commit a233797
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 164 deletions.
58 changes: 5 additions & 53 deletions lua/octohub.lua
Original file line number Diff line number Diff line change
@@ -1,54 +1,6 @@
---@class octohub
local M = {}

---@class octohub.config
---@field contrib_icons table : Table of icons to use for contributions, can be any length
---@field per_user_dir boolean : Whether to create a directory for each user
---@field projects_dir string : Directory where repositories are cloned
---@field sort_repos_by string : Sort repositories by various params
---@field repo_type string : Type of repositories to display
---@field max_contributions number : Max number of contributions per day to use for icon selection
---@field top_lang_count number : Number of top languages to display
---@field event_count number : Number of activity events to show
---@field window_width number : Width in percentage of the window to display stats
---@field window_height number :Height in percentage of the window to display stats
---@field show_recent_activity boolean : Whether to show recent activity
---@field show_contributions boolean : Whether to show contributions
---@field show_repo_stats boolean : Whether to show repository stats
---@field repo_cache_timeout number : Time in seconds to cache repositories
---@field username_cache_timeout number : Time in seconds to cache username
---@field events_cache_timeout number : Time in seconds to cache events data
---@field contributions_cache_timeout number : Time in seconds to contributions data
---@field user_cache_timeout number : Time in seconds to cache user data
---@field add_default_keybindings boolean : Whether to add default keybindings
local config = {
contrib_icons = { '', '', '', '', '', '', '' },
per_user_dir = true,
projects_dir = '~/Projects/',
sort_repos_by = '',
repo_type = '',
max_contributions = 50,
top_lang_count = 5,
event_count = 5,
window_width = 90,
window_height = 60,
show_recent_activity = true,
show_contributions = true,
show_repo_stats = true,
events_cache_timeout = 3600 * 6,
contibutions_cache_timeout = 3600 * 6,
repo_cache_timeout = 3600 * 24 * 7,
username_cache_timeout = 3600 * 24 * 7,
user_cache_timeout = 3600 * 24 * 7,
add_default_keybindings = true,
return {
setup = function (opts)
require('octohub.config').setup(opts)
require('octohub.setup_cmd').setup()
end
}

---@type octohub.config
M.config = config

---@param args octohub.config
M.setup = function(args)
M.config = vim.tbl_deep_extend('force', M.config, args or {})
end

return M
55 changes: 55 additions & 0 deletions lua/octohub/config.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---@class octohub
local M = {}

---@class octohub.config
---@field contrib_icons table : Table of icons to use for contributions, can be any length
---@field per_user_dir boolean : Whether to create a directory for each user
---@field projects_dir string : Directory where repositories are cloned
---@field sort_repos_by string : Sort repositories by various params
---@field repo_type string : Type of repositories to display
---@field max_contributions number : Max number of contributions per day to use for icon selection
---@field top_lang_count number : Number of top languages to display
---@field event_count number : Number of activity events to show
---@field window_width number : Width in percentage of the window to display stats
---@field window_height number :Height in percentage of the window to display stats
---@field show_recent_activity boolean : Whether to show recent activity
---@field show_contributions boolean : Whether to show contributions
---@field show_repo_stats boolean : Whether to show repository stats
---@field repo_cache_timeout number : Time in seconds to cache repositories
---@field username_cache_timeout number : Time in seconds to cache username
---@field events_cache_timeout number : Time in seconds to cache events data
---@field contributions_cache_timeout number : Time in seconds to contributions data
---@field user_cache_timeout number : Time in seconds to cache user data
---@field add_default_keybindings boolean : Whether to add default keybindings
local config = {
contrib_icons = { '', '', '', '', '', '', '' },
per_user_dir = true,
projects_dir = '~/Projects/',
sort_repos_by = '',
repo_type = '',
max_contributions = 50,
top_lang_count = 5,
event_count = 5,
window_width = 90,
window_height = 60,
show_recent_activity = true,
show_contributions = true,
show_repo_stats = true,
events_cache_timeout = 3600 * 6,
contibutions_cache_timeout = 3600 * 6,
repo_cache_timeout = 3600 * 24 * 7,
username_cache_timeout = 3600 * 24 * 7,
user_cache_timeout = 3600 * 24 * 7,
add_default_keybindings = true,
}

---@type octohub.config
M.config = config

---@param args octohub.config
M.setup = function(args)
M.config = vim.tbl_deep_extend('force', M.config, args or {})
end

return M

21 changes: 10 additions & 11 deletions lua/octohub/repos.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ local previewers = require('telescope.previewers')
local devicons = require('nvim-web-devicons')
local Path = require('plenary.path')

local utils = require('utils')
local languages = require('octohub.languages')
local config = require('octohub.config').config
local utils = require('utils')

---@class octohub.repos
local M = {}

---@type octohub.config
M.config = require('octohub').config

---@param repo table
---@return table
Expand Down Expand Up @@ -105,18 +104,18 @@ function M.get_default_username(callback)
if data then
callback(data.login)
end
end, M.config.username_cache_timeout)
end, config.username_cache_timeout)
end

---@param repo_name string
---@param owner string?
---@return string
local function get_repo_dir(repo_name, owner)
local projects_dir = Path:new(vim.fn.expand(M.config.projects_dir))
local projects_dir = Path:new(vim.fn.expand(config.projects_dir))
projects_dir:mkdir({ parents = true, exists_ok = true })

local repo_dir
if M.config.per_user_dir then
if config.per_user_dir then
local owner_dir = projects_dir:joinpath(owner)
owner_dir:mkdir({ parents = true, exists_ok = true })
repo_dir = owner_dir:joinpath(repo_name)
Expand Down Expand Up @@ -211,8 +210,8 @@ end
---@param callback fun(data: any)
function M.get_repos(args, callback)
local username = args and args.username or ''
local sort_by = args and args.sort_by or M.config.sort_repos_by
local repo_type = args and args.repo_type or M.config.repo_type
local sort_by = args and args.sort_by or config.sort_repos_by
local repo_type = args and args.repo_type or config.repo_type

local function get_user_repos(user_to_process, is_auth_user)
local all_repos = {}
Expand Down Expand Up @@ -244,7 +243,7 @@ function M.get_repos(args, callback)
all_repos = filter_repos(all_repos, repo_type)
callback(all_repos)
end
end, M.config.repo_cache_timeout)
end, config.repo_cache_timeout)
end
fetch_page(1)
end
Expand All @@ -260,8 +259,8 @@ end
---@param sort_by string?
---@param repo_type string?
function M.show_repos(username, sort_by, repo_type)
sort_by = #sort_by > 0 and sort_by or M.config.sort_repos_by
repo_type = #repo_type > 0 and repo_type or M.config.repo_type
sort_by = #sort_by > 0 and sort_by or config.sort_repos_by
repo_type = #repo_type > 0 and repo_type or config.repo_type

M.get_repos({ username = username, sort_by = sort_by, repo_type = repo_type }, function(repos)
vim.schedule(function()
Expand Down
90 changes: 90 additions & 0 deletions lua/octohub/setup_cmd.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
local repos = require('octohub.repos')
local stats = require('octohub.stats')
local web = require('octohub.web')
local config = require('octohub.config').config

M = {}

M.setup = function()
vim.api.nvim_create_user_command('OctoRepos', function(opts)
local args = vim.split(opts.args, ' ')
local user_arg, sort_arg, type_arg = '', '', ''

for _, arg in ipairs(args) do
if arg:sub(1, 5) == 'sort:' then
sort_arg = arg:sub(6)
elseif arg:sub(1, 5) == 'type:' then
type_arg = arg:sub(6)
else
user_arg = arg
end
end

repos.show_repos(user_arg, sort_arg, type_arg)
end, { nargs = '*' })

vim.api.nvim_create_user_command('OctoRepo', function(opts)
local args = vim.split(opts.args, ' ')
if #args == 1 then
repos.open_repo(args[1])
elseif #args == 2 then
repos.open_repo(args[2], args[1])
end
end, { nargs = '*' })

vim.api.nvim_create_user_command('OctoStats', function(opts)
stats.show_all_stats(opts.args)
end, { nargs = '?' })

vim.api.nvim_create_user_command('OctoActivityStats', function(opts)
local args = vim.split(opts.args, ' ')
local user_arg, count_arg = '', ''

for _, arg in ipairs(args) do
if arg:sub(1, 6) == 'count:' then
count_arg = arg:sub(7)
else
user_arg = arg
end
end
stats.show_activity_stats(user_arg, tonumber(count_arg))
end, { nargs = '*' })

vim.api.nvim_create_user_command('OctoContributionStats', function(opts)
stats.show_contribution_stats(opts.args)
end, { nargs = '?' })

vim.api.nvim_create_user_command('OctoRepoStats', function(opts)
stats.show_repo_stats(opts.args)
end, { nargs = '?' })

vim.api.nvim_create_user_command('OctoRepoWeb', function(_)
web.open_repo_web()
end, { nargs = '?' })

vim.api.nvim_create_user_command('OctoProfile', function(opts)
web.open_github_profile(opts.args)
end, { nargs = '?' })

if config.add_default_keybindings then
local function add_keymap(keys, cmd, desc)
vim.api.nvim_set_keymap('n', keys, cmd, { noremap = true, silent = true, desc = desc })
end

add_keymap('<leader>goo', ':OctoRepos<CR>', 'All Repos')
add_keymap('<leader>gos', ':OctoRepos sort:stars<CR>', 'Top Starred Repos')
add_keymap('<leader>goi', ':OctoRepos sort:issues<CR>', 'Repos With Issues')
add_keymap('<leader>gou', ':OctoRepos sort:updated<CR>', 'Recently Updated Repos')
add_keymap('<leader>gop', ':OctoRepos type:private<CR>', 'Private Repos')
add_keymap('<leader>gof', ':OctoRepos type:fork<CR>', 'Forked Repos')
add_keymap('<leader>goc', ':OctoRepo<CR>', 'Open Repo')
add_keymap('<leader>got', ':OctoStats<CR>', 'All Stats')
add_keymap('<leader>goa', ':OctoActivityStats<CR>', 'Activity Stats')
add_keymap('<leader>gog', ':OctoContributionStats<CR>', 'Contribution Graph')
add_keymap('<leader>gor', ':OctoRepoStats<CR>', 'Repo Stats')
add_keymap('<leader>goh', ':OctoProfile<CR>', 'Open GitHub Profile')
add_keymap('<leader>gow', ':OctoRepoWeb<CR>', 'Open Repo in Browser')
end
end

return M
32 changes: 15 additions & 17 deletions lua/octohub/stats.lua
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
local octorepos = require('octohub.repos')
local config = require('octohub.config').config
local utils = require('utils')

---@class octohub.stats
local M = {}

---@type octohub.config
M.config = require('octohub').config

---@param username string
---@param callback fun(data: table)
local function get_github_stats(username, callback)
local command = username == '' and 'gh api user' or 'gh api users/' .. username
utils.get_data_from_cache('user_' .. username, command, callback, M.config.user_cache_timeout)
utils.get_data_from_cache('user_' .. username, command, callback, config.user_cache_timeout)
end

---@param username string
---@param callback fun(data: table)
local function get_user_events(username, callback)
local command = 'gh api users/' .. username .. '/events?per_page=100'
utils.get_data_from_cache('events_' .. username, command, callback, M.config.events_cache_timeout)
utils.get_data_from_cache('events_' .. username, command, callback, config.events_cache_timeout)
end

---@param username string
Expand All @@ -27,17 +25,17 @@ local function get_contribution_data(username, callback)
local command = 'gh api graphql -f query=\'{user(login: "'
.. username
.. '") { contributionsCollection { contributionCalendar { weeks { contributionDays { contributionCount } } } } } }\''
utils.get_data_from_cache('contrib_' .. username, command, callback, M.config.contibutions_cache_timeout)
utils.get_data_from_cache('contrib_' .. username, command, callback, config.contibutions_cache_timeout)
end

---@param contribution_count number
---@return string icon
local function get_icon(contribution_count)
local index = math.min(
math.floor(contribution_count / (M.config.max_contributions / #M.config.contrib_icons)) + 1,
#M.config.contrib_icons
math.floor(contribution_count / (config.max_contributions / #config.contrib_icons)) + 1,
#config.contrib_icons
)
return M.config.contrib_icons[index]
return config.contrib_icons[index]
end

---@param contrib_data table
Expand Down Expand Up @@ -82,7 +80,7 @@ end
---@return string
local function get_recent_activity(events, event_count)
local activity = {}
event_count = event_count or M.config.event_count
event_count = event_count or config.event_count
table.insert(activity, ' Recent Activity\n')
for i = 1, math.min(event_count, #events) do
local event = events[i]
Expand Down Expand Up @@ -137,7 +135,7 @@ local function get_repo_stats(repos)

local lang_stats = calculate_language_stats(repos)
local top_langs = ''
for i = 1, math.min(M.config.top_lang_count, #lang_stats) do
for i = 1, math.min(config.top_lang_count, #lang_stats) do
top_langs = top_langs .. string.format('\n%d. %s (%d)', i, lang_stats[i].language, lang_stats[i].count)
end

Expand Down Expand Up @@ -184,10 +182,10 @@ local function format_message(stats, repos, events, contrib_data)
if repos and #repos > 0 then
table.insert(messageParts, '\n' .. get_repo_stats(repos) .. '\n')
end
if M.config.show_recent_activity then
if config.show_recent_activity then
table.insert(messageParts, '\n' .. get_recent_activity(events) .. '\n')
end
if M.config.show_contributions then
if config.show_contributions then
table.insert(messageParts, '\n' .. get_contribution_graph(contrib_data) .. '\n')
end
return table.concat(messageParts)
Expand All @@ -206,8 +204,8 @@ local function show_stats_window(content)
vim.api.nvim_buf_set_lines(stats_window_buf, 0, -1, true, vim.split(content, '\n'))

if not stats_window_win or not vim.api.nvim_win_is_valid(stats_window_win) then
local width = math.min(M.config.window_width, vim.o.columns - 4)
local height = math.min(M.config.window_height, vim.o.lines - 4)
local width = math.min(config.window_width, vim.o.columns - 4)
local height = math.min(config.window_height, vim.o.lines - 4)
stats_window_win = vim.api.nvim_open_win(stats_window_buf, true, {
relative = 'editor',
width = width,
Expand Down Expand Up @@ -247,7 +245,7 @@ end
---@param event_count number?
function M.show_activity_stats(username, event_count)
username = username or ''
event_count = event_count or M.config.event_count
event_count = event_count or config.event_count
get_github_stats(username, function(stats)
if stats.message then
utils.queue_notification('Error: ' .. stats.message, vim.log.levels.ERROR, 'Octohub')
Expand Down Expand Up @@ -286,7 +284,7 @@ function M.show_all_stats(username)
return
end

if M.config.show_repo_stats then
if config.show_repo_stats then
octorepos.get_repos({ username = stats.login }, function(repos)
get_user_events(stats.login, function(events)
get_contribution_data(stats.login, function(contrib_data)
Expand Down
Loading

0 comments on commit a233797

Please sign in to comment.