Giter VIP home page Giter VIP logo

conform.nvim's Introduction

conform.nvim

Lightweight yet powerful formatter plugin for Neovim

Requirements

  • Neovim 0.8+

Features

  • Preserves extmarks and folds - Most formatters replace the entire buffer, which clobbers extmarks and folds, and can cause the viewport and cursor to jump unexpectedly. Conform calculates minimal diffs and applies them using the built-in LSP format utilities.
  • Fixes bad-behaving LSP formatters - Some LSP servers are lazy and simply replace the entire buffer, leading to the problems mentioned above. Conform hooks into the LSP handler and turns these responses into proper piecewise changes.
  • Enables range formatting for all formatters - Since conform calculates minimal diffs, it can perform range formatting even if the underlying formatter doesn't support it.
  • Simple API - Conform exposes a simple, imperative API modeled after vim.lsp.buf.format().
  • Formats embedded code blocks - Can format code blocks inside markdown files or similar (see injected language formatting)

Installation

conform.nvim supports all the usual plugin managers

lazy.nvim
{
  'stevearc/conform.nvim',
  opts = {},
}

For a more thorough configuration involving lazy-loading, see Lazy loading with lazy.nvim.

Packer
require("packer").startup(function()
  use({
    "stevearc/conform.nvim",
    config = function()
      require("conform").setup()
    end,
  })
end)
Paq
require("paq")({
  { "stevearc/conform.nvim" },
})
vim-plug
Plug 'stevearc/conform.nvim'
dein
call dein#add('stevearc/conform.nvim')
Pathogen
git clone --depth=1 https://github.com/stevearc/conform.nvim.git ~/.vim/bundle/
Neovim native package
git clone --depth=1 https://github.com/stevearc/conform.nvim.git \
  "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/pack/conform/start/conform.nvim

Setup

At a minimum, you will need to set up some formatters by filetype

require("conform").setup({
  formatters_by_ft = {
    lua = { "stylua" },
    -- Conform will run multiple formatters sequentially
    python = { "isort", "black" },
    -- Use a sub-list to run only the first available formatter
    javascript = { { "prettierd", "prettier" } },
  },
})

Then you can use conform.format() just like you would vim.lsp.buf.format(). For example, to format on save:

vim.api.nvim_create_autocmd("BufWritePre", {
  pattern = "*",
  callback = function(args)
    require("conform").format({ bufnr = args.buf })
  end,
})

As a shortcut, conform will optionally set up this format-on-save autocmd for you

require("conform").setup({
  format_on_save = {
    -- These options will be passed to conform.format()
    timeout_ms = 500,
    lsp_fallback = true,
  },
})

See conform.format() for more details about the parameters.

Conform also provides a formatexpr, same as the LSP client:

vim.o.formatexpr = "v:lua.require'conform'.formatexpr()"

To view configured and available formatters, as well as to see the log file, run :ConformInfo

Formatters

You can view this list in vim with :help conform-formatters

Expand to see all formatters
  • alejandra - The Uncompromising Nix Code Formatter.
  • asmfmt - Go Assembler Formatter
  • ast-grep - A CLI tool for code structural search, lint and rewriting. Written in Rust.
  • astyle - A Free, Fast, and Small Automatic Formatter for C, C++, C++/CLI, Objective-C, C#, and Java Source Code.
  • auto_optional - Adds the Optional type-hint to arguments where the default value is None.
  • autocorrect - A linter and formatter to help you to improve copywriting, correct spaces, words, and punctuations between CJK.
  • autoflake - Removes unused imports and unused variables as reported by pyflakes.
  • autopep8 - A tool that automatically formats Python code to conform to the PEP 8 style guide.
  • awk - Format awk programs with awk
  • bean-format - Reformat Beancount files to right-align all the numbers at the same, minimal column.
  • beautysh - A Bash beautifier for the masses.
  • bibtex-tidy - Cleaner and Formatter for BibTeX files.
  • bicep - Bicep is a Domain Specific Language (DSL) for deploying Azure resources declaratively.
  • biome - A toolchain for web projects, aimed to provide functionalities to maintain them.
  • biome-check - A toolchain for web projects, aimed to provide functionalities to maintain them.
  • black - The uncompromising Python code formatter.
  • blade-formatter - An opinionated blade template formatter for Laravel that respects readability.
  • blue - The slightly less uncompromising Python code formatter.
  • buf - A new way of working with Protocol Buffers.
  • buildifier - buildifier is a tool for formatting bazel BUILD and .bzl files with a standard convention.
  • cabal_fmt - Format cabal files with cabal-fmt
  • cbfmt - A tool to format codeblocks inside markdown and org documents.
  • clang-format - Tool to format C/C++/… code according to a set of rules and heuristics.
  • cljstyle - Formatter for Clojure code.
  • cmake_format - Parse cmake listfiles and format them nicely.
  • codespell - Check code for common misspellings.
  • crystal - Format Crystal code.
  • csharpier - The opinionated C# code formatter.
  • cue_fmt - Format CUE files using cue fmt command.
  • darker - Run black only on changed lines.
  • dart_format - Replace the whitespace in your program with formatting that follows Dart guidelines.
  • deno_fmt - Use Deno to format TypeScript, JavaScript/JSON and markdown.
  • dfmt - Formatter for D source code.
  • djlint - ✨ HTML Template Linter and Formatter. Django - Jinja - Nunjucks - Handlebars - GoLang.
  • dprint - Pluggable and configurable code formatting platform written in Rust.
  • easy-coding-standard - ecs - Use Coding Standard with 0-knowledge of PHP-CS-Fixer and PHP_CodeSniffer.
  • elm_format - elm-format formats Elm source code according to a standard set of rules based on the official Elm Style Guide.
  • erb_format - Format ERB files with speed and precision.
  • eslint_d - Like ESLint, but faster.
  • fantomas - F# source code formatter.
  • fish_indent - Indent or otherwise prettify a piece of fish code.
  • fixjson - JSON Fixer for Humans using (relaxed) JSON5.
  • fnlfmt - A formatter for Fennel code.
  • fourmolu - Fourmolu is a formatter for Haskell source code.
  • gci - GCI, a tool that controls Go package import order and makes it always deterministic.
  • gdformat - A formatter for Godot's gdscript.
  • gersemi - A formatter to make your CMake code the real treasure.
  • gleam - ⭐️ A friendly language for building type-safe, scalable systems!
  • gn - gn build system.
  • gofmt - Formats go programs.
  • gofumpt - Enforce a stricter format than gofmt, while being backwards compatible. That is, gofumpt is happy with a subset of the formats that gofmt is happy with.
  • goimports - Updates your Go import lines, adding missing ones and removing unreferenced ones.
  • goimports-reviser - Right imports sorting & code formatting tool (goimports alternative).
  • golines - A golang formatter that fixes long lines.
  • google-java-format - Reformats Java source code according to Google Java Style.
  • htmlbeautifier - A normaliser/beautifier for HTML that also understands embedded Ruby. Ideal for tidying up Rails templates.
  • indent - GNU Indent.
  • injected - Format treesitter injected languages.
  • inko - A language for building concurrent software with confidence
  • isort - Python utility / library to sort imports alphabetically and automatically separate them into sections and by type.
  • joker - Small Clojure interpreter, linter and formatter.
  • jq - Command-line JSON processor.
  • jsonnetfmt - jsonnetfmt is a command line tool to format jsonnet files.
  • just - Format Justfile.
  • ktlint - An anti-bikeshedding Kotlin linter with built-in formatter.
  • latexindent - A perl script for formatting LaTeX files that is generally included in major TeX distributions.
  • liquidsoap-prettier - A binary to format Liquidsoap scripts
  • markdown-toc - API and CLI for generating a markdown TOC (table of contents) for a README or any markdown files.
  • markdownlint - A Node.js style checker and lint tool for Markdown/CommonMark files.
  • markdownlint-cli2 - A fast, flexible, configuration-based command-line interface for linting Markdown/CommonMark files with the markdownlint library.
  • mdformat - An opinionated Markdown formatter.
  • mdsf - Format markdown code blocks using your favorite code formatters.
  • mdslw - Prepare your markdown for easy diff'ing by adding line breaks after every sentence.
  • mix - Format Elixir files using the mix format command.
  • nimpretty - nimpretty is a Nim source code beautifier that follows the official style guide.
  • nixfmt - nixfmt is a formatter for Nix code, intended to apply a uniform style.
  • nixpkgs_fmt - nixpkgs-fmt is a Nix code formatter for nixpkgs.
  • ocamlformat - Auto-formatter for OCaml code.
  • ocp-indent - Automatic indentation of OCaml source files.
  • opa_fmt - Format Rego files using opa fmt command.
  • packer_fmt - The packer fmt Packer command is used to format HCL2 configuration files to a canonical format and style.
  • pangu - Insert whitespace between CJK and half-width characters.
  • perlimports - Make implicit Perl imports explicit.
  • perltidy - Perl::Tidy, a source code formatter for Perl.
  • pg_format - PostgreSQL SQL syntax beautifier.
  • php_cs_fixer - The PHP Coding Standards Fixer.
  • phpcbf - PHP Code Beautifier and Fixer fixes violations of a defined coding standard.
  • phpinsights - The perfect starting point to analyze the code quality of your PHP projects.
  • pint - Laravel Pint is an opinionated PHP code style fixer for minimalists.
  • prettier - Prettier is an opinionated code formatter. It enforces a consistent style by parsing your code and re-printing it with its own rules that take the maximum line length into account, wrapping code when necessary.
  • prettierd - prettier, as a daemon, for ludicrous formatting speed.
  • pretty-php - The opinionated PHP code formatter.
  • puppet-lint - Check that your Puppet manifests conform to the style guide.
  • purs-tidy - A syntax tidy-upper for PureScript.
  • reorder-python-imports - Rewrites source to reorder python imports
  • rescript-format - The built-in ReScript formatter.
  • roc - A fast, friendly, functional language.
  • rubocop - Ruby static code analyzer and formatter, based on the community Ruby style guide.
  • rubyfmt - Ruby Autoformatter! (Written in Rust)
  • ruff_fix - An extremely fast Python linter, written in Rust. Fix lint errors.
  • ruff_format - An extremely fast Python linter, written in Rust. Formatter subcommand.
  • rufo - Rufo is an opinionated ruby formatter.
  • rustfmt - A tool for formatting rust code according to style guidelines.
  • rustywind - A tool for formatting Tailwind CSS classes.
  • scalafmt - Code formatter for Scala.
  • shellcheck - A static analysis tool for shell scripts.
  • shellharden - The corrective bash syntax highlighter.
  • shfmt - A shell parser, formatter, and interpreter with bash support.
  • smlfmt - A custom parser and code formatter for Standard ML.
  • sql_formatter - A whitespace formatter for different query languages.
  • sqlfluff - A modular SQL linter and auto-formatter with support for multiple dialects and templated code.
  • sqlfmt - sqlfmt formats your dbt SQL files so you don't have to. It is similar in nature to Black, gofmt, and rustfmt (but for SQL)
  • squeeze_blanks - Squeeze repeated blank lines into a single blank line via cat -s.
  • standardjs - JavaScript Standard style guide, linter, and formatter.
  • standardrb - Ruby's bikeshed-proof linter and formatter.
  • stylelint - A mighty CSS linter that helps you avoid errors and enforce conventions.
  • styler - R formatter and linter.
  • stylua - An opinionated code formatter for Lua.
  • swift_format - Swift formatter from apple. Requires building from source with swift build.
  • swiftformat - SwiftFormat is a code library and command-line tool for reformatting swift code on macOS or Linux.
  • taplo - A TOML toolkit written in Rust.
  • templ - Formats templ template files.
  • terraform_fmt - The terraform-fmt command rewrites terraform configuration files to a canonical format and style.
  • terragrunt_hclfmt - Format hcl files into a canonical format.
  • tlint - Tighten linter for Laravel conventions with support for auto-formatting.
  • tofu_fmt - The tofu-fmt command rewrites OpenTofu configuration files to a canonical format and style.
  • trim_newlines - Trim new lines with awk.
  • trim_whitespace - Trim whitespaces with awk.
  • twig-cs-fixer - Automatically fix Twig Coding Standards issues
  • typos - Source code spell checker
  • typstfmt - Basic formatter for the Typst language with a future!
  • uncrustify - A source code beautifier for C, C++, C#, ObjectiveC, D, Java, Pawn and Vala.
  • usort - Safe, minimal import sorting for Python projects.
  • xmlformat - xmlformatter is an Open Source Python package, which provides formatting of XML documents.
  • xmllint - Despite the name, xmllint can be used to format XML files as well as lint them.
  • yamlfix - A configurable YAML formatter that keeps comments.
  • yamlfmt - yamlfmt is an extensible command line tool or library to format yaml files.
  • yapf - Yet Another Python Formatter.
  • yq - YAML/JSON processor
  • zigfmt - Reformat Zig source into canonical form.
  • zprint - Formatter for Clojure and EDN.

Customizing formatters

You can override/add to the default values of formatters

require("conform").setup({
  formatters = {
    yamlfix = {
      -- Change where to find the command
      command = "local/path/yamlfix",
      -- Adds environment args to the yamlfix formatter
      env = {
        YAMLFIX_SEQUENCE_STYLE = "block_style",
      },
    },
  },
})

-- These can also be set directly
require("conform").formatters.yamlfix = {
  env = {
    YAMLFIX_SEQUENCE_STYLE = "block_style",
  },
}

-- This can also be a function that returns the config,
-- which can be useful if you're doing lazy loading
require("conform").formatters.yamlfix = function(bufnr)
  return {
    command = require("conform.util").find_executable({
      "local/path/yamlfix",
    }, "yamlfix"),
  }
end

In addition to being able to override any of the original properties on the formatter, there is another property for easily adding additional arguments to the format command

require("conform").formatters.shfmt = {
  prepend_args = { "-i", "2" },
  -- The base args are { "-filename", "$FILENAME" } so the final args will be
  -- { "-i", "2", "-filename", "$FILENAME" }
}
-- prepend_args can be a function, just like args
require("conform").formatters.shfmt = {
  prepend_args = function(self, ctx)
    return { "-i", "2" }
  end,
}

If you want to overwrite the entire formatter definition and not merge with the default values, pass inherit = false. This is also the default behavior if there is no built-in formatter with the given name, which can be used to add your own custom formatters.

require("conform").formatters.shfmt = {
  inherit = false,
  command = "shfmt",
  args = { "-i", "2", "-filename", "$FILENAME" },
}

Recipes

Advanced topics

Options

A complete list of all configuration options

require("conform").setup({
  -- Map of filetype to formatters
  formatters_by_ft = {
    lua = { "stylua" },
    -- Conform will run multiple formatters sequentially
    go = { "goimports", "gofmt" },
    -- Use a sub-list to run only the first available formatter
    javascript = { { "prettierd", "prettier" } },
    -- You can use a function here to determine the formatters dynamically
    python = function(bufnr)
      if require("conform").get_formatter_info("ruff_format", bufnr).available then
        return { "ruff_format" }
      else
        return { "isort", "black" }
      end
    end,
    -- Use the "*" filetype to run formatters on all filetypes.
    ["*"] = { "codespell" },
    -- Use the "_" filetype to run formatters on filetypes that don't
    -- have other formatters configured.
    ["_"] = { "trim_whitespace" },
  },
  -- If this is set, Conform will run the formatter on save.
  -- It will pass the table to conform.format().
  -- This can also be a function that returns the table.
  format_on_save = {
    -- I recommend these options. See :help conform.format for details.
    lsp_fallback = true,
    timeout_ms = 500,
  },
  -- If this is set, Conform will run the formatter asynchronously after save.
  -- It will pass the table to conform.format().
  -- This can also be a function that returns the table.
  format_after_save = {
    lsp_fallback = true,
  },
  -- Set the log level. Use `:ConformInfo` to see the location of the log file.
  log_level = vim.log.levels.ERROR,
  -- Conform will notify you when a formatter errors
  notify_on_error = true,
  -- Custom formatters and changes to built-in formatters
  formatters = {
    my_formatter = {
      -- This can be a string or a function that returns a string.
      -- When defining a new formatter, this is the only field that is required
      command = "my_cmd",
      -- A list of strings, or a function that returns a list of strings
      -- Return a single string instead of a list to run the command in a shell
      args = { "--stdin-from-filename", "$FILENAME" },
      -- If the formatter supports range formatting, create the range arguments here
      range_args = function(ctx)
        return { "--line-start", ctx.range.start[1], "--line-end", ctx.range["end"][1] }
      end,
      -- Send file contents to stdin, read new contents from stdout (default true)
      -- When false, will create a temp file (will appear in "$FILENAME" args). The temp
      -- file is assumed to be modified in-place by the format command.
      stdin = true,
      -- A function that calculates the directory to run the command in
      cwd = require("conform.util").root_file({ ".editorconfig", "package.json" }),
      -- When cwd is not found, don't run the formatter (default false)
      require_cwd = true,
      -- When stdin=false, use this template to generate the temporary file that gets formatted
      tmpfile_format = ".conform.$RANDOM.$FILENAME",
      -- When returns false, the formatter will not be used
      condition = function(ctx)
        return vim.fs.basename(ctx.filename) ~= "README.md"
      end,
      -- Exit codes that indicate success (default { 0 })
      exit_codes = { 0, 1 },
      -- Environment variables. This can also be a function that returns a table.
      env = {
        VAR = "value",
      },
      -- Set to false to disable merging the config with the base definition
      inherit = true,
      -- When inherit = true, add these additional arguments to the command.
      -- This can also be a function, like args
      prepend_args = { "--use-tabs" },
    },
    -- These can also be a function that returns the formatter
    other_formatter = function(bufnr)
      return {
        command = "my_cmd",
      }
    end,
  },
})

-- You can set formatters_by_ft and formatters directly
require("conform").formatters_by_ft.lua = { "stylua" }
require("conform").formatters.my_formatter = {
  command = "my_cmd",
}

Formatter options

API

format(opts, callback)

format(opts, callback): boolean
Format a buffer

Param Type Desc
opts nil|table
timeout_ms nil|integer Time in milliseconds to block for formatting. Defaults to 1000. No effect if async = true.
bufnr nil|integer Format this buffer (default 0)
async nil|boolean If true the method won't block. Defaults to false. If the buffer is modified before the formatter completes, the formatting will be discarded.
dry_run nil|boolean If true don't apply formatting changes to the buffer
formatters nil|string[] List of formatters to run. Defaults to all formatters for the buffer filetype.
lsp_fallback nil|boolean|"always" Attempt LSP formatting if no formatters are available. Defaults to false. If "always", will attempt LSP formatting even if formatters are available.
quiet nil|boolean Don't show any notifications for warnings or failures. Defaults to false.
range nil|table Range to format. Table must contain start and end keys with {row, col} tuples using (1,0) indexing. Defaults to current selection in visual mode
id nil|integer Passed to vim.lsp.buf.format when lsp_fallback = true
name nil|string Passed to vim.lsp.buf.format when lsp_fallback = true
filter nil|fun(client: table): boolean Passed to vim.lsp.buf.format when lsp_fallback = true
callback nil|fun(err: nil|string, did_edit: nil|boolean) Called once formatting has completed

Returns:

Type Desc
boolean True if any formatters were attempted

list_formatters(bufnr)

list_formatters(bufnr): conform.FormatterInfo[]
Retrieve the available formatters for a buffer

Param Type Desc
bufnr nil|integer

list_all_formatters()

list_all_formatters(): conform.FormatterInfo[]
List information about all filetype-configured formatters

get_formatter_info(formatter, bufnr)

get_formatter_info(formatter, bufnr): conform.FormatterInfo
Get information about a formatter (including availability)

Param Type Desc
formatter string The name of the formatter
bufnr nil|integer

will_fallback_lsp(options)

will_fallback_lsp(options): boolean
Check if the buffer will use LSP formatting when lsp_fallback = true

Param Type Desc
options nil|table Options passed to vim.lsp.buf.format

Acknowledgements

Thanks to

  • nvim-lint for providing inspiration for the config and API. It's an excellent plugin that balances power and simplicity.
  • null-ls for formatter configurations and being my formatter/linter of choice for a long time.

conform.nvim's People

Contributors

azzamsa avatar cesconix avatar chrisgrieser avatar fbuchlak avatar folliehiyuki avatar github-actions[bot] avatar hougesen avatar isaksamsten avatar leiserfg avatar mattiasmts avatar mehalter avatar ndavd avatar nickhu avatar nitestack avatar petobens avatar pjg avatar razziel89 avatar reegnz avatar ribru17 avatar rishabh672003 avatar rnprest avatar scottmckendry avatar sebastianselander avatar shurizzle avatar stefanvanburen avatar stevearc avatar thimc avatar whoissethdaniel avatar z775729168 avatar zbindenren avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

conform.nvim's Issues

Feature request: toggling auto-format

Format-on-save is very useful, but it can be frustrating when working in projects without formatter configs, as I end up messing up the formatting or needing to use noautocmd write to avoid triggering auto-format. Would be nice to have user commands to enable and disable auto-format, similar to lsp-format which has FormatDisable/FormatEnable/FormatToggle. I am open to contributing a PR for this, just figured I'd open an issue first to see if there's interest.

How to pass ENV to existing formatters

I am using yamlfix to format yaml, but I would like to use block_style for lists, for this I need to set this env:

export YAMLFIX_SEQUENCE_STYLE="block_style"

I am using this code:

local M = {
    "stevearc/conform.nvim",
    event = "VeryLazy"
}

M.keys = {
    {
        "<leader>ff",
        function()
            require("conform").format({
                lsp_fallback = true
            })
        end
    }
}

M.config = function()
    require("conform").setup({
        log_level = vim.log.levels.DEBUG,
        format_on_save = {
            timeout_ms = 500,
            lsp_fallback = true
        },
        formatters_by_ft = {
            lua = {
                "lua"
            },
            json = {
                "json"
            },
            sh = {
                "shfmt",
                "shellharden"
            },
            yaml = {
                "yamlfix"
            }

        },
        formatters = {
            lua = {
                command = "lua-format",
                args = {
                    "--break-after-table-lb",
                    "--chop-down-table",
                    "--column-table-limit=1",
                    "--no-keep-simple-function-one-line"
                }
            },
            json = {
                command = "jq",
                args = {
                    "--indent",
                    "2"
                }
            }
        }
    })
end

return M

I tried adding yamlfix to the formaters to overwrite the defaults:

...
yamlfix ={
    env ={
        YAMLFIX_SEQUENCE_STYLE = "block_style"
    }
}

It didn't work since it need the command but after adding it it is not using the default, therefore wondering if there is an easy way to just append/pass args/ENV to the default formatters?

bug: Selection formatting doesn't work as expected with fallback LSP

Neovim version (nvim -v)

NVIM v0.8.3

Operating system/version

MacOS 13.5.2

Output of :ConformInfo

Log file: /Users/Jedrzej/.local/state/nvim/conform.log

Formatters for this buffer:
LSP: clangd

Other formatters:

Describe the bug

I tried following this example to set up the formatting of selection: #40

The selection formatting with require("conform").format({ async = true, lsp_fallback = true }) doesn't work as expected with LSP fallback formatting clangd - the whole file is being formatted instead of just the selection and the visual mode stays active. The formatting of the selection works fine though with the other solution: Format user command suggested in the same post.

Steps To Reproduce

  1. nvim -u repro.lua example.cpp
  2. select some lines
  3. press space -> f
  4. whole file is being reformatted instead of just selection <--- not expected
  5. undo with u
  6. select some line
  7. run :Format
  8. only the selected lines are being formatted <--- as expected

Expected Behavior

In both cases the selection formatting works as expected as suggested in the post #40

Minimal example file

       #include <iostream>

    int main() {
  int test = 123;
     std::cout << "Hello World!" << test << std::endl;
      return 0;
}

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.DEBUG,
      })
    end,
  },
  {
    {'VonHeikemen/lsp-zero.nvim', branch = 'v3.x'},

    -- LSP Support
    {'neovim/nvim-lspconfig'},
    {'williamboman/mason.nvim'},
    {'williamboman/mason-lspconfig.nvim'},

    -- Autocompletion
    {'hrsh7th/nvim-cmp'},
    {'hrsh7th/cmp-nvim-lsp'},
    {'L3MON4D3/LuaSnip'},
  },
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

vim.cmd.colorscheme("tokyonight")

-- add anything else here

-- set up Format and <leader>f commands which should behave equivalently
vim.api.nvim_create_user_command("Format", function(args)
  local range = nil
  if args.count ~= -1 then
    local end_line = vim.api.nvim_buf_get_lines(0, args.line2 - 1, args.line2, true)[1]
    range = {
      start = { args.line1, 0 },
      ["end"] = { args.line2, end_line:len() },
    }
  end
  require("conform").format({ async = true, lsp_fallback = true, range = range })
end, { range = true })
vim.keymap.set('', '<leader>f', function ()
  require("conform").format({async = true, lsp_fallback = true })
end)

-- set up LSP with clangd

local lsp_zero = require('lsp-zero')
lsp_zero.on_attach(function(client, bufnr)
  lsp_zero.default_keymaps({buffer = bufnr})
end)

require('mason').setup({})
require('mason-lspconfig').setup({
  ensure_installed = {'clangd'},
  handlers = {
    lsp_zero.default_setup,
    lua_ls = function()
      local lua_opts = lsp_zero.nvim_lua_ls()
      require('lspconfig').lua_ls.setup(lua_opts)
    end,
  }
})

local cmp = require('cmp')
local cmp_format = lsp_zero.cmp_format()

cmp.setup({
  formatting = cmp_format
})

Additional context

I tried fixing the issue but am not versatile in neovim API. If there is an easy workaround that would help too! The problem is that even setting something like:

vim.keymap.set('', '<leader>F', "<cmd>Format<cr>")

results in the unexpected behavior with selection formatting, but if I manually type :Format everything works as expected.

feature: lsp formatters per filetype

Hi!

First of all thank you for this great plugin. I'm enjoying it quite a bit.

There currently is the option to use lsp as a fallback, but it's not possible to easily configure this per filetype.

Would be great if something like the below would be possible.

formatters_by_ft = {
  go = { "goimports", "lsp" }, -- runs goimports and all lsp formatters
},
formatters_by_ft = {
  go = { "goimports", "lsp:gopls" }, -- runs goimports and all only the gopls lsp formatter
},

bug: formatting with lua-language-server rewrites the whole buffer

Neovim version (nvim -v)

0.9.2

Operating system/version

arch linux

Add the debug logs

  • I have set log_level = vim.log.levels.DEBUG and pasted the log contents below.

Log file

17:45:28[DEBUG] Running LSP formatter on /home/rawal/.config/nvim/lua/user/plugins.lua
17:45:32[DEBUG] Running LSP formatter on /home/rawal/.config/nvim/lua/user/plugins.lua

Describe the bug

same

Steps To Reproduce

  1. install lua language server
  2. format with lsp_fallback = true
  3. the whole buffer is written, even if there's no change

Expected Behavior

only formatted lines should have been written

Minimal example file

No response

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.DEBUG,
        -- add your config here
      })
    end,
  },
  -- add any other plugins here
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

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

Additional context

this issue does not happen with clangd

Question: How might you configure `prettier` differently for `javascript` & `yaml` without conflicts?

I'm curious how I would configure prettier to behave exclusively with yaml files. I'd like to add the arg: --no-bracket-spacing but only when prettier is working with yaml files.

The reason being yamllint defines a rule that specifies whether or not spaces are permissible inside brackets.

rules:
  brackets:
    forbid: false
    min-spaces-inside: 0
    max-spaces-inside: 0
    min-spaces-inside-empty: -1
    max-spaces-inside-empty: -1

Something like...

formatters = {
  prettier_yaml = require("conform.formatters.prettier")
}

...perhaps?

bug: incorrect range formatting with stylua

Neovim version (nvim -v)

NVIM v0.10.0-dev-1240+g9afbfb4d64

Operating system/version

Arch Linux

Output of :ConformInfo

~ │Formatters for this buffer:                                                                                                                                                                                    │
~ │stylua ready (lua)                                                                                                                                                                                             │

Describe the bug

Range formatting doesn't seem to work properly (at least with stylua)

Steps To Reproduce

  1. Open nvim with the minimal init.lua file
  2. Open a foo.lua file with
local x=2
local y=3
local z=4
  1. Select 2 lines as in the GIF and press ,fc
  2. Those 2 lines don't get properly formatted

Expected Behavior

After 4. get proper formatting (spaces around equal sign) for visually selected lines.

Minimal example file

No response

Minimal init.lua

local root = '/tmp/nvim-minimal'

-- Set stdpaths to use root dir
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 and configure plugins
local plugins = {
    {
        'stevearc/conform.nvim',
        config = function()
            vim.o.formatexpr = [[v:lua.require('conform').formatexpr()]]
            require('conform').setup({
                format_on_save = {
                    timeout_ms = 200,
                    lsp_fallback = false,
                },
                notify_on_error = false,
                formatters_by_ft = {
                    lua = { 'stylua' },
                },
            })
            vim.keymap.set({ 'n', 'v' }, ',fc', function()
                require('conform').format({ async = true, lsp_fallback = false })
            end)
        end,
    },
}
require('lazy').setup(plugins, {
    root = root .. '/plugins',
})

Additional context

conformvisual

How to format on save when using ":x"

Hi, first of all, many thanks for sharing and all your time on this, I have been struggling to find a plugin to format, and fortunately just found conform I am using it as a replacement for null-ls and so far working pretty good, but I don't know if I have more a configuration issue or bug when trying to exit using :x the file is not formatted, if I use :w or exit with :wq the file gets formatted, also I have an alias <leader>ff to format and works fine, attached is my current configuration:

local M = {
    "stevearc/conform.nvim",
     event = "VeryLazy"
}

M.keys = {
    {
        "<leader>ff",
        function()
            require("conform").format({
                lsp_fallback = true
            })
        end
    }
}

M.config = function()
    require("conform").setup({
        log_level = vim.log.levels.DEBUG,
        format_on_save = {
            timeout_ms = 500,
            lsp_fallback = true
        },
        formatters_by_ft = {
            lua = {
                "lua"
            },
            json = {
                "json"
            }

        },
        formatters = {
            lua = {
                command = "lua-format",
                args = {
                    "--break-after-table-lb",
                    "--chop-down-table",
                    "--column-table-limit=1",
                    "--no-keep-simple-function-one-line"
                }
            },
            json = {
                command = "jq",
                args = {
                    "--indent",
                    "2"
                }
            }
        }
    })
end

return M

Any ideas?

feature: easier configuration

LazyVim uses conform.nvim for formatting.

To make configuration easier, we added some extra options to conform.nvim:

  • opts.format: default options used by require("conform").format()
  • opts.formatters: instead of just adding new formatters, you can also override the default options for any formatter
  • opts.formatters[NAME].extra_args: extra arguments passed to the formatter command.
    If you want to fully override the args, just use args instead of extra_args.

This all works as expected in LazyVim, but I believe these changes would benefit others as well.
Ideally, I also prefer not to deviate from a plugin's options.

Would you be open to accept a PR for this? If so I can create one.

Example

{
  -- LazyVim will use these options when formatting with the conform.nvim formatter
  format = {
    timeout_ms = 1000,
  },
  formatters_by_ft = {
    lua = { "stylua" },
    fish = { "fish_indent" },
    sh = { "shfmt" },
  },
  -- LazyVim will merge the options you set here with builtin formatters.
  -- You can also define any custom formatters here.
  ---@type table<string,table>
  formatters = {
    injected = { options = { ignore_errors = true } },
    -- # Example of using dprint only when a dprint.json file is present
    dprint = {
      condition = function(ctx)
        return vim.fs.find({ "dprint.json" }, { path = ctx.filename, upward = true })[1]
      end,
    },
    --
    -- Example of using shfmt with extra args
    shfmt = {
      extra_args = { "-i", "2", "-ci" },
    },
  },
}

bug: format() api doesn't work

Neovim version (nvim -v)

0.9.2

Operating system/version

6.5.3-arch1-1

Output of :ConformInfo

Log file: /home/troysigx/.local/state/nvim/conform.log

Formatters for this buffer:
LSP: lua_ls

Other formatters:

Describe the bug

I have this config:

  require('conform').setup({
    format_after_save = function(bufnr)
      return {
        lsp_fallback = true,
        timeout_ms = 500,
      }
    end
  })

When using require('conform').format(), conform doesn't format the buffer, though format_after_save works as expected

Steps To Reproduce

  1. Load above config
  2. Try require('conform').format()
  3. Try saving the buffer

Expected Behavior

In step 2 of reproduction, conform doesn't format the buffer, but it does in step 3. So it is expected that conform also formats in step 2

Minimal example file

No response

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.DEBUG,
        -- add your config here
      })
    end,
  },
  -- add any other plugins here
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

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

Additional context

No response

LSP formatters not used as fallback?

With elentok-format-on-save.nvim, I'm using:

return {
  "elentok/format-on-save.nvim",
  event = { "BufReadPre", "BufNewFile" },
  config = function()
    local format_on_save = require("format-on-save")
    local formatters = require("format-on-save.formatters")

    format_on_save.setup({
        c = formatters.lsp,
        cpp = formatters.lsp,
        json = formatters.lsp,
        jsonc = formatters.lsp,
        lua = formatters.lsp,
    })
  end,
}

and my files with these filetypes are formatted on saving.

The LSP I'm using:

Filetype LSP
c, cpp clangd
json, jsonc json-lsp
lua lua-language-server

For lua, I guess it's using CppCXY/EmmyLuaCodeStyle, which is the formatter from lua-language-server, as mentioned here.

With conform.nvim, when saving in a c, cpp, json, jsonc or lua file, no formatting is applied at all. My config:

return {
  "stevearc/conform.nvim",
  event = { "BufReadPre", "BufNewFile" },
  config = function()
    require("conform").setup({
    formatters_by_ft = {
      css = { "prettierd" },
      javascript = { "prettierd" },
      markdown = { "prettierd" },
      sh = { "shfmt" },
      yaml = { "yamlfmt" },
    },
    format_on_save = {
        timeout_ms = 500,
        lsp_fallback = true,
    },
    })
  end
}

Am I missing something? I would expect lsp_fallback = true to use the formatter from the relevant LSP like elentok-format-on-save.nvim does.

bug: eslint_d failing in a way that disallows other formatters from running

Neovim version (nvim -v)

0.9.2

Operating system/version

NixOS

Output of :ConformInfo

06:56:07[ERROR] Formatter 'eslint_d' error: 

Describe the bug

eslint_d being listed as formatter seems to cause rest of the formatters to fail too for given filetype. If I use eslint instead, formatting works as expected.

From cli both eslint_d and eslint fail if I ran it on some random js file since no configuration was provided... as expected.

Steps To Reproduce

  1. have eslint_d and prettier listed as formatters
  2. have eslint_d ans prettier installed
  3. run require("conform").format({ async = true, lsp_fallback = true }) in javascript buffer

Expected Behavior

eslint_d fails to format so falls back to prettier.

Minimal lazy config for conform.nvim

  {
    "stevearc/conform.nvim",
    config = function()
      require("conform").setup {
        formatters_by_ft = {
          javascript = { "eslint_d", "prettier" },
        },
      }
      vim.o.formatexpr = "v:lua.require'conform'.formatexpr()"
      vim.keymap.set('', "<leader>f", function()
        require("conform").format({ async = true, lsp_fallback = true })
      end)
    end,
  },

bug: How do I enable codespell for all languages?

Neovim version (nvim -v)

nightly

Operating system/version

arch linux

Output of :ConformInfo

nothing

Describe the bug

How do I enable codespell for all languages?
According to the example, only one file type can be matched

Steps To Reproduce

nothing

Expected Behavior

nothing

Minimal example file

No response

Minimal init.lua

No response

Additional context

No response

bug: can't make `--config-path` arg to work

Neovim version (nvim -v)

NVIM v0.9.2

Operating system/version

MacOs 13.6 (22G120)

Output of :ConformInfo

Log file: /Users/henryoliver/.local/state/nvim/conform.log
          
          	Did you mean '--config-path'?
          
          	If you tried to supply `-- --config-path` as a value rather than a flag, use `-- -- --config-path`
          
          USAGE:
              stylua --config-path <CONFIG_PATH>
          
          For more information try --help
          
          22:14:57[ERROR] Formatter 'stylua' error: error: Found argument '-- --config-path' which wasn't expected, or isn't valid in this context
          
          	Did you mean '--config-path'?
          
          	If you tried to supply `-- --config-path` as a value rather than a flag, use `-- -- --config-path`
          
          USAGE:
              stylua --config-path <CONFIG_PATH>
          
          For more information try --help
          
          22:14:57[ERROR] Formatter 'stylua' error: error: Found argument '-- --config-path' which wasn't expected, or isn't valid in this context
          
          	Did you mean '--config-path'?
          
          	If you tried to supply `-- --config-path` as a value rather than a flag, use `-- -- --config-path`
          
          USAGE:
              stylua --config-path <CONFIG_PATH>
          
          For more information try --help
          
          22:20:00[ERROR] Formatter 'stylua' error: error: no files provided

Formatters for this buffer:
LSP: lua_ls
stylua ready (lua)

Describe the bug

Cant make this arg work:

			local stylua = require("conform.formatters.stylua")
			stylua.args = { "--config-path", vim.fn.expand("~/.config/lsp/stylua.toml") }

The path is correct:

❯ cat ~/.config/lsp/stylua.toml
indent_width = 4
column_width = 120
indent_type = "Spaces"
line_endings = "Unix"
call_parentheses = "Always"
quote_style = "AutoPreferDouble"
collapse_simple_statement = "Never"

How to disable error notifications?

I am using nvim-notify plugin to beautify my notifications,but,When I encounter a format error with this plugin, it takes up too much of my screen, is there a way to disable the error notification
2023-08-28_13-29

Formatter failed if there is an error on the buffer?

Question

Just want to ask if the formatter shows an error on saving if there is an error detected on the buffer?

  • When I try to save a file (and of course format), if there is an error on the file then it shows an error.
Error detected while processing BufWritePre Autocommands for "*":
Formatter failed. See :ConformInfo for details
  • :ConformInfo:
          08:58:13[ERROR] Formatter 'prettier' error: [error] /home/yuu/My Space/developer/work/PWA/Gauge-PWA/app/page.js: SyntaxError: Missing semicolon. (8:7)
          [error]    6 | const HomeRoute = () => {
          [error]    7 |   const { isLoading, isLoggedIn, deviceId } = useContext(UserCtx);
          [error] >  8 |   cons router = useRouter();
          [error]      |       ^
          [error]    9 |   useEffect(() => {
          [error]   10 |     if (!isLoading) {
          [error]   11 |       if (!isLoggedIn) {

Formatters for this buffer:
LSP: tsserver
prettier ready (json, markdown, svelte, yaml, html, python, javascript, typescript, graphql, typescriptreact, javascriptreact, css)

Very noob in configuring. Help much appreciated!

Unable to create custom formatter for Svelte

local options = {

  -- custom formatter
  formatters = {
    svelte_fmt = {
      command = "prettier",
      args = { "--write", "--plugin", "prettier-plugin-svelte", "$FILENAME" },
    },
  },

  formatters_by_ft = {
    svelte = { "svelte_fmt" },
  },
}

require("conform").setup(options)

image

bug: `async` format after buffer changes only fires after saving twice

Neovim version (nvim -v)

v0.10.0-dev-997+g6463116818

Operating system/version

Arch Linux WSL2

Output of :ConformInfo

Log file: /home/alex/.local/state/nvim/conform.log

Formatters for this buffer:
stylua ready (lua)

Other formatters:

Describe the bug

If I open a buffer with some text that needs formatting and save, it's correctly formatted.

If I make a change, say like indent something, and then save, it doesn't format. If I save again, it does format.

When not using async, it blocks and formats no problem on the first save.

Steps To Reproduce

Using this in a lazy.nvim config. The only other plugins I am using for this are catppuccin and nvim-treesitter, which I don't expect to interfere with it. I can remove those and re-try if you think otherwise!

{
    "stevearc/conform.nvim",
    config = function()
      require("conform").setup({
        formatters_by_ft = {
          lua = { "stylua" },
        },
      })
      vim.api.nvim_create_autocmd("BufWritePre", {
        pattern = "*",
        callback = function(args)
          require("conform").format({ async = true, lsp_fallback = true, buf = args.buf })
        end,
      })
    end,
}

Then I open my init.lua and indent something. Press :w, no format. Then I :q and reopen the file. :w will then correctly format. If I indent again, then press :w and then :w again, it formats.

Expected Behavior

It should format on the first save.

Minimal example file

No response

Minimal init.lua

(Just removing this since what I have above is pretty much it. It's the same lazy setup as the one in the template. Can provide the full file if that's preferred).

Additional context

No response

feat: let `lsp_fallback` use `textDocument/formatting` for range formatting when `textDocument/rangeFormatting` is not available

since it's supported for conform formatters, it would also be cool to support it for LSP formatters

function M.get_format_clients(options)
-  local method = options.range and "textDocument/rangeFormatting" or "textDocument/formatting"
+  local method = "textDocument/formatting"

then additionally handle the not client.supports_method("textDocument/rangeFormatting") case in lsp_format.format({ range = range })

using lsp formatting on specific filetypes

I am trying to use lsp formatting on scala files, but avoid using lsp formatting on typescript files.
I have the following config:

local utils = require("utils")

require("conform").setup({
	formatters_by_ft = {
		lua = { "stylua" },
		javascript = { "eslint_d" },
		javascriptreact = { "eslint_d" },
		typescript = { "eslint_d" },
		typescriptreact = { "eslint_d" },
		-- Use a sub-list to run only the first available formatter
		json = { { "prettierd", "prettier" } },
		scala = {},
		["*"] = { "trim_whitespace" },
	},
})

local function format()
	require("conform").format({ lsp_fallback = true })
end

local function format_write()
	require("conform").format({
		lsp_fallback = true,
	}, vim.cmd.write)
end

local opts = { silent = true }
local get_opts = utils.create_get_opts(opts)
vim.keymap.set("n", "<leader>f", format, get_opts({ desc = "conform.format" }))
vim.keymap.set("n", "<leader>F", format_write, get_opts({ desc = "conform.format_write" }))

vim.api.nvim_create_autocmd("BufWritePost", {
	group = vim.api.nvim_create_augroup("FormatAutogroup", {}),
	callback = format_write,
})

If I run format on a typescript file with this config, eslint_d will format the file. On a scala file, nothing will happen.
If I replace lsp_fallback = true -> "always", running format will run the lsp formatter on both scala and typescript.
There doesn't seem to be a way to specify running the lsp formatter on scala files, but not on typescript files?

Is `["*"]` OK to define some formatters for all filetypes?

As I was working on #29, I'm using locally:

return {
  dir = "/home/xfzv/.local/share/nvim/lazy/conform.nvim/",
  event = { "BufReadPre", "BufNewFile" },
  config = function()

    require("conform").setup({
    formatters_by_ft = {
      ["*"] = {
        formatters = {
          "trim_whitespace",
          "trim_newlines",
        },
        run_all_formatters = true,
      },
    },
    format_on_save = {
        timeout_ms = 500,
        lsp_fallback = true,
    },
    })
  end
}

Is using ["*"] so that any filetype is matched OK? It seems to work just fine on my end but I'm wondering if there's a better way to do that, or if it could lead to any kind of breakage.

Thanks!

bug: trim_whitespace adding newline at the end of the file

Neovim version (nvim -v)

neovim-0.10.0_dev_aab06ed

Operating system/version

slackware64-current

Output of :ConformInfo

Log file: /home/perrin4869/.local/state/nvim/conform.log

Formatters for this buffer:
stylua ready (lua)
trim_whitespace ready (*)

Other formatters:
eslint_d ready (typescript, javascriptreact, typescriptreact, javascript)
prettier ready (json)
prettierd unavailable: Command not found

Describe the bug

when running require("conform").format, a newline is added at the end of a lua file.

Steps To Reproduce

for example:

$ cat foo.lua                                                                                                                                                        
local omg = "foo"

running conform.format will cause the file to become

$ cat foo.lua                                                                                                                                                        
local omg = "foo"

Expected Behavior

Does not result in a newline at the end of the file

Minimal example file

No response

Minimal init.lua

No response

Additional context

No response

feat: Allow to set `formatexpr`

As null-ls has been archived, I've started to look into alternatives for formatting. According to neovim/neovim#24338 :help formatexpr should be used. By default the LSP implementation sets:

formatexpr=v:lua.vim.lsp.formatexpr()

It would be nice if conform would set it to a formatter lua functions it provides. The vim.lsp.formatexpr() is here:

https://github.com/neovim/neovim/blob/35e50d79c630b05f67a840ebe21b4043ba9a6066/runtime/lua/vim/lsp.lua#L2394-L2395

It would be nice to have a similar function in conform set it for configured filetype in conform. I can look into this in the next weeks if there is interest.

Mason support

I'm wondering if there is any plan to integrate with mason, such integration would allow auto-downloading of formatters depending on which ones the user has registered. Unsure how much work this would entail or if such feature is better of in a separate plugin.

Edit:

I have created a mason-conform.nvim plugin that detects the formatters registered with conform and automatically downloads them via mason. I added a conform to mason mapping for all the formatters I could find in the mason registry, I might have missed something but feel free to create a PR if that's the case.

How to add shell command with pipe?

The way conform.nvim is set up, it seems slightly more complicated commands do not work.

For example, shellcheck can be used to auto-fix some issues using this, effectively replacing shellharden:

shellcheck --format=diff my_file.sh | git apply

This works fine in the terminal, but the following config does not work:

formatters = {
	shellcheck = {
		command = "shellcheck",
		args = {"--format=diff", "$FILENAME", "|", "git", "apply" },
		stdin = false,
	},
},

I assume this is because in the background, conform.nvim uses fn.system with a list of strings, where pipes do not work. However, using fn.system with a single string does work fine, but passing a string to args results in an error.

Is there a way to make this work?

bug: no formatter on save with custom formatter

Neovim version (nvim -v)

NVIM v0.10.0-dev-1240+g9afbfb4d64

Operating system/version

Arch Linux

Output of :ConformInfo

~ │Formatters for this buffer:                                                                                                                                                                                    │
~ │sqlfluff ready (sql)                                                                                                                                                                                           │

Describe the bug

Formatter on save doesn't seem to work form custom formatter

Steps To Reproduce

  1. Open nvim with the minimal init.lua file provided
  2. Open a foo.sql file with:
SELECT
  this_column,
  that_column as this_name,
  some_number * 10 AS a_bigger_number
FROM my_table
  1. Run :w to write -> nothing happens
  2. Press ,fc to run the format code -> the code is formatted

Expected Behavior

After 3. I would expect the code to get formatted.

Minimal example file

No response

Minimal init.lua

local root = '/tmp/nvim-minimal'

-- Set stdpaths to use root dir
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 and configure plugins
local plugins = {
    {
        'stevearc/conform.nvim',
        config = function()
            vim.o.formatexpr = [[v:lua.require('conform').formatexpr()]]
            require('conform').setup({
                format_on_save = {
                    timeout_ms = 200,
                    lsp_fallback = false,
                },
                notify_on_error = false,
                formatters = {
                    sqlfluff = {
                        command = 'sqlfluff',
                        args = {
                            'fix',
                            '--disable-progress-bar',
                            '-f',
                            '-n',
                            '-',
                        },
                        stdin = true,
                    },
                },
                formatters_by_ft = {
                    sql = { 'sqlfluff' },
                },
            })
            vim.keymap.set({ 'n', 'v' }, ',fc', function()
                require('conform').format({ async = true, lsp_fallback = false })
            end)
        end,
    },
}
require('lazy').setup(plugins, {
    root = root .. '/plugins',
})

Additional context

conformsql

isort range formatting deletes lines

          I'm having an issue with lines being removed due to `isort`, probably related.

Test file:

import numpy as np

from A import B
import C

Output if I use conform.format() (works as expected):

import C
import numpy as np
from A import B

Output if I use conform.format({range = {start={1, 0}, ["end"]={4,8}}}) (whole file as range):

import C

I tracked it down to apply_format, in particular indices_in_range here is evaluating to false, so it does the deletion but not the insertion, shown in the lack of a second text edit for the call with a range. If I bypass that line (just saying if true for this test), it works exactly as expected.

trace for no range (conform.format()):

15:06:37[DEBUG] Running formatters on ~/test.py: { "isort" }
15:06:37[INFO] Run isort on ~/test.py
15:06:37[TRACE] Input lines: { "import numpy as np", "", "from A import B", "import C" }
15:06:37[DEBUG] Run command: { "isort", "--stdout", "--filename", "~/test.py", "-" }
15:06:38[DEBUG] isort exited with code 0
15:06:38[TRACE] Output lines: { "import C", "import numpy as np", "from A import B" }
15:06:38[TRACE] Applying formatting to ~/test.py
15:06:38[TRACE] Comparing lines { "import numpy as np", "", "from A import B", "import C" } and { "import C", "import numpy as np", "from A import B" }
15:06:38[TRACE] Diff indices { { 1, 3, 0, 0 }, { 4, 0, 2, 2 } }
15:06:38[TRACE] Applying text edits: { {
    newText = "",
    range = {
      ["end"] = {
        character = 0,
        line = 3
      },
      start = {
        character = 0,
        line = 0
      }
    }
  }, {
    newText = "import numpy as np\nfrom A import B",
    range = {
      ["end"] = {
        character = 0,
        line = 4
      },
      start = {
        character = 0,
        line = 4
      }
    }
  } }
15:06:38[TRACE] Done formatting ~/test.py

trace with a range (conform.format({range = {start={1, 0}, ["end"]={4,8}}})):

15:06:33[DEBUG] Running formatters on ~/test.py: { "isort" }
15:06:33[INFO] Run isort on ~/test.py
15:06:33[TRACE] Input lines: { "import numpy as np", "", "from A import B", "import C" }
15:06:33[DEBUG] Run command: { "isort", "--stdout", "--filename", "~/test.py", "-" }
15:06:33[DEBUG] isort exited with code 0
15:06:33[TRACE] Output lines: { "import C", "import numpy as np", "from A import B" }
15:06:33[TRACE] Applying formatting to ~/test.py
15:06:33[TRACE] Comparing lines { "import numpy as np", "", "from A import B", "import C" } and { "import C", "import numpy as np", "from A import B" }
15:06:33[TRACE] Diff indices { { 1, 3, 0, 0 }, { 4, 0, 2, 2 } }
15:06:33[TRACE] Applying text edits: { {
    newText = "",
    range = {
      ["end"] = {
        character = 0,
        line = 3
      },
      start = {
        character = 0,
        line = 0
      }
    }
  } }
15:06:33[TRACE] Done formatting ~/test.py

Originally posted by @milisims in #98 (comment)

conform.nvim checkhealth error

When I used neovim's checkhealth to check the conform.nvim plugin, this error occurred:
image
Here is my conform.nvim plugin configuration:
image
How to solve this problem?

Feature request: Formatting on changed lines only

This may not be the right place to ask, but I was wondering: Is it possible to run the formatters automatically, but only for the new changes as per the git diff?

I would like to use Neovim for work, but I find that it changes code that I didn’t touch and makes my PRs unnecessarily long 😅

Feature suggestion: Define LSP formatting in `formatters_by_ft`

Right now, CLI formatters are listed in formatters_by_ft, and LSP formatting is defined via lsp_fallback, which can be set in the config or in the keymap. When you want to use LSP formatting for some filetypes, and formatting via CLI for other filetypes, the config for that is pretty much split up into several places and one also has to pay attention to the distinction between lsp_fallback = "always" and lsp_fallback = true.

My suggestion is to list lsp in the formatters_by_ft table, which simplifies the formatting setup. Everything would be located in one place, and fallback-behavior would be defined the same way as with CLI formatters, making conform.nvim's more consistent.

require("conform").setup {
	formatters_by_ft = {
		-- run only CLI
		html = { "prettier" },

		-- run only LSP
		toml = { "lsp" },

		-- always run LSP after stylelint (like `lsp_fallback = "always"`)
		css = { "stylelint", "lsp" }, 

		-- sublist, run LSP only when stylua not available (like `lsp_fallback = true`)
		lua = { { "stylua", "lsp" } }, 
	},
}

issue: Setting up prisma formatting

Im trying to setup prisma file formatting using Prisma/prisma
At first it formats but after that the content in neovim gets replaced by prisma format response message
Preview video:

2023-10-04.16-03-29.mp4

bug: All formatters fail when injected formatter fails

Neovim version (nvim -v)

NVIM v0.9.2 Build type: Release LuaJIT 2.1.1694285958

Operating system/version

Arch Linux 6.5.5-arch1-1

Add the debug logs

  • I have set log_level = vim.log.levels.DEBUG and pasted the log contents below.

Log file

Log file: /home/rileyb/.local/state/nvim/conform.log
XDG_CONFIG_HOME = "/home/rileyb/.config/nvim/"
}
20:59:45[INFO] stylua exited with code 2
20:59:45[DEBUG] stylua stdout: { "" }
20:59:45[DEBUG] stylua stderr: { "error: could not format from stdin: failed to format from stdin: error parsing: error occurred while creating ast: unexpected token >. (starting from line 1, character 1 and ending on line 1, character 2)", "additional information: leftover token", "" }
20:59:45[ERROR] Formatter 'stylua' error: error: could not format from stdin: failed to format from stdin: error parsing: error occurred while creating ast: unexpected token >. (starting from line 1, character 1 and ending on line 1, character 2)
additional information: leftover token

      20:59:45[ERROR] Formatter 'stylua' error: error: could not format from stdin: failed to format from stdin: error parsing: error occurred while creating ast: unexpected token `>`. (starting from line 1, character 1 and ending on line 1, character 2)
      additional information: leftover token

Formatters for this buffer:
deno_fmt ready (javascript, javascriptreact, typescriptreact, markdown, typescript, jsonc, json)
injected ready (markdown)

Other formatters:
clang_format ready (c, cpp)
prettierd ready (css, html)
stylua ready (luau, lua)

Describe the bug

When using injected formatters, if an injected formatter fails then the main formatter(s) will not run. For example if an injected code block in a Markdown document cannot be formatted, the entire Markdown document will not be formatted.

Steps To Reproduce

  1. nvim -u repro.lua
  2. Open a file with injected formatting that will fail
  3. Save the file

Expected Behavior

The Lua code will not be formatted, but the rest of the markdown document will

Minimal example file

# Hi

   wrongly indented text

> ```lua
> require('hi')
> ```

The above cannot be formatted since it is in a block quote :)

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.DEBUG,
        format_on_save = {
          timeout_ms = 1000,
          lsp_fallback = false,
          quiet = true,
        },
        formatters_by_ft = {
          lua = { 'stylua' },
          markdown = { 'deno_fmt', 'injected' },
        },
      }
    end,
  },
  -- add any other plugins here
}
require('lazy').setup(plugins, {
  root = root .. '/plugins',
})

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

Additional context

No response

Explicit LSP formatter

Hi,

Great plugin. I think it would be nice to have a formatter named 'lsp' that would simply run the lsp formatter. Then it would be possible to be explicit about which filetypes would use the lsp formatter and the fallback option would not be needed anymore.

feature request: use `shiftwidth` and `expandtab` settings when invoking formatters

Neovim version (nvim -v)

0.10.0 commit 09a17f91d0d362c6e58bfdbe3ccdeacffb0b44b9

Operating system/version

Arch Linux

Add the debug logs

  • I have set log_level = vim.log.levels.DEBUG and pasted the log contents below.

Log file

NA

Describe the bug

conform should use the shiftwidth and expandtab settings when invoking formatters

For example,

args = { "--search-parent-directories", "--stdin-filepath", "$FILENAME", "-" },

should use --indent-width and --indent-type with values using shiftwidth and expandtab respectively

Steps To Reproduce

NA

Expected Behavior

NA

Minimal example file

No response

Minimal init.lua

No response

Additional context

No response

More convenient way to copy args from built-in formatter

Slightly off topic but I would also love a more generalized solution for passing arguments in general. Right now using list_extend works well enough unless a builtin formatter has args or range_args which are of type function(ctx). In this case the user needs to basically copy the original function from the source, modify it to their needs, and then set that new function as the property. If there were some with_args or extra_args property implemented for the formatters this would be really nice, and maybe something similar could be done for this problem.

Originally posted by @ribru17 in #44 (comment)

When all formatters for a buffer have `cond=false`, then a warning is printed every time.

In LazyVim, I do LSP formatting myself and don't use the conform.nvim fallback for this.

Unfortunately, this means when all formatters are disabled (due to cond=false), I always get the warning below.

I know there's quiet = true, but that would ignore all errors as well, which is not something I want to do.

Any suggestions?

vim.notify("No formatters found for buffer. See :ConformInfo", vim.log.levels.WARN)

bug: phpcbf discarding unsaved changes on format

Neovim version (nvim -v)

NVIM v0.9.2

Operating system/version

macOS 13.5.2

Add the debug logs

  • I have set log_level = vim.log.levels.DEBUG and pasted the log contents below.

Log file

14:01:38[DEBUG] Running formatters on /Users/scott/Code/conform-phpcbf/example.php: { "phpcbf" }
14:01:38[INFO] Run phpcbf on /Users/scott/Code/conform-phpcbf/example.php
14:01:38[DEBUG] Run command: { "/Users/scott/Code/conform-phpcbf/vendor/bin/phpcbf", "-q", "--stdin-path=", "/Users/scott/Code/conform-phpcbf/example.php", "-" }
14:01:38[DEBUG] phpcbf exited with code 1

Describe the bug

Follow-up to #103.

When making a change to a line in a PHP file, unsaved changes are lost when formatting via phpcbf.

Steps To Reproduce

  1. nvim -u repro.lua
  2. :e example.php
  3. Change the name of the 'example' variable on line 3 to something else like 'conform'.
  4. :w

Expected Behavior

The expected behaviour would be that the edit made to line 3 is preserved when formatting on save.

The actual behaviour is that line 3 stays as ‘example’, and unsaved changes are lost.

Minimal example file

<?php

$example = true;

Minimal composer.json

{
    "name": "test/conform-phpcbf",
    "type": "project",
    "require": {
        "squizlabs/php_codesniffer": "^3.7"
    }
}

Run composer install once the composer.json above is in place.

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.DEBUG,
        -- add your config here
        format_on_save = {
          -- phpcbf is slow.
          timeout_ms = 1000,
          lsp_fallback = true,
        },
        formatters_by_ft = {
          php = { "phpcbf" },
        },
      })
    end,
  },
  -- add any other plugins here
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

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

Additional context

No response

doc: How to format selection

The docs says that format() "Defaults to current selection in visual mode":

| | range | `nil\|table` | Range to format. Table must contain `start` and `end` keys with {row, col} tuples using (1,0) indexing. Defaults to current selection in visual mode |

Yet, it is unclear on how to format a visual selection.

[Question] Formatters are not detected

Hello,

here is my config:

return {
  "stevearc/conform.nvim",
  event = { "BufReadPre", "BufNewFile" },
  config = function()
    local conform = require('conform')

    conform.setup({
      forrmaters_by_ft = {
        swift = { "swiftformat" },
        lua = { "stylua" },
        markdown = { "prettier" },
        javascript = { "prettier" },
        html = { "prettier" },
        css = { "prettier" },
        yaml = { "prettier" },
        json = { "prettier" },
        -- Use the "*" filetype to run formatters on all filetypes.
        ["*"] = { "codespell" },
      },
      format_on_save = {
        timeout_ms = 500,
        lsp_fallback = true,
      },
      log_level = vim.log.levels.TRACE,
    })

    vim.keymap.set({ "n", "v" }, "<leader>mp", function()
      conform.format({
        lsp_fallback = true,
        async = false,
        timeout_ms = 500
      })
    end, { desc = "Format file or range (in visual mode)" })
  end
}

I installed all formatters via Homebrew, but it looks like formatters are not detected. When I open lua file and call :ConformInfo I get:
image

When I open Swift file:
image

What do I do wrong?

bug: Rubocop shows formatting as corrected in logs but doesn't write to buffer

Neovim version (nvim -v)

0.9.2

Operating system/version

Mac OS 14.0

Output of :ConformInfo

Log file: /Users/sameer/.local/state/nvim/conform.log
          C:  1: 41: [Corrected] Layout/TrailingWhitespace: Trailing whitespace detected.
          C:  3:  1: [Corrected] Layout/EmptyLines: Extra blank line detected.
          C:  3: 11: [Corrected] Layout/ArrayAlignment: Align the elements of an array literal if they span more than one line.
          C:  4:  1: [Corrected] Layout/EmptyLines: Extra blank line detected.
          C:  5:  1: [Corrected] Layout/EmptyLines: Extra blank line detected.
          C:  6:  1: [Corrected] Layout/EmptyLines: Extra blank line detected.
          C:  7:  1: [Corrected] Layout/EmptyLines: Extra blank line detected.
          C:  8:  1: [Corrected] Layout/EmptyLines: Extra blank line detected.
          C:  9:  1: [Corrected] Layout/EmptyLines: Extra blank line detected.
          C: 10:  1: [Corrected] Layout/EmptyLines: Extra blank line detected.
          C: 11:  3: [Corrected] Layout/ArrayAlignment: Align the elements of an array literal if they span more than one line.
          
          1 file inspected, 15 offenses detected, 14 offenses corrected, 1 more offense can be corrected with `rubocop -A`
          ====================

Formatters for this buffer:
rubocop ready (ruby)

Other formatters:
black ready (python)
isort ready (python)
prettier ready (javascriptreact, css, typescript, jsonc, javascript, scss, html, typescriptreact)
prettierd ready (javascriptreact, css, typescript, jsonc, javascript, scss, html, typescriptreact)
stylua ready (lua)
trim_whitespace ready (_)

Describe the bug

As seen in log for ruby files, rubocop is finding offenses but doesn't update the file when formatting. Strangely the log show corrected.

Steps To Reproduce

  1. open any ruby file and save with random spaces.

Expected Behavior

File should be formatted as per output in logs from rubocop

Minimal example file

`nums = [13, 57, 8,

39, 48, 24, 47]

nums.size.times do |i|
nums.combination(i).to_a.each do |x|
p x if x.sum == 100 # [13, 39, 48]
end
end`

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.DEBUG,
        -- add your config here
      })
    end,
  },
  -- add any other plugins here
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

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

Additional context

It works for all other file types like python, react tsx, json, etc.

Setup file:

return { "stevearc/conform.nvim", opts = { formatters_by_ft = { lua = { "stylua" }, javascript = { { "prettierd", "prettier" } }, javascriptreact = { { "prettierd", "prettier" } }, jsonc = { { "prettierd", "prettier" } }, typescript = { { "prettierd", "prettier" } }, typescriptreact = { { "prettierd", "prettier" } }, html = { { "prettierd", "prettier" } }, css = { { "prettierd", "prettier" } }, scss = { { "prettierd", "prettier" } }, python = { "isort", "black" }, ruby = { "rubocop" }, ["_"] = { "trim_whitespace" }, }, format_on_save = { lsp_fallback = true, }, }, }

Feature request: Toggle format on save command

I just tried this and it works like a charm! Yet another amazing plugin <3

I do think it would be very helpful to have a ToggleFormat command for disabling/enabling format on save in the current buffer. This is particularly useful when working on external code that one doesn't want to format, and for momentarily disabling the formatter to avoid messing up with other people's code.

Recommended way to override parts of a formatter

I've been fiddling with conform.nvim and I wonder if there is a recommended way to do the following:
Let's say there are 2 directories a and b. In a is a configuration file for prettier. In b there is no configuration for prettier. When I am editing a buffer that is within a I would like prettier to use the configuration file in a and change directory to there -- while also using the current definition for prettier for all other fields (plus I'd probably just assume use the same arguments as are in the defaults, but just prepending --config=). If I'm in b (or really anywhere else) I would like the defaults. I have been unable to come up with a satisfactory way to do this. What is recommended?

Have you considered opening up Discussions for this project? This question seems more appropriate to there.

Python Ruff formatter deletes all lines of the file

Not each time, but very often Ruff formatter delete all file (after save format and manually format).
If I make some changes, not delete, but if i try to format the same code second time, all lines cleared from file

conform.lua:

return {
  "stevearc/conform.nvim",
  enabled = true,
  event = { "BufReadPre", "BufNewFile" },
  config = function()
    local conform = require("conform")

    conform.setup({
      formatters_by_ft = {
        javascript = { "prettier" },
        typescript = { "prettier" },
        javascriptreact = { "prettier" },
        typescriptreact = { "prettier" },
        svelte = { "prettier" },
        css = { "prettier" },
        html = { "prettier" },
        json = { "prettier" },
        yaml = { "prettier" },
        markdown = { "prettier" },
        graphql = { "prettier" },
        lua = { "stylua" },
        python = { "isort", "ruff_format" },
      },
      format_on_save = {
        lsp_fallback = true,
        async = false,
        timeout_ms = 1000,
      },
    })

    vim.keymap.set({ "n", "v" }, "<leader>mp", function() -- Make prettier
      conform.format({
        lsp_fallback = true,
        async = false,
        timeout_ms = 1000,
      })
    end, { desc = "Format file or range (in visual mode)" })
  end,
}

:ConformInfo

Log file: /Users/vladimirsumarokov/.local/state/nvim/conform.log

Formatters for this buffer:
LSP: null-ls
isort ready (python)
ruff_format ready (python)

Other formatters:
prettier unavailable: Command not found
stylua unavailable: Command not found

Example python:

from telebot import TeleBot, types

bot = TeleBot("TOKEN")


@bot.message_handler(commands=["withdraw"])
def command_withdraw(message: types.Message):
    return message

bug: Formatter 'prettier' timeout on every save

Neovim version (nvim -v)

NVIM v0.10.0-dev-5362+g2c9f22e7e-Homebrew

Operating system/version

MacOS 13.5.1

Add the debug logs

  • I have set log_level = vim.log.levels.DEBUG and pasted the log contents below.

Log file

Log file: /Users/will.davidow/.local/state/nvim/conform.log
          16:51:30[WARN] Formatter 'prettier' timeout
          16:51:30[DEBUG] Running formatters on /Users/will.davidow/Development/Personal/github.com/project/apps/web/components/ClientBioForm/ClientBioForm.tsx: { "prettier" }
          16:51:30[INFO] Run prettier on /Users/will.davidow/Development/Personal/github.com/project/apps/web/components/ClientBioForm/ClientBioForm.tsx
          16:51:30[DEBUG] Run command: { "/Users/will.davidow/Development/Personal/github.com/project/node_modules/.bin/prettier", "--stdin-filepath", "/Users/will.davidow/Development/Personal/github.com/project/apps/web/components/ClientBioForm/ClientBioForm.tsx" }
          16:51:30[DEBUG] Run CWD: /Users/will.davidow/Development/Personal/github.com/project/apps/web
          16:51:30[INFO] prettier exited with code 143
          16:51:30[DEBUG] prettier stdout: { "" }
          16:51:30[DEBUG] prettier stderr: { "" }
          16:51:32[DEBUG] prettier exited with code 0

Describe the bug

Every time conform runs (I have prettier set to run on save) I see a notification Formatter 'prettier timeoutbut it runs. I've set my timeout to15000` in my config, and it's not taking anywhere near that long to run or show me the message that things timed out.

Steps To Reproduce

  1. Make a change in a JS file so things will be formatted on save.
  2. Save the file
  3. See the message.

Expected Behavior

Formatter runs without telling me it timed out when it did not.

Minimal example file

Really any javascript or typescript file. It happens every time for me.

Minimal init.lua

Here's my conform config:


-- Formatting.
return {
	{
		"stevearc/conform.nvim",
		event = { "LspAttach", "BufWritePre" },
		opts = {
			notify_on_error = true,
			formatters_by_ft = {
				sh = { "shfmt" },
				lua = { "stylua" },
				javascript = {
					{ --[[ "prettierd", ]]
						"prettier",
					},
				},
				typescript = {
					{ --[[ "prettierd", ]]
						"prettier",
					},
				},
				javascriptreact = {
					{ --[[ "prettierd", ]]
						"prettier",
					},
				},
				typescriptreact = {
					{ --[[ "prettierd", ]]
						"prettier",
					},
				},
			},
			format_on_save = {
				async = true,
				timeout_ms = 10000,
				lsp_fallback = true,
			},
			log_level = vim.log.levels.DEBUG,
			vim.api.nvim_create_autocmd("BufWritePre", {
				pattern = "*",
				callback = function(args)
					require("conform").format({ bufnr = args.buf })
				end,
			}),
		},
		--[[ init = function()
			-- Add commands to toggle formatting.
			vim.api.nvim_create_user_command("FormatDisable", function()
				vim.g.disable_autoformat = true
			end, { desc = "Disable format on save", nargs = 0 })
			vim.api.nvim_create_user_command("FormatEnable", function()
				vim.g.disable_autoformat = false
			end, { desc = "Enable format on save", nargs = 0 })
		end, ]]
	},
}


### Additional context

_No response_

unable to open :ConformInfo

after typing :ConformInfo
i get an error Not an editor command: ConformInfo

may i know where do i paste the formatter in too? do i need to create a file somewhere?

Support for environment variables?

Is there an option to use environment variables with specific formatters? I'd like to set PRETTIERD_LOCAL_PRETTIER_ONLY without redefining the prettierd formatter.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.