

Obsidian-like markdown spacing on headers/lists using autocmds
I use Obsidian for note-taking, but I also use Neovim for a lot of markdown files. My issue's been that I don't like how the markdown files (from Obsidian) look when I open them in Neovim, they're too cluttered and just a huge wall of solid text, and my bulleted lists are too flush against the left.
Simple post, but I love these two autocmds for adding header space and list left-side-padding using virtual text. It makes the Neovim markdown experience feel a lot more like how it looks from the Obsidian editor, with some overall space between sections, without having to change how I use Obsidian. I've still gotta play around, but sign_text could be used to set the '-' symbol for bulleted lists, I wonder if that's probably how some markdown plugins do it. I don't think there's a way to change row height for more/less spacing in a cell.
Images show before and after obsidian markdown file comparison, from within Neovim.
local ns_id = vim.api.nvim_create_namespace("vh_markdown_headers")
local function check_markdown_line_extmark(bufnum, linenum, linestr)
if linestr:match("^#") then
vim.api.nvim_buf_set_extmark(bufnum, ns_id, linenum, 0, {
virt_lines = { {} },
virt_lines_above = true,
})
elseif linestr:match("^- ") or linestr:match("^[ ]*- ") then
vim.api.nvim_buf_set_extmark(bufnum, ns_id, linenum, 0, {
virt_text = { {" ", ""} },
virt_text_pos = "inline",
-- sign_text = "a"
})
end
end
autocmd("Filetype", {
pattern = "markdown",
callback = function(args)
vim.api.nvim_buf_clear_namespace(0, ns_id, 0, -1)
local lines = vim.api.nvim_buf_get_lines(args.buf, 1, -1, false)
for i, line in ipairs(lines) do
check_markdown_line_extmark(args.buf, i, line)
end
end,
})
autocmd({"TextChanged", "InsertLeave"}, {
pattern = "*.md",
callback = function(args)
local curlinenum = vim.api.nvim_win_get_cursor(0)[1]
vim.api.nvim_buf_clear_namespace(0, ns_id, curlinenum-1, curlinenum)
check_markdown_line_extmark(args.buf, curlinenum-1, vim.fn.getline("."))
end,
})