8000 GitHub - NixOS/nixfmt: The official (but not yet stable) formatter for Nix code
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
/ nixfmt Public

The official (but not yet stable) formatter for Nix code

License

Notifications You must be signed in to change notification settings
8000

NixOS/nixfmt

nixfmt

nixfmt is the official formatter for Nix language code, intended to easily apply a uniform style.

Build Status

State

nixfmt was originally developed by Serokell. It was used as the basis for the official standardised Nix formatter, as established by RFC 166.

The official standard differs considerably from the original implementation. Be aware of this if you track the master branch. Until the next release, expect nixfmt to change.

A recent version of nixfmt is available as pkgs.nixfmt-rfc-style in Nixpkgs. The original nixfmt is still available as pkgs.nixfmt-classic, but it is unmaintained and will eventually be removed.

For more details, see the RFC implementation tracking issue.

Installation

Note

nixfmt can only process one file at a time. Consider using a configuration helper for formatting a project.

In the environment

NixOS

To install nixfmt on NixOS for all users, add it to the environment.systemPackages configuration option:

{ pkgs, ... }:
{
  environment.systemPackages = [ pkgs.nixfmt-rfc-style ];
}

To install it on NixOS for a particular user, add it to the users.users.<user>.packages configuration option:

{ pkgs, ... }:
{
  users.users.example-user-name.packages = [ pkgs.nixfmt-rfc-style ];
}

Home Manager

To install nixfmt in Home Manager, add it adding to the home.packages configuration option:

{ pkgs, ... }:
{
  home.packages = [ pkgs.nixfmt-rfc-style ];
}

Declarative shell environment

To make nixfmt available in a shell environment invoked with nix-shell, add it to the packages argument of mkShell:

{ pkgs }:
pkgs.mkShellNoCC {
  packages = [ pkgs.nixfmt-rfc-style ];
}

In an editor

neovim + nixd

local nvim_lsp = require("lspconfig")
nvim_lsp.nixd.setup({
   settings = {
      nixd = {
         formatting = {
            command = { "nixfmt" },
         },
      },
   },
})

Note

This only works when nixfmt is available in the environment.

neovim + nil

local nvim_lsp = require("lspconfig")
nvim_lsp.nil_ls.setup({
   settings = {
      ['nil'] = {
         formatting = {
            command = { "nixfmt" },
         },
      },
   },
})

Note

This only works when nixfmt is available in the environment.

neovim + none-ls

local null_ls = require("null-ls")
null_ls.setup({
    sources = {
        null_ls.builtins.formatting.nixfmt,
    },
})

Note

This only works when nixfmt is available in the environment.

In a project

treefmt-nix

treefmt-nix automatically configures the correct packages and formatters for treefmt using the Nix language, and has native support for nixfmt:

{ pkgs, treefmt-nix }:
treefmt-nix.mkWrapper pkgs {
  programs.nixfmt.enable = true;
};

treefmt

treefmt can also be used directly:

# treefmt.toml
[formatter.nixfmt-rfc-style]
command = "nixfmt"
includes = ["*.nix"]

Note

This only works when nixfmt is available in the environment.

git-hooks.nix

git-hooks.nix can automatically configure Git hooks like pre-commit using the Nix language, and has native support for nixfmt:

{ pkgs, git-hooks }:
{
  pre-commit-check = git-hooks.run {
    hooks = {
      nixfmt-rfc-style.enable = true;
    };
  };
  shell = pkgs.mkShellNoCC {
    packages = [ pre-commit-check.enabledPackages ];
    shellHook = ''
      ${pre-commit-check.shellHook}
    '';
  };
}

pre-commit

pre-commit can also be used directly:

  1. Make sure that you have the pre-commit command:

    $ pre-commit --version
    pre-commit 3.7.1
  2. Make sure that you’re in your Git repo:

    $ cd <path-to-git-repo>
  3. Make sure that the pre-commit tool is installed as a Git pre-commit hook:

    $ pre-commit install
    pre-commit installed at .git/hooks/pre-commit
  4. If you don’t already have one, then create a .pre-commit-config.yaml file.

  5. Add an entry for the nixfmt hook to your .pre-commit-config.yaml file:

    repos:
        - repo: https://github.com/NixOS/nixfmt
          rev: <version>
          hooks:
                - id: nixfmt

    If you want to use a stable version of nixfmt, then replace <version> with a tag from this repo. If you want to use an unstable version of nixfmt, then replace <version> with a commit hash from this repo.

  6. Try to commit a badly formatted Nix file in order to make sure that everything works.

Warning

nixfmt’s integration with the pre-commit tool is relatively new. At the moment, none of the stable releases of nixfmt can be used with the pre-commit tool. You’ll have to use an unstable version for the time being.

git mergetool

nixfmt provides a mode usable by git mergetool via --mergetool that allows resolving formatting-related conflicts automatically in many cases.

It can be installed by any of these methods:

  • For only for the current repo, run:
    git config mergetool.nixfmt.cmd 'nixfmt --mergetool "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
    git config mergetool.nixfmt.trustExitCode true
    
  • For all repos with a mutable config file, run
    git config --global mergetool.nixfmt.cmd 'nixfmt --mergetool "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
    git config --global mergetool.nixfmt.trustExitCode true
    
  • For all repos with a NixOS-provided config file, add this to your configuration.nix:
    programs.git.config = {
      mergetool.nixfmt = {
        cmd = "nixfmt --mergetool \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"";
        trustExitCode = true;
      };
    };
  • For all repos with a home-manager-provided config file, add this to your home.nix:
    programs.git.extraConfig = {
      mergetool.nixfmt = {
        cmd = "nixfmt --mergetool \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"";
        trustExitCode = true;
      };
    };

Then, when git merge or git rebase fails, run

git mergetool -t nixfmt .
# or, only for some specific files
git mergetool -t nixfmt FILE1 FILE2 FILE3

and some .nix files will probably get merged automagically.

Note that files that git merges successfully even before git mergetool will be ignored by `git mergetool`.

If you don't like the result, run

git restore --merge .
# or, only for some specific files
git restore --merge FILE1 FILE2 FILE3

to return back to the unmerged state.

nix fmt (experimental)

nix fmt (part of the flakes experimental feature) can be configured to use nixfmt by setting the formatter flake output to the respective package (assuming a nixpkgs flake input exists):

# flake.nix
{
  outputs =
    { nixpkgs, self }:
    {
      formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.nixfmt-rfc-style;
    };
}

Development

With Nix

Haskell dependencies will be built by Nix.

  • Enter nix-shell
  • Build with cabal new-build

Without Nix

Haskell dependencies will be built by Cabal.

  • Build with cabal new-build

Usage

  • nixfmt < input.nix – reads Nix code from stdin, formats it, and outputs to stdout
  • nixfmt file.nix – format the file in place

About Serokell

nixfmt is maintained and funded with ❤️ by Serokell. The names and logo for Serokell are trademark of Serokell OÜ.

We love open source software! See our other projects or hire us to design, develop and grow your idea!

0