Skip to main content

A fast, configurable Fortran formatter with Fypp, Doxygen, and OpenACC/OpenMP support

Project description

ffmt

PyPI CI License: MIT GitHub Marketplace

A fast, configurable Fortran formatter with support for Fypp, Doxygen, and OpenACC/OpenMP directives. Written in Rust. Installable via pip.

Installation

pip install ffmt

Or via Cargo:

cargo install ffmt

Usage

ffmt src/                        # format in-place
ffmt --check src/                # CI mode (exit 1 if changes needed)
ffmt --diff src/                 # show colored diff
ffmt -j 8 src/                   # parallel
cat file.fpp | ffmt -            # stdin/stdout
ffmt --range 10:50 file.fpp      # format only lines 10-50

What it does

  • Indentation -- scope-based indentation for all Fortran constructs
  • Whitespace -- consistent spacing around operators, commas, colons, parentheses
  • Keywords -- case normalization (IF -> if, ENDDO -> end do)
  • Continuation lines -- normalized with proportional re-indentation
  • Preprocessor -- Fypp (#:if, #:for), OpenACC (!$acc), OpenMP (!$omp) handled correctly

Configuration

Create ffmt.toml or add [tool.ffmt] to pyproject.toml. All options have sensible defaults -- most projects need no config file at all.

General

Option Default Description
indent-width 4 Number of spaces per indentation level.
line-length 132 Maximum line length. Code and comments are wrapped at this limit. Set to 1000 to disable wrapping.
keyword-case "lower" Case for Fortran keywords: "lower", "upper", or "preserve".
normalize-keywords true Split compound keywords like enddo into end do.
named-ends true Add procedure/module name to bare end statements (end subroutine -> end subroutine s_foo).
align-declarations true Vertically align :: in consecutive declaration blocks.
unicode-to-ascii true Replace Unicode Greek letters and math symbols with LaTeX equivalents in comments (σ -> \sigma).
rewrap-comments true Re-wrap long comments at line-length, splitting at word boundaries. Doxygen !> / !! blocks are joined and re-wrapped as units.
rewrap-code true Re-wrap long code lines at line-length using token-aware splitting (never breaks inside numbers or strings).
space-after-comment true Ensure a space after ! in regular comments (!comment -> ! comment). Does not affect !$acc, !<, !>, !!, or !&.
collapse-double-spaces true Collapse runs of multiple spaces to a single space in code (not in strings or comments).
keyword-paren-space true Add a space between control-flow keywords and ( (if( -> if (). Applies to if, call, allocate, select case, where, etc.
fypp-list-commas true Normalize comma spacing inside Fypp '[...]' list arguments.
indent-fypp true Indent Fypp preprocessor blocks (#:if, #:for, #:call).
indent-module true Indent the body of module and program blocks.

Whitespace

The [whitespace] section controls spacing around specific operators:

Option Default Description
relational true Space around ==, /=, <, <=, >, >=.
logical true Space around .and., .or., .not., .eqv., .neqv..
plusminus true Space around binary + and -.
multdiv false Space around * and /.
power false Space around **.
assignment true Space around = in assignments.
pointer true Space around =>.
concatenation true Space around // (string concatenation).
declaration true Space around :: in declarations.
comma true Space after ,.
slice-colon false Space around : in array slices.

Files

Option Default Description
extensions ["fpp", "f90", "F90", "f95", "f03", "F", "F95", "F03"] File extensions to format.
exclude [] Glob patterns to exclude.
respect-gitignore true Skip files listed in .gitignore.

Example

indent-width = 4
line-length = 132
keyword-case = "lower"
normalize-keywords = true

[whitespace]
relational = true
logical = true
plusminus = true
multdiv = false
power = false
assignment = true
declaration = true
comma = true

Preserved as-is

  • String literals and inline expressions (${...}$, @{...}@)
  • Comment contents and Doxygen alignment (!<, !>, !!)
  • Continuation line structure across #ifdef/#:if preprocessor blocks
  • #ifdef/#endif blocks (no indentation change)
  • Fypp/Python code inside $: and @: macro invocations

Editor integration

ffmt includes a built-in LSP server for real-time format-on-save:

ffmt --lsp

VS Code

{
    "fortran.formatting.formatter": "ffmt",
    "fortran.formatting.args": ["--stdin-filepath", "${file}", "-"]
}

Vim/Neovim

autocmd BufWritePost *.fpp,*.f90 silent !ffmt %
" Or: set formatprg=ffmt\ -

Neovim (LSP)

vim.lsp.start({
    name = "ffmt",
    cmd = { "ffmt", "--lsp" },
    root_dir = vim.fs.dirname(vim.fs.find({ "ffmt.toml", "pyproject.toml" }, { upward = true })[1]),
})

CI integration

GitHub Actions

- uses: sbryngelson/ffmt@latest
  with:
    args: "--check src/"

pre-commit

repos:
  - repo: https://github.com/sbryngelson/ffmt
    rev: v0.2.1
    hooks:
      - id: ffmt

To auto-update to the latest version, run:

pre-commit autoupdate

Or use pre-commit.ci to update hooks automatically via pull requests.

Other Fortran Formatters

Formatter Language Status Notes
fprettify Python Unmaintained (last release 2020) Free-form only. Fypp support. Requires multiple passes for convergence.
findent C Active Indentation and fixed/free conversion. No whitespace normalization.
Codee Formatter Proprietary Active Commercial. Tree-sitter based. Fixed and free-form.
LFortran fmt Rust In development AST-based. Part of the LFortran compiler project.
Fortitude Rust Active Linter with auto-fix, not a full formatter. Tree-sitter based.
f90-mode Emacs Lisp Active Emacs built-in. Indentation only.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ffmt-0.2.8.tar.gz (67.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ffmt-0.2.8-py3-none-win_amd64.whl (1.5 MB view details)

Uploaded Python 3Windows x86-64

ffmt-0.2.8-py3-none-manylinux_2_34_x86_64.whl (1.8 MB view details)

Uploaded Python 3manylinux: glibc 2.34+ x86-64

ffmt-0.2.8-py3-none-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file ffmt-0.2.8.tar.gz.

File metadata

  • Download URL: ffmt-0.2.8.tar.gz
  • Upload date:
  • Size: 67.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ffmt-0.2.8.tar.gz
Algorithm Hash digest
SHA256 df0a7661541d65f27faca062874a809577c328a2b17f07af3245ed07fd2919f9
MD5 670e77dff3c337c1c5bc524e42cf6407
BLAKE2b-256 cc146ef79771747c0ec305ae0a0cdf0d6a8af5d649eef332b166f72159190e9a

See more details on using hashes here.

Provenance

The following attestation bundles were made for ffmt-0.2.8.tar.gz:

Publisher: release.yml on sbryngelson/ffmt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ffmt-0.2.8-py3-none-win_amd64.whl.

File metadata

  • Download URL: ffmt-0.2.8-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ffmt-0.2.8-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 c99a212da04566db16d2096e97d330a40684b697f0a2e74562a3fc45c5a3f15f
MD5 b8471b8f9efa5a325fc13b32429d708c
BLAKE2b-256 b56ee67c62f63b20700a1d77acc1591d00cd70d7b58f87b4a72cea1092d60f80

See more details on using hashes here.

Provenance

The following attestation bundles were made for ffmt-0.2.8-py3-none-win_amd64.whl:

Publisher: release.yml on sbryngelson/ffmt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ffmt-0.2.8-py3-none-manylinux_2_34_x86_64.whl.

File metadata

  • Download URL: ffmt-0.2.8-py3-none-manylinux_2_34_x86_64.whl
  • Upload date:
  • Size: 1.8 MB
  • Tags: Python 3, manylinux: glibc 2.34+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ffmt-0.2.8-py3-none-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 e70f9bf51ea70409fcb5322da42c0742946c1f9b240ee773960432b394709792
MD5 d0b31d7077e3fda5421327a2b6efd78e
BLAKE2b-256 0eada35d1d7a0f64985e2c13a7940bd1bb60b4abfe868ae9a0a893f0bda3da4a

See more details on using hashes here.

Provenance

The following attestation bundles were made for ffmt-0.2.8-py3-none-manylinux_2_34_x86_64.whl:

Publisher: release.yml on sbryngelson/ffmt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ffmt-0.2.8-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: ffmt-0.2.8-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 1.6 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ffmt-0.2.8-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a60f5d1f4620fb799280fd2ff64eeb485458f0e4f94ff043d01ea6d11cc37913
MD5 8d30ce5bad55b9bb04ee070a4f67a278
BLAKE2b-256 3d4f49af7fc16b6387a02b34f8af21adb0dc4b1ae5ccddb5e4555235ff65414a

See more details on using hashes here.

Provenance

The following attestation bundles were made for ffmt-0.2.8-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on sbryngelson/ffmt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page