ymic9963/mdnotes.nvim
Simple, improved, and extensible Markdown note taking.
📓 mdnotes.nvim
Simple, improved, and extensible Markdown note taking.
☀️ Introduction
Mdnotes aims to be a lightweight plugin that improves the Markdown note-taking experience in Neovim, with minimal configuration required. It also exposes most of the functions used internally, so that the user can create an extensible note-taking experience similar to Neovim's philosophy.
In the Recommendations section I've written some notes on my recommended mdnotes setup, and please read MARKDOWN.md to know how mdnotes aims to format your notes.
If you are migrating from another note-taking application, then MIGRATING.md might be of interest to you, and I've also written some useful tips in TIPS.md for when writing notes in out-of-the-box Neovim. Lastly, a disclaimer I must unfortunately say, is if you are executing any mass data-altering commands, ensure you have a notes backup!
All documentation is available with :h mdnotes.txt. Execute :checkhealth mdnotes to ensure there are no problems with your plugin config.
🔥 Features
For a complete descriptive feature list with their associated commands, please see FEATURES.md.
- Open, toggle, rename, relink, and normalize inline links
- Create, follow, rename, show, delete, and find WikiLinks
- Insert, manage, and delete assets
- Create, best-fit, insert/move/duplicate/align/sort columns, and insert empty rows for tables
- Navigate to index file or dynamic journal files
- Sequential Markdown buffer history
- Heading navigation
- Toggling strong/emphasis/inline code/strikethrough/autolink formatting
- Ordered and unordered list continuation and renumbering
- Task list toggling
- Unformat lines to remove any Markdown formatting
- Generate Table of Contents
- Outliner mode
- Create user commands within the plugin namespace for organisation
- Most internal functions are exposed as an API for extensibility (
:h mdnotes-api).
👽 Setup
Supports Neovim 0.10 or later.
Using vim.pack,
vim.pack.add({"https://github.com/ymic9963/mdnotes.nvim" })
require("mdnotes").setup({
-- Config here
})
Using the lazy.nvim package manager,
{
"ymic9963/mdnotes.nvim",
}
and specify your config using opts = {} or with a setup({}) function,
{
"ymic9963/mdnotes.nvim",
opts = {
-- Config here
}
-- or
config = {
require("mdnotes").setup({
-- Config here
})
}
}
🌐 Default Config
{
index_file = "",
journal_file = "", -- path or function returning string for dynamic journal file
assets_path = "", -- path or function returning string for dynamic asset path
asset_insert_behaviour = "copy",-- "copy" or "move" files when inserting from clipboard
overwrite_behaviour = "error", -- "overwrite" or "error" when finding assset file conflicts
open_behaviour = "buffer", -- "buffer", "tab", "split", or "vsplit" to open when following links
date_format = "%a %d %b %Y" -- date format based on :h strftime()
prefer_lsp = false, -- to prefer LSP functions than the mdnotes functions
auto_list_continuation = true, -- automatic list continuation
default_keymaps = false,
autocmds = true, -- enable or disable plugin autocmds, check docs for enabling/disabling individual ones
table_best_fit_padding = 0, -- add padding around cell contents when using tables_best_fit
toc_depth = 4 -- depth shown in the ToC
user_commands = {} -- table with user commands in {command_name = function} scheme
}
📂 Directory Setup
Sample directory structure for mdnotes is shown below. See RATIONALE.md for reasons regarding the accepted file structure.
notes/
├───assets/
│ ├───fire.png
│ └───water.pdf
├───music.md
├───electronics.md
etc.
This plugin was made with this type of directory structure in mind because this is how I use it. If this directory configuration doesn't suit you please make an issue and hopefully I'll be able to accomodate anyone's needs.
💋 Recommendations
I've specified below some recommended plugins, keymaps, and optional settings for a great experience with mdnotes.
🔌 Plugins
For the best Neovim Markdown note-taking experience, I've listed some other projects to optionally install alongside mdnotes,
- nvim-treesitter - Tree-sitter for Neovim; with this also install the
markdown,markdown_inline, andlatexparsers. - In-Neovim Previewer for Markdown files (both are excellent),
- Live Previewer for Markdown files in browser,
- markdown-preview.nvim - Older, more widely used, has dependencies.
- live-preview.nvim - Newer, no dependencies.
- LSP - Please see the Using LSPs Section for more information regarding LSPs, but I recommend,
- Check out some Other Cool Markdown-related Plugins that you may want to use alongside (or instead of)
mdnotes.
⌨️ Keymaps
The keymappings below can be enabled by setting default_keymaps = true as they are not enabled by default, and they will only be available in Markdown buffers. Place any mdnotes keymaps in a <Neovim config path>/after/ftplugin/markdown.lua file so that they're also Markdown specific. For organisation they use the <leader>m prefix.
vim.keymap.set('n', '<leader>mgx', ':Mdn inline_link open<CR>', { buffer = true, desc = "Open inline link URI under cursor" })
vim.keymap.set('n', '<leader>mgf', ':Mdn wikilink follow<CR>', { buffer = true, desc = "Open markdown file from WikiLink" })
vim.keymap.set('n', '<leader>mgF', ':Mdn wikilink follow_hor<CR>', { buffer = true, desc = "Open markdown file from WikiLink in a horizontal split" })
vim.keymap.set('n', '<leader>mgrr', ':Mdn wikilink show_references<CR>', { buffer = true, desc = "Show references of link or buffer" })
vim.keymap.set('n', '<leader>mgrn', ':Mdn wikilink rename_references<CR>', { buffer = true, desc = "Rename references of link or current buffer" })
vim.keymap.set({"v", "n"}, "<leader>mk", ":Mdn inline_link toggle<CR>", { buffer = true, desc = "Toggle inline link" })
vim.keymap.set("n", "<leader>mh", ":Mdn history go_back<CR>", { buffer = true, desc = "Go to back to previously visited Markdown buffer" })
vim.keymap.set("n", "<leader>ml", ":Mdn history go_forward<CR>", { buffer = true, desc = "Go to next visited Markdown buffer" })
vim.keymap.set({"v", "n"}, "<leader>mb", ":Mdn formatting strong_toggle<CR>", { buffer = true, desc = "Toggle strong formatting" })
vim.keymap.set({"v", "n"}, "<leader>mi", ":Mdn formatting emphasis_toggle<CR>", { buffer = true, desc = "Toggle emphasis formatting" })
vim.keymap.set({"v", "n"}, "<leader>mt", ":Mdn formatting task_list_toggle<CR>", { buffer = true, desc = "Toggle task list status" })
vim.keymap.set("n", "<leader>mp", ":Mdn heading previous<CR>", { buffer = true, desc = "Go to previous Markdown heading" })
vim.keymap.set("n", "<leader>mn", ":Mdn heading next<CR>", { buffer = true, desc = "Go to next Markdown heading" })
👩💻 Optional Settings
Place these settings in your <Neovim config path>/after/ftplugin/markdown.lua file so that they are Markdown-specific. First one here is to enable wrapping only for the current Markdown buffer.
vim.wo[vim.api.nvim_get_current_win()][0].wrap = true -- Enable wrap for current .md buffer
Second one is to disable LSP diagnostics in the current Markdown buffer.
vim.diagnostic.enable(false, { bufnr = 0 }) -- Disable diagnostics for current .md buffer
Last one here is for the glorious Neovim Windows users. Setting this keymap will allow you to use the built in <C-x> <C-f> file completion for WikiLinks or just for using file paths in Markdown buffers.
vim.keymap.set("i", "<C-x><C-f>", "<cmd>set isfname-=[,]<CR><C-x><C-f><cmd>set isfname+=[,]<CR>",
{
desc = "Mdnotes i_CTRL-X_CTRL-F smart remap to allow path completion on Windows",
buffer = true
})
🫂 Motivation
I wanted to make a more Neovim-centric Markdown notes plugin that tries to work the available Markdown LSPs, is command/subcommand focused, concise, adheres to the CommonMark and GFM specs, while also providing the more widespread WikiLink support other note-taking apps provide. I hope I did in fact accomplish this (and more) for you as well as for me, and if I have not then please create an issue or contribute! Thanks for reading this :).
🫰 Other Cool Markdown-related Plugins
- obsidian.nvim
- markdown-plus.nvim
- mkdnflow.nvim
- markdown.nvim
- neowiki.nvim
- vim-markdown-toc
- vim-table-mode
Tests
Using mini.test for testing. For this project, if you want to run the tests then you need to install mini.test as a plugin locally. This was done to minimise dependencies in the repo. If you're not using lazy then you need to specify the mini.test location, using the mini_path variable in scripts/minimal_init.lua. To run the tests execute the following command in the project root,
nvim --headless --noplugin -u ./scripts/minimal_init.lua -c "lua MiniTest.run()"