render-markdown.nvim

repository·main·Indexed 26 days ago

https://github.com/meanderingprogrammer/render-markdown.nvim

A Neovim plugin that improves the visual presentation of Markdown files by rendering components such as headings, code blocks, tables, and callouts directly within the editor. It supports LaTeX rendering, paragraph indentation, thematic breaks, and completions for checkboxes and callouts via LSP, coq_nvim, or blink.cmp.

Tokens
18.9K
Snippets
52
Records
60
Agent score
88%

What's inside render-markdown.nvim

  1. Install render-markdown.nvim using packer.nvim

    main

    Add the plugin to your packer.nvim setup. It is recommended to load it after nvim-treesitter.

    use({
        'MeanderingProgrammer/render-markdown.nvim',
        after = { 'nvim-treesitter' },
        requires = { 'nvim-mini/mini.nvim', opt = true },            -- if you use the mini.nvim suite
        -- requires = { 'nvim-mini/mini.icons', opt = true },        -- if you use standalone mini plugins
        -- requires = { 'nvim-tree/nvim-web-devicons', opt = true }, -- if you prefer nvim-web-devicons
        config = function()
            require('render-markdown').setup({})
        end,
    })
  2. Identify plugin compatibility for render-markdown.nvim

    main

    When using render-markdown.nvim, be aware of how other plugins interact with the buffer. Plugins are categorized into three types:

    1. Conflicting Plugins (Avoid using together)

    Plugins that also specialize in rendering the buffer inside Neovim will likely clash and cause undesired behavior. Avoid using:

    • lukas-reineke/headlines.nvim
    • epwalsh/obsidian.nvim (due to its default UI)
    • OXY2DEV/markview.nvim

    2. Browser Preview Plugins (Safe to use)

    Plugins that render markdown in a browser do not interact with the Neovim buffer directly and can be used alongside render-markdown.nvim as a second pass:

    • iamcco/markdown-preview.nvim
    • euclio/vim-markdown-composer

    3. Orthogonal Plugins (Safe to use)

    Plugins that handle functions separate from rendering (like LSP or keybindings) should work without issues:

    • LSPs: marksman (completion, definition, references) or markdown-oxide (Obsidian PKM features).
    • Interaction/Syntax: tadmccorkle/markdown.nvim (keybindings/commands) or preservim/vim-markdown (syntax highlighting/keybindings).
  3. Configure render-markdown.nvim for use with vimwiki

    main

    Because vimwiki overrides the filetype of markdown files, you must perform two additional setup steps to ensure render-markdown.nvim works correctly:

    1. Add vimwiki to the file_types configuration in the plugin setup.
    2. Register markdown as the Treesitter parser for vimwiki files.
    -- 1. Add vimwiki to file_types
    require('render-markdown').setup({
        file_types = { 'markdown', 'vimwiki' },
    })
    
    -- 2. Register markdown parser for vimwiki
    vim.treesitter.language.register('markdown', 'vimwiki')
  4. Requirements for render-markdown.nvim

    main

    Ensure your environment meets the following requirements:

    Core

    • Neovim >= 0.9.0 (minimum) >= 0.10.0 (recommended)
    • Nerd font symbols
    • treesitter parsers:
      • markdown & markdown_inline (Required)
      • html (Optional: for concealing HTML comments)
      • latex (Optional: for rendering LaTeX blocks)
      • yaml (Optional: for rendering frontmatter metadata)

    Optional Dependencies

    • Icon provider: mini.icons or nvim-web-devicons (for code block language icons)
    • LaTeX rendering:
      • libtexprintf (System dependency: transforms LaTeX strings to Unicode via utftex)
      • pylatexenc (Python package: transforms LaTeX strings to Unicode via latex2text)
  5. Configure `latex` formula rendering with external plugins

    main

    By default, latex formula evaluations are placed above text rather than overlaid. To achieve overlaid rendering, disable the built-in latex feature in render-markdown.nvim and use an external plugin like latex.nvim or nabla.nvim.

    Note: These plugins often require a specific conceallevel to function correctly, which must be configured in the win_options of render-markdown.nvim.

    -- Example using latex.nvim
    {
        { 'ryleelyman/latex.nvim', opts = {} },
        {
            'MeanderingProgrammer/render-markdown.nvim',
            dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-mini/mini.nvim' },
            opts = {
                latex = { enabled = false },
                win_options = { conceallevel = { rendered = 2 } },
            },
        },
    }
    
    -- Example using nabla.nvim
    {
        { 'jbyuki/nabla.nvim' },
        {
            'MeanderingProgrammer/render-markdown.nvim',
            dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-mini/mini.nvim' },
            opts = {
                latex = { enabled = false },
                win_options = { conceallevel = { rendered = 2 } },
                on = {
                    render = function()
                        require('nabla').enable_virt({ autogen = true })
                    end,
                    clear = function()
                        require('nabla').disable_virt()
                    end,
                },
            },
        },
    }
  6. Install render-markdown.nvim using vim.pack

    main

    Add the plugin and its dependencies to your vim.pack configuration. You must call .setup({}) if you wish to provide custom options.

    vim.pack.add({
        'https://github.com/nvim-treesitter/nvim-treesitter',
        'https://github.com/nvim-mini/mini.nvim',            -- if you use the mini.nvim suite
        -- 'https://github.com/nvim-mini/mini.icons',        -- if you use standalone mini plugins
        -- 'https://github.com/nvim-tree/nvim-web-devicons', -- if you prefer nvim-web-devicons
        'https://github.com/MeanderingProgrammer/render-markdown.nvim',
    })
    require('render-markdown').setup({}) -- only mandatory if you want to set custom options
  7. Configure render-markdown.nvim to coexist with obsidian.nvim

    main

    Both render-markdown.nvim and obsidian.nvim provide UI functionality. To avoid conflicts, it is recommended to use only one of these plugins for the UI. If you prefer render-markdown.nvim, disable the obsidian.nvim UI in your obsidian configuration.

    require('obsidian').setup({
        ui = { enable = false },
    })
  8. Generate Trace Logs for debugging

    main

    If standard troubleshooting fails, you can generate detailed trace logs to provide in an issue report:

    1. Create a test file: Use a standard markdown file (like the one used for Parse Tree validation).
    2. Update Log Level: Set the log_level to 'trace' in your configuration:
      require('render-markdown').setup({
          log_level = 'trace',
      })
    3. Generate Logs: Restart Neovim and open the test markdown file to trigger the rendering logic, then close Neovim.
    4. Retrieve Logs: Run :RenderMarkdown log to view and copy the log contents.
    require('render-markdown').setup({
        log_level = 'trace',
    })
  9. Mitigate `block` width issues with `colorcolumn` and `cursorline`

    main

    When using { width = 'block' } for heading or code rendering, colorcolumn icons will be hidden on intersecting lines and cursorline will not work. You can improve the aesthetic using one of three methods:

    1. Disable colorcolumn during rendering: This is recommended if colorcolumn is only useful during editing.
    2. Sync min_width with colorcolumn: Set the min_width of the block to match your colorcolumn value.
    3. Use full width: Revert to the default full width instead of block.
    -- Option 1: Disable colorcolumn when rendering
    require('render-markdown').setup({
        win_options = {
            colorcolumn = { default = vim.o.colorcolumn, rendered = '' },
        },
    })
    
    -- Option 2: Set min_width to match colorcolumn
    require('render-markdown').setup({
        heading = { width = 'block', min_width = tonumber(vim.o.colorcolumn) },
        code = { width = 'block', min_width = tonumber(vim.o.colorcolumn) },
    })
    
    -- Option 3: Use 'full' width (default)
    require('render-markdown').setup({
        heading = { width = 'full' },
        code = { width = 'full' },
    })