parfit 0.2.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

Callum Dempsey Leach, 2026

Abstract

parfit reflows the prose inside code comments to a target width using optimal-fit line breaking, and passes machine-readable directives through unchanged. It is inspired by Adam M. Costello's par (1993) and aims to be a drop-in for the same niche with codebase awareness added.

1. Introduction

Code comments tend to accumulate long lines because editors autocomplete faster than humans press return. A reflow tool pipes a block of comments through a line breaker and puts them back at a sensible width. par has done this since 1993. Its greedy line breaker leaves orphan lines, and it does not know that //go:generate is a directive rather than prose.

parfit uses the optimal-fit (Knuth-Plass) algorithm to minimise raggedness, and ships a default list of directive patterns for Go, Rust, TypeScript, JavaScript, Python, and shell so tooling annotations are left alone. Custom patterns are accepted via -s/--skip.

2. Installation

cargo install parfit

Installs a parfit binary on $PATH.

3. Synopsis

parfit [OPTIONS] [PATH]...

With no PATH arguments parfit reads standard input and writes standard output. With one file path it reads that file and writes stdout. With multiple files, directories, or --recursive, use --in-place to rewrite the files.

4. Examples

Pipe a single block through:

cat foo.go | parfit

Reflow one file, preview result on stdout:

parfit foo.go

Reflow one file in place:

parfit --in-place foo.go

Recursively reflow every .go file under the current directory in place:

parfit --recursive --in-place --include '*.go' .

Reflow every .rs file except anything in target/:

parfit --recursive --in-place --include '*.rs' --exclude 'target/*' .

Directory walks respect .gitignore and other ignore rules by default (powered by the same walker as ripgrep and fd).

5. Options

-w N, --width N Target width in columns, inclusive of the detected prefix. Default 68.

-r, --recursive Walk directories recursively. Required when any path argument is a directory.

-i, --in-place Rewrite files in place instead of emitting to stdout. Required when more than one file will be processed.

--include GLOB Glob of file names to include. Repeatable. Applies only when path arguments are given.

--exclude GLOB Glob of file names to exclude. Repeatable.

-s REGEX, --skip REGEX Append a regular expression to the skip list. Paragraphs containing any matching line pass through verbatim. Repeatable.

--no-default-skips Disable the built-in directive patterns. Only user patterns supplied via --skip remain active.

-p STRING, --prefix STRING Force the given string as the comment prefix on every paragraph instead of auto-detecting.

6. Default skip patterns

Active unless --no-default-skips is given:

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

7. Prefix detection

parfit detects the prefix on each paragraph from its first line, matching the leading whitespace followed by one of:

/// , //! , // , /** , /* , */ ,  * , * , #! , # , ;

The detected prefix is preserved verbatim on every output line. When multiple consecutive lines share a prefix they are treated as a single paragraph; a blank line or a prefix change ends it.

8. Editor integration

parfit is a filter. Any editor that can pipe a visual selection through a command can use it.

  • Vim — select a comment block, then :!parfit.
  • EmacsM-| parfit RET on a region.
  • VS Code — bind a key to "Filter Through Command" running parfit.

9. Differences from par

  • Optimal-fit line breaking rather than greedy. The last line of a paragraph is rarely left short; Knuth-Plass dynamic programming distributes slack evenly.
  • Built-in directive awareness. par reformats //go:generate just like prose; parfit leaves it alone.
  • URL safety. Words containing :// never split.
  • Prefix auto-detection covering the comment markers of the most common programming languages, not just character classes.
  • Recursive directory walking with glob filtering and in-place edits.

10. License

MIT. See LICENSE.

11. References

[1] Costello, A.M., "par - a paragraph reformatter", 1993. http://www.nicemice.net/par/

[2] Knuth, D.E. and Plass, M.F., "Breaking Paragraphs into Lines", Software: Practice and Experience, Vol. 11, Issue 11, November 1981, pp. 1119-1184.

[3] textwrap crate (Martin Geisler), used by parfit for the optimal-fit implementation. https://crates.io/crates/textwrap

[4] ignore crate (Andrew Gallant), used by parfit's directory walker. https://crates.io/crates/ignore