stevearc / conform.nvim

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

question: Changing the `=` button to call prettier via conform? #372

Closed andrei0427 closed 3 months ago

andrei0427 commented 3 months ago

Hi, I'm a new nvim user coming from vscode (with vim bindings) and installed this plugin via the kickstart.nvim project.

Apologies if the answer to this question is obvious; but how do I change the mapping of the = button to call prettier via the plugin to format the selected range?

I checked the docs and other past issues/questions but I couldn't find an answer. It seems that a different formatter altogether is being used when I use =.

I haven't changed any defaults in the default config for conform:

  { -- Autoformat
    'stevearc/conform.nvim',
    lazy = false,
    keys = {
      {
        '<leader>f',
        function()
          require('conform').format { async = true, lsp_fallback = true }
        end,
        mode = '',
        desc = '[F]ormat buffer',
      },
    },
    opts = {
      log_level = vim.log.levels.DEBUG,
      notify_on_error = true,
      format_on_save = function(bufnr)
        -- Disable "format_on_save lsp_fallback" for languages that don't
        -- have a well standardized coding style. You can add additional
        -- languages here or re-enable it for the disabled ones.
        local disable_filetypes = { c = true, cpp = true }
        return {
          timeout_ms = 500,
          lsp_fallback = not disable_filetypes[vim.bo[bufnr].filetype],
        }
      end,
      formatters_by_ft = {
        lua = { 'stylua' },
        -- Conform can also run multiple formatters sequentially
        -- python = { "isort", "black" },
        --
        -- You can use a sub-list to tell conform to run *until* a formatter
        -- is found.
        typescript = { 'prettier' },
        javascript = { 'prettier' },
      },
    },
  },

Thanks!

daniele821 commented 3 months ago

you can, but overwriting a neovim keymap has some consecuences you would have to think about.

You can just use leader+f to format (which you also don't need, as this plugin automatically formats whenever you save your file)

stevearc commented 3 months ago

It's worth learning what the default behavior is and what it's used for. I recommend :help = and :help gq. In brief, = is used to trigger equalprg (a function you define to run on =), or if it's blank, it uses indentexpr (a function you define to set the indent level). gq, on the other hand, usesformatexpr. So=is typically used for setting the indentation, andgqis used to format. There are some notes in the docs for how to use conform as theformatexpr, and if you do that thengqwill perform formatting. If, after all of this, you still want to override=` to do formatting, then you can do so by setting a keymap

vim.keymap.set({ "n", "v" }, "=", function()
  require("conform").format({ async = true, lsp_fallback = true }, function(err)
    if not err then
      -- If we formatted in visual mode, escape to normal mode after formatting
      if vim.startswith(vim.api.nvim_get_mode().mode:lower(), "v") then
        vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<Esc>", true, false, true), "n", true)
      end
    end
  end)
end, { desc = "Format buffer" })
guanghechen commented 3 months ago

Hi @stevearc, I tried the settings you pasted above, it works perfectly on formatting entire buffer content, but once I tried to format a selected range, the behavior of = and gq are different, do you have any clue on it?