-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dev: Add funding options and Khal Endar module
- Added a new funding.yml file for the GitHub community to support the project. - Added new Khal Endar lua module in initialization, UI, and utility files. - The module contains utility functions for calculating dates for various time intervals (week, month, quarter, year). - The UI file sets up the user interface for the Khal Endar calendar display. - The initialization file combines these functionalities to show and interact with calendar events.
- Loading branch information
1 parent
0ed6f74
commit a687ed6
Showing
4 changed files
with
340 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
ko_fi: bentribyte | ||
buy_me_a_coffee: bentribyte |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
local M = {} | ||
M.ui = require("khal_endar.ui") | ||
M.utils = require("khal_endar.utils") | ||
local date_funcs = { | ||
["week"] = M.utils.calculate_week_dates, | ||
["month"] = M.utils.calculate_month_dates, | ||
["quarter"] = M.utils.calculate_quarter_dates, | ||
["year"] = M.utils.calculate_year_dates, | ||
} | ||
function M.execute_command(command, return_data, print_output) | ||
if not return_data or return_data == nil then | ||
command = command .. " 2>&1" | ||
end | ||
local handle = io.popen(command) | ||
local result = handle:read("*a") | ||
if print_output then | ||
print(result) | ||
end | ||
local _, status, code = handle:close() | ||
return code, result | ||
end | ||
|
||
function M.show(type, args) | ||
local start_date, end_date = nil, nil | ||
if #args == 0 then | ||
-- start_date, end_date = M.utils.calculate_relative_datetime('2w') | ||
start_date, end_date = M.utils.calculate_week_dates() | ||
elseif #args == 1 then | ||
if M.utils.table_contains(args[1], { "week", "month", "quarter", "year" }) then | ||
start_date, end_date = date_funcs[args[1]]() | ||
else | ||
start_date, end_date = M.utils.calculate_relative_datetime(args[1]) | ||
end | ||
else | ||
start_date, end_date = args[1], args[2] | ||
end | ||
local _, cal = M.execute_command("khal --color " .. type .. " " .. start_date .. " " .. end_date, true) | ||
local contents = vim.split(cal, "\n") | ||
M.ui.trigger_hover(contents, "List of events") | ||
end | ||
|
||
function M.run(args) | ||
M.execute_command("khal " .. table.concat(args, " "), false, true) | ||
end | ||
|
||
function M.interact() | ||
local Popup = require("nui.popup") | ||
local event = require("nui.utils.autocmd").event | ||
|
||
local popup = Popup({ | ||
enter = true, | ||
focusable = true, | ||
border = { | ||
style = "rounded", | ||
}, | ||
|
||
position = "50%", | ||
size = { | ||
width = "80%", | ||
height = "60%", | ||
}, | ||
}) | ||
|
||
-- mount/open the component | ||
popup:mount() | ||
vim.cmd("term ikhal") | ||
vim.cmd("startinsert") | ||
popup:on(event.TermClose, function() | ||
popup:unmount() | ||
end) | ||
|
||
end | ||
|
||
function M.setup() | ||
vim.api.nvim_create_user_command("KLendar", function(args) | ||
M.show("calendar", args.fargs) | ||
end, { nargs = "*" }) | ||
vim.api.nvim_create_user_command("KList", function(args) | ||
M.show("list", args.fargs) | ||
end, { nargs = "*" }) | ||
vim.api.nvim_create_user_command("KLInteract", function(args) | ||
M.interact() | ||
end, {}) | ||
vim.api.nvim_create_user_command("KLRun", function(args) | ||
M.run(args.fargs) | ||
end, { nargs = "*" }) | ||
|
||
end | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
local M = {} | ||
|
||
function M.trigger_hover(contents, title) | ||
if title == nil then | ||
title = "" | ||
end | ||
local Popup = require("nui.popup") | ||
local event = require("nui.utils.autocmd").event | ||
local autocmd = require("nui.utils.autocmd") | ||
local max_width = 0 | ||
for _, content in ipairs(contents) do | ||
max_width = math.max(max_width, #content) | ||
end | ||
local popup = Popup({ | ||
enter = false, | ||
focusable = true, | ||
border = { | ||
style = "rounded", | ||
text = { | ||
top = title, | ||
top_align = "center", | ||
}, | ||
}, | ||
relative = "cursor", | ||
position = 0, | ||
size = { | ||
width = max_width + 1, | ||
height = #contents, | ||
}, | ||
}) | ||
|
||
-- mount/open the component | ||
local bufnr = vim.api.nvim_get_current_buf() | ||
autocmd.buf.define(bufnr, { event.CursorMoved, event.BufWinLeave }, function() | ||
popup:unmount() | ||
end, { once = true }) | ||
popup:mount() | ||
|
||
vim.api.nvim_buf_set_lines(popup.bufnr, 0, 1, false, contents) | ||
vim.api.nvim_buf_set_keymap(popup.bufnr, "n", "q", "<Cmd>q<CR>", { silent = true }) | ||
vim.api.nvim_buf_call(popup.bufnr, function() | ||
vim.cmd("ColorHighlight") | ||
end) | ||
return popup | ||
end | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
local M = {} | ||
|
||
function M.table_contains(str, tbl) | ||
for _, value in ipairs(tbl) do | ||
if value == str then | ||
return true | ||
end | ||
end | ||
return false | ||
end | ||
|
||
-- Function to check if string_1 is a starting substring of string_2 | ||
function M.starts_with(string, substring) | ||
-- Get the substring from string_2 that has the same length as string_1 | ||
local substring_from_string = string.sub(string, 1, #substring) | ||
|
||
-- Compare the extracted substring with string_1 | ||
if substring_from_string == substring then | ||
return true | ||
else | ||
return false | ||
end | ||
end | ||
|
||
-- Function to calculate start_date and end_date of the current week | ||
function M.calculate_week_dates() | ||
-- Get the current time in seconds since the epoch | ||
local current_time = os.time() | ||
|
||
-- Get the current date | ||
local current_date = os.date("*t", current_time) | ||
|
||
-- Calculate the day of the week where Monday is 1 and Sunday is 7 | ||
local weekday = current_date.wday | ||
-- Calculate the number of days to subtract to get to the start of the week (Monday) | ||
local days_to_subtract = weekday - 2 -- We want Monday to be day 1 (subtract 2 for Sunday) | ||
-- Calculate the start date of the week (Monday) | ||
local start_date = os.date("*t", current_time - days_to_subtract * 86400) | ||
start_date.hour = 0 | ||
start_date.min = 0 | ||
start_date.sec = 0 | ||
-- Calculate the end date of the week (Sunday) | ||
local end_date = os.date("*t", current_time + (7 - weekday + 1) * 86400) | ||
end_date.hour = 23 | ||
end_date.min = 59 | ||
end_date.sec = 59 | ||
-- Return the start_date and end_date | ||
return os.date("%Y-%m-%d", os.time(start_date)), os.date("%Y-%m-%d", os.time(end_date)) | ||
end | ||
|
||
function M.calculate_month_dates() | ||
-- Get the current time in seconds since the epoch | ||
local current_time = os.time() | ||
|
||
-- Get the current date | ||
local current_date = os.date("*t", current_time) | ||
|
||
-- Set the day of the current date to 1 to get the start of the month | ||
current_date.day = 1 | ||
|
||
-- Calculate the start_date of the month | ||
local start_date = current_date | ||
start_date.hour = 0 | ||
start_date.min = 0 | ||
start_date.sec = 0 | ||
|
||
-- Calculate the end_date of the month | ||
local next_month = start_date.month + 1 | ||
local next_month_year = start_date.year | ||
if next_month > 12 then | ||
next_month = 1 | ||
next_month_year = next_month_year + 1 | ||
end | ||
local end_date = { | ||
year = next_month_year, | ||
month = next_month, | ||
day = 1, | ||
hour = 0, | ||
min = 0, | ||
sec = 0 | ||
} | ||
end_date = os.date("*t", os.time(end_date) - 1) -- Subtract 1 second to get last day of current month | ||
|
||
-- Return the start_date and end_date | ||
return os.date("%Y-%m-%d", os.time(start_date)), os.date("%Y-%m-%d", os.time(end_date)) | ||
|
||
end | ||
|
||
function M.calculate_quarter_dates() | ||
-- Get the current time in seconds since the epoch | ||
local current_time = os.time() | ||
|
||
-- Get the current date | ||
local current_date = os.date("*t", current_time) | ||
|
||
-- Determine the current quarter | ||
local quarter = math.ceil(current_date.month / 3) | ||
|
||
-- Calculate the start_date of the quarter | ||
local start_date = { | ||
year = current_date.year, | ||
month = (quarter - 1) * 3 + 1, | ||
day = 1, | ||
hour = 0, | ||
min = 0, | ||
sec = 0 | ||
} | ||
|
||
-- Calculate the end_date of the quarter | ||
local end_date = { | ||
year = current_date.year, | ||
month = quarter * 3 + 1, | ||
day = 1, | ||
hour = 0, | ||
min = 0, | ||
sec = 0 | ||
} | ||
end_date = os.date("*t", os.time(end_date) - 86400) -- Subtract 1 day to get last day of previous month | ||
|
||
-- Return the start_date and end_date | ||
return os.date("%Y-%m-%d", os.time(start_date)), os.date("%Y-%m-%d", os.time(end_date)) | ||
|
||
end | ||
|
||
-- Function to calculate start_date and end_date of the current year | ||
function M.calculate_year_dates() | ||
-- Get the current time in seconds since the epoch | ||
local current_time = os.time() | ||
|
||
-- Get the current date | ||
local current_date = os.date("*t", current_time) | ||
|
||
-- Calculate the start_date of the year (January 1st of the current year) | ||
local start_date = { | ||
year = current_date.year, | ||
month = 1, | ||
day = 1, | ||
hour = 0, | ||
min = 0, | ||
sec = 0 | ||
} | ||
|
||
-- Calculate the end_date of the year (December 31st of the current year) | ||
local end_date = { | ||
year = current_date.year, | ||
month = 12, | ||
day = 31, | ||
hour = 23, | ||
min = 59, | ||
sec = 59 | ||
} | ||
|
||
-- Return the start_date and end_date | ||
return os.date("%Y-%m-%d", os.time(start_date)), os.date("%Y-%m-%d", os.time(end_date)) | ||
|
||
end | ||
|
||
function M.calculate_relative_datetime(interval) | ||
-- Parse the interval string to extract the numeric value and unit | ||
local numeric_value, unit = interval:match("(%d+)(%a+)") | ||
if not numeric_value or not unit then | ||
return nil -- Invalid interval format | ||
end | ||
|
||
-- Convert numeric value to integer | ||
local numeric = tonumber(numeric_value) | ||
if not numeric then | ||
return nil -- Invalid numeric value | ||
end | ||
|
||
-- Get current time in seconds since epoch | ||
local now = os.time() | ||
|
||
-- Define time units in seconds | ||
local unit_seconds = { | ||
["secconds"] = 1, | ||
["minutes"] = 60, | ||
["hours"] = 3600, | ||
["days"] = 86400, | ||
["weeks"] = 604800, -- 7 days in seconds | ||
["months"] = 2592000, -- 30 days in seconds | ||
["years"] = 31536000, -- 365 days in seconds | ||
} | ||
for key, _ in pairs(unit_seconds) do | ||
if M.starts_with(key, unit) then | ||
unit = key | ||
break | ||
end | ||
end | ||
-- Calculate the relative time in seconds | ||
local interval_seconds = unit_seconds[unit] | ||
if not interval_seconds then | ||
return nil -- Invalid time unit | ||
end | ||
|
||
local relative_time = now + numeric * interval_seconds | ||
return 'today', os.date("%Y-%m-%d", relative_time) | ||
end | ||
|
||
|
||
return M |