Skip to content

About

Auto-formatter for modern Fortran source code

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

fprettier

fprettier is an auto-formatter for Fortran 90+ code.

fprettier is inspired by fprettify but strives to be:

  • ⚡ Fast, especially for large codebases
  • 🔧 Actively maintained, with prompt responses to issues

Installation

First, install Rust and Cargo by following the instructions at:

https://rustup.rs

Then install fprettier:

cargo install fprettier

Usage

Run fprettier with no arguments to display the usage information.

Format files in-place:

fprettier -r src/

Verify formatting without modifying files — prints the files that would change and exits non-zero if there are any, so CI needs just one step:

fprettier --check -r src/

Show what would change as a unified diff, without modifying files:

fprettier --diff -r src/

Configuration

Settings come from three places. Each overrides the one before it:

  1. fprettier.toml files
  2. command-line flags
  3. an ! fprettier: directive in the file being formatted

Config files

fprettier looks for fprettier.toml in your home directory, then in every directory from the filesystem root down to the file being formatted. Files found later win, so a fprettier.toml beside the source overrides one at the top of the repository. Only the keys a file actually sets are applied. --config PATH uses one file and skips the search.

indent = 4                      # spaces per indent level
line_length = 132               # maximum line length
whitespace = 2                  # whitespace level, 0-4 (see below)
impose_indent = true            # apply indentation
impose_whitespace = true        # apply whitespace formatting
strict_indent = true            # re-indent IF/DO even when already aligned
indent_fypp = true              # indent fypp preprocessor blocks
indent_mod = true               # indent module/program/submodule bodies
format_decl = false             # normalize spacing around ::
comment_spacing = 1             # spaces before an inline comment
normalize_comment_spacing = false   # apply comment_spacing everywhere
enable_replacements = false     # convert between .lt. and < style operators
c_relations = false             # with enable_replacements, prefer < over .lt.
sort_use = false                # sort use statements alphabetically within a group
sort_use_only = false           # sort the names in a use ... only: list

Whitespace levels

whitespace selects a preset: 0 adds no spacing, 1 covers commas, assignments, relational and logical operators, print/read statements, intrinsic calls and ::; 2 adds + and -; 3 adds * and /; 4 adds % and //. The default is 2.

Override individual rules with [whitespace_dict], which wins over the level:

whitespace = 2

[whitespace_dict]
comma = true            # after , and ;
assignments = true      # around = and =>
relational = true       # around <, >, ==, /=, .eq., ...
logical = true          # around .and., .or., ...
plusminus = true        # around binary + and -
multdiv = false         # around binary * and /
print = true            # in print/read statements
type = false            # around the % component selector
intrinsics = true       # before intrinsic call parentheses
decl = true             # around ::
concat = false          # around //

Each key has a matching flag, for example --whitespace-multdiv=true.

Case conversion

Each category takes 0 (leave alone), 1 (lowercase) or 2 (uppercase). Nothing is converted by default.

[case_dict]
keywords = 1        # if, then, subroutine, integer, ...
procedures = 1      # intrinsics called as functions: sin(x), size(a)
operators = 1       # .and., .eq., .true., ...
constants = 1       # iso_fortran_env and iso_c_binding names: output_unit, c_int
types = 2           # kind= values, literal kind suffixes and exponent letters

types is narrower than its name suggests. It covers real(kind=dp), the suffix in 2_int64, and the exponent letter in 1.0e-3 — not derived type names, and not real(dp) written without kind=:

real(kind=dp) :: a = 2.5e-8_real64    ! types = 2
real(kind=DP) :: a = 2.5E-8_REAL64

On the command line, the first four are one flag and types is its own, because a fifth value would be read as a file name:

fprettier --case 1 1 1 1 --case-types 2 -r src/

Sorting use statements

Nothing is sorted by default. sort_use (--sort-use) sorts use statements alphabetically, sort_use_only (--sort-use-only) sorts the names in an only: list. Use either alone or both together:

use foo
use bar

use gamma, only: delta, beta
use beta, only: zulu, alfa => tango

becomes

use bar
use foo

use beta, only: alfa => tango, zulu
use gamma, only: beta, delta

Sorting use statements with --sort-use and --sort-use-only

A group is a run of use statements with nothing between them. A blank line, a comment, a preprocessor directive, or any other statement ends the group and starts a new one, so use statements in different #:if branches never mix. Statements marked with !& or inside a !&<…!&> block stay where they are.

Comparison ignores case, and a rename sorts on its local name: c => x sorts under c. A statement moves as a whole, together with its continuation lines and its trailing comment.

sort_use_only rewrites the only: list as one logical line, which the usual line-length splitter then re-breaks — so a hand-broken list is re-flowed. A statement carrying a comment on a line other than its last is left alone, since that comment would have nowhere to go.

In-file directives

A comment anywhere in a file overrides everything else for that file:

! fprettier: --indent 2 --line-length 100 --case 1 1 1 1 --case-types 2

Directives accept -i/--indent, -l/--line-length, -w/--whitespace, --case, --case-types, --no-indent, --enable-indent, --no-whitespace and --enable-whitespace. Only the first directive in a file is used, so put every option on that one line; later directives are ignored, not merged.

Turning formatting off

!& at the end of a line leaves that line alone. !&< and !&> mark a block to leave alone:

matrix = [1, 0, &   !&<
          0, 1]     !&>

Changelog

See CHANGELOG.md.

About

Auto-formatter for modern Fortran source code

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages