Skip to content

jakewvincent/mkdnflow.nvim

Repository files navigation

Black mkdnflow logo in light color mode and white logo in dark color mode

Contents

  1. 🚀 Introduction
  2. ✨ Features
    1. 🧭 Navigation
    2. 🔗 Link and reference handling
    3. 📊 Table support
    4. 📝 List support
    5. ✅ To-do list support
    6. 📁 File management
    7. 🪗 Folding
    8. 🔮 Completion
    9. 🧩 YAML block parsing
    10. 🖌️ Visual enhancements
  3. 💾 Installation
  4. ⚙️ Configuration
    1. ⚡ Quick start
    2. 🔧 Advanced configuration and sample recipes
  5. 🛠️ Commands & mappings
  6. 📚 API
    1. Initialization
    2. Link management
    3. Link and path handling
    4. Buffer navigation
    5. Cursor movement
    6. Cursor-aware manipulations
    7. List management
    8. To-do list management
    9. Table management
    10. Folds
    11. Yaml blocks
    12. Bibliography
  7. 🤝 Contributing
  8. 🔢 Version information
  9. 🔗 Related projects
    1. Competition
    2. Complementary plugins

🚀 Introduction

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).

✨ Features

🧭 Navigation

Within-buffer navigation

  • Jump to links
  • Jump to section headings

In-buffer navigation demo

Within-notebook navigation

  • 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 and reference handling

  • 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 url or doi field in the default browser
    • Open documents specified in file field
  • 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)

📊 Table support

  • Table creation
  • Table extension (add rows and columns)
  • Table formatting
  • Paste delimited data as a table
  • Import delimited file into a new table

📝 List support

  • Automatic list extension
  • Sensible auto-indentation and auto-dedentation
  • Ordered list number updating

✅ To-do list support

  • 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

📁 File management

  • Simultaneous link and file renaming
  • As-needed directory creation

🪗 Folding

  • 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

🔮 Completion

  • Path completion
  • Completion of bibliography items

🧩 YAML block parsing

  • Specify a bibliography file in YAML front matter

🖌️ Visual enhancements

  • Conceal markdown and wiki link syntax
  • Extended link highlighting
    • Automatic links
    • Wiki links

💾 Installation

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
})
EOF

⚙️ Configuration

⚡ Quick start

Mkdnflow 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
}

🔧 Advanced configuration and sample recipes

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' },
    },
}

🎨 Configuration options

modules
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.
create_dirs
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.
perspective
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.)
filetypes
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.

wrap
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.
bib
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.
silent
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.
cursor
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.
links
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
    }
})
new_file_template
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 }}'
to_do
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 statuses
  • to_do.not_started - Which marker represents a not-yet-started to-do
  • to_do.in_progress - Which marker represents an in-progress to-do
  • to_do.complete - Which marker represents a complete to-do
  • to_do.update_parents - Whether parent to-dos' statuses should be updated
foldtext
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):

Enhanced foldtext example

tables
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.
yaml
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.
mappings
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).

🔮 Completion setup

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.

🛠️ Commands & mappings

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.

📚 API

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:

  1. Initialization (Initialization)
  2. Link management (Link management)
  3. Link & path handling (Link and path handling)
  4. Buffer navigation (Buffer navigation)
  5. Cursor movement (Cursor movement)
  6. Cursor-aware manipulations (Cursor-aware manipulations)
  7. List management (List management)
  8. To-do list management (To-do list management)
  9. Table management (Table management)
  10. Folds (Folds)
  11. Yaml blocks (Yaml blocks)
  12. Bibliography (Bibliography)

Initialization

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).

Link management

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. If nil, a path from a link under the cursor will be used.
      • anchor: (string|nil) An anchor, either one in the current buffer (in which case path will be nil), or one in the file referred to in path.
      • range: (boolean|nil) Whether a link should be created from a visual selection range. This is only relevant if create_on_follow_failure is true, 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 by require('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.

Link and path handling

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.

Buffer navigation

require('mkdnflow').buffers.goBack()

Navigates to the previously opened buffer.

require('mkdnflow').buffers.goForward()

Navigates to the next buffer in the history.

Cursor movement

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 link

require('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. If nil, 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.

Cursor-aware manipulations

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.

List management

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 of vim.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 to 0 if not provided.

To-do list management

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.

Table management

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 to 0, in which case a new row is added beneath the current cursor row. An offset of -1 will result in a row being inserted above the current cursor row; an offset of 1 will 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 to 0, in which case a new column is added after the current cursor table column. An offset of -1 will result in a column being inserted before the current cursor table column; an offset of 1 will 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 have
      • opts[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.

Folds

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.

Yaml blocks

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.

Bibliography

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.

🤝 Contributing

See CONTRIBUTING.md

🔢 Version information

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.

🔗 Related projects

Competition

Complementary plugins

About

Fluent navigation and management of markdown notebooks

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Sponsor this project

Contributors 18

Languages