Configuration
A project configures Ur in .ur/ur.toml, in a .ur directory at its root. Ur reads the nearest one
at or above each file, up to the repository’s root, and only that one.
Without an ur.toml, each style reads its formatter’s own configuration the way that formatter
finds it, such as Prettier’s .prettierrc, Black’s pyproject.toml, rustfmt.toml,
.rubocop.yml, .sqlfluff, and .editorconfig. With one, ur.toml decides, and Ur warns about
each setting in those files that disagrees with it.
target = ["python-3.11", "typescript-5.9"]
[format]
width = 100
indent = { width = 4, style = "spaces" }
trailing-comma = { add = "multiline", forces-break = true }
[format.javascript]
quotes = "single"
prettier = { arrow-parens = "avoid" }
[format.sql]
style = "river"
[[format.overrides]]
files = ["**/*.test.ts"]
width = 120
[lint]
files = { exclude = ["vendor/"] }
[lint.long-file]
max-lines = 800
target
The language versions the code targets, as Ur’s profiles name them, such as python-3.11 or
sql-postgres-18. Every command reads it: Ur parses each file as the newest profile its language
targets, and a style that formats differently by version, as Black does, formats for the versions
targeted. A profile names its language, so one list covers a project’s languages.
ur format --profile sets it for one run.
[format]
How ur format lays files out. The options in [format] apply to every language; the shared
options below are the same for every style, so width = 100 sets Prettier’s printWidth, Black’s
line-length, and rustfmt’s max_width alike.
A language’s table
[format.<language>], such as [format.python] or [format.sql], sets options for that language
alone, over [format]. Its style chooses the style that formats the language, where it has more
than one, as SQL has sqlfluff and river. ur format --style chooses it for one run.
A style’s own options
A table named for a style sets its own options, in [format] or in a language’s table:
[format.prettier], or prettier = { arrow-parens = "avoid" }. Options are written as ur.toml
names them: Prettier’s and rustfmt’s in kebab case, such as arrow-parens for arrowParens, and
the others as the tool writes them. A style that groups its options, as RuboCop does by cop, takes a
table for each group, such as "Layout/DotPosition" = { EnforcedStyle = "trailing" }. Each
style’s page lists its options.
files
files = { include = [...], exclude = [...] } chooses the files ur format formats, in [format]
or in a language’s table. Each entry is a glob: one with a / matches a path from the project’s
root, and covers everything under a directory it matches; one without matches a file or directory
name anywhere. exclude wins over include, and when include is set, a file must match one of
its globs.
[[format.overrides]]
Each [[format.overrides]] table sets options for the files its files globs match, over
everything else. Later overrides win over earlier ones.
[lint]
What ur lint and ur check add to their rules for a project.
files = { include = [...], exclude = [...] }chooses the files the lint reads, with globs as[format]writes them.no-comments = trueturns on the optionalno-commentsrule.[lint.stray-env-var]says where the project may read its environment variables for thestray-env-varrule:filesnames the env files, in place of each language’s usual ones, andenabled = falseturns the rule off.[lint.tests]givesassertions, the names of the project’s own assertion helpers, such ascheck_parses, which the rules about tests count as assertions.
The text rules
A table for one of the rules that read files as text turns that rule on: [lint.long-file],
[lint.deep-nesting], [lint.stray-emoji], [lint.stray-todo], [lint.hardcoded-color],
[lint.inline-svg], [lint.hardcoded-font], and [lint.ad-hoc-motion]. Each takes exclude,
globs of the files it leaves out, such as generated data or the theme file that defines a project’s
colours. [lint.long-file] takes max-lines, 1500 unless it says, and [lint.deep-nesting] takes
max-depth.
The rules were renamed so that each name says what is wrong, and a table may still go by its rule’s
old name: [lint.file-length], [lint.emoji], [lint.color], [lint.inline-font],
[lint.motion], and [lint.env-file] still work. --rule and ur-allow comments take the old
names too.
[check]
Where ur check expects a project’s working notes and shell scripts, relative to the directory it
checks.
notes,notesunless it says: the directory for working notes, where a Markdown or text file at the top of the checked directory belongs unless its name is a conventional one, such asREADME.md.scripts,scriptsunless it says: the directory for shell scripts.allow: files that stay where they are, such asVISION.mdorci/build.sh.
The shared options
Every style takes these, in [format], a language's table, or an override, under the same names whatever its formatter calls them.
| Option | Values | What it does |
|---|---|---|
width | a number | The line width code is fitted within, in columns, measured as the style's reference formatter measures it. |
indent.width | a number | The columns each level of indentation adds. |
indent.style | "spaces", "tabs" | Whether indentation is written with spaces or tabs. |
line-ending | "lf", "crlf", "cr", "auto", "native" | The line ending written at the end of each line. |
trailing-comma.add | "never", "multiline", "always", "es5", "preserve" | When a trailing comma is added after the last item of a broken list. |
trailing-comma.forces-break | true or false | Whether a trailing comma already in a list keeps the list broken across lines, as Black's magic trailing comma does. |
quotes | "double", "single", "preserve" | The quotes strings are written with, where the language lets either do. |
target | a list of profiles, such as "python-3.11" | The language versions the code targets, as Ur's profiles name them, such as python-3.11: Ur parses with the newest, and a style that formats differently by version, as Black does, formats for them. |
Each style's own options
A style's own options go in a table named for it. Each style's page lists them, with its defaults for the shared options. Options that only change how its formatter runs, such as --check, are left out.
| Style | Formats | Options |
|---|---|---|
black | Python | 8 |
google-java-format | Java | 6 |
mathlib | Lean | None of its own |
prettier | JavaScript, TypeScript, Markdown | 22 |
river | SQL | 1 |
rubocop | Ruby | 226 |
rustfmt | Rust | 22 |
sqlfluff | SQL | 135 |
tla2tools | TLA+ | None of its own |