Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/sbdchd/neoformat

:sparkles: A (Neo)vim plugin for formatting code.
https://github.com/sbdchd/neoformat

formatter neovim plugin vim

Last synced: about 2 months ago
JSON representation

:sparkles: A (Neo)vim plugin for formatting code.

Awesome Lists containing this project

README

        

# Neoformat [![Build Status](https://travis-ci.org/sbdchd/neoformat.svg?branch=master)](https://travis-ci.org/sbdchd/neoformat)

A (Neo)vim plugin for formatting code.

Neoformat uses a variety of formatters for many filetypes. Currently, Neoformat
will run a formatter using the current buffer data, and on success it will
update the current buffer with the formatted text. On a formatter failure,
Neoformat will try the next formatter defined for the filetype.

By using `getbufline()` to read from the current buffer instead of file,
Neoformat is able to format your buffer without you having to `:w` your file first.
Also, by using `setline()`, marks, jumps, etc. are all maintained after formatting.

Neoformat supports both sending buffer data to formatters via stdin, and also
writing buffer data to `/tmp/` for formatters to read that do not support input
via stdin.

## Basic Usage

Format the entire buffer, or visual selection of the buffer

```viml
:Neoformat
```

Or specify a certain formatter (must be defined for the current filetype)

```viml
:Neoformat jsbeautify
```

Or format a visual selection of code in a different filetype

**Note:** you must use a ! and pass the filetype of the selection

```viml
:Neoformat! python
```

You can also pass a formatter to use

```viml
:Neoformat! python yapf
```

Or perhaps run a formatter on save

```viml
augroup fmt
autocmd!
autocmd BufWritePre * undojoin | Neoformat
augroup END
```

The `undojoin` command will put changes made by Neoformat into the same
`undo-block` with the latest preceding change. See
[Managing Undo History](#managing-undo-history).

## Install

The best way to install Neoformat is with your favorite plugin manager for Vim, such as [vim-plug](https://github.com/junegunn/vim-plug):

```viml
Plug 'sbdchd/neoformat'
```

## Current Limitation(s)

If a formatter is either not configured to use `stdin`, or is not able to read
from `stdin`, then buffer data will be written to a file in `/tmp/neoformat/`,
where the formatter will then read from

## Config [Optional]

Define custom formatters.

Options:

| name | description | default | optional / required |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------------------- |
| `exe` | the name the formatter executable in the path | n/a | **required** |
| `args` | list of arguments | \[] | optional |
| `replace` | overwrite the file, instead of updating the buffer | 0 | optional |
| `stdin` | send data to the stdin of the formatter | 0 | optional |
| `stderr` | capture stderr output from formatter | 0 | optional |
| `no_append` | do not append the `path` of the file to the formatter command, used when the `path` is in the middle of a command | 0 | optional |
| `env` | list of environment variable definitions to be prepended to the formatter command | \[] | optional |
| `valid_exit_codes` | list of valid exit codes for formatters who do not respect common unix practices | \[0] | optional |
| `try_node_exe` | attempt to find `exe` in a `node_modules/.bin` directory in the current working directory or one of its parents (requires setting `g:neoformat_try_node_exe`) | 0 | optional |

Example:

```viml
let g:neoformat_python_autopep8 = {
\ 'exe': 'autopep8',
\ 'args': ['-s 4', '-E'],
\ 'replace': 1, " replace the file, instead of updating buffer (default: 0)
\ 'stdin': 1, " send data to stdin of formatter (default: 0)
\ 'env': ["DEBUG=1"], " prepend environment variables to formatter command
\ 'valid_exit_codes': [0, 23],
\ 'no_append': 1,
\ }

let g:neoformat_enabled_python = ['autopep8']
```

Configure enabled formatters.

```viml
let g:neoformat_enabled_python = ['autopep8', 'yapf', 'docformatter']
```

Have Neoformat use &formatprg as a formatter

```viml
let g:neoformat_try_formatprg = 1
```

Enable basic formatting when a filetype is not found. Disabled by default.

```viml
" Enable alignment
let g:neoformat_basic_format_align = 1

" Enable tab to spaces conversion
let g:neoformat_basic_format_retab = 1

" Enable trimmming of trailing whitespace
let g:neoformat_basic_format_trim = 1
```

Run all enabled formatters (by default Neoformat stops after the first formatter
succeeds)

```viml
let g:neoformat_run_all_formatters = 1
```

Above options can be activated or deactivated per buffer. For example:

```viml
" runs all formatters for current buffer without tab to spaces conversion
let b:neoformat_run_all_formatters = 1
let b:neoformat_basic_format_retab = 0
```

Have Neoformat only msg when there is an error

```viml
let g:neoformat_only_msg_on_error = 1
```

When debugging, you can enable either of following variables for extra logging.

```viml
let g:neoformat_verbose = 1 " only affects the verbosity of Neoformat
" Or
let &verbose = 1 " also increases verbosity of the editor as a whole
```

Have Neoformat look for a formatter executable in the `node_modules/.bin`
directory in the current working directory or one of its parents (only applies
to formatters with `try_node_exe` set to `1`):

```viml
let g:neoformat_try_node_exe = 1
```

## Adding a New Formatter

Note: you should replace everything `{{ }}` accordingly

1. Create a file in `autoload/neoformat/formatters/{{ filetype }}.vim` if it does not
already exist for your filetype.

2. Follow the following format

See Config above for options

```viml
function! neoformat#formatters#{{ filetype }}#enabled() abort
return ['{{ formatter name }}', '{{ other formatter name for filetype }}']
endfunction

function! neoformat#formatters#{{ filetype }}#{{ formatter name }}() abort
return {
\ 'exe': '{{ formatter name }}',
\ 'args': ['-s 4', '-q'],
\ 'stdin': 1
\ }
endfunction

function! neoformat#formatters#{{ filetype }}#{{ other formatter name }}() abort
return {'exe': {{ other formatter name }}
endfunction
```

## Managing Undo History

If you use an `autocmd` to run Neoformat on save, and you have your editor
configured to save automatically on `CursorHold` then you might run into
problems reverting changes. Pressing `u` will undo the last change made by
Neoformat instead of the change that you made yourself - and then Neoformat
will run again redoing the change that you just reverted. To avoid this
problem you can run Neoformat with the Vim `undojoin` command to put changes
made by Neoformat into the same `undo-block` with the preceding change. For
example:

```viml
augroup fmt
autocmd!
autocmd BufWritePre * undojoin | Neoformat
augroup END
```

When `undojoin` is used this way pressing `u` will "skip over" the Neoformat
changes - it will revert both the changes made by Neoformat and the change
that caused Neoformat to be invoked.

## Supported Filetypes

- Arduino
- [`uncrustify`](http://uncrustify.sourceforge.net),
[`clang-format`](http://clang.llvm.org/docs/ClangFormat.html),
[`astyle`](http://astyle.sourceforge.net)
- Assembly
- [`asmfmt`](https://github.com/klauspost/asmfmt)
- Astro
- [`prettier`](https://github.com/withastro/prettier-plugin-astro/)
- Bazel
- [`buildifier`](https://github.com/bazelbuild/buildtools/blob/master/buildifier/README.md)
- Beancount
- [`bean-format`](https://beancount.github.io/docs/running_beancount_and_generating_reports.html#bean-format)
- Blade
- [`blade-formatter`](https://github.com/shufo/blade-formatter)
- Bib
- [bibtex-tidy](https://github.com/FlamingTempura/bibtex-tidy)
- [bibclean](https://github.com/tobywf/bibclean)
- C
- [`uncrustify`](http://uncrustify.sourceforge.net),
[`clang-format`](http://clang.llvm.org/docs/ClangFormat.html),
[`astyle`](http://astyle.sourceforge.net)
- C#
- [`uncrustify`](http://uncrustify.sourceforge.net),
[`astyle`](http://astyle.sourceforge.net),
[`clang-format`](http://clang.llvm.org/docs/ClangFormat.html)
[`csharpier`](https://csharpier.com/)
- C++
- [`uncrustify`](http://uncrustify.sourceforge.net),
[`clang-format`](http://clang.llvm.org/docs/ClangFormat.html),
[`astyle`](http://astyle.sourceforge.net)
- Cabal
- [`cabal-fmt`](https://github.com/phadej/cabal-fmt)
- Caddyfile
- [`caddy fmt`](https://caddyserver.com/docs/command-line#caddy-fmt)
- CMake
- [`cmake_format`](https://github.com/cheshirekow/cmake_format)
- Crystal
- `crystal tool format` (ships with [`crystal`](http://crystal-lang.org))
- CSS
- `css-beautify` (ships with [`js-beautify`](https://github.com/beautify-web/js-beautify)),
[`prettydiff`](https://github.com/prettydiff/prettydiff),
[`stylefmt`](https://github.com/morishitter/stylefmt),
[`stylelint`](https://stylelint.io/),
[`csscomb`](http://csscomb.com),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier)
- CSV
- [`prettydiff`](https://github.com/prettydiff/prettydiff)
- Cue
- [`cue fmt`](https://cuelang.org/)
- D
- [`uncrustify`](http://uncrustify.sourceforge.net),
[`dfmt`](https://github.com/Hackerpilot/dfmt)
- D2
- [`d2 fmt`](https://d2lang.com/tour/auto-formatter)
- Dart
- [`dartfmt`](https://www.dartlang.org/tools/)
- [`dart format`](https://dart.dev/tools/dart-format)
- Dhall
- [`dhall format`](https://dhall-lang.org)
- dune
- [`dune format`](https://github.com/ocaml/dune)
- Ebuild
- [`shfmt`](https://github.com/mvdan/sh)
```vim
let g:shfmt_opt="-ci"
```
- Elixir
- [`mix format`](https://hexdocs.pm/mix/master/Mix.Tasks.Format.html)
- Elm
- [`elm-format`](https://github.com/avh4/elm-format)
- Eruby
- [`htmlbeautifier`](https://github.com/threedaymonk/htmlbeautifier)
- Erlang
- [`erlfmt`](https://github.com/WhatsApp/erlfmt)
- Fennel
- [`fnlfmt`](https://git.sr.ht/~technomancy/fnlfmt)
- Fish
- [`fish_indent`](http://fishshell.com)
- Fortran
- [`fprettify`](https://github.com/pseewald/fprettify)
- F#
- [`fantomas`](https://github.com/fsprojects/fantomas)
- GDScript
- [`gdformat`](https://github.com/Scony/godot-gdscript-toolkit)
- Gleam
- [`gleam format`](https://github.com/gleam-lang/gleam/)
- Go
- [`gofmt`](https://golang.org/cmd/gofmt/),
[`goimports`](https://godoc.org/golang.org/x/tools/cmd/goimports),
[`gofumpt`](https://github.com/mvdan/gofumpt),
[`gofumports`](https://github.com/mvdan/gofumpt)
- GLSL
- [`clang-format`](http://clang.llvm.org/docs/ClangFormat.html)
- GN
- [`gn`](https://gn.googlesource.com/gn)
- GraphQL
- [`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier)
- Haskell
- [`stylishhaskell`](https://github.com/jaspervdj/stylish-haskell),
[`hindent`](https://github.com/chrisdone/hindent),
[`hfmt`](https://github.com/danstiner/hfmt),
[`brittany`](https://github.com/lspitzner/brittany),
[`sortimports`](https://github.com/evanrelf/sort-imports),
[`floskell`](https://github.com/ennocramer/floskell)
[`ormolu`](https://github.com/tweag/ormolu)
```vim
let g:ormolu_ghc_opt=["TypeApplications", "RankNTypes"]
```
- You must use formatter's name without "`-`"
```vim
" right
let g:neoformat_enabled_haskell = ['sortimports', 'stylishhaskell']
" wrong
let g:neoformat_enabled_haskell = ['sort-imports', 'stylish-haskell']
```
- HCL
- [`hclfmt`](https://github.com/hashicorp/hcl)
- Toml
- [`taplo`](https://taplo.tamasfe.dev/cli/usage/formatting.html),
[`topiary`](https://topiary.tweag.io)
- Puppet
- [`puppet-lint`](https://github.com/rodjek/puppet-lint)
- PureScript
- [`purs-tidy`](https://github.com/natefaubion/purescript-tidy)
- [`purty`](https://gitlab.com/joneshf/purty)
- HTML
- `html-beautify` (ships with [`js-beautify`](https://github.com/beautify-web/js-beautify)),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier),
[`prettydiff`](https://github.com/prettydiff/prettydiff)
- HTMLDjango
- [djlint](https://djlint.com/)
- Jade
- [`pug-beautifier`](https://github.com/vingorius/pug-beautifier)
- Java
- [`uncrustify`](http://uncrustify.sourceforge.net),
[`astyle`](http://astyle.sourceforge.net),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier)
- JavaScript
- [`js-beautify`](https://github.com/beautify-web/js-beautify),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier),
[`prettydiff`](https://github.com/prettydiff/prettydiff),
[`clang-format`](http://clang.llvm.org/docs/ClangFormat.html),
[`esformatter`](https://github.com/millermedeiros/esformatter/),
[`prettier-eslint`](https://github.com/kentcdodds/prettier-eslint-cli),
[`eslint_d`](https://github.com/mantoni/eslint_d.js),
[`standard`](https://standardjs.com/),
[`semistandard`](https://github.com/standard/semistandard),
[`deno fmt`](https://deno.land/manual/tools/formatter),
[`biome format`](https://biomejs.dev)
- JSON
- [`js-beautify`](https://github.com/beautify-web/js-beautify),
[`prettydiff`](https://github.com/prettydiff/prettydiff),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier),
[`jq`](https://stedolan.github.io/jq/),
[`fixjson`](https://github.com/rhysd/fixjson),
[`deno fmt`](https://deno.land/manual/tools/formatter),
[`topiary`](https://topiary.tweag.io),
[`biome format`](https://biomejs.dev)
- JSONC (JSON with comments)
- [`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier),
[`deno fmt`](https://deno.land/manual/tools/formatter),
[`biome format`](https://biomejs.dev)
- jsonnet
- [`jsonnetfmt`](https://github.com/google/jsonnet)
- just
- [`just`](https://github.com/casey/just)
- Kotlin
- [`ktlint`](https://github.com/shyiko/ktlint),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier)
- LaTeX
- [`latexindent`](https://github.com/cmhughes/latexindent.pl)
```vim
let g:latexindent_opt="-m"
```
- Less
- [`csscomb`](http://csscomb.com),
[`prettydiff`](https://github.com/prettydiff/prettydiff),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier),
[`stylelint`](https://stylelint.io/)
- Lua
- [`luaformatter`](https://github.com/LuaDevelopmentTools/luaformatter)
- [`lua-fmt`](https://github.com/trixnz/lua-fmt)
- [`lua-format`](https://github.com/Koihik/LuaFormatter)
- [`stylua`](https://github.com/JohnnyMorganz/StyLua)
- Markdown
- [`remark`](https://github.com/wooorm/remark),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier),
[`deno fmt`](https://deno.land/manual/tools/formatter),
[`mdformat`](https://github.com/executablebooks/mdformat)
- Matlab
- [`matlab-formatter-vscode`](https://github.com/affenwiesel/matlab-formatter-vscode)
- Nginx
- [nginxbeautifier](https://github.com/vasilevich/nginxbeautifier)
- Nickel
- [`topiary`](https://topiary.tweag.io)
- Nim
- `nimpretty` (ships with [`nim`](https://nim-lang.org/))
- [`nph`](https://github.com/arnetheduck/nph)
- Nix
- [`nixfmt`](https://github.com/serokell/nixfmt)
- [`nixpkgs-fmt`](https://github.com/nix-community/nixpkgs-fmt)
- [`alejandra`](https://github.com/kamadorueda/alejandra)
- Objective-C
- [`uncrustify`](http://uncrustify.sourceforge.net),
[`clang-format`](http://clang.llvm.org/docs/ClangFormat.html),
[`astyle`](http://astyle.sourceforge.net)
- Objective-C++
- [`uncrustify`](http://uncrustify.sourceforge.net),
[`clang-format`](http://clang.llvm.org/docs/ClangFormat.html),
[`astyle`](http://astyle.sourceforge.net)
- OCaml
- [`ocp-indent`](http://www.typerex.org/ocp-indent.html),
[`ocamlformat`](https://github.com/ocaml-ppx/ocamlformat),
[`topiary`](https://topiary.tweag.io)
- OpenSCAD
- [`openscad-format`](https://github.com/Maxattax97/openscad-format)
- Pandoc Markdown
- [`pandoc`](https://pandoc.org/MANUAL.html)
- Pawn
- [`uncrustify`](http://uncrustify.sourceforge.net)
- Perl
- [`perltidy`](http://perltidy.sourceforge.net)
- [`perlimports`](https://github.com/perl-ide/App-perlimports)
- PHP
- [`php_beautifier`](http://pear.php.net/package/PHP_Beautifier),
[`php-cs-fixer`](http://cs.sensiolabs.org/),
[`phpcbf`](https://github.com/squizlabs/PHP_CodeSniffer),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/plugin-php)
[`laravel-pint`](https://github.com/laravel/pint),
- PowerShell
- [`PSScriptAnalyzer`](https://github.com/PowerShell/PSScriptAnalyzer),
[`PowerShell-Beautifier`](https://github.com/DTW-DanWard/PowerShell-Beautifier)
- Prisma
- [`prettier`](https://github.com/umidbekk/prettier-plugin-prisma)
- Proto
- [`clang-format`](http://clang.llvm.org/docs/ClangFormat.html)
- Pug (formally Jade)
- [`pug-beautifier`](https://github.com/vingorius/pug-beautifier)
- Python
- [`yapf`](https://github.com/google/yapf),
[`autopep8`](https://github.com/hhatto/autopep8),
[`black`](https://github.com/psf/black),
[`pydevf`](https://github.com/fabioz/PyDev.Formatter),
[`isort`](https://github.com/timothycrosley/isort),
[`docformatter`](https://github.com/myint/docformatter),
[`pyment`](https://github.com/dadadel/pyment),
[`ruff`](https://github.com/astral-sh/ruff)
- R
- [`styler`](https://github.com/r-lib/styler),
[`formatR`](https://github.com/yihui/formatR)
- Reason
- [`refmt`](https://github.com/facebook/reason)
- [`bsrefmt`](https://github.com/bucklescript/bucklescript)
- Rego
- [`opa fmt`](https://www.openpolicyagent.org/docs/latest/cli/#opa-fmt)
- Ruby
- [`rufo`](https://github.com/ruby-formatter/rufo),
[`ruby-beautify`](https://github.com/erniebrodeur/ruby-beautify),
[`rubocop`](https://github.com/rubocop/rubocop),
[`standard`](https://github.com/testdouble/standard)
[`prettier`](https://github.com/prettier/plugin-ruby)
- Rust
- [`rustfmt`](https://github.com/rust-lang-nursery/rustfmt),
[`topiary`](https://topiary.tweag.io)
- Sass
- [`sass-convert`](http://sass-lang.com/documentation/#executables),
[`stylelint`](https://stylelint.io/),
[`csscomb`](http://csscomb.com)
- Sbt
- [`scalafmt`](http://scalameta.org/scalafmt/)
- Scala
- [`scalariform`](https://github.com/scala-ide/scalariform),
[`scalafmt`](http://scalameta.org/scalafmt/)
- SCSS
- [`sass-convert`](http://sass-lang.com/documentation/#executables),
[`stylelint`](https://stylelint.io/),
[`stylefmt`](https://github.com/morishitter/stylefmt),
[`prettydiff`](https://github.com/prettydiff/prettydiff),
[`csscomb`](http://csscomb.com),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier)
- Shell
- [`shfmt`](https://github.com/mvdan/sh)
```vim
let g:shfmt_opt="-ci"
```
- [`topiary`](https://topiary.tweag.io)
- Solidity
- [`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier-solidity/prettier-plugin-solidity),
[`forge fmt`](https://book.getfoundry.sh/)
- SQL
- [`sqlfmt`](https://github.com/jackc/sqlfmt),
`sqlformat` (ships with [sqlparse](https://github.com/andialbrecht/sqlparse)),
`pg_format` (ships with [pgFormatter](https://github.com/darold/pgFormatter)),
[`sleek`](https://github.com/nrempel/sleek)
- Starlark
- [`buildifier`](https://github.com/bazelbuild/buildtools/blob/master/buildifier/README.md)
- SugarSS
[`stylelint`](https://stylelint.io/)
- Svelte
- [`prettierd`](https://github.com/fsouza/prettierd),
[`prettier-plugin-svelte`](https://github.com/UnwrittenFun/prettier-plugin-svelte)
- Swift
- [`Swiftformat`](https://github.com/nicklockwood/SwiftFormat)
- Terraform
- [`terraform`](https://www.terraform.io/docs/commands/fmt.html),
- TypeScript
- [`tsfmt`](https://github.com/vvakame/typescript-formatter),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier),
[`prettier-eslint`](https://github.com/kentcdodds/prettier-eslint-cli),
[`tslint`](https://palantir.github.io/tslint),
[`eslint_d`](https://github.com/mantoni/eslint_d.js),
[`clang-format`](http://clang.llvm.org/docs/ClangFormat.html),
[`deno fmt`](https://deno.land/manual/tools/formatter),
[`biome format`](https://biomejs.dev)
- Typst
- [`typstfmt`](https://github.com/astrale-sharp/typstfmt)
[`typstyle`](https://github.com/Enter-tainer/typstyle)
- V
- `v fmt` (ships with [`v`](https://vlang.io))
- VALA
- [`uncrustify`](http://uncrustify.sourceforge.net)
- Vue
- [`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier)
- XHTML
- [`tidy`](http://www.html-tidy.org),
[`prettydiff`](https://github.com/prettydiff/prettydiff)
- XML
- [`tidy`](http://www.html-tidy.org),
[`prettydiff`](https://github.com/prettydiff/prettydiff),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier),
[`xmllint`](https://gitlab.gnome.org/GNOME/libxml2)
- YAML
- [`pyaml`](https://pypi.python.org/pypi/pyaml),
[`prettierd`](https://github.com/fsouza/prettierd),
[`prettier`](https://github.com/prettier/prettier),
[`yamlfmt`](https://github.com/mmlb/yamlfmt) (by @mmlb),
[`yamlfmt`](https://github.com/google/yamlfmt) (by @google),
[`yamlfix`](https://github.com/lyz-code/yamlfix)
- zig
- [`zigformat`](https://github.com/Himujjal/zigformat)
[`zig fmt`](https://github.com/ziglang/zig)
- zsh
- [`shfmt`](https://github.com/mvdan/sh)
```vim
let g:shfmt_opt="-ci"
```