mkdn.nvim is markdown toolkit for neovim. It utilize LSP, telescope/ripgrep and universal-ctags to provide a better markdown editing experience.
-
Paste URL
-
Paste from clipboard and convert to markdown link, e.g. paste url
https://github.com/
will insert[GitHub: Let’s build from here · GitHub](https://github.com/)
to your markdown file -
If the URL is a image URL, it will download the image locally and insert
![image](url)
to your markdown file
-
Note
requires curl
- Follow URL
A keybinding to open url in browser; if it is a local file, it will open in neovim, The feature utilize LSP to open wiki link in neovim
URL | Action |
---|---|
[sample.md file](sample.md) |
open sample.md in neovim |
![image](./assets/sample.png) |
open sample.png with open |
[mkdn](http://github.com/ray-x/mkdn.nvim) |
open URL github.com/ray-x/mkdn.nvim with browser |
[[sample]] | open wiki link file sample.md in neovim with LSP |
[[sample#Sample Heading]] | open sample.md in neovim and jump to Sample Heading with LSP |
[[sample#^37066d]] | open sample.md and jump to block ^37066d with LSP |
Note
To open wiki link in neovim, you need config a markdown LSP, e.g. marksman or markdown-oxide, also please check the LSP documentation for the supported URL format
- Find in frontmatter
Suppose you have a note with the following frontmatter
---
tags:
- tag1
- tag2
type: note
title: "Note Title"
You can list all notes with tag1 and tag2
require('mkdn').list_files({filter = {tags = {'tag1', 'tag2'}, type = 'note'}})
Or
MkdnFiles tags=tag1,tag2 type=note
User case: list all notes with tag python
and ML
require('mkdn').grep_files({filter={tags = {'tag1', 'tag2'}, type = 'daily'}})
Or
MkdnGrep tags=tag1,tag2 type=daily
User case: search all notes with tag python
and ML
and do a live grep for scipy
It searches
- tags in frontmatter
- page references in markdown
- wiki links in markdown
require('mkdn').grep_tag({default_text = 'tag1'})
Or
MkdnTag tag1
A simple task livecircle management with markdown
Command | Description |
---|---|
GtdStartTask | start a new task |
GtdPauseTask | pause a task |
GtdResumeTask | resume a task |
GtdFinishTask | finish a task |
Usage: suppose you have a task
- [ ] sample task 1
Put cursor on the task and run GtdStartTask
, it will change the task to
[>] sample task1
due:
time:
- [08:29]
total:
Then 'GtdPauseTask' to pause the task, it will change the task to
[|] sample task1
due:
time:
- [08:29, 08:40]
total: 11 mins
Then 'GtdResumeTask' to resume the task, it will change the task to
[>] sample task1
time:
- [08:29, 08:40]
- [08:45]
total: 11 mins
Then 'GtdFinishTask' to finish the task, it will change the task to
[x] sample task1
time:
- [08:29, 08:40]
- [08:45, 08:50]
total: 16 mins
make sure treesitter markdown parser is installed
set foldexpr to treesitter
It is already implemented in lsp. But a Cmdline command is provided to open the table of content
MkdnToc
open table of content in quickfix MkdnTocTelescope
open table of content in Telescope
You can also use navigator.lua LspSymbol to navigate the table of content
require('mkdn').setup{
follow_link = 'gx', -- keymap to follow link set to false to disable
paste_link = '<leader>u', -- keymap to fetch and paste url title
templates = {
-- see below: templates setup
},
notes_root = '~/notes', -- default note root
assets_path = 'assets', -- default assets path to store images, a subfolder of notes_root
author = os.getenv('USER'), -- default author
}
universal-ctags is capable to parse markdown, frontmatter, fenced languages
The ablitity to generate tags from fenced languages is useful for code block navigation
copy the files in .ctags.d to your note directory and setup nvim to run ctags -R
on save in your note directory when
you saved/commit your notes
You can use Telescope or navigator.lua to navigate the tags
The plugin allow you to capture your ideas quickly with a template
command | description |
---|---|
MkdnNew {subfolder/name} |
create a new note with frontmatter |
MkdnDaily {name} |
create a new daily note with frontmatter |
MkdnCapture |
create note from your selected template |
MkdnListNotes |
list all notes in notes_root |
Note
MkdnNew note_name
creates a new note name.md in note_path, MkdnNew subfolder/name
creates a new note
name.md in subfolder of notes_root. Default notes_root is ~/notes
. If name is not provided, it will prompt for a
note name or default to a hash string A template name can be provided as the first argument, e.g.
MkdnNew template_name note_name
Capture allows you to create a note without interrupting your workflow. You can define a template for your notes. The default template is defined in config.lua
{
templates = {
_meta = { -- meta data for templates
-- some default value for templates e.g. {{author}}
author = os.getenv('USER'), -- replace {{author}}
date = os.date('%Y-%m-%d'), -- replace {{date}} in template
},
daily = { -- `daily` note template
name = function() -- default name for daily note
return os.date('%Y-%m-%d')
end, -- or a function that returns the name
path = '[journal](journal.md)', -- default path for daily note inside notes_root
content = { -- content of daily note
function() -- content can be a function return a string or a table
return frontmatter({ tags = 'daily', category = 'daily' })
end, -- frontmatter generates frontmatter
'# {{name}}', -- content item can be a string with meta data
'\n', -- extra empty line
'## Tasks',
'- [ ] Task 1',
},
},
default = {
path = '',
name = function()
-- default name with random number in hex
vim.ui.input({
prompt = 'Note name: ',
default = 'default_' .. string.format('%x', math.random(16, 1000000)):sub(1, 4),
}, function(result)
return result
end)
end, -- or a function that returns the name
content = {
function()
return frontmatter({ category = 'note' })
end,
'# {{name}}',
},
},
}
There are good resources and setups for markdown note taking, here are some of them