Coding conventions
Syntax
Use 2 spaces of indentation per indentation level in
Nix expressions, 4 spaces in shell scripts.
Do not use tab characters, i.e. configure your
editor to use soft tabs. For instance, use (setq-default
indent-tabs-mode nil) in Emacs. Everybody has different
tab settings so it’s asking for trouble.
Use lowerCamelCase for variable
names, not UpperCamelCase. TODO: naming of
attributes in
all-packages.nix?
Function calls with attribute set arguments are
written as
foo {
arg = ...;
}
not
foo
{
arg = ...;
}
Also fine is
foo { arg = ...; }
if it's a short call.
In attribute sets or lists that span multiple lines,
the attribute names or list elements should be aligned:
# A long list.
list =
[ elem1
elem2
elem3
];
# A long attribute set.
attrs =
{ attr1 = short_expr;
attr2 =
if true then big_expr else big_expr;
};
# Alternatively:
attrs = {
attr1 = short_expr;
attr2 =
if true then big_expr else big_expr;
};
Short lists or attribute sets can be written on one
line:
# A short list.
list = [ elem1 elem2 elem3 ];
# A short set.
attrs = { x = 1280; y = 1024; };
Breaking in the middle of a function argument can
give hard-to-read code, like
someFunction { x = 1280;
y = 1024; } otherArg
yetAnotherArg
(especially if the argument is very large, spanning multiple
lines).
Better:
someFunction
{ x = 1280; y = 1024; }
otherArg
yetAnotherArg
or
let res = { x = 1280; y = 1024; };
in someFunction res otherArg yetAnotherArg
The bodies of functions, asserts, and withs are not
indented to prevent a lot of superfluous indentation levels, i.e.
{ arg1, arg2 }:
assert system == "i686-linux";
stdenv.mkDerivation { ...
not
{ arg1, arg2 }:
assert system == "i686-linux";
stdenv.mkDerivation { ...
Function formal arguments are written as:
{ arg1, arg2, arg3 }:
but if they don't fit on one line they're written as:
{ arg1, arg2, arg3
, arg4, ...
, # Some comment...
argN
}:
Functions should list their expected arguments as
precisely as possible. That is, write
{ stdenv, fetchurl, perl }: ...
instead of
args: with args; ...
or
{ stdenv, fetchurl, perl, ... }: ...
For functions that are truly generic in the number of
arguments (such as wrappers around mkDerivation)
that have some required arguments, you should write them using an
@-pattern:
{ stdenv, doCoverageAnalysis ? false, ... } @ args:
stdenv.mkDerivation (args // {
... if doCoverageAnalysis then "bla" else "" ...
})
instead of
args:
args.stdenv.mkDerivation (args // {
... if args ? doCoverageAnalysis && args.doCoverageAnalysis then "bla" else "" ...
})
File naming and organisation
Names of files and directories should be in lowercase, with
dashes between words — not in camel case. For instance, it should be
all-packages.nix, not
allPackages.nix or
AllPackages.nix.
Each package should be stored in its own directory somewhere in
the pkgs/ tree, i.e. in
pkgs/category/subcategory/.../pkgname.
Below are some rules for picking the right category for a package.
Many packages fall under several categories; what matters is the
primary purpose of a package. For example, the
libxml2 package builds both a library and some
tools; but it’s a library foremost, so it goes under
pkgs/development/libraries.
When in doubt, consider refactoring the
pkgs/ tree, e.g. creating new categories or
splitting up an existing category.
If it’s used to support software development:
If it’s a library used by other packages:
development/libraries (e.g. libxml2)
If it’s a compiler:
development/compilers (e.g. gcc)
If it’s an interpreter:
development/interpreters (e.g. guile)
If it’s a (set of) development tool(s):
If it’s a parser generator (including lexers):
development/tools/parsing (e.g. bison, flex)
If it’s a build manager:
development/tools/build-managers (e.g. gnumake)
Else:
development/tools/misc (e.g. binutils)
Else:
development/misc
If it’s a (set of) tool(s):
(A tool is a relatively small program, especially one intented
to be used non-interactively.)
If it’s for networking:
tools/networking (e.g. wget)
If it’s for text processing:
tools/text (e.g. diffutils)
If it’s a system utility, i.e.,
something related or essential to the operation of a
system:
tools/system (e.g. cron)
If it’s an archiver (which may
include a compression function):
tools/archivers (e.g. zip, tar)
If it’s a compression program:
tools/compression (e.g. gzip, bzip2)
If it’s a security-related program:
tools/security (e.g. nmap, gnupg)
Else:
tools/misc
If it’s a shell:
shells (e.g. bash)
If it’s a server:
If it’s a web server:
servers/http (e.g. apache-httpd)
If it’s an implementation of the X Windowing System:
servers/x11 (e.g. xorg — this includes the client libraries and programs)
Else:
servers/misc
If it’s a desktop environment
(including window managers):
desktops (e.g. kde, gnome, enlightenment)
If it’s an application:
A (typically large) program with a distinct user
interface, primarily used interactively.
If it’s a version management system:
applications/version-management (e.g. subversion)
If it’s for video playback / editing:
applications/video (e.g. vlc)
If it’s for graphics viewing / editing:
applications/graphics (e.g. gimp)
If it’s for networking:
If it’s a mailreader:
applications/networking/mailreaders (e.g. thunderbird)
If it’s a newsreader:
applications/networking/newsreaders (e.g. pan)
If it’s a web browser:
applications/networking/browsers (e.g. firefox)
Else:
applications/networking/misc
Else:
applications/misc
If it’s data (i.e., does not have a
straight-forward executable semantics):
If it’s a font:
data/fonts
If it’s related to SGML/XML processing:
If it’s an XML DTD:
data/sgml+xml/schemas/xml-dtd (e.g. docbook)
If it’s an XSLT stylesheet:
(Okay, these are executable...)
data/sgml+xml/stylesheets/xslt (e.g. docbook-xsl)
If it’s a game:
games
Else:
misc