# Notes setup This directory contains the Neovim-side notes integration for the dotfiles repository. The setup keeps `zk` as the source of truth for note creation, uses `markdown_oxide` for Markdown/wiki-link LSP behavior, and normalizes frontmatter independently of Obsidian.nvim. ## Goals - Create notes consistently from the CLI and Neovim. - Keep note files compatible with the Obsidian desktop app by using plain Markdown, YAML frontmatter, and Obsidian-style wiki links. - Let `markdown_oxide` handle workspace-aware Markdown LSP features such as hover, definitions, diagnostics, and missing-link actions. - Keep frontmatter fallback behavior independent of Obsidian.nvim. ## Files | File | Purpose | | --- | --- | | `init.lua` | Defines Neovim commands such as `:Note`, `:N`, `:NoteWork`, and `:NoteFrontmatter`. It calls `zk-nvim` for note creation and then normalizes frontmatter. | | `frontmatter.lua` | Shared frontmatter normalization logic used by the Neovim commands. | | `README.md` | This document. | Related files outside this directory: | File | Purpose | | --- | --- | | `config/nvim/plugin/markdown.lua` | Loads Markdown plugins, configures `zk-nvim` with its LSP disabled, and calls `require('_.notes').setup()`. | | `config/nvim/plugin/lsp.lua` | Enables `markdown_oxide` as the Markdown LSP and makes navic prefer it for Markdown symbols. | | `config/zk/config.toml` | Owns CLI note creation aliases, filename templates, group rules, and default templates. | | `config/zk/templates/` | Owns the actual note content templates used by `zk` for CLI and Neovim-created notes. | | `nix/parts/modules/shared/zk.nix` | Installs `zk` and links the `zk` config and templates. | | `nix/parts/modules/shared/vim.nix` | Installs `markdown-oxide` and Neovim support tooling. | ## Creation model `zk` is the only source of truth for creating intentional notes. This means filename generation, template expansion, group-specific behavior, and default frontmatter all come from `config/zk/config.toml` and `config/zk/templates/`. The Neovim commands call `zk-nvim`'s API, which delegates to `zk`. They do not duplicate template rendering in Lua. Lua only decides which `zk` options to pass and then normalizes frontmatter after the file exists. Prefer `:Note`/`:N` over the generic `:ZkNew` command for interactive note creation. `:ZkNew` remains available from `zk-nvim`, but `:Note` adds this repository's target parsing, command completion, and frontmatter normalization while still delegating note creation to `zk`. ## Neovim commands ### `:Note` and `:N` `:Note` is the real command. `:N` is a command-line abbreviation because `:N` is already a built-in Ex command. Examples: ```vim :Note My root note :N My root note :Note work Planning note :N personal Private note :Note til Something I learned :Note { dir = 'work', template = 'system-design.md', title = 'Queues' } ``` Default behavior creates a note at the root of `$NOTES_DIR`: ```vim :N My root note ``` If the first argument is a known alias or an existing top-level subdirectory, that target is used and the rest of the command becomes the title: ```vim :N work Team design note :N projects Side project note ``` First-argument completion includes both configured aliases and top-level subdirectories under `$NOTES_DIR`. Hidden directories and `assets` are excluded from completion. Bang form creates the note without opening it: ```vim :N! Inbox note ``` ### Convenience commands These commands are thin wrappers around `:Note` aliases: ```vim :NoteWork :NotePersonal <title> :NoteTil <title> :NoteJournal :NoteRfc <title> ``` They exist for muscle memory and discoverability; the flexible `:Note`/`:N` command is the preferred base command. ### `:NoteFrontmatter` `:NoteFrontmatter` normalizes frontmatter in the current buffer without writing the file. `:NoteFrontmatter!` normalizes frontmatter and writes the file. This command is useful for existing notes, notes created by tools outside the normal `zk` flow, or manual cleanup. ## Frontmatter normalization Frontmatter normalization is implemented in `frontmatter.lua` and is deliberately independent of Obsidian.nvim. Normalization guarantees these fields: - `id` - `title` - `aliases` The normalizer preserves other existing frontmatter fields. It also sorts known keys in this order when it rewrites frontmatter: ```text id, title, date, aliases, tags, then all other keys in their existing order ``` ### `id` fallback order `id` is derived in this order: 1. Existing valid `id`. 2. Timestamp/date prefix in the filename. 3. Existing `date` field. 4. Current timestamp as `YYYYMMDDHHMM`. Supported date inputs include: ```text YYYYMMDDHHMM YYYYMMDD YYYY-MM-DDTHH:MM YYYY-MM-DD HH:MM YYYY-MM-DD ``` A date-only input falls back to midnight, so `2024-01-02` becomes `202401020000`. ### `title` fallback order `title` is derived in this order: 1. Existing `title` field. 2. First level-one Markdown heading. 3. Filename stem with a leading timestamp/date prefix removed. Examples: ```text 202606141200 My Note.md -> My Note 2024-01-02 My Note.md -> My Note Plain Note.md -> Plain Note ``` ### `aliases` fallback behavior The normalizer parses existing inline or list-style aliases, then adds the normalized title as an alias if it is missing. Examples: ```yaml aliases: ['Existing'] ``` ```yaml aliases: - Existing ``` Both forms are read. The rewritten form is inline: ```yaml aliases: ['Existing', 'Title'] ``` ## When frontmatter normalization runs Frontmatter normalization runs in these places: 1. After creating a note through `:Note`, `:N`, or one of the convenience commands. 2. When an empty Markdown file under `$NOTES_DIR` is opened or created in Neovim. 3. Manually via `:NoteFrontmatter`. The empty-file path is important for `markdown_oxide`: if its missing-link code action creates an empty Markdown file, opening that file in Neovim adds fallback frontmatter. ## LSP responsibilities `markdown_oxide` is the Markdown LSP. It owns workspace-aware Markdown behavior such as: - wiki-link resolution - hover - jump to document - diagnostics for unresolved links - code actions for missing linked files `zk-nvim` is still installed, but its LSP auto-attach is disabled. It is used as a command/API layer for `zk` note creation and note pickers, not as the active Markdown LSP. Obsidian.nvim is intentionally not used. Obsidian app compatibility comes from the file format: plain Markdown, YAML frontmatter, and wiki links. ## CLI behavior CLI note creation remains owned by `zk` and `config/zk/config.toml`. Examples: ```sh zk p 'Personal note' zk w 'Work note' zk j zk til 'Something I learned' ``` ## Troubleshooting ### `:N` does not appear as a normal user command `:N` is an abbreviation for `:Note` because `:N` is already a built-in Ex command. Use `:Note` if you want to bypass abbreviation behavior. ### A new note was created in the wrong directory `:Note` treats the first word as a target only if it is a configured alias or an existing top-level subdirectory under `$NOTES_DIR`. Otherwise the entire command is treated as the title and the note is created at the root. ### Frontmatter was not added to a file created by another tool Open the file in Neovim, or run `:NoteFrontmatter!` in the buffer.