You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
326 lines
8.5 KiB
Lua
326 lines
8.5 KiB
Lua
local M = {}
|
|
_VT_NS = vim.api.nvim_create_namespace("lsp_signature")
|
|
|
|
local prescript
|
|
local prescript_hi
|
|
local due_hi
|
|
local ft
|
|
local today
|
|
local today_hi
|
|
local overdue
|
|
local overdue_hi
|
|
local date_hi
|
|
local pattern_start
|
|
local pattern_end
|
|
|
|
local use_clock_time
|
|
local use_clock_today
|
|
local use_seconds
|
|
local default_due_time
|
|
|
|
local user_hour
|
|
local user_min
|
|
local user_sec
|
|
|
|
local date_pattern
|
|
local datetime_pattern
|
|
local datetime12_pattern
|
|
local fulldate_pattern
|
|
local fulldatetime_pattern
|
|
local fulldatetime12_pattern
|
|
|
|
local regex_hi
|
|
|
|
local update_rate
|
|
|
|
local function patternify(str)
|
|
return str:gsub("[%(%)%.%%%+%-%*%?%[%^%$%]]", "%%%1")
|
|
end
|
|
|
|
local function regexify(str) return str:gsub("\\%^%$%.%*~%[%]&", "\\%1") end
|
|
|
|
local function make_pattern(pattern)
|
|
return patternify(pattern_start) .. pattern:gsub('%(', ''):gsub('%)', '') ..
|
|
patternify(pattern_end)
|
|
end
|
|
|
|
local function make_pattern_match(pattern)
|
|
return patternify(pattern_start) .. pattern .. patternify(pattern_end)
|
|
end
|
|
|
|
local function parseDue(due)
|
|
local year = 31556926
|
|
local month = 2629743
|
|
local week = 604800
|
|
local day = 86400
|
|
local hour = 3600
|
|
local minute = 60
|
|
local res = ''
|
|
local is_today = due < day
|
|
|
|
if due >= year then
|
|
res = res .. math.floor(due / year) .. 'y '
|
|
due = due % year
|
|
end
|
|
|
|
if due >= month then
|
|
res = res .. math.floor(due / month) .. 'm '
|
|
due = due % month
|
|
end
|
|
|
|
if due >= week then
|
|
res = res .. math.floor(due / week) .. 'w '
|
|
due = due % week
|
|
end
|
|
|
|
if use_clock_time or (is_today and use_clock_today) then
|
|
if due >= day then
|
|
res = res .. math.floor(due / day) .. 'd '
|
|
due = due % day
|
|
end
|
|
|
|
if due >= hour then
|
|
res = res .. math.floor(due / hour) .. 'h '
|
|
due = due % hour
|
|
end
|
|
|
|
if due >= minute then
|
|
res = res .. math.floor(due / minute) .. 'min '
|
|
due = due % minute
|
|
end
|
|
|
|
if use_seconds then res = res .. math.floor(due / 1) + 1 .. 's ' end
|
|
|
|
else
|
|
res = res .. math.floor(due / day) + 1 .. 'd '
|
|
end
|
|
|
|
return res
|
|
end
|
|
|
|
function M.setup(c)
|
|
c = c or {}
|
|
use_clock_time = c.use_clock_time or false
|
|
use_clock_today = c.use_clock_time or false
|
|
if type(c.use_seconds) == 'boolean' then
|
|
use_seconds = c.use_seconds
|
|
else
|
|
use_seconds = c.use_clock_time or false
|
|
end
|
|
update_rate = c.update_rate or
|
|
(use_clock_time and (use_seconds and 1000 or 60000) or 0)
|
|
default_due_time = c.default_due_time or 'midnight'
|
|
prescript = c.prescript or 'due: '
|
|
prescript_hi = c.prescript_hi or 'Comment'
|
|
due_hi = c.due_hi or 'String'
|
|
ft = c.ft or '*.md'
|
|
today = c.today or 'TODAY'
|
|
today_hi = c.today_hi or 'Character'
|
|
overdue = c.overdue or 'OVERDUE'
|
|
overdue_hi = c.overdue_hi or 'Error'
|
|
date_hi = c.date_hi or 'Conceal'
|
|
week_hi = c.week_hi or 'Question'
|
|
pattern_start = c.pattern_start or '<'
|
|
pattern_end = c.pattern_end or '>'
|
|
date_pattern = c.date_pattern or '(%d%d)%-(%d%d)'
|
|
datetime_pattern = c.datetime_pattern or (date_pattern .. ' (%d+):(%d%d)')
|
|
datetime12_pattern = c.datetime12_pattern or (datetime_pattern .. ' (%a%a)')
|
|
fulldate_pattern = c.fulldate_pattern or ('(%d%d%d%d)%-' .. date_pattern)
|
|
fulldatetime_pattern = c.fulldatetime_pattern or
|
|
('(%d%d%d%d)%-' .. datetime_pattern)
|
|
fulldatetime12_pattern = c.fulldatetime12_pattern or
|
|
(fulldatetime_pattern .. ' (%a%a)')
|
|
regex_hi = c.regex_hi or
|
|
"\\d*-*\\d\\+-\\d\\+\\( \\d*:\\d*\\( \\a\\a\\)\\?\\)\\?"
|
|
|
|
if default_due_time == "midnight" then
|
|
user_hour = 23
|
|
user_min = 59
|
|
user_sec = 59
|
|
elseif default_due_time == "noon" then
|
|
user_hour = 12
|
|
user_min = 00
|
|
user_sec = 00
|
|
end
|
|
|
|
local regex_start = regexify(pattern_start)
|
|
local regex_end = regexify(pattern_end)
|
|
|
|
local regex_hi_full = '/' .. regex_start .. regex_hi .. regex_end .. '/'
|
|
|
|
vim.api.nvim_exec(string.format(
|
|
[[
|
|
augroup Due
|
|
autocmd!
|
|
autocmd BufEnter %s lua require("due_nvim").draw(0)
|
|
autocmd BufEnter %s lua require("due_nvim").async_update(0)
|
|
autocmd InsertLeave %s lua require("due_nvim").redraw(0)
|
|
autocmd TextChanged %s lua require("due_nvim").redraw(0)
|
|
autocmd TextChangedI %s lua require("due_nvim").redraw(0)
|
|
autocmd BufEnter %s syn match DueDate %s display containedin=mkdNonListItemBlock,mkdListItemLine,mkdBlockquote conceal
|
|
autocmd BufEnter %s hi def link DueDate %s
|
|
augroup END
|
|
]] , ft, ft, ft, ft, ft, ft, regex_hi_full, ft, date_hi),
|
|
false
|
|
)
|
|
-- old autcmd
|
|
--autocmd BufEnter %s syn match DueDate %s display containedin=mkdNonListItemBlock,mkdListItemLine,mkdBlockquote contained conceal
|
|
end
|
|
|
|
local function draw_due(due, buf, key)
|
|
local parsed
|
|
|
|
if due > 0 then
|
|
if not (use_clock_time or use_clock_today) and due < 86400 then
|
|
parsed = { today, today_hi }
|
|
elseif due < 86400 then
|
|
parsed = { parseDue(due), today_hi }
|
|
elseif due < 604800 then
|
|
parsed = { parseDue(due), due_hi }
|
|
else
|
|
parsed = { parseDue(due), week_hi }
|
|
end
|
|
else
|
|
parsed = { overdue, overdue_hi }
|
|
end
|
|
|
|
vim.api.nvim_buf_set_virtual_text(buf, _VT_NS, key - 1,
|
|
{ { prescript, prescript_hi }, parsed }, {})
|
|
end
|
|
|
|
function M.draw(buf)
|
|
-- get current time
|
|
local now = os.time(os.date('*t'))
|
|
|
|
-- find which date pattern is being passed in by user
|
|
for key, value in pairs(vim.api.nvim_buf_get_lines(buf, 0, -1, {})) do
|
|
local fulldatetime12 = value:match(make_pattern(fulldatetime12_pattern))
|
|
if fulldatetime12 then
|
|
local year, month, day, hour, min, period =
|
|
fulldatetime12:match(make_pattern_match(fulldatetime12_pattern))
|
|
hour = tonumber(hour)
|
|
local is_pm = period:lower() == 'pm'
|
|
if is_pm and hour < 12 or not is_pm and hour == 12 then
|
|
hour = hour + 12
|
|
if hour == 24 then
|
|
hour = 0
|
|
end
|
|
end
|
|
draw_due(os.time({
|
|
year = year,
|
|
month = month,
|
|
day = day,
|
|
hour = hour,
|
|
min = min,
|
|
sec = user_sec
|
|
}) - now, buf, key)
|
|
goto continue
|
|
end
|
|
|
|
local fulldatetime = value:match(make_pattern(fulldatetime_pattern))
|
|
if fulldatetime then
|
|
local year, month, day, hour, min =
|
|
fulldatetime:match(make_pattern_match(fulldatetime_pattern))
|
|
draw_due(os.time({
|
|
year = year,
|
|
month = month,
|
|
day = day,
|
|
hour = hour,
|
|
min = min,
|
|
sec = user_sec
|
|
}) - now, buf, key)
|
|
goto continue
|
|
end
|
|
|
|
local fulldate = value:match(make_pattern(fulldate_pattern))
|
|
if fulldate then
|
|
local year, month, day = fulldate:match(make_pattern_match(
|
|
fulldate_pattern))
|
|
draw_due(os.time({
|
|
year = year,
|
|
month = month,
|
|
day = day,
|
|
hour = user_hour,
|
|
min = user_min,
|
|
sec = user_sec
|
|
}) - now, buf, key)
|
|
goto continue
|
|
end
|
|
|
|
local datetime12 = value:match(make_pattern(datetime12_pattern))
|
|
if datetime12 then
|
|
local month, day, hour, min, period =
|
|
datetime12:match(make_pattern_match(datetime12_pattern))
|
|
local year = os.date("%Y")
|
|
hour = tonumber(hour)
|
|
local is_pm = period:lower() == 'pm'
|
|
if is_pm and hour < 12 or not is_pm and hour == 12 then
|
|
hour = hour + 12
|
|
if hour == 24 then
|
|
hour = 0
|
|
end
|
|
end
|
|
draw_due(os.time({
|
|
year = year,
|
|
month = month,
|
|
day = day,
|
|
hour = hour,
|
|
min = min,
|
|
sec = user_sec
|
|
}) - now, buf, key)
|
|
goto continue
|
|
end
|
|
|
|
local datetime = value:match(make_pattern(datetime_pattern))
|
|
if datetime then
|
|
local month, day, hour, min = datetime:match(make_pattern_match(
|
|
datetime_pattern))
|
|
local year = os.date("%Y")
|
|
draw_due(os.time({
|
|
year = year,
|
|
month = month,
|
|
day = day,
|
|
hour = hour,
|
|
min = min,
|
|
sec = user_sec
|
|
}) - now, buf, key)
|
|
goto continue
|
|
end
|
|
|
|
local date = value:match(make_pattern(date_pattern))
|
|
if date then
|
|
local month, day = date:match(make_pattern_match(date_pattern))
|
|
local year = os.date("%Y")
|
|
|
|
draw_due(os.time({
|
|
year = year,
|
|
month = month,
|
|
day = day,
|
|
hour = user_hour,
|
|
min = user_min,
|
|
sec = user_sec
|
|
}) - now, buf, key)
|
|
goto continue
|
|
end
|
|
::continue::
|
|
end
|
|
end
|
|
|
|
function M.clear(buf) vim.api.nvim_buf_clear_namespace(buf, _VT_NS, 0, -1) end
|
|
|
|
function M.redraw(buf)
|
|
M.clear(buf)
|
|
M.draw(buf)
|
|
end
|
|
|
|
function M.async_update(buf)
|
|
if update_rate <= 0 then return end
|
|
local timer = vim.loop.new_timer()
|
|
timer:start(update_rate, 0, vim.schedule_wrap(function()
|
|
M.redraw(buf)
|
|
M.async_update(buf)
|
|
end))
|
|
end
|
|
|
|
return M
|