Add sample templates to your NOTES_DIR
July 21, 2025 ยท View on GitHub
tdo is a opinionated, command line based note-taking system. Demo video
โจ Features
- Unified Note System: Manage daily todos, journal entries, and long-term notes in one organized system with intuitive navigation
- Natural Language Dates: Use expressions like
tomorrow,next-friday,2-weeks-ago, or2025-12-25instead of calculating offsets manually - Fuzzy Search: Interactive search powered by fzf with syntax highlighting to quickly find and review any note
- Git Integration: Automatically commits and backs up your notes with timestamps for seamless sync across devices
- Editor Flexibility: Works with any editor through
$EDITOR- vim, emacs, vscode, includes neovim integration - AI & Automation: Integrates with workflows, pipes, subshells, and AI agents through mcp-tdo
โก Setup
๐ Requirements
- ripgrep, fzf
- bat (optional, for syntax highlighting in search)
- coreutils (required on macOS, for gdate command)
๐ป Installation
git clone https://github.com/2kabhishek/tdo
cd tdo
./install.sh
๐ฆ Environment Variables
-
NOTES_DIRshould point to your notes directory -
TODOS_DIRoptional, should point to your todos directory, default:NOTES_DIR/todos -
JOURNAL_DIRoptional, should point to your journal directory, default:NOTES_DIR/entries -
EDITORset to your choice of editor
๐ Manual Installation
If you want to customize the setup or are facing issues with installation, you can set up tdo manually.
Change these commands according to your needs.
# Link tdo to a directory that's in PATH (~/.local/bin here)
ln -sfnv "$PWD/tdo.sh" ~/.local/bin/tdo
# Create a notes dir if not already present
mkdir -p $HOME/Projects/Notes
# Add the NOTES_DIR env var to your shell config ~/.bashrc, ~/.zshrc etc
echo "NOTES_DIR=$HOME/Projects/Notes" >> ~/.zshrc
# Add sample templates to your NOTES_DIR
cp -irv templates $NOTES_DIR
# Reload shell config
source ~/.zshrc
๐ค Shell Completion
If you want to enable tab completion for tdo, add this to your shell's RC file (bashrc, zshrc, config.fish etc).
# zsh and bash
source /path/to/tdo/completions/tdo_completion.sh
# fish
source /path/to/tdo/completions/tdo_completion.fish
This will allow you to use tab completion to quickly access your notes when you type tdo <tab>.
๐พ Git Integration
If you want to sync your notes across devices, you can set up a git repo on the $NOTES_DIR and add GitHub/GitLab as remote.
cd $NOTES_DIR
git init
git add .
git commit -m 'init: notes'
git remote add origin <your-remote-git-url>
git push origin main
tdo will automatically commit every change with a timestamp like 03 Feb 11:33 as commit message.
๐ Usage
If you use Neovim, I highly recommend using tdo.nvim, it seamlessly integrates tdo and nvim and adds some useful features on top.
tdoto open today's todostdo <date_expression>to open todos with flexible date formats, e.g:tdo 1,tdo monday,tdo next-friday,tdo 2-weeks-later,tdo 2025-07-14tdo entry <date_expression>to open journal entry with same flexible date formats as todos, e.g:tdo e tomorrowtdo e last-tue,tdo e 1-year-agotdo <note_title>to open or create anote_tile.mdnote, use folder names to categorise notes, e.g:tdo tech/vim-tipstdo noteortdo nto create a new note with the current timestamp indraftstdo find <text>ortdo fto interactively search fortextin all your notestdo findwithout any search term to review all your notestdo todoortdo tto show all your pending todostdo pendingortdo pwill show count of pending todostdo commit <path>ortdo cto commit changes in path, happens automatically, needed for plugins and integrations
Run
tdo hto get more help info on the command line
๐ Natural Date Parsing
tdo supports intuitive natural language date expressions for both todos and journal entries. This makes it easy to reference dates without calculating offsets manually.
Supported Formats
Numeric Offsets:
- Positive numbers for future days:
1,7,30 - Negative numbers for past days:
-1,-7,-30
Basic Relative Dates:
today,tomorrow,yesterday
Weekdays:
sunday,monday,tuesday,wednesday,thursday,friday,saturdaynext-sunday,next-monday, etc. (next week's occurrence)last-sunday,last-monday, etc. (previous week's occurrence)- Short forms:
sun,mon,tue,wed,thu,fri,satnext-sun,last-mon, etc.
Quick Aliases:
next-week,last-week,next-month,last-month,next-year,last-year
Programmatic Patterns:
N-weeks-ago/N-weeks-later(e.g.,2-weeks-ago,3-weeks-later)N-months-ago/N-months-later(e.g.,1-month-ago,6-months-later)N-years-ago/N-years-later(e.g.,1-year-ago,2-years-later)
Absolute Dates:
YYYY-MM-DDformat (e.g.,2025-07-14)
๐ Folder Structure
tdo expects an opinionated directory structure to function.
- Notes live in the
notessub-dir, use these for long term knowledge management, second brain - Notes use the templates/note.md file as template
- Todos live in the
todossub-dir, use these for short term notes, daily todos - Todos use the templates/todo.md file as template
- Journal entries live in
entriessub-dir, use these for personal notes, life logging - Journal entries use the templates/entry.md file as template
โโโ todos
โย ย โโโ 2023
โย ย โโโ 11
โย ย ย ย โโโ 2023-11-29.md
โโโ entries
โย ย โโโ 2024
โย ย โโโ 02
โย ย ย ย โโโ 2024-02-03.md
โโโ notes
โย ย โโโ tech
โย ย ย ย โโโ quit-vim.md
โย ย ย ย โโโ arch-btw.md
โโโ templates
ย ย โโโ entry.md
ย ย โโโ note.md
ย ย โโโ todo.md
โ๏ธ Configuration
You can configure tdo by either defining environment variables or via a $HOME/.config/tdorc file.
ADD_ENTRY_TIMESTAMP[boolean]: Whether to add a time stamp when usingtdo entryortdo e.ADD_NEW_NOTE_TIMESTAMP[boolean]: Whether to add a time stamp when creating new notes withtdo <note_title>.FILE_NAME_AS_TITLE[boolean]: Whether to add the file name as title when creating new notes withtdo <note_title>. Iftrue, then it adds<note_title>as a markdown title in the first line of the new note.ENTRY_TIMESTAMP_FORMAT[string]: can be any bash string such as a date format expression. It is ignored ifADD_ENTRY_TIMESTAMPis set tofalse.NOTE_TIMESTAMP_FORMAT([string]: can be any bash string such as a date format expression. It is ignored ifADD_NEW_NOTE_TIMESTAMPis set tofalse.
Default Configs
ADD_ENTRY_TIMESTAMP=true
ADD_NEW_NOTE_TIMESTAMP=false
FILE_NAME_AS_TITLE=false
# Reads ## Mon, 12:00 PM
ENTRY_TIMESTAMP_FORMAT="## %a, %I:%M %p"
# Reads ## Fri. Apr 06, 2024 - 06:48 PM
NOTE_TIMESTAMP_FORMAT="## %a. %b %d, %Y - %I:%M %p"
configs defined in
tdorcwill override corresponding environment variables
๐งช Testing
tdo includes comprehensive unit and integration tests to ensure reliability.
Running Tests
# Install bats-core (testing framework)
brew install bats-core # macOS
sudo apt-get install bats # Ubuntu/Debian
# Run all tests
bats tests/unit tests/integration
Test Coverage
- Unit Tests: Date parsing, file generation, utility functions
- Integration Tests: End-to-end workflows for todos, journal entries, and notes
- Mock System: Isolated testing with fixed dates and mocked external dependencies
All tests use a comprehensive mocking strategy to ensure consistent, predictable results across different environments and dates.
๐๏ธ What's Next
You tell me!
๐งโ๐ป Behind The Code
๐ Inspiration
After trying out every note management system under the sun I had decided on using plain markdown notes powered by nvim2k.
tdo is a spiritual successor and complimentary tool to that, taking the same principles and making it more accessible and simple.
๐ More CLI Tools
- cmtr โ Fast git commits
- mkrepo โ Spin up new GitHub repos from the CLI
- ghpm โ Manage all your GitHub repos
- gsync โ Sync your git repos
๐งฐ Tooling
- dots2k โ Dev Environment
- nvim2k โ Personalized Editor
- sway2k โ Desktop Environment
- qute2k โ Personalized Browser
โญ hit the star button if you found this useful โญ
Source | Blog | Twitter | LinkedIn | More Links | Other Projects