ffmt 0.1.0__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
Binary file
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ffmt
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Developers
|
|
6
|
+
Classifier: Intended Audience :: Science/Research
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Programming Language :: Fortran
|
|
9
|
+
Classifier: Programming Language :: Rust
|
|
10
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Summary: An opinionated Fortran formatter with Fypp and OpenACC support
|
|
13
|
+
Keywords: fortran,formatter,fypp,openacc,openmp
|
|
14
|
+
License: MIT
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
17
|
+
|
|
18
|
+
# ffmt
|
|
19
|
+
|
|
20
|
+
An opinionated, idempotent Fortran formatter with first-class [Fypp](https://github.com/aradi/fypp) preprocessor and OpenACC/OpenMP directive support.
|
|
21
|
+
|
|
22
|
+
`ffmt` is a single-pass formatter written in Rust.
|
|
23
|
+
It replaces [fprettify](https://github.com/pseewald/fprettify) and produces consistent output on the first run -- no multi-pass convergence needed.
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
### From PyPI
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install ffmt
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### From crates.io
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cargo install ffmt
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### From source
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/sbryngelson/ffmt
|
|
43
|
+
cd ffmt
|
|
44
|
+
cargo install --path .
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Format files in-place
|
|
51
|
+
ffmt file.fpp
|
|
52
|
+
ffmt src/
|
|
53
|
+
|
|
54
|
+
# Check mode (CI) -- exit 1 if any file would change
|
|
55
|
+
ffmt --check src/
|
|
56
|
+
|
|
57
|
+
# Show what would change (with color)
|
|
58
|
+
ffmt --diff src/
|
|
59
|
+
|
|
60
|
+
# Both
|
|
61
|
+
ffmt --check --diff src/
|
|
62
|
+
|
|
63
|
+
# Parallel formatting
|
|
64
|
+
ffmt -j 8 src/
|
|
65
|
+
|
|
66
|
+
# Read from stdin, write to stdout (for editor integration)
|
|
67
|
+
cat file.fpp | ffmt -
|
|
68
|
+
ffmt --stdin-filepath file.fpp - < file.fpp
|
|
69
|
+
|
|
70
|
+
# Exclude patterns
|
|
71
|
+
ffmt --exclude "autogen/**" src/
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Stdin/stdout mode
|
|
75
|
+
|
|
76
|
+
Use `-` as the path to read from stdin and write formatted output to stdout. This enables editor integration (format-on-save) and piping:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Format stdin to stdout
|
|
80
|
+
echo "INTEGER::x" | ffmt -
|
|
81
|
+
# Output: integer :: x
|
|
82
|
+
|
|
83
|
+
# Check stdin (exit 1 if it would change)
|
|
84
|
+
cat file.fpp | ffmt --check --stdin-filepath file.fpp -
|
|
85
|
+
|
|
86
|
+
# Diff stdin
|
|
87
|
+
cat file.fpp | ffmt --diff --stdin-filepath file.fpp -
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The `--stdin-filepath` flag provides a filename for diagnostics.
|
|
91
|
+
|
|
92
|
+
### .gitignore support
|
|
93
|
+
|
|
94
|
+
`ffmt` automatically respects `.gitignore`, `.ignore`, `.fdignore`, and `.git/info/exclude` when walking directories. Files ignored by git are skipped.
|
|
95
|
+
|
|
96
|
+
## Editor integration
|
|
97
|
+
|
|
98
|
+
### Vim/Neovim
|
|
99
|
+
|
|
100
|
+
```vim
|
|
101
|
+
" Format on save
|
|
102
|
+
autocmd BufWritePost *.fpp,*.f90 silent !ffmt %
|
|
103
|
+
|
|
104
|
+
" Or use as formatprg
|
|
105
|
+
set formatprg=ffmt\ -
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### VS Code
|
|
109
|
+
|
|
110
|
+
Add to `settings.json`:
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"[fortran]": {
|
|
114
|
+
"editor.formatOnSave": true
|
|
115
|
+
},
|
|
116
|
+
"fortran.formatting.formatter": "ffmt",
|
|
117
|
+
"fortran.formatting.path": "ffmt",
|
|
118
|
+
"fortran.formatting.args": ["--stdin-filepath", "${file}", "-"]
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## CI integration
|
|
123
|
+
|
|
124
|
+
### GitHub Actions
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
- uses: sbryngelson/ffmt@v1
|
|
128
|
+
with:
|
|
129
|
+
args: "--check src/"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Or install directly:
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
- run: pip install ffmt
|
|
136
|
+
- run: ffmt --check src/
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### pre-commit
|
|
140
|
+
|
|
141
|
+
Add to `.pre-commit-config.yaml`:
|
|
142
|
+
|
|
143
|
+
```yaml
|
|
144
|
+
repos:
|
|
145
|
+
- repo: https://github.com/sbryngelson/ffmt
|
|
146
|
+
rev: v0.1.0
|
|
147
|
+
hooks:
|
|
148
|
+
- id: ffmt
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Use `ffmt-check` instead of `ffmt` for check-only mode (no modifications).
|
|
152
|
+
|
|
153
|
+
## What it does
|
|
154
|
+
|
|
155
|
+
`ffmt` formats Fortran free-form source files (`.fpp`, `.f90`, `.f95`, `.f03`) through a single-pass pipeline:
|
|
156
|
+
|
|
157
|
+
1. **Indentation** -- 4-space indentation based on scope tracking (`if/do/subroutine/module/type/...`)
|
|
158
|
+
2. **Fypp block indentation** -- `#:if`, `#:for`, `#:call`, `#:def`, etc. are indented as nested blocks
|
|
159
|
+
3. **Directive indentation** -- `!$acc`, `!$omp`, `!DIR$` lines indented to match surrounding Fortran scope
|
|
160
|
+
4. **Whitespace normalization** -- consistent spacing around operators, commas, colons, parentheses
|
|
161
|
+
5. **Case normalization** -- Fortran keywords lowercased (`IF` -> `if`, `END DO` -> `end do`)
|
|
162
|
+
|
|
163
|
+
### Formatting rules
|
|
164
|
+
|
|
165
|
+
**Indentation:**
|
|
166
|
+
- 4 spaces per scope level
|
|
167
|
+
- Fypp blocks (`#:if`/`#:for`/`#:call`/`#:def`/`#:block`/`#:mute`) create scope
|
|
168
|
+
- `#ifdef`/`#endif` preprocessor blocks do **not** change indentation
|
|
169
|
+
- Continuation lines (`&`) preserve their original spacing
|
|
170
|
+
- `!!` Doxygen continuation comments preserve their original alignment
|
|
171
|
+
|
|
172
|
+
**Operators -- space each side:**
|
|
173
|
+
`==`, `/=`, `<=`, `>=`, `<`, `>`, `.and.`, `.or.`, `.not.`, `=` (assignment), `=>`, `+`, `-` (binary), `//` (concatenation), `::`
|
|
174
|
+
|
|
175
|
+
**Operators -- no spaces:**
|
|
176
|
+
`*`, `/`, `**`
|
|
177
|
+
|
|
178
|
+
**Other:**
|
|
179
|
+
- Commas: one space after, none before
|
|
180
|
+
- Array slices: no spaces around `:` -- `a(1:n)`
|
|
181
|
+
- Keyword arguments: no spaces around `=` -- `call foo(bar=1)`
|
|
182
|
+
- Parentheses: no internal padding -- `f(x)` not `f( x )`
|
|
183
|
+
- Trailing whitespace: always stripped
|
|
184
|
+
- Blank lines: 3+ consecutive collapsed to 2
|
|
185
|
+
- Blank lines after `!$acc loop` directives: removed
|
|
186
|
+
|
|
187
|
+
**Preserved as-is:**
|
|
188
|
+
- String literal contents (`'...'`, `"..."`)
|
|
189
|
+
- Inline Fypp expressions (`${...}$`, `@{...}@`)
|
|
190
|
+
- Comment contents
|
|
191
|
+
- Doxygen comment alignment (`!<`, `!>`, `!!`)
|
|
192
|
+
- Continuation line structure and alignment
|
|
193
|
+
|
|
194
|
+
## Design
|
|
195
|
+
|
|
196
|
+
`ffmt` is opinionated like `gofmt` -- one style, no configuration file, minimal CLI flags.
|
|
197
|
+
|
|
198
|
+
### Why not fprettify?
|
|
199
|
+
|
|
200
|
+
- **Not idempotent** -- fprettify requires 2-4 passes to converge
|
|
201
|
+
- **No directive awareness** -- requires a separate indenter script for `!$acc`/`!$omp` lines
|
|
202
|
+
- **Fragile Fypp support** -- treats Fypp lines as "not Fortran," causing inconsistent indentation
|
|
203
|
+
- **Unmaintained** -- last release circa 2020
|
|
204
|
+
|
|
205
|
+
### Architecture
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
Source lines -> Join continuations -> Classify (LineKind enum) ->
|
|
209
|
+
Track scope depth -> Apply indentation -> Normalize whitespace ->
|
|
210
|
+
Normalize case -> Emit formatted lines
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
| Module | Responsibility |
|
|
214
|
+
|--------|---------------|
|
|
215
|
+
| `reader.rs` | Join `&` continuations, mark opaque regions (strings, `${...}$`, comments) |
|
|
216
|
+
| `classifier.rs` | Classify lines into `LineKind` enum with disambiguation rules |
|
|
217
|
+
| `scope.rs` | Scope tracking state machine (push/pop on block open/close) |
|
|
218
|
+
| `indent.rs` | Apply `4 * depth` leading spaces |
|
|
219
|
+
| `whitespace.rs` | Operator/comma/colon/paren spacing normalization |
|
|
220
|
+
| `case_norm.rs` | Lowercase Fortran keywords outside strings/Fypp/comments |
|
|
221
|
+
| `formatter.rs` | Pipeline orchestrator |
|
|
222
|
+
| `cli.rs` | CLI with stdin/stdout, .gitignore, color, exclude patterns |
|
|
223
|
+
|
|
224
|
+
## Exit codes
|
|
225
|
+
|
|
226
|
+
| Code | Meaning |
|
|
227
|
+
|------|---------|
|
|
228
|
+
| 0 | Success (all files formatted, or no changes needed in `--check` mode) |
|
|
229
|
+
| 1 | Files would change (`--check` mode only) |
|
|
230
|
+
| 2 | Usage error or I/O failure |
|
|
231
|
+
|
|
232
|
+
## License
|
|
233
|
+
|
|
234
|
+
MIT
|
|
235
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
ffmt-0.1.0.data/scripts/ffmt.exe,sha256=hjCqnqKQK4kgYgMexbMTUtVYF6cSqsUXKcSD_JyaxwQ,3373568
|
|
2
|
+
ffmt-0.1.0.dist-info/METADATA,sha256=kBPb1hO8RJjIR0TxNrrZbH_H25VcsBrTqhBfDAthfwE,6672
|
|
3
|
+
ffmt-0.1.0.dist-info/WHEEL,sha256=uJOc2U-Q1x95AlblQcqMRb3iR4QnPtdI7X2ycPN99rM,94
|
|
4
|
+
ffmt-0.1.0.dist-info/licenses/LICENSE,sha256=76sgeSfED6PO-R19tLHgf-eM5Dk_IjeSCaLgCc_5M9w,1100
|
|
5
|
+
ffmt-0.1.0.dist-info/sboms/ffmt.cyclonedx.json,sha256=bVtnUcb-PNx7Fzyep3Qf9840wmdyZzCXkG_Kw9bfMEY,59094
|
|
6
|
+
ffmt-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MFlowCode contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|