Skip to content

milhnl/vis-format

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 

Repository files navigation

vis-format - integrates vis with external formatters

A plugin for vis to integrate prettier, rustfmt etc.

Installation

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)

Usage

Press = to format the whole file.

Currently, the following formatters are supported out-of-the-box.

  • bash: shfmt
  • csharp: CSharpier. Although dotnet-format is the 'default' formatter for dotnet, it does not support formatting stdin (and does not break lines).
  • git-commit: Actually diff with an extra check, as that's how vis.ftdetect ends up labeling it. Uses fmt -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 if colorcolumn is set.
  • powershell: PSScriptAnalyzer via powershell.exe in the WSL if available or pwsh.
  • 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")

Advanced usage

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.

formatters

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.

stdio_formatter

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)

with_filename

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

  • 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.

Bugs

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.

Note on editor options and vis versions before 0.9

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.

About

integrate vis with external formatters

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages