A plugin for vis to integrate prettier
,
rustfmt
etc.
Clone this repository to where you install your plugins. (If this is your first
plugin, running git clone https://github.com/milhnl/vis-format
in
~/.config/vis/
will probably work).
Then, add something like the following to your visrc
.
local format = require('vis-format')
vis:map(vis.modes.NORMAL, '=', format.apply)
Press =
to format the whole file.
Currently, the following formatters are supported out-of-the-box.
bash
: shfmtcsharp
: CSharpier. Although dotnet-format is the 'default' formatter for dotnet, it does not support formatting stdin (and does not break lines).git-commit
: Actuallydiff
with an extra check, as that's howvis.ftdetect
ends up labeling it. Usesfmt -w
and some glue code to reformat the commit body, but not the summary and comments.go
:gofmt
lua
: StyLua and LuaFormatter, depending on which config file is in the working directory.markdown
:prettier
with--prose-wrap
enabled ifcolorcolumn
is set.powershell
: PSScriptAnalyzer viapowershell.exe
in the WSL if available orpwsh
.rust
:rustfmt
text
:fmt
with width based on colorcolumn if set, otherwise joined paragraphs.
I'm working on some more heuristics for detecting which formatter to use for languages without a 'blessed' formatter. In the meantime, this is how you add the ones you want to use:
format.formatters.html = format.stdio_formatter("prettier --parser html")
The following methods and tables are fields of the table that is returned by
require('vis-format')
(e.g. format
). You can use them to extend or
configure vis-format
.
A table containing the configured formatters. There are some predefined (see
the list above under "Usage"), and you can add or override those by assigning
your formatter to a key corresponding to the vis syntax
it is relevant for.
Each entry is of either of these forms:
{
apply = func(win, range, pos) end,
options = {
ranged = nil,
check_same = nil,
}
}
or
{
pick = func(win, range, pos) end,
}
The first form directly defines a formatter. An entry containing pick
is
executed and its result is directly used as a formatter. A recommended way to
use pick
is to return a different formatter from the formatters
table. Note
that using the vis syntax
as keys in this table is only necessary for
formatters that are run directly. This means that lua
is a good key for a
pick
entry, which chooses between the formatters found at stylua
and
luaformatter
.
The stdio_formatter
function wraps the command to produce something like
this:
{
apply = function(win, range, pos) end,
options = { ranged = false }
}
The command given can also be a function, which is expected to return a string,
which is then used as a command. This allows you to use the given range, or
options from win
. ranged
is automatically set to true in this case.
Apart from mapping vis-format
in normal mode, you can also define an operator
(with vis:operator_new
) to format ranges of code/text. This will require a
formatter that can work with ranges of text. Configuring that looks like this:
-- Add a formatter that can use a range
format.formatters.lua = format.stdio_formatter(function(win, range, pos)
return 'stylua -s --range-start ' .. range.start .. ' --range-end '
.. range.finish .. ' -'
end)
-- Bind it to keys
vis:operator_new('=', format.apply) -- this'll handle ranges
vis:map(vis.modes.NORMAL, '=', function() -- this'll format whole files
format.apply(vis.win.file, nil, vis.win.selection.pos)
end)
Most formatters take a path for where stdin
would be. If the file has a path
with_filename
concatenates the option and the shell-escaped path. Note that
it does not add any spaces to separate options/arguments.
stdio_formatter(function(win)
return 'shfmt ' .. with_filename(win, '--filename ') .. ' -'
end, { ranged = false })
options.check_same
(boolean|number
) — After formatting, to avoid updating the file,vis-format
can compare the old and the new. If this is set to a number, that's the maximum size of the file for which it is enabled. This option is also available in the per-formatter options.
Ranged formatting is not enabled and will currently not work with prettier
.
Prettier extends the range given on the command line to the beginning and end
of the statement containing it. This will not work with how vis-format
currently applies the output. I have some ideas on how to fix this, but wanted
to release what works first.
vis
has an options
table with editor settings like tab width etc. built-in
since 0.9. vis-format
will not read this most of the time, because the
correct way to configure formatters is with their dedicated configuration
files, or .editorconfig
(Which can be read in vis with
vis-editorconfig and
vis-editorconfig-options
).
The included formatter integrations that do use this information assume that
the options
table in vis
and win
is present. If you use an older version,
vis-format
will still work, but can't detect your editor settings. To fix
that, look at the
vis-options-backport plugin.
This will 'polyfill' that for older versions.