NVIM LUAU

Awesome plugins for Neovim

GitHubAdd Plugin

    Tabline

  • akinsho/bufferline.nvim
    944

    A snazzy bufferline for Neovim

  • crispgm/nvim-tabline
    19

    nvim port of tabline.vim with Lua

  • koenverburg/minimal-tabline.nvim
    2

    A minimal tabline, that's it

  • nanozuki/tabby.nvim
    381

    A declarative, highly configurable, and neovim style tabline plugin. Use your nvim tabs as a workspace multiplexer!

  • noib3/nvim-cokeline
    169

    :nose: A Neovim bufferline for people with addictive personalities

  • romgrk/barbar.nvim
    899

    The neovim tabline plugin.

  • Status Line

  • alvarosevilla95/luatab.nvim
    109

    Tabline lua plugin for neovim

  • b0o/incline.nvim
    105

    🎈 Floating statuslines for Neovim

  • datwaft/bubbly.nvim
    167

    Bubbly statusline for neovim

  • feline-nvim/feline.nvim
    564

    A minimal, stylish and customizable statusline for Neovim written in Lua

  • konapun/vacuumline.nvim
    17

    A prebuilt configuration for galaxyline inspired by airline

  • NTBBloodbath/galaxyline.nvim
    118

    neovim statusline plugin written in lua

  • nvim-lualine/lualine.nvim
    1434

    A blazing fast and easy to configure neovim statusline plugin written in pure lua.

  • rebelot/heirline.nvim
    208

    Heirline.nvim is a no-nonsense Neovim Statusline plugin designed around recursive inheritance to be exceptionally fast and versatile.

  • tamton-aquib/staline.nvim
    138

    A modern lightweight statusline and bufferline for neovim in lua. Mainly uses unicode symbols for showing info.

  • windwp/windline.nvim
    280

    Animation statusline, floating window statusline. Use lua + luv make some wind

  • Keybinding

  • b0o/mapx.nvim
    141

    🗺 A better way to create key mappings in Neovim.

  • folke/which-key.nvim
    1189

    💥 Create key bindings that stick. WhichKey is a lua plugin for Neovim 0.5 that displays a popup with possible keybindings of the command you started typing.

  • mrjones2014/legendary.nvim
    210

    🗺️ A legend for your keymaps, commands, and autocmds, with which-key.nvim integration (requires Neovim nightly)

  • simrat39/rust-tools.nvim
    684

    Tools for better development in rust using neovim's builtin lsp

  • LSP

  • b0o/SchemaStore.nvim
    159

    🛍 JSON schemas for Neovim

  • folke/trouble.nvim
    1388

    🚦 A pretty diagnostics, references, telescope results, quickfix and location list to help you solve all the trouble your code is causing.

  • jose-elias-alvarez/nvim-lsp-ts-utils
    373

    Utilities to improve the TypeScript development experience for Neovim's built-in LSP client.

  • neovim/nvim-lspconfig
    3936

    Quickstart configurations for the Nvim LSP client

  • nvim-lua/lsp_extensions.nvim
    193

    Repo to hold a bunch of info & extension callbacks for built-in LSP. Use at your own risk :wink:

  • nvim-lua/lsp-status.nvim
    426

    Utility functions for getting diagnostic status and progress messages from LSP servers, for use in the Neovim statusline

  • ray-x/navigator.lua
    572

    Navigate codes like a breeze🎐. Exploring LSP and 🌲Treesitter symbols a piece of 🍰. Take control like a boss 🦍.

  • williamboman/nvim-lsp-installer
    1157

    Neovim plugin that allows you to seamlessly manage LSP servers with :LspInstall. With full Windows support!

  • Guides

  • bennypowers/nvim-regexplainer
    183

    Describe the regexp under the cursor

  • nvim-lua/kickstart.nvim
    2356

    A launch point for your personal nvim configuration

  • Colorschemes

  • catppuccin/nvim
    546

    🍨 Soothing pastel theme for NeoVim

  • dharmx/nvim-colo
    26

    Theming utlilities for neovim. This is very experimental at the moment.

  • ful1e5/onedark.nvim
    174

    Atom's iconic One Dark theme for Neovim, written in Lua

  • HUAHUAI23/nvim-quietlight
    0

    A theme for Neovim with support for LSP, Treesitter, and more.

  • kvrohit/substrata.nvim
    56

    A cold, dark color scheme for Neovim

  • lalitmee/cobalt2.nvim
    7

    cobalt2 theme for neovim in Lua using colorbuddy

  • luisiacc/gruvbox-baby
    42

    Gruvbox theme for neovim with full 🎄TreeSitter support.

  • mhartington/oceanic-next
    986

    Oceanic Next theme for neovim

  • Mofiqul/adwaita.nvim
    38

    Neovim colorscheme using Gnome Adwaita syntax

  • Mofiqul/dracula.nvim
    123

    Dracula colorscheme for neovim written in Lua

  • mrjones2014/lighthaus.nvim
    40

    A Lua implementation of lighthaus-theme/vim-lighthaus

  • navarasu/onedark.nvim
    270

    One dark and light colorscheme for neovim >= 0.5.0 written in lua based on Atom's One Dark and Light theme. Additionally, it comes with 5 color variant styles

  • NTBBloodbath/doom-one.nvim
    74

    doom-emacs' doom-one Lua port for Neovim

  • rebelot/kanagawa.nvim
    738

    NeoVim dark colorscheme inspired by the colors of the famous painting by Katsushika Hokusai.

  • rose-pine/neovim
    310

    Soho vibes for Neovim

  • RRethy/nvim-base16
    301

    Neovim plugin for building a sync base16 colorscheme. Includes support for Treesitter and LSP highlight groups.

  • sunjon/Shade.nvim
    374

    An Nvim lua plugin that dims your inactive windows

  • themercorp/themer.lua
    130

    A simple, minimal highlighter plugin for neovim

  • zanglg/nova.nvim
    82

    Another color scheme for neovim written in lua, WIP

  • Comment

  • danymat/neogen
    373

    A better annotation generator. Supports multiple languages and annotation conventions.

  • Utility

  • echasnovski/mini.nvim
    405

    Neovim plugin with collection of minimal, independent, and fast Lua modules dedicated to improve Neovim (version 0.5 and higher) experience

  • hood/popui.nvim
    42

    NeoVim UI sweetness powered by popfix.

  • meznaric/conmenu
    21

  • mrjones2014/dash.nvim
    132

    🏃💨 Search Dash.app from your Neovim fuzzy finder. Built with Rust 🦀 and Lua

  • Cursor Line

  • edluffy/specs.nvim
    233

    👓 A fast and lightweight Neovim lua plugin to keep an eye on where your cursor has jumped.

  • mg979/vim-visual-multi
    2046

    Multiple cursors plugin for vim/neovim

  • Code Runner

  • FeiyouG/command_center.nvim
    57

    Create and manage keybindings and commands in a more organized manner, and search them quickly through Telescope

  • Extras

  • folke/zen-mode.nvim
    377

    🧘 Distraction-free coding for Neovim

  • goolord/alpha-nvim
    322

    a lua powered greeter like vim-startify / dashboard-nvim

  • Start Up

  • henriquehbr/nvim-startup.lua
    45

    Displays neovim startup time

  • lewis6991/impatient.nvim
    563

    Improve startup time for Neovim

  • Session

  • HUAHUAI23/telescope-session.nvim
    12

    manage your vim session with telescope 🔭

  • Fuzzy Finder

  • ibhagwan/fzf-lua
    418

    Improved fzf.vim written in lua

  • nvim-telescope/telescope.nvim
    5023

    Find, Filter, Preview, Pick. All lua, all the time.

  • vijaymarupudi/nvim-fzf
    223

    A Lua API for using fzf in neovim.

  • Misc

  • iggredible/Learn-Vim
    9061

    Learning Vim and Vimscript doesn't have to be hard. This is the guide that you're looking for 📖

  • m-demare/attempt.nvim
    53

    Manage temporary buffers

  • SmiteshP/nvim-gps
    348

    Simple statusline component that shows what scope you are working inside

  • windwp/nvim-autopairs
    1479

    autopairs for neovim written by lua

  • zegervdv/nrpattern.nvim
    43

    Neovim plugin to expand incrementing/decrementing to more formats.

  • Note Taking

  • jakewvincent/mkdnflow.nvim
    97

    Tools for markdown notebook navigation and management

  • nvim-neorg/neorg
    2078

    Modernity meets insane extensibility. The future of organizing your life in Neovim.

  • Motion

  • jinh0/eyeliner.nvim
    170

    👀 Move faster with unique f/F indicators.

  • Terminal Integration

  • jlesquembre/nterm.nvim
    35

    neovim plugin to interact with the terminal

  • Scrolling

  • karb94/neoscroll.nvim
    765

    Smooth scrolling neovim plugin written in lua

  • Git

  • kdheepak/lazygit.nvim
    313

    Plugin for calling lazygit from within neovim.

  • zegervdv/settle.nvim
    0

    Settle your merge conflicts from Neovim

  • File Explorer

  • kevinhwang91/rnvimr
    451

    Make Ranger running in a floating window to communicate with Neovim via RPC

  • kyazdani42/nvim-tree.lua
    2040

    A file explorer tree for neovim written in lua

  • Snippets

  • L3MON4D3/LuaSnip
    692

    Snippet Engine for Neovim written in Lua.

  • Browser Integration

  • lalitmee/browse.nvim
    0

    browse for anything using your choice of method

  • Indent

  • lukas-reineke/indent-blankline.nvim
    1272

    Indent guides for Neovim

  • Formatting

  • lukas-reineke/lsp-format.nvim
    248

    A wrapper around Neovims native LSP formatting.

  • Syntax

  • m-demare/hlargs.nvim/
    30

    Highlight arguments' definitions and usages, using Treesitter

  • Splits and Window

  • mrjones2014/smart-splits.nvim
    83

    🧠 Smart, directional Neovim split resizing and navigation. Think about resizing splits in terms of "move the divider to the left/right/up/down".

  • Completion

  • noib3/nvim-compleet
    413

    :zap: An async autocompletion framework for Neovim

  • zbirenbaum/copilot-cmp
    69

    Lua plugin to turn github copilot into a cmp source

  • zbirenbaum/copilot.lua
    100

    Lua plugin for starting and interacting with github copilot

  • Package Managers

  • NTBBloodbath/cheovim
    145

    Neovim configuration switcher written in Lua. Inspired by chemacs.

  • savq/paq-nvim
    408

    🌚 Neovim package manager

  • wbthomason/packer.nvim
    2321

    A use-package inspired plugin manager for Neovim. Uses native packages, supports Luarocks dependencies, written in Lua, allows for expressive config

  • Game

  • ThePrimeagen/vim-be-good
    619

    vim-be-good is a nvim plugin designed to make you better at Vim Movements.

https://github.com/jakewvincent/mkdnflow.nvim

🆕 Top three latest features

  1. Templates for new files
  2. Follow automatic links
  3. Create links using the system clipboard's content as the link source

📝 Description

Mkdnflow is designed for the fluent navigation of documents and notebooks (AKA "wikis") written in markdown. The plugin's flexibility and its prioritization of markdown also means it can become part of your webdev workflow if you use static site generators like Jekyll or Hugo, which can generate static sites from markdown documents.

The plugin is an extended set of functions and mappings to those functions which make it easy to navigate and manipulate markdown documents and notebooks in Neovim. I originally started writing Mkdnflow to replicate some features from Vimwiki in Lua instead of Vimscript, but my current goal for this project is to make this plugin as useful as possible for anyone using Neovim who maintains a set of markdown notes and wishes to efficiently navigate those notes and keep them organized and connected. The plugin now includes some convenience features I wished Vimwiki had, including functionality to rename the source part of a link and its associated file simultaneously.

I keep tabs on the project's issues and appreciate feature requests, suggestions, and bug reports. I invite you to use the discussion board if you would like to share your config, share how Mkdnflow fits into your workflow, get help with setup, or contribute feature suggestions or optimizations. Contributions to the plugin are welcome: fork this repo and submit a pull request with your changes or additions. For Lua resources, see this page or call :h lua or :h api in Neovim.

⚡ Requirements

  • Linux, macOS, or Windows
  • Neovim >= 0.7.0 for all functionality (most will work with Neovim >= 0.5.0, but mappings will need to be set separately)
  • Optional: If you wish to use UTF-8 symbols as custom to-do symbols, in tables that you wish to have Mkdnflow format, or in anchor links, you'll need the luarocks module luautf8. Luarocks dependencies can be installed via Packer using the rocks key:
use({'jakewvincent/mkdnflow.nvim',
    rocks = 'luautf8', -- Ensures optional luautf8 dependency is installed
    config = function()
        require('mkdnflow').setup()
    end
})

➖ Differences from Vimwiki

  • Vimwiki doesn't use markdown by default; mkdnflow only works for markdown
  • I'm intending mkdnflow to be a little lighter weight/less involved than Vimwiki. Mkdnflow doesn't and won't provide syntax highlighting and won't create new filetypes (although it now optionally provides link concealing, since this was a requested feature).
  • Mkdnflow allows you to prevent modules from being loaded that provide features you don't want or don't expect to use (all are enabled by default except yaml)
    • Mappings to user commands associated with these modules will not be defined if the command depends on a module that is not loaded
  • Written in Lua

✨ Features

Markdown or wiki link styles

  • See links config
  • Markdown link formats recognized:
    • Standard style: [name](source)
    • 🆕 Reference style:
      • [name][label] followed anywhere in the file by [label]: source, where label is an integer
      • source can optionally be surrounded by < and >
      • source can optionally be followed by a title, following any of the formats specified here
  • Wiki link formats recognized:
    • Source-only wiki links: [[source]]
    • Source-left, name-right wiki links: [[source|name]]
  • Conceal link sources for either link type by enabling conceal in your config
    • Markdown-style links are shortened from [Link](source.md) to Link
    • Wiki-style links are shortened from [[source|Link]] to Link or from [[source]] to source
    • NOTE: If you are using the recently split treesitter parsers for markdown, you do not need to enable conceal through mkdnflow--if you are using markdown-style links. Just make sure you have markdown and markdown_inline installed and enabled in markdown filetypes, and in your .vimrc or init.lua, enable conceal (set conceallevel=2 or vim.wo.conceallevel = 2).

Follow links and citations

  • <CR> on various kinds of links to "follow" them:
    • .md links open in the current window
    • Absolute links or .md links relative to home open in the current window but are interpreted with absolute perspective (e.g. [File](/home/user/file.md)/[File](C:\Users\user\file.md) on Windows, or [File](~/Documents/file.md))
    • Links to a file prefixed with file: (e.g. [My Xournal notes](file:notes.xopp)) open with the system's default program for that filetype
    • Links to URLs are opened in the default browser
    • Anchor links to headings (or bracketed spans) in the current file will trigger a jump to that heading or bracketed span. (Install the luautf8 Luarocks module if you want your anchor links to be able to include non-ascii symbols.)
      • Bracketed spans can have arbitrary ID attributes; if multiple bracketed spans in a file have the same ID attribute, the first will be jumped to. If a bracketed span's ID attribute is identical to that of a heading, the bracketed span will be prioritized since it is explicitly labeled.
      • Headings must start with a hash, and the source part of the anchor link must look like the heading with (a) any spaces between the last hash mark and the beginning of the heading text removed, (b) all other spaces converted to a dash, (c) non-alphanumeric characters removed, (d) strings of multiple hashes converted into a single hash, and (e) all upper-case characters converted to lower-case characters. For example:
        • ## Bills to pay will be jumped to if the path in the anchor link is #bills-to-pay
        • #### Groceries/other things to buy will be jumped to if the path in the anchor link is #groceriesother-things-to-buy
    • Links to markdown files that include an anchor (e.g. [Link](grocery_list.md#produce)) will open the file in the current window and jump to a bracketed span or heading matching the # attribute
    • Following a link to a directory (e.g. another notebook) will open a dialogue for you to select which file in the directory to open in the current window
    • 🆕 Automatic links (URLs enclosed in angle brackets, e.g. <https://example.org>) are followed directly
  • <CR> on citations to open associated files or websites (e.g. @Chomsky1957, with or without brackets around it)
    • Specify a path to a .bib file in your config—or if perspective.priority is root, simply place your bib files to be searched in your notebook's root directory.
    • Files are prioritized. If no file is found associated with the citation key, a URL associated with it will be opened. If no URL is found, a DOI is opened. If no DOI is found, whatever is in the howpublished field is opened.
    • 🔥 Hot tip: make reaching your contacts via work messaging apps (e.g. Slack) easier by keeping a bib file that associates your contacts' messaging handles with the URL for your direct message thread with that contact. For instance, if you point the plugin to a bib file with the following entry, <CR>ing on @dschrute in a markdown document would take you to the associated Slack thread.
@misc{dschrute,
    url={https://dundermifflin.slack.com/archives/P07BFJD82}
}

Templates for new files

  • Define a custom template (under config option new_file_template.template) that gets populated and inserted into new markdown files.
  • Familiar double-brace syntax for placeholders, e.g. {{title}} or {{ title }}
  • Define custom template placeholders (under config option new_file_template.placeholders).
    • Evaluate the placeholder value before switching to the new buffer or after switching to the new buffer by defining the placeholder in either placeholders.before or placeholders.after.
    • {{ title }} and {{ date }} are assigned by default to "link_title" and "os_date" but can be overridden. "link_title" refers to the title of the file, as determined by the label of the the link that led to the new document. "os_date" refers to the system time (formatted as YYYY-MM-DD).

Example template

In the following example, {{ date }} will be filled in based on the result of evaluating the date function at the exact moment one tries to follow a link. {{ filename }} will be filled in based on the result of evaluating the filename function after the new buffer has been opened (thereby inserting the filename of the newly-opened buffer, rather than the previous one).

new_file_template = {
    template = [[
# {{ title }}
Date: {{ date }}
Filename: {{ filename }}
]],
    placeholders = {
        before = {
            date = function()
                return os.date("%A, %B %d, %Y") -- Wednesday, March 1, 2023
            end
        },
        after = {
            filename = function()
                return vim.api.nvim_buf_get_name(0)
            end
        }
    }
}

Customizable link interpretation

  • Specify what perspective the plugin-should take when interpreting links to files. There are three options:
    1. Interpret links relative to the first-opened file (default behavior; similar to #3 if your first-opened file is always in the root directory)
    2. Interpret links relative to the file open in the current buffer
    3. Interpret links relative to the root directory of the notebook that the file in the current buffer is a part of. To enable this functionality, set perspective.priority to root in your config, and pass a file as the value of perspective.root_tell. The tell is the name of a single file that can be used to identify the root directory (e.g. index.md, .git, .root, .wiki_root, etc.). See the default config for how to configure the perspective table.
    • Override any of the above settings by specifying a link to a markdown file with an absolute path (one that starts with / or ~/). Links within this file will still receive the relative interpretation, so this is best for references out of the project directory to markdown files without their own dependencies (unless those dependencies are within the project directory).
  • Keep your files organized and your links simple by customizing link interpretation using an implicit transformation function.

Create, customize, and destroy links

  • <CR> on the word under cursor or visual selection to create a notebook-internal link
    • Customizable path text transformations (by default, text is converted to lowercase, spaces are converted to dashes, and the date in YYYY-MM-DD format is prefixed to the filename, separated by an underscore). See the description of the links config key for customization instructions.
  • 🆕 <leader>p on the word under cursor or visual selection to create a link using the system clipboard's content as the source
  • <M-CR> (Alt-Enter) when your cursor is anywhere in a link to destroy it (replace it with the text in [...])
  • Create an anchor link if the visual selection starts with #
  • 🆕 Tag visually selected spans of text (mapped to <M-CR> in visual mode) using the style specified in the Pandoc bracketed_spans extension (ID must be assigned with the ID selector—i.e. #): [This is a span]{#important-span}.
  • Create a web link if what's under the cursor is a URL (and move the cursor to enter the link name)
  • yaa ("yank as anchor link"; formerly ya) on a heading or bracketed span to add a formatted anchor link for the heading to the default register (ready to paste in the current window)
    • yfa to do the same, but adding the absolute path of the file before the anchor (for pasting in another buffer)
  • Customize how link sources are generated from text using a custom explicit transformation function
    • Adding the following to your setup would result in a link that looks like the following: [Some text the link was created from](sometextthelinkwascreatedfrom.md)
require('mkdnflow').setup({
    links = {
        transform_explicit = function(text)
            -- Make lowercase, remove spaces, and reverse the string
            return string.lower(text:gsub(' ', ''))
        end
    }
})

Jump to links, headings

  • <Tab> and <S-Tab> jump to the next and previous links in the file
  • ]] and [[ jump to the next and previous headings in the file
  • "Wrap" back to the beginning/end of the file when jumping with a config setting

Create missing directories

  • If a link goes to a file in a directory that doesn't exist, it can optionally be created

Rename link sources and files simultaneously

  • Use built-in dialog triggered by MkdnMoveSource (mapped to <F2> by default) to rename a link's source and rename/move the linked file simultaneously
    • Perspective, implicit extensions, and custom implicit transformations are all taken into account when moving the linked file
    • The dialog will confirm the details of the changes for you to approve/reject before taking any action
    • 🆕 When a reference-style link is renamed, the reference line will be found and renamed accordingly without moving the cursor

Backward and forward navigation through buffers

  • <BS> to go backward (to the previous file/buffer opened in the current window, like clicking the back button in a web browser)
  • <Del> to go forward (to the subsequent file/buffer opened in the current window, like clicking the forward button in a web browser)

Keybindings

  • Easy-to-remember default keybindings that activate only in markdown files (and/or other filetypes you specify in the filetypes config table)
  • Customize keybindings individually or disable them altogether by disabling the maps module)

Manipulate headings

  • Increase/decrease heading levels (mapped to +/- by default). Note: Increasing the heading means increasing it in importance (i.e. making it bigger or more prominent when converted to HTML and rendered in a browser), which counterintuitively means removing a hash symbol.

Section folding

  • 🆕 Fold a section using <CR> in normal mode if the cursor is on the heading of the section
    • Unfold a folded section using <CR> or <leader>F (both are default mappings; the former maps to a wrapper function that will follow links if the cursor is not on a fold or section heading; the latter is mapped specifically to :MkdnUnfoldSection<CR>)
    • If you wish to create a link in a heading (normally done with <CR>), you'll need to do so by making a visual selection of the text you wish to create a link from and then hitting <CR>, or otherwise disabling the mapping for MkdnEnter and mapping MkdnFollowLink to <CR> in visual and normal modes.
  • 🆕 Fold the section the cursor is currently in—even if the cursor is not on the heading—using <leader>f

Lists

  • List markers recognized: -, *, and +
  • Toggle the status of a to-do list item on the current line (mapped to <C-Space> by default). Using the default settings, toggling will result in the following changes. To-do symbols can be customized (make sure to use the luautf8 luarock dependency if you want to use utf8 to-do symbols).
    • * [ ] ... → * [-] ...
    • * [-] ... → * [X] ...
    • * [X] ... → * [ ] ...
  • Toggle multiple to-do items at once by selecting the lines to toggle in (simple) visual mode (mapped to <C-Space> by default)
  • Create to-do items from plain unordered or ordered lists by toggling a non-to-do-list item (<C-Space> by default)
  • Automatically update any parent to-dos when child to-dos are toggled.
    • When all child to-dos have been marked complete, the parent is marked complete
    • When at least one child to-do has been marked in-progress, the parent to-do is marked in-progress
    • When a parent to-do is marked complete and one child to-do is reverted to not-yet-started or in-progress, the parent to-do is marked in-progress
    • When a parent to-do is marked complete or in-progress and all child to-dos have been reverted to not-yet-started, the parent to-do is marked not-yet-started.
  • Update numbering for the list the cursor is currently on
    • <leader>nn (default mapping) or :MkdnUpdateNumbering 0<CR>, e.g., if you want to start numbering at 0
  • Smart(er) behavior when <CR>ing in lists (NOTE: currently not enabled by default. See below.)
    • NOTE: The following functionality is disabled by default in case some find it intrusive. To enable the functionality, remap <CR> in insert mode (see the following code block).
    • In unordered lists: Add another bullet on the next line, unless the current list item is empty, in which case it will be erased
    • In ordered lists: Add another item on the next line (keeping numbering updated), unless the current item is empty, in which case it will be erased
    • In unordered and ordered to-do lists: Add another to-do item on the next line, unless the current to-do is empty, in which case it will be replaced with a simple (non-to-do) list item
    • Automatically indent a new list item when the current one ends in a colon
    • Demote empty indented list items by reducing the indentation by one level
  • Add new list items using the list type of the current line without any of the fancy stuff listed above (see MkdnExtendList)
require('mkdnflow').setup({
    mappings = {
        MkdnEnter = {{'i', 'n', 'v'}, '<CR>'} -- This monolithic command has the aforementioned
            -- insert-mode-specific behavior and also will trigger row jumping in tables. Outside
            -- of lists and tables, it behaves as <CR> normally does.
        -- MkdnNewListItem = {'i', '<CR>'} -- Use this command instead if you only want <CR> in
            -- insert mode to add a new list item (and behave as usual outside of lists).
    }
})

Tables

  • 🆕 Create a markdown table of x columns and y rows with :MkdnTable x y. Table headers are added automatically; to exclude headers, use :MkdnTable x y noh
  • 🆕 Format existing tables with :MkdnTableFormat
    • Make sure you have the luautf8 rock installed if you want to format tables containing non-ascii symbols!
  • 🆕 Jump forward and backward between cells (mapped to <Tab> and <S-Tab> in insert mode by default)
  • 🆕 Jump forward and backward between rows (the latter is mapped to <M-CR> in insert mode by default; jumping forward is not mapped to anything by default; see MkdnEnter or MkdnTableNextRow in default mappings)
  • 🆕 Optionally trim extra whitespace from a cell when formatting (see config options)
  • 🆕 Optionally disable formatting when moving cells
  • 🆕 Add new rows or columns (before or after the current row/cell; see default mappings)

🆕 Disable unused modules

  • Individually disable any of the modules that enable all of the above functionality (see modules config option descriptions)
    • Prevents the module from being loaded (rather than simply disabling the functionality the module provides)
    • Disabling a module prevents mappings to commands that are dependent on that module from being defined

🆕 YAML block parsing

  • Use YAML blocks at the very top of a markdown document to specify certain settings on a by-file basis:
    • Paths to bib files (must be absolute paths):
      • Specify as a string or a list (see examples of each below)

Specify one bib source:

---
bib: /home/user/Documents/Library/library.bib
---

Specify multiple bib sources:

---
bib:
  - /home/user/Documents/Library/library.bib
  - /home/user/Projects/special_project/refs.bib
---

📦 Installation and usage

init.lua

use({'jakewvincent/mkdnflow.nvim',
     config = function()
        require('mkdnflow').setup({
            -- Config goes here; leave blank for defaults
        })
     end
})

If you wish to use custom UTF-8 to-do symbols, add the luautf8 luarock dependency

use({'jakewvincent/mkdnflow.nvim',
     rocks = 'luautf8',
     config = function()
        require('mkdnflow').setup({
            -- Config goes here; leave blank for defaults
        })
     end
})
require('paq')({
    -- Your other plugins;
    'jakewvincent/mkdnflow.nvim';
    -- Your other plugins;
})

-- Include the setup function somewhere else in your init.lua/vim file, or the
-- plugin won't activate itself:

require('mkdnflow').setup({
    -- Config goes here; leave blank for defaults
})

init.vim

" Vim-Plug
Plug 'jakewvincent/mkdnflow.nvim'

" NeoBundle
NeoBundle 'jakewvincent/mkdnflow.nvim'

" Vundle
Bundle 'jakewvincent/mkdnflow.nvim'

" Pathogen
git clone https://github.com/jakewvincent/mkdnflow.nvim.git ~/.vim/bundle/mkdownflow.nvim

" Dein
call dein#add('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

❗ Caveats/warnings

All functionality of the plugin should now work on all operating systems, including Windows! However, since I don't use Windows on my daily driver, there may be edge cases that cause trouble. Please file an issue if anything comes up.

🏁 Starting a notebook

As long as you successfully installed Mkdnflow, you don't need to do anything special to start using the plugin. All of the plugin's features will be enabled for any markdown file (or for any filetype you specify under the filetypes config key). If you would like to start a notebook (AKA "wiki"), first create a directory for it. If you're using Neovim in the terminal, simply enter nvim index.md and start writing. I suggest using index.md as a landing page/table of contents that contains links to all other notes in your notebook. If you use such a landing page, try setting perspective.priority in your Mkdnflow config to 'root' and your perspective.root_tell to 'index.md' so that Mkdnflow can identify your notebook's root directory and reliably interpret links relative to this directory.

⚙️ Configuration

Currently, the setup function uses the defaults shown below. See the descriptions and non-default options in the section below the following block. To use these defaults, simply pass no arguments setup function: require('mkdnflow').setup(). To change these settings, specify new values for any of them them in the setup function.

-- ** DEFAULT SETTINGS; TO USE THESE, PASS NO ARGUMENTS TO THE SETUP FUNCTION **
require('mkdnflow').setup({
    modules = {
        bib = true,
        buffers = true,
        conceal = true,
        cursor = true,
        folds = true,
        links = true,
        lists = true,
        maps = true,
        paths = true,
        tables = true,
        yaml = false
    },
    filetypes = {md = true, rmd = true, markdown = true},
    create_dirs = true,             
    perspective = {
        priority = 'first',
        fallback = 'current',
        root_tell = false,
        nvim_wd_heel = false,
        update = false
    },    
    wrap = false,
    bib = {
        default_path = nil,
        find_in_root = true
    },
    silent = false,
    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
    },
    new_file_template = {
        use_template = false,
        placeholders = {
            before = {
                title = "link_title",
                date = "os_date"
            },
            after = {}
        },
        template = "# {{ title }}"
    },
    to_do = {
        symbols = {' ', '-', 'X'},
        update_parents = true,
        not_started = ' ',
        in_progress = '-',
        complete = 'X'
    },
    tables = {
        trim_whitespace = true,
        format_on_move = true,
        auto_extend_rows = false,
        auto_extend_cols = false
    },
    yaml = {
        bib = { override = false }
    },
    mappings = {
        MkdnEnter = {{'n', 'v'}, '<CR>'},
        MkdnTab = false,
        MkdnSTab = false,
        MkdnNextLink = {'n', '<Tab>'},
        MkdnPrevLink = {'n', '<S-Tab>'},
        MkdnNextHeading = {'n', ']]'},
        MkdnPrevHeading = {'n', '[['},
        MkdnGoBack = {'n', '<BS>'},
        MkdnGoForward = {'n', '<Del>'},
        MkdnCreateLink = false, -- see MkdnEnter
        MkdnCreateLinkFromClipboard = {{'n', 'v'}, '<leader>p'}, -- see MkdnEnter
        MkdnFollowLink = false, -- see MkdnEnter
        MkdnDestroyLink = {'n', '<M-CR>'},
        MkdnTagSpan = {'v', '<M-CR>'},
        MkdnMoveSource = {'n', '<F2>'},
        MkdnYankAnchorLink = {'n', 'yaa'},
        MkdnYankFileAnchorLink = {'n', 'yfa'},
        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'}
    }
})

Config descriptions

modules (dictionary-like table)

  • Most modules are enabled by default:
    • modules.bib (required for parsing bib files and following citations)
    • modules.buffers (required for backward and forward navigation through buffers)
    • modules.conceal (required if you wish to enable link concealing; note that you must declare links.conceal as true in addition to leaving this module enabled [it is enabled by default] if you wish to conceal links)
    • modules.cursor (required for jumping to links and headings; yanking anchor links)
    • modules.folds (required for folding by section)
    • modules.links (required for creating and destroying links and following links)
    • modules.lists (required for manipulating lists, toggling to-do list items, etc.)
    • modules.maps (required for setting mappings via the mappings table; set to false if you wish to set mappings outside of the plugin)
    • modules.paths (required for link interpretation and following links)
    • modules.tables (required for table navigation and formatting)
  • Modules not enabled by default:
    • modules.yaml (required for parsing yaml blocks)

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 (dictionary-like table)

  • perspective.priority (string): Specifies the priority perspective to take when interpreting link paths
    • 'first' (default): Links will be interpreted relative to the first-opened file (when the current instance of Neovim was started)
    • 'current': Links will be interpreted relative to the current file
    • 'root': Links will be interpreted relative to the root directory of the current notebook (requires perspective.root_tell to be specified)
  • perspective.root_tell (string or boolean)
    • '<any file name>': Any arbitrary filename by which the plugin can uniquely identify the root directory of the current notebook. If false is used instead, the plugin will never search for a root directory, even if perspective.priority is set to root.
  • perspective.fallback (string): Specifies the backup perspective to take if priority isn't possible (e.g. if it is 'root' but no root directory is found)
    • 'first': (see above)
    • 'current' (default): (see above)
    • 'root': (see above)
  • perspective.nvim_wd_heel (boolean): Specifies whether changes in perspective will result in corresponding changes to Neovim's working directory
    • 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): Determines whether the plugin looks to determine if a followed link is in a different notebook/wiki than before. If it is, the perspective will be updated. Requires root_tell to be defined and priority to be root.
    • true (default): 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: Perspective will be not updated when following a link to a file in a separate notebook/wiki. Under the hood, links in the file in the separate notebook/wiki will be interpreted relative to the original notebook/wiki.

filetypes (dictionary-like table)

  • <any arbitrary filetype extension> (boolean value)
    • true: A matching extension will enable the plugin's functionality for a file with that 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 (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 (dictionary-like table)

  • bib.default_path (string or nil): Specifies a path to a default .bib file to look for citation keys in (need not be in root directory of 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 appended 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 (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 (all messages from the plugin start with ⬇️ )

links (dictionary-like table)

  • 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 (number)
    • 0 (default): When following or jumping to links, assume no link will be split over multiple lines
    • n (an 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)
  • 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 (function or false): 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. If you want all link paths to be explicitly prefixed with the year, for instance, and for the path to be converted to uppercase, you could provide the following function under this key. (FYI: The previous functionality specified under the prefix key has been migrated here to provide greater flexibility.)
function(input)
    return(string.upper(os.date('%Y-')..input))
end
  • links.transform_implicit (function or false): 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 instance, 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, using the following function:
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 (dictionary-like table)

  • new_file_template.use_template (boolean)
    • true: the template is filled in (if it contains placeholders) and inserted into any new buffers entered by following a link to a buffer that doesn't exist yet
    • false: no templates are filled in and inserted into new buffers
  • new_file_template.placeholders (dictionary-like table)
    • new_file_template.placeholders.before (dictionary-like table) A table whose keys are placeholder names pointing to functions to be evaluated immediately before the buffer is opened in the current window
    • new_file_template.placeholders.after (dictionary-like table) A table hose keys are placeholder names pointing to functions to be evaluated immediately after the buffer is opened in the current window
  • new_file_template.template (string) A string, optionally containing placeholder names, that will be inserted into new buffers

to_do (dictionary-like table)

  • to_do.symbols (array-like table): A list of symbols (each no more than one character) that represent to-do list completion statuses. MkdnToggleToDo references these when toggling the status of a to-do item. Three are expected: one representing not-yet-started to-dos (default: ' '), one representing in-progress to-dos (default: -), and one representing complete to-dos (default: X).
    • NOTE: Native Lua support for UTF-8 characters is limited, so in order to ensure all functionality works as intended if you are using non-ascii to-do symbols, you'll need to install the luarocks module "luautf8".
  • to_do.update_parents (boolean): Whether parent to-dos' statuses should be updated based on child to-do status changes performed via MkdnToggleToDo
    • true (default): Parent to-do statuses will be inferred and automatically updated when a child to-do's status is changed
    • false: To-do items can be toggled, but parent to-do statuses (if any) will not be automatically changed
  • The following entries can be used to stipulate which symbols shall be used when updating a parent to-do's status when a child to-do's status is changed. These are not required: if to_do.symbols is customized but these options are not provided, the plugin will attempt to infer what the meanings of the symbols in your list are by their order. For example, if you set to_do.symbols as {' ', '⧖', '✓'}, ' ' will be assiged to to_do.not_started, '⧖' will be assigned to to_do.in_progress, etc. If more than three symbols are specified, the first will be used as not_started, the second will be used as in_progress, and the last will be used as complete. If two symbols are provided (e.g. ' ', '✓'), the first will be used as both not_started and in_progress, and the second will be used as complete.
    • to_do.not_started (string): Stipulates which symbol represents a not-yet-started to-do (default: ' ')
    • to_do.in_progress (string): Stipulates which symbol represents an in-progress to-do (default: '-')
    • to_do.complete (string): Stipulates which symbol represents a complete to-do (default: 'X')

tables (dictionary-like table)

  • tables.trim_whitespace (boolean): Whether extra whitespace should be trimmed from the end of a table cell when a table is formatted (default: true)
  • tables.format_on_move (boolean): Whether tables should be formatted each time the cursor is moved via MkdnTable{Next/Prev}{Cell/Row} (default: true)
  • tables.auto_extend_rows (boolean): Whether calling MkdnTableNextRow when the cursor is in the last row should add another row instead of leaving the table (default: false)
  • tables.auto_extend_cols (boolean): Whether calling MkdnTableNextCol when the cursor is in the last cell should add another column instead of jumping to the first cell of the next row (default: false)

yaml (dictionary-like table)

  • yaml.bib (dictionary-like table)
    • yaml.bib.override (boolean): Whether or not a bib path specified in a yaml block should be the only source considered for bib references in that file (default: false)

mappings (dictionary-like table)

  • mappings.<name of command> (array-like table or false)
    • mappings.<name of command>[1] string or array table representing the mode (or array of modes) that the mapping should apply in ('n', 'v', etc.)
    • mappings.<name of command>[2] string representing the keymap (e.g. '<Space>')
    • set mappings.<name of command> = false to disable default mapping without providing a custom mapping

Note: <name of command> should be the name of a commands defined in mkdnflow.nvim/plugin/mkdnflow.lua (see :h Mkdnflow-commands for a list).

👍 Recommended vim settings

I recommended turning on autowriteall in Neovim for markdown filetypes. This will ensure that changes to buffers are saved when you navigate away from that buffer, e.g. by following a link to another file. See :h awa. If you have hidden enabled or if a buffer is hidden by bufhidden, you may need to use the second option (thanks, @vandalt).

-- If you have an init.lua
vim.api.nvim_create_autocmd("FileType", {pattern = "markdown", command = "set awa"})
-- Use the following if your buffer is set to become hidden
--vim.api.nvim_create_autocmd("BufLeave", {pattern = "*.md", command = "silent! wall"})
" If you have an init.vim
autocmd FileType markdown set autowriteall
" Use the following if your buffer is set to become hidden
autocmd BufLeave *.md silent! wall

❕ Commands and default mappings

These default mappings can be disabled; see Configuration. Commands with no mappings trigger functions that are called by the functions with mappings, but I've given them a command name so you can use them as independent functions if you'd like to.

| Keymap | Mode | Command | Description | | ------------ | --------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | <CR> | n, v(, i) | :MkdnEnter<CR> | 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>} | | <Tab> | n | :MkdnNextLink<CR> | Move cursor to the beginning of the next link (if there is a next link) | | <S-Tab> | n | :MkdnPrevLink<CR> | Move the cursor to the beginning of the previous link (if there is one) | | ]] | n | :MkdnNextHeading<CR> | Move the cursor to the beginning of the next heading (if there is one) | | [[ | n | :MkdnPrevHeading<CR> | Move the cursor to the beginning of the previous heading (if there is one) | | <BS> | n | :MkdnGoBack<CR> | Open the historically last-active buffer in the current window | | <Del> | n | :MkdnGoForward<CR> | Open the buffer that was historically navigated away from in the current window | | -- | -- | :MkdnCreateLink<CR> | Create a link from the word under the cursor (in normal mode) or from the visual selection (in visual mode) | | <leader>p | n, v | :MkdnCreateLinkFromClipboard<CR> | 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<CR> | 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 | | <M-CR> | n | :MkdnDestroyLink<CR> | Destroy the link under the cursor, replacing it with just the text from [...] | | <M-CR> | v | :MkdnTagSpan<CR> | Tag a visually-selected span of text with an ID, allowing it to be linked to with an anchor link | | <F2> | n | :MkdnMoveSource<CR> | 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) | | yaa | n | :MkdnYankAnchorLink<CR> | Yank a formatted anchor link (if cursor is currently on a line with a heading) | | yfa | n | :MkdnYankFileAnchorLink<CR> | Yank a formatted anchor link with the filename included before the anchor (if cursor is currently on a line with a heading) | | + | n | :MkdnIncreaseHeading<CR> | Increase heading importance (remove hashes) | | - | n | :MkdnDecreaseHeading<CR> | Decrease heading importance (add hashes) | | <C-Space> | n | :MkdnToggleToDo<CR> | Toggle to-do list item's completion status or convert a list item into a to-do list item | | <leader>nn | n | :MkdnUpdateNumbering<CR> | Update numbering for all siblings of the list item of the current line | | -- | -- | :MkdnNewListItem<CR> | Add a new ordered list item, unordered list item, or (uncompleted) to-do list item | | o | n | :MkdnNewListItemBelowInsert<CR> | Add a new ordered list item, unordered list item, or (uncompleted) to-do 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. | | O | n | :MkdnNewListItemAboveInsert<CR> | Add a new ordered list item, unordered list item, or (uncompleted) to-do 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<CR> | Like above, but the cursor stays on the current line (new list items of the same typ 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<CR> | Format a table under the cursor | | <Tab> | i | :MkdnTableNextCell<CR> | Move the cursor to the beginning of the next cell in the table, jumping to the next row if needed | | <S-Tab> | i | :MkdnTablePrevCell<CR> | Move the cursor to the beginning of the previous cell in the table, jumping to the previous row if needed | | <leader>ir | n | :MkdnTableNewRowBelow<CR> | Add a new row below the row the cursor is currently in | | <leader>iR | n | :MkdnTableNewRowAbove<CR> | Add a new row above the row the cursor is currently in | | <leader>ic | n | :MkdnTableNewColAfter<CR> | Add a new column following the column the cursor is currently in | | <leader>iC | n | :MkdnTableNewColBefore<CR> | Add a new column before the column the cursor is currently in | | -- | -- | :MkdnTab<CR> | 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<CR> | 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) | | <leader>f | -- | :MkdnFoldSection<CR> | Fold the section the cursor is currently on/in | | <leader>F | -- | :MkdnUnfoldSection<CR> | Unfold the folded section the cursor is currently on | | -- | -- | :Mkdnflow<CR> | Manually start Mkdnflow |

Miscellaneous notes (+ troubleshooting) on remapping

  • The back-end function for :MkdnGoBack, require('mkdnflow').buffers.goBack(), returns a boolean indicating the success of goBack() (thanks, @pbogut!). This is useful if the user wishes to remap <BS> so that when goBack() is unsuccessful, another function is performed.
  • 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 using the mapping with a fallback, as shown here: cmp-mapping
    • If using an autopair plugin that automtically maps <CR> (e.g. nvim-autopairs), see if it provides a way to disable its <CR> mapping (e.g. nvim-autopairs allows you to disable that mapping by adding map_cr = false to the table passed to its setup function).

☑️ To do

  • [X] Improve citation functionality
    • [X] Add ability to stipulate a .bib file in a yaml block at the top of a markdown file
  • [X] Interpret reference-style links (spec: Reference-style Links)
  • [X] Overhaul help documents (i.e. :h mkdnflow)
  • [X] Tables: add a config option to automatically expand a table (row-wise or col-wise) when attempting to jump to the next col/row and there is none
  • [X] Add a way to disable modules the user doesn't wish/plan to use
  • [X] Headings
    • [X] Easy folding & unfolding
  • [X] Fancy table creation & editing
    • [X] Create a table of x columns and y rows
    • [X] Add/remove columns and rows
    • [X] Horizontal navigation through tables (with <Tab>)
    • [X] Vertical navigation through tables (with <CR>?)
    • [X] Table formatting for tables with explicit left-, center-, or right-aligned columns
  • [X] Easily rename file in link
  • [X] Add ability to identify/use any given .bib file in notebook's root directory (if perspective is set to root)
  • [X] Lists
    • [X] To-do list functions & mappings
      • [X] Modify status of parent to-do when changing a child to-do (infer based on tab settings)
    • [X] Smart <CR> when in lists, etc.
  • [X] Full compatibility with Windows
  • [X] "Undo" a link (replace link w/ the text part of the link)
  • [X] Easy forward navigation through buffers (with ~~<S-BS>?~~ <Del>)
  • [X] Allow reference to absolute paths (interpret relatively [following config] if not prepended w/ ~ or /)
  • [X] Allow parentheses in link names (issue #8)
  • [X] Add a config option to wrap to the beginning of the document when navigating between links (11/08/21)

🔧 Recent changes

  • 04/02/23: Updated yank-as-anchor mapping from ya to yaa to prevent interference with yap (yank around paragraph)
  • 03/18/23: Added template functionality for new files
  • 01/14/23: Added support for non-ascii symbols in anchor links (with the luautf8 Luarocks module)
  • 01/05/23: Added + as a valid unordered list or unordered to-do list marker (requested in issue #112)
  • 01/02/23: Automatic links (URLs enclosed in < + > and lacking the usual markdown link syntax that are automatically rendered as links when compiled into HTML) will now be followed
  • 10/08/22: Create links using the system clipboard content as the link's source
  • 10/02/22: Add ability to consider n lines of context around the cursor when following, renaming, or removing links
  • 09/21/22: Add compact option for wiki-link creation
  • 09/21/22: Add support for angle brackets in link sources
  • 09/20/22: Ignore escaped vertical bars when formatting tables
  • 08/19/22: Add yaml parsing and yaml config options; add bib paths found in parsed yaml block to bib sources
  • 08/11/22: Add two new commands (:MkdnNewListItemBelowInsert and :MkdnNewListItemAboveInsert) mapped to o and O by default
  • 08/07/22: Extend link-following, link-jumping, and source editing/moving functionality to reference-style links
  • 07/26/22: Add config option for automatically extending table (col-wise or row-wise) when attempting to jump to the next cell/row while in the last cell/row
  • 07/26/22: Command & mapping for creating bracketed spans (spans assigned an ID attribute)
  • 07/19/22: Update newly-converted (via MkdnToggleToDo/<C-Space>) to-do item's status if it has children
  • 07/13/22: Follow links to arbitrary spans
  • 07/13/22: Individually disable modules
  • 07/09/22: Added folding functionality; replaced default normal/visual-mode mapping with mapping to wrapper function that will fold/open sections
  • 07/01/22: Properly handle alignment markers in tables
  • 07/01/22: Add option not to format table when moving the cursor to a different cell
  • 06/29/22: Conceal links
  • 06/27/22: Added wrapper functions so <Tab> and <S-Tab> can be used in both tables and lists
  • 06/27/22: Added functionality to add new rows and columns
  • 06/17/22: Added functionality to jump rows in tables
  • 06/16/22: Added functionality to format tables and jump cells in tables
  • 06/11/22: Added function and command to insert tables
  • 06/06/22: Extend functionality of MkdnToggleToDo so that it (a) will create a to-do item from a plain list item, and (b) can toggle multiple to-do items selected with simple visual mode
  • 06/04/22: Easily rename files in links (with MkdnMoveSource, mapped to <F2> by default)
  • 06/04/22: Variant of MkdnNewListItem added as MkdnExtendList
  • 06/03/22: Add command and mapping for updating numbering
  • 05/30/22: Implement root directory switching to allow for easier switching between notebooks
  • 05/30/22: Indent new list item when current one ends in a colon
  • 05/12/22: Add functionality to search for bib files in the project's root directory
  • 05/11/22: Customize path text when links are created with a customizable transformation function
  • 05/11/22: Customize link interpretation with a customizable interpretation function (thanks @jmbuhr!)
  • 04/30/22: Customize link style (markdown/wiki; addresses issue #10)
  • 04/30/22: Added functionality to update parent to-dos when child to-do status is changed; customize to-do symbols
  • 04/28/22: Interpret links to markdown files correctly when specified with an absolute path (one starting with / or ~/)
  • 04/28/22: Added ability to follow links to markdown files with an anchor and then jump to the appropriate heading (if one exists)
  • 04/27/22: Add in some list item functionality (not mapped to anything by default yet)
  • 04/26/22: Set command name to false in mappings table to disable mapping
  • 04/25/22: Specify mode in mappings table
  • 04/24/22: User can shut up messages by specifying 'true' in their config under the 'silent' key
  • 04/24/22: Added Windows compatibility!
  • 04/23/22: Major reorganization of followPath() function which ships off some of its old functionality to the new links module and much of it to smaller, path-type-specific functions in the new paths module
  • 04/22/22: Added ability to identify the notebook's root directory by specifying a "tell" in the config (a file that can be used to identify the root)
  • 04/20/22: Added ability to replace a link with just its name (effectively undoing the link) -- mapped to <M-CR> by default (Alt-Enter)
  • 04/20/22: Fix for issue #22
  • 04/19/22: Toggle to-do list item's completion status
  • 04/18/22: If URL is under cursor, make a link from the whole URL (addresses issue #18)
  • 04/16/22: Added forward navigation (~undoing 'back')
  • 04/11/22: Added ability to change heading level
  • 04/05/22: Added ability to create anchor links; jump to matching headings; yank formatted anchor links from headings
  • 04/03/22: Added ability to jump to headings if a link is an anchor link
  • 03/06/22: Added ability to search .bib files and act on relevant information in bib entries when the cursor is in a citation and <CR> is pressed
  • 02/03/22: Fixed case issue w/ file extensions (issue #13)
  • 01/21/22: Path handler can now identify links with the file: prefix that have absolute paths or paths starting with ~/
  • 11/10/21: Merged @pbogut's PR, which modifies require('mkdnflow').buffers.goBack() to return a boolean (true if goBack() succeeds; false if goBack() isn't possible). For the default mappings, this causes no change in behavior, but users who wish <BS> to perform another function in the case that goBack() fails can now use goBack() in the antecedent of a conditional. @pbogut's mapping, for reference:
if not require('mkdnflow').buffers.goBack() then
  vim.cmd('Dirvish %:p')
end
  • 11/08/21: Add option to wrap to beginning/end of file when jumping to next/previous link. Off by default.
  • 11/01/21: Added vimdoc documentation
  • 10/30/21: Added capability for manually starting the plugin with :Mkdnflow, addressing issue #5
  • 09/23/21: Fixed issue #3
  • 09/23/21: Added compatibility with macOS
  • 09/21/21: Fixed issue #1. Implemented a push-down stack to better handle backwards navigation through previously-opened buffers.
  • 09/19/21: Fixed issue #2. Paths with spaces can now be created.

🔗 Links

  • Awesome Neovim's list of (markdown) plugins
  • A more granular list of Neovim plugins

To complement mkdnflow

  • clipboard-image.nvim (Paste links to images in markdown syntax)
  • mdeval.nvim (Evaluate code blocks inside markdown documents)
  • Preview plugins
    • Markdown Preview for (Neo)vim ("Preview markdown on your modern browser with synchronised scrolling and flexible configuration")
    • nvim-markdown-preview ("Markdown preview in the browser using pandoc and live-server through Neovim's job-control API")
    • glow.nvim (Markdown preview using glow—render markdown in Neovim, with pizzazz!)
    • auto-pandoc.nvim ("[...] allows you to easily convert your markdown files using pandoc.")

Alternatives to mkdnflow

  • Vimwiki (Full-featured wiki navigation/maintenance and filetype plugin, written in Vimscript)
  • wiki.vim (A lighter-weight alternative to Vimwiki, written in Vimscript)
  • Neorg (A revised Org-mode for Neovim, written in Lua)
  • follow-md-links.nvim (A simpler plugin for following markdown links, written in Lua)