This document describes a code style as applied by the mofmt.
There is no line length limit. There are plenty of limits already.
mofmt uses a single space as a horizontal separator between tokens.
Spaces are not inserted before:
- semicolons (
;
), except when preceded bywithin
- commas (
,
) - parentheses and brackets (
()[]{}
) - dots (
.
) in type specifiers and names
Spaces are not inserted after:
- dots (
.
) in type specifiers and names - opening brackets (
([{
)
parameter .Foo.Bar[10] Baz(start = 0, max = 100);
Two kinds of Modelica unary operators are treated differently:
not
operator is always followed by a space+
,-
,.+
,.-
are not followed by a space
-4
.-A
not is_off
All binary operators are surrounded with spaces.
(-2) * (3 - 1.76)
a <= b or x
1 : 10
:=
and =
tokens are surrounded with spaces.
foo = bar * 2
Real foo(min = 0, max = 2) = 1 / 2
foo := bar(x)
foo := if x < 2 then bar else baz
Every comma (,
) and semicolon (;
) is followed by a space. This includes
discarded slots in output-expression-list.
{1.0, 2.0, 3.0}
(foo, , bar) := baz(x, y)
[x, y; a, b]
Indentation is two spaces per level.
Line is automatically wrapped before every:
- class definition
- element
- equation
- statement
- description string
- annotation
- constraining clause
- enumeration item
In case of:
- class definition
- element
- equation
- statement
wrap can be doubled so there is a single blank line instead.
Section keywords:
public
protected
equation
algorithm
external
are always preceded and followed by a blank line. Those keywords are placed without indentation.
Blank lines are also inserted:
- at the beginning and end of the composition rule
- before the "lass-wide annotation in the composition rule
within SomePackage;
final model Foo
// AUTO BLANK
Real x;
Real y;
// AUTO BLANK
protected
// AUTO BLANK
Real z;
// AUTO BLANK
equation
// AUTO BLANK
x + y = z;
x * 2 = y;
// OPTIONAL BLANK
z = 3 ^ 2;
// AUTO BLANK
annotation ();
// AUTO BLANK
end foo;
// OPTIONAL BLANK
partial record Bar
// AUTO BLANK
parameter Boolean is_off = false;
// AUTO BLANK
end Bar;
Indentation is increased only one per element.
replaceable package Medium = Modelica.Media.R134a.R134a_ph
constrainedby Modelica.Media.Interfaces.PartialMedium
"Fluid medium"
annotation(Dialog(tab = "General", group = "Medium"));
But not:
replaceable package Medium = Modelica.Media.R134a.R134a_ph
constrainedby Modelica.Media.Interfaces.PartialMedium
"Fluid medium"
annotation(Dialog(tab = "General", group = "Medium"));
Indentation is increased inside enumeration()
and at every
description.
type BoundaryType = enumeration(
Pressure
"Pressure boundary",
Flow
"Flow boundary")
"Enumeration of possible boundary types";
Indentation is increased once per block.
if foo == bar then
baz := bark;
bam := bem;
else
if some_condition then
baz := 0;
bam := 1;
else
baz := bam;
end if;
end if;
The main rule here is: be consistent. The following approach is applied:
- If a line was originally wrapped at any argument in the specific construct, then wrap at every argument in this construct.
- If a line was originally wrapped inside a nested construct, then wrap at every argument in every outer construct.
Indentation is increased accordingly to help visually identify the scope.
// No wrap is fine
h = enthalpy_pT(p, T)
// Outer array is wrapped, but inner ones are kept intact
parameter Real A[2, 3] = {
{1.0, 2.0, 3.0},
{5.0, 6.0, 7.0}}
// In nested function call, if inner call is wrapped, outer call is
// wrapped as well
cp_a = specificHeat_pT(
p = p_a,
T = temperature_ph(
p = p_a,
h = h_a))
// But it is fine to wrap only outer call, keeping inner one intact
cp_b = specificHeat_pT(
p = p_b,
T = temperature_ph(p = p_b, h = h_b));
// Wrapped comprehensions are little bit special
{
a[i] * b[i]
for i in 1 : n}
// Import lists
import Modelica.Constants.{
pi,
inf};
Expressions like arithmetic, logical etc. are handled in a different way, because mofmt doesn't apply autowrapping when it detects a wrap in the original file. Original wraps are preserved, and indentation is adjusted. Indentation is increased only once per expression.
Other difference is that instead of commas line may be wrapped before binary operators.
// No wrap
foo := 2 * (bar - baz) / 5
// Single wrap
foo := 2
* (bar - baz) / 5
// Two wraps
foo := 2
* (bar - baz)
/ 5