pending.nvim/lua/pending/complete.lua
2026-02-25 13:06:20 -05:00

138 lines
2.6 KiB
Lua

local config = require('pending.config')
---@class pending.complete
local M = {}
---@return string
local function date_key()
return config.get().date_syntax or 'due'
end
---@return string
local function recur_key()
return config.get().recur_syntax or 'rec'
end
---@return string[]
local function get_categories()
local store = require('pending.store')
local seen = {}
local result = {}
for _, task in ipairs(store.active_tasks()) do
local cat = task.category
if cat and not seen[cat] then
seen[cat] = true
table.insert(result, cat)
end
end
table.sort(result)
return result
end
---@return string[]
local function date_completions()
return {
'today',
'tomorrow',
'yesterday',
'+1d',
'+2d',
'+3d',
'+1w',
'+2w',
'+1m',
'mon',
'tue',
'wed',
'thu',
'fri',
'sat',
'sun',
'eod',
'eow',
'eom',
'eoq',
'eoy',
'sow',
'som',
'soq',
'soy',
'later',
}
end
---@return string[]
local function recur_completions()
local recur = require('pending.recur')
local list = recur.shorthand_list()
local result = {}
for _, s in ipairs(list) do
table.insert(result, s)
end
for _, s in ipairs(list) do
table.insert(result, '!' .. s)
end
return result
end
---@type string?
local _complete_source = nil
---@param findstart integer
---@param base string
---@return integer|table[]
function M.omnifunc(findstart, base)
if findstart == 1 then
local line = vim.api.nvim_get_current_line()
local col = vim.api.nvim_win_get_cursor(0)[2]
local before = line:sub(1, col)
local dk = date_key()
local rk = recur_key()
local checks = {
{ vim.pesc(dk) .. ':([%S]*)$', dk },
{ 'cat:([%S]*)$', 'cat' },
{ vim.pesc(rk) .. ':([%S]*)$', rk },
}
for _, check in ipairs(checks) do
local start = before:find(check[1])
if start then
local colon_pos = before:find(':', start, true)
if colon_pos then
_complete_source = check[2]
return colon_pos
end
end
end
_complete_source = nil
return -1
end
local candidates = {}
local source = _complete_source or ''
local dk = date_key()
local rk = recur_key()
if source == dk then
candidates = date_completions()
elseif source == 'cat' then
candidates = get_categories()
elseif source == rk then
candidates = recur_completions()
end
local matches = {}
for _, c in ipairs(candidates) do
if base == '' or c:sub(1, #base) == base then
table.insert(matches, { word = c, menu = '[' .. source .. ']' })
end
end
return matches
end
return M