From 18049e91a08546b5c9bd9ae8316d3e34f5fad295 Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Wed, 25 Feb 2026 20:34:56 -0500 Subject: [PATCH] feat(complete): add info descriptions to omnifunc items Problem: completion menu items had no description, making it hard to distinguish between similar entries like date shorthands and recurrence patterns. Solution: return { word, info } tables from date_completions() and recur_completions(), surfacing human-readable descriptions in the completion popup. --- lua/pending/complete.lua | 124 +++++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 52 deletions(-) diff --git a/lua/pending/complete.lua b/lua/pending/complete.lua index 17fc8a2..79f338b 100644 --- a/lua/pending/complete.lua +++ b/lua/pending/complete.lua @@ -29,60 +29,75 @@ local function get_categories() return result end ----@return string[] +---@return { word: string, info: 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', - 'today@08:00', - 'today@09:00', - 'today@10:00', - 'today@12:00', - 'today@14:00', - 'today@17:00', - 'tomorrow@08:00', - 'tomorrow@09:00', - 'tomorrow@10:00', - 'tomorrow@12:00', - 'tomorrow@14:00', - 'tomorrow@17:00', + { word = 'today', info = "Today's date" }, + { word = 'tomorrow', info = "Tomorrow's date" }, + { word = 'yesterday', info = "Yesterday's date" }, + { word = '+1d', info = '1 day from today' }, + { word = '+2d', info = '2 days from today' }, + { word = '+3d', info = '3 days from today' }, + { word = '+1w', info = '1 week from today' }, + { word = '+2w', info = '2 weeks from today' }, + { word = '+1m', info = '1 month from today' }, + { word = 'mon', info = 'Next Monday' }, + { word = 'tue', info = 'Next Tuesday' }, + { word = 'wed', info = 'Next Wednesday' }, + { word = 'thu', info = 'Next Thursday' }, + { word = 'fri', info = 'Next Friday' }, + { word = 'sat', info = 'Next Saturday' }, + { word = 'sun', info = 'Next Sunday' }, + { word = 'eod', info = 'End of day (today)' }, + { word = 'eow', info = 'End of week (Sunday)' }, + { word = 'eom', info = 'End of month' }, + { word = 'eoq', info = 'End of quarter' }, + { word = 'eoy', info = 'End of year (Dec 31)' }, + { word = 'sow', info = 'Start of week (Monday)' }, + { word = 'som', info = 'Start of month' }, + { word = 'soq', info = 'Start of quarter' }, + { word = 'soy', info = 'Start of year (Jan 1)' }, + { word = 'later', info = 'Someday (sentinel date)' }, + { word = 'today@08:00', info = 'Today at 08:00' }, + { word = 'today@09:00', info = 'Today at 09:00' }, + { word = 'today@10:00', info = 'Today at 10:00' }, + { word = 'today@12:00', info = 'Today at 12:00' }, + { word = 'today@14:00', info = 'Today at 14:00' }, + { word = 'today@17:00', info = 'Today at 17:00' }, } end ----@return string[] +---@type table +local recur_descriptions = { + daily = 'Every day', + weekdays = 'Monday through Friday', + weekly = 'Every week', + biweekly = 'Every 2 weeks', + monthly = 'Every month', + quarterly = 'Every 3 months', + yearly = 'Every year', + ['2d'] = 'Every 2 days', + ['3d'] = 'Every 3 days', + ['2w'] = 'Every 2 weeks', + ['3w'] = 'Every 3 weeks', + ['2m'] = 'Every 2 months', + ['3m'] = 'Every 3 months', + ['6m'] = 'Every 6 months', + ['2y'] = 'Every 2 years', +} + +---@return { word: string, info: 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) + local desc = recur_descriptions[s] or s + table.insert(result, { word = s, info = desc }) end for _, s in ipairs(list) do - table.insert(result, '!' .. s) + local desc = recur_descriptions[s] or s + table.insert(result, { word = '!' .. s, info = desc .. ' (from completion date)' }) end return result end @@ -123,24 +138,29 @@ function M.omnifunc(findstart, base) return -1 end - local candidates = {} + local matches = {} local source = _complete_source or '' local dk = date_key() local rk = recur_key() if source == dk then - candidates = date_completions() + for _, c in ipairs(date_completions()) do + if base == '' or c.word:sub(1, #base) == base then + table.insert(matches, { word = c.word, menu = '[' .. source .. ']', info = c.info }) + end + end elseif source == 'cat' then - candidates = get_categories() + for _, c in ipairs(get_categories()) do + if base == '' or c:sub(1, #base) == base then + table.insert(matches, { word = c, menu = '[cat]' }) + end + end 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 .. ']' }) + for _, c in ipairs(recur_completions()) do + if base == '' or c.word:sub(1, #base) == base then + table.insert(matches, { word = c.word, menu = '[' .. source .. ']', info = c.info }) + end end end