├── .envrc ├── .gitattributes ├── .gitignore ├── .pre-commit-entry.sh ├── .pre-commit-hooks.yaml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── README.md ├── STYLE.md ├── UNLICENSE ├── alejandra.toml ├── buildkite-cd.yaml ├── buildkite-ci.yaml ├── buildkite.yaml ├── default.nix ├── flake.lock ├── flake.nix ├── front ├── .envrc ├── Cargo.lock ├── Cargo.toml ├── deploy ├── flake.lock ├── flake.nix ├── package.json ├── public │ └── index.html ├── serve ├── src │ ├── App.js │ ├── Editor.js │ ├── SideBySide.js │ ├── index.js │ ├── lib.rs │ ├── nixpkgs.js │ └── nixpkgsFiles.js └── yarn.lock ├── integrations ├── doom-emacs │ └── README.md ├── gnu-emacs │ └── README.md ├── neovim │ └── README.md ├── pre-commit-hooks-nix │ └── README.md ├── pre-commit │ └── README.md ├── vim │ └── README.md └── vscode │ ├── .yarnrc │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── README.md │ ├── extension.js │ ├── jsconfig.json │ ├── package.json │ ├── yarn.lock │ └── yarn.lock.nix ├── rustfmt.toml ├── src ├── alejandra │ ├── Cargo.toml │ ├── src │ │ ├── builder.rs │ │ ├── children.rs │ │ ├── children2.rs │ │ ├── config.rs │ │ ├── format.rs │ │ ├── lib.rs │ │ ├── parsers │ │ │ ├── mod.rs │ │ │ └── pattern.rs │ │ ├── position.rs │ │ ├── rules │ │ │ ├── apply.rs │ │ │ ├── attr_set.rs │ │ │ ├── bin_op.rs │ │ │ ├── dynamic.rs │ │ │ ├── if_else.rs │ │ │ ├── inherit.rs │ │ │ ├── key_value.rs │ │ │ ├── lambda.rs │ │ │ ├── let_in.rs │ │ │ ├── list.rs │ │ │ ├── mod.rs │ │ │ ├── paren.rs │ │ │ ├── pat_bind.rs │ │ │ ├── pat_entry.rs │ │ │ ├── pattern.rs │ │ │ ├── root.rs │ │ │ ├── scoped.rs │ │ │ └── string.rs │ │ ├── utils.rs │ │ └── version.rs │ └── tests │ │ ├── cases │ │ ├── default │ │ │ ├── apply │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── assert │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── attr_set │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── bin_op │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── comment │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── dynamic │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── error │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── idioms │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── idioms_lib_1 │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── idioms_lib_2 │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── idioms_nixos_1 │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── idioms_pkgs_1 │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── idioms_pkgs_2 │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── idioms_pkgs_3 │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── if_else │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── inherit │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── inherit_blank_trailing │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── inherit_comment │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── inherit_from │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── key_value │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── lambda │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── let_in │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── lists │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── monsters_1 │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── monsters_2 │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── monsters_3 │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── monsters_4 │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── monsters_5 │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── or_default │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── paren │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── pat_bind │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── pattern │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── pipe_operators │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── root │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── select │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── string │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ ├── string_interpol │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ │ └── with │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ ├── indentation-four-spaces │ │ │ └── string │ │ │ │ ├── in.nix │ │ │ │ └── out.nix │ │ └── indentation-tabs │ │ │ ├── apply │ │ │ ├── in.nix │ │ │ └── out.nix │ │ │ ├── attr-set │ │ │ ├── in.nix │ │ │ └── out.nix │ │ │ ├── list │ │ │ ├── in.nix │ │ │ └── out.nix │ │ │ └── string │ │ │ ├── in.nix │ │ │ └── out.nix │ │ └── fmt.rs └── alejandra_cli │ ├── Cargo.toml │ ├── src │ ├── ads │ │ ├── contributor_thanks.txt │ │ ├── mod.rs │ │ ├── please_sponsor.txt │ │ ├── please_star.txt │ │ └── sponsor_thanks.txt │ ├── cli.rs │ ├── find.rs │ ├── lib.rs │ ├── main.rs │ └── verbosity.rs │ └── tests │ ├── cli.rs │ ├── configs │ ├── empty_config.toml │ └── wrong_key.toml │ ├── inputs │ ├── changed.nix │ ├── error.nix │ └── unchanged.nix │ └── output.txt └── treefmt.toml /.envrc: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # reload when these files change 4 | watch_file flake.nix 5 | watch_file flake.lock 6 | 7 | { 8 | # shell gc root dir 9 | mkdir -p "$(direnv_layout_dir)" 10 | eval "$(nix print-dev-env --profile $(direnv_layout_dir)/flake-profile)" 11 | } 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Ignore the generated list of nixpkgs files for language stats. 2 | nixpkgsFiles.js linguist-generated 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /**/*.vsix 2 | /**/node_modules/ 3 | /**/result* 4 | /**/target/ 5 | /.direnv 6 | /.idea/ 7 | /front/build 8 | /front/worktree 9 | /tarpaulin* 10 | -------------------------------------------------------------------------------- /.pre-commit-entry.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env sh 2 | 3 | set -eux 4 | 5 | if ! command -v nix-build; then 6 | echo 'ERROR: this pre-commit hook requires "nix-build" to be installed first' 7 | exit 1 8 | fi 9 | 10 | echo INFO: building Alejandra 11 | 12 | nix-build \ 13 | --out-link result-alejandra \ 14 | https://github.com/kamadorueda/alejandra/tarball/4.0.0 15 | 16 | echo INFO: running Alejandra: 17 | result-alejandra/bin/alejandra -- -q "${@}" 18 | -------------------------------------------------------------------------------- /.pre-commit-hooks.yaml: -------------------------------------------------------------------------------- 1 | - id: alejandra 2 | name: alejandra 3 | description: Format Nix code with Alejandra. 4 | entry: alejandra 5 | language: rust 6 | files: \.nix$ 7 | minimum_pre_commit_version: 2.21.0 8 | 9 | - id: alejandra-nix 10 | name: alejandra (Nix) 11 | description: Format Nix code with Alejandra. 12 | entry: .pre-commit-entry.sh 13 | language: script 14 | files: \.nix$ 15 | minimum_pre_commit_version: 1.18.1 16 | 17 | - id: alejandra-system 18 | name: alejandra (system) 19 | description: Format Nix code with Alejandra. 20 | entry: alejandra 21 | language: system 22 | files: \.nix$ 23 | args: ["-q"] 24 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Please visit: 4 | https://www.contributor-covenant.org/version/2/0/code_of_conduct/ 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | Note that Alejandra is and has always been 4 | [public domain software](https://stpeter.im/writings/essays/publicdomain.html). 5 | Unless explicitly stated by you, 6 | contributing implies licensing those contributions under the same [license](./UNLICENSE). 7 | For more information please visit https://unlicense.org/. 8 | 9 | # Opening Issues 10 | 11 | Feel free to speak your mind :) 12 | 13 | # Submitting changes 14 | 15 | If your contribution has the potential to be controversial or subjective, 16 | please open an issue first so that we can discuss it first. 17 | 18 | Otherwise just feel free to contribute anything you want 19 | (if it makes the project _better_). 20 | 21 | # Maintainers zone 22 | 23 | ## Release process 24 | 25 | 1. Update dependencies with: 26 | 27 | ```sh 28 | pushd . 29 | cargo update 30 | nix flake update 31 | popd 32 | pushd front/ 33 | cargo update 34 | nix flake update 35 | yarn upgrade 36 | popd 37 | pushd integrations/vscode/ 38 | yarn upgrade 39 | yarn2nix > yarn.lock.nix 40 | popd 41 | ``` 42 | 43 | 1. Update the [changelog](./CHANGELOG.md). 44 | 1. Tag the project with git. 45 | 1. Publish to crates.io. 46 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [profile.release] 2 | lto = true 3 | 4 | [profile.dev] 5 | opt-level = 2 6 | 7 | [workspace] 8 | members = ["src/*"] 9 | resolver = "2" 10 | -------------------------------------------------------------------------------- /STYLE.md: -------------------------------------------------------------------------------- 1 | # Alejandra's Style Guide 2 | 3 | Alejandra's mission is to produce a **consistent style** 4 | that is **easy to read** 5 | and produces **clean diffs**. 6 | This means trading aggressively compact code 7 | for regularity and ease of modification. 8 | 9 | ## Function 10 | 11 | > Discussions: 12 | > [1](https://github.com/kamadorueda/alejandra/issues/95) 13 | 14 | ### With Destructured Arguments 15 | 16 | ✅ Good: 17 | 18 | ```nix 19 | {mkDerivation, ...} @ attrs: 20 | mkDerivation # ... 21 | ``` 22 | 23 | - Indenting the body relative to the function signature 24 | hints that a new scope is introduced by the 25 | function arguments. 26 | - Keeping the signature in one line 27 | when there is only 1 argument in the destructuring (`mkDerivation`) 28 | helps saving vertical space. 29 | - Spacing between elements of the destructuring, 30 | and between opening and closing elements 31 | is consistent with _List_ and _Map_. 32 | 33 | ✅ Good: 34 | 35 | ```nix 36 | {mkDerivation, ...} @ attrs: 37 | mkDerivation # ... 38 | ``` 39 | 40 | - When there is only 1 function in the whole file 41 | it's valid not to indent the body 42 | because it's clear when reading the file from top to bottom 43 | that the whole remaining of the file 44 | is the scope of the function, 45 | Therefore saving an unneeded indent. 46 | 47 | ✅ Good: 48 | 49 | ```nix 50 | { 51 | mkDerivation, 52 | lib, 53 | fetchurl, 54 | ... 55 | } @ attrs: 56 | stdenv.mkDerivation # ... 57 | ``` 58 | 59 | - Adding an argument produces a minimal diff 60 | (including the first and last elements): 61 | 62 | ```patch 63 | mkDerivation, 64 | lib, 65 | fetchurl, 66 | + google-chrome-stable, 67 | ``` 68 | 69 | - Removing an argument produces a minimal diff 70 | (including the first and last elements): 71 | 72 | ```patch 73 | mkDerivation, 74 | - lib, 75 | fetchurl, 76 | ``` 77 | 78 | - The comma at the end is consistent with _Let-In_, and _Map_, 79 | where the separator goes after the element 80 | instead of at the beginning. 81 | 82 | ❌ Bad: 83 | 84 | 85 | 86 | ```nix 87 | { lib 88 | , mkDerivation 89 | , fetchurl 90 | , ... 91 | } @ attrs: 92 | stdenv.mkDerivation # ... 93 | ``` 94 | 95 | - Removing the first element 96 | produces a diff in two elements: 97 | 98 | ```diff 99 | - { lib 100 | - , mkDerivation 101 | + { mkDerivation 102 | , fetchurl 103 | , ... 104 | } @ attrs: 105 | stdenv.mkDerivation # ... 106 | ``` 107 | 108 | - Documenting the first argument creates an inconsistency 109 | between the way arguments start: 110 | 111 | ```nix 112 | { 113 | # Lorem Ipsum 114 | lib 115 | , mkDerivation 116 | , fetchurl 117 | , ... 118 | } @ attrs: 119 | stdenv.mkDerivation # ... 120 | ``` 121 | 122 | - This is not consistent with _Let-In_, and _Map_, 123 | where the separator goes after the element 124 | instead of at the beginning. 125 | - It ruins "folding by indentation" modes 126 | on Vim, Neovim, VSCode, and other major code editors, 127 | because the data-structure has the same indentation 128 | as the opening bracket. 129 | 130 | ❌ Bad: 131 | 132 | 133 | 134 | ```nix 135 | { mkDerivation, lib, fetchurl, ... }@attrs: stdenv.mkDerivation # ... 136 | ``` 137 | 138 | - One-liners are unreadable. 139 | 140 | ❌ Bad: 141 | 142 | 143 | 144 | ```nix 145 | { mkDerivation, lib, fetchurl, extra-cmake-modules, kdoctools, wrapGAppsHook 146 | , karchive, kconfig, kcrash, kguiaddons, kinit, kparts, kwind, ... }@attrs: 147 | stdenv.mkDerivation # ... 148 | ``` 149 | 150 | - It's hard to tell this destructuring has an ellipsis (`...`) at a first glance, 151 | because it's mixed with the other arguments. 152 | - Moving elements becomes harder 153 | than a simple whole-line movement. 154 | (Moving a whole line is normally a keyboard-shortcut 155 | or command in major code editors). 156 | - Excessively compact: 157 | adding, removing, or editing an argument 158 | produces a diff in more than one argument. 159 | - `}@attrs` is not intuitive 160 | with the rules of written english, 161 | where you add whitespace 162 | after the end of the previous phrase 163 | (`phrase. Other phrase`). 164 | 165 | ## If-Then-Else 166 | 167 | ✅ Good: 168 | 169 | ```nix 170 | if predicate 171 | then foo 172 | else bar 173 | ``` 174 | 175 | - The keyword at the beginning of the line 176 | states clearly the meaning of the content that follows. 177 | - Produces a clean diff when you add more code. 178 | For example: adding content to the `else` 179 | only produces a diff in the `else`. 180 | 181 | ❌ Bad: 182 | 183 | 184 | 185 | ```nix 186 | if predicate then foo else bar 187 | ``` 188 | 189 | - One-liners are hard to understand, 190 | specially when nested, 191 | or when logic gets long. 192 | - Adding content produces a diff in the entire `if-then-else`. 193 | 194 | ✅ Good: 195 | 196 | ```nix 197 | if something <= 2.0 198 | then 199 | if somethingElse 200 | then foo 201 | else bar 202 | else if something <= 4.0 203 | then baz 204 | else if something <= 6.0 205 | then foo 206 | else bar 207 | ``` 208 | 209 | - It's easy to follow that there are many conditionals. 210 | - The indentation makes it easy to read 211 | which expression is associated to each conditional. 212 | - Adding or modifying the branches produces a clean diff. 213 | 214 | ❌ Bad: 215 | 216 | 217 | 218 | ```nix 219 | if cond 220 | then if 221 | looooooooooooooooooooooooooooooooooooooooooooooooooooong 222 | then foo 223 | else bar 224 | else if cond 225 | then foo 226 | else bar 227 | ``` 228 | 229 | - It's complex to distinct the parent `if-then-else` 230 | from the child `if-then-else` 231 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /alejandra.toml: -------------------------------------------------------------------------------- 1 | # (experimental) Configuration options for Alejandra 2 | 3 | indentation = "TwoSpaces" # Or: FourSpaces, Tabs 4 | -------------------------------------------------------------------------------- /buildkite-cd.yaml: -------------------------------------------------------------------------------- 1 | agents: 2 | queue: private 3 | 4 | steps: 5 | - label: build 6 | artifacts: 7 | - alejandra-* 8 | command: 9 | - echo +++ 10 | - nix build .#alejandra-binaries 11 | - nix-store 12 | --query 13 | --include-outputs $(nix-store --query --deriver result) 14 | --requisites | 15 | grep -v '\.drv$$' | 16 | cachix push alejandra 17 | - cp -L result/* . 18 | 19 | - label: coverage 20 | command: 21 | - echo +++ Fetch 22 | - git branch -D main 23 | - git branch main 24 | - git checkout main 25 | - echo --- Load environment 26 | - direnv allow 27 | - eval "$(direnv export bash)" 28 | - echo +++ Run tests 29 | - cd src/alejandra 30 | - cargo tarpaulin --coveralls "$${COVERALLS_REPO_TOKEN}" 31 | -------------------------------------------------------------------------------- /buildkite-ci.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | - label: formatting diff 3 | artifacts: 4 | - formatting-before-vs-after.patch.txt 5 | command: 6 | - echo +++ Formatting - demo 7 | - nix run . -- flake.nix 8 | 9 | - echo --- Cloning nixpkgs 10 | - git config --global user.email CI/CD 11 | - git config --global user.name CI/CD 12 | - git config --global --add safe.directory /data/nixpkgs/.git 13 | - git clone --branch=master --depth 1 --origin=upstream file:///data/nixpkgs 14 | 15 | - echo --- Formatting - before 16 | - nix run github:kamadorueda/alejandra -- --quiet nixpkgs 17 | - git -C nixpkgs add . 18 | - git -C nixpkgs commit -m formatting-before -q 19 | - git -C nixpkgs branch formatting-before 20 | - git -C nixpkgs reset --hard master~1 21 | 22 | - echo --- Formatting - after 23 | - nix run . -- --quiet nixpkgs 24 | - git -C nixpkgs diff formatting-before > formatting-before-vs-after.patch.txt 25 | 26 | - label: closure diff 27 | artifacts: 28 | - closure-before.txt 29 | - closure-after.txt 30 | - closure-before-vs-after.patch.txt 31 | command: 32 | - git config --global user.email CI/CD 33 | - git config --global user.name CI/CD 34 | - git config --global --add safe.directory /data/nixpkgs/.git 35 | - git clone --branch=master --depth 1 --origin=upstream file:///data/nixpkgs 36 | 37 | - echo --- Closure @ before 38 | - nix-env --query --available --attr-path --drv-path --file nixpkgs --xml > closure-before.txt 39 | 40 | - echo --- Formatting 41 | - nix run . -- --quiet nixpkgs 42 | 43 | - echo --- Closure @ after 44 | - nix-env --query --available --attr-path --drv-path --file nixpkgs --xml > closure-after.txt 45 | 46 | - echo +++ Closure diff 47 | - git diff --no-index closure-before.txt closure-after.txt > closure-before-vs-after.patch.txt || true 48 | - git diff --no-index closure-before.txt closure-after.txt --shortstat || true 49 | 50 | - echo +++ Derivations count 51 | - grep -c drvPath= closure-after.txt 52 | 53 | - label: lint 54 | command: 55 | - echo --- Load environment 56 | - direnv allow 57 | - eval "$(direnv export bash)" 58 | - echo +++ Run Linter 59 | - cargo clippy 60 | 61 | - label: flake check 62 | command: 63 | - echo +++ 64 | - nix flake check 65 | -------------------------------------------------------------------------------- /buildkite.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | - if: build.branch == "main" 3 | command: buildkite-agent pipeline upload buildkite-cd.yaml 4 | 5 | - if: build.branch != "main" 6 | command: buildkite-agent pipeline upload buildkite-ci.yaml 7 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | let 2 | lockData = builtins.readFile ./flake.lock; 3 | lock = builtins.fromJSON lockData; 4 | flakeCompat = lock.nodes.flakeCompat.locked; 5 | flakeCompatSrc = builtins.fetchTarball { 6 | url = "https://github.com/edolstra/flake-compat/archive/${flakeCompat.rev}.tar.gz"; 7 | sha256 = flakeCompat.narHash; 8 | }; 9 | flake = import flakeCompatSrc {src = ./.;}; 10 | in 11 | {system ? builtins.currentSystem, ...}: 12 | if builtins.hasAttr system flake.defaultNix.defaultPackage 13 | then flake.defaultNix.defaultPackage.${system} 14 | else 15 | builtins.throw '' 16 | 17 | Alejandra does not support the system: ${system} 18 | 19 | Please consider creating an issue requesting 20 | support for such system: 21 | https://github.com/kamadorueda/alejandra 22 | 23 | Thank you! 24 | 25 | '' 26 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "fenix": { 4 | "inputs": { 5 | "nixpkgs": [ 6 | "nixpkgs" 7 | ], 8 | "rust-analyzer-src": "rust-analyzer-src" 9 | }, 10 | "locked": { 11 | "lastModified": 1730615655, 12 | "narHash": "sha256-2HBR3zLn57LXKNRtxBb+O+uDqHM4n0pz51rPayMl4cg=", 13 | "owner": "nix-community", 14 | "repo": "fenix", 15 | "rev": "efeb50e2535b17ffd4a135e6e3e5fd60a525180c", 16 | "type": "github" 17 | }, 18 | "original": { 19 | "owner": "nix-community", 20 | "repo": "fenix", 21 | "type": "github" 22 | } 23 | }, 24 | "flakeCompat": { 25 | "flake": false, 26 | "locked": { 27 | "lastModified": 1696426674, 28 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", 29 | "owner": "edolstra", 30 | "repo": "flake-compat", 31 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", 32 | "type": "github" 33 | }, 34 | "original": { 35 | "owner": "edolstra", 36 | "repo": "flake-compat", 37 | "type": "github" 38 | } 39 | }, 40 | "nixpkgs": { 41 | "locked": { 42 | "lastModified": 1730642263, 43 | "narHash": "sha256-UXqvGZOHUDeAo8Sv5A5oObiQgBPELVgHQi130TU0jMU=", 44 | "owner": "nixos", 45 | "repo": "nixpkgs", 46 | "rev": "650fe87347086b30a6dbcc32b55987ce5a23c6ae", 47 | "type": "github" 48 | }, 49 | "original": { 50 | "owner": "nixos", 51 | "ref": "nixos-unstable-small", 52 | "repo": "nixpkgs", 53 | "type": "github" 54 | } 55 | }, 56 | "root": { 57 | "inputs": { 58 | "fenix": "fenix", 59 | "flakeCompat": "flakeCompat", 60 | "nixpkgs": "nixpkgs" 61 | } 62 | }, 63 | "rust-analyzer-src": { 64 | "flake": false, 65 | "locked": { 66 | "lastModified": 1730555913, 67 | "narHash": "sha256-KNHZUlqsEibg3YtfUyOFQSofP8hp1HKoY+laoesBxRM=", 68 | "owner": "rust-lang", 69 | "repo": "rust-analyzer", 70 | "rev": "f17a5bbfd0969ba2e63a74505a80e55ecb174ed9", 71 | "type": "github" 72 | }, 73 | "original": { 74 | "owner": "rust-lang", 75 | "ref": "nightly", 76 | "repo": "rust-analyzer", 77 | "type": "github" 78 | } 79 | } 80 | }, 81 | "root": "root", 82 | "version": 7 83 | } 84 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "The Uncompromising Nix Code Formatter"; 3 | 4 | inputs = { 5 | fenix.url = "github:nix-community/fenix"; 6 | fenix.inputs.nixpkgs.follows = "nixpkgs"; 7 | 8 | flakeCompat.url = "github:edolstra/flake-compat"; 9 | flakeCompat.flake = false; 10 | 11 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small"; 12 | }; 13 | 14 | outputs = inputs: let 15 | commit = inputs.self.shortRev or "dirty"; 16 | date = inputs.self.lastModifiedDate or inputs.self.lastModified or "19700101"; 17 | version = "4.0.0+${builtins.substring 0 8 date}.${commit}"; 18 | 19 | nixpkgsForHost = host: 20 | import inputs.nixpkgs { 21 | overlays = [overlay]; 22 | system = host; 23 | }; 24 | 25 | nixpkgs."aarch64-darwin" = nixpkgsForHost "aarch64-darwin"; 26 | nixpkgs."aarch64-linux" = nixpkgsForHost "aarch64-linux"; 27 | nixpkgs."i686-linux" = nixpkgsForHost "i686-linux"; 28 | nixpkgs."x86_64-darwin" = nixpkgsForHost "x86_64-darwin"; 29 | nixpkgs."x86_64-linux" = nixpkgsForHost "x86_64-linux"; 30 | 31 | overlay = final: prev: { 32 | alejandra = final.rustPlatform.buildRustPackage { 33 | pname = "alejandra"; 34 | inherit version; 35 | src = ./.; 36 | cargoLock.lockFile = ./Cargo.lock; 37 | 38 | passthru.tests = { 39 | version = final.testVersion {package = prev.alejandra;}; 40 | }; 41 | 42 | meta = { 43 | description = "The Uncompromising Nix Code Formatter."; 44 | homepage = "https://github.com/kamadorueda/alejandra"; 45 | license = final.lib.licenses.unlicense; 46 | maintainers = [final.lib.maintainers.kamadorueda]; 47 | platforms = final.lib.systems.doubles.all; 48 | mainProgram = "alejandra"; 49 | }; 50 | }; 51 | }; 52 | 53 | buildBinariesForHost = host: pkgs: let 54 | binaries = builtins.listToAttrs ( 55 | builtins.map (pkg: { 56 | name = "alejandra-${pkg.stdenv.targetPlatform.config}"; 57 | value = pkg; 58 | }) 59 | pkgs 60 | ); 61 | in 62 | binaries 63 | // { 64 | "alejandra-binaries" = nixpkgs.${host}.linkFarm "alejandra-binaries" ( 65 | nixpkgs.${host}.lib.mapAttrsToList 66 | (name: binary: { 67 | inherit name; 68 | path = "${binary}/bin/alejandra"; 69 | }) 70 | binaries 71 | ); 72 | "default" = builtins.elemAt pkgs 0; 73 | }; 74 | in rec { 75 | checks."aarch64-darwin" = packages."aarch64-darwin"; 76 | checks."aarch64-linux" = packages."aarch64-linux"; 77 | checks."i686-linux" = packages."i686-linux"; 78 | checks."x86_64-darwin" = packages."x86_64-darwin"; 79 | checks."x86_64-linux" = packages."x86_64-linux"; 80 | 81 | defaultPackage."aarch64-darwin" = packages."aarch64-darwin"."alejandra-aarch64-apple-darwin"; 82 | defaultPackage."aarch64-linux" = packages."aarch64-linux"."alejandra-aarch64-unknown-linux-gnu"; 83 | defaultPackage."i686-linux" = packages."i686-linux"."alejandra-i686-unknown-linux-gnu"; 84 | defaultPackage."x86_64-darwin" = packages."x86_64-darwin"."alejandra-x86_64-apple-darwin"; 85 | defaultPackage."x86_64-linux" = packages."x86_64-linux"."alejandra-x86_64-unknown-linux-gnu"; 86 | 87 | devShell."x86_64-linux" = with nixpkgs."x86_64-linux"; 88 | mkShell { 89 | name = "alejandra"; 90 | packages = [ 91 | cargo-bloat 92 | cargo-license 93 | cargo-tarpaulin 94 | jq 95 | inputs.fenix.packages."x86_64-linux".latest.rustfmt 96 | inputs.fenix.packages."x86_64-linux".stable.toolchain 97 | linuxPackages_latest.perf 98 | nodejs 99 | nodePackages.prettier 100 | nodePackages.prettier-plugin-toml 101 | shfmt 102 | treefmt 103 | yarn 104 | yarn2nix 105 | ]; 106 | }; 107 | 108 | inherit overlay; 109 | overlays.default = overlay; 110 | 111 | packages."aarch64-darwin" = with nixpkgs."aarch64-darwin"; 112 | buildBinariesForHost "aarch64-darwin" [ 113 | alejandra 114 | ]; 115 | packages."aarch64-linux" = with nixpkgs."aarch64-linux"; 116 | buildBinariesForHost "aarch64-linux" [ 117 | alejandra 118 | pkgsStatic.alejandra 119 | ]; 120 | packages."i686-linux" = with nixpkgs."i686-linux"; 121 | buildBinariesForHost "i686-linux" [ 122 | alejandra 123 | ]; 124 | packages."x86_64-darwin" = with nixpkgs."x86_64-darwin"; 125 | buildBinariesForHost "x86_64-darwin" [ 126 | alejandra 127 | ]; 128 | packages."x86_64-linux" = with nixpkgs."x86_64-linux"; 129 | (buildBinariesForHost "x86_64-linux" [ 130 | alejandra 131 | pkgsStatic.alejandra 132 | 133 | pkgsCross.aarch64-multiplatform.pkgsStatic.alejandra 134 | # Temporarily disabled to speed up release 135 | # pkgsCross.armv7l-hf-multiplatform.pkgsStatic.alejandra 136 | # pkgsCross.gnu32.pkgsStatic.alejandra 137 | # pkgsCross.raspberryPi.pkgsStatic.alejandra 138 | ]) 139 | // { 140 | "alejandra-vscode-vsix" = mkYarnPackage { 141 | name = "alejandra"; 142 | src = ./integrations/vscode; 143 | packageJSON = ./integrations/vscode/package.json; 144 | yarnLock = ./integrations/vscode/yarn.lock; 145 | yarnNix = ./integrations/vscode/yarn.lock.nix; 146 | }; 147 | }; 148 | }; 149 | } 150 | -------------------------------------------------------------------------------- /front/.envrc: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | watch_file flake.lock 4 | watch_file flake.nix 5 | 6 | source <(nix print-dev-env) 7 | -------------------------------------------------------------------------------- /front/Cargo.toml: -------------------------------------------------------------------------------- 1 | [dependencies] 2 | alejandra = { "path" = "../src/alejandra" } 3 | console_error_panic_hook = "*" 4 | wasm-bindgen = "*" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | 9 | [package] 10 | authors = ["Kevin Amado "] 11 | description = "The Uncompromising Nix Code Formatter" 12 | edition = "2021" 13 | name = "alejandra_front" 14 | repository = "https://github.com/kamadorueda/alejandra" 15 | version = "4.0.0" 16 | 17 | [package.metadata.wasm-pack.profile.release] 18 | wasm-opt = false 19 | 20 | [profile.release] 21 | lto = true 22 | 23 | [workspace] 24 | -------------------------------------------------------------------------------- /front/deploy: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | wasm-pack build --target web 6 | rm -rf node_modules/ 7 | yarn install 8 | yarn build 9 | 10 | git worktree remove --force worktree || true 11 | git worktree add -B front worktree 12 | git -C worktree reset --hard 6adfbe8516bf6d9e896534e01118e1bc41f65425 13 | cp -rT ./build/ ./worktree/ 14 | 15 | git -C worktree add . 16 | git -C worktree commit -m "feat: deploy website" 17 | git -C worktree push --force origin HEAD:front 18 | -------------------------------------------------------------------------------- /front/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "fenix": { 4 | "inputs": { 5 | "nixpkgs": [ 6 | "nixpkgs" 7 | ], 8 | "rust-analyzer-src": "rust-analyzer-src" 9 | }, 10 | "locked": { 11 | "lastModified": 1730615655, 12 | "narHash": "sha256-2HBR3zLn57LXKNRtxBb+O+uDqHM4n0pz51rPayMl4cg=", 13 | "owner": "nix-community", 14 | "repo": "fenix", 15 | "rev": "efeb50e2535b17ffd4a135e6e3e5fd60a525180c", 16 | "type": "github" 17 | }, 18 | "original": { 19 | "owner": "nix-community", 20 | "repo": "fenix", 21 | "type": "github" 22 | } 23 | }, 24 | "nixpkgs": { 25 | "locked": { 26 | "lastModified": 1730642263, 27 | "narHash": "sha256-UXqvGZOHUDeAo8Sv5A5oObiQgBPELVgHQi130TU0jMU=", 28 | "owner": "nixos", 29 | "repo": "nixpkgs", 30 | "rev": "650fe87347086b30a6dbcc32b55987ce5a23c6ae", 31 | "type": "github" 32 | }, 33 | "original": { 34 | "owner": "nixos", 35 | "ref": "nixos-unstable-small", 36 | "repo": "nixpkgs", 37 | "type": "github" 38 | } 39 | }, 40 | "root": { 41 | "inputs": { 42 | "fenix": "fenix", 43 | "nixpkgs": "nixpkgs" 44 | } 45 | }, 46 | "rust-analyzer-src": { 47 | "flake": false, 48 | "locked": { 49 | "lastModified": 1730555913, 50 | "narHash": "sha256-KNHZUlqsEibg3YtfUyOFQSofP8hp1HKoY+laoesBxRM=", 51 | "owner": "rust-lang", 52 | "repo": "rust-analyzer", 53 | "rev": "f17a5bbfd0969ba2e63a74505a80e55ecb174ed9", 54 | "type": "github" 55 | }, 56 | "original": { 57 | "owner": "rust-lang", 58 | "ref": "nightly", 59 | "repo": "rust-analyzer", 60 | "type": "github" 61 | } 62 | } 63 | }, 64 | "root": "root", 65 | "version": 7 66 | } 67 | -------------------------------------------------------------------------------- /front/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | fenix.url = "github:nix-community/fenix"; 4 | fenix.inputs.nixpkgs.follows = "nixpkgs"; 5 | 6 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small"; 7 | }; 8 | 9 | outputs = inputs: let 10 | system = "x86_64-linux"; 11 | 12 | fenix = inputs.fenix.packages.${system}; 13 | nixpkgs = import inputs.nixpkgs {inherit system;}; 14 | in { 15 | devShell.${system} = nixpkgs.mkShell { 16 | name = "alejandra"; 17 | packages = [ 18 | (fenix.combine [ 19 | fenix.latest.rustc 20 | fenix.latest.toolchain 21 | fenix.targets."wasm32-unknown-unknown".latest.rust-std 22 | ]) 23 | nixpkgs.binaryen 24 | nixpkgs.pkg-config 25 | nixpkgs.openssl 26 | nixpkgs.yarn 27 | nixpkgs.wasm-pack 28 | ]; 29 | shellHook = '' 30 | export LD_LIBRARY_PATH=${nixpkgs.gcc.cc.lib}/lib:$LD_LIBRARY_PATH 31 | export LD_LIBRARY_PATH=${nixpkgs.zlib}/lib:$LD_LIBRARY_PATH 32 | ''; 33 | }; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /front/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "browserslist": { 3 | "development": [ 4 | "last 1 chrome version", 5 | "last 1 firefox version", 6 | "last 1 safari version" 7 | ], 8 | "production": [ 9 | ">0.2%", 10 | "not dead", 11 | "not op_mini all" 12 | ] 13 | }, 14 | "dependencies": { 15 | "alejandra_front": "file:pkg", 16 | "codemirror": "5", 17 | "react": "*", 18 | "react-codemirror2": "*", 19 | "react-diff-viewer": "*", 20 | "react-dom": "*", 21 | "react-scripts": "*", 22 | "react-wasm": "*", 23 | "tachyons": "*" 24 | }, 25 | "homepage": "https://kamadorueda.github.io/alejandra", 26 | "name": "front", 27 | "private": true, 28 | "scripts": { 29 | "build": "react-scripts build", 30 | "start": "react-scripts start" 31 | }, 32 | "version": "0.0.0" 33 | } 34 | -------------------------------------------------------------------------------- /front/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | Alejandra 💅 12 | 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /front/serve: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | wasm-pack build --target web 6 | rm -rf node_modules/ 7 | yarn install 8 | yarn start 9 | -------------------------------------------------------------------------------- /front/src/App.js: -------------------------------------------------------------------------------- 1 | import react from "react"; 2 | import { SideBySide } from "./SideBySide"; 3 | import "tachyons"; 4 | 5 | const App = () => { 6 | return ( 7 | 8 |

Alejandra 💅

9 |

The Uncompromising Nix Code Formatter

10 |
11 |
12 |
13 | 14 |
15 | ); 16 | }; 17 | 18 | export default App; 19 | -------------------------------------------------------------------------------- /front/src/Editor.js: -------------------------------------------------------------------------------- 1 | import "codemirror/lib/codemirror.css"; 2 | import "codemirror/mode/javascript/javascript"; 3 | import "codemirror/theme/monokai.css"; 4 | import { Controlled as CodeMirror } from "react-codemirror2"; 5 | 6 | export const Editor = ({ code, onChange }) => { 7 | return ( 8 | { 16 | onChange(value); 17 | }} 18 | /> 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /front/src/SideBySide.js: -------------------------------------------------------------------------------- 1 | import react from "react"; 2 | import ReactDiffViewer from "react-diff-viewer"; 3 | import * as wasm from "alejandra_front"; 4 | import { Editor } from "./Editor"; 5 | import { get, randomPath } from "./nixpkgs"; 6 | 7 | const getPermalink = (before, path) => { 8 | const searchParams = new URLSearchParams(); 9 | 10 | if (path !== undefined) { 11 | searchParams.append("path", path); 12 | } else { 13 | searchParams.append("before", before); 14 | } 15 | 16 | return ( 17 | window.location.origin + 18 | window.location.pathname + 19 | `?${searchParams.toString()}` 20 | ); 21 | }; 22 | 23 | export const SideBySide = () => { 24 | const [path, setPath] = react.useState(undefined); 25 | const [loading, setLoading] = react.useState(true); 26 | const [before, setBefore] = react.useState(""); 27 | 28 | react.useEffect(() => { 29 | const searchParams = new URLSearchParams(window.location.search); 30 | 31 | if (searchParams.has("path")) { 32 | setPath(searchParams.get("path")); 33 | } else if (searchParams.has("before")) { 34 | setBefore(searchParams.get("before")); 35 | } else { 36 | setPath(randomPath()); 37 | } 38 | }, []); 39 | 40 | react.useEffect(() => { 41 | (async () => { 42 | await wasm.default(); 43 | setLoading(false); 44 | })(); 45 | }, [wasm]); 46 | 47 | react.useEffect(() => { 48 | if (path !== undefined) { 49 | (async () => { 50 | const content = await get(path); 51 | setBefore(content); 52 | })(); 53 | } 54 | }, [path]); 55 | 56 | if (loading) { 57 | return ( 58 |
59 |
Loading
60 |
61 | ); 62 | } 63 | 64 | const after = wasm.format(before, "before.nix"); 65 | 66 | const permalink = getPermalink(before, path); 67 | 68 | return ( 69 | 70 |
71 |
72 | Type your code below or  73 | { 76 | setPath(randomPath()); 77 | }} 78 | > 79 | click here to fetch a random file from Nixpkgs 80 | 81 |
82 |
83 |
With Alejandra ❤️
84 |
85 |
86 |
87 | { 90 | setBefore(code); 91 | setPath(undefined); 92 | }} 93 | /> 94 |
95 | Permalink:  96 | {permalink.length > 2048 ? ( 97 | "not available, exceeds 2048 characters" 98 | ) : ( 99 | 100 | here 101 | 102 | )} 103 |
104 |
105 |
106 |
107 | {}} /> 108 |
109 |
110 |
111 |
Git patch
112 |
113 |
114 |
115 | 120 |
121 |
122 | 123 | ); 124 | }; 125 | -------------------------------------------------------------------------------- /front/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import App from "./App"; 4 | 5 | const CONTAINER = document.getElementById("root"); 6 | const ROOT = ReactDOM.createRoot(CONTAINER); 7 | 8 | ROOT.render(); 9 | -------------------------------------------------------------------------------- /front/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::panic; 2 | 3 | use wasm_bindgen::prelude::*; 4 | 5 | #[wasm_bindgen(start)] 6 | pub fn main() -> Result<(), JsValue> { 7 | panic::set_hook(Box::new(console_error_panic_hook::hook)); 8 | Ok(()) 9 | } 10 | 11 | #[wasm_bindgen] 12 | pub fn format(before: String, path: String) -> String { 13 | alejandra::format::in_memory(path, before, Default::default()).1 14 | } 15 | -------------------------------------------------------------------------------- /front/src/nixpkgs.js: -------------------------------------------------------------------------------- 1 | import { COMMIT, FILES } from "./nixpkgsFiles"; 2 | 3 | export const randomPath = () => FILES[Math.floor(Math.random() * FILES.length)]; 4 | 5 | export const path2url = (path) => 6 | `https://raw.githubusercontent.com/nixos/nixpkgs/${COMMIT}/${path}`; 7 | 8 | export const get = async (path) => { 9 | const url = path2url(path); 10 | 11 | try { 12 | const response = await fetch(url); 13 | 14 | return await response.text(); 15 | } catch (error) { 16 | return `# An error ocurred while fetching ${url}\n# ${error}`; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /integrations/doom-emacs/README.md: -------------------------------------------------------------------------------- 1 | # Doom Emacs integration 2 | 3 | In order to configure Alejandra in 4 | [Doom Emacs](https://github.com/hlissner/doom-emacs) 5 | just use the following: 6 | 7 | ```lisp 8 | (after! nix-mode 9 | (set-formatter! 'alejandra '("alejandra" "--quiet") :modes '(nix-mode))) 10 | ``` 11 | 12 | If you've enabled formatting via LSP in Nix, 13 | you might also need to add the following: 14 | 15 | ```lisp 16 | (setq-hook! 'nix-mode-hook +format-with-lsp nil) 17 | ``` 18 | -------------------------------------------------------------------------------- /integrations/gnu-emacs/README.md: -------------------------------------------------------------------------------- 1 | # Emacs integration 2 | 3 | In order to use Alejandra with 4 | [Emacs](https://www.gnu.org/software/emacs/) 5 | please use any of the following plugins: 6 | 7 | - [format-all for Emacs](https://github.com/lassik/emacs-format-all-the-code) 8 | -------------------------------------------------------------------------------- /integrations/neovim/README.md: -------------------------------------------------------------------------------- 1 | # Neovim integration 2 | 3 | In order to use Alejandra with 4 | [Neovim](https://neovim.io/) 5 | please use the `:%!alejandra -qq` command 6 | to format the current buffer, 7 | or use any of the following plugins: 8 | 9 | - [Neoformat](https://github.com/sbdchd/neoformat) 10 | - [null-ls.nvim](https://github.com/jose-elias-alvarez/null-ls.nvim) 11 | - [ALE](https://github.com/dense-analysis/ale) 12 | -------------------------------------------------------------------------------- /integrations/pre-commit-hooks-nix/README.md: -------------------------------------------------------------------------------- 1 | # Pre-commit-hooks.nix integration 2 | 3 | In order to use Alejandra with 4 | [pre-commit-hooks.nix](https://github.com/cachix/pre-commit-hooks.nix) 5 | use a configuration file like the following: 6 | 7 | ```nix 8 | { 9 | pre-commit-check = pre-commit-hooks.lib.${system}.run { 10 | hooks = { 11 | alejandra.enable = true; 12 | }; 13 | }; 14 | } 15 | ``` 16 | -------------------------------------------------------------------------------- /integrations/pre-commit/README.md: -------------------------------------------------------------------------------- 1 | # Pre-Commit integration 2 | 3 | In order to use Alejandra with 4 | [Pre-Commit](https://pre-commit.com/) 5 | just create a file named `.pre-commit-config.yaml` 6 | with contents: 7 | 8 | ```yaml 9 | repos: 10 | - repo: https://github.com/kamadorueda/alejandra 11 | rev: 4.0.0 12 | # Choose either the 'alejandra' or 'alejandra-system' hook 13 | # depending on what pre-requisites you have: 14 | hooks: 15 | # No prerequisites 16 | - id: alejandra 17 | 18 | # Requires Nix to be previously installed in the system 19 | - id: alejandra-nix 20 | 21 | # Requires Alejandra to be previously installed in the system 22 | - id: alejandra-system 23 | ``` 24 | 25 | To use the latest hook, run `pre-commit autoupdate --freeze --repo=https://github.com/kamadorueda/alejandra`. 26 | -------------------------------------------------------------------------------- /integrations/vim/README.md: -------------------------------------------------------------------------------- 1 | # Vim integration 2 | 3 | In order to use Alejandra with 4 | [Vim](https://www.vim.org/) 5 | please use the `:%!alejandra -qq` command 6 | to format the current buffer. 7 | -------------------------------------------------------------------------------- /integrations/vscode/.yarnrc: -------------------------------------------------------------------------------- 1 | --ignore-engines true -------------------------------------------------------------------------------- /integrations/vscode/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Publishing the extension to open-vsx 2 | 3 | > https://open-vsx.org/extension/kamadorueda/alejandra 4 | 5 | ```sh 6 | $ yarn install 7 | $ yarn vsce package 8 | $ ovsx create-namespace kamadorueda -p "${TOKEN}" 9 | $ ovsx publish -p "${TOKEN}" ./alejandra-*.vsix 10 | ``` 11 | -------------------------------------------------------------------------------- /integrations/vscode/LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /integrations/vscode/README.md: -------------------------------------------------------------------------------- 1 |

Alejandra 💅

2 | 3 |

The Uncompromising Nix Code Formatter

4 | 5 | ## Features 6 | 7 | This extension adds built-in editor support 8 | for formatting Nix files automatically 9 | with [Alejandra](https://github.com/kamadorueda/alejandra). 10 | 11 | ## Getting started 12 | 13 | 1. Make sure to install 14 | [Alejandra](https://github.com/kamadorueda/alejandra) 15 | in your system first 16 | as explained [here](https://github.com/kamadorueda/alejandra). 17 | 18 | 1. Install the vscode extension and reload the window (just close and open again). 19 | 20 | 1. Open a Nix file, 21 | do a right click 22 | and you should be able to see "Format Document" in the menu. 23 | 24 | Alternatively, it will be formatted automatically when you save the file. 25 | 26 | Enjoy! 27 | 28 | ## Troubleshooting 29 | 30 | If you encounter a problem 31 | please let us know in the 32 | [issues section](https://github.com/kamadorueda/alejandra/issues). 33 | 34 | The most probable causes of failure are: 35 | 36 | - Not having Alejandra installed in your system. 37 | 38 | In this case please follow the instructions 39 | [here](https://github.com/kamadorueda/alejandra). 40 | 41 | - A misconfiguration. 42 | 43 | In this case please make sure that your config contains the following values: 44 | 45 | ```json 46 | { 47 | "[nix]": { 48 | "editor.defaultFormatter": "kamadorueda.alejandra", 49 | "editor.formatOnPaste": true, 50 | "editor.formatOnSave": true, 51 | "editor.formatOnType": false 52 | }, 53 | "alejandra.program": "alejandra" 54 | } 55 | ``` 56 | -------------------------------------------------------------------------------- /integrations/vscode/extension.js: -------------------------------------------------------------------------------- 1 | const { execFile } = require("child_process"); 2 | const vscode = require("vscode"); 3 | 4 | const activate = (_) => { 5 | const outputChannel = vscode.window.createOutputChannel("Alejandra"); 6 | 7 | vscode.languages.registerDocumentFormattingEditProvider("nix", { 8 | provideDocumentFormattingEdits(document, _) { 9 | const config = { 10 | alejandra: vscode.workspace.getConfiguration("alejandra"), 11 | }; 12 | 13 | return new Promise((resolve, reject) => { 14 | try { 15 | outputChannel.appendLine( 16 | `Running Alejandra with settings: ${JSON.stringify(config)}` 17 | ); 18 | 19 | const process = execFile( 20 | config.alejandra.program, 21 | [], 22 | {}, 23 | (error, stdout, stderr) => { 24 | if (error) { 25 | outputChannel.appendLine(`error: ${error}`); 26 | outputChannel.appendLine(`stderr: ${stderr}`); 27 | vscode.window.showErrorMessage( 28 | `While executing Alejandra with settings: ` + 29 | `${JSON.stringify(config)}, ` + 30 | `${error}` 31 | ); 32 | reject(error); 33 | } 34 | 35 | const documentRange = new vscode.Range( 36 | document.lineAt(0).range.start, 37 | document.lineAt( 38 | document.lineCount - 1 39 | ).rangeIncludingLineBreak.end 40 | ); 41 | 42 | resolve([new vscode.TextEdit(documentRange, stdout)]); 43 | } 44 | ); 45 | 46 | const documentText = document.getText(); 47 | 48 | outputChannel.appendLine( 49 | `Feeding ${documentText.length} of input to stdin` 50 | ); 51 | 52 | process.stdin.write(documentText); 53 | process.stdin.end(); 54 | } catch (error) { 55 | vscode.window.showErrorMessage( 56 | `While executing Alejandra with settings: ` + 57 | `${JSON.stringify(config)} ` + 58 | `${error}` 59 | ); 60 | reject(error); 61 | } 62 | }); 63 | }, 64 | }); 65 | }; 66 | 67 | const deactivate = () => {}; 68 | 69 | module.exports = { 70 | activate, 71 | deactivate, 72 | }; 73 | -------------------------------------------------------------------------------- /integrations/vscode/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "checkJs": true, 4 | "lib": ["ES2020"], 5 | "module": "CommonJS", 6 | "target": "ES2020" 7 | }, 8 | "exclude": ["node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /integrations/vscode/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "activationEvents": [ 3 | "onLanguage:nix" 4 | ], 5 | "author": { 6 | "email": "kamadorueda@gmail.com", 7 | "name": "Kevin Amado", 8 | "url": "https://github.com/kamadorueda" 9 | }, 10 | "categories": [ 11 | "Formatters" 12 | ], 13 | "contributes": { 14 | "configuration": { 15 | "properties": { 16 | "alejandra.program": { 17 | "default": "alejandra", 18 | "description": "Specifies an alternative full path to the Alejandra executable.", 19 | "type": [ 20 | "string" 21 | ] 22 | } 23 | }, 24 | "title": "Alejandra" 25 | }, 26 | "configurationDefaults": { 27 | "[nix]": { 28 | "editor.defaultFormatter": "kamadorueda.alejandra", 29 | "editor.formatOnPaste": true, 30 | "editor.formatOnSave": true, 31 | "editor.formatOnType": false 32 | }, 33 | "alejandra.program": "alejandra" 34 | }, 35 | "languages": [ 36 | { 37 | "aliases": [ 38 | "nix", 39 | "Nix" 40 | ], 41 | "extensions": [ 42 | ".nix" 43 | ], 44 | "id": "nix" 45 | } 46 | ] 47 | }, 48 | "description": "The Uncompromising Nix Code Formatter", 49 | "devDependencies": { 50 | "ovsx": "*", 51 | "vsce": "*" 52 | }, 53 | "displayName": "Alejandra 💅", 54 | "engines": { 55 | "vscode": "^1.64.0" 56 | }, 57 | "funding": { 58 | "type": "patreon", 59 | "url": "https://www.patreon.com/kamadorueda" 60 | }, 61 | "license": "Unlicense", 62 | "main": "./extension.js", 63 | "name": "alejandra", 64 | "publisher": "kamadorueda", 65 | "repository": { 66 | "type": "git", 67 | "url": "https://github.com/kamadorueda/alejandra" 68 | }, 69 | "version": "4.0.0" 70 | } 71 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | # https://github.com/kamadorueda/machine/blob/main/nixos-modules/editor/rustfmt.toml 2 | edition = "2021" 3 | enum_discrim_align_threshold = 999 4 | # force_multiline_blocks = true 5 | format_code_in_doc_comments = true 6 | format_generated_files = true 7 | format_macro_bodies = true 8 | format_macro_matchers = true 9 | format_strings = true 10 | group_imports = "StdExternalCrate" 11 | hex_literal_case = "Lower" 12 | imports_granularity = "Item" 13 | imports_layout = "Vertical" 14 | # match_block_trailing_comma = true 15 | max_width = 80 16 | normalize_comments = true 17 | normalize_doc_attributes = true 18 | overflow_delimited_expr = true 19 | reorder_impl_items = true 20 | struct_field_align_threshold = 999 21 | unstable_features = true 22 | use_field_init_shorthand = true 23 | use_small_heuristics = "Max" 24 | style_edition = "2021" 25 | wrap_comments = true 26 | -------------------------------------------------------------------------------- /src/alejandra/Cargo.toml: -------------------------------------------------------------------------------- 1 | [dependencies] 2 | rnix = { version = "*", default-features = false, features = [] } 3 | rowan = { version = "0.15.16", default-features = false, features = [] } 4 | serde = { version = "*", default-features = false, features = ["derive"] } 5 | 6 | [target.aarch64-unknown-linux-musl.dependencies.mimalloc] 7 | default-features = false 8 | version = "0" 9 | 10 | [target.arm-unknown-linux-musleabihf.dependencies.mimalloc] 11 | default-features = false 12 | version = "0" 13 | 14 | [target.i686-unknown-linux-musl.dependencies.mimalloc] 15 | default-features = false 16 | version = "0" 17 | 18 | [target.x86_64-unknown-linux-gnu.dependencies.mimalloc] 19 | default-features = false 20 | version = "0" 21 | 22 | [target.x86_64-unknown-linux-musl.dependencies.mimalloc] 23 | default-features = false 24 | version = "0" 25 | 26 | [package] 27 | authors = ["Kevin Amado "] 28 | description = "The Uncompromising Nix Code Formatter" 29 | edition = "2021" 30 | license = "Unlicense" 31 | name = "alejandra" 32 | readme = "../../README.md" 33 | repository = "https://github.com/kamadorueda/alejandra" 34 | version = "4.0.0" 35 | 36 | [dev-dependencies] 37 | pretty_assertions = "1.3.0" 38 | -------------------------------------------------------------------------------- /src/alejandra/src/children2.rs: -------------------------------------------------------------------------------- 1 | use std::collections::LinkedList; 2 | 3 | pub(crate) enum Trivia { 4 | Comment(String), 5 | Newlines, 6 | } 7 | 8 | pub(crate) struct Child { 9 | pub element: rnix::SyntaxElement, 10 | 11 | pub inline_comment: Option, 12 | pub has_inline_comment: bool, 13 | 14 | pub trivialities: LinkedList, 15 | pub has_comments: bool, 16 | pub has_trivialities: bool, 17 | } 18 | 19 | pub(crate) fn new( 20 | build_ctx: &crate::builder::BuildCtx, 21 | node: &rnix::SyntaxNode, 22 | ) -> std::collections::linked_list::IntoIter { 23 | let mut children = crate::children::Children::new(build_ctx, node); 24 | 25 | let mut elements = LinkedList::new(); 26 | 27 | while let Some(element) = children.get_next() { 28 | let mut inline_comment = None; 29 | let mut trivialities = LinkedList::new(); 30 | 31 | let mut skip_next_newline = false; 32 | children.drain_trivia(|element| match element { 33 | crate::children::Trivia::Comment(text) => { 34 | if inline_comment.is_none() 35 | && trivialities.is_empty() 36 | && text.starts_with('#') 37 | { 38 | inline_comment = Some(text); 39 | skip_next_newline = true; 40 | } else { 41 | trivialities.push_back(Trivia::Comment(text)); 42 | } 43 | } 44 | crate::children::Trivia::Whitespace(text) => { 45 | let mut newlines = crate::utils::count_newlines(&text); 46 | 47 | if skip_next_newline && newlines > 0 { 48 | newlines -= 1; 49 | skip_next_newline = false; 50 | } 51 | 52 | if newlines > 0 { 53 | trivialities.push_back(Trivia::Newlines) 54 | } 55 | } 56 | }); 57 | 58 | let has_inline_comment = inline_comment.is_some(); 59 | let has_comments = trivialities 60 | .iter() 61 | .any(|trivia| matches!(trivia, Trivia::Comment(_))); 62 | let has_trivialities = !trivialities.is_empty(); 63 | 64 | elements.push_back(Child { 65 | element, 66 | 67 | inline_comment, 68 | has_inline_comment, 69 | 70 | trivialities, 71 | has_comments, 72 | has_trivialities, 73 | }) 74 | } 75 | 76 | elements.into_iter() 77 | } 78 | -------------------------------------------------------------------------------- /src/alejandra/src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | 3 | /// Configuration used by the formatter 4 | #[derive(Clone, Copy, Default, Deserialize)] 5 | #[serde(deny_unknown_fields)] 6 | pub struct Config { 7 | /// Indentation to use 8 | #[serde(default)] 9 | pub indentation: Indentation, 10 | } 11 | 12 | #[derive(Clone, Copy, Default, Deserialize)] 13 | /// Indentation options 14 | pub enum Indentation { 15 | /// Four spaces 16 | FourSpaces, 17 | /// Tabs 18 | Tabs, 19 | #[default] 20 | /// Two spaces 21 | TwoSpaces, 22 | } 23 | -------------------------------------------------------------------------------- /src/alejandra/src/format.rs: -------------------------------------------------------------------------------- 1 | use crate::config::Config; 2 | 3 | /// Possibles results after formatting. 4 | #[derive(Clone)] 5 | pub enum Status { 6 | /// An error occurred, and its reason. 7 | Error(String), 8 | /// Formatting was successful, 9 | /// the file changed or not according to the boolean. 10 | Changed(bool), 11 | } 12 | 13 | impl From for Status { 14 | fn from(error: std::io::Error) -> Status { 15 | Status::Error(error.to_string()) 16 | } 17 | } 18 | 19 | /// Formats the content of `before` in-memory 20 | /// assuming the contents come from `path` when displaying error messages 21 | pub fn in_memory( 22 | path: String, 23 | before: String, 24 | config: Config, 25 | ) -> (Status, String) { 26 | let parsed = rnix::Root::parse(&before); 27 | 28 | let errors = parsed.errors(); 29 | 30 | if !errors.is_empty() { 31 | return (Status::Error(errors[0].to_string()), before); 32 | } 33 | 34 | let mut build_ctx = crate::builder::BuildCtx { 35 | config, 36 | fitting_in_single_line_depth: 0, 37 | force_wide: false, 38 | force_wide_success: true, 39 | indentation: 0, 40 | path, 41 | pos_old: crate::position::Position::default(), 42 | vertical: true, 43 | }; 44 | 45 | let root = parsed.syntax(); 46 | 47 | let after = 48 | crate::builder::build(&mut build_ctx, root.into()).unwrap().to_string(); 49 | 50 | if before == after { 51 | (Status::Changed(false), after) 52 | } else { 53 | (Status::Changed(true), after) 54 | } 55 | } 56 | 57 | /// Formats the file at `path`, 58 | /// optionally overriding it's contents if `in_place` is true. 59 | pub fn in_fs(path: String, config: Config, in_place: bool) -> Status { 60 | use std::io::Write; 61 | 62 | match std::fs::read_to_string(&path) { 63 | Ok(before) => { 64 | let (status, data) = 65 | crate::format::in_memory(path.clone(), before, config); 66 | 67 | match status { 68 | Status::Changed(changed) => { 69 | if in_place { 70 | if changed { 71 | match std::fs::File::create(path) { 72 | Ok(mut file) => { 73 | match file.write_all(data.as_bytes()) { 74 | Ok(_) => Status::Changed(true), 75 | Err(error) => Status::from(error), 76 | } 77 | } 78 | Err(error) => Status::from(error), 79 | } 80 | } else { 81 | Status::Changed(false) 82 | } 83 | } else { 84 | Status::Changed(changed) 85 | } 86 | } 87 | Status::Error(error) => Status::Error(error), 88 | } 89 | } 90 | Err(error) => Status::from(error), 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/alejandra/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Alejandra takes your Nix code and re-formats it in a consistent style. 2 | //! 3 | //! For more information please visit the 4 | //! [Alejandra repository on GitHub](https://github.com/kamadorueda/alejandra). 5 | #![deny(missing_docs)] 6 | #![deny(rustdoc::bare_urls)] 7 | #![deny(rustdoc::broken_intra_doc_links)] 8 | #![deny(rustdoc::invalid_codeblock_attributes)] 9 | #![deny(rustdoc::invalid_html_tags)] 10 | #![deny(rustdoc::invalid_rust_codeblocks)] 11 | #![deny(rustdoc::missing_crate_level_docs)] 12 | #![deny(rustdoc::private_intra_doc_links)] 13 | #![deny(rustdoc::private_doc_tests)] 14 | 15 | #[cfg(any( 16 | // aarch64-unknown-linux-musl 17 | all( 18 | target_arch = "aarch64", 19 | target_vendor = "unknown", 20 | target_os = "linux", 21 | target_env = "musl" 22 | ), 23 | // arm-unknown-linux-musleabihf 24 | all( 25 | target_arch = "arm", 26 | target_vendor = "unknown", 27 | target_os = "linux", 28 | target_env = "musl", 29 | target_abi = "eabihf" 30 | ), 31 | // i686-unknown-linux-musl 32 | all( 33 | target_arch = "x86", 34 | target_vendor = "unknown", 35 | target_os = "linux", 36 | target_env = "musl" 37 | ), 38 | // x86_64-unknown-linux-gnu 39 | // x86_64-unknown-linux-musl 40 | all( 41 | target_arch = "x86_64", 42 | target_vendor = "unknown", 43 | target_os = "linux", 44 | any(target_env = "gnu", target_env = "musl") 45 | ), 46 | ))] 47 | #[global_allocator] 48 | static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; 49 | 50 | pub(crate) mod builder; 51 | pub(crate) mod children; 52 | pub(crate) mod children2; 53 | /// Configuration options for the formatter 54 | pub mod config; 55 | /// Functions for formatting Nix code. 56 | pub mod format; 57 | pub(crate) mod parsers; 58 | pub(crate) mod position; 59 | pub(crate) mod rules; 60 | pub(crate) mod utils; 61 | /// Metadata. 62 | pub mod version; 63 | -------------------------------------------------------------------------------- /src/alejandra/src/parsers/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod pattern; 2 | -------------------------------------------------------------------------------- /src/alejandra/src/parsers/pattern.rs: -------------------------------------------------------------------------------- 1 | use std::collections::LinkedList; 2 | 3 | #[derive(Default)] 4 | pub(crate) struct Argument { 5 | pub comments_before: LinkedList, 6 | pub item: Option, 7 | pub comment_after: Option, 8 | } 9 | 10 | #[derive(Default)] 11 | pub(crate) struct Pattern { 12 | pub initial_at: Option, 13 | pub comments_after_initial_at: LinkedList, 14 | pub arguments: LinkedList, 15 | pub comments_before_curly_b_close: LinkedList, 16 | pub comments_before_end_at: LinkedList, 17 | pub end_at: Option, 18 | } 19 | 20 | pub(crate) fn parse( 21 | build_ctx: &crate::builder::BuildCtx, 22 | node: &rnix::SyntaxNode, 23 | ) -> Pattern { 24 | let mut pattern = Pattern::default(); 25 | 26 | let mut children = crate::children::Children::new(build_ctx, node); 27 | 28 | // x @ 29 | let child = children.peek_next().unwrap(); 30 | if let rnix::SyntaxKind::NODE_PAT_BIND = child.kind() { 31 | pattern.initial_at = Some(child); 32 | children.move_next(); 33 | } 34 | 35 | // /**/ 36 | children.drain_trivia(|element| match element { 37 | crate::children::Trivia::Comment(text) => { 38 | pattern.comments_after_initial_at.push_back(text); 39 | } 40 | crate::children::Trivia::Whitespace(_) => {} 41 | }); 42 | 43 | // { 44 | children.move_next(); 45 | 46 | // arguments 47 | loop { 48 | let mut argument = Argument::default(); 49 | 50 | // Before an item we can have: comma, comments, whitespace 51 | loop { 52 | let child = children.peek_next().unwrap(); 53 | 54 | match child.kind() { 55 | rnix::SyntaxKind::NODE_PAT_ENTRY 56 | | rnix::SyntaxKind::TOKEN_R_BRACE 57 | | rnix::SyntaxKind::TOKEN_ELLIPSIS => { 58 | break; 59 | } 60 | rnix::SyntaxKind::TOKEN_COMMA => { 61 | children.move_next(); 62 | } 63 | rnix::SyntaxKind::TOKEN_COMMENT => { 64 | let content = child.into_token().unwrap().to_string(); 65 | 66 | argument.comments_before.push_back(content); 67 | children.move_next(); 68 | } 69 | rnix::SyntaxKind::TOKEN_WHITESPACE => { 70 | children.move_next(); 71 | } 72 | _ => {} 73 | } 74 | } 75 | 76 | // item 77 | let child = children.peek_next().unwrap(); 78 | match child.kind() { 79 | rnix::SyntaxKind::TOKEN_R_BRACE => { 80 | pattern.comments_before_curly_b_close = 81 | argument.comments_before; 82 | break; 83 | } 84 | rnix::SyntaxKind::TOKEN_ELLIPSIS 85 | | rnix::SyntaxKind::NODE_PAT_ENTRY => { 86 | argument.item = Some(child); 87 | children.move_next(); 88 | } 89 | _ => {} 90 | } 91 | 92 | // After an item we can have: comma, comments, whitespace 93 | loop { 94 | let child = children.peek_next().unwrap(); 95 | 96 | match child.kind() { 97 | rnix::SyntaxKind::NODE_PAT_ENTRY 98 | | rnix::SyntaxKind::TOKEN_ELLIPSIS 99 | | rnix::SyntaxKind::TOKEN_R_BRACE => { 100 | break; 101 | } 102 | rnix::SyntaxKind::TOKEN_COMMA => { 103 | children.move_next(); 104 | } 105 | rnix::SyntaxKind::TOKEN_COMMENT => { 106 | let content = child.into_token().unwrap().to_string(); 107 | 108 | children.move_next(); 109 | argument.comment_after = Some(content); 110 | break; 111 | } 112 | rnix::SyntaxKind::TOKEN_WHITESPACE => { 113 | let content = child.into_token().unwrap().to_string(); 114 | 115 | children.move_next(); 116 | if crate::utils::count_newlines(&content) > 0 { 117 | break; 118 | } 119 | } 120 | _ => {} 121 | } 122 | } 123 | 124 | pattern.arguments.push_back(argument); 125 | } 126 | 127 | // } 128 | children.move_next(); 129 | 130 | // /**/ 131 | children.drain_trivia(|element| match element { 132 | crate::children::Trivia::Comment(text) => { 133 | pattern.comments_before_end_at.push_back(text); 134 | } 135 | crate::children::Trivia::Whitespace(_) => {} 136 | }); 137 | 138 | // @ x 139 | if let Some(child) = children.peek_next() { 140 | if let rnix::SyntaxKind::NODE_PAT_BIND = child.kind() { 141 | pattern.end_at = Some(child); 142 | } 143 | } 144 | 145 | pattern 146 | } 147 | -------------------------------------------------------------------------------- /src/alejandra/src/position.rs: -------------------------------------------------------------------------------- 1 | #[derive(Clone)] 2 | pub(crate) struct Position { 3 | pub column: usize, 4 | pub line: usize, 5 | } 6 | 7 | impl Default for Position { 8 | fn default() -> Position { 9 | Position { column: 0, line: 1 } 10 | } 11 | } 12 | 13 | impl Position { 14 | pub fn update(&mut self, text: &str) { 15 | for char in text.chars() { 16 | if char == '\n' { 17 | self.line += 1; 18 | self.column = 0; 19 | } else { 20 | self.column += 1; 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/apply.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children2::new(build_ctx, node); 8 | 9 | let first = children.next().unwrap(); 10 | let second = children.next().unwrap(); 11 | 12 | let vertical = build_ctx.vertical 13 | || first.has_inline_comment 14 | || first.has_trivialities 15 | || second.has_inline_comment 16 | || second.has_trivialities; 17 | 18 | // first 19 | if vertical { 20 | steps.push_back(crate::builder::Step::FormatWider(first.element)); 21 | } else { 22 | steps.push_back(crate::builder::Step::Format(first.element)); 23 | } 24 | 25 | if let Some(text) = first.inline_comment { 26 | steps.push_back(crate::builder::Step::Whitespace); 27 | steps.push_back(crate::builder::Step::Comment(text)); 28 | steps.push_back(crate::builder::Step::NewLine); 29 | steps.push_back(crate::builder::Step::Pad); 30 | } 31 | 32 | for trivia in first.trivialities { 33 | match trivia { 34 | crate::children2::Trivia::Comment(text) => { 35 | steps.push_back(crate::builder::Step::NewLine); 36 | steps.push_back(crate::builder::Step::Pad); 37 | steps.push_back(crate::builder::Step::Comment(text)); 38 | } 39 | crate::children2::Trivia::Newlines => {} 40 | } 41 | } 42 | 43 | // second 44 | if vertical { 45 | if !first.has_inline_comment 46 | && !first.has_trivialities 47 | && matches!( 48 | second.element.kind(), 49 | rnix::SyntaxKind::NODE_ATTR_SET 50 | | rnix::SyntaxKind::NODE_LIST 51 | | rnix::SyntaxKind::NODE_PAREN 52 | | rnix::SyntaxKind::NODE_STRING 53 | ) 54 | { 55 | steps.push_back(crate::builder::Step::Whitespace); 56 | } else { 57 | steps.push_back(crate::builder::Step::NewLine); 58 | steps.push_back(crate::builder::Step::Pad); 59 | }; 60 | steps.push_back(crate::builder::Step::FormatWider(second.element)); 61 | } else { 62 | steps.push_back(crate::builder::Step::Whitespace); 63 | steps.push_back(crate::builder::Step::Format(second.element)); 64 | } 65 | 66 | steps 67 | } 68 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/attr_set.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children::Children::new(build_ctx, node); 8 | 9 | let items_count = node 10 | .children_with_tokens() 11 | .skip_while(|element| element.kind() != rnix::SyntaxKind::TOKEN_L_BRACE) 12 | .take_while(|element| element.kind() != rnix::SyntaxKind::TOKEN_R_BRACE) 13 | .filter(|element| { 14 | matches!( 15 | element.kind(), 16 | rnix::SyntaxKind::NODE_ATTRPATH_VALUE 17 | | rnix::SyntaxKind::NODE_INHERIT 18 | | rnix::SyntaxKind::NODE_INHERIT_FROM 19 | | rnix::SyntaxKind::TOKEN_COMMENT 20 | ) 21 | }) 22 | .count(); 23 | 24 | let vertical = items_count > 1 25 | || children.has_comments() 26 | || children.has_newlines() 27 | || build_ctx.vertical; 28 | 29 | // rec 30 | let child = children.peek_next().unwrap(); 31 | if let rnix::SyntaxKind::TOKEN_REC = child.kind() { 32 | steps.push_back(crate::builder::Step::Format(child)); 33 | children.move_next(); 34 | 35 | if let rnix::SyntaxKind::TOKEN_COMMENT 36 | | rnix::SyntaxKind::TOKEN_WHITESPACE = 37 | children.peek_next().unwrap().kind() 38 | { 39 | steps.push_back(crate::builder::Step::NewLine); 40 | steps.push_back(crate::builder::Step::Pad); 41 | } else { 42 | steps.push_back(crate::builder::Step::Whitespace); 43 | } 44 | } 45 | 46 | // /**/ 47 | children.drain_trivia(|element| match element { 48 | crate::children::Trivia::Comment(text) => { 49 | steps.push_back(crate::builder::Step::Comment(text)); 50 | steps.push_back(crate::builder::Step::NewLine); 51 | steps.push_back(crate::builder::Step::Pad); 52 | } 53 | crate::children::Trivia::Whitespace(_) => {} 54 | }); 55 | 56 | // { 57 | let child = children.get_next().unwrap(); 58 | steps.push_back(crate::builder::Step::Format(child)); 59 | if vertical { 60 | steps.push_back(crate::builder::Step::Indent); 61 | } 62 | 63 | let mut item_index: usize = 0; 64 | let mut inline_next_comment = false; 65 | 66 | loop { 67 | // /**/ 68 | children.drain_trivia(|element| match element { 69 | crate::children::Trivia::Comment(text) => { 70 | if inline_next_comment && text.starts_with('#') { 71 | steps.push_back(crate::builder::Step::Whitespace); 72 | } else { 73 | steps.push_back(crate::builder::Step::NewLine); 74 | steps.push_back(crate::builder::Step::Pad); 75 | } 76 | steps.push_back(crate::builder::Step::Comment(text)); 77 | item_index += 1; 78 | inline_next_comment = false; 79 | } 80 | crate::children::Trivia::Whitespace(text) => { 81 | let newlines = crate::utils::count_newlines(&text); 82 | 83 | if newlines > 1 && item_index > 0 && item_index < items_count { 84 | steps.push_back(crate::builder::Step::NewLine); 85 | } 86 | 87 | inline_next_comment = newlines == 0; 88 | } 89 | }); 90 | 91 | if let Some(child) = children.peek_next() { 92 | if let rnix::SyntaxKind::TOKEN_R_BRACE = child.kind() { 93 | break; 94 | } 95 | 96 | // item 97 | item_index += 1; 98 | if vertical { 99 | steps.push_back(crate::builder::Step::NewLine); 100 | steps.push_back(crate::builder::Step::Pad); 101 | steps.push_back(crate::builder::Step::FormatWider(child)); 102 | } else { 103 | if item_index > 1 { 104 | steps.push_back(crate::builder::Step::Whitespace); 105 | } 106 | steps.push_back(crate::builder::Step::Format(child)); 107 | } 108 | children.move_next(); 109 | inline_next_comment = true; 110 | } 111 | } 112 | 113 | // } 114 | let child = children.get_next().unwrap(); 115 | if vertical { 116 | steps.push_back(crate::builder::Step::Dedent); 117 | steps.push_back(crate::builder::Step::NewLine); 118 | steps.push_back(crate::builder::Step::Pad); 119 | } 120 | steps.push_back(crate::builder::Step::Format(child)); 121 | 122 | steps 123 | } 124 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/bin_op.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | 6 | let mut steps = std::collections::LinkedList::new(); 7 | 8 | let mut children = crate::children2::new(build_ctx, node); 9 | 10 | let first = children.next().unwrap(); 11 | let second = children.next().unwrap(); 12 | let third = children.next().unwrap(); 13 | 14 | let vertical = build_ctx.vertical 15 | || first.has_inline_comment 16 | || first.has_trivialities 17 | || second.has_inline_comment 18 | || second.has_trivialities 19 | || third.has_inline_comment 20 | || third.has_trivialities; 21 | 22 | // first 23 | if vertical { 24 | let kind = first.element.kind(); 25 | 26 | if matches!(kind, rnix::SyntaxKind::NODE_BIN_OP) { 27 | steps.push_back(crate::builder::Step::Format(first.element)); 28 | } else { 29 | steps.push_back(crate::builder::Step::FormatWider(first.element)); 30 | } 31 | } else { 32 | steps.push_back(crate::builder::Step::Format(first.element)); 33 | } 34 | 35 | if let Some(text) = first.inline_comment { 36 | steps.push_back(crate::builder::Step::Whitespace); 37 | steps.push_back(crate::builder::Step::Comment(text)); 38 | steps.push_back(crate::builder::Step::NewLine); 39 | steps.push_back(crate::builder::Step::Pad); 40 | } else if vertical { 41 | steps.push_back(crate::builder::Step::NewLine); 42 | steps.push_back(crate::builder::Step::Pad); 43 | } 44 | 45 | for trivia in first.trivialities { 46 | match trivia { 47 | crate::children2::Trivia::Comment(text) => { 48 | steps.push_back(crate::builder::Step::Comment(text)); 49 | steps.push_back(crate::builder::Step::NewLine); 50 | steps.push_back(crate::builder::Step::Pad); 51 | } 52 | crate::children2::Trivia::Newlines => {} 53 | } 54 | } 55 | 56 | // second 57 | if !vertical { 58 | steps.push_back(crate::builder::Step::Whitespace); 59 | } 60 | steps.push_back(crate::builder::Step::Format(second.element)); 61 | 62 | if let Some(text) = second.inline_comment { 63 | steps.push_back(crate::builder::Step::Whitespace); 64 | steps.push_back(crate::builder::Step::Comment(text)); 65 | steps.push_back(crate::builder::Step::NewLine); 66 | steps.push_back(crate::builder::Step::Pad); 67 | } 68 | 69 | if second.has_comments { 70 | steps.push_back(crate::builder::Step::NewLine); 71 | steps.push_back(crate::builder::Step::Pad); 72 | for trivia in second.trivialities { 73 | match trivia { 74 | crate::children2::Trivia::Comment(text) => { 75 | steps.push_back(crate::builder::Step::Comment(text)); 76 | steps.push_back(crate::builder::Step::NewLine); 77 | steps.push_back(crate::builder::Step::Pad); 78 | } 79 | crate::children2::Trivia::Newlines => {} 80 | } 81 | } 82 | } else if !second.has_inline_comment { 83 | steps.push_back(crate::builder::Step::Whitespace); 84 | } 85 | 86 | // third 87 | if vertical { 88 | steps.push_back(crate::builder::Step::FormatWider(third.element)); 89 | } else { 90 | steps.push_back(crate::builder::Step::Format(third.element)); 91 | } 92 | 93 | steps 94 | } 95 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/dynamic.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children2::new(build_ctx, node); 8 | 9 | let first = children.next().unwrap(); 10 | let second = children.next().unwrap(); 11 | let third = children.next().unwrap(); 12 | 13 | let vertical = build_ctx.vertical 14 | || first.has_inline_comment 15 | || first.has_trivialities 16 | || second.has_inline_comment 17 | || second.has_trivialities 18 | || third.has_inline_comment 19 | || third.has_trivialities; 20 | 21 | // first 22 | steps.push_back(crate::builder::Step::Format(first.element)); 23 | if vertical { 24 | steps.push_back(crate::builder::Step::Indent); 25 | } 26 | 27 | if let Some(text) = first.inline_comment { 28 | steps.push_back(crate::builder::Step::Whitespace); 29 | steps.push_back(crate::builder::Step::Comment(text)); 30 | steps.push_back(crate::builder::Step::NewLine); 31 | steps.push_back(crate::builder::Step::Pad); 32 | } else if vertical { 33 | steps.push_back(crate::builder::Step::NewLine); 34 | steps.push_back(crate::builder::Step::Pad); 35 | } 36 | 37 | for trivia in first.trivialities { 38 | match trivia { 39 | crate::children2::Trivia::Comment(text) => { 40 | steps.push_back(crate::builder::Step::Comment(text)); 41 | steps.push_back(crate::builder::Step::NewLine); 42 | steps.push_back(crate::builder::Step::Pad); 43 | } 44 | crate::children2::Trivia::Newlines => {} 45 | } 46 | } 47 | 48 | // second 49 | if vertical { 50 | steps.push_back(crate::builder::Step::FormatWider(second.element)); 51 | } else { 52 | steps.push_back(crate::builder::Step::Format(second.element)); 53 | } 54 | 55 | if let Some(text) = second.inline_comment { 56 | steps.push_back(crate::builder::Step::Whitespace); 57 | steps.push_back(crate::builder::Step::Comment(text)); 58 | steps.push_back(crate::builder::Step::NewLine); 59 | steps.push_back(crate::builder::Step::Pad); 60 | } 61 | 62 | for trivia in second.trivialities { 63 | match trivia { 64 | crate::children2::Trivia::Comment(text) => { 65 | steps.push_back(crate::builder::Step::NewLine); 66 | steps.push_back(crate::builder::Step::Pad); 67 | steps.push_back(crate::builder::Step::Comment(text)); 68 | } 69 | crate::children2::Trivia::Newlines => {} 70 | } 71 | } 72 | 73 | // third 74 | if vertical { 75 | steps.push_back(crate::builder::Step::Dedent); 76 | steps.push_back(crate::builder::Step::NewLine); 77 | steps.push_back(crate::builder::Step::Pad); 78 | } 79 | steps.push_back(crate::builder::Step::Format(third.element)); 80 | 81 | steps 82 | } 83 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/inherit.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let children: Vec = 8 | crate::children2::new(build_ctx, node).collect(); 9 | 10 | let vertical = build_ctx.vertical 11 | || children 12 | .iter() 13 | .any(|child| child.has_inline_comment || child.has_trivialities); 14 | 15 | let children_count = children.len() - 1; 16 | let mut children = children.into_iter(); 17 | 18 | // inherit 19 | let child = children.next().unwrap(); 20 | steps.push_back(crate::builder::Step::Format(child.element)); 21 | if vertical { 22 | steps.push_back(crate::builder::Step::Indent); 23 | } 24 | 25 | if let Some(text) = child.inline_comment { 26 | steps.push_back(crate::builder::Step::Whitespace); 27 | steps.push_back(crate::builder::Step::Comment(text)); 28 | steps.push_back(crate::builder::Step::NewLine); 29 | steps.push_back(crate::builder::Step::Pad); 30 | } else if vertical { 31 | steps.push_back(crate::builder::Step::NewLine); 32 | steps.push_back(crate::builder::Step::Pad); 33 | } 34 | 35 | for trivia in child.trivialities { 36 | match trivia { 37 | crate::children2::Trivia::Comment(text) => { 38 | steps.push_back(crate::builder::Step::Comment(text)); 39 | steps.push_back(crate::builder::Step::NewLine); 40 | steps.push_back(crate::builder::Step::Pad); 41 | } 42 | crate::children2::Trivia::Newlines => {} 43 | } 44 | } 45 | 46 | for (index, child) in children.enumerate() { 47 | let not_last_child = index + 1 < children_count; 48 | 49 | if vertical { 50 | steps.push_back(crate::builder::Step::FormatWider(child.element)); 51 | 52 | if let Some(text) = child.inline_comment { 53 | steps.push_back(crate::builder::Step::Whitespace); 54 | steps.push_back(crate::builder::Step::Comment(text)); 55 | steps.push_back(crate::builder::Step::NewLine); 56 | // Only add padding if there are no `trivialities` (that is, 57 | // there's no extra `Newlines` to be added) 58 | // or if the first one is a comment (that is, it'll need 59 | // to be indented to match the content). 60 | if matches!( 61 | child.trivialities.front(), 62 | None | Some(crate::children2::Trivia::Comment(_)) 63 | ) { 64 | steps.push_back(crate::builder::Step::Pad); 65 | } 66 | } else if (not_last_child && !child.has_trivialities) 67 | || matches!( 68 | child.trivialities.front(), 69 | Some(crate::children2::Trivia::Comment(_)) 70 | ) 71 | { 72 | steps.push_back(crate::builder::Step::NewLine); 73 | steps.push_back(crate::builder::Step::Pad); 74 | } 75 | 76 | let mut trivia_iter = child.trivialities.into_iter().peekable(); 77 | while let Some(trivia) = trivia_iter.next() { 78 | match trivia { 79 | crate::children2::Trivia::Comment(text) => { 80 | steps.push_back(crate::builder::Step::Comment(text)); 81 | // If the next `trivia` is a newline, don't add newlines 82 | // and padding at the 83 | // end of this iteration, as it will lead to a new blank 84 | // line in the output. 85 | if matches!( 86 | trivia_iter.peek(), 87 | Some(crate::children2::Trivia::Newlines) 88 | ) { 89 | continue; 90 | } 91 | } 92 | crate::children2::Trivia::Newlines => {} 93 | } 94 | if not_last_child { 95 | steps.push_back(crate::builder::Step::NewLine); 96 | steps.push_back(crate::builder::Step::Pad); 97 | } 98 | } 99 | } else { 100 | if not_last_child { 101 | steps.push_back(crate::builder::Step::Whitespace); 102 | } 103 | steps.push_back(crate::builder::Step::Format(child.element)); 104 | } 105 | } 106 | 107 | if vertical { 108 | steps.push_back(crate::builder::Step::Dedent); 109 | } 110 | 111 | steps 112 | } 113 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/key_value.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children::Children::new(build_ctx, node); 8 | 9 | let vertical = build_ctx.vertical 10 | || children.has_comments() 11 | || children.has_newlines(); 12 | 13 | // a 14 | let child = children.get_next().unwrap(); 15 | if vertical { 16 | steps.push_back(crate::builder::Step::FormatWider(child)); 17 | } else { 18 | steps.push_back(crate::builder::Step::Format(child)); 19 | } 20 | 21 | // /**/ 22 | let mut comment = false; 23 | children.drain_trivia(|element| match element { 24 | crate::children::Trivia::Comment(text) => { 25 | comment = true; 26 | steps.push_back(crate::builder::Step::NewLine); 27 | steps.push_back(crate::builder::Step::Pad); 28 | steps.push_back(crate::builder::Step::Comment(text)); 29 | } 30 | crate::children::Trivia::Whitespace(_) => {} 31 | }); 32 | if comment { 33 | steps.push_back(crate::builder::Step::NewLine); 34 | steps.push_back(crate::builder::Step::Pad); 35 | } else { 36 | steps.push_back(crate::builder::Step::Whitespace); 37 | } 38 | 39 | // peek: = 40 | let child_equal = children.get_next().unwrap(); 41 | 42 | // peek: /**/ 43 | let mut comments_before = std::collections::LinkedList::new(); 44 | let mut newlines = false; 45 | children.drain_trivia(|element| match element { 46 | crate::children::Trivia::Comment(text) => { 47 | comments_before.push_back(crate::builder::Step::Comment(text)) 48 | } 49 | crate::children::Trivia::Whitespace(text) => { 50 | if crate::utils::count_newlines(&text) > 0 { 51 | newlines = true; 52 | } 53 | } 54 | }); 55 | 56 | // peek: expr 57 | let child_expr = children.get_next().unwrap(); 58 | 59 | // Superfluous parens can be removed: `a = (x);` -> `a = x;` 60 | let child_expr = 61 | if matches!(child_expr.kind(), rnix::SyntaxKind::NODE_PAREN) { 62 | let mut children: Vec = 63 | child_expr.as_node().unwrap().children_with_tokens().collect(); 64 | 65 | if children.len() == 3 { 66 | children.swap_remove(1) 67 | } else { 68 | child_expr 69 | } 70 | } else { 71 | child_expr 72 | }; 73 | 74 | // peek: /**/ 75 | let mut comments_after = std::collections::LinkedList::new(); 76 | children.drain_trivia(|element| match element { 77 | crate::children::Trivia::Comment(text) => { 78 | comments_after.push_back(crate::builder::Step::Comment(text)) 79 | } 80 | crate::children::Trivia::Whitespace(_) => {} 81 | }); 82 | 83 | // = 84 | let mut dedent = false; 85 | steps.push_back(crate::builder::Step::Format(child_equal)); 86 | 87 | if vertical { 88 | if !comments_before.is_empty() || !comments_after.is_empty() { 89 | dedent = true; 90 | steps.push_back(crate::builder::Step::Indent); 91 | steps.push_back(crate::builder::Step::NewLine); 92 | steps.push_back(crate::builder::Step::Pad); 93 | } else if matches!( 94 | child_expr.kind(), 95 | rnix::SyntaxKind::NODE_ASSERT 96 | | rnix::SyntaxKind::NODE_ATTR_SET 97 | | rnix::SyntaxKind::NODE_PAREN 98 | | rnix::SyntaxKind::NODE_LAMBDA 99 | | rnix::SyntaxKind::NODE_LET_IN 100 | | rnix::SyntaxKind::NODE_LIST 101 | | rnix::SyntaxKind::NODE_STRING 102 | | rnix::SyntaxKind::NODE_WITH 103 | ) || (matches!( 104 | child_expr.kind(), 105 | rnix::SyntaxKind::NODE_APPLY 106 | ) 107 | && crate::utils::second_through_penultimate_line_are_indented( 108 | build_ctx, 109 | child_expr.clone(), 110 | false, 111 | )) 112 | { 113 | steps.push_back(crate::builder::Step::Whitespace); 114 | } else { 115 | dedent = true; 116 | steps.push_back(crate::builder::Step::Indent); 117 | steps.push_back(crate::builder::Step::NewLine); 118 | steps.push_back(crate::builder::Step::Pad); 119 | } 120 | } else { 121 | steps.push_back(crate::builder::Step::Whitespace); 122 | } 123 | 124 | // /**/ 125 | for comment in comments_before { 126 | steps.push_back(comment); 127 | steps.push_back(crate::builder::Step::NewLine); 128 | steps.push_back(crate::builder::Step::Pad); 129 | } 130 | 131 | // expr 132 | if vertical { 133 | steps.push_back(crate::builder::Step::FormatWider(child_expr)); 134 | if !comments_after.is_empty() { 135 | steps.push_back(crate::builder::Step::NewLine); 136 | steps.push_back(crate::builder::Step::Pad); 137 | } 138 | } else { 139 | steps.push_back(crate::builder::Step::Format(child_expr)); 140 | } 141 | 142 | // /**/ 143 | for comment in comments_after { 144 | steps.push_back(comment); 145 | steps.push_back(crate::builder::Step::NewLine); 146 | steps.push_back(crate::builder::Step::Pad); 147 | } 148 | 149 | // ; 150 | let child = children.get_next().unwrap(); 151 | steps.push_back(crate::builder::Step::Format(child)); 152 | if dedent { 153 | steps.push_back(crate::builder::Step::Dedent); 154 | } 155 | 156 | steps 157 | } 158 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/lambda.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children::Children::new(build_ctx, node); 8 | 9 | let vertical = children.has_comments() 10 | || children.has_newlines() 11 | || build_ctx.vertical; 12 | 13 | // a 14 | let child = children.get_next().unwrap(); 15 | if vertical { 16 | steps.push_back(crate::builder::Step::FormatWider(child)); 17 | } else { 18 | steps.push_back(crate::builder::Step::Format(child)); 19 | } 20 | 21 | if let rnix::SyntaxKind::TOKEN_COMMENT 22 | | rnix::SyntaxKind::TOKEN_WHITESPACE = 23 | children.peek_next().unwrap().kind() 24 | { 25 | steps.push_back(crate::builder::Step::NewLine); 26 | steps.push_back(crate::builder::Step::Pad); 27 | } 28 | 29 | // /**/ 30 | children.drain_trivia(|element| match element { 31 | crate::children::Trivia::Comment(text) => { 32 | steps.push_back(crate::builder::Step::Comment(text)); 33 | steps.push_back(crate::builder::Step::NewLine); 34 | steps.push_back(crate::builder::Step::Pad); 35 | } 36 | crate::children::Trivia::Whitespace(_) => {} 37 | }); 38 | 39 | // : 40 | let child = children.get_next().unwrap(); 41 | steps.push_back(crate::builder::Step::Format(child)); 42 | 43 | // /**/ 44 | let mut comment = false; 45 | children.drain_trivia(|element| match element { 46 | crate::children::Trivia::Comment(text) => { 47 | comment = true; 48 | steps.push_back(crate::builder::Step::NewLine); 49 | steps.push_back(crate::builder::Step::Pad); 50 | steps.push_back(crate::builder::Step::Comment(text)); 51 | } 52 | crate::children::Trivia::Whitespace(_) => {} 53 | }); 54 | 55 | // c 56 | let child = children.get_next().unwrap(); 57 | if vertical { 58 | if comment 59 | || !matches!( 60 | child.kind(), 61 | rnix::SyntaxKind::NODE_ATTR_SET 62 | | rnix::SyntaxKind::NODE_PAREN 63 | | rnix::SyntaxKind::NODE_LAMBDA 64 | | rnix::SyntaxKind::NODE_LET_IN 65 | | rnix::SyntaxKind::NODE_LIST 66 | | rnix::SyntaxKind::NODE_LITERAL 67 | | rnix::SyntaxKind::NODE_STRING 68 | ) 69 | { 70 | let should_indent = !matches!( 71 | child.kind(), 72 | rnix::SyntaxKind::NODE_ATTR_SET 73 | | rnix::SyntaxKind::NODE_PAREN 74 | | rnix::SyntaxKind::NODE_LAMBDA 75 | | rnix::SyntaxKind::NODE_LET_IN 76 | | rnix::SyntaxKind::NODE_LIST 77 | | rnix::SyntaxKind::NODE_STRING 78 | ) && build_ctx.indentation > 0; 79 | 80 | if should_indent { 81 | steps.push_back(crate::builder::Step::Indent); 82 | } 83 | 84 | steps.push_back(crate::builder::Step::NewLine); 85 | steps.push_back(crate::builder::Step::Pad); 86 | steps.push_back(crate::builder::Step::FormatWider(child)); 87 | if should_indent { 88 | steps.push_back(crate::builder::Step::Dedent); 89 | } 90 | } else { 91 | steps.push_back(crate::builder::Step::Whitespace); 92 | steps.push_back(crate::builder::Step::FormatWider(child)); 93 | } 94 | } else { 95 | steps.push_back(crate::builder::Step::Whitespace); 96 | steps.push_back(crate::builder::Step::Format(child)); 97 | } 98 | 99 | steps 100 | } 101 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/let_in.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children::Children::new(build_ctx, node); 8 | 9 | let items_count = node 10 | .children() 11 | .filter(|element| { 12 | matches!( 13 | element.kind(), 14 | rnix::SyntaxKind::NODE_ATTRPATH_VALUE 15 | | rnix::SyntaxKind::NODE_INHERIT 16 | | rnix::SyntaxKind::NODE_INHERIT_FROM 17 | ) 18 | }) 19 | .count(); 20 | 21 | let vertical = items_count > 1 22 | || children.has_comments() 23 | || children.has_newlines() 24 | || build_ctx.vertical; 25 | 26 | // let 27 | let child = children.get_next().unwrap(); 28 | steps.push_back(crate::builder::Step::Format(child)); 29 | if vertical { 30 | steps.push_back(crate::builder::Step::Indent); 31 | } 32 | 33 | let mut item_index: usize = 0; 34 | let mut inline_next_comment = false; 35 | 36 | loop { 37 | // /**/ 38 | children.drain_trivia(|element| match element { 39 | crate::children::Trivia::Comment(text) => { 40 | if inline_next_comment && text.starts_with('#') { 41 | steps.push_back(crate::builder::Step::Whitespace); 42 | } else { 43 | steps.push_back(crate::builder::Step::NewLine); 44 | steps.push_back(crate::builder::Step::Pad); 45 | } 46 | steps.push_back(crate::builder::Step::Comment(text)); 47 | inline_next_comment = false; 48 | } 49 | crate::children::Trivia::Whitespace(text) => { 50 | let newlines = crate::utils::count_newlines(&text); 51 | 52 | if newlines > 1 && item_index > 0 && item_index < items_count { 53 | steps.push_back(crate::builder::Step::NewLine); 54 | } 55 | 56 | inline_next_comment = newlines == 0; 57 | } 58 | }); 59 | 60 | if let Some(child) = children.peek_next() { 61 | if let rnix::SyntaxKind::TOKEN_IN = child.kind() { 62 | break; 63 | } 64 | 65 | // expr 66 | item_index += 1; 67 | if vertical { 68 | steps.push_back(crate::builder::Step::NewLine); 69 | steps.push_back(crate::builder::Step::Pad); 70 | steps.push_back(crate::builder::Step::FormatWider(child)); 71 | } else { 72 | steps.push_back(crate::builder::Step::Whitespace); 73 | steps.push_back(crate::builder::Step::Format(child)); 74 | } 75 | 76 | children.move_next(); 77 | inline_next_comment = true; 78 | } 79 | } 80 | 81 | if vertical { 82 | steps.push_back(crate::builder::Step::Dedent); 83 | steps.push_back(crate::builder::Step::NewLine); 84 | steps.push_back(crate::builder::Step::Pad); 85 | } else { 86 | steps.push_back(crate::builder::Step::Whitespace); 87 | } 88 | 89 | // in 90 | let child_in = children.get_next().unwrap(); 91 | 92 | // /**/ 93 | let mut child_comments = std::collections::LinkedList::new(); 94 | children.drain_trivia(|element| match element { 95 | crate::children::Trivia::Comment(text) => { 96 | child_comments.push_back(crate::builder::Step::Comment(text)) 97 | } 98 | crate::children::Trivia::Whitespace(_) => {} 99 | }); 100 | 101 | // expr 102 | let child_expr = children.get_next().unwrap(); 103 | 104 | // in 105 | let mut dedent = false; 106 | steps.push_back(crate::builder::Step::Format(child_in)); 107 | if vertical { 108 | if child_comments.is_empty() 109 | && matches!( 110 | child_expr.kind(), 111 | rnix::SyntaxKind::NODE_ATTR_SET 112 | | rnix::SyntaxKind::NODE_LET_IN 113 | | rnix::SyntaxKind::NODE_LIST 114 | | rnix::SyntaxKind::NODE_PAREN 115 | | rnix::SyntaxKind::NODE_STRING 116 | ) 117 | { 118 | steps.push_back(crate::builder::Step::Whitespace); 119 | } else { 120 | dedent = true; 121 | steps.push_back(crate::builder::Step::Indent); 122 | steps.push_back(crate::builder::Step::NewLine); 123 | steps.push_back(crate::builder::Step::Pad); 124 | } 125 | } 126 | 127 | // /**/ 128 | for comment in child_comments { 129 | steps.push_back(comment); 130 | steps.push_back(crate::builder::Step::NewLine); 131 | steps.push_back(crate::builder::Step::Pad); 132 | } 133 | 134 | // expr 135 | if vertical { 136 | steps.push_back(crate::builder::Step::FormatWider(child_expr)); 137 | if dedent { 138 | steps.push_back(crate::builder::Step::Dedent); 139 | } 140 | } else { 141 | steps.push_back(crate::builder::Step::Whitespace); 142 | steps.push_back(crate::builder::Step::Format(child_expr)); 143 | } 144 | 145 | steps 146 | } 147 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/list.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children::Children::new(build_ctx, node); 8 | 9 | let items_count = node 10 | .children_with_tokens() 11 | .filter(|element| { 12 | !matches!(element.kind(), rnix::SyntaxKind::TOKEN_WHITESPACE) 13 | }) 14 | .count() 15 | - 2; 16 | 17 | let vertical = children.has_comments() 18 | || children.has_newlines() 19 | || build_ctx.vertical; 20 | 21 | // [ 22 | let child = children.get_next().unwrap(); 23 | steps.push_back(crate::builder::Step::Format(child)); 24 | if vertical { 25 | steps.push_back(crate::builder::Step::Indent); 26 | } 27 | 28 | let mut item_index: usize = 0; 29 | let mut inline_next_comment = false; 30 | 31 | loop { 32 | // /**/ 33 | children.drain_trivia(|element| { 34 | match element { 35 | crate::children::Trivia::Comment(text) => { 36 | if inline_next_comment && text.starts_with('#') { 37 | steps.push_back(crate::builder::Step::Whitespace); 38 | } else { 39 | steps.push_back(crate::builder::Step::NewLine); 40 | steps.push_back(crate::builder::Step::Pad); 41 | } 42 | 43 | steps.push_back(crate::builder::Step::Comment(text)); 44 | item_index += 1; 45 | inline_next_comment = false; 46 | } 47 | crate::children::Trivia::Whitespace(text) => { 48 | let newlines = crate::utils::count_newlines(&text); 49 | 50 | if newlines > 1 51 | && item_index > 0 52 | && item_index < items_count 53 | { 54 | steps.push_back(crate::builder::Step::NewLine); 55 | } 56 | 57 | inline_next_comment = newlines == 0; 58 | } 59 | }; 60 | }); 61 | 62 | if let Some(child) = children.peek_next() { 63 | let child_kind = child.kind(); 64 | 65 | if let rnix::SyntaxKind::TOKEN_R_BRACK = child_kind { 66 | break; 67 | } 68 | 69 | // item 70 | item_index += 1; 71 | if vertical { 72 | steps.push_back(crate::builder::Step::NewLine); 73 | steps.push_back(crate::builder::Step::Pad); 74 | steps.push_back(crate::builder::Step::FormatWider(child)); 75 | } else { 76 | if item_index > 1 { 77 | steps.push_back(crate::builder::Step::Whitespace); 78 | } 79 | steps.push_back(crate::builder::Step::Format(child)); 80 | } 81 | 82 | children.move_next(); 83 | inline_next_comment = true; 84 | } 85 | } 86 | 87 | // ] 88 | let child = children.get_next().unwrap(); 89 | if vertical { 90 | steps.push_back(crate::builder::Step::Dedent); 91 | steps.push_back(crate::builder::Step::NewLine); 92 | steps.push_back(crate::builder::Step::Pad); 93 | } 94 | steps.push_back(crate::builder::Step::Format(child)); 95 | 96 | steps 97 | } 98 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod apply; 2 | pub(crate) mod attr_set; 3 | pub(crate) mod bin_op; 4 | pub(crate) mod dynamic; 5 | pub(crate) mod if_else; 6 | pub(crate) mod inherit; 7 | pub(crate) mod key_value; 8 | pub(crate) mod lambda; 9 | pub(crate) mod let_in; 10 | pub(crate) mod list; 11 | pub(crate) mod paren; 12 | pub(crate) mod pat_bind; 13 | pub(crate) mod pat_entry; 14 | pub(crate) mod pattern; 15 | pub(crate) mod root; 16 | pub(crate) mod scoped; 17 | pub(crate) mod string; 18 | 19 | pub(crate) fn default( 20 | _: &crate::builder::BuildCtx, 21 | node: &rnix::SyntaxNode, 22 | ) -> std::collections::LinkedList { 23 | node.children_with_tokens().map(crate::builder::Step::Format).collect() 24 | } 25 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/paren.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children2::new(build_ctx, node); 8 | 9 | let opener = children.next().unwrap(); 10 | let expression = children.next().unwrap(); 11 | let closer = children.next().unwrap(); 12 | 13 | let loose = opener.has_inline_comment 14 | || opener.has_comments 15 | || expression.has_inline_comment 16 | || expression.has_comments 17 | || closer.has_inline_comment 18 | || closer.has_comments 19 | || matches!(expression.element.kind(), rnix::SyntaxKind::NODE_IF_ELSE) 20 | || ((opener.has_trivialities 21 | || expression.has_trivialities 22 | || closer.has_trivialities) 23 | && !matches!( 24 | expression.element.kind(), 25 | rnix::SyntaxKind::NODE_ATTR_SET 26 | | rnix::SyntaxKind::NODE_IDENT 27 | | rnix::SyntaxKind::NODE_LITERAL 28 | | rnix::SyntaxKind::NODE_LIST 29 | | rnix::SyntaxKind::NODE_STRING 30 | | rnix::SyntaxKind::NODE_UNARY_OP 31 | )); 32 | 33 | let should_indent = loose 34 | || matches!( 35 | expression.element.kind(), 36 | rnix::SyntaxKind::NODE_APPLY 37 | | rnix::SyntaxKind::NODE_ASSERT 38 | | rnix::SyntaxKind::NODE_BIN_OP 39 | | rnix::SyntaxKind::NODE_LAMBDA 40 | | rnix::SyntaxKind::NODE_SELECT 41 | | rnix::SyntaxKind::NODE_WITH 42 | ) && !crate::utils::second_through_penultimate_line_are_indented( 43 | build_ctx, 44 | expression.element.clone(), 45 | matches!(expression.element.kind(), rnix::SyntaxKind::NODE_LAMBDA), 46 | ); 47 | 48 | // opener 49 | steps.push_back(crate::builder::Step::Format(opener.element)); 50 | if should_indent { 51 | steps.push_back(crate::builder::Step::Indent); 52 | } 53 | 54 | if let Some(text) = opener.inline_comment { 55 | steps.push_back(crate::builder::Step::Whitespace); 56 | steps.push_back(crate::builder::Step::Comment(text)); 57 | steps.push_back(crate::builder::Step::NewLine); 58 | steps.push_back(crate::builder::Step::Pad); 59 | } else if loose { 60 | steps.push_back(crate::builder::Step::NewLine); 61 | steps.push_back(crate::builder::Step::Pad); 62 | } 63 | 64 | for trivia in opener.trivialities { 65 | match trivia { 66 | crate::children2::Trivia::Comment(text) => { 67 | steps.push_back(crate::builder::Step::Comment(text)); 68 | steps.push_back(crate::builder::Step::NewLine); 69 | steps.push_back(crate::builder::Step::Pad); 70 | } 71 | crate::children2::Trivia::Newlines => {} 72 | } 73 | } 74 | 75 | // expression 76 | if loose { 77 | steps.push_back(crate::builder::Step::FormatWider(expression.element)); 78 | } else { 79 | steps.push_back(crate::builder::Step::Format(expression.element)); 80 | } 81 | 82 | if let Some(text) = expression.inline_comment { 83 | steps.push_back(crate::builder::Step::Whitespace); 84 | steps.push_back(crate::builder::Step::Comment(text)); 85 | } 86 | 87 | for trivia in expression.trivialities { 88 | match trivia { 89 | crate::children2::Trivia::Comment(text) => { 90 | steps.push_back(crate::builder::Step::NewLine); 91 | steps.push_back(crate::builder::Step::Pad); 92 | steps.push_back(crate::builder::Step::Comment(text)); 93 | } 94 | crate::children2::Trivia::Newlines => {} 95 | } 96 | } 97 | 98 | // closer 99 | if should_indent { 100 | steps.push_back(crate::builder::Step::Dedent); 101 | } 102 | 103 | if loose { 104 | steps.push_back(crate::builder::Step::NewLine); 105 | steps.push_back(crate::builder::Step::Pad); 106 | } 107 | steps.push_back(crate::builder::Step::Format(closer.element)); 108 | 109 | steps 110 | } 111 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/pat_bind.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children::Children::new(build_ctx, node); 8 | 9 | let vertical = children.has_comments() 10 | || children.has_newlines() 11 | || build_ctx.vertical; 12 | 13 | let child = children.get_next().unwrap(); 14 | if vertical { 15 | steps.push_back(crate::builder::Step::FormatWider(child)); 16 | } else { 17 | steps.push_back(crate::builder::Step::Format(child)); 18 | } 19 | 20 | // /**/ 21 | let mut comment = false; 22 | children.drain_trivia(|element| match element { 23 | crate::children::Trivia::Comment(text) => { 24 | steps.push_back(crate::builder::Step::NewLine); 25 | steps.push_back(crate::builder::Step::Pad); 26 | steps.push_back(crate::builder::Step::Comment(text)); 27 | comment = true; 28 | } 29 | crate::children::Trivia::Whitespace(_) => {} 30 | }); 31 | 32 | if comment { 33 | steps.push_back(crate::builder::Step::NewLine); 34 | steps.push_back(crate::builder::Step::Pad); 35 | } else { 36 | steps.push_back(crate::builder::Step::Whitespace); 37 | } 38 | 39 | let child = children.get_next().unwrap(); 40 | if vertical { 41 | steps.push_back(crate::builder::Step::FormatWider(child)); 42 | } else { 43 | steps.push_back(crate::builder::Step::Format(child)); 44 | } 45 | children.move_prev(); 46 | 47 | steps 48 | } 49 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/pat_entry.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children::Children::new(build_ctx, node); 8 | 9 | let vertical = children.has_comments() 10 | || children.has_newlines() 11 | || build_ctx.vertical; 12 | 13 | // expr 14 | let child = children.get_next().unwrap(); 15 | if vertical { 16 | steps.push_back(crate::builder::Step::FormatWider(child)); 17 | } else { 18 | steps.push_back(crate::builder::Step::Format(child)); 19 | } 20 | 21 | if children.has_next() { 22 | // /**/ 23 | let mut comment = false; 24 | children.drain_trivia(|element| match element { 25 | crate::children::Trivia::Comment(text) => { 26 | steps.push_back(crate::builder::Step::NewLine); 27 | steps.push_back(crate::builder::Step::Pad); 28 | steps.push_back(crate::builder::Step::Comment(text)); 29 | comment = true; 30 | } 31 | crate::children::Trivia::Whitespace(_) => {} 32 | }); 33 | 34 | if comment { 35 | steps.push_back(crate::builder::Step::NewLine); 36 | steps.push_back(crate::builder::Step::Pad); 37 | } else { 38 | steps.push_back(crate::builder::Step::Whitespace); 39 | } 40 | 41 | // operator 42 | let child = children.get_next().unwrap(); 43 | steps.push_back(crate::builder::Step::Format(child)); 44 | 45 | // /**/ 46 | let mut comment = false; 47 | children.drain_trivia(|element| match element { 48 | crate::children::Trivia::Comment(text) => { 49 | steps.push_back(crate::builder::Step::NewLine); 50 | steps.push_back(crate::builder::Step::Pad); 51 | steps.push_back(crate::builder::Step::Comment(text)); 52 | comment = true; 53 | } 54 | crate::children::Trivia::Whitespace(_) => {} 55 | }); 56 | 57 | // expr 58 | let child = children.get_next().unwrap(); 59 | let mut dedent = false; 60 | 61 | if comment { 62 | steps.push_back(crate::builder::Step::NewLine); 63 | steps.push_back(crate::builder::Step::Pad); 64 | } else if matches!( 65 | child.kind(), 66 | rnix::SyntaxKind::NODE_ATTR_SET 67 | | rnix::SyntaxKind::NODE_IDENT 68 | | rnix::SyntaxKind::NODE_PAREN 69 | | rnix::SyntaxKind::NODE_LAMBDA 70 | | rnix::SyntaxKind::NODE_LET_IN 71 | | rnix::SyntaxKind::NODE_LIST 72 | | rnix::SyntaxKind::NODE_LITERAL 73 | | rnix::SyntaxKind::NODE_STRING, 74 | ) || crate::builder::fits_in_single_line( 75 | build_ctx, 76 | child.clone(), 77 | ) { 78 | steps.push_back(crate::builder::Step::Whitespace); 79 | } else { 80 | dedent = true; 81 | steps.push_back(crate::builder::Step::Indent); 82 | steps.push_back(crate::builder::Step::NewLine); 83 | steps.push_back(crate::builder::Step::Pad); 84 | } 85 | 86 | if vertical { 87 | steps.push_back(crate::builder::Step::FormatWider(child)); 88 | } else { 89 | steps.push_back(crate::builder::Step::Format(child)); 90 | } 91 | if dedent { 92 | steps.push_back(crate::builder::Step::Dedent); 93 | } 94 | } 95 | 96 | steps 97 | } 98 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/root.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children::Children::new(build_ctx, node); 8 | 9 | let vertical = children.has_comments() 10 | || children.has_newlines() 11 | || build_ctx.vertical; 12 | 13 | while children.has_next() { 14 | children.drain_trivia(|element| match element { 15 | crate::children::Trivia::Comment(text) => { 16 | steps.push_back(crate::builder::Step::Comment(text)); 17 | steps.push_back(crate::builder::Step::NewLine); 18 | steps.push_back(crate::builder::Step::Pad); 19 | } 20 | crate::children::Trivia::Whitespace(_) => {} 21 | }); 22 | 23 | if let Some(child) = children.get_next() { 24 | if vertical { 25 | steps.push_back(crate::builder::Step::FormatWider(child)); 26 | steps.push_back(crate::builder::Step::NewLine); 27 | } else { 28 | steps.push_back(crate::builder::Step::Format(child)); 29 | } 30 | } 31 | } 32 | 33 | // Trailing newline 34 | if let Some(last_step) = steps.back() { 35 | if *last_step != crate::builder::Step::NewLine { 36 | steps.push_back(crate::builder::Step::NewLine); 37 | } 38 | } 39 | 40 | steps 41 | } 42 | -------------------------------------------------------------------------------- /src/alejandra/src/rules/scoped.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn rule( 2 | build_ctx: &crate::builder::BuildCtx, 3 | node: &rnix::SyntaxNode, 4 | ) -> std::collections::LinkedList { 5 | let mut steps = std::collections::LinkedList::new(); 6 | 7 | let mut children = crate::children2::new(build_ctx, node); 8 | 9 | let first = children.next().unwrap(); 10 | let second = children.next().unwrap(); 11 | let third = children.next().unwrap(); 12 | let fourth = children.next().unwrap(); 13 | 14 | let vertical = build_ctx.vertical 15 | || first.has_inline_comment 16 | || first.has_trivialities 17 | || second.has_inline_comment 18 | || second.has_trivialities 19 | || third.has_inline_comment 20 | || third.has_trivialities 21 | || fourth.has_inline_comment 22 | || fourth.has_trivialities; 23 | 24 | // first 25 | steps.push_back(crate::builder::Step::Format(first.element)); 26 | 27 | if let Some(text) = first.inline_comment { 28 | steps.push_back(crate::builder::Step::Whitespace); 29 | steps.push_back(crate::builder::Step::Comment(text)); 30 | steps.push_back(crate::builder::Step::NewLine); 31 | steps.push_back(crate::builder::Step::Pad); 32 | } else if first.has_comments { 33 | steps.push_back(crate::builder::Step::NewLine); 34 | steps.push_back(crate::builder::Step::Pad); 35 | } else { 36 | steps.push_back(crate::builder::Step::Whitespace); 37 | } 38 | 39 | for trivia in first.trivialities { 40 | match trivia { 41 | crate::children2::Trivia::Comment(text) => { 42 | steps.push_back(crate::builder::Step::Comment(text)); 43 | steps.push_back(crate::builder::Step::NewLine); 44 | steps.push_back(crate::builder::Step::Pad); 45 | } 46 | crate::children2::Trivia::Newlines => {} 47 | } 48 | } 49 | 50 | // second 51 | if vertical { 52 | steps.push_back(crate::builder::Step::FormatWider(second.element)); 53 | } else { 54 | steps.push_back(crate::builder::Step::Format(second.element)); 55 | } 56 | 57 | // third 58 | steps.push_back(crate::builder::Step::Format(third.element)); 59 | 60 | if let Some(text) = third.inline_comment { 61 | steps.push_back(crate::builder::Step::Whitespace); 62 | steps.push_back(crate::builder::Step::Comment(text)); 63 | steps.push_back(crate::builder::Step::NewLine); 64 | steps.push_back(crate::builder::Step::Pad); 65 | } 66 | 67 | for trivia in third.trivialities { 68 | match trivia { 69 | crate::children2::Trivia::Comment(text) => { 70 | steps.push_back(crate::builder::Step::NewLine); 71 | steps.push_back(crate::builder::Step::Pad); 72 | steps.push_back(crate::builder::Step::Comment(text)); 73 | } 74 | crate::children2::Trivia::Newlines => {} 75 | } 76 | } 77 | 78 | // fourth 79 | if vertical { 80 | if matches!( 81 | fourth.element.kind(), 82 | rnix::SyntaxKind::NODE_ASSERT | rnix::SyntaxKind::NODE_WITH 83 | ) { 84 | steps.push_back(crate::builder::Step::NewLine); 85 | steps.push_back(crate::builder::Step::Pad); 86 | steps.push_back(crate::builder::Step::FormatWider(fourth.element)); 87 | } else if third.has_inline_comment 88 | || third.has_comments 89 | || !matches!( 90 | fourth.element.kind(), 91 | rnix::SyntaxKind::NODE_ATTR_SET 92 | | rnix::SyntaxKind::NODE_IDENT 93 | | rnix::SyntaxKind::NODE_PAREN 94 | | rnix::SyntaxKind::NODE_LET_IN 95 | | rnix::SyntaxKind::NODE_LIST 96 | | rnix::SyntaxKind::NODE_LITERAL 97 | | rnix::SyntaxKind::NODE_STRING 98 | ) 99 | { 100 | steps.push_back(crate::builder::Step::Indent); 101 | steps.push_back(crate::builder::Step::NewLine); 102 | steps.push_back(crate::builder::Step::Pad); 103 | steps.push_back(crate::builder::Step::FormatWider(fourth.element)); 104 | steps.push_back(crate::builder::Step::Dedent); 105 | } else { 106 | steps.push_back(crate::builder::Step::Whitespace); 107 | steps.push_back(crate::builder::Step::FormatWider(fourth.element)); 108 | } 109 | } else { 110 | steps.push_back(crate::builder::Step::Whitespace); 111 | steps.push_back(crate::builder::Step::Format(fourth.element)); 112 | } 113 | 114 | steps 115 | } 116 | -------------------------------------------------------------------------------- /src/alejandra/src/utils.rs: -------------------------------------------------------------------------------- 1 | pub(crate) fn has_newlines(string: &str) -> bool { 2 | string.chars().any(|c| c == '\n') 3 | } 4 | 5 | pub(crate) fn count_newlines(string: &str) -> usize { 6 | string.chars().filter(|c| *c == '\n').count() 7 | } 8 | 9 | pub(crate) fn second_through_penultimate_line_are_indented( 10 | build_ctx: &crate::builder::BuildCtx, 11 | element: rnix::SyntaxElement, 12 | if_leq_than_two_lines: bool, 13 | ) -> bool { 14 | let mut build_ctx = 15 | crate::builder::BuildCtx { force_wide: false, ..build_ctx.clone() }; 16 | 17 | let formatted = 18 | crate::builder::build(&mut build_ctx, element).unwrap().to_string(); 19 | 20 | let formatted_lines: Vec<&str> = formatted.split('\n').collect(); 21 | 22 | if formatted_lines.len() <= 2 { 23 | return if_leq_than_two_lines; 24 | } 25 | 26 | let whitespace = format!("{0:<1$} ", "", 2 * build_ctx.indentation); 27 | let lambda = format!("{0:<1$}}}:", "", 2 * build_ctx.indentation); 28 | let in_ = format!("{0:<1$}in", "", 2 * build_ctx.indentation); 29 | 30 | formatted_lines.iter().skip(1).rev().skip(1).all(|line| { 31 | line.is_empty() 32 | || line.starts_with(&lambda) 33 | || line.starts_with(&in_) 34 | || line.starts_with(&whitespace) 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /src/alejandra/src/version.rs: -------------------------------------------------------------------------------- 1 | /// The version of Alejandra. 2 | pub const VERSION: &str = "4.0.0"; 3 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/apply/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (a 3 | b) 4 | ( 5 | (a b) 6 | (a b) 7 | (a /*b*/ c) 8 | (/*a*/ b /*c*/ d /*e*/) 9 | ) 10 | '' 11 | otherModules=${ 12 | pkgs.writeText "other-modules.json" 13 | (l.toJSON 14 | (l.mapAttrs 15 | (pname: subOutputs: 16 | let 17 | pkg = subOutputs.packages."${pname}".overrideAttrs (old: { 18 | buildScript = "true"; 19 | installMethod = "copy"; 20 | }); 21 | in 22 | "${pkg}/lib/node_modules/${pname}/node_modules") 23 | outputs.subPackages)) 24 | } 25 | '' 26 | { 27 | name1 = 28 | function 29 | arg 30 | {asdf = 1;}; 31 | 32 | name2 = 33 | function 34 | arg 35 | {asdf = 1;} 36 | argument; 37 | 38 | name3 = 39 | function 40 | arg 41 | {asdf = 1;} 42 | {qwer = 12345;} 43 | argument; 44 | } 45 | { 46 | name1 = function arg { 47 | asdf = 1; 48 | }; 49 | 50 | name2 = function arg { 51 | asdf = 1; 52 | } 53 | argument; 54 | 55 | name3 = function arg { 56 | asdf = 1; 57 | } { 58 | qwer = 12345; 59 | } 60 | argument; 61 | } 62 | { 63 | name4 = 64 | function 65 | arg 66 | {asdf = 1;} 67 | { 68 | qwer = 12345; 69 | qwer2 = 54321; 70 | } 71 | argument; 72 | } 73 | { 74 | option1 = function arg {asdf = 1;} { 75 | qwer = 12345; 76 | qwer2 = 54321; 77 | } 78 | lastArg; 79 | 80 | option2 = function arg {asdf = 1;} { 81 | qwer = 12345; 82 | qwer2 = 54321; 83 | } 84 | lastArg; 85 | 86 | option3 = function arg {asdf = 1;} 87 | { 88 | qwer = 12345; 89 | qwer2 = 54321; 90 | } 91 | lastArg; 92 | } 93 | ] 94 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/apply/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (a 3 | b) 4 | ( 5 | (a b) 6 | (a b) 7 | (a 8 | /* 9 | b 10 | */ 11 | c) 12 | ( 13 | /* 14 | a 15 | */ 16 | b 17 | /* 18 | c 19 | */ 20 | d 21 | /* 22 | e 23 | */ 24 | ) 25 | ) 26 | '' 27 | otherModules=${ 28 | pkgs.writeText "other-modules.json" 29 | (l.toJSON 30 | (l.mapAttrs 31 | (pname: subOutputs: let 32 | pkg = subOutputs.packages."${pname}".overrideAttrs (old: { 33 | buildScript = "true"; 34 | installMethod = "copy"; 35 | }); 36 | in "${pkg}/lib/node_modules/${pname}/node_modules") 37 | outputs.subPackages)) 38 | } 39 | '' 40 | { 41 | name1 = 42 | function 43 | arg 44 | {asdf = 1;}; 45 | 46 | name2 = 47 | function 48 | arg 49 | {asdf = 1;} 50 | argument; 51 | 52 | name3 = 53 | function 54 | arg 55 | {asdf = 1;} 56 | {qwer = 12345;} 57 | argument; 58 | } 59 | { 60 | name1 = function arg { 61 | asdf = 1; 62 | }; 63 | 64 | name2 = 65 | function arg { 66 | asdf = 1; 67 | } 68 | argument; 69 | 70 | name3 = 71 | function arg { 72 | asdf = 1; 73 | } { 74 | qwer = 12345; 75 | } 76 | argument; 77 | } 78 | { 79 | name4 = 80 | function 81 | arg 82 | {asdf = 1;} 83 | { 84 | qwer = 12345; 85 | qwer2 = 54321; 86 | } 87 | argument; 88 | } 89 | { 90 | option1 = 91 | function arg {asdf = 1;} { 92 | qwer = 12345; 93 | qwer2 = 54321; 94 | } 95 | lastArg; 96 | 97 | option2 = 98 | function arg {asdf = 1;} { 99 | qwer = 12345; 100 | qwer2 = 54321; 101 | } 102 | lastArg; 103 | 104 | option3 = 105 | function arg {asdf = 1;} 106 | { 107 | qwer = 12345; 108 | qwer2 = 54321; 109 | } 110 | lastArg; 111 | } 112 | ] 113 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/assert/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (assert b ; e) 3 | (assert b ; /*d*/ e) 4 | (assert b /*c*/; e) 5 | (assert b /*c*/; /*d*/ e) 6 | (assert /*a*/ b ; e) 7 | (assert /*a*/ b ; /*d*/ e) 8 | (assert /*a*/ b /*c*/; e) 9 | (assert /*a*/ b /*c*/; /*d*/ e) 10 | ( assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ) 11 | ( assert b; 12 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ) 13 | ] 14 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/assert/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (assert b; e) 3 | (assert b; 4 | /* 5 | d 6 | */ 7 | e) 8 | (assert b; e) 9 | (assert b; 10 | /* 11 | d 12 | */ 13 | e) 14 | (assert 15 | /* 16 | a 17 | */ 18 | b; e) 19 | (assert 20 | /* 21 | a 22 | */ 23 | b; 24 | /* 25 | d 26 | */ 27 | e) 28 | (assert 29 | /* 30 | a 31 | */ 32 | b; e) 33 | (assert 34 | /* 35 | a 36 | */ 37 | b; 38 | /* 39 | d 40 | */ 41 | e) 42 | (assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) 43 | (assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) 44 | ] 45 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/attr_set/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | {} 3 | {/*a*/} 4 | {a=1;} 5 | {a=1; 6 | } 7 | 8 | { b=1; } 9 | { b=1; /*c*/ } 10 | { /*a*/ b=1; } 11 | { /*a*/ b=1; /*c*/ } 12 | 13 | rec { c=1; } 14 | rec { c=1; /*d*/ } 15 | rec { /*b*/ c=1; } 16 | rec { /*b*/ c=1; /*d*/ } 17 | rec /*a*/ { c=1; } 18 | rec /*a*/ { c=1; /*d*/ } 19 | rec /*a*/ { /*b*/ c=1; } 20 | rec /*a*/ { /*b*/ c=1; /*d*/ } 21 | 22 | { 23 | a=rec { 24 | a={ 25 | a=rec { 26 | a={ 27 | a=rec {a={a=rec {a={a=rec {a={};};};};};};};};};};} 28 | 29 | rec { 30 | 31 | c=1; 32 | 33 | 34 | e=1; 35 | 36 | 37 | } 38 | 39 | rec 40 | /*a*/ 41 | { 42 | 43 | 44 | /*b*/ 45 | 46 | 47 | c=1; 48 | 49 | 50 | /*d*/ 51 | 52 | 53 | e=1; 54 | 55 | 56 | /*f*/ 57 | 58 | 59 | } 60 | ] 61 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/attr_set/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | {} 3 | { 4 | /* 5 | a 6 | */ 7 | } 8 | {a = 1;} 9 | { 10 | a = 1; 11 | } 12 | 13 | {b = 1;} 14 | { 15 | b = 1; 16 | /* 17 | c 18 | */ 19 | } 20 | { 21 | /* 22 | a 23 | */ 24 | b = 1; 25 | } 26 | { 27 | /* 28 | a 29 | */ 30 | b = 1; 31 | /* 32 | c 33 | */ 34 | } 35 | 36 | rec {c = 1;} 37 | rec { 38 | c = 1; 39 | /* 40 | d 41 | */ 42 | } 43 | rec { 44 | /* 45 | b 46 | */ 47 | c = 1; 48 | } 49 | rec { 50 | /* 51 | b 52 | */ 53 | c = 1; 54 | /* 55 | d 56 | */ 57 | } 58 | rec 59 | /* 60 | a 61 | */ 62 | { 63 | c = 1; 64 | } 65 | rec 66 | /* 67 | a 68 | */ 69 | { 70 | c = 1; 71 | /* 72 | d 73 | */ 74 | } 75 | rec 76 | /* 77 | a 78 | */ 79 | { 80 | /* 81 | b 82 | */ 83 | c = 1; 84 | } 85 | rec 86 | /* 87 | a 88 | */ 89 | { 90 | /* 91 | b 92 | */ 93 | c = 1; 94 | /* 95 | d 96 | */ 97 | } 98 | 99 | { 100 | a = rec { 101 | a = { 102 | a = rec { 103 | a = { 104 | a = rec {a = {a = rec {a = {a = rec {a = {};};};};};}; 105 | }; 106 | }; 107 | }; 108 | }; 109 | } 110 | 111 | rec { 112 | c = 1; 113 | 114 | e = 1; 115 | } 116 | 117 | rec 118 | /* 119 | a 120 | */ 121 | { 122 | /* 123 | b 124 | */ 125 | 126 | c = 1; 127 | 128 | /* 129 | d 130 | */ 131 | 132 | e = 1; 133 | 134 | /* 135 | f 136 | */ 137 | } 138 | ] 139 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/bin_op/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (1 + 1) 3 | (1 +/**/1) 4 | (1/**/+ 1) 5 | (1/**/+/**/1) 6 | (1/**/+/**/(1/**/+/**/(1/**/+/**/1))) 7 | ( 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 ) 8 | ( 1 9 | + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1) 10 | ] 11 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/bin_op/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (1 + 1) 3 | (1 4 | + 5 | /**/ 6 | 1) 7 | (1 8 | /**/ 9 | + 1) 10 | (1 11 | /**/ 12 | + 13 | /**/ 14 | 1) 15 | (1 16 | /**/ 17 | + 18 | /**/ 19 | (1 20 | /**/ 21 | + 22 | /**/ 23 | (1 24 | /**/ 25 | + 26 | /**/ 27 | 1))) 28 | (1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1) 29 | (1 30 | + 1 31 | + 1 32 | + 1 33 | + 1 34 | + 1 35 | + 1 36 | + 1 37 | + 1 38 | + 1 39 | + 1 40 | + 1 41 | + 1 42 | + 1 43 | + 1 44 | + 1 45 | + 1 46 | + 1 47 | + 1 48 | + 1) 49 | ] 50 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/comment/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | /* 3 | */ 4 | /* 5 | */ 6 | 7 | /* 8 | */ 9 | 10 | /* 11 | */ 12 | 13 | /* 14 | */ 15 | 16 | /* 17 | */ 18 | 19 | /*@*/ 20 | 21 | /**@*/ 22 | 23 | /**@ 24 | @ 25 | @*/ 26 | 27 | /** 28 | */ 29 | 30 | /** 31 | @ 32 | **/ 33 | 34 | /*@ 35 | @ 36 | @*/ 37 | 38 | /*@ 39 | @ 40 | @*/ 41 | 42 | /*@ 43 | @ 44 | @*/ 45 | 46 | /*@ 47 | @ 48 | @*/ 49 | 50 | /* test 51 | * test 52 | */ 53 | 54 | [ # 1 55 | #2 56 | a # 3 57 | b 58 | c # 4 59 | #5 60 | 61 | #6 62 | 63 | d 64 | #7 65 | ] 66 | 67 | { 68 | a = 123; # comment 69 | } 70 | 71 | { # 1 72 | #2 73 | a=1; # 3 74 | b=1; 75 | c=1; # 4 76 | #5 77 | 78 | #6 79 | 80 | d=1; 81 | #7 82 | } 83 | 84 | (let # 1 85 | #2 86 | a=1; # 3 87 | b=1; 88 | c=1; # 4 89 | #5 90 | 91 | #6 92 | 93 | d=1; 94 | #7 95 | in 96 | d) 97 | 98 | ({ 99 | a, # comment 100 | b ? 2,# comment 101 | }: _) 102 | ] 103 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/comment/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | /**/ 3 | /**/ 4 | 5 | /**/ 6 | 7 | /**/ 8 | 9 | /**/ 10 | 11 | /**/ 12 | 13 | /* 14 | @ 15 | */ 16 | 17 | /** 18 | @ 19 | */ 20 | 21 | /** 22 | @ 23 | @ 24 | @ 25 | */ 26 | 27 | /***/ 28 | 29 | /** 30 | @ 31 | * 32 | */ 33 | 34 | /* 35 | @ 36 | @ 37 | @ 38 | */ 39 | 40 | /* 41 | @ 42 | @ 43 | @ 44 | */ 45 | 46 | /* 47 | @ 48 | @ 49 | @ 50 | */ 51 | 52 | /* 53 | @ 54 | @ 55 | @ 56 | */ 57 | 58 | /* 59 | test 60 | * test 61 | */ 62 | 63 | [ 64 | # 1 65 | #2 66 | a # 3 67 | b 68 | c # 4 69 | #5 70 | 71 | #6 72 | 73 | d 74 | #7 75 | ] 76 | 77 | { 78 | a = 123; # comment 79 | } 80 | 81 | { 82 | # 1 83 | #2 84 | a = 1; # 3 85 | b = 1; 86 | c = 1; # 4 87 | #5 88 | 89 | #6 90 | 91 | d = 1; 92 | #7 93 | } 94 | 95 | (let 96 | # 1 97 | #2 98 | a = 1; # 3 99 | b = 1; 100 | c = 1; # 4 101 | #5 102 | 103 | #6 104 | 105 | d = 1; 106 | #7 107 | in 108 | d) 109 | 110 | ({ 111 | a, # comment 112 | b ? 2, # comment 113 | }: 114 | _) 115 | ] 116 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/dynamic/in.nix: -------------------------------------------------------------------------------- 1 | a.${/*b*/c.${/*d*/e.${f}}/*g*/} 2 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/dynamic/out.nix: -------------------------------------------------------------------------------- 1 | a.${ 2 | /* 3 | b 4 | */ 5 | c.${ 6 | /* 7 | d 8 | */ 9 | e.${f} 10 | } 11 | /* 12 | g 13 | */ 14 | } 15 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/error/in.nix: -------------------------------------------------------------------------------- 1 | ;-) 2 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/error/out.nix: -------------------------------------------------------------------------------- 1 | ;-) 2 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/idioms/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | { meta = with lib; { a=1; b=2; c=3; };} 3 | 4 | { meta = with lib; 5 | # comment 6 | { a=1; b=2; c=3; };} 7 | ] 8 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/idioms/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | meta = with lib; { 4 | a = 1; 5 | b = 2; 6 | c = 3; 7 | }; 8 | } 9 | 10 | { 11 | meta = with lib; 12 | # comment 13 | { 14 | a = 1; 15 | b = 2; 16 | c = 3; 17 | }; 18 | } 19 | ] 20 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/idioms_lib_1/in.nix: -------------------------------------------------------------------------------- 1 | { 2 | traceIf = 3 | # Predicate to check 4 | pred: 5 | # Message that should be traced 6 | msg: 7 | # Value to return 8 | x: if pred then trace msg x else x; 9 | } 10 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/idioms_lib_1/out.nix: -------------------------------------------------------------------------------- 1 | { 2 | traceIf = 3 | # Predicate to check 4 | pred: 5 | # Message that should be traced 6 | msg: 7 | # Value to return 8 | x: 9 | if pred 10 | then trace msg x 11 | else x; 12 | } 13 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/idioms_pkgs_1/in.nix: -------------------------------------------------------------------------------- 1 | {stdenv, lib, fetchFrom, ... }: 2 | 3 | stdenv.mkDerivation rec { 4 | pname = "test"; 5 | version = "0.0"; 6 | src = fetchFrom { 7 | url = "example/${version}"; 8 | }; 9 | meta = with lib; { 10 | maintainers = with maintainers; [ someone ]; 11 | description = "something"; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/idioms_pkgs_1/out.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenv, 3 | lib, 4 | fetchFrom, 5 | ... 6 | }: 7 | stdenv.mkDerivation rec { 8 | pname = "test"; 9 | version = "0.0"; 10 | src = fetchFrom { 11 | url = "example/${version}"; 12 | }; 13 | meta = with lib; { 14 | maintainers = with maintainers; [someone]; 15 | description = "something"; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/idioms_pkgs_2/in.nix: -------------------------------------------------------------------------------- 1 | { lib 2 | , stdenv 3 | , fetchurl 4 | , nixos 5 | , testVersion 6 | , testEqualDerivation 7 | , hello 8 | }: 9 | 10 | stdenv.mkDerivation rec { 11 | pname = "hello"; 12 | version = "2.12"; 13 | 14 | src = fetchurl { 15 | url = "mirror://gnu/hello/${pname}-${version}.tar.gz"; 16 | sha256 = "1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g"; 17 | }; 18 | 19 | doCheck = true; 20 | 21 | passthru.tests = { 22 | version = testVersion { package = hello; }; 23 | 24 | invariant-under-noXlibs = 25 | testEqualDerivation 26 | "hello must not be rebuilt when environment.noXlibs is set." 27 | hello 28 | (nixos { environment.noXlibs = true; }).pkgs.hello; 29 | }; 30 | 31 | meta = with lib; { 32 | description = "A program that produces a familiar, friendly greeting"; 33 | longDescription = '' 34 | GNU Hello is a program that prints "Hello, world!" when you run it. 35 | It is fully customizable. 36 | ''; 37 | homepage = "https://www.gnu.org/software/hello/manual/"; 38 | changelog = "https://git.savannah.gnu.org/cgit/hello.git/plain/NEWS?h=v${version}"; 39 | license = licenses.gpl3Plus; 40 | maintainers = [ maintainers.eelco ]; 41 | platforms = platforms.all; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/idioms_pkgs_2/out.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | stdenv, 4 | fetchurl, 5 | nixos, 6 | testVersion, 7 | testEqualDerivation, 8 | hello, 9 | }: 10 | stdenv.mkDerivation rec { 11 | pname = "hello"; 12 | version = "2.12"; 13 | 14 | src = fetchurl { 15 | url = "mirror://gnu/hello/${pname}-${version}.tar.gz"; 16 | sha256 = "1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g"; 17 | }; 18 | 19 | doCheck = true; 20 | 21 | passthru.tests = { 22 | version = testVersion {package = hello;}; 23 | 24 | invariant-under-noXlibs = 25 | testEqualDerivation 26 | "hello must not be rebuilt when environment.noXlibs is set." 27 | hello 28 | (nixos {environment.noXlibs = true;}).pkgs.hello; 29 | }; 30 | 31 | meta = with lib; { 32 | description = "A program that produces a familiar, friendly greeting"; 33 | longDescription = '' 34 | GNU Hello is a program that prints "Hello, world!" when you run it. 35 | It is fully customizable. 36 | ''; 37 | homepage = "https://www.gnu.org/software/hello/manual/"; 38 | changelog = "https://git.savannah.gnu.org/cgit/hello.git/plain/NEWS?h=v${version}"; 39 | license = licenses.gpl3Plus; 40 | maintainers = [maintainers.eelco]; 41 | platforms = platforms.all; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/if_else/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (if true 3 | then { 4 | version = "1.2.3"; 5 | } 6 | else { 7 | version = "3.2.1"; 8 | }) 9 | (if true 10 | then '' 11 | some text 12 | '' 13 | else '' 14 | other text 15 | '') 16 | (if ./a then b else c) 17 | (if /**/ a /**/ then /**/ b /**/ else /**/ c) 18 | (if # test 19 | a # test 20 | then # test 21 | b # test 22 | else # test 23 | c) 24 | (if # test 25 | /**/ 26 | a # test 27 | /**/ 28 | then # test 29 | b # test 30 | /**/ 31 | else # test 32 | /**/ 33 | c) 34 | (if if a then b else c then b else if a then b else if a then b else c) 35 | (if if a then b else c then b else if a then b else /*x*/ if a then b else c) 36 | (if 37 | (if 38 | (if 39 | (if a then b else c) 40 | then 41 | (if a then b else c) 42 | else 43 | (if a then b else c)) 44 | then 45 | (if 46 | (if a then b else c) 47 | then 48 | (if a then b else c) 49 | else 50 | (if a then b else c)) 51 | else 52 | (if 53 | (if a then b else c) 54 | then 55 | (if a then b else c) 56 | else 57 | (if a then b else c))) 58 | then 59 | (if 60 | (if 61 | (if a then b else c) 62 | then 63 | (if a then b else c) 64 | else 65 | (if a then b else c)) 66 | then 67 | (if 68 | (if a then b else c) 69 | then 70 | (if a then b else c) 71 | else 72 | (if a then b else c)) 73 | else 74 | (if 75 | (if a then b else c) 76 | then 77 | (if a then b else c) 78 | else 79 | (if a then b else c))) 80 | else 81 | (if 82 | (if 83 | (if a then b else c) 84 | then 85 | (if a then b else c) 86 | else 87 | (if a then b else c)) 88 | then 89 | (if 90 | (if a then b else c) 91 | then 92 | (if a then b else c) 93 | else 94 | (if a then b else c)) 95 | else 96 | (if 97 | (if a then b else c) 98 | then 99 | (if a then b else c) 100 | else 101 | (if a then b else c)))) 102 | ] 103 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/if_else/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | ( 3 | if true 4 | then { 5 | version = "1.2.3"; 6 | } 7 | else { 8 | version = "3.2.1"; 9 | } 10 | ) 11 | ( 12 | if true 13 | then '' 14 | some text 15 | '' 16 | else '' 17 | other text 18 | '' 19 | ) 20 | ( 21 | if ./a 22 | then b 23 | else c 24 | ) 25 | ( 26 | if 27 | /**/ 28 | a 29 | /**/ 30 | then 31 | /**/ 32 | b 33 | /**/ 34 | else 35 | /**/ 36 | c 37 | ) 38 | ( 39 | if # test 40 | a # test 41 | then # test 42 | b # test 43 | else # test 44 | c 45 | ) 46 | ( 47 | if # test 48 | /**/ 49 | a # test 50 | /**/ 51 | then # test 52 | b # test 53 | /**/ 54 | else # test 55 | /**/ 56 | c 57 | ) 58 | ( 59 | if 60 | if a 61 | then b 62 | else c 63 | then b 64 | else if a 65 | then b 66 | else if a 67 | then b 68 | else c 69 | ) 70 | ( 71 | if 72 | if a 73 | then b 74 | else c 75 | then b 76 | else if a 77 | then b 78 | else 79 | /* 80 | x 81 | */ 82 | if a 83 | then b 84 | else c 85 | ) 86 | ( 87 | if 88 | ( 89 | if 90 | ( 91 | if 92 | ( 93 | if a 94 | then b 95 | else c 96 | ) 97 | then 98 | ( 99 | if a 100 | then b 101 | else c 102 | ) 103 | else 104 | ( 105 | if a 106 | then b 107 | else c 108 | ) 109 | ) 110 | then 111 | ( 112 | if 113 | ( 114 | if a 115 | then b 116 | else c 117 | ) 118 | then 119 | ( 120 | if a 121 | then b 122 | else c 123 | ) 124 | else 125 | ( 126 | if a 127 | then b 128 | else c 129 | ) 130 | ) 131 | else 132 | ( 133 | if 134 | ( 135 | if a 136 | then b 137 | else c 138 | ) 139 | then 140 | ( 141 | if a 142 | then b 143 | else c 144 | ) 145 | else 146 | ( 147 | if a 148 | then b 149 | else c 150 | ) 151 | ) 152 | ) 153 | then 154 | ( 155 | if 156 | ( 157 | if 158 | ( 159 | if a 160 | then b 161 | else c 162 | ) 163 | then 164 | ( 165 | if a 166 | then b 167 | else c 168 | ) 169 | else 170 | ( 171 | if a 172 | then b 173 | else c 174 | ) 175 | ) 176 | then 177 | ( 178 | if 179 | ( 180 | if a 181 | then b 182 | else c 183 | ) 184 | then 185 | ( 186 | if a 187 | then b 188 | else c 189 | ) 190 | else 191 | ( 192 | if a 193 | then b 194 | else c 195 | ) 196 | ) 197 | else 198 | ( 199 | if 200 | ( 201 | if a 202 | then b 203 | else c 204 | ) 205 | then 206 | ( 207 | if a 208 | then b 209 | else c 210 | ) 211 | else 212 | ( 213 | if a 214 | then b 215 | else c 216 | ) 217 | ) 218 | ) 219 | else 220 | ( 221 | if 222 | ( 223 | if 224 | ( 225 | if a 226 | then b 227 | else c 228 | ) 229 | then 230 | ( 231 | if a 232 | then b 233 | else c 234 | ) 235 | else 236 | ( 237 | if a 238 | then b 239 | else c 240 | ) 241 | ) 242 | then 243 | ( 244 | if 245 | ( 246 | if a 247 | then b 248 | else c 249 | ) 250 | then 251 | ( 252 | if a 253 | then b 254 | else c 255 | ) 256 | else 257 | ( 258 | if a 259 | then b 260 | else c 261 | ) 262 | ) 263 | else 264 | ( 265 | if 266 | ( 267 | if a 268 | then b 269 | else c 270 | ) 271 | then 272 | ( 273 | if a 274 | then b 275 | else c 276 | ) 277 | else 278 | ( 279 | if a 280 | then b 281 | else c 282 | ) 283 | ) 284 | ) 285 | ) 286 | ] 287 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/inherit/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | inherit aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; } 4 | { inherit 5 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; } 6 | { inherit b d ; } 7 | { inherit b d /*e*/ ; } 8 | { inherit b /*c*/ d ; } 9 | { inherit b /*c*/ d /*e*/ ; } 10 | { inherit /*a*/ b d ; } 11 | { inherit /*a*/ b d /*e*/ ; } 12 | { inherit /*a*/ b /*c*/ d ; } 13 | { inherit /*a*/ b /*c*/ d /*e*/ ; } 14 | { 15 | inherit # test 16 | a # test 17 | 18 | b # test 19 | c # test 20 | d # test 21 | 22 | e 23 | f 24 | 25 | g 26 | h 27 | ; 28 | } 29 | ] 30 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/inherit/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | inherit aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; 4 | } 5 | { 6 | inherit 7 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 8 | ; 9 | } 10 | {inherit b d;} 11 | { 12 | inherit 13 | b 14 | d 15 | /* 16 | e 17 | */ 18 | ; 19 | } 20 | { 21 | inherit 22 | b 23 | /* 24 | c 25 | */ 26 | d 27 | ; 28 | } 29 | { 30 | inherit 31 | b 32 | /* 33 | c 34 | */ 35 | d 36 | /* 37 | e 38 | */ 39 | ; 40 | } 41 | { 42 | inherit 43 | /* 44 | a 45 | */ 46 | b 47 | d 48 | ; 49 | } 50 | { 51 | inherit 52 | /* 53 | a 54 | */ 55 | b 56 | d 57 | /* 58 | e 59 | */ 60 | ; 61 | } 62 | { 63 | inherit 64 | /* 65 | a 66 | */ 67 | b 68 | /* 69 | c 70 | */ 71 | d 72 | ; 73 | } 74 | { 75 | inherit 76 | /* 77 | a 78 | */ 79 | b 80 | /* 81 | c 82 | */ 83 | d 84 | /* 85 | e 86 | */ 87 | ; 88 | } 89 | { 90 | inherit # test 91 | a # test 92 | 93 | b # test 94 | c # test 95 | d # test 96 | 97 | e 98 | f 99 | g 100 | h 101 | ; 102 | } 103 | ] 104 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/inherit_blank_trailing/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | inherit # test 4 | a # test 5 | 6 | b # test 7 | c # test 8 | d # test 9 | 10 | e 11 | f 12 | 13 | g 14 | h 15 | ; 16 | } 17 | { 18 | inherit 19 | a # mixed trivialities 20 | 21 | # comment 1 22 | # comment 2 23 | 24 | # comment 3 after blanks 25 | b # multiple newlines 26 | 27 | 28 | c # multiple comments 29 | # comment 1 30 | # comment 2 31 | # comment 3 32 | ; 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/inherit_blank_trailing/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | inherit # test 4 | a # test 5 | 6 | b # test 7 | c # test 8 | d # test 9 | 10 | e 11 | f 12 | g 13 | h 14 | ; 15 | } 16 | { 17 | inherit 18 | a # mixed trivialities 19 | 20 | # comment 1 21 | # comment 2 22 | # comment 3 after blanks 23 | b # multiple newlines 24 | 25 | c # multiple comments 26 | # comment 1 27 | # comment 2 28 | # comment 3 29 | ; 30 | } 31 | ] 32 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/inherit_comment/in.nix: -------------------------------------------------------------------------------- 1 | { 2 | inherit # eeby deeby 3 | a 4 | # b 5 | c 6 | ; 7 | } 8 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/inherit_comment/out.nix: -------------------------------------------------------------------------------- 1 | { 2 | inherit # eeby deeby 3 | a 4 | # b 5 | c 6 | ; 7 | } 8 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/inherit_from/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | { inherit ( c ) f h ; } 3 | { inherit ( c ) f h /*i*/; } 4 | { inherit ( c ) f /*g*/ h ; } 5 | { inherit ( c ) f /*g*/ h /*i*/; } 6 | { inherit ( c ) /*e*/ f h ; } 7 | { inherit ( c ) /*e*/ f h /*i*/; } 8 | { inherit ( c ) /*e*/ f /*g*/ h ; } 9 | { inherit ( c ) /*e*/ f /*g*/ h /*i*/; } 10 | { inherit ( c /*d*/) f h ; } 11 | { inherit ( c /*d*/) f h /*i*/; } 12 | { inherit ( c /*d*/) f /*g*/ h ; } 13 | { inherit ( c /*d*/) f /*g*/ h /*i*/; } 14 | { inherit ( c /*d*/) /*e*/ f h ; } 15 | { inherit ( c /*d*/) /*e*/ f h /*i*/; } 16 | { inherit ( c /*d*/) /*e*/ f /*g*/ h ; } 17 | { inherit ( c /*d*/) /*e*/ f /*g*/ h /*i*/; } 18 | { inherit (/*b*/ c ) f h ; } 19 | { inherit (/*b*/ c ) f h /*i*/; } 20 | { inherit (/*b*/ c ) f /*g*/ h ; } 21 | { inherit (/*b*/ c ) f /*g*/ h /*i*/; } 22 | { inherit (/*b*/ c ) /*e*/ f h ; } 23 | { inherit (/*b*/ c ) /*e*/ f h /*i*/; } 24 | { inherit (/*b*/ c ) /*e*/ f /*g*/ h ; } 25 | { inherit (/*b*/ c ) /*e*/ f /*g*/ h /*i*/; } 26 | { inherit (/*b*/ c /*d*/) f h ; } 27 | { inherit (/*b*/ c /*d*/) f h /*i*/; } 28 | { inherit (/*b*/ c /*d*/) f /*g*/ h ; } 29 | { inherit (/*b*/ c /*d*/) f /*g*/ h /*i*/; } 30 | { inherit (/*b*/ c /*d*/) /*e*/ f h ; } 31 | { inherit (/*b*/ c /*d*/) /*e*/ f h /*i*/; } 32 | { inherit (/*b*/ c /*d*/) /*e*/ f /*g*/ h ; } 33 | { inherit (/*b*/ c /*d*/) /*e*/ f /*g*/ h /*i*/; } 34 | { inherit /*a*/ ( c ) f h ; } 35 | { inherit /*a*/ ( c ) f h /*i*/; } 36 | { inherit /*a*/ ( c ) f /*g*/ h ; } 37 | { inherit /*a*/ ( c ) f /*g*/ h /*i*/; } 38 | { inherit /*a*/ ( c ) /*e*/ f h ; } 39 | { inherit /*a*/ ( c ) /*e*/ f h /*i*/; } 40 | { inherit /*a*/ ( c ) /*e*/ f /*g*/ h ; } 41 | { inherit /*a*/ ( c ) /*e*/ f /*g*/ h /*i*/; } 42 | { inherit /*a*/ ( c /*d*/) f h ; } 43 | { inherit /*a*/ ( c /*d*/) f h /*i*/; } 44 | { inherit /*a*/ ( c /*d*/) f /*g*/ h ; } 45 | { inherit /*a*/ ( c /*d*/) f /*g*/ h /*i*/; } 46 | { inherit /*a*/ ( c /*d*/) /*e*/ f h ; } 47 | { inherit /*a*/ ( c /*d*/) /*e*/ f h /*i*/; } 48 | { inherit /*a*/ ( c /*d*/) /*e*/ f /*g*/ h ; } 49 | { inherit /*a*/ ( c /*d*/) /*e*/ f /*g*/ h /*i*/; } 50 | { inherit /*a*/ (/*b*/ c ) f h ; } 51 | { inherit /*a*/ (/*b*/ c ) f h /*i*/; } 52 | { inherit /*a*/ (/*b*/ c ) f /*g*/ h ; } 53 | { inherit /*a*/ (/*b*/ c ) f /*g*/ h /*i*/; } 54 | { inherit /*a*/ (/*b*/ c ) /*e*/ f h ; } 55 | { inherit /*a*/ (/*b*/ c ) /*e*/ f h /*i*/; } 56 | { inherit /*a*/ (/*b*/ c ) /*e*/ f /*g*/ h ; } 57 | { inherit /*a*/ (/*b*/ c ) /*e*/ f /*g*/ h /*i*/; } 58 | { inherit /*a*/ (/*b*/ c /*d*/) f h ; } 59 | { inherit /*a*/ (/*b*/ c /*d*/) f h /*i*/; } 60 | { inherit /*a*/ (/*b*/ c /*d*/) f /*g*/ h ; } 61 | { inherit /*a*/ (/*b*/ c /*d*/) f /*g*/ h /*i*/; } 62 | { inherit /*a*/ (/*b*/ c /*d*/) /*e*/ f h ; } 63 | { inherit /*a*/ (/*b*/ c /*d*/) /*e*/ f h /*i*/; } 64 | { inherit /*a*/ (/*b*/ c /*d*/) /*e*/ f /*g*/ h ; } 65 | { inherit /*a*/ (/*b*/ c /*d*/) /*e*/ f /*g*/ h /*i*/; } 66 | ] 67 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/key_value/in.nix: -------------------------------------------------------------------------------- 1 | rec /**/ { 2 | 3 | a = (((4))); 4 | a = (((a: b))); 5 | 6 | a = {a = 1 ;}; 7 | 8 | 9 | b = {a = 1/*d*/;}; 10 | 11 | 12 | c = {a =/*c*/1 ;}; 13 | d = {a =/*c*/1/*d*/;}; 14 | e = {a/*b*/= 1 ;}; 15 | f = {a/*b*/= 1/*d*/;}; 16 | h = {a/*b*/=/*c*/1 ;}; 17 | i = {a/*b*/=/*c*/1/*d*/;}; 18 | j = a: { b = 1 ;}; 19 | k = a: { b = 1; c = 2;}; 20 | l = a: /*b*/ { b = 1 ;}; 21 | m = a: /*b*/ { b = 1; c = 2;}; 22 | n = pkgs: { }; 23 | o = { pkgs 24 | , ... 25 | }: { }; 26 | 27 | a 28 | /*b*/ 29 | = 30 | /*c*/ 31 | 1 32 | /*d*/ 33 | ; 34 | 35 | p = 36 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { } 37 | a; 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/key_value/out.nix: -------------------------------------------------------------------------------- 1 | rec 2 | /**/ 3 | { 4 | a = 4; 5 | a = a: b; 6 | 7 | a = {a = 1;}; 8 | 9 | b = { 10 | a = 11 | 1 12 | /* 13 | d 14 | */ 15 | ; 16 | }; 17 | 18 | c = { 19 | a = 20 | /* 21 | c 22 | */ 23 | 1; 24 | }; 25 | d = { 26 | a = 27 | /* 28 | c 29 | */ 30 | 1 31 | /* 32 | d 33 | */ 34 | ; 35 | }; 36 | e = { 37 | a 38 | /* 39 | b 40 | */ 41 | = 42 | 1; 43 | }; 44 | f = { 45 | a 46 | /* 47 | b 48 | */ 49 | = 50 | 1 51 | /* 52 | d 53 | */ 54 | ; 55 | }; 56 | h = { 57 | a 58 | /* 59 | b 60 | */ 61 | = 62 | /* 63 | c 64 | */ 65 | 1; 66 | }; 67 | i = { 68 | a 69 | /* 70 | b 71 | */ 72 | = 73 | /* 74 | c 75 | */ 76 | 1 77 | /* 78 | d 79 | */ 80 | ; 81 | }; 82 | j = a: {b = 1;}; 83 | k = a: { 84 | b = 1; 85 | c = 2; 86 | }; 87 | l = a: 88 | /* 89 | b 90 | */ 91 | {b = 1;}; 92 | m = a: 93 | /* 94 | b 95 | */ 96 | { 97 | b = 1; 98 | c = 2; 99 | }; 100 | n = pkgs: {}; 101 | o = {pkgs, ...}: {}; 102 | 103 | a 104 | /* 105 | b 106 | */ 107 | = 108 | /* 109 | c 110 | */ 111 | 1 112 | /* 113 | d 114 | */ 115 | ; 116 | 117 | p = 118 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {} 119 | a; 120 | } 121 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/lambda/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (a: b: /*c*/ d) 3 | ({}: b: /*c*/ d) 4 | (a: {}: /*c*/ d) 5 | (a : d) 6 | (a : /*c*/ d) 7 | (a /*b*/ : d) 8 | (a /*b*/ : /*c*/ d) 9 | ( 10 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 11 | ) 12 | ( 13 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ) 14 | ({ pkgs ? import ./.. { }, locationsXml }: null) 15 | (a: b: c: 16 | { }: 17 | a: b: c: 18 | a) 19 | 20 | ({pkgs, ...}: { 21 | # Stuff 22 | }) 23 | 24 | ({pkgs, ...}: let 25 | in pkgs) 26 | 27 | (a: {b, 28 | ...}: c: { 29 | # Stuff 30 | }) 31 | 32 | (a: {b, c, 33 | ...}: d: { 34 | # Stuff 35 | }) 36 | ] 37 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/lambda/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (a: b: 3 | /* 4 | c 5 | */ 6 | d) 7 | ({}: b: 8 | /* 9 | c 10 | */ 11 | d) 12 | (a: {}: 13 | /* 14 | c 15 | */ 16 | d) 17 | (a: d) 18 | (a: 19 | /* 20 | c 21 | */ 22 | d) 23 | (a 24 | /* 25 | b 26 | */ 27 | : 28 | d) 29 | (a 30 | /* 31 | b 32 | */ 33 | : 34 | /* 35 | c 36 | */ 37 | d) 38 | ( 39 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 40 | ) 41 | ( 42 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 43 | ) 44 | ({ 45 | pkgs ? import ./.. {}, 46 | locationsXml, 47 | }: 48 | null) 49 | (a: b: c: {}: a: b: c: 50 | a) 51 | 52 | ({pkgs, ...}: { 53 | # Stuff 54 | }) 55 | 56 | ({pkgs, ...}: let 57 | in 58 | pkgs) 59 | 60 | (a: {b, ...}: c: { 61 | # Stuff 62 | }) 63 | 64 | (a: { 65 | b, 66 | c, 67 | ... 68 | }: d: { 69 | # Stuff 70 | }) 71 | ] 72 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/let_in/in.nix: -------------------------------------------------------------------------------- 1 | let 2 | 3 | 4 | /**/ 5 | a = let b=2; c=3; in d; 6 | /**/ 7 | a = let c=1; in f; 8 | 9 | 10 | /**/ 11 | a = let c=1; in /*e*/ f; 12 | /**/ 13 | a = let c=1; /*d*/ in f; 14 | /**/ 15 | 16 | 17 | a = let c=1; /*d*/ in /*e*/ f; 18 | /**/ 19 | a = let /*b*/ c=1; in f; 20 | /**/ 21 | a = let /*b*/ c=1; in /*e*/ f; 22 | /**/ 23 | a = let /*b*/ c=1; /*d*/ in f; 24 | /**/ 25 | a = let /*b*/ c=1; /*d*/ in /*e*/ f; 26 | /**/ 27 | 28 | a = let 29 | in [ 30 | 1 31 | 2 32 | ]; 33 | 34 | in 35 | 36 | 37 | /**/ 38 | 39 | 40 | a 41 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/let_in/out.nix: -------------------------------------------------------------------------------- 1 | let 2 | /**/ 3 | a = let 4 | b = 2; 5 | c = 3; 6 | in 7 | d; 8 | /**/ 9 | a = let c = 1; in f; 10 | 11 | /**/ 12 | a = let 13 | c = 1; 14 | in 15 | /* 16 | e 17 | */ 18 | f; 19 | /**/ 20 | a = let 21 | c = 1; 22 | /* 23 | d 24 | */ 25 | in 26 | f; 27 | /**/ 28 | 29 | a = let 30 | c = 1; 31 | /* 32 | d 33 | */ 34 | in 35 | /* 36 | e 37 | */ 38 | f; 39 | /**/ 40 | a = let 41 | /* 42 | b 43 | */ 44 | c = 1; 45 | in 46 | f; 47 | /**/ 48 | a = let 49 | /* 50 | b 51 | */ 52 | c = 1; 53 | in 54 | /* 55 | e 56 | */ 57 | f; 58 | /**/ 59 | a = let 60 | /* 61 | b 62 | */ 63 | c = 1; 64 | /* 65 | d 66 | */ 67 | in 68 | f; 69 | /**/ 70 | a = let 71 | /* 72 | b 73 | */ 74 | c = 1; 75 | /* 76 | d 77 | */ 78 | in 79 | /* 80 | e 81 | */ 82 | f; 83 | /**/ 84 | 85 | a = let 86 | in [ 87 | 1 88 | 2 89 | ]; 90 | in 91 | /**/ 92 | a 93 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/lists/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | [ 1 ] 3 | 4 | [ 1 5 | ] 6 | 7 | [ b d ] 8 | [ b d /*e*/ ] 9 | [ b /*c*/ d ] 10 | [ b /*c*/ d /*e*/ ] 11 | [ /*a*/ b d ] 12 | [ /*a*/ b d /*e*/ ] 13 | [ /*a*/ b /*c*/ d ] 14 | [ /*a*/ b /*c*/ d /*e*/ ] 15 | 16 | [ 17 | 18 | 19 | b 20 | 21 | 22 | d 23 | 24 | 25 | ] 26 | [ 27 | 28 | 29 | /*a*/ 30 | 31 | 32 | b 33 | 34 | 35 | /*c*/ 36 | 37 | 38 | d 39 | 40 | 41 | /*e*/ 42 | 43 | 44 | ] 45 | 46 | ] 47 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/lists/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | [1] 3 | 4 | [ 5 | 1 6 | ] 7 | 8 | [b d] 9 | [ 10 | b 11 | d 12 | /* 13 | e 14 | */ 15 | ] 16 | [ 17 | b 18 | /* 19 | c 20 | */ 21 | d 22 | ] 23 | [ 24 | b 25 | /* 26 | c 27 | */ 28 | d 29 | /* 30 | e 31 | */ 32 | ] 33 | [ 34 | /* 35 | a 36 | */ 37 | b 38 | d 39 | ] 40 | [ 41 | /* 42 | a 43 | */ 44 | b 45 | d 46 | /* 47 | e 48 | */ 49 | ] 50 | [ 51 | /* 52 | a 53 | */ 54 | b 55 | /* 56 | c 57 | */ 58 | d 59 | ] 60 | [ 61 | /* 62 | a 63 | */ 64 | b 65 | /* 66 | c 67 | */ 68 | d 69 | /* 70 | e 71 | */ 72 | ] 73 | 74 | [ 75 | b 76 | 77 | d 78 | ] 79 | [ 80 | /* 81 | a 82 | */ 83 | 84 | b 85 | 86 | /* 87 | c 88 | */ 89 | 90 | d 91 | 92 | /* 93 | e 94 | */ 95 | ] 96 | ] 97 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/monsters_1/in.nix: -------------------------------------------------------------------------------- 1 | { 2 | # foo 3 | stdenv 4 | # foo 5 | , 6 | # foo 7 | lib 8 | # foo 9 | , 10 | # foo 11 | fetchFromGitLab 12 | # foo 13 | , 14 | # foo 15 | cairo 16 | # foo 17 | , 18 | # foo 19 | desktop-file-utils 20 | # foo 21 | , 22 | # foo 23 | gettext 24 | # foo 25 | , 26 | # foo 27 | glib 28 | # foo 29 | , 30 | # foo 31 | gtk4 32 | # foo 33 | , 34 | # foo 35 | libadwaita 36 | # foo 37 | , 38 | # foo 39 | meson 40 | # foo 41 | , 42 | # foo 43 | ninja 44 | # foo 45 | , 46 | # foo 47 | pango 48 | # foo 49 | , 50 | # foo 51 | pkg-config 52 | # foo 53 | , 54 | # foo 55 | python3 56 | # foo 57 | , 58 | # foo 59 | rustPlatform 60 | # foo 61 | , 62 | # foo 63 | wrapGAppsHook4 64 | # foo 65 | }: 66 | # foo 67 | stdenv.mkDerivation 68 | # foo 69 | rec 70 | # foo 71 | { 72 | # foo 73 | pname 74 | # foo 75 | = 76 | # foo 77 | "contrast"; 78 | # foo 79 | version 80 | # foo 81 | = 82 | # foo 83 | "0.0.5"; 84 | # foo 85 | src 86 | # foo 87 | = 88 | # foo 89 | fetchFromGitLab 90 | # foo 91 | { 92 | # foo 93 | domain 94 | # foo 95 | = 96 | # foo 97 | "gitlab.gnome.org"; 98 | # foo 99 | group 100 | # foo 101 | = 102 | # foo 103 | "World"; 104 | # foo 105 | owner 106 | # foo 107 | = 108 | # foo 109 | "design"; 110 | # foo 111 | repo 112 | # foo 113 | = 114 | # foo 115 | "contrast"; 116 | # foo 117 | rev 118 | # foo 119 | = 120 | # foo 121 | version; 122 | # foo 123 | sha256 124 | # foo 125 | = 126 | # foo 127 | "cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0="; 128 | # foo 129 | }; 130 | # foo 131 | cargoDeps 132 | # foo 133 | = 134 | # foo 135 | rustPlatform.fetchCargoTarball 136 | # foo 137 | { 138 | # foo 139 | inherit 140 | # foo 141 | src; 142 | # foo 143 | name 144 | # foo 145 | = 146 | # foo 147 | "${pname}-${version}"; 148 | # foo 149 | hash 150 | # foo 151 | = 152 | # foo 153 | "sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ="; 154 | # foo 155 | }; 156 | # foo 157 | nativeBuildInputs 158 | # foo 159 | = 160 | # foo 161 | [ 162 | # foo 163 | desktop-file-utils 164 | # foo 165 | gettext 166 | # foo 167 | meson 168 | # foo 169 | ninja 170 | # foo 171 | pkg-config 172 | # foo 173 | python3 174 | # foo 175 | rustPlatform.rust.cargo 176 | # foo 177 | rustPlatform.cargoSetupHook 178 | # foo 179 | rustPlatform.rust.rustc 180 | # foo 181 | wrapGAppsHook4 182 | # foo 183 | glib 184 | # foo 185 | # for glib-compile-resources 186 | 187 | # foo 188 | ]; 189 | # foo 190 | buildInputs 191 | # foo 192 | = 193 | # foo 194 | [ 195 | # foo 196 | cairo 197 | # foo 198 | glib 199 | # foo 200 | gtk4 201 | # foo 202 | libadwaita 203 | # foo 204 | pango 205 | # foo 206 | ]; 207 | # foo 208 | postPatch 209 | # foo 210 | = 211 | # foo 212 | '' 213 | patchShebangs build-aux/meson_post_install.py 214 | # https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23 215 | substituteInPlace build-aux/meson_post_install.py \ 216 | --replace "gtk-update-icon-cache" "gtk4-update-icon-cache" 217 | ''; 218 | # foo 219 | meta 220 | # foo 221 | = 222 | # foo 223 | with 224 | # foo 225 | lib; 226 | # foo 227 | { 228 | # foo 229 | description 230 | # foo 231 | = 232 | # foo 233 | "Checks whether the contrast between two colors meet the WCAG requirements"; 234 | # foo 235 | homepage 236 | # foo 237 | = 238 | # foo 239 | "https://gitlab.gnome.org/World/design/contrast"; 240 | # foo 241 | license 242 | # foo 243 | = 244 | # foo 245 | licenses.gpl3Plus; 246 | # foo 247 | maintainers 248 | # foo 249 | = 250 | # foo 251 | with 252 | # foo 253 | maintainers; 254 | # foo 255 | [ 256 | # foo 257 | jtojnar 258 | # foo 259 | ]; 260 | # foo 261 | platforms 262 | # foo 263 | = 264 | # foo 265 | platforms.unix; 266 | # foo 267 | }; 268 | # foo 269 | } 270 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/monsters_1/out.nix: -------------------------------------------------------------------------------- 1 | { 2 | # foo 3 | stdenv, 4 | # foo 5 | # foo 6 | lib, 7 | # foo 8 | # foo 9 | fetchFromGitLab, 10 | # foo 11 | # foo 12 | cairo, 13 | # foo 14 | # foo 15 | desktop-file-utils, 16 | # foo 17 | # foo 18 | gettext, 19 | # foo 20 | # foo 21 | glib, 22 | # foo 23 | # foo 24 | gtk4, 25 | # foo 26 | # foo 27 | libadwaita, 28 | # foo 29 | # foo 30 | meson, 31 | # foo 32 | # foo 33 | ninja, 34 | # foo 35 | # foo 36 | pango, 37 | # foo 38 | # foo 39 | pkg-config, 40 | # foo 41 | # foo 42 | python3, 43 | # foo 44 | # foo 45 | rustPlatform, 46 | # foo 47 | # foo 48 | wrapGAppsHook4, 49 | # foo 50 | }: 51 | # foo 52 | stdenv.mkDerivation 53 | # foo 54 | rec 55 | # foo 56 | { 57 | # foo 58 | pname 59 | # foo 60 | = 61 | # foo 62 | "contrast"; 63 | # foo 64 | version 65 | # foo 66 | = 67 | # foo 68 | "0.0.5"; 69 | # foo 70 | src 71 | # foo 72 | = 73 | # foo 74 | fetchFromGitLab 75 | # foo 76 | { 77 | # foo 78 | domain 79 | # foo 80 | = 81 | # foo 82 | "gitlab.gnome.org"; 83 | # foo 84 | group 85 | # foo 86 | = 87 | # foo 88 | "World"; 89 | # foo 90 | owner 91 | # foo 92 | = 93 | # foo 94 | "design"; 95 | # foo 96 | repo 97 | # foo 98 | = 99 | # foo 100 | "contrast"; 101 | # foo 102 | rev 103 | # foo 104 | = 105 | # foo 106 | version; 107 | # foo 108 | sha256 109 | # foo 110 | = 111 | # foo 112 | "cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0="; 113 | # foo 114 | }; 115 | # foo 116 | cargoDeps 117 | # foo 118 | = 119 | # foo 120 | rustPlatform.fetchCargoTarball 121 | # foo 122 | { 123 | # foo 124 | inherit 125 | # foo 126 | src 127 | ; 128 | # foo 129 | name 130 | # foo 131 | = 132 | # foo 133 | "${pname}-${version}"; 134 | # foo 135 | hash 136 | # foo 137 | = 138 | # foo 139 | "sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ="; 140 | # foo 141 | }; 142 | # foo 143 | nativeBuildInputs 144 | # foo 145 | = 146 | # foo 147 | [ 148 | # foo 149 | desktop-file-utils 150 | # foo 151 | gettext 152 | # foo 153 | meson 154 | # foo 155 | ninja 156 | # foo 157 | pkg-config 158 | # foo 159 | python3 160 | # foo 161 | rustPlatform.rust.cargo 162 | # foo 163 | rustPlatform.cargoSetupHook 164 | # foo 165 | rustPlatform.rust.rustc 166 | # foo 167 | wrapGAppsHook4 168 | # foo 169 | glib 170 | # foo 171 | # for glib-compile-resources 172 | 173 | # foo 174 | ]; 175 | # foo 176 | buildInputs 177 | # foo 178 | = 179 | # foo 180 | [ 181 | # foo 182 | cairo 183 | # foo 184 | glib 185 | # foo 186 | gtk4 187 | # foo 188 | libadwaita 189 | # foo 190 | pango 191 | # foo 192 | ]; 193 | # foo 194 | postPatch 195 | # foo 196 | = 197 | # foo 198 | '' 199 | patchShebangs build-aux/meson_post_install.py 200 | # https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23 201 | substituteInPlace build-aux/meson_post_install.py \ 202 | --replace "gtk-update-icon-cache" "gtk4-update-icon-cache" 203 | ''; 204 | # foo 205 | meta 206 | # foo 207 | = 208 | # foo 209 | with 210 | # foo 211 | lib; 212 | # foo 213 | { 214 | # foo 215 | description 216 | # foo 217 | = 218 | # foo 219 | "Checks whether the contrast between two colors meet the WCAG requirements"; 220 | # foo 221 | homepage 222 | # foo 223 | = 224 | # foo 225 | "https://gitlab.gnome.org/World/design/contrast"; 226 | # foo 227 | license 228 | # foo 229 | = 230 | # foo 231 | licenses.gpl3Plus; 232 | # foo 233 | maintainers 234 | # foo 235 | = 236 | # foo 237 | with 238 | # foo 239 | maintainers; 240 | # foo 241 | [ 242 | # foo 243 | jtojnar 244 | # foo 245 | ]; 246 | # foo 247 | platforms 248 | # foo 249 | = 250 | # foo 251 | platforms.unix; 252 | # foo 253 | }; 254 | # foo 255 | } 256 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/monsters_2/in.nix: -------------------------------------------------------------------------------- 1 | 2 | { 3 | lib = { 4 | 5 | /* Concatenate two lists 6 | 7 | Type: concat :: [a] -> [a] -> [a] 8 | 9 | Example: 10 | concat [ 1 2 ] [ 3 4 ] 11 | => [ 1 2 3 4 ] 12 | */ 13 | concat = x: y: x ++ y; 14 | }; 15 | 16 | options = { 17 | 18 | boot.kernel.features = mkOption { 19 | default = {}; 20 | example = literalExpression "{ debug = true; }"; 21 | internal = true; 22 | description = '' 23 | This option allows to enable or disable certain kernel features. 24 | It's not API, because it's about kernel feature sets, that 25 | make sense for specific use cases. Mostly along with programs, 26 | which would have separate nixos options. 27 | `grep features pkgs/os-specific/linux/kernel/common-config.nix` 28 | ''; 29 | }; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/monsters_2/out.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib = { 3 | /* 4 | Concatenate two lists 5 | 6 | Type: concat :: [a] -> [a] -> [a] 7 | 8 | Example: 9 | concat [ 1 2 ] [ 3 4 ] 10 | => [ 1 2 3 4 ] 11 | */ 12 | concat = x: y: x ++ y; 13 | }; 14 | 15 | options = { 16 | boot.kernel.features = mkOption { 17 | default = {}; 18 | example = literalExpression "{ debug = true; }"; 19 | internal = true; 20 | description = '' 21 | This option allows to enable or disable certain kernel features. 22 | It's not API, because it's about kernel feature sets, that 23 | make sense for specific use cases. Mostly along with programs, 24 | which would have separate nixos options. 25 | `grep features pkgs/os-specific/linux/kernel/common-config.nix` 26 | ''; 27 | }; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/monsters_3/in.nix: -------------------------------------------------------------------------------- 1 | { stdenv , lib , fetchFromGitLab , cairo , desktop-file-utils , gettext , glib , gtk4 , libadwaita , meson , ninja , pango , pkg-config , python3 , rustPlatform , wrapGAppsHook4 }: stdenv.mkDerivation rec { pname = "contrast"; version = "0.0.5"; src = fetchFromGitLab { domain = "gitlab.gnome.org"; group = "World"; owner = "design"; repo = "contrast"; rev = version; sha256 = "cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0="; }; cargoDeps = rustPlatform.fetchCargoTarball { inherit src; name = "${pname}-${version}"; hash = "sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ="; }; nativeBuildInputs = [ desktop-file-utils gettext meson ninja pkg-config python3 rustPlatform.rust.cargo rustPlatform.cargoSetupHook rustPlatform.rust.rustc wrapGAppsHook4 glib # for glib-compile-resources 2 | ]; buildInputs = [ cairo glib gtk4 libadwaita pango ]; postPatch = '' 3 | patchShebangs build-aux/meson_post_install.py 4 | # https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23 5 | substituteInPlace build-aux/meson_post_install.py \ 6 | --replace "gtk-update-icon-cache" "gtk4-update-icon-cache" 7 | ''; meta = with lib; { description = "Checks whether the contrast between two colors meet the WCAG requirements"; homepage = "https://gitlab.gnome.org/World/design/contrast"; license = licenses.gpl3Plus; maintainers = with maintainers; [ jtojnar ]; platforms = platforms.unix; }; } 8 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/monsters_3/out.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenv, 3 | lib, 4 | fetchFromGitLab, 5 | cairo, 6 | desktop-file-utils, 7 | gettext, 8 | glib, 9 | gtk4, 10 | libadwaita, 11 | meson, 12 | ninja, 13 | pango, 14 | pkg-config, 15 | python3, 16 | rustPlatform, 17 | wrapGAppsHook4, 18 | }: 19 | stdenv.mkDerivation rec { 20 | pname = "contrast"; 21 | version = "0.0.5"; 22 | src = fetchFromGitLab { 23 | domain = "gitlab.gnome.org"; 24 | group = "World"; 25 | owner = "design"; 26 | repo = "contrast"; 27 | rev = version; 28 | sha256 = "cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0="; 29 | }; 30 | cargoDeps = rustPlatform.fetchCargoTarball { 31 | inherit src; 32 | name = "${pname}-${version}"; 33 | hash = "sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ="; 34 | }; 35 | nativeBuildInputs = [ 36 | desktop-file-utils 37 | gettext 38 | meson 39 | ninja 40 | pkg-config 41 | python3 42 | rustPlatform.rust.cargo 43 | rustPlatform.cargoSetupHook 44 | rustPlatform.rust.rustc 45 | wrapGAppsHook4 46 | glib # for glib-compile-resources 47 | ]; 48 | buildInputs = [cairo glib gtk4 libadwaita pango]; 49 | postPatch = '' 50 | patchShebangs build-aux/meson_post_install.py 51 | # https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23 52 | substituteInPlace build-aux/meson_post_install.py \ 53 | --replace "gtk-update-icon-cache" "gtk4-update-icon-cache" 54 | ''; 55 | meta = with lib; { 56 | description = "Checks whether the contrast between two colors meet the WCAG requirements"; 57 | homepage = "https://gitlab.gnome.org/World/design/contrast"; 58 | license = licenses.gpl3Plus; 59 | maintainers = with maintainers; [jtojnar]; 60 | platforms = platforms.unix; 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/monsters_4/in.nix: -------------------------------------------------------------------------------- 1 | {/*Foo*/stdenv/*Foo*/,/*Foo*/lib/*Foo*/,/*Foo*/fetchFromGitLab/*Foo*/,/*Foo*/cairo/*Foo*/,/*Foo*/desktop-file-utils/*Foo*/,/*Foo*/gettext/*Foo*/,/*Foo*/glib/*Foo*/,/*Foo*/gtk4/*Foo*/,/*Foo*/libadwaita/*Foo*/,/*Foo*/meson/*Foo*/,/*Foo*/ninja/*Foo*/,/*Foo*/pango/*Foo*/,/*Foo*/pkg-config/*Foo*/,/*Foo*/python3/*Foo*/,/*Foo*/rustPlatform/*Foo*/,/*Foo*/wrapGAppsHook4/*Foo*/}:/*Foo*/stdenv.mkDerivation/*Foo*/rec/*Foo*/{/*Foo*/pname/*Foo*/=/*Foo*/"contrast";/*Foo*/version/*Foo*/=/*Foo*/"0.0.5";/*Foo*/src/*Foo*/=/*Foo*/fetchFromGitLab/*Foo*/{/*Foo*/domain/*Foo*/=/*Foo*/"gitlab.gnome.org";/*Foo*/group/*Foo*/=/*Foo*/"World";/*Foo*/owner/*Foo*/=/*Foo*/"design";/*Foo*/repo/*Foo*/=/*Foo*/"contrast";/*Foo*/rev/*Foo*/=/*Foo*/version;/*Foo*/sha256/*Foo*/=/*Foo*/"cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0=";/*Foo*/};/*Foo*/cargoDeps/*Foo*/=/*Foo*/rustPlatform.fetchCargoTarball/*Foo*/{/*Foo*/inherit/*Foo*/src;/*Foo*/name/*Foo*/=/*Foo*/"${pname}-${version}";/*Foo*/hash/*Foo*/=/*Foo*/"sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ=";/*Foo*/};/*Foo*/nativeBuildInputs/*Foo*/=/*Foo*/[/*Foo*/desktop-file-utils/*Foo*/gettext/*Foo*/meson/*Foo*/ninja/*Foo*/pkg-config/*Foo*/python3/*Foo*/rustPlatform.rust.cargo/*Foo*/rustPlatform.cargoSetupHook/*Foo*/rustPlatform.rust.rustc/*Foo*/wrapGAppsHook4/*Foo*/glib/*Foo*/# for glib-compile-resources 2 | /*Foo*/];/*Foo*/buildInputs/*Foo*/=/*Foo*/[/*Foo*/cairo/*Foo*/glib/*Foo*/gtk4/*Foo*/libadwaita/*Foo*/pango/*Foo*/];/*Foo*/postPatch/*Foo*/=/*Foo*/'' 3 | patchShebangs build-aux/meson_post_install.py 4 | # https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23 5 | substituteInPlace build-aux/meson_post_install.py \ 6 | --replace "gtk-update-icon-cache" "gtk4-update-icon-cache" 7 | '';/*Foo*/meta/*Foo*/=/*Foo*/with/*Foo*/lib;/*Foo*/{/*Foo*/description/*Foo*/=/*Foo*/"Checks whether the contrast between two colors meet the WCAG requirements";/*Foo*/homepage/*Foo*/=/*Foo*/"https://gitlab.gnome.org/World/design/contrast";/*Foo*/license/*Foo*/=/*Foo*/licenses.gpl3Plus;/*Foo*/maintainers/*Foo*/=/*Foo*/with/*Foo*/maintainers;/*Foo*/[/*Foo*/jtojnar/*Foo*/];/*Foo*/platforms/*Foo*/=/*Foo*/platforms.unix;/*Foo*/};/*Foo*/} 8 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/monsters_5/in.nix: -------------------------------------------------------------------------------- 1 | { 2 | 3 | config, 4 | 5 | lib, 6 | 7 | pkgs, 8 | 9 | ... 10 | 11 | }: 12 | 13 | with 14 | 15 | lib; 16 | 17 | let 18 | 19 | 20 | 21 | 22 | 23 | inherit 24 | 25 | (config.boot) 26 | 27 | kernelPatches; 28 | 29 | 30 | 31 | 32 | inherit 33 | 34 | (config.boot.kernel) 35 | 36 | features 37 | 38 | randstructSeed; 39 | 40 | 41 | 42 | 43 | inherit 44 | 45 | (config.boot.kernelPackages) 46 | 47 | kernel; 48 | 49 | 50 | 51 | 52 | 53 | kernelModulesConf 54 | 55 | = 56 | 57 | pkgs.writeText 58 | 59 | "nixos.conf" 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | '' 69 | ${concatStringsSep "\n" config.boot.kernelModules} 70 | ''; 71 | 72 | in 73 | 74 | { 75 | 76 | 77 | 78 | 79 | 80 | ###### interface 81 | 82 | 83 | 84 | 85 | 86 | options 87 | 88 | = 89 | 90 | { 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | boot.kernel.features 101 | 102 | = 103 | 104 | mkOption 105 | 106 | { 107 | 108 | 109 | default 110 | 111 | = 112 | 113 | {}; 114 | 115 | 116 | example 117 | 118 | = 119 | 120 | literalExpression 121 | 122 | "{debug= true;}"; 123 | 124 | 125 | internal 126 | 127 | = 128 | 129 | true; 130 | 131 | 132 | description 133 | 134 | = 135 | 136 | '' 137 | This option allows to enable or disable certain kernel features. 138 | It's not API, because it's about kernel feature sets, that 139 | make sense for specific use cases. Mostly along with programs, 140 | which would have separate nixos options. 141 | `grep features pkgs/os-specific/linux/kernel/common-config.nix` 142 | ''; 143 | 144 | 145 | }; 146 | 147 | 148 | 149 | boot.kernelPackages 150 | 151 | = 152 | 153 | mkOption 154 | 155 | { 156 | 157 | 158 | default 159 | 160 | = 161 | 162 | pkgs.linuxPackages; 163 | 164 | 165 | type 166 | 167 | = 168 | 169 | types.unspecified 170 | 171 | // 172 | 173 | { 174 | 175 | merge 176 | 177 | = 178 | 179 | mergeEqualOption; 180 | 181 | }; 182 | 183 | 184 | apply 185 | 186 | = 187 | 188 | kernelPackages: 189 | 190 | kernelPackages.extend 191 | 192 | (self: 193 | 194 | super: 195 | 196 | { 197 | 198 | 199 | kernel 200 | 201 | = 202 | 203 | super.kernel.override 204 | 205 | (originalArgs: 206 | 207 | { 208 | 209 | 210 | inherit 211 | 212 | randstructSeed; 213 | 214 | 215 | kernelPatches 216 | 217 | = 218 | 219 | (originalArgs.kernelPatches 220 | 221 | or 222 | 223 | []) 224 | 225 | ++ 226 | 227 | kernelPatches; 228 | 229 | 230 | features 231 | 232 | = 233 | 234 | lib.recursiveUpdate 235 | 236 | super.kernel.features 237 | 238 | features; 239 | 240 | 241 | }); 242 | 243 | 244 | }); 245 | 246 | 247 | # We don't want to evaluate all of linuxPackages for the manual 248 | # - some of it might not even evaluate correctly. 249 | 250 | 251 | defaultText 252 | 253 | = 254 | 255 | literalExpression 256 | 257 | "pkgs.linuxPackages"; 258 | 259 | 260 | example 261 | 262 | = 263 | 264 | literalExpression 265 | 266 | "pkgs.linuxKernel.packages.linux_5_10"; 267 | 268 | 269 | description 270 | 271 | = 272 | 273 | '' 274 | This option allows you to override the Linux kernel used by 275 | NixOS. Since things like external kernel module packages are 276 | tied to the kernel you're using, it also overrides those. 277 | This option is a function that takes Nixpkgs as an argument 278 | (as a convenience), and returns an attribute set containing at 279 | the very least an attribute kernel. 280 | Additional attributes may be needed depending on your 281 | configuration. For instance, if you use the NVIDIA X driver, 282 | then it also needs to contain an attribute 283 | nvidia_x11. 284 | ''; 285 | 286 | 287 | }; 288 | 289 | 290 | 291 | boot.kernelPatches 292 | 293 | = 294 | 295 | mkOption 296 | 297 | { 298 | 299 | 300 | type 301 | 302 | = 303 | 304 | types.listOf 305 | 306 | types.attrs; 307 | 308 | 309 | default 310 | 311 | = 312 | 313 | []; 314 | 315 | 316 | example 317 | 318 | = 319 | 320 | literalExpression 321 | 322 | "[ pkgs.kernelPatches.ubuntu_fan_4_4 ]"; 323 | description = "A list of additional patches to apply to the kernel."; 324 | }; 325 | 326 | 327 | };} 328 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/monsters_5/out.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | with lib; let 8 | inherit 9 | (config.boot) 10 | kernelPatches 11 | ; 12 | 13 | inherit 14 | (config.boot.kernel) 15 | features 16 | randstructSeed 17 | ; 18 | 19 | inherit 20 | (config.boot.kernelPackages) 21 | kernel 22 | ; 23 | 24 | kernelModulesConf = 25 | pkgs.writeText 26 | "nixos.conf" 27 | '' 28 | ${concatStringsSep "\n" config.boot.kernelModules} 29 | ''; 30 | in { 31 | ###### interface 32 | 33 | options = { 34 | boot.kernel.features = 35 | mkOption 36 | { 37 | default = {}; 38 | 39 | example = 40 | literalExpression 41 | "{debug= true;}"; 42 | 43 | internal = 44 | true; 45 | 46 | description = '' 47 | This option allows to enable or disable certain kernel features. 48 | It's not API, because it's about kernel feature sets, that 49 | make sense for specific use cases. Mostly along with programs, 50 | which would have separate nixos options. 51 | `grep features pkgs/os-specific/linux/kernel/common-config.nix` 52 | ''; 53 | }; 54 | 55 | boot.kernelPackages = 56 | mkOption 57 | { 58 | default = 59 | pkgs.linuxPackages; 60 | 61 | type = 62 | types.unspecified 63 | // { 64 | merge = 65 | mergeEqualOption; 66 | }; 67 | 68 | apply = kernelPackages: 69 | kernelPackages.extend 70 | (self: super: { 71 | kernel = 72 | super.kernel.override 73 | (originalArgs: { 74 | inherit 75 | randstructSeed 76 | ; 77 | 78 | kernelPatches = 79 | (originalArgs.kernelPatches 80 | 81 | or 82 | 83 | []) 84 | ++ kernelPatches; 85 | 86 | features = 87 | lib.recursiveUpdate 88 | super.kernel.features 89 | features; 90 | }); 91 | }); 92 | 93 | # We don't want to evaluate all of linuxPackages for the manual 94 | # - some of it might not even evaluate correctly. 95 | 96 | defaultText = 97 | literalExpression 98 | "pkgs.linuxPackages"; 99 | 100 | example = 101 | literalExpression 102 | "pkgs.linuxKernel.packages.linux_5_10"; 103 | 104 | description = '' 105 | This option allows you to override the Linux kernel used by 106 | NixOS. Since things like external kernel module packages are 107 | tied to the kernel you're using, it also overrides those. 108 | This option is a function that takes Nixpkgs as an argument 109 | (as a convenience), and returns an attribute set containing at 110 | the very least an attribute kernel. 111 | Additional attributes may be needed depending on your 112 | configuration. For instance, if you use the NVIDIA X driver, 113 | then it also needs to contain an attribute 114 | nvidia_x11. 115 | ''; 116 | }; 117 | 118 | boot.kernelPatches = 119 | mkOption 120 | { 121 | type = 122 | types.listOf 123 | types.attrs; 124 | 125 | default = []; 126 | 127 | example = 128 | literalExpression 129 | "[ pkgs.kernelPatches.ubuntu_fan_4_4 ]"; 130 | description = "A list of additional patches to apply to the kernel."; 131 | }; 132 | }; 133 | } 134 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/or_default/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (a.b or c) 3 | (a.b or/**/c) 4 | (a.b/**/or c) 5 | (a.b/**/or/**/c) 6 | (a.b/**/or/**/(a.b/**/or/**/(a.b/**/or/**/c))) 7 | (a.b/**/or/**/(a.b/**/or/**/(a.b/**/or/**/c))) 8 | ( a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a ) 9 | ( a.a or a.a # test 10 | or a.a # test 11 | or # test 12 | a.a or 13 | a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a) 14 | ] 15 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/or_default/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (a.b or c) 3 | (a.b or/**/c) 4 | (a.b/**/or c) 5 | (a.b/**/or/**/c) 6 | (a.b/**/or/**/(a.b/**/or/**/(a.b/**/or/**/c))) 7 | (a.b/**/or/**/(a.b/**/or/**/(a.b/**/or/**/c))) 8 | (a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a) 9 | (a.a or a.a # test 10 | or a.a # test 11 | or # test 12 | a.a or 13 | a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a) 14 | ] 15 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/paren/in.nix: -------------------------------------------------------------------------------- 1 | ( 2 | ( # test 3 | a # test 4 | ) 5 | ( ( c ) ) 6 | ( ( c )/*e*/) 7 | ( ( c/*d*/) ) 8 | ( ( c/*d*/)/*e*/) 9 | ( (/*b*/c ) ) 10 | ( (/*b*/c )/*e*/) 11 | ( (/*b*/c/*d*/) ) 12 | ( (/*b*/c/*d*/)/*e*/) 13 | (/*a*/( c ) ) 14 | (/*a*/( c )/*e*/) 15 | (/*a*/( c/*d*/) ) 16 | (/*a*/( c/*d*/)/*e*/) 17 | (/*a*/(/*b*/c ) ) 18 | (/*a*/(/*b*/c )/*e*/) 19 | (/*a*/(/*b*/c/*d*/) ) 20 | (/*a*/(/*b*/c/*d*/)/*e*/) 21 | ) 22 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/paren/out.nix: -------------------------------------------------------------------------------- 1 | ( 2 | ( # test 3 | a # test 4 | ) 5 | c 6 | ( 7 | c 8 | /* 9 | e 10 | */ 11 | ) 12 | ( 13 | c 14 | /* 15 | d 16 | */ 17 | ) 18 | ( 19 | ( 20 | c 21 | /* 22 | d 23 | */ 24 | ) 25 | /* 26 | e 27 | */ 28 | ) 29 | ( 30 | /* 31 | b 32 | */ 33 | c 34 | ) 35 | ( 36 | ( 37 | /* 38 | b 39 | */ 40 | c 41 | ) 42 | /* 43 | e 44 | */ 45 | ) 46 | ( 47 | /* 48 | b 49 | */ 50 | c 51 | /* 52 | d 53 | */ 54 | ) 55 | ( 56 | ( 57 | /* 58 | b 59 | */ 60 | c 61 | /* 62 | d 63 | */ 64 | ) 65 | /* 66 | e 67 | */ 68 | ) 69 | ( 70 | /* 71 | a 72 | */ 73 | c 74 | ) 75 | ( 76 | /* 77 | a 78 | */ 79 | c 80 | /* 81 | e 82 | */ 83 | ) 84 | ( 85 | /* 86 | a 87 | */ 88 | ( 89 | c 90 | /* 91 | d 92 | */ 93 | ) 94 | ) 95 | ( 96 | /* 97 | a 98 | */ 99 | ( 100 | c 101 | /* 102 | d 103 | */ 104 | ) 105 | /* 106 | e 107 | */ 108 | ) 109 | ( 110 | /* 111 | a 112 | */ 113 | ( 114 | /* 115 | b 116 | */ 117 | c 118 | ) 119 | ) 120 | ( 121 | /* 122 | a 123 | */ 124 | ( 125 | /* 126 | b 127 | */ 128 | c 129 | ) 130 | /* 131 | e 132 | */ 133 | ) 134 | ( 135 | /* 136 | a 137 | */ 138 | ( 139 | /* 140 | b 141 | */ 142 | c 143 | /* 144 | d 145 | */ 146 | ) 147 | ) 148 | ( 149 | /* 150 | a 151 | */ 152 | ( 153 | /* 154 | b 155 | */ 156 | c 157 | /* 158 | d 159 | */ 160 | ) 161 | /* 162 | e 163 | */ 164 | ) 165 | ) 166 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/pat_bind/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | ({} @ a: _) 3 | ({} @ /**/ a: _) 4 | ({} /**/ @ a: _) 5 | ({} /**/ @ /**/ a: _) 6 | 7 | (a @ {}: _) 8 | (a @ /**/ {}: _) 9 | (a /**/ @ {}: _) 10 | (a /**/ @ /**/ {}: _) 11 | ] 12 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/pat_bind/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | ({} @ a: _) 3 | ({} @ 4 | /**/ 5 | a: 6 | _) 7 | ({} 8 | /**/ 9 | @ a: 10 | _) 11 | ({} 12 | /**/ 13 | @ 14 | /**/ 15 | a: 16 | _) 17 | 18 | (a @ {}: _) 19 | (a @ 20 | /**/ 21 | {}: 22 | _) 23 | (a 24 | /**/ 25 | @ {}: 26 | _) 27 | (a 28 | /**/ 29 | @ 30 | /**/ 31 | {}: 32 | _) 33 | ] 34 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/pattern/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | ({ foo 3 | , bar 4 | # Some comment 5 | , baz 6 | }: {}) 7 | ({ foo 8 | , bar # Some comment 9 | }: {}) 10 | (a@{ 11 | self, 12 | gomod2nix, 13 | mach-nix, 14 | }: _) 15 | ({ 16 | self, 17 | gomod2nix, 18 | mach-nix, 19 | }@inp: _) 20 | ({ 21 | a ? [ 22 | 1 23 | 2 24 | 3 25 | ], 26 | b ? { 27 | # ... 28 | } 29 | }: _) 30 | ({}: _) 31 | ({ a }: _) 32 | ({ /**/ }: _) 33 | ({ ... }: _) 34 | ({ ... /**/}: _) 35 | ({ /**/ ... }: _) 36 | ({ /**/ ... /**/}: _) 37 | 38 | ({ b , e , ... }: _) 39 | ({ b , e , ... /*h*/ }: _) 40 | ({ b , e , /*g*/ ... }: _) 41 | ({ b , e , /*g*/ ... /*h*/ }: _) 42 | ({ b , e /*f*/ , ... }: _) 43 | ({ b , e /*f*/ , ... /*h*/ }: _) 44 | ({ b , e /*f*/ , /*g*/ ... }: _) 45 | ({ b , e /*f*/ , /*g*/ ... /*h*/ }: _) 46 | ({ b , /*d*/ e , ... }: _) 47 | ({ b , /*d*/ e , ... /*h*/ }: _) 48 | ({ b , /*d*/ e , /*g*/ ... }: _) 49 | ({ b , /*d*/ e , /*g*/ ... /*h*/ }: _) 50 | ({ b , /*d*/ e /*f*/ , ... }: _) 51 | ({ b , /*d*/ e /*f*/ , ... /*h*/ }: _) 52 | ({ b , /*d*/ e /*f*/ , /*g*/ ... }: _) 53 | ({ b , /*d*/ e /*f*/ , /*g*/ ... /*h*/ }: _) 54 | ({ b /*c*/ , e , ... }: _) 55 | ({ b /*c*/ , e , ... /*h*/ }: _) 56 | ({ b /*c*/ , e , /*g*/ ... }: _) 57 | ({ b /*c*/ , e , /*g*/ ... /*h*/ }: _) 58 | ({ b /*c*/ , e /*f*/ , ... }: _) 59 | ({ b /*c*/ , e /*f*/ , ... /*h*/ }: _) 60 | ({ b /*c*/ , e /*f*/ , /*g*/ ... }: _) 61 | ({ b /*c*/ , e /*f*/ , /*g*/ ... /*h*/ }: _) 62 | ({ b /*c*/ , /*d*/ e , ... }: _) 63 | ({ b /*c*/ , /*d*/ e , ... /*h*/ }: _) 64 | ({ b /*c*/ , /*d*/ e , /*g*/ ... }: _) 65 | ({ b /*c*/ , /*d*/ e , /*g*/ ... /*h*/ }: _) 66 | ({ b /*c*/ , /*d*/ e /*f*/ , ... }: _) 67 | ({ b /*c*/ , /*d*/ e /*f*/ , ... /*h*/ }: _) 68 | ({ b /*c*/ , /*d*/ e /*f*/ , /*g*/ ... }: _) 69 | ({ b /*c*/ , /*d*/ e /*f*/ , /*g*/ ... /*h*/ }: _) 70 | ({ /*a*/ b , e , ... }: _) 71 | ({ /*a*/ b , e , ... /*h*/ }: _) 72 | ({ /*a*/ b , e , /*g*/ ... }: _) 73 | ({ /*a*/ b , e , /*g*/ ... /*h*/ }: _) 74 | ({ /*a*/ b , e /*f*/ , ... }: _) 75 | ({ /*a*/ b , e /*f*/ , ... /*h*/ }: _) 76 | ({ /*a*/ b , e /*f*/ , /*g*/ ... }: _) 77 | ({ /*a*/ b , e /*f*/ , /*g*/ ... /*h*/ }: _) 78 | ({ /*a*/ b , /*d*/ e , ... }: _) 79 | ({ /*a*/ b , /*d*/ e , ... /*h*/ }: _) 80 | ({ /*a*/ b , /*d*/ e , /*g*/ ... }: _) 81 | ({ /*a*/ b , /*d*/ e , /*g*/ ... /*h*/ }: _) 82 | ({ /*a*/ b , /*d*/ e /*f*/ , ... }: _) 83 | ({ /*a*/ b , /*d*/ e /*f*/ , ... /*h*/ }: _) 84 | ({ /*a*/ b , /*d*/ e /*f*/ , /*g*/ ... }: _) 85 | ({ /*a*/ b , /*d*/ e /*f*/ , /*g*/ ... /*h*/ }: _) 86 | ({ /*a*/ b /*c*/ , e , ... }: _) 87 | ({ /*a*/ b /*c*/ , e , ... /*h*/ }: _) 88 | ({ /*a*/ b /*c*/ , e , /*g*/ ... }: _) 89 | ({ /*a*/ b /*c*/ , e , /*g*/ ... /*h*/ }: _) 90 | ({ /*a*/ b /*c*/ , e /*f*/ , ... }: _) 91 | ({ /*a*/ b /*c*/ , e /*f*/ , ... /*h*/ }: _) 92 | ({ /*a*/ b /*c*/ , e /*f*/ , /*g*/ ... }: _) 93 | ({ /*a*/ b /*c*/ , e /*f*/ , /*g*/ ... /*h*/ }: _) 94 | ({ /*a*/ b /*c*/ , /*d*/ e , ... }: _) 95 | ({ /*a*/ b /*c*/ , /*d*/ e , ... /*h*/ }: _) 96 | ({ /*a*/ b /*c*/ , /*d*/ e , /*g*/ ... }: _) 97 | ({ /*a*/ b /*c*/ , /*d*/ e , /*g*/ ... /*h*/ }: _) 98 | ({ /*a*/ b /*c*/ , /*d*/ e /*f*/ , ... }: _) 99 | ({ /*a*/ b /*c*/ , /*d*/ e /*f*/ , ... /*h*/ }: _) 100 | ({ /*a*/ b /*c*/ , /*d*/ e /*f*/ , /*g*/ ... }: _) 101 | ({ /*a*/ b /*c*/ , /*d*/ e /*f*/ , /*g*/ ... /*h*/ }: _) 102 | 103 | ({ a ? null }: _) 104 | ({ /*a*/ b /*a*/ ? /*a*/ null /*c*/ , /*d*/ e /*a*/ ? /*a*/ null /*f*/ , /*g*/ ... /*h*/ }: _) 105 | 106 | ({ 107 | /*a*/ 108 | # 109 | b 110 | /*a*/ 111 | # 112 | ? 113 | /*a*/ 114 | # 115 | null 116 | /*c*/ 117 | # 118 | , 119 | /*d*/ 120 | # 121 | e 122 | /*a*/ 123 | # 124 | ? 125 | /*a*/ 126 | # 127 | null 128 | /*f*/ 129 | # 130 | , 131 | /*g*/ 132 | # 133 | ... 134 | /*h*/ 135 | # 136 | } 137 | /*i*/ 138 | # 139 | : 140 | /*j*/ 141 | # 142 | _ 143 | ) 144 | ] 145 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/pipe_operators/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (1 |> builtins.add 2 |> builtins.mul 3) 3 | (builtins.add 1 <| builtins.mul 2 <| 3) 4 | (1 |> builtins.add 2 |> 5 | builtins.mul 3) 6 | ] 7 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/pipe_operators/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (1 |> builtins.add 2 |> builtins.mul 3) 3 | (builtins.add 1 <| builtins.mul 2 <| 3) 4 | (1 5 | |> builtins.add 2 6 | |> builtins.mul 3) 7 | ] 8 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/root/in.nix: -------------------------------------------------------------------------------- 1 | /* Some functions f 2 | name attribute. 3 | */ 4 | /* Add to or over 5 | derivation. 6 | 7 | Example: 8 | addMetaAttrs {des 9 | */ 10 | 1 11 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/root/out.nix: -------------------------------------------------------------------------------- 1 | /* 2 | Some functions f 3 | name attribute. 4 | */ 5 | /* 6 | Add to or over 7 | derivation. 8 | 9 | Example: 10 | addMetaAttrs {des 11 | */ 12 | 1 13 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/select/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (a . a) 3 | (a ./**/a) 4 | (a/**/. a) 5 | (a/**/./**/a) 6 | ( a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a ) 7 | ( a.a 8 | .a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a ) 9 | ] 10 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/select/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (a . a) 3 | (a ./**/a) 4 | (a/**/. a) 5 | (a/**/./**/a) 6 | (a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a) 7 | (a.a 8 | .a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a) 9 | ] 10 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/string/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | '' 3 | foo 4 |  bar 5 | '' 6 | "" 7 | ### 8 | " 9 | " 10 | ### 11 | "a 12 | ${x} 13 | b 14 | " 15 | ### 16 | '''' 17 | ### 18 | ''a'' 19 | ### 20 | ''${""}'' 21 | ### 22 | ''${""} 23 | 24 | '' 25 | ### 26 | ''a 27 | '' 28 | ### 29 | ''a 30 | 31 | '' 32 | ### 33 | '' a 34 | '' 35 | ### 36 | 37 | ''a 38 | '' 39 | ### 40 | '' 41 | a 42 | ${""} 43 | b 44 | ${""} 45 | c ${""} d 46 | e 47 | '' 48 | ### 49 | '' 50 | '' 51 | ### 52 | '' 53 | declare -a makefiles=(./*.mak) 54 | sed -i -f ${makefile-sed} "''${makefiles[@]}" 55 | ### assign Makefile variables eagerly & change backticks to `$(shell …)` 56 | sed -i -e 's/ = `\([^`]\+\)`/ := $(shell \1)/' \ 57 | -e 's/`\([^`]\+\)`/$(shell \1)/' \ 58 | "''${makefiles[@]}" 59 | '' 60 | ### 61 | '' 62 | [${ mkSectionName sectName }] 63 | '' 64 | ### 65 | ''-couch_ini ${ cfg.package }/etc/default.ini ${ configFile } ${ pkgs.writeText "couchdb-extra.ini" cfg.extraConfig } ${ cfg.configFile }'' 66 | ### 67 | ''exec i3-input -F "mark %s" -l 1 -P 'Mark: ' '' 68 | ### 69 | ''exec i3-input -F '[con_mark="%s"] focus' -l 1 -P 'Go to: ' '' 70 | ### 71 | ''"${ pkgs.name or "" }";'' 72 | ### 73 | '' 74 | ${pkgs.replace-secret}/bin/replace-secret '${placeholder}' '${secretFile}' '${targetFile}' '' 75 | ### 76 | '' 77 | mkdir -p "$out/lib/modules/${ kernel.modDirVersion }/kernel/net/wireless/" 78 | '' 79 | ### 80 | '' 81 | 82 | 83 | ${ expr "" v } 84 | '' 85 | 86 | '' 87 | --${ 88 | "test" 89 | } 90 | '' 91 | 92 | "--${ 93 | "test" 94 | }" 95 | ] 96 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/string/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | '' 3 | foo 4 | bar 5 | '' 6 | "" 7 | ### 8 | " 9 | " 10 | ### 11 | "a 12 | ${x} 13 | b 14 | " 15 | ### 16 | '''' 17 | ### 18 | ''a'' 19 | ### 20 | ''${""}'' 21 | ### 22 | '' ${""} 23 | 24 | '' 25 | ### 26 | '' a 27 | '' 28 | ### 29 | '' a 30 | 31 | '' 32 | ### 33 | '' a 34 | '' 35 | ### 36 | 37 | '' a 38 | '' 39 | ### 40 | '' 41 | a 42 | ${""} 43 | b 44 | ${""} 45 | c ${""} d 46 | e 47 | '' 48 | ### 49 | '' 50 | '' 51 | ### 52 | '' 53 | declare -a makefiles=(./*.mak) 54 | sed -i -f ${makefile-sed} "''${makefiles[@]}" 55 | ### assign Makefile variables eagerly & change backticks to `$(shell …)` 56 | sed -i -e 's/ = `\([^`]\+\)`/ := $(shell \1)/' \ 57 | -e 's/`\([^`]\+\)`/$(shell \1)/' \ 58 | "''${makefiles[@]}" 59 | '' 60 | ### 61 | '' 62 | [${mkSectionName sectName}] 63 | '' 64 | ### 65 | ''-couch_ini ${cfg.package}/etc/default.ini ${configFile} ${pkgs.writeText "couchdb-extra.ini" cfg.extraConfig} ${cfg.configFile}'' 66 | ### 67 | ''exec i3-input -F "mark %s" -l 1 -P 'Mark: ' '' 68 | ### 69 | ''exec i3-input -F '[con_mark="%s"] focus' -l 1 -P 'Go to: ' '' 70 | ### 71 | ''"${pkgs.name or ""}";'' 72 | ### 73 | '' 74 | ${pkgs.replace-secret}/bin/replace-secret '${placeholder}' '${secretFile}' '${targetFile}' '' 75 | ### 76 | '' 77 | mkdir -p "$out/lib/modules/${kernel.modDirVersion}/kernel/net/wireless/" 78 | '' 79 | ### 80 | '' 81 | 82 | 83 | ${expr "" v} 84 | '' 85 | 86 | '' 87 | --${"test"} 88 | '' 89 | 90 | "--${"test"}" 91 | ] 92 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/string_interpol/in.nix: -------------------------------------------------------------------------------- 1 | "${/*a*/"${/*b*/"${c}"}"/*d*/}" 2 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/string_interpol/out.nix: -------------------------------------------------------------------------------- 1 | "${ 2 | /* 3 | a 4 | */ 5 | "${ 6 | /* 7 | b 8 | */ 9 | "${c}" 10 | }" 11 | /* 12 | d 13 | */ 14 | }" 15 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/with/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (with b; c) 3 | (with b; /*b*/ c) 4 | (with /*a*/ b; c) 5 | (with /*a*/ b; /*b*/ c) 6 | ( with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ) 7 | ( with b; 8 | cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ) 9 | { a = with b; 1;} 10 | { a = with b; 1 + 1;} 11 | { a = with b; {c=1;};} 12 | { a = with b; {c=1; d=2; e=3;};} 13 | { a = with b; 14 | # comment 15 | 1; 16 | } 17 | { a = with b; 18 | 1; 19 | # comment 20 | } 21 | (with a; with b; with c; {a=1;}) 22 | (with a; with b; with c; {a=1;b=2;}) 23 | (with a; /* comment */ with b; with c; {a=1;b=2;}) 24 | { a = with b;with b;with b; 25 | 1; 26 | } 27 | { 28 | binPath = 29 | with pkgs; 30 | makeBinPath ( 31 | [ 32 | rsync 33 | util-linux]);} 34 | ] 35 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/default/with/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | (with b; c) 3 | (with b; 4 | /* 5 | b 6 | */ 7 | c) 8 | (with 9 | /* 10 | a 11 | */ 12 | b; c) 13 | (with 14 | /* 15 | a 16 | */ 17 | b; 18 | /* 19 | b 20 | */ 21 | c) 22 | (with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) 23 | (with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) 24 | {a = with b; 1;} 25 | {a = with b; 1 + 1;} 26 | {a = with b; {c = 1;};} 27 | { 28 | a = with b; { 29 | c = 1; 30 | d = 2; 31 | e = 3; 32 | }; 33 | } 34 | { 35 | a = with b; 36 | # comment 37 | 1; 38 | } 39 | { 40 | a = with b; 1; 41 | # comment 42 | } 43 | (with a; with b; with c; {a = 1;}) 44 | (with a; 45 | with b; 46 | with c; { 47 | a = 1; 48 | b = 2; 49 | }) 50 | (with a; 51 | /* 52 | comment 53 | */ 54 | with b; 55 | with c; { 56 | a = 1; 57 | b = 2; 58 | }) 59 | { 60 | a = with b; with b; with b; 1; 61 | } 62 | { 63 | binPath = with pkgs; 64 | makeBinPath [ 65 | rsync 66 | util-linux 67 | ]; 68 | } 69 | ] 70 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/indentation-four-spaces/string/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | '' 3 | foo 4 | bar 5 | '' 6 | ] 7 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/indentation-four-spaces/string/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | '' 3 | foo 4 | bar 5 | '' 6 | ] 7 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/indentation-tabs/apply/in.nix: -------------------------------------------------------------------------------- 1 | { 2 | foo = 3 | bar: 4 | baz: 5 | fnbody; 6 | } 7 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/indentation-tabs/apply/out.nix: -------------------------------------------------------------------------------- 1 | { 2 | foo = bar: baz: 3 | fnbody; 4 | } 5 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/indentation-tabs/attr-set/in.nix: -------------------------------------------------------------------------------- 1 | { 2 | a = rec { 3 | a = { 4 | a = rec { 5 | a = { 6 | a = rec {a = {a = rec {a = {a = rec {a = {};};};};};}; 7 | }; 8 | }; 9 | }; 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/indentation-tabs/attr-set/out.nix: -------------------------------------------------------------------------------- 1 | { 2 | a = rec { 3 | a = { 4 | a = rec { 5 | a = { 6 | a = rec {a = {a = rec {a = {a = rec {a = {};};};};};}; 7 | }; 8 | }; 9 | }; 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/indentation-tabs/list/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | # over indented 3 | 1 4 | # under indented 5 | 2 6 | # no indentation 7 | [1 2] 8 | [ 9 | 1 2 3 10 | ] 11 | ] 12 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/indentation-tabs/list/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | # over indented 3 | 1 4 | # under indented 5 | 2 6 | # no indentation 7 | [1 2] 8 | [ 9 | 1 10 | 2 11 | 3 12 | ] 13 | ] 14 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/indentation-tabs/string/in.nix: -------------------------------------------------------------------------------- 1 | [ 2 | '' 3 | foo 4 | bar 5 | '' 6 | ] 7 | -------------------------------------------------------------------------------- /src/alejandra/tests/cases/indentation-tabs/string/out.nix: -------------------------------------------------------------------------------- 1 | [ 2 | '' 3 | foo 4 | bar 5 | '' 6 | ] 7 | -------------------------------------------------------------------------------- /src/alejandra/tests/fmt.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::io::Write; 3 | use std::path::PathBuf; 4 | 5 | use alejandra::config::Config; 6 | use alejandra::config::Indentation; 7 | use pretty_assertions::assert_eq; 8 | 9 | #[test] 10 | fn cases() { 11 | let should_update = std::env::var("UPDATE").is_ok(); 12 | 13 | let configs = HashMap::from([ 14 | ("default", Config::default()), 15 | ("indentation-four-spaces", Config { 16 | indentation: Indentation::FourSpaces, 17 | }), 18 | ("indentation-tabs", Config { indentation: Indentation::Tabs }), 19 | ]); 20 | 21 | let cases_path = PathBuf::new().join("tests").join("cases"); 22 | 23 | for (config_name, config) in configs { 24 | let config_cases_path = cases_path.join(config_name); 25 | 26 | std::fs::create_dir_all(&config_cases_path).unwrap(); 27 | 28 | let cases: Vec = std::fs::read_dir(&config_cases_path) 29 | .unwrap() 30 | .map(|entry| entry.unwrap().file_name().into_string().unwrap()) 31 | .collect(); 32 | 33 | for case in cases { 34 | let case_path = config_cases_path.join(&case); 35 | 36 | let path_in = case_path.join("in.nix"); 37 | let content_in = std::fs::read_to_string(&path_in).unwrap(); 38 | 39 | let path_out = case_path.join("out.nix"); 40 | let content_got = alejandra::format::in_memory( 41 | path_in.to_str().unwrap().to_owned(), 42 | content_in.clone(), 43 | config, 44 | ) 45 | .1; 46 | 47 | if should_update { 48 | std::fs::File::create(&path_out) 49 | .unwrap() 50 | .write_all(content_got.as_bytes()) 51 | .unwrap(); 52 | } 53 | 54 | let content_out = std::fs::read_to_string(&path_out).unwrap(); 55 | 56 | assert_eq!( 57 | content_out, content_got, 58 | "Test case `{:?}` failed", 59 | case_path 60 | ); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/alejandra_cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [[bin]] 2 | name = "alejandra" 3 | path = "src/main.rs" 4 | 5 | [dependencies] 6 | alejandra = { path = "../alejandra" } 7 | clap = { version = "*", default-features = false, features = [ 8 | "color", 9 | "derive", 10 | "env", 11 | "std", 12 | "strsim", 13 | ] } 14 | futures = { version = "*", default-features = false, features = [ 15 | "executor", 16 | "thread-pool", 17 | ] } 18 | num_cpus = { version = "*", default-features = false, features = [] } 19 | rand = { version = "*", default-features = false, features = [ 20 | "alloc", 21 | "getrandom", 22 | ] } 23 | toml = { version = "*", default-features = false, features = ["parse"] } 24 | walkdir = { version = "*", default-features = false, features = [] } 25 | 26 | [package] 27 | authors = ["Kevin Amado "] 28 | description = "The Uncompromising Nix Code Formatter" 29 | edition = "2021" 30 | license = "Unlicense" 31 | name = "alejandra_cli" 32 | repository = "https://github.com/kamadorueda/alejandra" 33 | version = "4.0.0" 34 | 35 | [dev-dependencies] 36 | pretty_assertions = "1.3.0" 37 | -------------------------------------------------------------------------------- /src/alejandra_cli/src/ads/contributor_thanks.txt: -------------------------------------------------------------------------------- 1 | 👏 Special thanks to {name} for helping improve this project: https://github.com/{github} 2 | -------------------------------------------------------------------------------- /src/alejandra_cli/src/ads/mod.rs: -------------------------------------------------------------------------------- 1 | use rand::distributions::weighted::WeightedIndex; 2 | use rand::distributions::Distribution; 3 | use rand::rngs::OsRng; 4 | 5 | pub(crate) fn random_ad() -> String { 6 | let ads = [ 7 | // 90% distributed proportional to total past and present contributions 8 | (0.9001, sponsor_benefits as fn() -> String), 9 | // 10% is reserved for everything else 10 | (0.0333, contributor_thanks as fn() -> String), 11 | (0.0333, please_sponsor as fn() -> String), 12 | (0.0333, please_star as fn() -> String), 13 | ]; 14 | 15 | random_weighted_choice(&ads[..])() 16 | } 17 | 18 | fn sponsor_benefits() -> String { 19 | let sponsors = [ 20 | // Proportional to total past and present contributions 21 | (0.0316, "Guangtao Zhang"), 22 | (0.0372, "Fabio Leimgruber"), 23 | (0.0633, "Raphael Megzari"), 24 | (0.1215, "Daniel Salazar"), 25 | (0.6642, "https://mercury.com"), 26 | (0.0633, "https://shop.beekeeb.com/"), 27 | (0.0063, "Murat Cabuk"), 28 | (0.0127, "Pavel Roskin"), 29 | ]; 30 | 31 | let name = random_weighted_choice(&sponsors[..]); 32 | 33 | include_str!("sponsor_thanks.txt").replace("{name}", name) 34 | } 35 | 36 | fn contributor_thanks() -> String { 37 | let names = [ 38 | (1.0, ("Bobbe", "30350n")), 39 | (1.0, ("Connor Baker", "ConnorBaker")), 40 | (1.0, ("Daniel Bast", "dbast")), 41 | (1.0, ("David Arnold", "blaggacao")), 42 | (1.0, ("David Hauer", "DavHau")), 43 | (1.0, ("esf", "exscientiafortis")), 44 | (1.0, ("Fabian Möller", "B4dM4n")), 45 | (1.0, ("Florian Finkernagel", "TyberiusPrime")), 46 | (1.0, ("Jamie Quigley", "Sciencentistguy")), 47 | (1.0, ("Joachim Ernst", "0x4A6F")), 48 | (1.0, ("Johannes Kirschbauer", "hsjobeki")), 49 | (1.0, ("Jörg Thalheim", "Mic92")), 50 | (1.0, ("Kevin Amado", "kamadorueda")), 51 | (1.0, ("Loïc Reynier", "loicreynier")), 52 | (1.0, ("Matthew Kenigsberg", "mkenigs")), 53 | (1.0, ("Michael Utz ", "theutz")), 54 | (1.0, ("Mr Hedgehog", "ModdedGamers")), 55 | (1.0, ("Nathan Henrie", "n8henrie")), 56 | (1.0, ("Norbert Melzer", "NobbZ")), 57 | (1.0, ("Pablo Ovelleiro Corral", "pinpox")), 58 | (1.0, ("Patrick Stevens", "Smaug123")), 59 | (1.0, ("Piegames", "piegamesde")), 60 | (1.0, ("Rebecca Turner", "9999years")), 61 | (1.0, ("Rehno Lindeque", "rehno-lindeque")), 62 | (1.0, ("Rok Garbas", "garbas")), 63 | (1.0, ("Ryan Mulligan", "ryantm")), 64 | (1.0, ("Thomas Bereknyei", "tomberek")), 65 | (1.0, ("Tobias Bora", "tobiasBora")), 66 | (1.0, ("Tristan Maat", "TLATER")), 67 | (1.0, ("UserSv4", "UserSv4")), 68 | (1.0, ("Victor Engmark", "l0b0")), 69 | (1.0, ("Vincent Ambo", "tazjin")), 70 | (1.0, ("Vladimir Fetisov", "3timeslazy")), 71 | (1.0, ("Yorick van Pelt", "yorickvP")), 72 | ]; 73 | 74 | let (name, github) = random_weighted_choice(&names[..]); 75 | 76 | include_str!("contributor_thanks.txt") 77 | .replace("{github}", github) 78 | .replace("{name}", name) 79 | } 80 | 81 | fn please_sponsor() -> String { 82 | include_str!("please_sponsor.txt").to_string() 83 | } 84 | 85 | fn please_star() -> String { 86 | include_str!("please_star.txt").to_string() 87 | } 88 | 89 | fn random_weighted_choice(choices: &[(f64, T)]) -> &T { 90 | let weights = choices.iter().map(|(weight, _)| *weight); 91 | let index: usize = WeightedIndex::new(weights).unwrap().sample(&mut OsRng); 92 | 93 | &choices[index].1 94 | } 95 | -------------------------------------------------------------------------------- /src/alejandra_cli/src/ads/please_sponsor.txt: -------------------------------------------------------------------------------- 1 | 🤟 If Alejandra is useful to you, please consider sponsoring its author: https://github.com/sponsors/kamadorueda 2 | -------------------------------------------------------------------------------- /src/alejandra_cli/src/ads/please_star.txt: -------------------------------------------------------------------------------- 1 | ⭐ If Alejandra is useful to you, please add your star to the repository: https://github.com/kamadorueda/alejandra 2 | -------------------------------------------------------------------------------- /src/alejandra_cli/src/ads/sponsor_thanks.txt: -------------------------------------------------------------------------------- 1 | 👏 Special thanks to {name} for being a sponsor of Alejandra! 2 | -------------------------------------------------------------------------------- /src/alejandra_cli/src/find.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashSet; 2 | use std::process::exit; 3 | 4 | pub(crate) fn nix_files(include: &[&str], exclude: &[String]) -> Vec { 5 | let include: HashSet<_> = 6 | include.iter().flat_map(|s| nix_files_in_path(s)).collect(); 7 | let exclude: HashSet<_> = 8 | exclude.iter().flat_map(|s| nix_files_in_path(s)).collect(); 9 | 10 | let mut paths: Vec<_> = include 11 | .difference(&exclude) 12 | .cloned() 13 | .map(|path| (len_of(&path), path)) 14 | .collect(); 15 | 16 | paths.sort_unstable_by(|(len_a, _), (len_b, _)| len_b.cmp(len_a)); 17 | 18 | paths.into_iter().map(|(_, path)| path).collect() 19 | } 20 | 21 | fn nix_files_in_path(path: &str) -> HashSet { 22 | walkdir::WalkDir::new(path) 23 | .into_iter() 24 | .filter_entry(is_nix_file_or_dir) 25 | .filter_map(|entry| match entry { 26 | Ok(entry) => Some(entry), 27 | Err(_) => None, 28 | }) 29 | .filter(is_nix_file) 30 | .map(to_full_path) 31 | .collect() 32 | } 33 | 34 | fn is_nix_file(entry: &walkdir::DirEntry) -> bool { 35 | entry.file_type().is_file() 36 | && entry.file_name().to_str().unwrap().ends_with(".nix") 37 | } 38 | 39 | fn is_nix_file_or_dir(entry: &walkdir::DirEntry) -> bool { 40 | entry.file_type().is_dir() || is_nix_file(entry) 41 | } 42 | 43 | fn to_full_path(entry: walkdir::DirEntry) -> String { 44 | entry.path().to_str().unwrap().to_string() 45 | } 46 | 47 | fn len_of(path: &str) -> u64 { 48 | match std::fs::metadata(path) { 49 | Ok(meta) => meta.len(), 50 | Err(err) => { 51 | eprintln!("Could not get the size of file at: {path}"); 52 | eprintln!("Got error: {err}"); 53 | exit(1); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/alejandra_cli/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod ads; 2 | pub mod cli; 3 | mod find; 4 | mod verbosity; 5 | -------------------------------------------------------------------------------- /src/alejandra_cli/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() -> std::io::Result<()> { 2 | alejandra_cli::cli::main() 3 | } 4 | -------------------------------------------------------------------------------- /src/alejandra_cli/src/verbosity.rs: -------------------------------------------------------------------------------- 1 | #[derive(Clone, Copy)] 2 | pub(crate) enum Verbosity { 3 | Everything, 4 | NoInfo, 5 | NoErrors, 6 | } 7 | 8 | impl Verbosity { 9 | pub(crate) fn allows_info(&self) -> bool { 10 | matches!(self, Verbosity::Everything) 11 | } 12 | 13 | pub(crate) fn allows_errors(&self) -> bool { 14 | self.allows_info() || matches!(self, Verbosity::NoInfo) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/alejandra_cli/tests/configs/empty_config.toml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamadorueda/alejandra/33cb45569dfb22d4cc3c3fa859ee9b7baf1fa38f/src/alejandra_cli/tests/configs/empty_config.toml -------------------------------------------------------------------------------- /src/alejandra_cli/tests/configs/wrong_key.toml: -------------------------------------------------------------------------------- 1 | asdf = "asdf" 2 | -------------------------------------------------------------------------------- /src/alejandra_cli/tests/inputs/changed.nix: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /src/alejandra_cli/tests/inputs/error.nix: -------------------------------------------------------------------------------- 1 | [ -------------------------------------------------------------------------------- /src/alejandra_cli/tests/inputs/unchanged.nix: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /treefmt.toml: -------------------------------------------------------------------------------- 1 | [formatter] 2 | 3 | [formatter.nix] 4 | command = "cargo" 5 | includes = ["*.nix"] 6 | excludes = ["./src/alejandra/tests/cases/**"] 7 | options = ["run", "--"] 8 | 9 | [formatter.prettier] 10 | command = "prettier" 11 | includes = ["*.html", "*.js", "*.json", "*.md", "*.toml", "*.yaml"] 12 | options = ["--plugin", "prettier-plugin-toml", "--write"] 13 | 14 | [formatter.rust] 15 | command = "rustfmt" 16 | includes = ["*.rs"] 17 | 18 | [formatter.shell] 19 | command = "shfmt" 20 | includes = ["*.sh"] 21 | options = ["-bn", "-ci", "-sr", "-i", "2", "-s", "-w"] 22 | --------------------------------------------------------------------------------