parfit 0.1.0

Paragraph fit — a codebase-aware comment reflow tool that wraps prose with optimal-fit line breaking and leaves directives alone. Inspired by par.
Documentation

parfit

Paragraph fit — a codebase-aware comment reflow tool. Wraps the prose inside code comments at a sensible width with optimal-fit line breaking, and leaves machine-readable directives alone.

Inspired by Adam M. Costello's par (1993).

What it does

$ cat foo.go
// parfit is a codebase-aware comment reflow tool that wraps long lines at a sensible width while leaving machine-readable directives alone.

//go:generate stringer -type=Foo

// see https://example.com/a/very/long/url for more context here

$ cat foo.go | parfit
// parfit is a codebase-aware comment reflow tool that wraps
// long lines at a sensible width while leaving machine-readable
// directives alone.

//go:generate stringer -type=Foo

// see https://example.com/a/very/long/url for more context here

How it differs from par

  • Optimal-fit line breaks, not greedy. Uses dynamic programming to minimise raggedness, so the last line of a paragraph is rarely left dangling. This is the Knuth-Plass approach the TeX line-breaker uses.
  • Knows what directives look like. //go:generate, // +build, //nolint, // eslint-disable, // @ts-ignore, #!/usr/bin/env …, # type:, # noqa, Rust attributes, and other machine-readable annotations pass through unchanged. par happily mangles them.
  • URL-safe. Words containing :// never split.
  • Prefix auto-detection. Works with //, ///, //!, #, ;, * (C multi-line continuation), and picks up leading indentation automatically.

Install

cargo install parfit

Installs a parfit binary.

Use

parfit                            # reads stdin, writes stdout, width 68
parfit --width 72                 # override width
parfit --skip 'TODO\(.+\):'       # pass any lines matching this regex through unchanged
parfit --no-default-skips         # turn the built-in directive list off
parfit --prefix '// '             # force a specific comment marker

Editor integration is just "pipe selection through parfit":

Vim: select a comment block in visual mode, then :!parfit.

Emacs: M-| parfit RET on a region.

VS Code: bind a keystroke to "Filter Through Command" pointing at parfit, or use any "run shell command on selection" extension.

Built-in skip patterns

On by default; turn off with --no-default-skips.

Language Patterns
Go //go:, // +build, //nolint, //noinspection, //lint:
Rust #[, #![
Shell #!/ (shebangs)
Python # type:, # noqa, # pragma:
TS / JS // @ts-, // eslint-, /* eslint-, // @param/@returns/@internal/@deprecated/@see
Generic Lone-URL lines, separator lines (// ---)

License

MIT. See LICENSE.