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