Skip to content

Commit

Permalink
feat: resolve #56 (#87)
Browse files Browse the repository at this point in the history
* feat: Daily/Weekly/Monthly hardtime report

* fix: Add date format for log

* fix(report): Date time parsing

* fix(report): refactor ui

---------

Co-authored-by: EFDE <[email protected]>
  • Loading branch information
The-Sirius-Black and The-Sirius-Black authored Jun 30, 2024
1 parent 9a4e24f commit 730b381
Show file tree
Hide file tree
Showing 7 changed files with 333 additions and 41 deletions.
7 changes: 6 additions & 1 deletion lua/hardtime/log.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ local default_config = {
msg
)
else
return string.format("[%-6s%s] %s\n", nameupper, os.date(), msg)
return string.format(
"[%-6s%s] %s\n",
nameupper,
os.date("%d.%m.%Y %H:%M:%S"),
msg
)
end
end,
}
Expand Down
104 changes: 64 additions & 40 deletions lua/hardtime/report.lua
Original file line number Diff line number Diff line change
@@ -1,61 +1,85 @@
local report = require("hardtime.ui.state")
local util = require("hardtime.util")

local M = {}

local function sort_hints(hints)
local sorted_hints = {}

for hint, count in pairs(hints) do
table.insert(sorted_hints, { hint, count })
end

table.sort(sorted_hints, function(a, b)
return a[2] > b[2]
end)

return sorted_hints
end

function M.report()
local file_path = vim.api.nvim_call_function("stdpath", { "log" })
.. "/hardtime.nvim.log"
.. "/hardtime.nvim.log"

local file = io.open(file_path, "r")

if file == nil then
print("Error: Unable to open", file_path)
return
end

local hints = {}
local all_hints = {}
local daily_hints = {}
local weekly_hints = {}
local monthly_hints = {}

for line in file:lines() do
local time_info = string.match(line, "%[(.-)%]")
time_info = string.gsub(time_info, "INFO", "")

local hint = string.gsub(line, "%[.-%] ", "")
hints[hint] = hints[hint] and hints[hint] + 1 or 1
end
file:close()
all_hints[hint] = all_hints[hint] and all_hints[hint] + 1 or 1

local sorted_hints = {}
for hint, count in pairs(hints) do
table.insert(sorted_hints, { hint, count })
end
local day, month, year =
string.match(time_info, "(%d+).(%d+).(%d+) (%d+):(%d+):(%d+)")

table.sort(sorted_hints, function(a, b)
return a[2] > b[2]
end)
if day ~= nil and month ~= nil and year ~= nil then
local date = os.time({
year = year,
month = month,
day = day,
})

local Popup = require("nui.popup")
local event = require("nui.utils.autocmd").event

local popup = Popup({
enter = true,
focusable = true,
border = {
style = "rounded",
text = {
top = "Hardtime Report",
top_align = "center",
},
},
position = "50%",
size = {
width = "40%",
height = "60%",
},
})

popup:mount()
popup:on(event.BufLeave, function()
popup:unmount()
end)
if util.is_today(date) then
daily_hints[hint] = daily_hints[hint] and daily_hints[hint] + 1 or 1
end

for i, pair in ipairs(sorted_hints) do
local content = string.format("%d. %s (%d times)", i, pair[1], pair[2])
if util.is_this_week(date) then
weekly_hints[hint] = weekly_hints[hint] and weekly_hints[hint] + 1
or 1
end

vim.api.nvim_buf_set_lines(popup.bufnr, i - 1, i - 1, false, { content })
vim.api.nvim_win_set_cursor(0, { 1, 0 })
if util.is_this_month(date) then
monthly_hints[hint] = monthly_hints[hint]
and monthly_hints[hint] + 1
or 1
end
end
end

file:close()

local ReportModel = require("hardtime.ui.report_model")

local reports = {
ReportModel.new(" All Time (A) ", sort_hints(all_hints), "A"),
ReportModel.new(" Daily (D) ", sort_hints(daily_hints), "D"),
ReportModel.new(" Weekly (W) ", sort_hints(weekly_hints), "W"),
ReportModel.new(" Monthly (M) ", sort_hints(monthly_hints), "M"),
}

local initial_index = 1
report.open(reports, initial_index)
end

return M
40 changes: 40 additions & 0 deletions lua/hardtime/ui/highlights.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
local M = {}

M.report_tab_focused = "ReportTabFocused"
M.report_tab_unfocused = "ReportTabUnfocused"
M.title_highlight = "TitleHighlight"

local hl_groups = {
report_tab_unfocused = {
name = M.report_tab_unfocused,
bg = "#888888",
fg = "#222222",
default = true,
},
report_tab_focused = {
name = M.report_tab_focused,
bg = "#ABE9B3",
fg = "#222222",
default = true,
},
title_highlight = {
name = M.title_highlight,
bg = "#6C8EBF",
fg = "#222222",
default = true,
},
}

function M.init()
for _, hl in pairs(hl_groups) do
local command = "highlight "
.. hl.name
.. " guifg="
.. hl.fg
.. " guibg="
.. hl.bg
vim.api.nvim_command(command)
end
end

return M
89 changes: 89 additions & 0 deletions lua/hardtime/ui/renderer.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
local highlights = require("hardtime.ui.highlights")

local M = {}

function M.render_title(title, bufnr)
local buf_width = vim.api.nvim_win_get_width(0)

local indent_length = math.floor((buf_width - #title) / 2)

local indent = string.rep(" ", indent_length)

vim.api.nvim_buf_set_lines(bufnr, 0, 0, false, { indent .. title })

vim.api.nvim_buf_add_highlight(
bufnr,
0,
highlights.title_highlight,
0,
indent_length,
indent_length + #title
)
end

function M.render_report(reports, bufnr)
local hints = {}

for index, report in ipairs(reports) do
local repetition = " (" .. report[2] .. ")"
local hint = index .. ". " .. report[1] .. repetition
table.insert(hints, hint)
end

vim.api.nvim_buf_set_lines(bufnr, 6, -1, false, hints)
end

local function find_highlighted_indexes(tabs)
local result = {}

local start = 0

for i = 1, #tabs do
local ending = start + #tabs[i]
table.insert(result, { start, ending })
start = ending + 1
end

return result
end

function M.render_tabs(tabs, picked_tab_idx, bufnr)
highlights.init()

vim.api.nvim_buf_set_lines(
bufnr,
2,
2,
false,
{ table.concat(tabs, " ") }
)

local indexes = find_highlighted_indexes(tabs)

for i, indices in ipairs(indexes) do
local start_index = indices[1]
local end_index = indices[2]

if i == picked_tab_idx then
vim.api.nvim_buf_add_highlight(
bufnr,
2,
highlights.report_tab_focused,
2,
start_index,
end_index
)
else
vim.api.nvim_buf_add_highlight(
bufnr,
2,
highlights.report_tab_unfocused,
2,
start_index,
end_index
)
end
end
end

return M
21 changes: 21 additions & 0 deletions lua/hardtime/ui/report_model.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--- @class ReportModel
--- @field tab string
--- @field report table<string , string>
--- @field keybind string
local ReportModel = {
tab = "",
report = {},
keybind = "",
}

function ReportModel.new(tab, report, keybind)
local self = setmetatable({}, ReportModel)

self.tab = tab
self.report = report
self.keybind = keybind

return self
end

return ReportModel
87 changes: 87 additions & 0 deletions lua/hardtime/ui/state.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
local _ = require("hardtime.ui.report_model")
local renderer = require("hardtime.ui.renderer")

local M = {}

local function render_content(reports, picked_tab, bufnr)
vim.api.nvim_buf_set_option(bufnr, "modifiable", true)
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {})

local tabs = {}

for _, report in ipairs(reports) do
table.insert(tabs, report.tab)
end

renderer.render_title(" Hardtime Report ", bufnr)

renderer.render_tabs(tabs, picked_tab, bufnr)

vim.api.nvim_buf_set_lines(bufnr, 5, 5, false, { "" })

renderer.render_report(reports[picked_tab].report, bufnr)

vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
end

local function add_keybinds(reports, bufnr)
for index, report in ipairs(reports) do
vim.keymap.set("n", report.keybind, function()
render_content(reports, index, bufnr)
end, {
buffer = bufnr,
nowait = true,
silent = true,
})
end
end

local is_open = false

function M.open(reports, initial_tab)
if is_open then
return
end

local Popup = require("nui.popup")

local popup = Popup({
enter = true,
focusable = true,
position = "50%",
size = {
width = "60%",
height = "70%",
},
border = {
padding = {
left = 2,
right = 2,
},
},
relative = "editor",
})

popup:mount()
is_open = true

vim.keymap.set("n", "q", function()
is_open = false
popup:unmount()
end, {
buffer = popup.bufnr,
nowait = true,
silent = true,
})

add_keybinds(reports, popup.bufnr)

popup:on("BufWinLeave", function()
is_open = false
end)

render_content(reports, initial_tab, popup.bufnr)
vim.api.nvim_buf_set_option(popup.bufnr, "modifiable", false)
end

return M
Loading

0 comments on commit 730b381

Please sign in to comment.