ffmt 0.2.1

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

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:

indent-width = 4
line-length = 132
keyword-case = "lower"         # lower, upper, preserve
normalize-keywords = true      # enddo -> end do
named-ends = true              # end subroutine -> end subroutine s_foo
align-declarations = true      # align :: in consecutive declarations
unicode-to-ascii = true        # Greek/math symbols -> LaTeX in comments
rewrap-comments = true         # wrap long comments at line-length
rewrap-code = true             # wrap long code lines at line-length
space-after-comment = true     # !comment -> ! comment
collapse-double-spaces = true  # x  =  y -> x = y
keyword-paren-space = true     # if( -> if (
fypp-list-commas = true        # normalize commas in Fypp '[...]' args

[whitespace]
relational = true              # ==, /=, <, <=, >, >=
logical = true                 # .and., .or., .not.
plusminus = true                # binary +, -
multdiv = false                 # *, /
power = false                   # **
assignment = true               # =
declaration = true              # ::
comma = true                    # space after comma

All options have sensible defaults -- most projects need no config file at all.

Preserved as-is

  • String literals and inline expressions (${...}$, @{...}@)
  • Comment contents and Doxygen alignment (!<, !>, !!)
  • Continuation line structure
  • #ifdef/#endif blocks (no indentation change)

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@v0.1.0
  with:
    args: "--check src/"

pre-commit

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

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