Marcus Kazmierczak

Home mkaz.blog

Working With Vim

VimWiki: Personal Knowledge Management in Vim

VimWiki transforms Vim (Neovim) into a powerful personal knowledge management system. If you spend your day in Vim, VimWiki provides an instant-access note-taking environment where you can capture thoughts, maintain daily journals, track tasks, and build an interconnected web of knowledgeβ€”all without leaving your editor.

πŸ“
Yes, you can take notes in any text editor. VimWiki provides something better: a structured system with keyboard shortcuts, automatic file organization, daily notes, templates, interlinking, and a dedicated workspace that's always ready when inspiration strikes.

The killer feature? Daily notes that are always just two keystrokes away. Whether you're deep in a coding session or reviewing yesterday's work, <Leader>w<Leader>w instantly opens today's journal entry. No context switching, no hunting for files, just pure note-taking flow.

Why VimWiki for Journaling and Note-Taking?

If you're already comfortable in Vim, VimWiki offers several compelling advantages:

  • Zero friction: Launch notes instantly from anywhere without switching applications
  • Plain text storage: Your notes are markdown files you can sync, backup, grep, or version control
  • Daily notes built-in: Automatic date-based organization with keyboard navigation between days
  • Flexible templates: Standardize your note structure for different contexts (meetings, daily logs, project notes)
  • Bidirectional linking: Build a personal wiki with interconnected pages
  • Task management: Built-in todo lists with completion tracking and progress levels
  • Keyboard-driven: No mouse requiredβ€”navigate, create, and organize entirely from the keyboard

VimWiki excels as a personal knowledge base where you accumulate notes, observations, and todos in a searchable, linkable format that grows with you over time.

Installation and Configuration

Install VimWiki using your preferred plugin manager. For vim-plug:

Plug 'vimwiki/vimwiki'

Basic Configuration

The most important configuration step is setting your wiki directory and choosing markdown as your format. I recommend storing your wiki in a location you can sync across devices using tools like Syncthing, Dropbox, or iCloud.

For traditional Vim (.vimrc):

let g:vimwiki_list = [{'path': '~/wiki/', 'syntax': 'markdown', 'ext': 'md'}]

For Neovim (init.lua):

vim.g.vimwiki_list = {{
    path = '~/wiki',
    syntax = 'markdown',
    ext = 'md'
}}

This configuration:

  • Sets your wiki root to ~/wiki/
  • Uses markdown syntax (recommended over VimWiki's default format)
  • Uses .md file extensions for compatibility with other markdown tools
⚠️
Setting ext to .md will set all your markdown fiels to Vimwiki syntax. If you don't want that set: vim.g.vimwiki_global_ext = 0

Your Daily Journaling Workflow

Let's walk through the most common use case: maintaining a daily journal or work log where you track tasks, capture notes, and document and review your progress.

Creating Today's Entry

From anywhere in Vim, press <Leader>w<Leader>w to create or open today's journal entry. VimWiki automatically:

  1. Creates a diary subdirectory in your wiki (if it doesn't exist)
  2. Generates a date-stamped file like 2025-10-08.md
  3. Opens the file, ready for you to start writing

The beauty of this system: it works regardless of where you are. Deep in a code project? Working in a different directory? Doesn't matter. Two keystrokes get you to your journal.

Example Daily Note Structure

Here's what a typical daily note might look like:

# Oct 08, 2025

## Todo

- [ ] Review PR for authentication refactor
- [ ] Write test cases for payment integration
- [ ] Team meeting at 2pm
- [ ] Update documentation for API changes

## Notes

Had a good conversation with Sarah about the database migration strategy.
Key points:
- Plan to migrate in three phases
- Need to maintain backwards compatibility for 2 weeks
- [[Database Migration Plan]] - created detailed page

## Learning

Discovered that Python's `walrus operator` can simplify the file processing
loop. See [[Python Tips]] for examples.

## Tomorrow

- Follow up on the PR feedback
- Start work on the payment webhook handler

VimWiki provides keyboard shortcuts to review previous entries:

  • <Ctrl-Up> – Jump to yesterday's note (or the most recent note before today)
  • <Ctrl-Down> – Jump to tomorrow's note (if it exists)

This navigation is incredibly useful for reviewing what you left unfinished yesterday. My typical morning workflow:

  1. Press <Leader>w<Leader>w to open today's note
  2. Press <Ctrl-Up> to jump to yesterday
  3. Review incomplete tasks and notes
  4. Press <Ctrl-Down> to return to today
  5. Copy over tasks that need to continue

Calendar Integration

For a visual way to browse your daily notes, install the Calendar plugin:

Plug 'mattn/calendar-vim'

I map F3 to open the calendar:

" Traditional Vim
nnoremap <F3> :Calendar<CR>

" Or in Neovim Lua
vim.keymap.set('n', '<F3>', ':Calendar<CR>', { desc = 'Open calendar' })

The calendar shows which days have existing entries and lets you jump to any date by pressing Enter.

Vimwiki Calendar Screenshot

Working with Templates

Templates are game-changers for consistency. Instead of manually typing the same structure each time, templates let you define reusable note structures that auto-populate when creating new entries.

Automatic Diary Templates

The simplest approach uses VimWiki's built-in auto_header option, which inserts a date-based heading:

vim.g.vimwiki_auto_header = 1

This creates a basic heading like # 2025-10-08 in new diary entries.

Custom Templates with Autocmds

For more control, use Vim's autocmd feature to insert custom templates when creating new files. Here's how to set up a diary template:

Simple static template (Neovim Lua):

-- Create the template file first at ~/wiki/templates/diary-template.md
vim.api.nvim_create_autocmd('BufNewFile', {
    pattern = '*/diary/*.md',
    command = '0r ~/wiki/templates/diary-template.md',
})

The 0r command reads the template file and inserts it at line 0 (the beginning).

Dynamic template with script (for date formatting):

vim.api.nvim_create_autocmd('BufNewFile', {
    pattern = '*diary/*.md',
    command = "0r! ~/bin/vimwiki-diary-tpl.py '%'",
})

The 0r! runs a command and inserts its output. The script receives the filename, allowing it to parse the date and generate formatted content.

Here's a Python script for diary templates:

#!/usr/bin/env python3
import sys
from datetime import datetime
from pathlib import Path

template = """# {date}

## Todo

- [ ]

## Notes

## Learning

## Tomorrow
"""

# Parse date from filename (format: YYYY-MM-DD.md)
dt = datetime.now()
if len(sys.argv) > 1:
    fp = Path(sys.argv[1])
    dt = datetime.strptime(fp.stem, "%Y-%m-%d")

print(template.format(date=dt.strftime("%b %d, %Y")))

Make it executable: chmod +x ~/bin/vimwiki-diary-tpl.py

This approach gives you:

  • Formatted date headers ("Oct 08, 2025" instead of "2025-10-08")
  • Pre-defined sections that structure your daily notes
  • Correct dates even when opening older diary entries

Advanced Template Example: Interview Notes

I use templates often, not just for daily notes, or just in VimWiki. Here's a good example that I use for interviews, I use a custom template with an interactive prompts and variable substitution:

-- File: ~/.config/nvim/lua/interview.lua

local function create_interview_note()
  -- Prompt for candidate name
  local candidate = vim.fn.input('Candidate name: ')
  if candidate == '' then
    return
  end

  -- Generate filename from name
  local filename = candidate:gsub(' ', '-')
  local filepath = vim.fn.expand('~/Documents/Archive/Interviews/') .. filename .. '.md'

  -- Create directory if needed
  vim.fn.mkdir(vim.fn.fnamemodify(filepath, ':h'), 'p')

  -- Open the new file
  vim.cmd('edit ' .. vim.fn.fnameescape(filepath))

  -- Read template and substitute variables
  local template_path = vim.fn.expand('~/Documents/Resources/Templates/Interview-Template.md')
  local template_lines = {}
  local date = os.date('%b %d, %Y')

  for line in io.lines(template_path) do
    line = line:gsub('{{title}}', candidate)
    line = line:gsub('{{date}}', date)
    table.insert(template_lines, line)
  end

  -- Insert processed template into buffer
  vim.api.nvim_buf_set_lines(0, 0, -1, false, template_lines)
end

-- Map to <leader>ni (New Interview)
vim.keymap.set('n', '<leader>ni', create_interview_note, { desc = 'New interview note' })

The template file at ~/Documents/Resources/Templates/Interview-Template.md:

# Interview: {{title}}

**Date:** {{date}}
**Position:**
**Interviewer:**

## Candidate Background

- Current role:
- Years of experience:
- Key technologies:

## Technical Discussion

### Question 1: [Topic]

**Question:**

**Answer:**

**Assessment:**

## Behavioral Questions

### Tell me about a time when...

**Answer:**

**Assessment:**

## Strengths

-

## Concerns

-

## Decision

- [ ] Move to next round
- [ ] Send take-home assignment
- [ ] Pass

## Follow-up Actions

- [ ]

Source the file in your Neovim config:

require('interview')

Now typing <leader>ni prompts for a candidate name, creates a file like ~/Documents/Archive/Interviews/john-smith.md, and populates it with a structured interview template where {{title}} and {{date}} are replaced with actual values.

Template Use Cases

Templates work great for:

  • Meeting notes: Standard agenda, attendees, action items structure
  • Project pages: Overview, goals, timeline, resources sections
  • Learning notes: Topic, key concepts, examples, references
  • Weekly reviews: Accomplishments, challenges, next week's focus
  • 1-on-1 meetings: Talking points, feedback, action items
  • Bug reports: Steps to reproduce, environment, expected vs actual behavior

Create template files for contexts you visit frequently, then use autocmds or custom functions to insert them automatically.

Building Your Personal Wiki

Beyond daily journaling, VimWiki shines for building an interconnected knowledge base.

Opening Your Wiki

Press <Leader>ww to open your wiki's index page (~/wiki/index.md). This becomes your home baseβ€”a table of contents linking to your major note collections.

Example index structure:

# My Wiki

## Daily Notes

- [[diary/diary|Journal Index]] - All daily entries
- Quick access: Press `<Leader>w<Leader>w`

## Projects

- [[Project Alpha]] - Client work for Alpha Corp
- [[Project Beta]] - Internal tool development
- [[Side Projects]] - Personal projects and experiments

## Learning

- [[Python Tips]] - Python snippets and techniques
- [[Vim Tricks]] - Vim commands I want to remember
- [[System Design]] - Architecture patterns and concepts

## Reference

- [[Vim Cheatsheet]]
- [[Git Workflows]]
- [[Command Line Tools]]

## Work

- [[Team Meetings]] - Notes from team meetings
- [[1-on-1s]] - Manager 1-on-1 notes
- [[Performance Reviews]]

Creating and Linking Pages

VimWiki uses wiki-style double-bracket links: [[Page Name]]

To create a linked page:

  1. Type the link: [[Database Migration Plan]]
  2. Put your cursor on the link (in normal mode)
  3. Press <Enter>
  4. VimWiki creates database-migration-plan.md and opens it
  5. Start writing content

The filename is automatically generated from the link text (lowercased, spaces to hyphens).

Press <Backspace> to return to the previous page.

  • <Leader>ww – Open wiki index
  • <Leader>w<Leader>w – Open today's diary entry
  • <Enter> – Follow link or create linked page
  • <Backspace> – Return to previous page
  • <Tab> – Jump to next link on the page
  • <Shift-Tab> – Jump to previous link on the page

These shortcuts enable fast keyboard-driven navigation through your knowledge base.

Organizing Your Notes

As your wiki grows, organization becomes important. Here are strategies that work:

Topic-based organization:

~/wiki/
β”œβ”€β”€ index.md
β”œβ”€β”€ python/
β”‚   β”œβ”€β”€ index.md
β”‚   β”œβ”€β”€ decorators.md
β”‚   β”œβ”€β”€ async-patterns.md
β”‚   └── testing.md
β”œβ”€β”€ vim/
β”‚   β”œβ”€β”€ index.md
β”‚   β”œβ”€β”€ plugins.md
β”‚   └── custom-functions.md
└── diary/
    β”œβ”€β”€ 2025-10-01.md
    β”œβ”€β”€ 2025-10-02.md
    └── ...

Create links with relative paths: [[python/decorators]]

Tag-based connections:

Add tags to your notes for cross-cutting themes:

# Python Decorators

tags: #python #programming #design-patterns

Decorators are a powerful pattern for...

Then use grep/ripgrep to find all notes with a tag:

rg '#python' ~/wiki/

Date-based references:

Link from daily notes to topic pages, and from topic pages back to daily notes where you made progress:

# Database Migration Plan

## Timeline

- 2025-10-08: Initial planning ([[diary/2025-10-08]])
- 2025-10-15: Phase 1 complete ([[diary/2025-10-15]])

This creates a bidirectional timeline between your journal and your project pages.

Task Management with Todo Lists

VimWiki includes built-in todo list support with markdown checkbox syntax.

Basic Todo Lists

Create checkboxes with standard markdown syntax:

- [ ] Write proposal for new feature
- [ ] Review Sarah's PR
- [ ] Update documentation

Put your cursor on any line and press <Ctrl-Space> to toggle completion:

- [X] Write proposal for new feature
- [ ] Review Sarah's PR
- [ ] Update documentation

Nested Tasks

Indent items to create sub-tasks. Toggling a parent task automatically toggles all children:

- [ ] Launch new feature
    - [ ] Write tests
    - [ ] Update documentation
    - [ ] Deploy to staging
    - [ ] Get approval from QA

Toggling "Launch new feature" marks all sub-items complete or incomplete.

Vim's folding works with nested listsβ€”use za to toggle fold on the parent item.

Partial Completion

For tasks that are in-progress, use gln to cycle forward through completion states:

  • gln – Toggle forward through completion levels
  • glp – Toggle backward through completion levels

The progression uses these characters:

- [ ] -- 0% complete
- [.] -- 1-33% complete
- [o] -- 34-66% complete
- [O] -- 67-99% complete
- [X] -- 100% complete

This is useful for tracking progress on large tasks:

- [o] Refactor authentication system (about halfway done)
    - [X] Extract auth logic to separate module
    - [X] Add unit tests for auth module
    - [ ] Update all controllers to use new module
    - [ ] Integration testing

Customizing Completion Symbols

You can customize the progression symbols:

let g:vimwiki_listsyms = 'βœ—β—‹β—β—βœ“'

For Lua config:

vim.g.vimwiki_listsyms = 'βœ—β—‹β—β—βœ“'

See :help vimwiki-todo for more options.

Searching Your Wiki

VimWiki includes built-in search, but I typically use ripgrep for more flexible searching.

From any wiki page, use:

:VWS /search term/

This searches all wiki files and opens results in the location list. Use :lopen to view all matches and jump between them.

The advantage: VimWiki search works from any directory since it targets your configured wiki path.

Using ripgrep

For more powerful searches, use ripgrep directly:

rg "database migration" ~/wiki/
rg -i "todo.*urgent" ~/wiki/diary/
rg "#python" ~/wiki/ -l  # List files containing tag

Ripgrep is faster, supports complex patterns, and integrates well with tools like fzf. See my Vim search page for integration tips.

Combine both: use VimWiki search when you're already in your wiki, and ripgrep when you need more sophisticated pattern matching or are searching from outside Vim.

Creating Tables

VimWiki makes markdown table creation painless with automatic formatting and navigation.

Create a table with :VimwikiTable 4 2 (4 columns, 2 rows):

|  |  |  |  |
|--|--|--|--|
|  |  |  |  |
|  |  |  |  |

Press <Tab> to move to the next cellβ€”VimWiki auto-formats the table as you type:

| Name    | Role       | Team     | Location |
| ------- | ---------- | -------- | -------- |
| Alice   | Engineer   | Backend  | SF       |
| Bob     | Designer   | Product  | NYC      |

Press <Enter> or <Tab> in the last cell to create a new row.

Vimwiki table creation and navigation

Tables are great for: - Meeting attendee lists - Decision matrices - Comparison charts - Time tracking logs

See :help vimwiki-tables for advanced table commands.

Advanced Configuration

Changing Diary Frequency

Daily notes are the default, but VimWiki supports other frequencies:

vim.g.vimwiki_list = {{
    path = '~/wiki',
    syntax = 'markdown',
    ext = 'md',
    diary_frequency = 'weekly',  -- or 'monthly', 'yearly'
    diary_start_week_day = 'monday'
}}

Options: - daily – One entry per day (default) - weekly – One entry per week (dated to week start) - monthly – One entry per month (dated to month start) - yearly – One entry per year (dated to year start)

For weekly frequency, diary_start_week_day sets which day starts the week (default: monday).

A monthly entry for April 2025 would be 2025-04-01.md, not 2025-04.md.

Custom Diary Location

Change the diary subdirectory name:

vim.g.vimwiki_list = {{
    path = '~/wiki',
    syntax = 'markdown',
    ext = 'md',
    diary_rel_path = 'Journal'  -- Use Journal/ instead of diary/
}}

Multiple Wikis

You can maintain separate wikis for different contexts:

vim.g.vimwiki_list = {
    {
        path = '~/wiki/personal',
        syntax = 'markdown',
        ext = 'md'
    },
    {
        path = '~/wiki/work',
        syntax = 'markdown',
        ext = 'md'
    }
}

Use <Leader>ww for the first wiki, <Leader>w<Leader>ww for the second, etc.

Disabling Table Mappings

If VimWiki's table mappings conflict with other plugins:

vim.g.vimwiki_key_mappings = {
    table_mappings = 0,
}

Tips and Workflow Recommendations

Start with Daily Notes

If you're new to VimWiki, start with the diary feature. Build the habit of opening today's note each morning and capturing tasks and thoughts throughout the day. Once that feels natural, expand into topic-based pages.

Your daily notes become an index of your work. When you make progress on a project or learn something new, create a link:

# Oct 08, 2025

## Notes

Figured out the caching issue. Added details to [[Redis Configuration]].

This creates a trail from what you did (daily notes) to what you learned (topic pages).

Review Yesterday Before Planning Today

Make it a ritual: 1. Open today's note (<Leader>w<Leader>w) 2. Jump to yesterday (<Ctrl-Up>) 3. Review incomplete tasks and notes 4. Return to today (<Ctrl-Down>) 5. Plan your day

Use Templates Consistently

The more consistent your note structure, the easier it is to review and search later. Pick a template for daily notes and stick with it for at least a month.

Sync Your Wiki

Store your wiki in a synced folder (Dropbox, iCloud, Syncthing) so you can access it from multiple machines. Plain text markdown files sync effortlessly.

Don't Over-Organize

Resist the urge to create elaborate folder hierarchies. Start with a flat structure and only add organization when you feel the pain of too many files. Links and search are often enough.

Combine with Version Control

For important wikis (especially work notes), initialize a git repository:

cd ~/wiki
git init
git add .
git commit -m "Initial wiki"

Commit periodically to create snapshots of your knowledge base. This provides history, backup, and the ability to recover deleted content.

Troubleshooting

Links aren't working: Make sure you're in a wiki file (inside your configured wiki path). VimWiki features only activate for files within the wiki.

Diary templates not inserting: Check that your autocmd pattern matches your diary path. Use :echo expand('%:p') in a diary file to see the full path.

Wrong diary date: If creating notes with the calendar plugin shows incorrect dates, verify your diary_frequency and diary_start_week_day settings.

Table formatting breaks: VimWiki table formatting works best with fixed-width fonts. If using a proportional font in your terminal, tables may appear misaligned.

Conflicts with other plugins: If you experience mapping conflicts, see :help vimwiki-key-mappings for options to disable specific VimWiki shortcuts.

Summary

VimWiki transforms Vim into a personal knowledge management system that integrates seamlessly into your development workflow. The combination of instant-access daily notes, flexible templates, bidirectional linking, and plain text storage creates a note-taking environment that grows with you.

Start simple: install VimWiki, configure your directory, and begin using daily notes with <Leader>w<Leader>w. As the habit forms, expand into topic pages, templates, and interconnected notes.

The power isn't in the featuresβ€”it's in having a low-friction place to capture, organize, and retrieve your thoughts without leaving the editor where you already spend your day.

Additional Resources

  • VimWiki GitHub - Plugin source and documentation
  • Calendar plugin - Visual calendar for diary navigation
  • :help vimwiki - Complete built-in documentation
  • :help vimwiki-todo - Todo list features
  • :help vimwiki-tables - Table commands and formatting
  • My Vim search page - Search integration tips

Hat tip to Jakub Kadlcik for the diary template autocmd approach.