feat: rename
This commit is contained in:
parent
c69a3957c8
commit
78a275d096
21 changed files with 191 additions and 191 deletions
4
.github/DISCUSSION_TEMPLATE/q-a.yaml
vendored
4
.github/DISCUSSION_TEMPLATE/q-a.yaml
vendored
|
|
@ -4,8 +4,8 @@ body:
|
|||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this space for questions, ideas, and general discussion about todo.nvim.
|
||||
For bug reports, please [open an issue](https://github.com/barrettruth/todo.nvim/issues/new/choose) instead.
|
||||
Use this space for questions, ideas, and general discussion about pending.nvim.
|
||||
For bug reports, please [open an issue](https://github.com/barrettruth/pending.nvim/issues/new/choose) instead.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Question or topic
|
||||
|
|
|
|||
4
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
4
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
|
|
@ -9,7 +9,7 @@ body:
|
|||
options:
|
||||
- label:
|
||||
I have searched [existing
|
||||
issues](https://github.com/barrettruth/todo.nvim/issues)
|
||||
issues](https://github.com/barrettruth/pending.nvim/issues)
|
||||
required: true
|
||||
- label: I have updated to the latest version
|
||||
required: true
|
||||
|
|
@ -69,7 +69,7 @@ body:
|
|||
require('lazy.nvim').setup({
|
||||
spec = {
|
||||
{
|
||||
'barrettruth/todo.nvim',
|
||||
'barrettruth/pending.nvim',
|
||||
opts = {},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
2
.github/ISSUE_TEMPLATE/config.yaml
vendored
2
.github/ISSUE_TEMPLATE/config.yaml
vendored
|
|
@ -1,5 +1,5 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Questions
|
||||
url: https://github.com/barrettruth/todo.nvim/discussions
|
||||
url: https://github.com/barrettruth/pending.nvim/discussions
|
||||
about: Ask questions and discuss ideas
|
||||
|
|
|
|||
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
|
|
@ -9,7 +9,7 @@ body:
|
|||
options:
|
||||
- label:
|
||||
I have searched [existing
|
||||
issues](https://github.com/barrettruth/todo.nvim/issues)
|
||||
issues](https://github.com/barrettruth/pending.nvim/issues)
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
|
|
|
|||
46
README.md
46
README.md
|
|
@ -1,4 +1,4 @@
|
|||
# todo.nvim
|
||||
# pending.nvim
|
||||
|
||||
Edit tasks like text. `:w` saves them.
|
||||
|
||||
|
|
@ -27,13 +27,13 @@ concealed, and metadata is parsed from inline syntax on save.
|
|||
## Install
|
||||
|
||||
```
|
||||
luarocks install todo.nvim
|
||||
luarocks install pending.nvim
|
||||
```
|
||||
|
||||
**lazy.nvim:**
|
||||
|
||||
```lua
|
||||
{ 'barrettruth/todo.nvim' }
|
||||
{ 'barrettruth/pending.nvim' }
|
||||
```
|
||||
|
||||
Requires Neovim 0.10+. No external dependencies for local use. Google Calendar
|
||||
|
|
@ -41,7 +41,7 @@ sync requires `curl` and `openssl`.
|
|||
|
||||
## Usage
|
||||
|
||||
`:Todo` opens the task buffer. From there, it's just vim:
|
||||
`:Pending` opens the task buffer. From there, it's just vim:
|
||||
|
||||
| Key | Action |
|
||||
| --------- | ------------------------------- |
|
||||
|
|
@ -68,24 +68,24 @@ header.
|
|||
### Quick add
|
||||
|
||||
```vim
|
||||
:Todo add Buy groceries due:2026-03-15
|
||||
:Todo add School: Submit homework
|
||||
:Pending add Buy groceries due:2026-03-15
|
||||
:Pending add School: Submit homework
|
||||
```
|
||||
|
||||
### Archive
|
||||
|
||||
```vim
|
||||
:Todo archive " purge done tasks older than 30 days
|
||||
:Todo archive 7 " purge done tasks older than 7 days
|
||||
:Pending archive " purge done tasks older than 30 days
|
||||
:Pending archive 7 " purge done tasks older than 7 days
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
No `setup()` call required. Set `vim.g.todo` before the plugin loads:
|
||||
No `setup()` call required. Set `vim.g.pending` before the plugin loads:
|
||||
|
||||
```lua
|
||||
vim.g.todo = {
|
||||
data_path = vim.fn.stdpath('data') .. '/todo/tasks.json',
|
||||
vim.g.pending = {
|
||||
data_path = vim.fn.stdpath('data') .. '/pending/tasks.json',
|
||||
default_view = 'category', -- 'category' or 'priority'
|
||||
default_category = 'Inbox',
|
||||
date_format = '%b %d', -- strftime format for virtual text
|
||||
|
|
@ -101,7 +101,7 @@ One-way push of tasks with due dates to a dedicated Google Calendar as all-day
|
|||
events.
|
||||
|
||||
```lua
|
||||
vim.g.todo = {
|
||||
vim.g.pending = {
|
||||
gcal = {
|
||||
calendar = 'Tasks',
|
||||
credentials_path = '/path/to/client_secret.json',
|
||||
|
|
@ -110,11 +110,11 @@ vim.g.todo = {
|
|||
```
|
||||
|
||||
```vim
|
||||
:Todo sync
|
||||
:Pending sync
|
||||
```
|
||||
|
||||
On first run, a browser window opens for OAuth consent. The refresh token is
|
||||
stored at `stdpath('data')/todo/gcal_tokens.json`. Completed or deleted tasks
|
||||
stored at `stdpath('data')/pending/gcal_tokens.json`. Completed or deleted tasks
|
||||
have their calendar events removed. Due date changes update events in place.
|
||||
|
||||
## Mappings
|
||||
|
|
@ -122,25 +122,25 @@ have their calendar events removed. Due date changes update events in place.
|
|||
The plugin defines `<Plug>` mappings for custom keybinds:
|
||||
|
||||
```lua
|
||||
vim.keymap.set('n', '<leader>t', '<Plug>(todo-open)')
|
||||
vim.keymap.set('n', '<leader>T', '<Plug>(todo-toggle)')
|
||||
vim.keymap.set('n', '<leader>t', '<Plug>(pending-open)')
|
||||
vim.keymap.set('n', '<leader>T', '<Plug>(pending-toggle)')
|
||||
```
|
||||
|
||||
| Plug mapping | Action |
|
||||
| ---------------------- | --------------------- |
|
||||
| `<Plug>(todo-open)` | Open task buffer |
|
||||
| `<Plug>(todo-toggle)` | Toggle complete |
|
||||
| `<Plug>(todo-view)` | Switch view |
|
||||
| `<Plug>(todo-priority)`| Toggle priority flag |
|
||||
| `<Plug>(todo-date)` | Prompt for due date |
|
||||
| `<Plug>(pending-open)` | Open task buffer |
|
||||
| `<Plug>(pending-toggle)` | Toggle complete |
|
||||
| `<Plug>(pending-view)` | Switch view |
|
||||
| `<Plug>(pending-priority)`| Toggle priority flag |
|
||||
| `<Plug>(pending-date)` | Prompt for due date |
|
||||
|
||||
## Data format
|
||||
|
||||
Tasks are stored as JSON at `stdpath('data')/todo/tasks.json`. The schema is
|
||||
Tasks are stored as JSON at `stdpath('data')/pending/tasks.json`. The schema is
|
||||
versioned and forward-compatible — unknown fields are preserved on round-trip.
|
||||
|
||||
## Documentation
|
||||
|
||||
```vim
|
||||
:checkhealth todo
|
||||
:checkhealth pending
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
local config = require('todo.config')
|
||||
local store = require('todo.store')
|
||||
local views = require('todo.views')
|
||||
local config = require('pending.config')
|
||||
local store = require('pending.store')
|
||||
local views = require('pending.views')
|
||||
|
||||
---@class todo.buffer
|
||||
---@class pending.buffer
|
||||
local M = {}
|
||||
|
||||
---@type integer?
|
||||
local task_bufnr = nil
|
||||
local task_ns = vim.api.nvim_create_namespace('todo')
|
||||
local task_ns = vim.api.nvim_create_namespace('pending')
|
||||
---@type 'category'|'priority'|nil
|
||||
local current_view = nil
|
||||
---@type todo.LineMeta[]
|
||||
---@type pending.LineMeta[]
|
||||
local _meta = {}
|
||||
|
||||
---@return todo.LineMeta[]
|
||||
---@return pending.LineMeta[]
|
||||
function M.meta()
|
||||
return _meta
|
||||
end
|
||||
|
|
@ -33,7 +33,7 @@ local function set_buf_options(bufnr)
|
|||
vim.bo[bufnr].buftype = 'acwrite'
|
||||
vim.bo[bufnr].bufhidden = 'hide'
|
||||
vim.bo[bufnr].swapfile = false
|
||||
vim.bo[bufnr].filetype = 'todo'
|
||||
vim.bo[bufnr].filetype = 'pending'
|
||||
vim.bo[bufnr].modifiable = true
|
||||
end
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ end
|
|||
|
||||
---@param bufnr integer
|
||||
local function setup_indentexpr(bufnr)
|
||||
vim.bo[bufnr].indentexpr = 'v:lua.require("todo.buffer").get_indent()'
|
||||
vim.bo[bufnr].indentexpr = 'v:lua.require("pending.buffer").get_indent()'
|
||||
end
|
||||
|
||||
---@return integer
|
||||
|
|
@ -82,7 +82,7 @@ function M.get_indent()
|
|||
end
|
||||
|
||||
---@param bufnr integer
|
||||
---@param line_meta todo.LineMeta[]
|
||||
---@param line_meta pending.LineMeta[]
|
||||
local function apply_extmarks(bufnr, line_meta)
|
||||
vim.api.nvim_buf_clear_namespace(bufnr, task_ns, 0, -1)
|
||||
for i, m in ipairs(line_meta) do
|
||||
|
|
@ -90,7 +90,7 @@ local function apply_extmarks(bufnr, line_meta)
|
|||
if m.type == 'task' then
|
||||
if m.due then
|
||||
vim.api.nvim_buf_set_extmark(bufnr, task_ns, row, 0, {
|
||||
virt_text = { { m.due, 'TodoDue' } },
|
||||
virt_text = { { m.due, 'PendingDue' } },
|
||||
virt_text_pos = 'right_align',
|
||||
})
|
||||
end
|
||||
|
|
@ -99,14 +99,14 @@ local function apply_extmarks(bufnr, line_meta)
|
|||
local col_start = line:find('/%d+/') and select(2, line:find('/%d+/')) + 2 or 0
|
||||
vim.api.nvim_buf_set_extmark(bufnr, task_ns, row, col_start, {
|
||||
end_col = #line,
|
||||
hl_group = 'TodoDone',
|
||||
hl_group = 'PendingDone',
|
||||
})
|
||||
end
|
||||
elseif m.type == 'header' then
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false)[1] or ''
|
||||
vim.api.nvim_buf_set_extmark(bufnr, task_ns, row, 0, {
|
||||
end_col = #line,
|
||||
hl_group = 'TodoHeader',
|
||||
hl_group = 'PendingHeader',
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
@ -118,10 +118,10 @@ local function setup_highlights()
|
|||
vim.api.nvim_set_hl(0, name, opts)
|
||||
end
|
||||
end
|
||||
hl('TodoHeader', { bold = true })
|
||||
hl('TodoDue', { fg = '#888888', italic = true })
|
||||
hl('TodoDone', { strikethrough = true, fg = '#666666' })
|
||||
hl('TodoPriority', { fg = '#e06c75', bold = true })
|
||||
hl('PendingHeader', { bold = true })
|
||||
hl('PendingDue', { fg = '#888888', italic = true })
|
||||
hl('PendingDone', { strikethrough = true, fg = '#666666' })
|
||||
hl('PendingPriority', { fg = '#e06c75', bold = true })
|
||||
end
|
||||
|
||||
---@param bufnr? integer
|
||||
|
|
@ -179,7 +179,7 @@ function M.open()
|
|||
end
|
||||
|
||||
task_bufnr = vim.api.nvim_create_buf(true, false)
|
||||
vim.api.nvim_buf_set_name(task_bufnr, 'todo://')
|
||||
vim.api.nvim_buf_set_name(task_bufnr, 'pending://')
|
||||
|
||||
set_buf_options(task_bufnr)
|
||||
setup_indentexpr(task_bufnr)
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
---@class todo.GcalConfig
|
||||
---@class pending.GcalConfig
|
||||
---@field calendar? string
|
||||
---@field credentials_path? string
|
||||
|
||||
---@class todo.Config
|
||||
---@class pending.Config
|
||||
---@field data_path string
|
||||
---@field default_view 'category'|'priority'
|
||||
---@field default_category string
|
||||
|
|
@ -10,27 +10,27 @@
|
|||
---@field date_syntax string
|
||||
---@field gcal? task.GcalConfig
|
||||
|
||||
---@class todo.config
|
||||
---@class pending.config
|
||||
local M = {}
|
||||
|
||||
---@type todo.Config
|
||||
---@type pending.Config
|
||||
local defaults = {
|
||||
data_path = vim.fn.stdpath('data') .. '/todo/tasks.json',
|
||||
data_path = vim.fn.stdpath('data') .. '/pending/tasks.json',
|
||||
default_view = 'category',
|
||||
default_category = 'Inbox',
|
||||
date_format = '%b %d',
|
||||
date_syntax = 'due',
|
||||
}
|
||||
|
||||
---@type todo.Config?
|
||||
---@type pending.Config?
|
||||
local _resolved = nil
|
||||
|
||||
---@return todo.Config
|
||||
---@return pending.Config
|
||||
function M.get()
|
||||
if _resolved then
|
||||
return _resolved
|
||||
end
|
||||
local user = vim.g.todo or {}
|
||||
local user = vim.g.pending or {}
|
||||
_resolved = vim.tbl_deep_extend('force', defaults, user)
|
||||
return _resolved
|
||||
end
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
local config = require('todo.config')
|
||||
local parse = require('todo.parse')
|
||||
local store = require('todo.store')
|
||||
local config = require('pending.config')
|
||||
local parse = require('pending.parse')
|
||||
local store = require('pending.store')
|
||||
|
||||
---@class todo.ParsedEntry
|
||||
---@class pending.ParsedEntry
|
||||
---@field type 'task'|'header'|'blank'
|
||||
---@field id? integer
|
||||
---@field description? string
|
||||
|
|
@ -11,7 +11,7 @@ local store = require('todo.store')
|
|||
---@field due? string
|
||||
---@field lnum integer
|
||||
|
||||
---@class todo.diff
|
||||
---@class pending.diff
|
||||
local M = {}
|
||||
|
||||
---@return string
|
||||
|
|
@ -20,7 +20,7 @@ local function timestamp()
|
|||
end
|
||||
|
||||
---@param lines string[]
|
||||
---@return todo.ParsedEntry[]
|
||||
---@return pending.ParsedEntry[]
|
||||
function M.parse_buffer(lines)
|
||||
local result = {}
|
||||
local current_category = nil
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
local M = {}
|
||||
|
||||
function M.check()
|
||||
vim.health.start('todo.nvim')
|
||||
vim.health.start('pending.nvim')
|
||||
|
||||
local ok, config = pcall(require, 'todo.config')
|
||||
local ok, config = pcall(require, 'pending.config')
|
||||
if not ok then
|
||||
vim.health.error('Failed to load todo.config')
|
||||
vim.health.error('Failed to load pending.config')
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ function M.check()
|
|||
end
|
||||
|
||||
if vim.fn.filereadable(cfg.data_path) == 1 then
|
||||
local store_ok, store = pcall(require, 'todo.store')
|
||||
local store_ok, store = pcall(require, 'pending.store')
|
||||
if store_ok then
|
||||
local load_ok, err = pcall(store.load)
|
||||
if load_ok then
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
local buffer = require('todo.buffer')
|
||||
local diff = require('todo.diff')
|
||||
local parse = require('todo.parse')
|
||||
local store = require('todo.store')
|
||||
local buffer = require('pending.buffer')
|
||||
local diff = require('pending.diff')
|
||||
local parse = require('pending.parse')
|
||||
local store = require('pending.store')
|
||||
|
||||
---@class task
|
||||
local M = {}
|
||||
|
||||
---@type todo.Task[]?
|
||||
---@type pending.Task[]?
|
||||
local _undo_state = nil
|
||||
|
||||
---@return integer bufnr
|
||||
|
|
@ -19,7 +19,7 @@ end
|
|||
|
||||
---@param bufnr integer
|
||||
function M._setup_autocmds(bufnr)
|
||||
local group = vim.api.nvim_create_augroup('TodoBuffer', { clear = true })
|
||||
local group = vim.api.nvim_create_augroup('PendingBuffer', { clear = true })
|
||||
vim.api.nvim_create_autocmd('BufWriteCmd', {
|
||||
group = group,
|
||||
buffer = bufnr,
|
||||
|
|
@ -127,13 +127,13 @@ end
|
|||
---@param text string
|
||||
function M.add(text)
|
||||
if not text or text == '' then
|
||||
vim.notify('Usage: :Todo add <description>', vim.log.levels.ERROR)
|
||||
vim.notify('Usage: :Pending add <description>', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
store.load()
|
||||
local description, metadata = parse.command_add(text)
|
||||
if not description or description == '' then
|
||||
vim.notify('Todo must have a description.', vim.log.levels.ERROR)
|
||||
vim.notify('Pending must have a description.', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
store.add({
|
||||
|
|
@ -146,11 +146,11 @@ function M.add(text)
|
|||
if bufnr and vim.api.nvim_buf_is_valid(bufnr) then
|
||||
buffer.render(bufnr)
|
||||
end
|
||||
vim.notify('Todo added: ' .. description)
|
||||
vim.notify('Pending added: ' .. description)
|
||||
end
|
||||
|
||||
function M.sync()
|
||||
local ok, gcal = pcall(require, 'todo.sync.gcal')
|
||||
local ok, gcal = pcall(require, 'pending.sync.gcal')
|
||||
if not ok then
|
||||
vim.notify('Google Calendar sync module not available.', vim.log.levels.ERROR)
|
||||
return
|
||||
|
|
@ -196,10 +196,10 @@ function M.archive(days)
|
|||
end
|
||||
|
||||
function M.show_help()
|
||||
local cfg = require('todo.config').get()
|
||||
local cfg = require('pending.config').get()
|
||||
local dk = cfg.date_syntax or 'due'
|
||||
local lines = {
|
||||
'todo.nvim keybindings',
|
||||
'pending.nvim keybindings',
|
||||
'',
|
||||
'<CR> Toggle complete/uncomplete',
|
||||
'<Tab> Switch category/priority view',
|
||||
|
|
@ -208,10 +208,10 @@ function M.show_help()
|
|||
'p / P Paste (duplicates get new IDs)',
|
||||
':w Save all changes',
|
||||
'',
|
||||
':Todo add <text> Quick-add task',
|
||||
':Todo add Cat: <text> Quick-add with category',
|
||||
':Todo sync Push to Google Calendar',
|
||||
':Todo archive [days] Purge old done tasks',
|
||||
':Pending add <text> Quick-add task',
|
||||
':Pending add Cat: <text> Quick-add with category',
|
||||
':Pending sync Push to Google Calendar',
|
||||
':Pending archive [days] Purge old done tasks',
|
||||
'',
|
||||
'Inline metadata (on new lines before :w):',
|
||||
' ' .. dk .. ':YYYY-MM-DD Set due date',
|
||||
|
|
@ -257,7 +257,7 @@ function M.command(args)
|
|||
local d = rest ~= '' and tonumber(rest) or nil
|
||||
M.archive(d)
|
||||
else
|
||||
vim.notify('Unknown Todo subcommand: ' .. cmd, vim.log.levels.ERROR)
|
||||
vim.notify('Unknown Pending subcommand: ' .. cmd, vim.log.levels.ERROR)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
local config = require('todo.config')
|
||||
local config = require('pending.config')
|
||||
|
||||
---@class todo.parse
|
||||
---@class pending.parse
|
||||
local M = {}
|
||||
|
||||
---@param s string
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
local config = require('todo.config')
|
||||
local config = require('pending.config')
|
||||
|
||||
---@class todo.Task
|
||||
---@class pending.Task
|
||||
---@field id integer
|
||||
---@field description string
|
||||
---@field status 'pending'|'done'|'deleted'
|
||||
|
|
@ -13,20 +13,20 @@ local config = require('todo.config')
|
|||
---@field order integer
|
||||
---@field _extra? table<string, any>
|
||||
|
||||
---@class todo.Data
|
||||
---@class pending.Data
|
||||
---@field version integer
|
||||
---@field next_id integer
|
||||
---@field tasks task.Task[]
|
||||
|
||||
---@class todo.store
|
||||
---@class pending.store
|
||||
local M = {}
|
||||
|
||||
local SUPPORTED_VERSION = 1
|
||||
|
||||
---@type todo.Data?
|
||||
---@type pending.Data?
|
||||
local _data = nil
|
||||
|
||||
---@return todo.Data
|
||||
---@return pending.Data
|
||||
local function empty_data()
|
||||
return {
|
||||
version = SUPPORTED_VERSION,
|
||||
|
|
@ -62,7 +62,7 @@ local known_fields = {
|
|||
order = true,
|
||||
}
|
||||
|
||||
---@param task todo.Task
|
||||
---@param task pending.Task
|
||||
---@return table
|
||||
local function task_to_table(task)
|
||||
local t = {
|
||||
|
|
@ -96,7 +96,7 @@ local function task_to_table(task)
|
|||
end
|
||||
|
||||
---@param t table
|
||||
---@return todo.Task
|
||||
---@return pending.Task
|
||||
local function table_to_task(t)
|
||||
local task = {
|
||||
id = t.id,
|
||||
|
|
@ -122,7 +122,7 @@ local function table_to_task(t)
|
|||
return task
|
||||
end
|
||||
|
||||
---@return todo.Data
|
||||
---@return pending.Data
|
||||
function M.load()
|
||||
local path = config.get().data_path
|
||||
local f = io.open(path, 'r')
|
||||
|
|
@ -138,11 +138,11 @@ function M.load()
|
|||
end
|
||||
local ok, decoded = pcall(vim.json.decode, content)
|
||||
if not ok then
|
||||
error('todo.nvim: failed to parse ' .. path .. ': ' .. tostring(decoded))
|
||||
error('pending.nvim: failed to parse ' .. path .. ': ' .. tostring(decoded))
|
||||
end
|
||||
if decoded.version and decoded.version > SUPPORTED_VERSION then
|
||||
error(
|
||||
'todo.nvim: data file version '
|
||||
'pending.nvim: data file version '
|
||||
.. decoded.version
|
||||
.. ' is newer than supported version '
|
||||
.. SUPPORTED_VERSION
|
||||
|
|
@ -177,13 +177,13 @@ function M.save()
|
|||
local encoded = vim.json.encode(out)
|
||||
local f = io.open(path, 'w')
|
||||
if not f then
|
||||
error('todo.nvim: cannot write to ' .. path)
|
||||
error('pending.nvim: cannot write to ' .. path)
|
||||
end
|
||||
f:write(encoded)
|
||||
f:close()
|
||||
end
|
||||
|
||||
---@return todo.Data
|
||||
---@return pending.Data
|
||||
function M.data()
|
||||
if not _data then
|
||||
M.load()
|
||||
|
|
@ -191,12 +191,12 @@ function M.data()
|
|||
return _data
|
||||
end
|
||||
|
||||
---@return todo.Task[]
|
||||
---@return pending.Task[]
|
||||
function M.tasks()
|
||||
return M.data().tasks
|
||||
end
|
||||
|
||||
---@return todo.Task[]
|
||||
---@return pending.Task[]
|
||||
function M.active_tasks()
|
||||
local result = {}
|
||||
for _, task in ipairs(M.tasks()) do
|
||||
|
|
@ -208,7 +208,7 @@ function M.active_tasks()
|
|||
end
|
||||
|
||||
---@param id integer
|
||||
---@return todo.Task?
|
||||
---@return pending.Task?
|
||||
function M.get(id)
|
||||
for _, task in ipairs(M.tasks()) do
|
||||
if task.id == id then
|
||||
|
|
@ -219,7 +219,7 @@ function M.get(id)
|
|||
end
|
||||
|
||||
---@param fields { description: string, status?: string, category?: string, priority?: integer, due?: string, order?: integer, _extra?: table }
|
||||
---@return todo.Task
|
||||
---@return pending.Task
|
||||
function M.add(fields)
|
||||
local data = M.data()
|
||||
local now = timestamp()
|
||||
|
|
@ -243,7 +243,7 @@ end
|
|||
|
||||
---@param id integer
|
||||
---@param fields table<string, any>
|
||||
---@return todo.Task?
|
||||
---@return pending.Task?
|
||||
function M.update(id, fields)
|
||||
local task = M.get(id)
|
||||
if not task then
|
||||
|
|
@ -263,7 +263,7 @@ function M.update(id, fields)
|
|||
end
|
||||
|
||||
---@param id integer
|
||||
---@return todo.Task?
|
||||
---@return pending.Task?
|
||||
function M.delete(id)
|
||||
return M.update(id, { status = 'deleted', ['end'] = timestamp() })
|
||||
end
|
||||
|
|
@ -279,7 +279,7 @@ function M.find_index(id)
|
|||
return nil
|
||||
end
|
||||
|
||||
---@param tasks todo.Task[]
|
||||
---@param tasks pending.Task[]
|
||||
function M.replace_tasks(tasks)
|
||||
M.data().tasks = tasks
|
||||
end
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
local config = require('todo.config')
|
||||
local store = require('todo.store')
|
||||
local config = require('pending.config')
|
||||
local store = require('pending.store')
|
||||
|
||||
local M = {}
|
||||
|
||||
|
|
@ -14,12 +14,12 @@ local function gcal_config()
|
|||
end
|
||||
|
||||
local function token_path()
|
||||
return vim.fn.stdpath('data') .. '/todo/gcal_tokens.json'
|
||||
return vim.fn.stdpath('data') .. '/pending/gcal_tokens.json'
|
||||
end
|
||||
|
||||
local function credentials_path()
|
||||
local gc = gcal_config()
|
||||
return gc.credentials_path or (vim.fn.stdpath('data') .. '/todo/gcal_credentials.json')
|
||||
return gc.credentials_path or (vim.fn.stdpath('data') .. '/pending/gcal_credentials.json')
|
||||
end
|
||||
|
||||
local function load_json_file(path)
|
||||
|
|
@ -153,7 +153,7 @@ local function get_access_token()
|
|||
local creds = load_credentials()
|
||||
if not creds then
|
||||
vim.notify(
|
||||
'todo.nvim: No Google Calendar credentials found at ' .. credentials_path(),
|
||||
'pending.nvim: No Google Calendar credentials found at ' .. credentials_path(),
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
return nil
|
||||
|
|
@ -172,7 +172,7 @@ local function get_access_token()
|
|||
if now - obtained > expires - 60 then
|
||||
tokens = refresh_access_token(creds, tokens)
|
||||
if not tokens then
|
||||
vim.notify('todo.nvim: Failed to refresh access token.', vim.log.levels.ERROR)
|
||||
vim.notify('pending.nvim: Failed to refresh access token.', vim.log.levels.ERROR)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
|
@ -183,7 +183,7 @@ function M.authorize()
|
|||
local creds = load_credentials()
|
||||
if not creds then
|
||||
vim.notify(
|
||||
'todo.nvim: No Google Calendar credentials found at ' .. credentials_path(),
|
||||
'pending.nvim: No Google Calendar credentials found at ' .. credentials_path(),
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
return
|
||||
|
|
@ -225,7 +225,7 @@ function M.authorize()
|
|||
.. '&code_challenge_method=S256'
|
||||
|
||||
vim.ui.open(auth_url)
|
||||
vim.notify('todo.nvim: Opening browser for Google authorization...')
|
||||
vim.notify('pending.nvim: Opening browser for Google authorization...')
|
||||
|
||||
local server = vim.uv.new_tcp()
|
||||
server:bind('127.0.0.1', port)
|
||||
|
|
@ -288,24 +288,24 @@ function M._exchange_code(creds, code, code_verifier, port)
|
|||
:wait()
|
||||
|
||||
if result.code ~= 0 then
|
||||
vim.notify('todo.nvim: Token exchange failed.', vim.log.levels.ERROR)
|
||||
vim.notify('pending.nvim: Token exchange failed.', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local ok, decoded = pcall(vim.json.decode, result.stdout or '')
|
||||
if not ok or not decoded.access_token then
|
||||
vim.notify('todo.nvim: Invalid token response.', vim.log.levels.ERROR)
|
||||
vim.notify('pending.nvim: Invalid token response.', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
decoded.obtained_at = os.time()
|
||||
save_tokens(decoded)
|
||||
vim.notify('todo.nvim: Google Calendar authorized successfully.')
|
||||
vim.notify('pending.nvim: Google Calendar authorized successfully.')
|
||||
end
|
||||
|
||||
local function find_or_create_calendar(access_token)
|
||||
local gc = gcal_config()
|
||||
local cal_name = gc.calendar or 'Todos'
|
||||
local cal_name = gc.calendar or 'Pendings'
|
||||
|
||||
local data, err =
|
||||
curl_request('GET', BASE_URL .. '/users/me/calendarList', auth_headers(access_token))
|
||||
|
|
@ -389,7 +389,7 @@ function M.sync()
|
|||
|
||||
local calendar_id, err = find_or_create_calendar(access_token)
|
||||
if err then
|
||||
vim.notify('todo.nvim: ' .. err, vim.log.levels.ERROR)
|
||||
vim.notify('pending.nvim: ' .. err, vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -442,7 +442,7 @@ function M.sync()
|
|||
store.save()
|
||||
vim.notify(
|
||||
string.format(
|
||||
'todo.nvim: Synced to Google Calendar (created: %d, updated: %d, deleted: %d)',
|
||||
'pending.nvim: Synced to Google Calendar (created: %d, updated: %d, deleted: %d)',
|
||||
created,
|
||||
updated,
|
||||
deleted
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
local config = require('todo.config')
|
||||
local config = require('pending.config')
|
||||
|
||||
---@class todo.LineMeta
|
||||
---@class pending.LineMeta
|
||||
---@field type 'task'|'header'|'blank'
|
||||
---@field id? integer
|
||||
---@field due? string
|
||||
|
|
@ -8,7 +8,7 @@ local config = require('todo.config')
|
|||
---@field status? string
|
||||
---@field category? string
|
||||
|
||||
---@class todo.views
|
||||
---@class pending.views
|
||||
local M = {}
|
||||
|
||||
---@param due? string
|
||||
|
|
@ -25,7 +25,7 @@ local function format_due(due)
|
|||
return os.date(config.get().date_format, t)
|
||||
end
|
||||
|
||||
---@param tasks todo.Task[]
|
||||
---@param tasks pending.Task[]
|
||||
local function sort_tasks(tasks)
|
||||
table.sort(tasks, function(a, b)
|
||||
if a.priority ~= b.priority then
|
||||
|
|
@ -38,7 +38,7 @@ local function sort_tasks(tasks)
|
|||
end)
|
||||
end
|
||||
|
||||
---@param tasks todo.Task[]
|
||||
---@param tasks pending.Task[]
|
||||
local function sort_tasks_priority(tasks)
|
||||
table.sort(tasks, function(a, b)
|
||||
if a.priority ~= b.priority then
|
||||
|
|
@ -62,9 +62,9 @@ local function sort_tasks_priority(tasks)
|
|||
end)
|
||||
end
|
||||
|
||||
---@param tasks todo.Task[]
|
||||
---@param tasks pending.Task[]
|
||||
---@return string[] lines
|
||||
---@return todo.LineMeta[] meta
|
||||
---@return pending.LineMeta[] meta
|
||||
function M.category_view(tasks)
|
||||
local by_cat = {}
|
||||
local cat_order = {}
|
||||
|
|
@ -130,9 +130,9 @@ function M.category_view(tasks)
|
|||
return lines, meta
|
||||
end
|
||||
|
||||
---@param tasks todo.Task[]
|
||||
---@param tasks pending.Task[]
|
||||
---@return string[] lines
|
||||
---@return todo.LineMeta[] meta
|
||||
---@return pending.LineMeta[] meta
|
||||
function M.priority_view(tasks)
|
||||
local pending = {}
|
||||
local done = {}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
rockspec_format = '3.0'
|
||||
package = 'todo.nvim'
|
||||
package = 'pending.nvim'
|
||||
version = 'scm-1'
|
||||
|
||||
source = {
|
||||
url = 'git+https://github.com/barrettruth/todo.nvim.git',
|
||||
url = 'git+https://github.com/barrettruth/pending.nvim.git',
|
||||
}
|
||||
|
||||
description = {
|
||||
summary = 'Oil-like task management for Neovim',
|
||||
homepage = 'https://github.com/barrettruth/todo.nvim',
|
||||
homepage = 'https://github.com/barrettruth/pending.nvim',
|
||||
license = 'MIT',
|
||||
}
|
||||
|
||||
39
plugin/pending.lua
Normal file
39
plugin/pending.lua
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
if vim.g.loaded_pending then
|
||||
return
|
||||
end
|
||||
vim.g.loaded_pending = true
|
||||
|
||||
vim.api.nvim_create_user_command('Pending', function(opts)
|
||||
require('pending').command(opts.args)
|
||||
end, {
|
||||
nargs = '*',
|
||||
complete = function(arg_lead, cmd_line)
|
||||
local subcmds = { 'add', 'sync', 'archive' }
|
||||
if not cmd_line:match('^Pending%s+%S') then
|
||||
return vim.tbl_filter(function(s)
|
||||
return s:find(arg_lead, 1, true) == 1
|
||||
end, subcmds)
|
||||
end
|
||||
return {}
|
||||
end,
|
||||
})
|
||||
|
||||
vim.keymap.set('n', '<Plug>(pending-open)', function()
|
||||
require('pending').open()
|
||||
end)
|
||||
|
||||
vim.keymap.set('n', '<Plug>(pending-toggle)', function()
|
||||
require('pending').toggle_complete()
|
||||
end)
|
||||
|
||||
vim.keymap.set('n', '<Plug>(pending-view)', function()
|
||||
require('pending.buffer').toggle_view()
|
||||
end)
|
||||
|
||||
vim.keymap.set('n', '<Plug>(pending-priority)', function()
|
||||
require('pending').toggle_priority()
|
||||
end)
|
||||
|
||||
vim.keymap.set('n', '<Plug>(pending-date)', function()
|
||||
require('pending').prompt_date()
|
||||
end)
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
if vim.g.loaded_todo then
|
||||
return
|
||||
end
|
||||
vim.g.loaded_todo = true
|
||||
|
||||
vim.api.nvim_create_user_command('Todo', function(opts)
|
||||
require('todo').command(opts.args)
|
||||
end, {
|
||||
nargs = '*',
|
||||
complete = function(arg_lead, cmd_line)
|
||||
local subcmds = { 'add', 'sync', 'archive' }
|
||||
if not cmd_line:match('^Todo%s+%S') then
|
||||
return vim.tbl_filter(function(s)
|
||||
return s:find(arg_lead, 1, true) == 1
|
||||
end, subcmds)
|
||||
end
|
||||
return {}
|
||||
end,
|
||||
})
|
||||
|
||||
vim.keymap.set('n', '<Plug>(todo-open)', function()
|
||||
require('todo').open()
|
||||
end)
|
||||
|
||||
vim.keymap.set('n', '<Plug>(todo-toggle)', function()
|
||||
require('todo').toggle_complete()
|
||||
end)
|
||||
|
||||
vim.keymap.set('n', '<Plug>(todo-view)', function()
|
||||
require('todo.buffer').toggle_view()
|
||||
end)
|
||||
|
||||
vim.keymap.set('n', '<Plug>(todo-priority)', function()
|
||||
require('todo').toggle_priority()
|
||||
end)
|
||||
|
||||
vim.keymap.set('n', '<Plug>(todo-date)', function()
|
||||
require('todo').prompt_date()
|
||||
end)
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
require('spec.helpers')
|
||||
|
||||
local config = require('todo.config')
|
||||
local store = require('todo.store')
|
||||
local config = require('pending.config')
|
||||
local store = require('pending.store')
|
||||
|
||||
describe('diff', function()
|
||||
local tmpdir
|
||||
local diff = require('todo.diff')
|
||||
local diff = require('pending.diff')
|
||||
|
||||
before_each(function()
|
||||
tmpdir = vim.fn.tempname()
|
||||
vim.fn.mkdir(tmpdir, 'p')
|
||||
vim.g.todo = { data_path = tmpdir .. '/tasks.json' }
|
||||
vim.g.pending = { data_path = tmpdir .. '/tasks.json' }
|
||||
config.reset()
|
||||
store.unload()
|
||||
store.load()
|
||||
|
|
@ -18,7 +18,7 @@ describe('diff', function()
|
|||
|
||||
after_each(function()
|
||||
vim.fn.delete(tmpdir, 'rf')
|
||||
vim.g.todo = nil
|
||||
vim.g.pending = nil
|
||||
config.reset()
|
||||
end)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
require('spec.helpers')
|
||||
|
||||
local config = require('todo.config')
|
||||
local config = require('pending.config')
|
||||
|
||||
describe('parse', function()
|
||||
before_each(function()
|
||||
vim.g.todo = nil
|
||||
vim.g.pending = nil
|
||||
config.reset()
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
vim.g.todo = nil
|
||||
vim.g.pending = nil
|
||||
config.reset()
|
||||
end)
|
||||
|
||||
local parse = require('todo.parse')
|
||||
local parse = require('pending.parse')
|
||||
|
||||
describe('body', function()
|
||||
it('returns plain description when no metadata', function()
|
||||
|
|
@ -73,7 +73,7 @@ describe('parse', function()
|
|||
end)
|
||||
|
||||
it('uses configurable date syntax', function()
|
||||
vim.g.todo = { date_syntax = 'by' }
|
||||
vim.g.pending = { date_syntax = 'by' }
|
||||
config.reset()
|
||||
local desc, meta = parse.body('Buy milk by:2026-03-15')
|
||||
assert.are.equal('Buy milk', desc)
|
||||
|
|
@ -81,7 +81,7 @@ describe('parse', function()
|
|||
end)
|
||||
|
||||
it('ignores old syntax when date_syntax is changed', function()
|
||||
vim.g.todo = { date_syntax = 'by' }
|
||||
vim.g.pending = { date_syntax = 'by' }
|
||||
config.reset()
|
||||
local desc, meta = parse.body('Buy milk due:2026-03-15')
|
||||
assert.are.equal('Buy milk due:2026-03-15', desc)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
require('spec.helpers')
|
||||
|
||||
local config = require('todo.config')
|
||||
local store = require('todo.store')
|
||||
local config = require('pending.config')
|
||||
local store = require('pending.store')
|
||||
|
||||
describe('store', function()
|
||||
local tmpdir
|
||||
|
|
@ -9,14 +9,14 @@ describe('store', function()
|
|||
before_each(function()
|
||||
tmpdir = vim.fn.tempname()
|
||||
vim.fn.mkdir(tmpdir, 'p')
|
||||
vim.g.todo = { data_path = tmpdir .. '/tasks.json' }
|
||||
vim.g.pending = { data_path = tmpdir .. '/tasks.json' }
|
||||
config.reset()
|
||||
store.unload()
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
vim.fn.delete(tmpdir, 'rf')
|
||||
vim.g.todo = nil
|
||||
vim.g.pending = nil
|
||||
config.reset()
|
||||
end)
|
||||
|
||||
|
|
@ -37,14 +37,14 @@ describe('store', function()
|
|||
tasks = {
|
||||
{
|
||||
id = 1,
|
||||
description = 'Todo one',
|
||||
description = 'Pending one',
|
||||
status = 'pending',
|
||||
entry = '2026-01-01T00:00:00Z',
|
||||
modified = '2026-01-01T00:00:00Z',
|
||||
},
|
||||
{
|
||||
id = 2,
|
||||
description = 'Todo two',
|
||||
description = 'Pending two',
|
||||
status = 'done',
|
||||
entry = '2026-01-01T00:00:00Z',
|
||||
modified = '2026-01-01T00:00:00Z',
|
||||
|
|
@ -55,7 +55,7 @@ describe('store', function()
|
|||
local data = store.load()
|
||||
assert.are.equal(3, data.next_id)
|
||||
assert.are.equal(2, #data.tasks)
|
||||
assert.are.equal('Todo one', data.tasks[1].description)
|
||||
assert.are.equal('Pending one', data.tasks[1].description)
|
||||
assert.are.equal('done', data.tasks[2].status)
|
||||
end)
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ describe('store', function()
|
|||
tasks = {
|
||||
{
|
||||
id = 1,
|
||||
description = 'Todo',
|
||||
description = 'Pending',
|
||||
status = 'pending',
|
||||
entry = '2026-01-01T00:00:00Z',
|
||||
modified = '2026-01-01T00:00:00Z',
|
||||
|
|
@ -157,7 +157,7 @@ describe('store', function()
|
|||
tasks = {
|
||||
{
|
||||
id = 1,
|
||||
description = 'Todo',
|
||||
description = 'Pending',
|
||||
status = 'pending',
|
||||
entry = '2026-01-01T00:00:00Z',
|
||||
modified = '2026-01-01T00:00:00Z',
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ syntax match taskHeader /^\S.*$/ contains=taskId
|
|||
syntax match taskPriority /!\ze / contained
|
||||
syntax match taskLine /^\/\d\+\/ .*$/ contains=taskId,taskPriority
|
||||
|
||||
highlight default link taskHeader TodoHeader
|
||||
highlight default link taskPriority TodoPriority
|
||||
highlight default link taskHeader PendingHeader
|
||||
highlight default link taskPriority PendingPriority
|
||||
highlight default link taskLine Normal
|
||||
|
||||
let b:current_syntax = 'task'
|
||||
Loading…
Add table
Add a link
Reference in a new issue