local function trim(s) return (s:gsub("^%s*(.-)%s*$", "%1")) end local augroup = vim.api.nvim_create_augroup("Timer", { clear = true }) local filename = ".timer.toml" local username = trim(os.getenv("USER")) .. "_at_" .. trim(io.popen("hostname -s"):read("*a")) local focus_events = {} local clean_to = 1 local function clean_from(from, events) -- cleans the events local clean_events = {} -- coppy until from for i = 1, from - 1, 1 do table.insert(clean_events, events[i]) end local last = {} for i = from, #events, 1 do local event = events[i] local next_event = events[i + 1] if next_event == nil then --do nothing elseif next_event.event == "gain" and event.event == "lose" then if os.difftime(next_event.time, event.time) > 5 * 60 then table.insert(clean_events, event) end end if last == nil then -- do nothing elseif last.event == "lose" and event.event == "gain" then if os.difftime(event.time, last.time) > 5 * 60 then table.insert(clean_events, event) end end last = event end return clean_events end local function summ_time() --returns time in seconds from the fous events focus_events = clean_from(clean_to + 1, focus_events) clean_to = #focus_events local t = 0 local start = os.time() for _, fe in pairs(focus_events) do if fe.event == "gain" then start = fe.time else t = t + os.difftime(fe.time, start) end if focus_events[#focus_events].event == "gain" then t = t + os.difftime(os.time(), focus_events[#focus_events].time) end end return t end local function fmt_time(time) local str = "" local days = math.floor(time / (60 * 60 * 24)) if days ~= 0 then str = str .. days .. "d" end time = time % (60 * 60 * 24) local hours = math.floor(time / (60 * 60)) if hours ~= 0 then str = str .. hours .. "h" end time = time % (60 * 60) local minutes = math.floor(time / 60) if minutes ~= 0 then str = str .. minutes .. "m" end local seconds = time % (60) if seconds ~= 0 then str = str .. seconds .. "s" end return str end local function log_total_time() local times = {} times[username] = summ_time() local file = io.open(filename, "r") -- if file exists read if file ~= nil then local history = require("toml").parse(file:read("*a")) file:close() print("Time for:", filename) for _, day in pairs(history) do for user, time in pairs(day) do if times[user] == nil then times[user] = 0 end times[user] = times[user] + time end end end for user, time in pairs(times) do print(user, fmt_time(time)) end end local function log_time_table() for i, e in pairs(focus_events) do print(i, e.event, os.date("%H:%M:%S", e.time)) end end local function focus_gained() table.insert(focus_events, { time = os.time(), event = "gain", }) end local function focus_lost() table.insert(focus_events, { time = os.time(), event = "lose", }) end local function next_lowest_time_file() local file_path = filename for _ = 1, 10, 1 do local f = io.open(file_path) if f ~= nil then return file_path end file_path = "../" .. file_path end return "" end local function persist(force) return function() local TOML = require("toml") local today = os.date("%y-%m-%d", os.time()) local table = {} local file_path = filename local file = io.open(file_path, "r") -- if file exists read if file ~= nil then table = TOML.parse(file:read("*a")) file:close() else if not force then file_path = next_lowest_time_file() if file_path == "" then print("No save file found. To create a new save file run :TimerSave") return end print("Save file found:", file_path) end end -- write time to table if table[today] ~= nil and table[today][username] ~= nil then table[today][username] = table[today][username] + summ_time() else if table[today] == nil then table[today] = {} end table[today][username] = summ_time() end -- write table to file file = io.open(file_path, "w") if file == nil then error("can't write to .timer file") return end local tml = TOML.encode(table) file:write("## dates and their corresponding seconds been here :)\n", tml, "\n") file:close() print("Timer saved successfully :-)") --reset timer clean_to = 1 focus_events = {} focus_gained() end end local function setup() vim.api.nvim_create_autocmd("VimEnter", { group = augroup, desc = "Start Timer", once = true, callback = focus_gained }) vim.api.nvim_create_autocmd("ExitPre", { group = augroup, desc = "Persist timer", once = true, callback = persist(false) }) vim.api.nvim_create_autocmd("FocusGained", { group = augroup, callback = focus_gained }) vim.api.nvim_create_autocmd("FocusLost", { group = augroup, callback = focus_lost }) vim.api.nvim_create_user_command( 'Timer', log_total_time, { nargs = 0 } -- No arguments for this command (you can configure this later) ) vim.api.nvim_create_user_command( 'TimerLog', log_time_table, { nargs = 0 } -- No arguments for this command (you can configure this later) ) vim.api.nvim_create_user_command( 'TimerSave', persist(true), { nargs = 0 } -- No arguments for this command (you can configure this later) ) end return { setup = setup }