conform.nvim icon indicating copy to clipboard operation
conform.nvim copied to clipboard

README/use case: describe how to make ['_'] = { 'trim_whitespace', 'trim_newlines' }, play nice with editorconfig autocommands

Open matu3ba opened this issue 1 year ago • 5 comments

Did you check existing requests?

  • [X] I have searched the existing issues

Describe the feature

Wanted: Extend the configuration in the usage section to some more low level usage, but probably it is simpler to mention 1. combined actions, 2. ['_'] problems:

local fmts_by_ft = {
  c = { 'clang-format' }, -- // clang-format off|on
  ['_'] = { 'trim_whitespace', 'trim_newlines' }, -- <- might make problems behavior for external fmting etc
}

local user_fmts_by_ft = {
  zig = function(args)
    vim.lsp.buf.code_action { context = { only = { 'source.fixAll' } }, apply = true }
    vim.loop.sleep(5)
    -- SHENNANIGAN conform.nvim can screw up formatting the first time
    vim.lsp.buf.format()
  end,
}

vim.api.nvim_create_autocmd('BufWritePre', {
  group = aucmds_conform_fmt,
  pattern = '*',
  callback = function(args)
    local ft = vim.bo[args.buf].filetype
    if fmts_by_ft[ft] == nil then
      if user_fmts_by_ft[ft] ~= nil then
        user_fmts_by_ft[ft]()
      else
        conform.format { bufnr = args.buf, formatters = { 'trim_whitespace', 'trim_newlines' } }
      end
    else
      conform.format { bufnr = args.buf, formatters = { fmts_by_ft[vim.bo[args.buf].filetype] } }
    end
  end,
})

Provide background

Justification: Running one or multiple code actions to autofix code and then the formatter (because formatter might break code for the autofix) prevents trim_whitespace and trim_newlines from being usable.

For example, I have

vim.api.nvim_create_autocmd('BufWritePre', {
  group = aucmds_zig_fmt,
  pattern = { '*.zig', '*.zon' },
  callback = function()
    vim.lsp.buf.code_action {
      -- SHENNANIGAN lsp.CodeActionContext: diagnostics field is optional,
      -- but shown as error by lsp from meta information
      context = { only = { 'source.fixAll' } },
      apply = true,
    }
    vim.loop.sleep(5)
    -- SHENNANIGAN conform.nvim can screw up formatting the first time
    vim.lsp.buf.format()
  end,
})

What is the significance of this feature?

nice to have

Additional details

Going more low level makes things less error prone, if the options '*' and _ or doing lsp actions before formatting (or custom checks) are wanted.

matu3ba avatar Nov 25 '24 20:11 matu3ba

Feel free to close, if you feel like this is out of scope/user responsibility. I'll leave the config for others inspiration, if they want to do something like this.

matu3ba avatar Nov 25 '24 20:11 matu3ba

Currently there is no silent mode for lua autocommand and code_action has neither a silent mode to suppress prompt confirmation.

So one way or the other one has to spam autocommands to workaround that. Ugh.

See also https://github.com/neovim/neovim/pull/22651.

matu3ba avatar Nov 25 '24 22:11 matu3ba

Ok, there is a workaround/hack:

local user_fmts_by_ft = {
  markdown = function() end, -- stub
  supermd = function() end, -- stub
  zig = function(args)
    local original = vim.notify
    ---@diagnostic disable-next-line: duplicate-set-field
    vim.notify = function(msg, level, opts)
      if msg == 'No code actions available' then return end
      original(msg, level, opts)
    end
    vim.lsp.buf.code_action {
      ---@diagnostic disable-next-line: missing-fields
      context = { only = { 'source.fixAll' } },
      apply = true,
    }
    conform.format { bufnr = args.buf, formatters = { fmts_by_ft['zig'] } }
  end,
  --fmts_by_ft[vim.bo[args.buf].filetype]
  zon = function(args) conform.format { bufnr = args.buf, formatters = { fmts_by_ft['zig'] } } end,
}

This is frustrating.

matu3ba avatar Nov 25 '24 22:11 matu3ba

Running one or multiple code actions to autofix code and then the formatter (because formatter might break code for the autofix) prevents trim_whitespace and trim_newlines from being usable

How can formatting the code break it for autofix? And how can performing an autofix code action prevent the trim_whitespace and trim_newlines from working?

stevearc avatar Nov 27 '24 20:11 stevearc

How can formatting the code break it for autofix? And how can performing an autofix code action prevent the trim_whitespace and trim_newlines from working?

Sorry, the cause of the issue was eventually something else: I eventually figured that the existence of a loaded editorconfig can do leading to line fixup at EOF and truncating empty space. After having consistent insert_final_newline = true the weird behavior was gone. Not really sure what was the exact reason though.

See :Telescope autocommands -> BufWritePre -> editorconfig

  • function properties.trim_trailing_whitespace(bufnr, val) ~/.local/nvim/share/nvim/runtime/lua/editorconfig.lua
  • function properties.insert_final_newline(bufnr, val) ~/.local/nvim/share/nvim/runtime/lua/editorconfig.lua

Possible fixes:

    1. detect usage of trim_trailing_whitespace, insert_final_newline in editorconfig on buffer and handle it correctly/fix it up, see lua files how to do it
    1. document the behavior to suggest to user to handle the behavior in https://github.com/stevearc/conform.nvim?tab=readme-ov-file#options

matu3ba avatar Nov 28 '24 20:11 matu3ba