Skip to content

kensonjohnson/notes.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

33 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

notes.nvim

A powerful yet simple Neovim plugin for managing daily notes and quick notes with flexible templates and frontmatter support.

โœจ Features

  • ๐Ÿ“… Daily Notes: Create and open daily notes with intelligent date parsing
  • โšก Quick Notes: Create random-named notes in an inbox for rapid capture
  • ๐ŸŽจ Flexible Templates: Progressive enhancement from zero-config to fully customizable
  • ๐Ÿ“ Smart Frontmatter: Automatic YAML frontmatter with timestamps and metadata
  • โž• Add Frontmatter: Add frontmatter to any existing markdown file
  • ๐Ÿ”„ Auto-timestamps: Automatically update modified timestamps on save
  • ๐ŸŽฏ Smart Completion: Intelligent date completion with fuzzy matching
  • ๐Ÿ›ก๏ธ Robust Error Handling: Helpful error messages with actionable suggestions
  • ๐ŸŒ Cross-platform: Works seamlessly on macOS, Linux, and Windows

๐Ÿš€ Quick Start

Zero Configuration - Just provide your PKM directory:

require('notes').setup({
  pkm_dir = '~/Documents/notes'  -- That's it!
})

This gives you sensible defaults with useful daily note templates:

  • Today's Focus - Plan your priorities
  • Notes - Capture thoughts throughout the day
  • Tomorrow's Prep - Set yourself up for success

๐Ÿ“ฆ Installation

Requirements

IMPORTANT: You must specify your PKM directory. The plugin will validate the path and provide helpful setup guidance.

Common PKM directory examples:

  • macOS/Linux: '~/Documents/pkm' or '/home/username/notes'
  • Windows: 'C:\\Users\\username\\Documents\\pkm'
  • Obsidian vault: '~/Documents/MyVault'
  • Any path: The plugin supports ~ expansion and environment variables

Setup with Lazy.nvim

return {
  "kensonjohnson/notes.nvim",
  config = function()
    require('notes').setup({
      pkm_dir = '~/Documents/notes',  -- REQUIRED: Your PKM directory
    })
  end,
  keys = {
    { '<leader>nd', function() require('notes').daily_note() end, desc = 'Open daily note' },
    { '<leader>nt', function() require('notes').tomorrow_note() end, desc = 'Open tomorrow note' },
    { '<leader>nn', function() require('notes').quick_note() end, desc = 'Create quick note' },
    { '<leader>nf', function() require('notes').add_frontmatter() end, desc = 'Add frontmatter' },
  },
  cmd = { 'DailyNote', 'TomorrowNote', 'QuickNote', 'AddFrontmatter' },
  ft = "markdown", 
}

โšก Lazy Loading Configuration

IMPORTANT: If you use lazy loading with cmd and/or keys, you should also include ft = "markdown" to ensure autocommands are properly registered.

return {
  "kensonjohnson/notes.nvim",
  config = function()
    require('notes').setup({
      pkm_dir = '~/Documents/notes',
    })
  end,
  ft = "markdown",  -- Makes sure autocommands register without needing to create a new note with :DailyNote or :QuickNote
  keys = {
    { '<leader>nd', function() require('notes').daily_note() end, desc = 'Open daily note' },
    { '<leader>nt', function() require('notes').tomorrow_note() end, desc = 'Open tomorrow note' },
    { '<leader>nn', function() require('notes').quick_note() end, desc = 'Create quick note' },
    { '<leader>nf', function() require('notes').add_frontmatter() end, desc = 'Add frontmatter' },
  },
  cmd = { 'DailyNote', 'TomorrowNote', 'QuickNote', 'AddFrontmatter' },
}

Why ft = "markdown" is needed:

  • The plugin sets up autocommands to auto-update the modified field in frontmatter
  • With only cmd, the plugin loads when commands are executed, but autocommands aren't registered until then
  • Adding ft = "markdown" ensures the plugin loads when you open any markdown file, registering the autocommands
  • This allows the modified timestamp to update automatically when you save files in your PKM directory

๐ŸŽจ Template System

The plugin features a progressive enhancement template system - start simple, customize as needed.

Level 0: Zero Config (Sensible Defaults)

require('notes').setup({ pkm_dir = '~/notes' })

Creates daily notes with:

# Wednesday, July 23, 2025

## Today's Focus


## Notes


## Tomorrow's Prep

Level 1: Simple Customization

require('notes').setup({
  pkm_dir = '~/notes',
  templates = {
    daily = { "Morning Pages", "Work Log", "Gratitude" }
  }
})

Level 2: Function Templates (Dynamic)

require('notes').setup({
  pkm_dir = '~/notes',
  templates = {
    daily = function(context)
      local sections = { "## Today's Goals" }
      
      if context.is_monday then
        table.insert(sections, "## Weekly Planning")
      end
      
      if context.is_friday then
        table.insert(sections, "## Week Review")
      end
      
      table.insert(sections, "## Notes")
      return sections
    end
  }
})

Level 3: Object Templates (Full Control)

require('notes').setup({
  pkm_dir = '~/notes',
  templates = {
    daily = {
      header = "# {{weekday}} Focus - {{month_name}} {{day}}",
      sections = {
        { title = "Priority", content = "- " },
        { title = "Notes", content = "" },
        { 
          title = "Weekend Plans", 
          condition = "is_friday",
          content = { "- Plan weekend activities", "- Review week" }
        }
      },
      footer = "---\nCreated: {{timestamp}}"
    }
  }
})

Level 4: External Template Files

require('notes').setup({
  pkm_dir = '~/notes',
  templates = {
    daily = { file = "~/.config/nvim/templates/daily.md" },
    meeting = { file = "~/.config/nvim/templates/meeting.md" }
  }
})

Template file example (daily.md):

# {{weekday}}, {{month_name}} {{day}}, {{year}}

## Daily Focus
- Priority: {{user_name}}'s main task

## Notes

Created at {{time_12h}}

๐ŸŽฏ Smart Date Input

The :DailyNote command supports intelligent date parsing with smart completion:

Supported Formats

  • Relative: today, tomorrow, yesterday
  • Offsets: 1, -2, 7 (days from today)
  • Weekdays: next monday, last friday
  • ISO dates: 2025-07-23
  • US dates: 7/23/2025, 7/23/25

Smart Completion

Type :DailyNote and press <Tab> for intelligent suggestions:

  • Filters based on your input
  • Shows relative dates, weekdays, and date examples
  • Fuzzy matching for easy selection

โš™๏ธ Full Configuration

require('notes').setup({
  pkm_dir = '~/Documents/notes',  -- REQUIRED: Your PKM directory
  
  frontmatter = {
    use_frontmatter = true,          -- Enable/disable frontmatter
    auto_update_modified = true,     -- Auto-update modified timestamp on save
    scan_lines = 20,                 -- Lines to scan for frontmatter (1-100)
    overwrite_frontmatter = false,   -- Allow :AddFrontmatter to replace existing frontmatter
    fields = {
      id = true,                     -- Include ID field
      created = true,                -- Include created timestamp
      modified = true,               -- Include modified timestamp
      tags = true,                   -- Include tags field
    }
  },
  
  templates = {
    daily = {
      tags = "[#daily]",             -- Default tags for daily notes
      -- Use any template level here (array, function, object, or file)
    },
    quick = {
      tags = "[]",                   -- Default tags for quick notes
      id_length = 8,                 -- Random ID length (4-32)
      -- Custom template supported here too
    }
  }
})

โž• Adding Frontmatter to Existing Files

Add frontmatter to any markdown file with :AddFrontmatter:

:AddFrontmatter   " Adds frontmatter with random ID and empty tags
  • Generates random ID (same as quick notes)
  • Uses empty tags [] by default
  • Respects your frontmatter.fields settings
  • Won't overwrite existing frontmatter unless overwrite_frontmatter = true

๐Ÿ“ Directory Structure

Daily notes are organized as:

PKM_DIR/Daily/YYYY/MM-MMM/YYYY-MM-DD-Weekday.md

Quick notes go to:

PKM_DIR/+Inbox/randomname.md

๐ŸŽฎ Usage

Commands

  • :DailyNote [date] - Open daily note (supports smart date input)
  • :TomorrowNote - Open tomorrow's daily note
  • :QuickNote - Create a new quick note
  • :AddFrontmatter - Add frontmatter to current markdown file

Examples

:DailyNote                " Today's note
:DailyNote tomorrow       " Tomorrow's note
:DailyNote next friday    " Next Friday's note
:DailyNote 2025-12-25     " Christmas note
:DailyNote -3             " Note from 3 days ago

Programmatic Usage

-- Call functions directly
require('notes').daily_note()
require('notes').tomorrow_note()
require('notes').quick_note()
require('notes').dynamic_daily_note('next monday')
require('notes').add_frontmatter()

๐Ÿ”ง Template Context

Templates receive a rich context object with:

context = {
  -- Date information
  date = "2025-07-23",
  year = 2025,
  month = 7,
  day = 23,
  weekday = "Wednesday",
  month_name = "July",
  
  -- Convenience booleans
  is_monday = false,
  is_friday = false,
  is_weekend = false,
  is_workday = true,
  
  -- Time information
  timestamp = "2025-07-23T09:00:00",
  time_12h = "9:00 AM",
  time_24h = "09:00",
  
  -- Note information
  note_id = "2025-07-23",
  note_type = "daily", -- or "quick"
  user_name = "username",
  
  -- Utility functions
  format_date = function(fmt) return os.date(fmt, timestamp) end
}

๐Ÿ›ก๏ธ Error Handling

The plugin provides helpful error messages with actionable suggestions:

  • Configuration errors: Clear guidance on fixing setup issues
  • Invalid dates: Suggestions for valid date formats
  • Missing directories: Step-by-step instructions for resolution
  • Template errors: Graceful fallbacks with helpful debugging info

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

AI

Try using the llms.md file to improve generated output!

๐Ÿ“„ License

MIT License - see LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages