- 🚀 Introduction
- ✨ Features
- 💾 Installation
- ⚙️ Configuration
- 🛠️ Commands & mappings
- 📚 API
- 🤝 Contributing
- 🔢 Version information
- 🔗 Related projects
Mkdnflow is designed for the fluent navigation and management of markdown documents and document collections (notebooks, wikis, etc). It features numerous convenience functions that make it easier to work within raw markdown documents or document collections: link and reference handling (🔗 Link and reference handling), navigation (🧭 Navigation), table support (📊 Table support), list (📝 List support) and to-do list (✅ To-do list support) support, file management (📁 File management), section folding (🪗 Folding), and more. Use it for notetaking, personal knowledge management, static website building, and more. Most features are highly tweakable (⚙️ Configuration).
- Jump to links
- Jump to section headings
- Link following
- Open markdown and other text filetypes in the current window
- Open other filetypes and URLs with your system's default application
- Browser-like 'Back' and 'Forward' functionality
- Table of contents window
- Link creation from a visual selection or the word under the cursor
- Link destruction
- Follow links to local paths and other Markdown files
- Follow external links (open using default application)
- Follow
.bib-based references- Open
urlordoifield in the default browser - Open documents specified in
filefield
- Open
- Implicit filetype extensions
- Support for various link types
- Standard Markdown links (
[my page](my_page.md)) - Wiki links (direct
[[my page]]or piped[[my_page.md|my page]]) - Automatic links (
<https://my.page>) - Reference-style links (
[my page][1]with[1]: my_page.md)
- Standard Markdown links (
- Table creation
- Table extension (add rows and columns)
- Table formatting
- Paste delimited data as a table
- Import delimited file into a new table
- Automatic list extension
- Sensible auto-indentation and auto-dedentation
- Ordered list number updating
- Toggle to-do item status
- Status propagation
- To-do list sorting
- Create to-do items from plain ordered or unordered list items
- Customizable highlighting for to-do status markers and content
- Simultaneous link and file renaming
- As-needed directory creation
- Section folding and fold toggling
- Helpful indicators for folded section contents
- Section heading level
- Counts of Markdown objects (tables, lists, code blocks, etc.)
- Line and word counts
- YAML block folding
- Path completion
- Completion of bibliography items
- Specify a bibliography file in YAML front matter
- Conceal markdown and wiki link syntax
- Extended link highlighting
- Automatic links
- Wiki links
Requirements:
- Linux, macOS, or Windows
- Neovim >= 0.10.0 (older versions may work, but the plugin is only tested on Neovim 0.10.x)
Install Mkdnflow using your preferred package manager for Neovim. Once installed, Mkdnflow is configured and initialized using a setup function.
Install with Lazy
require('lazy').setup({
-- Your other plugins
{
'jakewvincent/mkdnflow.nvim',
config = function()
require('mkdnflow').setup({
-- Your config
})
end
}
-- Your other plugins
})Install with Vim-Plug
" Vim-Plug
Plug 'jakewvincent/mkdnflow.nvim'
" Include the setup function somewhere else in your init.vim file, or the
" plugin won't activate itself:
lua << EOF
require('mkdnflow').setup({
-- Config goes here; leave blank for defaults
})
EOFMkdnflow is configured and initialized using a setup function. To use the default settings, pass no arguments or an empty table to the setup function:
{
'jakewvincent/mkdnflow.nvim',
config = function()
require('mkdnflow').setup({})
end
}Most features are highly configurable. Study the default config first and read the documentation for the configuration options below or in the help files.
🔧 Complete default config
{
modules = {
bib = true,
buffers = true,
conceal = true,
cursor = true,
folds = true,
foldtext = true,
links = true,
lists = true,
maps = true,
paths = true,
tables = true,
to_do = true,
yaml = false,
cmp = false,
},
create_dirs = true,
silent = false,
wrap = false,
perspective = {
priority = 'first',
fallback = 'current',
root_tell = false,
nvim_wd_heel = false,
update = true,
},
filetypes = {
md = true,
rmd = true,
markdown = true,
},
foldtext = {
object_count = true,
object_count_icon_set = 'emoji',
object_count_opts = function()
return require('mkdnflow').foldtext.default_count_opts
end,
line_count = true,
line_percentage = true,
word_count = false,
title_transformer = function()
return require('mkdnflow').foldtext.default_title_transformer
end,
fill_chars = {
left_edge = '⢾⣿⣿',
right_edge = '⣿⣿⡷',
item_separator = ' · ',
section_separator = ' ⣹⣿⣏ ',
left_inside = ' ⣹',
right_inside = '⣏ ',
middle = '⣿',
},
},
bib = {
default_path = nil,
find_in_root = true,
},
cursor = {
jump_patterns = nil,
},
links = {
style = 'markdown',
name_is_source = false,
conceal = false,
context = 0,
implicit_extension = nil,
transform_implicit = false,
transform_explicit = function(text)
text = text:gsub('[ /]', '-')
text = text:lower()
text = os.date('%Y-%m-%d_') .. text
return text
end,
create_on_follow_failure = true,
},
new_file_template = {
use_template = false,
placeholders = {
before = {
title = 'link_title',
date = 'os_date',
},
after = {},
},
template = '# {{ title }}',
},
to_do = {
highlight = false,
statuses = {
{
name = 'not_started',
symbol = ' ',
colors = {
marker = { link = 'Conceal' },
content = { link = 'Conceal' },
},
sort = { section = 2, position = 'top' },
exclude_from_rotation = false,
propagate = {
up = function(host_list) ... end,
down = function(child_list) ... end,
},
},
{
name = 'in_progress',
symbol = '-',
colors = {
marker = { link = 'WarningMsg' },
content = { bold = true },
},
sort = { section = 1, position = 'bottom' },
exclude_from_rotation = false,
propagate = {
up = function(host_list) ... end,
down = function(child_list) end,
},
},
{
name = 'complete',
symbol = { 'X', 'x' },
colors = {
marker = { link = 'String' },
content = { link = 'Conceal' },
},
sort = { section = 3, position = 'top' },
exclude_from_rotation = false,
propagate = {
up = function(host_list) ... end,
down = function(child_list) ... end,
},
},
},
status_propagation = {
up = true,
down = true,
},
sort = {
on_status_change = false,
recursive = false,
cursor_behavior = {
track = true,
},
},
},
tables = {
trim_whitespace = true,
format_on_move = true,
auto_extend_rows = false,
auto_extend_cols = false,
style = {
cell_padding = 1,
separator_padding = 1,
outer_pipes = true,
mimic_alignment = true,
},
},
yaml = {
bib = { override = false },
},
mappings = {
MkdnEnter = { { 'n', 'v' }, '<CR>' },
MkdnGoBack = { 'n', '<BS>' },
MkdnGoForward = { 'n', '<Del>' },
MkdnMoveSource = { 'n', '<F2>' },
MkdnNextLink = { 'n', '<Tab>' },
MkdnPrevLink = { 'n', '<S-Tab>' },
MkdnFollowLink = false,
MkdnDestroyLink = { 'n', '<M-CR>' },
MkdnTagSpan = { 'v', '<M-CR>' },
MkdnYankAnchorLink = { 'n', 'yaa' },
MkdnYankFileAnchorLink = { 'n', 'yfa' },
MkdnNextHeading = { 'n', ']]' },
MkdnPrevHeading = { 'n', '[[' },
MkdnIncreaseHeading = { 'n', '+' },
MkdnDecreaseHeading = { 'n', '-' },
MkdnToggleToDo = { { 'n', 'v' }, '<C-Space>' },
MkdnNewListItem = false,
MkdnNewListItemBelowInsert = { 'n', 'o' },
MkdnNewListItemAboveInsert = { 'n', 'O' },
MkdnExtendList = false,
MkdnUpdateNumbering = { 'n', '<leader>nn' },
MkdnTableNextCell = { 'i', '<Tab>' },
MkdnTablePrevCell = { 'i', '<S-Tab>' },
MkdnTableNextRow = false,
MkdnTablePrevRow = { 'i', '<M-CR>' },
MkdnTableNewRowBelow = { 'n', '<leader>ir' },
MkdnTableNewRowAbove = { 'n', '<leader>iR' },
MkdnTableNewColAfter = { 'n', '<leader>ic' },
MkdnTableNewColBefore = { 'n', '<leader>iC' },
MkdnFoldSection = { 'n', '<leader>f' },
MkdnUnfoldSection = { 'n', '<leader>F' },
MkdnTab = false,
MkdnSTab = false,
MkdnCreateLink = false,
MkdnCreateLinkFromClipboard = { { 'n', 'v' }, '<leader>p' },
},
}require('mkdnflow').setup({
modules = {
bib = true,
buffers = true,
conceal = true,
cursor = true,
folds = true,
foldtext = true,
links = true,
lists = true,
maps = true,
paths = true,
tables = true,
to_do = true,
yaml = false,
cmp = false,
}
})| Option | Type | Description |
|---|---|---|
modules.bib |
boolean |
true (default): bib module is enabled (required for parsing .bib files and following citations).false: Disable bib module functionality. |
modules.buffers |
boolean |
true (default): buffers module is enabled (required for backward and forward navigation through buffers).false: Disable buffers module functionality. |
modules.conceal |
boolean |
true (default): conceal module is enabled (required if you wish to enable link concealing. This does not automatically enable conceal behavior; see links.conceal.)false: Disable conceal module functionality. |
modules.cursor |
boolean |
true (default): cursor module is enabled (required for cursor movements: jumping to links, headings, etc.).false: Disable cursor module functionality. |
modules.folds |
boolean |
true (default): folds module is enabled (required for section folding).false: Disable folds module functionality. |
modules.foldtext |
boolean |
true (default): foldtext module is enabled (required for prettified foldtext).false: Disable foldtext module functionality. |
modules.links |
boolean |
true (default): links module is enabled (required for creating, destroying, and following links).false: Disable links module functionality. |
modules.lists |
boolean |
true (default): lists module is enabled (required for working in and manipulating lists, etc.).false: Disable lists module functionality. |
modules.to_do |
boolean |
true (default): to_do module is enabled (required for manipulating to-do statuses/lists, toggling to-do items, to-do list sorting, etc.)false: Disable to_do module functionality. |
modules.paths |
boolean |
true (default): paths module is enabled (required for link interpretation, link following, etc.).false: Disable paths module functionality. |
modules.tables |
boolean |
true (default): tables module is enabled (required for table management, navigation, formatting, etc.).false: Disable tables module functionality. |
modules.yaml |
boolean |
true: yaml module is enabled (required for parsing yaml headers).false (default): Disable yaml module functionality. |
modules.cmp |
boolean |
true: cmp module is enabled (required if you wish to enable completion for nvim-cmp).false (default): Disable cmp module functionality. |
require('mkdnflow').setup({
create_dirs = true,
})| Option | Type | Description |
|---|---|---|
create_dirs |
boolean |
true (default): Directories referenced in a link will be (recursively) created if they do not exist.false: No action will be taken when directories referenced in a link do not exist. Neovim will open a new file, but you will get an error when you attempt to write the file. |
require('mkdnflow').setup({
perspective = {
priority = 'first',
fallback = 'current',
root_tell = false,
nvim_wd_heel = false,
update = false,
},
})| Option | Type | Description |
|---|---|---|
perspective.priority |
string |
'first' (default): Links will be interpreted relative to the first-opened file (when the current instance of Neovim was started).'current': Links will always be interpreted relative to the current file.'root': Links will be always interpreted relative to the root directory of the current notebook (requires perspective.root_tell to be specified). |
perspective.fallback |
string |
'first': (see above)'current' (default): (see above)'root': (see above) |
perspective.root_tell |
string | boolean |
false (default): The plugin does not look for the notebook root.string: The name of a file (not a full path) by which a notebook's root directory can be identified. For instance, '.root' or 'index.md'. |
perspective.nvim_wd_heel |
boolean |
true: Changes in perspective will be reflected in the nvim working directory. (In other words, the working directory will "heel" to the plugin's perspective.) This helps ensure (at least) that path completions (if using a completion plugin with support for paths) will be accurate and usable.false (default): Neovim's working directory will not be affected by Mkdnflow. |
perspective.update |
boolean |
true: Perspective will be updated when following a link to a file in a separate notebook/wiki (or navigating backwards to a file in another notebook/wiki).false (default): Perspective will be not updated when following a link to a file in a separate notebook/wiki. (Links in the file in the separate notebook/wiki will be interpreted relative to the original notebook/wiki.) |
require('mkdnflow').setup({
filetypes = {
md = true,
rmd = true,
markdown = true,
},
})| Option | Type | Description |
|---|---|---|
filetypes.md |
boolean |
true (default): The plugin activates for files with a .md extension.false: The plugin does not activate for files with a .md extension. |
filetypes.rmd |
boolean |
true (default): The plugin activates for files with a .rmd (rmarkdown) extension.false: The plugin does not activate for files with a .rmd extension. |
filetypes.markdown |
boolean |
true (default): The plugin activates for files with a .markdown extension.false: The plugin does not activate for files with a .markdown extension. |
filetypes.<ext> |
boolean |
true: The plugin activates for files with the specified extension.false: The plugin does not activate for files with the specified extension. |
Note
This functionality references the file's extension. It does not rely on
Neovim's filetype recognition. The extension must be provided in lower case
because the plugin converts file names to lowercase. Any arbitrary extension
can be supplied. Setting an extension to false is the same as not including
it in the list.
require('mkdnflow').setup({
wrap = false,
})| Option | Type | Description |
|---|---|---|
wrap |
boolean |
true: When jumping to next/previous links or headings, the cursor will continue searching at the beginning/end of the file.false (default): When jumping to next/previous links or headings, the cursor will stop searching at the end/beginning of the file. |
require('mkdnflow').setup({
bib = {
default_path = nil,
find_in_root = true,
},
})| Option | Type | Description |
|---|---|---|
bib.default_path |
string | nil |
nil (default): No default/fallback bib file will be used to search for citation keys.string: A path to a default .bib file to look for citation keys in when attempting to follow a reference. The path need not be in the root directory of the notebook. |
bib.find_in_root |
boolean |
true (default): When perspective.priority is also set to root (and a root directory was found), the plugin will search for bib files to reference in the notebook's top-level directory. If bib.default_path is also specified, the default path will be added to the list of bib files found in the top-level directory so that it will also be searched.false: The notebook's root directory will not be searched for bib files. |
require('mkdnflow').setup({
silent = false,
})| Option | Type | Description |
|---|---|---|
silent |
boolean |
true: The plugin will not display any messages in the console except compatibility warnings related to your config.false (default): The plugin will display messages to the console. |
require('mkdnflow').setup({
cursor = {
jump_patterns = nil,
},
})| Option | Type | Description |
|---|---|---|
cursor.jump_patterns |
table | nil |
nil (default): The default jump patterns for the configured link style are used (markdown-style links by default).table: A table of custom Lua regex patterns.{} (empty table): Disable link jumping without disabling the cursor module. |
require('mkdnflow').setup({
links = {
style = 'markdown',
name_is_source = false,
conceal = false,
context = 0,
implicit_extension = nil,
transform_implicit = false,
transform_explicit = function(text)
text = text:gsub(" ", "-")
text = text:lower()
text = os.date('%Y-%m-%d_') .. text
return(text)
end,
create_on_follow_failure = true,
},
})| Option | Type | Description |
|---|---|---|
links.style |
string |
'markdown' (default): Links will be expected in the standard markdown format: [<title>](<source>)'wiki': Links will be expected in the unofficial wiki-link style, specifically the title-after-pipe format: [[<source>|<title>]]. |
links.name_is_source |
boolean |
true: Wiki-style links will be created with the source and name being the same (e.g. [[Link]] will display as "Link" and go to a file named "Link.md").false (default): Wiki-style links will be created with separate name and source (e.g. [[link-to-source|Link]] will display as "Link" and go to a file named "link-to-source.md"). |
links.conceal |
boolean |
true: Link sources and delimiters will be concealed (depending on which link style is selected).false (default): Link sources and delimiters will not be concealed by mkdnflow. |
links.context |
integer |
When following or jumping to links, consider n lines before and after a given line (useful if you ever permit links to be interrupted by a hard line break). Default: 0. |
links.implicit_extension |
string |
A string that instructs the plugin (a) how to interpret links to files that do not have an extension, and (b) how to create new links from the word under cursor or text selection.nil (default): Extensions will be explicit when a link is created and must be explicit in any notebook link.'<any extension>' (e.g. 'md'): Links without an extension (e.g. [Homepage](index)) will be interpreted with the implicit extension (e.g. index.md), and new links will be created without an extension. |
links.transform_explicit |
fun(string): string | boolean |
false: No transformations are applied to the text to be turned into the name of the link source/path.fun(string): string (default): A function that transforms the text to be inserted as the source/path of a link when a link is created. Anchor links are not currently customizable. For an example, see the sample recipes beneath this table. |
links.transform_implicit |
fun(string): string | boolean |
false (default): Do not perform any implicit transformations on the link's source.fun(string): string: A function that transforms the path of a link immediately before interpretation. It does not transform the actual text in the buffer but can be used to modify link interpretation. For an example, see the sample recipe below. |
links.create_on_follow_failure |
boolean |
true (default): Try to create a link from the word under the cursor if there is no link under the cursor to follow.false: Do nothing if trying to follow a link and a link can't be found under the cursor. |
Sample links recipes
require('mkdnflow').setup({
links = {
-- If you want all link paths to be explicitly prefixed with the year
-- and for the path to be converted to uppercase:
transform_explicit = function(input)
return(string.upper(os.date('%Y-')..input))
end,
-- Link paths that match a date pattern can be opened in a `journals`
-- subdirectory of your notebook, and all others can be opened in a
-- `pages` subdirectory:
transform_implicit = function(input)
if input:match('%d%d%d%d%-%d%d%-%d%d') then
return('journals/'..input)
else
return('pages/'..input)
end
end
}
})require('mkdnflow').setup({
new_file_template = {
use_template = false,
placeholders = {
before = { title = 'link_title', date = 'os_date' },
after = {},
},
template = '# {{ title }}',
},
})| Option | Type | Description |
|---|---|---|
new_file_template.use_template |
boolean |
true: Use the new-file template when opening a new file by following a link.false (default): Don't use the new-file template when opening a new file by following a link. |
new_file_template.placeholders.before |
table<string, string|fun(): string> |
A table whose keys are placeholder names mapped either to a function (to be evaluated immediately before the buffer is opened in the current window) or to one of a limited set of recognized strings:'link_title': The title of the link that was followed to get to the just-opened file.'os_date': The current date, according to the OS.Default: { title = 'link_title', date = 'os_date' } |
new_file_template.placeholders.after |
table<string, string|fun(): string> |
A table whose keys are placeholder names mapped either to a function (to be evaluated immediately after the buffer is opened in the current window) or to one of a limited set of recognized strings (see above). Default: {} |
new_file_template.template |
string |
A string, optionally containing placeholder names, that will be inserted into a new file. Default: '# {{ title }}' |
require('mkdnflow').setup({
to_do = {
highlight = false,
status_propagation = { up = true, down = true },
sort = {
on_status_change = false,
recursive = false,
cursor_behavior = { track = true },
},
statuses = { ... }, -- See full default in docs
},
})| Option | Type | Description |
|---|---|---|
to_do.highlight |
boolean |
true: Apply highlighting to to-do status markers and/or content (as defined in to_do.statuses[*].highlight).false (default): Do not apply any highlighting. |
to_do.status_propagation.up |
boolean |
true (default): Update ancestor statuses (recursively) when a descendant status is changed. Updated according to logic provided in to_do.statuses[*].propagate.up.false: Ancestor statuses are not affected by descendant status changes. |
to_do.status_propagation.down |
boolean |
true (default): Update descendant statuses (recursively) when an ancestor's status is changed. Updated according to logic provided in to_do.statuses[*].propagate.down.false: Descendant statuses are not affected by ancestor status changes. |
to_do.sort_on_status_change |
boolean |
true: Sort a to-do list when an item's status is changed.false (default): Leave all to-do items in their current position when an item's status is changed.Note: This will not apply if the to-do item's status is changed manually (i.e. by typing or pasting in the status marker). |
to_do.sort.recursive |
boolean |
true: sort_on_status_change applies recursively, sorting the host list of each successive parent until the root of the list is reached.false (default): sort_on_status_change only applies at the current to-do list level (not to the host list of the parent to-do item). |
to_do.sort.cursor_behavior.track |
boolean |
true (default): Move the cursor so that it remains on the same to-do item, even after a to-do list sort relocates the item.false: The cursor remains on its current line number, even if the to-do item is relocated by sorting. |
to_do.statuses |
table (array-like) |
A list of tables, each of which represents a to-do status. See options in the following rows. An arbitrary number of to-do status tables can be provided. See default statuses in the settings table. |
to_do.statuses[*].name |
string |
The designated name of the to-do status. |
to_do.statuses[*].marker |
string | table |
The marker symbol to use for the status. The marker's string width must be 1. |
to_do.statuses[*].highlight.marker |
table (highlight definition) |
A table of highlight definitions to apply to a status marker, including brackets. See the {val} parameter of :h nvim_set_hl for possible options. |
to_do.statuses[*].highlight.content |
table (highlight definition) |
A table of highlight definitions to apply to the to-do item content (everything following the status marker). See the {val} parameter of :h nvim_set_hl for possible options. |
to_do.statuses[*].exclude_from_rotation |
boolean |
true: When toggling/rotating a to-do item's status, exclude the current symbol from the list of symbols used.false: Leave the symbol in the rotation.Note: This setting is useful if there is a status marker that you never want to manually set and only want to apply when automatically updating ancestors or descendants. |
to_do.statuses[*].sort.section |
integer |
The integer should represent the linear section of the list in which items of this status should be placed when sorted. A section refers to a segment of a to-do list. If you want items with the 'in_progress' status to be first in the list, you would set this option to 1 for the status.Note: Sections are not visually delineated in any way other than items with the same section number occurring on adjacent lines in the list. |
to_do.statuses[*].sort.position |
string |
Where in its assigned section a to-do item should be placed:'top': Place a sorted item at the top of its corresponding section.'bottom': Place a sorted item at the bottom of its corresponding section.'relative': Maintain the current relative order of the sorted item whose status was just changed (vs. other list items). |
to_do.statuses[*].propagate.up |
fun(to_do_list): string | nil |
A function that accepts a to-do list instance and returns a valid to-do status name. The list passed in is the list that hosts the to-do item whose status was just changed. The return value should be the desired value of the parent. Return nil to leave the parent's status as is. |
to_do.statuses[*].propagate.down |
fun(to_do_list): string[] |
A function that accepts a to-do list instance and returns a list of valid to-do status names. The list passed in will be the child list of the to-do item whose status was just changed. Return nil or an empty table to leave the children's status as is. |
Warning
The following to-do configuration options are deprecated. Please use the
to_do.statuses table instead. Continued support for these options is
temporarily provided by a compatibility layer that will be removed in the
near future.
to_do.symbols- A list of markers representing to-do completion statusesto_do.not_started- Which marker represents a not-yet-started to-doto_do.in_progress- Which marker represents an in-progress to-doto_do.complete- Which marker represents a complete to-doto_do.update_parents- Whether parent to-dos' statuses should be updated
require('mkdnflow').setup({
foldtext = {
object_count = true,
object_count_icon_set = 'emoji',
object_count_opts = function()
return require('mkdnflow').foldtext.default_count_opts
end,
line_count = true,
line_percentage = true,
word_count = false,
title_transformer = function()
return require('mkdnflow').foldtext.default_title_transformer
end,
fill_chars = {
left_edge = '⢾⣿⣿',
right_edge = '⣿⣿⡷',
item_separator = ' · ',
section_separator = ' ⣹⣿⣏ ',
left_inside = ' ⣹',
right_inside = '⣏ ',
middle = '⣿',
},
},
})| Option | Type | Description |
|---|---|---|
foldtext.object_count |
boolean |
true (default): Show a count of all objects inside of a folded section.false: Do not show a count of any objects inside of a folded section. |
foldtext.object_count_icon_set |
string | table |
'emoji' (default): Use pre-defined emojis as icons for counted objects.'plain': Use pre-defined plaintext UTF-8 characters as icons for counted objects.'nerdfont': Use pre-defined nerdfont characters as icons for counted objects. Requires a nerdfont.table<string, string>: Use custom mapping of object names to icons. |
foldtext.object_count_opts |
fun(): table<string, table> |
A function that returns the options table defining the final attributes of the objects to be counted, including icons and counting methods. The pre-defined object types are tbl, ul, ol, todo, img, fncblk, sec, par, and link. |
foldtext.line_count |
boolean |
true (default): Show a count of the lines contained in the folded section.false: Don't show a line count. |
foldtext.line_percentage |
boolean |
true (default): Show the percentage of document (buffer) lines contained in the folded section.false: Don't show the percentage. |
foldtext.word_count |
boolean |
true: Show a count of the paragraph words in the folded section, ignoring words inside of other objects.false (default): Don't show a word count. |
foldtext.title_transformer |
fun(): fun(string): string |
A function that returns another function. The inner function accepts a string (the section heading text) and returns a potentially modified string. |
foldtext.fill_chars.left_edge |
string |
The character(s) to use at the very left edge of the foldtext. Default: '⢾⣿⣿'. |
foldtext.fill_chars.right_edge |
string |
The character(s) to use at the very right edge of the foldtext. Default: '⣿⣿⡷' |
foldtext.fill_chars.item_separator |
string |
The character(s) used to separate the items within a section. Default: ' · ' |
foldtext.fill_chars.section_separator |
string |
The character(s) used to separate adjacent sections. Default: ' ⣹⣿⣏ ' |
foldtext.fill_chars.left_inside |
string |
The character(s) used at the internal left edge of fill characters. Default: ' ⣹' |
foldtext.fill_chars.right_inside |
string |
The character(s) used at the internal right edge of fill characters. Default: '⣏ ' |
foldtext.fill_chars.middle |
string |
The character used to fill empty space in the foldtext line. Default: '⣿' |
Sample foldtext recipes
-- SAMPLE FOLDTEXT CONFIGURATION RECIPE WITH COMMENTS
require('mkdnflow').setup({
foldtext = {
title_transformer = function()
local function my_title_transformer(text)
local updated_title = text:gsub('%b{}', '')
updated_title = updated_title:gsub('^%s*', '')
updated_title = updated_title:gsub('%s*$', '')
updated_title = updated_title:gsub('^######', '░░░░░▓')
updated_title = updated_title:gsub('^#####', '░░░░▓▓')
updated_title = updated_title:gsub('^####', '░░░▓▓▓')
updated_title = updated_title:gsub('^###', '░░▓▓▓▓')
updated_title = updated_title:gsub('^##', '░▓▓▓▓▓')
updated_title = updated_title:gsub('^#', '▓▓▓▓▓▓')
return updated_title
end
return my_title_transformer
end,
object_count_icon_set = 'nerdfont',
object_count_opts = function()
local opts = {
link = false,
blockquote = {
icon = ' ',
count_method = {
pattern = { '^>.+$' },
tally = 'blocks',
}
},
fncblk = { icon = ' ' }
}
return opts
end,
line_count = false,
word_count = true,
fill_chars = {
left_edge = '╾─🖿 ─',
right_edge = '──╼',
item_separator = ' · ',
section_separator = ' // ',
left_inside = ' ┝',
right_inside = '┥ ',
middle = '─',
},
},
})The above recipe will produce foldtext like the following
(for an h3-level section heading called My section):
require('mkdnflow').setup({
tables = {
trim_whitespace = true,
format_on_move = true,
auto_extend_rows = false,
auto_extend_cols = false,
style = {
cell_padding = 1,
separator_padding = 1,
outer_pipes = true,
mimic_alignment = true,
},
},
})| Option | Type | Description |
|---|---|---|
tables.trim_whitespace |
boolean |
true (default): Trim extra whitespace from the end of a table cell when a table is formatted.false: Leave whitespace at the end of a table cell when formatting. |
tables.format_on_move |
boolean |
true (default): Format the table each time the cursor is moved to the next/previous cell/row using the plugin's API.false: Don't format the table when the cursor is moved. |
tables.auto_extend_rows |
boolean |
true: Add another row when attempting to jump to the next row and the row doesn't exist.false (default): Leave the table when attempting to jump to the next row and the row doesn't exist. |
tables.auto_extend_cols |
boolean |
true: Add another column when attempting to jump to the next column and the column doesn't exist.false (default): Go to the first cell of the next row when attempting to jump to the next column and the column doesn't exist. |
tables.style.cell_padding |
integer |
1 (default): Use one space as padding at the beginning and end of each cell.<n>: Use <n> spaces as cell padding. |
tables.style.separator_padding |
integer |
1 (default): Use one space as padding in the separator row.<n>: Use <n> spaces as padding in the separator row. |
tables.style.outer_pipes |
boolean |
true (default): Include outer pipes when formatting a table.false: Do not use outer pipes when formatting a table. |
tables.style.mimic_alignment |
boolean |
true (default): Mimic the cell alignment indicated in the separator row when formatting the table.false: Always visually left-align cell contents when formatting a table. |
require('mkdnflow').setup({
yaml = {
bib = { override = false },
},
})| Option | Type | Description |
|---|---|---|
yaml.bib.override |
boolean |
true: A bib path specified in a markdown file's yaml header should be the only source considered for bib references in that file.false (default): All known bib paths will be considered, whether specified in the yaml header or in your configuration settings. |
require('mkdnflow').setup({
mappings = {
MkdnEnter = { { 'n', 'v' }, '<CR>' },
MkdnGoBack = { 'n', '<BS>' },
MkdnGoForward = { 'n', '<Del>' },
MkdnMoveSource = { 'n', '<F2>' },
MkdnNextLink = { 'n', '<Tab>' },
MkdnPrevLink = { 'n', '<S-Tab>' },
MkdnFollowLink = false,
MkdnDestroyLink = { 'n', '<M-CR>' },
MkdnTagSpan = { 'v', '<M-CR>' },
MkdnYankAnchorLink = { 'n', 'yaa' },
MkdnYankFileAnchorLink = { 'n', 'yfa' },
MkdnNextHeading = { 'n', ']]' },
MkdnPrevHeading = { 'n', '[[' },
MkdnIncreaseHeading = { 'n', '+' },
MkdnDecreaseHeading = { 'n', '-' },
MkdnToggleToDo = { { 'n', 'v' }, '<C-Space>' },
MkdnNewListItem = false,
MkdnNewListItemBelowInsert = { 'n', 'o' },
MkdnNewListItemAboveInsert = { 'n', 'O' },
MkdnExtendList = false,
MkdnUpdateNumbering = { 'n', '<leader>nn' },
MkdnTableNextCell = { 'i', '<Tab>' },
MkdnTablePrevCell = { 'i', '<S-Tab>' },
MkdnTableNextRow = false,
MkdnTablePrevRow = { 'i', '<M-CR>' },
MkdnTableNewRowBelow = { 'n', '<leader>ir' },
MkdnTableNewRowAbove = { 'n', '<leader>iR' },
MkdnTableNewColAfter = { 'n', '<leader>ic' },
MkdnTableNewColBefore = { 'n', '<leader>iC' },
MkdnFoldSection = { 'n', '<leader>f' },
MkdnUnfoldSection = { 'n', '<leader>F' },
MkdnTab = false,
MkdnSTab = false,
MkdnCreateLink = false,
MkdnCreateLinkFromClipboard = { { 'n', 'v' }, '<leader>p' },
},
})See descriptions of commands and mappings below.
Note: <command> should be the name of a command defined in
mkdnflow.nvim/plugin/mkdnflow.lua (see :h Mkdnflow-commands for a list).
| Option | Type | Description |
|---|---|---|
mappings.<command> |
[string|string[], string] |
The first item is a string or an array of strings representing the mode(s) that the mapping should apply in ('n', 'v', etc.). The second item is a string representing the mapping (in the expected format for vim). |
To enable completion via cmp using the provided source, add mkdnflow as a
source in your cmp setup function. You may also want to modify the formatting
to see which completions are coming from Mkdnflow:
cmp.setup({
-- Add 'mkdnflow' as a completion source
sources = cmp.config.sources({
{ name = 'mkdnflow' },
}),
-- Completion source attribution
formatting = {
format = function(entry, vim_item)
vim_item.menu = ({
-- Other attributions
mkdnflow = '[Mkdnflow]',
})[entry.source_name]
return vim_item
end
}
})Warning
There may be some compatibility issues with the completion module and
links.transform_explicit/links.transform_implicit functions.
If you have some transform_explicit option for links to organizing in folders
then the folder name will be inserted accordingly. Some transformations may not
work as expected in completions.
To prevent this, make sure you write sensible transformation functions, preferably using it for folder organization.
Below are descriptions of the user commands defined by Mkdnflow. For the
default mappings to these commands, see the mappings = ... section of
Configuration options.
| Command | Default mapping | Description |
|---|---|---|
MkdnEnter |
-- | Triggers a wrapper function which will (a) infer your editor mode, and then if in normal or visual mode, either follow a link, create a new link from the word under the cursor or visual selection, or fold a section (if cursor is on a section heading); if in insert mode, it will create a new list item (if cursor is in a list), go to the next row in a table (if cursor is in a table), or behave normally (if cursor is not in a list or a table). Note: There is no insert-mode mapping for this command by default since some may find its effects intrusive. To enable the insert-mode functionality, add to the mappings table: MkdnEnter = {{'i', 'n', 'v'}, '<CR>'}. |
MkdnNextLink |
{ 'n', '<Tab>' } |
Move cursor to the beginning of the next link (if there is a next link). |
MkdnPrevLink |
{ 'n', '<S-Tab>' } |
Move the cursor to the beginning of the previous link (if there is one). |
MkdnNextHeading |
{ 'n', ']]' } |
Move the cursor to the beginning of the next heading (if there is one). |
MkdnPrevHeading |
{ 'n', '[[' } |
Move the cursor to the beginning of the previous heading (if there is one). |
MkdnGoBack |
{ 'n', '<BS>' } |
Open the historically last-active buffer in the current window. Note: The back-end function for :MkdnGoBack (require('mkdnflow').buffers.goBack()) returns a boolean indicating the success of goBack(). This may be useful if you wish to remap <BS> such that when goBack() is unsuccessful, another function is performed. |
MkdnGoForward |
{ 'n', '<Del>' } |
Open the buffer that was historically navigated away from in the current window. |
MkdnCreateLink |
-- | Create a link from the word under the cursor (in normal mode) or from the visual selection (in visual mode). |
MkdnCreateLinkFromClipboard |
{ { 'n', 'v' }, '<leader>p' } |
Create a link, using the content from the system clipboard (e.g. a URL) as the source and the word under cursor or visual selection as the link text. |
MkdnFollowLink |
-- | Open the link under the cursor, creating missing directories if desired, or if there is no link under the cursor, make a link from the word under the cursor. |
MkdnDestroyLink |
{ 'n', '<M-CR>' } |
Destroy the link under the cursor, replacing it with just the text from the link name. |
MkdnTagSpan |
{ 'v', '<M-CR>' } |
Tag a visually-selected span of text with an ID, allowing it to be linked to with an anchor link. |
MkdnMoveSource |
{ 'n', '<F2>' } |
Open a dialog where you can provide a new source for a link and the plugin will rename and move the associated file on the backend (and rename the link source). |
MkdnYankAnchorLink |
{ 'n', 'yaa' } |
Yank a formatted anchor link (if cursor is currently on a line with a heading). |
MkdnYankFileAnchorLink |
{ 'n', 'yfa' } |
Yank a formatted anchor link with the filename included before the anchor (if cursor is currently on a line with a heading). |
MkdnIncreaseHeading |
{ 'n', '+' } |
Increase heading importance (remove hashes). |
MkdnDecreaseHeading |
{ 'n', '-' } |
Decrease heading importance (add hashes). |
MkdnToggleToDo |
{ { 'n', 'v' }, '<C-Space>' } |
Toggle to-do list item's completion status or convert a list item into a to-do list item. |
MkdnUpdateNumbering |
{ 'n', '<leader>nn' } |
Update numbering for all siblings of the list item of the current line. |
MkdnNewListItem |
-- | Add a new ordered list item, unordered list item, or (uncompleted) to-do list item. |
MkdnNewListItemBelowInsert |
{ 'n', 'o' } |
Add a new list item below the current line and begin insert mode. Add a new line and enter insert mode when the cursor is not in a list. |
MkdnNewListItemAboveInsert |
{ 'n', 'O' } |
Add a new list item above the current line and begin insert mode. Add a new line and enter insert mode when the cursor is not in a list. |
MkdnExtendList |
-- | Like above, but the cursor stays on the current line (new list items of the same type are added below). |
MkdnTable ncol nrow (noh) |
-- | Make a table of ncol columns and nrow rows. Pass noh as a third argument to exclude table headers. |
MkdnTableFormat |
-- | Format a table under the cursor. |
MkdnTableNextCell |
{ 'i', '<Tab>' } |
Move the cursor to the beginning of the next cell in the table, jumping to the next row if needed. |
MkdnTablePrevCell |
{ 'i', '<S-Tab>' } |
Move the cursor to the beginning of the previous cell in the table, jumping to the previous row if needed. |
MkdnTableNextRow |
-- | Move the cursor to the beginning of the same cell in the next row of the table. |
MkdnTablePrevRow |
{ 'i', '<M-CR>' } |
Move the cursor to the beginning of the same cell in the previous row of the table. |
MkdnTableNewRowBelow |
{ 'n', '<leader>ir' } |
Add a new row below the row the cursor is currently in. |
MkdnTableNewRowAbove |
{ 'n', '<leader>iR' } |
Add a new row above the row the cursor is currently in. |
MkdnTableNewColAfter |
{ 'n', '<leader>ic' } |
Add a new column following the column the cursor is currently in. |
MkdnTableNewColBefore |
{ 'n', '<leader>iC' } |
Add a new column before the column the cursor is currently in. |
MkdnTab |
-- | Wrapper function which will jump to the next cell in a table (if cursor is in a table) or indent an (empty) list item (if cursor is in a list item). |
MkdnSTab |
-- | Wrapper function which will jump to the previous cell in a table (if cursor is in a table) or de-indent an (empty) list item (if cursor is in a list item). |
MkdnFoldSection |
{ 'n', '<leader>f' } |
Fold the section the cursor is currently on/in. |
MkdnUnfoldSection |
{ 'n', '<leader>F' } |
Unfold the folded section the cursor is currently on. |
Mkdnflow |
-- | Manually start Mkdnflow. |
Tip
If you are attempting to (re)map <CR> in insert mode but can't get it to
work, try inspecting your current insert mode mappings and seeing if anything
is overriding your mapping. Possible candidates are completion plugins and
auto-pair plugins.
If using nvim-cmp, consider using the mapping with a fallback.
If using an autopair plugin that automatically maps <CR> (e.g. nvim-autopairs),
see if it provides a way to disable its <CR> mapping.
Mkdnflow provides a range of Lua functions that can be called directly to manipulate markdown files, navigate through buffers, manage links, and more. Below are the primary functions available:
- Initialization (Initialization)
- Link management (Link management)
- Link & path handling (Link and path handling)
- Buffer navigation (Buffer navigation)
- Cursor movement (Cursor movement)
- Cursor-aware manipulations (Cursor-aware manipulations)
- List management (List management)
- To-do list management (To-do list management)
- Table management (Table management)
- Folds (Folds)
- Yaml blocks (Yaml blocks)
- Bibliography (Bibliography)
require('mkdnflow').setup(config)
Initializes the plugin with the provided configuration. See Advanced configuration and sample recipes. If called with an empty table, the default configuration is used.
- Parameters:
config: (table) Configuration table containing various settings such as filetypes, modules, mappings, and more.
require('mkdnflow').forceStart(opts)
Similar to setup, but forces the initialization of the plugin regardless of the current buffer's filetype.
- Parameters:
opts: (table) Table of options.opts[1]: (boolean) Whether to attempt initialization silently (true) or not (false).
require('mkdnflow').links.createLink(args)
Creates a markdown link from the word under the cursor or visual selection.
- Parameters:
args: (table) Arguments to customize link creation.from_clipboard: (boolean) If true, use the system clipboard content as the link source.
require('mkdnflow').links.followLink(args)
Follows the link under the cursor, opening the corresponding file, URL, or directory.
- Parameters:
args: (table) Arguments for following the link.path: (string|nil) The path/source to follow. Ifnil, a path from a link under the cursor will be used.anchor: (string|nil) An anchor, either one in the current buffer (in which casepathwill benil), or one in the file referred to inpath.range: (boolean|nil) Whether a link should be created from a visual selection range. This is only relevant ifcreate_on_follow_failureistrue, there is no link under the cursor, and there is currently a visual selection that needs to be made into a link.
require('mkdnflow').links.destroyLink()
Destroys the link under the cursor, replacing it with plain text.
require('mkdnflow').links.tagSpan()
Tags a visual selection as a span, useful for adding attributes to specific text segments.
require('mkdnflow').links.getLinkUnderCursor(col)
Returns the link under the cursor at the specified column.
- Parameters:
col: (number|nil) The column position to check for a link. The current cursor position is used if this is not specified.
require('mkdnflow').links.getLinkPart(link_table, part)
Retrieves a specific part of a link, such as the source or the text.
- Parameters:
link_table: (table) The table containing link details, as provided byrequire('mkdnflow').links.getLinkUnderCursor().part: (string|nil) The part of the link to retrieve (one of'source','name', or'anchor'). Default:'source'.
require('mkdnflow').links.getBracketedSpanPart(part)
Retrieves a specific part of a bracketed span.
- Parameters:
part: (string|nil) The part of the span to retrieve (one of'text'or'attr'). Default:'attr'.
require('mkdnflow').links.hasUrl(string, to_return, col)
Checks if a given string contains a URL and optionally returns the URL.
- Parameters:
string: (string) The string to check for a URL.to_return: (string) The part to return (e.g., "url").col: (number) The column position to check.
require('mkdnflow').links.transformPath(text)
Transforms the given text according to the default or user-supplied explicit transformation function.
- Parameters:
text: (string) The text to transform.
require('mkdnflow').links.formatLink(text, source, part)
Creates a formatted link with whatever is provided.
- Parameters:
text: (string) The link text.source: (string) The link source.part: (integer|nil) The specific part of the link to return.nil: () Return the entire link.1: () Return the text part of the link.2: () Return the source part of the link.
require('mkdnflow').paths.moveSource()
Moves the source file of a link to a new location, updating the link accordingly.
require('mkdnflow').paths.handlePath(path, anchor)
Handles all 'following' behavior for a given path, potentially opening it or performing other actions based on the type.
- Parameters:
path: (string) The path to handle.anchor: (string|nil) Optional anchor within the path.
require('mkdnflow').paths.formatTemplate(timing, template)
Formats the new file template based on the specified timing (before or after buffer creation). If this is called once with 'before' timing, the output can be captured and passed back in with 'after' timing to perform different substitutions before and after a new buffer is opened.
- Parameters:
timing: (string) "before" or "after" specifying when to perform the formatting.'before': () Perform the template formatting before the new buffer is opened.'after': () Perform the template formatting after the new buffer is opened.
template: (string|nil) The template to format. If not provided, the default new file template is used.
require('mkdnflow').paths.updateDirs()
Updates the working directory after switching notebooks or notebook folders (if nvim_wd_heel is true).
require('mkdnflow').paths.pathType(path, anchor)
Determines the type of the given path (file, directory, URL, etc.).
- Parameters:
path: (string) The path to check.anchor: (string|nil) Optional anchor within the path.
require('mkdnflow').paths.transformPath(path)
Transforms the given path based on the plugin's configuration and transformations.
- Parameters:
path: (string) The path to transform.
require('mkdnflow').buffers.goBack()
Navigates to the previously opened buffer.
require('mkdnflow').buffers.goForward()
Navigates to the next buffer in the history.
require('mkdnflow').cursor.goTo(pattern, reverse)
Moves the cursor to the next or previous occurrence of the specified pattern.
- Parameters:
pattern: (string|table) The Lua regex pattern(s) to search for.reverse: (boolean) If true, search backward.
require('mkdnflow').cursor.goTo("%[.*%](.*)", false) -- Go to next markdown linkrequire('mkdnflow').cursor.toNextLink()
Moves the cursor to the next link in the file.
require('mkdnflow').cursor.toPrevLink()
Moves the cursor to the previous link in the file.
require('mkdnflow').cursor.toHeading(anchor_text, reverse)
Moves the cursor to the specified heading.
- Parameters:
anchor_text: (string|nil) The text of the heading to move to, transformed in the way that is expected for an anchor link to a heading. Ifnil, the function will go to the next closest heading.reverse: (boolean) If true, search backward.
require('mkdnflow').cursor.toId(id, starting_row)
Moves the cursor to the specified ID in the file.
- Parameters:
id: (string) The Pandoc-style ID attribute (in a tagged span) to move to.starting_row: (number|nil) The row to start the search from. If not provided, the cursor row will be used.
require('mkdnflow').cursor.changeHeadingLevel(change)
Increases or decreases the importance of the heading under the cursor by adjusting the number of hash symbols.
- Parameters:
change: (string) "increase" to decrease hash symbols (increasing importance), "decrease" to add hash symbols, decreasing importance.
require('mkdnflow').cursor.yankAsAnchorLink(full_path)
Yanks the current line as an anchor link, optionally including the full file path depending on the value of the argument.
- Parameters:
full_path: (boolean) If true, includes the full file path.
require('mkdnflow').lists.newListItem({ carry, above, cursor_moves, mode_after, alt })
Inserts a new list item with various customization options such as whether to carry content from the current line, position the new item above or below, and the editor mode after insertion.
- Parameters:
carry: (boolean) Whether to carry content following the cursor on the current line into the new line/list item.above: (boolean) Whether to insert the new item above the current line.cursor_moves: (boolean) Whether the cursor should move to the new line.mode_after: (string) The mode to enter after insertion ("i" for insert, "n" for normal).alt: (string) Which key(s) to feed if this is called while the cursor is not on a line with a list item. Must be a valid string for the first argument ofvim.api.nvim_feedkeys.
require('mkdnflow').lists.hasListType(line)
Checks if the given line is part of a list.
- Parameters:
line: (string) The (content of the) line to check. If not provided, the current cursor line will be used.
require('mkdnflow').lists.toggleToDo(opts)
Toggles (rotates) the status of a to-do list item based on the provided options.
- Parameters:
opts: (table) Options for toggling.
Warning
require('mkdnflow').lists.toggleToDo(opts) is deprecated. For convenience, it is
now a wrapper function that calls its replacement, require('mkdnflow').to_do.toggle_to_do(opts).
See require('mkdnflow').to_do.toggle_to_do() for details.
require('mkdnflow').lists.updateNumbering(opts, offset)
Updates the numbering of the list items in the current list.
- Parameters:
opts: (table) Options for updating numbering.opts[1]: (integer) The number to start the current ordered list with.
offset: (number) The offset to start numbering from. Defaults to0if not provided.
require('mkdnflow').to_do.toggle_to_do()
Toggle (rotate) to-do statuses for a to-do item under the cursor.
require('mkdnflow').to_do.get_to_do_item(line_nr)
Retrieves a to-do item from the specified line number.
- Parameters:
line_nr: (number) The line number to retrieve the to-do item from. If not provided, defaults to the cursor line number.
require('mkdnflow').to_do.get_to_do_list(line_nr)
Retrieves the entire to-do list of which the specified line number is an item/member.
- Parameters:
line_nr: (number) The line number to retrieve the to-do list from. If not provided, defaults to the cursor line number.
require('mkdnflow').to_do.hl.init()
Initializes highlighting for to-do items. If highlighting is enabled in your configuration, you should never need to use this.
require('mkdnflow').tables.formatTable()
Formats the current table, ensuring proper alignment and spacing.
require('mkdnflow').tables.addRow(offset)
Adds a new row to the table at the specified offset.
- Parameters:
offset: (number) The position (relative to the current cursor row) in which to insert the new row. Defaults to0, in which case a new row is added beneath the current cursor row. An offset of-1will result in a row being inserted above the current cursor row; an offset of1will result in a row being inserted after the row following the current cursor row; etc.
require('mkdnflow').tables.addCol(offset)
Adds a new column to the table at the specified offset.
- Parameters:
offset: (number) The position (relative to the table column the cursor is currently in) to insert the new column. Defaults to0, in which case a new column is added after the current cursor table column. An offset of-1will result in a column being inserted before the current cursor table column; an offset of1will result in a column being inserted after the column following the current cursor table column; etc.
require('mkdnflow').tables.newTable(opts)
Creates a new table with the specified options.
- Parameters:
opts: (table) Options for the new table (number of columns and rows).opts[1]: (integer) The number of columns the table should haveopts[2]: (integer) The number of rows the table should have (excluding the header row)opts[3]: (string) Whether to include a header for the table or not ('noh'or'noheader': Don't include a header row;nil: Include a header)
require('mkdnflow').tables.isPartOfTable(text, linenr)
Guesses as to whether the specified text is part of a table.
- Parameters:
text: (string) The content to check for table membership.linenr: (number) The line number corresponding to the text passed in.
require('mkdnflow').tables.moveToCell(row_offset, cell_offset)
Moves the cursor to the specified cell in the table.
- Parameters:
row_offset: (number) The difference between the current row and the target row.0, for instance, will target the current row.cell_offset: (number) The difference between the current table column and the target table column.0, for instance, will target the current column.
require('mkdnflow').folds.getHeadingLevel(line)
Gets the heading level of the specified line.
- Parameters:
line: (string) The line content to get the heading level for. Required.
require('mkdnflow').folds.foldSection()
Folds the current section based on markdown headings.
require('mkdnflow').folds.unfoldSection()
Unfolds the current section.
require('mkdnflow').yaml.hasYaml()
Checks if the current buffer contains a YAML header block.
require('mkdnflow').yaml.ingestYamlBlock(start, finish)
Parses and ingests a YAML block from the specified range.
- Parameters:
start: (number) The starting line number.finish: (number) The ending line number.
require('mkdnflow').bib.handleCitation(citation)
Handles a citation, potentially linking to a bibliography entry or external source.
- Parameters:
citation: (string) The citation key to handle. Required.
See CONTRIBUTING.md
Mkdnflow uses Semantic Versioning. Version numbers follow the format MAJOR.MINOR.PATCH:
- MAJOR: Incompatible API or configuration changes
- MINOR: New functionality in a backward-compatible manner
- PATCH: Backward-compatible bug fixes
For a detailed history of changes, see CHANGELOG.md.
- Obsidian.md
- clipboard-image.nvim
- mdeval.nvim
- In-editor rendering
- Preview plugins
