A flexible, interactive note-taking plugin for Neovim that adapts to any organizational system.
- 🎯 Interactive UI - Visual directory and template selection
- 📁 Flexible Structure - Works with any organizational system (PARA, Zettelkasten, flat files, etc.)
- 📝 Custom Templates - Pre-built templates for different note types
- 🔍 Powerful Search - Full-text search with quickfix integration
- ✅ Todo Management - Toggle checkboxes and manage tasks
- ⚡ Quick Capture - Instant note creation without breaking flow
- 🎨 Highly Customizable - Adapt to your workflow, not the other way around
{
"samar-exe/nvim-notes",
config = function()
require("notes").setup()
end,
}use {
"samar-exe/notes-nvim", -- Replace with actual repo
config = function()
require("notes").setup()
end
}- Clone or download the repository
- Copy
lua/notes/init.luato~/.config/nvim/lua/notes/init.lua - Add to your
init.lua:
require("notes").setup()require("notes").setup({
notes_dir = vim.fn.expand("~/notes/"), -- Where to store notes
})require("notes").setup({
notes_dir = vim.fn.expand("~/my-notes/"),
default_extension = ".md",
-- Directory structure (customize to your needs)
directories = {
"inbox", -- Quick capture
"projects", -- Active projects
"areas", -- Life areas
"resources", -- Reference material
"archive" -- Completed items
},
-- Custom templates
templates = {
default = {
"# {title}",
"",
"Created: {datetime}",
"",
},
project = {
"# Project: {title}",
"",
"**Status:** Active | **Created:** {date}",
"",
"## Objective",
"",
"## Tasks",
"- [ ] ",
"",
"## Notes",
"",
},
meeting = {
"# Meeting: {title}",
"",
"**Date:** {datetime}",
"**Attendees:** ",
"",
"## Agenda",
"",
"## Notes",
"",
"## Action Items",
"- [ ] ",
}
}
})Switch between popular organizational methods instantly:
-- PARA Method
:lua require("notes").switch_system("para")
-- Flat structure (everything in root)
:lua require("notes").switch_system("flat")
-- Simple categories
:lua require("notes").switch_system("simple")
-- By note type
:lua require("notes").switch_system("by_type")
-- Zettelkasten style
:lua require("notes").switch_system("zettelkasten")| Command | Description |
|---|---|
:NotesNew [name] |
Create new note (interactive directory & template selection) |
:NotesOpen |
Open existing note (with visual browser) |
:NotesBrowse |
Browse notes by directory |
:NotesList |
List all notes organized by directory |
:NotesDaily |
Create/open daily note |
:NotesQuick |
Create quick note in inbox |
:NotesSearch [query] |
Search across all notes |
-- Todo management
vim.keymap.set("n", "<leader>tt", "<cmd>lua require('notes').toggle_todo()<cr>", { desc = "Toggle todo" })
vim.keymap.set("n", "<leader>ta", "<cmd>lua require('notes').add_todo()<cr>", { desc = "Add todo" })Add these to your init.lua for faster access:
-- Note management
vim.keymap.set("n", "<leader>nn", "<cmd>NotesNew<cr>", { desc = "New note" })
vim.keymap.set("n", "<leader>no", "<cmd>NotesOpen<cr>", { desc = "Open note" })
vim.keymap.set("n", "<leader>nf", "<cmd>NotesSearch<cr>", { desc = "Find in notes" })
vim.keymap.set("n", "<leader>nd", "<cmd>NotesDaily<cr>", { desc = "Daily note" })
vim.keymap.set("n", "<leader>nq", "<cmd>NotesQuick<cr>", { desc = "Quick note" })
vim.keymap.set("n", "<leader>nb", "<cmd>NotesBrowse<cr>", { desc = "Browse notes" })
vim.keymap.set("n", "<leader>nl", "<cmd>NotesList<cr>", { desc = "List notes" })local wk = require("which-key")
wk.register({
["<leader>n"] = {
name = "Notes",
n = { "<cmd>NotesNew<cr>", "New note" },
o = { "<cmd>NotesOpen<cr>", "Open note" },
f = { "<cmd>NotesSearch<cr>", "Find in notes" },
d = { "<cmd>NotesDaily<cr>", "Daily note" },
q = { "<cmd>NotesQuick<cr>", "Quick note" },
b = { "<cmd>NotesBrowse<cr>", "Browse notes" },
l = { "<cmd>NotesList<cr>", "List notes" },
t = {
name = "Todo",
t = { "<cmd>lua require('notes').toggle_todo()<cr>", "Toggle todo" },
a = { "<cmd>lua require('notes').add_todo()<cr>", "Add todo" },
}
}
})Initialize the plugin with custom configuration.
require("notes").setup({
notes_dir = "~/notes/",
directories = {"inbox", "projects"},
templates = { ... }
})Create a new note. All parameters are optional - will prompt interactively if not provided.
-- Interactive creation
require("notes").new_note()
-- With specific parameters
require("notes").new_note("My Note", "projects", "project")Open existing note with interactive selection.
require("notes").open_note()Browse notes by directory with interactive selection.
require("notes").browse_directory()Search across all notes. If query not provided, will prompt for input.
-- Interactive search
require("notes").search_notes()
-- Direct search
require("notes").search_notes("todo")Create or open today's daily note.
require("notes").daily_note()Create a quick note in inbox for immediate capture.
require("notes").quick_note()Toggle todo checkbox on current line.
require("notes").toggle_todo()Add new todo item with interactive input.
require("notes").add_todo()Switch to a predefined organizational system.
require("notes").switch_system("para") -- PARA method
require("notes").switch_system("flat") -- Flat structureAvailable systems: "flat", "para", "simple", "by_type", "zettelkasten"
List all notes organized by directory in command output.
require("notes").list_notes()Templates support these automatic replacements:
{title}- Note title (without .md extension){date}- Current date (YYYY-MM-DD format){datetime}- Full timestamp (YYYY-MM-DD HH:MM:SS format)
Example template:
{
"# {title}",
"",
"Created: {datetime}",
"Date: {date}",
""
}-- Morning: Plan your day
:NotesDaily
-- During work: Quick capture
:NotesQuick
-- For projects: Interactive creation
:NotesNew
-- Find something: Search all notes
:NotesSearch "meeting notes"-- Create project note
:NotesNew "API Redesign"
-- Choose "projects" directory
-- Choose "project" template
-- Later, find and update
:NotesOpen
-- Select from visual list-- Create learning note
:NotesNew "PostgreSQL Basics"
-- Choose "learning" or "resources" directory
-- Choose "default" or custom "learning" templaterequire("notes").setup({
directories = {} -- Everything in ~/notes/
})require("notes").setup({
directories = {
"01-projects",
"02-areas",
"03-resources",
"04-archive"
}
})require("notes").setup({
directories = {
"work",
"personal",
"learning",
"ideas"
}
})- Neovim 0.7+
vim.ui.select(built-in or via UI plugin like dressing.nvim)
- ripgrep - For faster searching (falls back to
grep) - which-key.nvim - For keymap descriptions
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License - see LICENSE file for details.
- Inspired by various note-taking methodologies (PARA, Zettelkasten, etc.)
- Built for the Neovim ecosystem with modern Lua practices