stevearc / conform.nvim

Lightweight yet powerful formatter plugin for Neovim
MIT License
3.12k stars 163 forks source link

bug: Markdown comments mess up formatting #205

Closed ribru17 closed 11 months ago

ribru17 commented 11 months ago

Neovim version (nvim -v)

NVIM v0.9.4 Build type: Release LuaJIT 2.1.1699392533

Operating system/version

Arch Linux 6.6.1-arch1-1

Add the debug logs

Log file

Log file: /home/rileyb/.local/state/nvim/conform.log ~

      10:25:45[ERROR] Formatter 'prettierd' error: 
      10:25:45[ERROR] Formatter 'prettierd' error: 
      10:25:57[ERROR] Formatter 'prettierd' error: 
      10:25:57[ERROR] Formatter 'prettierd' error: 
      10:26:16[ERROR] Formatter 'prettierd' error: 
      10:26:16[ERROR] Formatter 'prettierd' error: 
      10:38:30[DEBUG] Running formatters on /home/rileyb/Documents/Homework/118cs-hw/6/md.md: { "prettierd", "injected" }
      10:38:30[INFO] Run prettierd on /home/rileyb/Documents/Homework/118cs-hw/6/md.md
      10:38:30[DEBUG] Run command: { "prettierd", "/home/rileyb/Documents/Homework/118cs-hw/6/md.md" }
      10:38:30[DEBUG] prettierd exited with code 0
      10:38:30[INFO] Run injected on /home/rileyb/Documents/Homework/118cs-hw/6/md.md
      10:38:30[DEBUG] Injected format html:3:24: { "prettierd" }
      10:38:30[INFO] Run prettierd on /home/rileyb/Documents/Homework/118cs-hw/6/md.md.html
      10:38:30[DEBUG] Run command: { "prettierd", "/home/rileyb/Documents/Homework/118cs-hw/6/md.md.html" }
      10:38:30[DEBUG] prettierd exited with code 0

Formatters for this buffer: prettierd ready (markdown, html, css) injected ready (markdown)

Other formatters: clang_format ready (cpp, c) deno_fmt ready (javascript, typescript, javascriptreact, typescriptreact, json, jsonc) stylua ready (luau, lua)

Describe the bug

Basically, Markdown comments are treated like HTML injections by the Tree-sitter parser and I believe this causes some issues with the formatter now. This has only started since e2b889e26586acf30dda7b4a5c3f1a063bc18f18. At least with prettierd as an HTML formatter, the Markdown comments will cause paragraphs above them to be joined on the same line with the paragraphs above them (example shown below).

Steps To Reproduce

  1. nvim -u repro.lua example.md
  2. :lua require('conform').format()

Expected Behavior

Expected file formatting:

# Homework 6

<!-- vim: set spell: -->

## Problem 1

> Quote here

<!-- Beginning of first paragraph -->

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Aliquet nec ullamcorper sit amet.
Volutpat diam ut venenatis tellus in. Egestas sed sed risus pretium quam
vulputate dignissim suspendisse. Sapien pellentesque habitant morbi tristique
senectus et netus et malesuada. Eu feugiat pretium nibh ipsum. Convallis aenean
et tortor at risus viverra. Libero volutpat sed cras ornare arcu. Pharetra vel
turpis nunc eget lorem dolor sed viverra. Lacus laoreet non curabitur gravida
arcu ac tortor dignissim. Ut eu sem integer vitae justo eget magna fermentum.
Leo duis ut diam quam nulla porttitor massa id. Purus sit amet volutpat
consequat mauris nunc congue. Eget lorem dolor sed viverra ipsum nunc aliquet
bibendum. Cursus risus at ultrices mi.

- Bullet here

<!-- End of data -->

Actual formatting:

# Homework 6

<!-- vim: set spell: -->

## Problem 1 > Quote here

<!-- Beginning of first paragraph -->

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Aliquet nec ullamcorper sit amet.
Volutpat diam ut venenatis tellus in. Egestas sed sed risus pretium quam
vulputate dignissim suspendisse. Sapien pellentesque habitant morbi tristique
senectus et netus et malesuada. Eu feugiat pretium nibh ipsum. Convallis aenean
et tortor at risus viverra. Libero volutpat sed cras ornare arcu. Pharetra vel
turpis nunc eget lorem dolor sed viverra. Lacus laoreet non curabitur gravida
arcu ac tortor dignissim. Ut eu sem integer vitae justo eget magna fermentum.
Leo duis ut diam quam nulla porttitor massa id. Purus sit amet volutpat
consequat mauris nunc congue. Eget lorem dolor sed viverra ipsum nunc aliquet
bibendum. Cursus risus at ultrices mi. - Bullet here
<!-- End of data -->

Minimal example file

example.md

# Homework 6

<!-- vim: set spell: -->

## Problem 1

> Quote here

<!-- Beginning of first paragraph -->

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Aliquet nec ullamcorper sit amet.
Volutpat diam ut venenatis tellus in. Egestas sed sed risus pretium quam
vulputate dignissim suspendisse. Sapien pellentesque habitant morbi tristique
senectus et netus et malesuada. Eu feugiat pretium nibh ipsum. Convallis aenean
et tortor at risus viverra. Libero volutpat sed cras ornare arcu. Pharetra vel
turpis nunc eget lorem dolor sed viverra. Lacus laoreet non curabitur gravida
arcu ac tortor dignissim. Ut eu sem integer vitae justo eget magna fermentum.
Leo duis ut diam quam nulla porttitor massa id. Purus sit amet volutpat
consequat mauris nunc congue. Eget lorem dolor sed viverra ipsum nunc aliquet
bibendum. Cursus risus at ultrices mi.

- Bullet here

<!-- End of data -->

Minimal init.lua

-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify('./.repro', ':p')

-- set stdpaths to use .repro
for _, name in ipairs { 'config', 'data', 'state', 'cache' } do
  vim.env[('XDG_%s_HOME'):format(name:upper())] = root .. '/' .. name
end

-- bootstrap lazy
local lazypath = root .. '/plugins/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system {
    'git',
    'clone',
    '--filter=blob:none',
    '--single-branch',
    'https://github.com/folke/lazy.nvim.git',
    lazypath,
  }
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  {
    'nvim-treesitter/nvim-treesitter',
    build = ':TSUpdate',
    event = { 'BufReadPost', 'BufNewFile' },
    config = function()
      require('nvim-treesitter.configs').setup {
        ensure_installed = {
          'markdown',
          'html',
          'comment',
        },
        highlight = {
          enable = true,
        },
      }
    end,
  },
  'folke/tokyonight.nvim',
  {
    'stevearc/conform.nvim',
    config = function()
      require('conform').setup {
        log_level = vim.log.levels.DEBUG,
        -- add your config here
        formatters_by_ft = {
          html = { 'prettierd' },
          markdown = { 'prettierd', 'injected' },
        },
      }
    end,
  },
  -- add any other plugins here
}
require('lazy').setup(plugins, {
  root = root .. '/plugins',
})

vim.cmd.colorscheme('tokyonight')
-- add anything else here

Additional context

This only occurs when the injected formatter is also used with a Markdown file, and a formatter is used for HTML files (I have only tested with prettierd). I have observed this issue with prettierd as well as deno_fmt as a Markdown formatter.

stevearc commented 11 months ago

This was a tricky one. I ended up needing to use some private methods in treesitter to get the correct behavior, but it should be working now

ribru17 commented 11 months ago

Thanks so much, it works like a charm, and I've noticed a significant performance improvement for the injected formatter on large md files. Awesome!