Google Tasks in Neovim!
Over time, I have consolidated all my stuff into neovim - local CSVs over spreadsheet apps, markdown notes instead of the latest flavor of Evernote, journals, progress trackers, dev logs, so on and so forth.
One notable exception however has been task management. While I've tried many apps and strategies for managing my tasks, Google Tasks was one I kept returning to. It has all the features that I need (and few more), and it works well with (unfortunately, indispensable) Google Calendar. I've been mostly happy with it (esp on mobile with tight integration with assistant). So why gtask.nvim?
There are a couple of pain point that I hope to address with this plugin:
First and foremost, my aim to have tasks slot into my current workflow. By that, I mean I do not plan to use it as a "separate" app or interface, rather it should fit inside notes as I take them.
Another major issue I face is that the "description" field is extremely cumbersome to use. Unable to add any formatting, and the way it is shown is downright horrendous. In here though, it's just another markdown content block. Neat, eh?
video.mp4
Example lazy.nvim:
{
"p-tupe/gtask.nvim",
}
require("gtask").setup()Always take backups!
All options are optional. Heh.
-- Default Options
require("gtask").setup({
markdown_dir = "~/gtask.nvim", -- Directory of markdown files
ignore_patterns = {}, -- Files/dirs to skip like "archive", "draft.md"
proxy_url = "https://app.priteshtupe.com/gtask", -- OAuth proxy
keep_completed_in_markdown = true, -- Keep completed tasks in markdown even if deleted from Google Tasks
verbosity = "error", -- Logging level: "error", "warn", or "info"
})markdown_dir: Absolute path to your markdown directory. Must start with/or~(no relative paths like./notes)proxy_url: URL of your OAuth proxy backend.ignore_patterns: List of directory names or.mdfile names to ignore when scanning. Directory names will skip entire subdirectories, file names will skip specific markdown files.keep_completed_in_markdown: Whentrue, completed tasks deleted from Google Tasks will remain in your markdown files as historical records. Whenfalse, they will be deleted from markdown to mirror Google Tasks exactly.verbosity: Controls which log messages are displayed:"error": Only show error messages"warn": Show warnings and errors"info": Show all messages including info, warnings, and errors
I recommend setting
verbosityto"info"for initial setup.
- Configure gtask.nvim using setup options if you have an existing directory or custom proxy
- Run
:GtaskAuthand follow the steps to authenticate - Sync: Run
:GtaskSyncto sync with Google Tasks - Done!
You may now update tasks in either markdown_dir or Google Tasks and :GtaskSync to synchronize them.
# Travel Plan 3025 `<-- First H1 heading is the tasks list name (and the file name as well)`
## Let's go to Mars!
... more notes on space regulations `<-- These notes (list description?) are NOT saved on Google`
- [ ] Check visa requirements | 2025-10-31 `<-- Task with due date (YYYY-MM-DD)`
- [ ] Submit application | 2025-11-01 `<-- Task with sub tasks`
Notes on visa requirements when checking `<-- This is the task's description (any spacing, optional blank line)`
More notes here (until a double empty line is encountered)
- [ ] Contact Martian friend who knows stuff `<-- This becomes a sub-task (indented 2+ spaces)`
Friend's contact number: xxx-yyy-zz `<-- This is sub-task's description`Rules:
- H1 heading → Google Tasks list name
- [ ]incomplete,- [x]complete... | YYYY-MM-DDfor due dates- Subtasks: indent 2+ spaces from parent
- Descriptions: indented lines after task
- UUIDs: auto-generated
<!-- gtask:uuid -->comments (can be hidden, see below)
- Limited Heirarchy: Only parent-child relation in subtasks, no grandchildren (all 1+ level tasks treated as children)
- No Time/Recurrence: Google Tasks API doesn't allow setting a due time or recurrence for tasks :(
- Please open an issue if you find more... :)
vim.api.nvim_create_autocmd("BufWritePost", {
pattern = vim.fn.expand("~/gtask.nvim") .. "/*.md",
desc = "Sync Google Tasks on writing any file in ~/Notes dir",
callback = function()
vim.cmd(":GtaskSync")
end,
})OR
" Sync Google Tasks on writing any file in ~/Notes dir
autocmd BufWritePost ~/gtask.nvim/*.md :GtaskSyncvim.api.nvim_create_autocmd("FileType", {
pattern = "markdown",
desc = "Hide the gtask id comments from tasks",
callback = function()
vim.defer_fn(function()
vim.cmd([[syntax match gtaskComment /<!--\s*gtask:[^>]*-->/ conceal]])
vim.opt_local.conceallevel = 2
vim.opt_local.concealcursor = "v"
end, 0)
end,
})OR
"Hide the gtask id comments from tasks
augroup GtaskConceal
autocmd!
autocmd FileType markdown syntax match gtaskComment /<!--\s*gtask:[^>]*-->/ conceal
autocmd FileType markdown setlocal conceallevel=2 concealcursor=v
augroup ENDOR
In ~/.config/nvim/after/syntax/markdown.vim:
syntax match gtaskComment /<!--\s*gtask:[^>]*-->/ concealThen in your config:
set conceallevel=2
set concealcursor=v- Make Sync more reliable
- Multiple machine sync
- File/List renames
- Mass removals
- Mapping file deleted
- Multiple levels of subtasks
- Invalid task-description-subtask structure
- Fix sub-sub-tasks not creating children
- Fix file rename/delete removing tasks
See gtask.nvim/wiki for more stuff!