stevearc / conform.nvim

Lightweight yet powerful formatter plugin for Neovim
MIT License
2.72k stars 142 forks source link

bug: Injected formatter removing necessary white spaces #359

Open mehalter opened 4 months ago

mehalter commented 4 months ago

Neovim version (nvim -v)

NVIM v0.9.5

Operating system/version

Arch Linux

Add the debug logs

Log file

10:22:14[DEBUG] Running formatters on /home/micah/Documents/conform/test.md: { "prettier", "injected" }
10:22:14[INFO] Run prettier on /home/micah/Documents/conform/test.md
10:22:14[TRACE] Input lines: { "<p>", "  Hello World", "</p>", "", "# Test" }
10:22:14[DEBUG] Run command: { "prettier", "--stdin-filepath", "/home/micah/Documents/conform/test.md" }
10:22:14[DEBUG] prettier exited with code 0
10:22:14[TRACE] Output lines: { "<p>", "  Hello World", "</p>", "", "# Test" }
10:22:14[TRACE] prettier stderr: { "" }
10:22:14[INFO] Run injected on /home/micah/Documents/conform/test.md
10:22:14[TRACE] Input lines: { "<p>", "  Hello World", "</p>", "", "# Test" }
10:22:14[TRACE] Injected formatter regions { { "html", 1, 0, 5, 0 } }
10:22:14[DEBUG] Injected format html:1:5: { "prettier" }
10:22:14[TRACE] Injected format lines { "<p>", "  Hello World", "</p>", "", "" }
10:22:14[INFO] Run prettier on /home/micah/Documents/conform/test.md.1.html
10:22:14[TRACE] Input lines: { "<p>", "  Hello World", "</p>", "" }
10:22:14[DEBUG] Run command: { "prettier", "--stdin-filepath", "/home/micah/Documents/conform/test.md.1.html" }
10:22:14[DEBUG] prettier exited with code 0
10:22:14[TRACE] Output lines: { "<p>Hello World</p>" }
10:22:14[TRACE] prettier stderr: { "" }
10:22:14[TRACE] Injected html:1:5 formatted lines { "<p>Hello World</p>" }
10:22:14[TRACE] Applying formatting to /home/micah/Documents/conform/test.md
10:22:14[TRACE] Comparing lines { "<p>", "  Hello World", "</p>", "", "# Test" } and { "<p>Hello World</p>", "# Test" }
10:22:14[TRACE] Diff indices { { 1, 4, 1, 1 } }
10:22:14[TRACE] Applying text edits: { {
    newText = "Hello World</p>",
    range = {
      ["end"] = {
        character = 0,
        line = 3
      },
      start = {
        character = 3,
        line = 0
      }
    }
  } }
10:22:14[TRACE] Done formatting /home/micah/Documents/conform/test.md

Describe the bug

One of the best use cases of the injected formatter is for use with Markdown and markup languages that embed code blocks or intertwine different languages together.

What is the severity of this bug?

breaking (some functionality is broken)

Steps To Reproduce

  1. save the repro.lua and test.md into a folder
  2. nvim -u repro.lua test.md, start up the minimal reproduction environment and open the minimal example file. Wait for plugins to install and treesitter to install the html and markdown parsers
  3. run :InspectTree and see that there is html_block as well as a separate section recognized as markdown
  4. :lua require("conform").format(), run the formatter and see that the white space is clobbered surrounding the HTML code block which breaks the markdown parsing
  5. :InspectTree, Inspect the tree post processing and see that now the entire block without whitespace is considered the html_block because white space is removed.

In larger example files, like if there was a paragraph below the header, continuing to run require("conform").format() will continuously clobber the file since the treesitter parser now considers this new block as "HTML"

Expected Behavior

Injected formatter shouldn't destroy the file and should preserve the white space around the content since white space in a mixed language document is typically very important.

Minimal example file

Hello World

Test

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 = {
  "folke/tokyonight.nvim",
  {
    "stevearc/conform.nvim",
    config = function()
      require("conform").setup {
        log_level = vim.log.levels.TRACE,
        -- add your config here
        formatters_by_ft = {
          ["*"] = { "injected" },
          html = { "prettier" },
          markdown = { "prettier" },
        },
      }
    end,
  },
  -- add any other plugins here
  {
    "nvim-treesitter/nvim-treesitter",
    config = function()
      require("nvim-treesitter.configs").setup {
        ensure_installed = { "markdown", "html" },
      }
    end,
  },
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

vim.cmd.colorscheme "tokyonight"
-- add anything else here

Additional context

No response

kabinspace commented 3 months ago

I have an identical config to @mehalter, and I've been facing the same issue. Version: NVIM v0.9.5 OS: Arch Linux