https://github.com/user-attachments/assets/ae3d2912-65d4-4dd7-a8bb-614c4406c4e3
A highly-customisable & feature rich markdown previewer inside Neovim.
๐ Wiki page | ๐ฎ Usage examples
Markdown renderer,
callouts/alertd
. Supports callout titles too.states
.+
, -
, *
, n.
& n)
)HTML renderer,
LaTeX renderer,
\mathbfit
, \mathcal
, \mathfrak
, \mathbb
, \mathsfbf
, \mathsfit
, \mathsfbfit
, \mathtt
.Others,
Extras,
>=0.10.1
.markdown
, markdown_inline
, html
.Optional,
latex
.nvim-tree/nvim-web-deviconso
.markview.nvim
can be installed via your favourite plugin manager!
[!NOTE] If you have manually installed the parsers then you don't need
nvim-treesitter
. Just make sure the parsers are loaded before this plugin.
[!CAUTION] It is not recommended to lazy load this plugin.
{
"OXY2DEV/markview.nvim",
lazy = false, -- Recommended
-- ft = "markdown" -- If you decide to lazy-load anyway
dependencies = {
"nvim-treesitter/nvim-treesitter",
"nvim-tree/nvim-web-devicons"
}
}
local MiniDeps = require("mini.deps");
MiniDeps.add({
source = "OXY2DEV/markview.nvim",
depends = {
"nvim-treesitter/nvim-treesitter",
"nvim-tree/nvim-web-devicons"
}
});
[!NOTE]
Luarocks
may receive updates a bit later as the release is done after fixing any potential bug(s).
:Rocks install markview.nvim
[!NOTE] Releases may be slow to update as they are done after fixing potential bug(s).
[Current version: v25.0.0]()
[!WARNING]
dev
branch may remain out-dated for an indefinite period of time. It is NOT meant for general use.
New features are usually done on the [dev branch]() first.
So, If you are curious about them, try this branch out!
The configuration table is too large to fit here.
Go check the [wiki page]() or see :h markview.nvim-configuration
.
Here's all the main options,
{
-- Buffer types to ignore
buf_ignore = { "nofile" },
-- Delay, in miliseconds
-- to wait before a redraw occurs(after an event is triggered)
debounce = 50,
-- Filetypes where the plugin is enabled
filetypes = { "markdown", "quarto", "rmd" },
-- Highlight groups to use
-- "dynamic" | "light" | "dark"
highlight_groups = "dynamic",
-- Modes where hybrid mode is enabled
hybrid_modes = nil,
-- Tree-sitter query injections
injections = {},
-- Initial plugin state,
-- true = show preview
-- falss = don't show preview
initial_state = true,
-- Max file size that is rendered entirely
max_file_length = 1000,
-- Modes where preview is shown
modes = { "n", "no", "c" },
-- Lines from the cursor to draw when the
-- file is too big
render_distance = 100,
-- Window configuration for split view
split_conf = {},
-- Rendering related configuration
block_quotes = {},
callbacks = {},
checkboxes = {},
code_blocks = {},
escaped = {},
footnotes = {},
headings = {},
horizontal_rules = {},
html = {},
inline_codes = {},
latex = {},
links = {},
list_items = {},
tables = {}
}
markview.nvim
has a single command :Markview
.
When used without any
subcommands
, it toggles the plugin.
Available subcommands,
[!NOTE] Subcommands that end with
{n}
can also take a buffer id. If a buffer id isn't provided then the current buffer's id is used. Completion for buffer id is also provided by the plugin.
Additional command(s),
MarkOpen
, Opens the link under cursor, falls back to vim.ui.open().
Highlight groups defined by the plugin are given below.
Block quotes
MarkviewBlockQuoteWarn
MarkviewBlockQuoteSpecial
MarkviewBlockQuoteNote
MarkviewBlockQuoteDefault
MarkviewBlockQuoteOk
MarkviewBlockQuoteError
Checkboxes
MarkviewCheckboxCancelled
MarkviewCheckboxChecked
MarkviewCheckboxPending
MarkviewCheckboxProgress
MarkviewCheckboxUnchecked
MarkviewCheckboxStriked
Code blocks & Inline codes
MarkviewInlineCode
MarkviewCodeInfo
MarkviewCode
Code block icons(Internal icon provider)
MarkviewIcon1
MarkviewIcon1Sign
MarkviewIcon1Fg
MarkviewIcon2
MarkviewIcon2Sign
MarkviewIcon2Fg
MarkviewIcon3
MarkviewIcon3Sign
MarkviewIcon3Fg
MarkviewIcon4
MarkviewIcon4Sign
MarkviewIcon4Fg
MarkviewIcon5
MarkviewIcon5Sign
MarkviewIcon5Fg
MarkviewIcon6
MarkviewIcon6Sign
MarkviewIcon6Fg
Headings
MarkviewHeading1Sign
MarkviewHeading1
MarkviewHeading2Sign
MarkviewHeading2
MarkviewHeading3Sign
MarkviewHeading3
MarkviewHeading4Sign
MarkviewHeading4
MarkviewHeading5Sign
MarkviewHeading5
MarkviewHeading6Sign
MarkviewHeading6
Horizontal rules
MarkviewGradient1
MarkviewGradient2
MarkviewGradient3
MarkviewGradient4
MarkviewGradient5
MarkviewGradient6
MarkviewGradient7
MarkviewGradient8
MarkviewGradient9
MarkviewGradient10
LaTeX
MarkviewLatexSubscript
MarkviewLatexSuperscript
List items
MarkviewListItemStar
MarkviewListItemPlus
MarkviewListItemMinus
Links
MarkviewEmail
MarkviewImageLink
MarkviewHyperlink
Tables
MarkviewTableHeader
MarkviewTableBorder
MarkviewTableAlignCenter
MarkviewTableAlignLeft
MarkviewTableAlignRight
Don't forget to check out the wiki!
Hybrid mode can be used by just modifying the hybrid_modes
option.
require("markview").setup({
hybrid_modes = { "n" }
});
[!Tip] You can toggle
hybrid mode
via:Markview hybridToggle
!
You can show previews in a split!
:Markview splitToggle
You can use tree-sitter
injections for folding text!
You first need to modify the fold method and the expression used for folding text.
vim.o.foldmethod = "expr";
vim.o.foldexpr= "nvim_treesitter#foldexpr()";
[!Note] You might want to set this using the
on_enable
callback of the plugin, if you don't want this in other filetypes.
Now, we create a query to fold the headings.
require("markview").setup({
injections = {
languages = {
markdown = {
--- This disables other
--- injected queries!
overwrite = true,
query = [[
(section
(atx_headng) @injections.mkv.fold
(#set! @fold))
]]
}
}
}
});
Here's a bit of explanation on what the text does.
; Matches any section of text that starts with
; a heading.
(section
(atx_headng) @injections.mkv.fold
; This folds the section!
(#set! fold))
Optionally, you can use a foldtext plugin tp change what is shown! For example, I can use foldtext.nvim for this.
local def = require("foldtext").configuration;
local handler = function (_, buf)
local ln = table.concat(vim.fn.getbufline(buf, vim.v.foldstart));
local markers = ln:match("^%s*([#]+)");
local heading_txt = ln:match("^%s*[#]+(.+)$");
local icons = {
"๓ฐค", "๓ฐฉ", "๓ฐช", "๓ฐฎ", "๓ฐฑ", "๓ฐต"
}
return {
icons[vim.fn.strchars(markers or "")] .. heading_txt,
"MarkviewHeading" .. vim.fn.strchars(markers or "");
}
end
local spaces = function (_, buf)
local ln = table.concat(vim.fn.getbufline(buf, vim.v.foldstart));
local markers = ln:match("^%s*([#]+)");
local heading_txt = ln:match("^%s*[#]+(.+)$");
return {
string.rep(" ", vim.o.columns - vim.fn.strchars(heading_txt) - 1),
"MarkviewHeading" .. vim.fn.strchars(markers or "");
}
end
require("foldtext").setup({
custom = vim.list_extend(def, {
{
ft = { "markdown" },
config = {
{ type = "indent" },
{
type = "custom",
handler = handler
},
{
type = "custom",
handler = spaces
}
}
}
});
});