u/Vova____

Image 1 — Obsidian-like markdown spacing on headers/lists using autocmds
Image 2 — Obsidian-like markdown spacing on headers/lists using autocmds
▲ 13 r/neovim

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,
})
u/Vova____ — 15 hours ago