mirror of
https://github.com/nix-community/home-manager
synced 2024-12-23 18:29:47 +01:00
Initial import
This commit is contained in:
parent
e4c63eb66a
commit
d7d02c3ce8
26 changed files with 1749 additions and 0 deletions
2
default.nix
Normal file
2
default.nix
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Simply defer to the home-manager script derivation.
|
||||
import ./home-manager
|
39
home-manager/default.nix
Normal file
39
home-manager/default.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{ pkgs }:
|
||||
|
||||
let
|
||||
|
||||
homeManagerExpr = pkgs.writeText "home-manager.nix" ''
|
||||
{ pkgs ? import <nixpkgs> {}, confPath, modulesPath }:
|
||||
|
||||
let
|
||||
env = import modulesPath {
|
||||
configuration = import confPath;
|
||||
pkgs = pkgs;
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit (env) activation-script;
|
||||
}
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "home-manager";
|
||||
|
||||
phases = [ "installPhase" ];
|
||||
|
||||
installPhase = ''
|
||||
install -v -D -m755 ${./home-manager} $out/bin/home-manager
|
||||
|
||||
substituteInPlace $out/bin/home-manager \
|
||||
--subst-var-by bash "${pkgs.bash}" \
|
||||
--subst-var-by HOME_MANAGER_EXPR_PATH "${homeManagerExpr}"
|
||||
'';
|
||||
|
||||
meta = with pkgs.stdenv.lib; {
|
||||
description = "A user environment configurator";
|
||||
maintainers = [ maintainers.rycee ];
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
}
|
62
home-manager/home-manager
Normal file
62
home-manager/home-manager
Normal file
|
@ -0,0 +1,62 @@
|
|||
#!@bash@/bin/bash
|
||||
|
||||
function doRebuild() {
|
||||
if [[ -z "$1" ]] ; then
|
||||
echo "Need to provide path to configuration file."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local wrkdir
|
||||
wrkdir="$(mktemp -d)"
|
||||
|
||||
nix-build --show-trace \
|
||||
"@HOME_MANAGER_EXPR_PATH@" \
|
||||
--argstr modulesPath "$HOME/.nixpkgs/home-manager/modules" \
|
||||
--argstr confPath "$1" \
|
||||
-A activation-script \
|
||||
-o "$wrkdir/activate"
|
||||
|
||||
"$wrkdir/activate/libexec/home-activate"
|
||||
|
||||
rm -rv "$wrkdir"
|
||||
}
|
||||
|
||||
function doListGens() {
|
||||
ls --color=yes -gG --sort time "/nix/var/nix/gcroots/per-user/$(whoami)" \
|
||||
| cut -d' ' -f 4-
|
||||
}
|
||||
|
||||
function doListPackages() {
|
||||
local outPath
|
||||
outPath="$(nix-env -q --out-path | grep -o '/.*home-manager-path$')"
|
||||
nix-store -q --references "$outPath" | sed 's/[^-]*-//'
|
||||
}
|
||||
|
||||
function doHelp() {
|
||||
echo "Usage: $0 {help | rebuild CONF | generations | packages}"
|
||||
echo
|
||||
echo "Commands"
|
||||
echo " help Print this help"
|
||||
echo " rebuild Rebuild the current environment"
|
||||
echo " generations List all home environment generations"
|
||||
echo " packages List all packages installed in home-manager-path"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
rebuild)
|
||||
doRebuild "$2"
|
||||
;;
|
||||
generations)
|
||||
doListGens
|
||||
;;
|
||||
packages)
|
||||
doListPackages
|
||||
;;
|
||||
help|--help)
|
||||
doHelp
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command: $1"
|
||||
doHelp
|
||||
exit 1
|
||||
esac
|
47
modules/default.nix
Normal file
47
modules/default.nix
Normal file
|
@ -0,0 +1,47 @@
|
|||
{ configuration
|
||||
, pkgs
|
||||
, lib ? pkgs.stdenv.lib
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
modules = [
|
||||
./home-environment.nix
|
||||
./programs/bash.nix
|
||||
./programs/beets.nix
|
||||
./programs/eclipse.nix
|
||||
./programs/emacs.nix
|
||||
./programs/git.nix
|
||||
./programs/gnome-terminal.nix
|
||||
./programs/lesspipe.nix
|
||||
./programs/texlive.nix
|
||||
./services/dunst.nix
|
||||
./services/gnome-keyring.nix
|
||||
./services/gpg-agent.nix
|
||||
./services/keepassx.nix
|
||||
./services/network-manager-applet.nix
|
||||
./services/random-background.nix
|
||||
./services/taffybar.nix
|
||||
./services/tahoe-lafs.nix
|
||||
./services/udiskie.nix
|
||||
./services/xscreensaver.nix
|
||||
./systemd.nix
|
||||
./xsession.nix
|
||||
];
|
||||
|
||||
pkgsModule = {
|
||||
config._module.args.pkgs = lib.mkForce pkgs;
|
||||
};
|
||||
|
||||
module = lib.evalModules {
|
||||
modules = [ configuration ] ++ modules ++ [ pkgsModule ];
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
inherit (module) options config;
|
||||
|
||||
activation-script = module.config.home.activationPackage;
|
||||
home-path = module.config.home.path;
|
||||
}
|
314
modules/home-environment.nix
Normal file
314
modules/home-environment.nix
Normal file
|
@ -0,0 +1,314 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.home;
|
||||
|
||||
languageSubModule = types.submodule {
|
||||
options = {
|
||||
base = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The language to use unless overridden by a more specific option.
|
||||
'';
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for addresses.
|
||||
'';
|
||||
};
|
||||
|
||||
monetary = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for formatting currencies and money amounts.
|
||||
'';
|
||||
};
|
||||
|
||||
paper = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for paper sizes.
|
||||
'';
|
||||
};
|
||||
|
||||
time = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The language to use for formatting times.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
keyboardSubModule = types.submodule {
|
||||
options = {
|
||||
layout = mkOption {
|
||||
type = types.str;
|
||||
default = "us";
|
||||
description = ''
|
||||
Keyboard layout.
|
||||
'';
|
||||
};
|
||||
|
||||
model = mkOption {
|
||||
type = types.str;
|
||||
default = "pc104";
|
||||
example = "presario";
|
||||
description = ''
|
||||
Keyboard model.
|
||||
'';
|
||||
};
|
||||
|
||||
options = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = ["grp:caps_toggle" "grp_led:scroll"];
|
||||
description = ''
|
||||
X keyboard options; layout switching goes here.
|
||||
'';
|
||||
};
|
||||
|
||||
variant = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "colemak";
|
||||
description = ''
|
||||
X keyboard variant.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
home.file = mkOption {
|
||||
description = "Attribute set of files to link into the user home.";
|
||||
default = {};
|
||||
type = types.loaOf (types.submodule (
|
||||
{ name, config, ... }: {
|
||||
options = {
|
||||
target = mkOption {
|
||||
type = types.str;
|
||||
description = "Path to target file relative to $HOME.";
|
||||
};
|
||||
|
||||
text = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.lines;
|
||||
description = "Text of the file.";
|
||||
};
|
||||
|
||||
source = mkOption {
|
||||
type = types.path;
|
||||
description = "Path of the source file.";
|
||||
};
|
||||
|
||||
mode = mkOption {
|
||||
type = types.str;
|
||||
default = "444";
|
||||
description = "The permissions to apply to the file.";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
target = mkDefault name;
|
||||
source = mkIf (config.text != null) (
|
||||
let name' = "user-etc-" + baseNameOf name;
|
||||
in mkDefault (pkgs.writeText name' config.text)
|
||||
);
|
||||
};
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
home.language = mkOption {
|
||||
type = languageSubModule;
|
||||
default = {};
|
||||
description = "Language configuration.";
|
||||
};
|
||||
|
||||
home.keyboard = mkOption {
|
||||
type = keyboardSubModule;
|
||||
default = {};
|
||||
description = "Keyboard configuration.";
|
||||
};
|
||||
|
||||
home.sessionVariables = mkOption {
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
description = "Environment variables to always set at login.";
|
||||
};
|
||||
|
||||
home.packages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
description = "The set of packages to appear in the user environment.";
|
||||
};
|
||||
|
||||
home.path = mkOption {
|
||||
internal = true;
|
||||
description = "The derivation installing the user packages.";
|
||||
};
|
||||
|
||||
home.activation = mkOption {
|
||||
internal = true;
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
description = "Activation scripts for the home environment.";
|
||||
};
|
||||
|
||||
home.activationPackage = mkOption {
|
||||
internal = true;
|
||||
type = types.package;
|
||||
description = "The package containing the complete activation script.";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
home.sessionVariables =
|
||||
let
|
||||
maybeSet = name: value:
|
||||
listToAttrs (optional (value != null) { inherit name value; });
|
||||
in
|
||||
(maybeSet "LANG" cfg.language.base)
|
||||
//
|
||||
(maybeSet "LC_ADDRESS" cfg.language.address)
|
||||
//
|
||||
(maybeSet "LC_MONETARY" cfg.language.monetary)
|
||||
//
|
||||
(maybeSet "LC_PAPER" cfg.language.paper)
|
||||
//
|
||||
(maybeSet "LC_TIME" cfg.language.time);
|
||||
|
||||
home.activation.linkages =
|
||||
let
|
||||
pak = pkgs.stdenv.mkDerivation {
|
||||
name = "home-environment";
|
||||
|
||||
phases = [ "installPhase" ];
|
||||
|
||||
installPhase =
|
||||
concatStringsSep "\n" (
|
||||
mapAttrsToList (name: value:
|
||||
"install -v -D -m${value.mode} ${value.source} $out/${value.target}"
|
||||
) cfg.file
|
||||
);
|
||||
};
|
||||
|
||||
link = pkgs.writeText "link" ''
|
||||
for sourcePath in "$@" ; do
|
||||
basePath="''${sourcePath#/nix/store/*-home-environment/}"
|
||||
targetPath="$HOME/$basePath"
|
||||
mkdir -vp "$(dirname "$targetPath")"
|
||||
ln -vsf "$sourcePath" "$targetPath"
|
||||
done
|
||||
'';
|
||||
|
||||
cleanup = pkgs.writeText "cleanup" ''
|
||||
for sourcePath in "$@" ; do
|
||||
basePath="''${sourcePath#/nix/store/*-home-environment/}"
|
||||
targetPath="$HOME/$basePath"
|
||||
echo -n "Checking $targetPath"
|
||||
if [[ -f "${pak}/$basePath" ]] ; then
|
||||
echo " exists"
|
||||
else
|
||||
echo " gone (deleting)"
|
||||
rm -v "$targetPath"
|
||||
rmdir --ignore-fail-on-non-empty -v -p "$(dirname "$targetPath")"
|
||||
fi
|
||||
done
|
||||
'';
|
||||
in
|
||||
''
|
||||
function setupVars() {
|
||||
local gcPath="/nix/var/nix/gcroots/per-user/$(whoami)"
|
||||
local greatestGenNum=( \
|
||||
$(find "$gcPath" -name 'home-*' \
|
||||
| sed 's/^.*-\([0-9]*\)$/\1/' \
|
||||
| sort -rn \
|
||||
| head -1) \
|
||||
)
|
||||
if [[ -n "$greatestGenNum" ]] ; then
|
||||
oldGenNum=$greatestGenNum
|
||||
newGenNum=$(($oldGenNum + 1))
|
||||
oldGenPath="$(readlink -e "$gcPath/home-$oldGenNum")"
|
||||
else
|
||||
newGenNum=1
|
||||
fi
|
||||
newGenPath="${pak}";
|
||||
newGenGcPath="$gcPath/home-$newGenNum"
|
||||
}
|
||||
|
||||
# Set some vars, these can be used later on as well.
|
||||
setupVars
|
||||
|
||||
if [[ "$oldGenPath" != "$newGenPath" ]] ; then
|
||||
ln -sfv "$newGenPath" "$newGenGcPath"
|
||||
find "$newGenPath" -type f -print0 | xargs -0 bash ${link}
|
||||
if [[ -n "$oldGenPath" ]] ; then
|
||||
echo "Cleaning up orphan links from $HOME"
|
||||
find "$oldGenPath" -type f -print0 | xargs -0 bash ${cleanup}
|
||||
fi
|
||||
else
|
||||
echo "Same home files as previous generation ... doing nothing"
|
||||
fi
|
||||
'';
|
||||
|
||||
home.activation.installPackages =
|
||||
''
|
||||
nix-env -i ${cfg.path}
|
||||
'';
|
||||
|
||||
home.activationPackage =
|
||||
let
|
||||
addHeader = n: v:
|
||||
v // {
|
||||
text = ''
|
||||
echo Activating ${n}
|
||||
${v.text}
|
||||
'';
|
||||
};
|
||||
toDepString = n: v: if isString v then noDepEntry v else v;
|
||||
activationWithDeps =
|
||||
mapAttrs addHeader (mapAttrs toDepString cfg.activation);
|
||||
activationCmds =
|
||||
textClosureMap id activationWithDeps (attrNames activationWithDeps);
|
||||
|
||||
sf = pkgs.writeText "activation-script" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
|
||||
${activationCmds}
|
||||
'';
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "activate-home";
|
||||
|
||||
phases = [ "installPhase" ];
|
||||
|
||||
installPhase = ''
|
||||
install -v -D -m755 ${sf} $out/libexec/home-activate
|
||||
'';
|
||||
};
|
||||
|
||||
home.path = pkgs.buildEnv {
|
||||
name = "home-manager-path";
|
||||
|
||||
paths = cfg.packages;
|
||||
|
||||
meta = {
|
||||
description = "Environment of packages installed through home-manager";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
93
modules/lib/generators.nix
Normal file
93
modules/lib/generators.nix
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* Functions that generate widespread file
|
||||
* formats from nix data structures.
|
||||
*
|
||||
* They all follow a similar interface:
|
||||
* generator { config-attrs } data
|
||||
*
|
||||
* Tests can be found in ./tests.nix
|
||||
* Documentation in the manual, #sec-generators
|
||||
*/
|
||||
with import <nixpkgs/lib/trivial.nix>;
|
||||
let
|
||||
libStr = import <nixpkgs/lib/strings.nix>;
|
||||
libAttr = import <nixpkgs/lib/attrsets.nix>;
|
||||
|
||||
flipMapAttrs = flip libAttr.mapAttrs;
|
||||
in
|
||||
|
||||
rec {
|
||||
|
||||
/* Generate a line of key k and value v, separated by
|
||||
* character sep. If sep appears in k, it is escaped.
|
||||
* Helper for synaxes with different separators.
|
||||
*
|
||||
* mkKeyValueDefault ":" "f:oo" "bar"
|
||||
* > "f\:oo:bar"
|
||||
*/
|
||||
mkKeyValueDefault = sep: k: v:
|
||||
"${libStr.escape [sep] k}${sep}${toString v}";
|
||||
|
||||
|
||||
/* Generate a key-value-style config file from an attrset.
|
||||
*
|
||||
* mkKeyValue is the same as in toINI.
|
||||
*/
|
||||
toKeyValue = {
|
||||
mkKeyValue ? mkKeyValueDefault "="
|
||||
}: attrs:
|
||||
let mkLine = k: v: mkKeyValue k v + "\n";
|
||||
in libStr.concatStrings (libAttr.mapAttrsToList mkLine attrs);
|
||||
|
||||
|
||||
/* Generate an INI-style config file from an
|
||||
* attrset of sections to an attrset of key-value pairs.
|
||||
*
|
||||
* generators.toINI {} {
|
||||
* foo = { hi = "${pkgs.hello}"; ciao = "bar"; };
|
||||
* baz = { "also, integers" = 42; };
|
||||
* }
|
||||
*
|
||||
*> [baz]
|
||||
*> also, integers=42
|
||||
*>
|
||||
*> [foo]
|
||||
*> ciao=bar
|
||||
*> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10
|
||||
*
|
||||
* The mk* configuration attributes can generically change
|
||||
* the way sections and key-value strings are generated.
|
||||
*
|
||||
* For more examples see the test cases in ./tests.nix.
|
||||
*/
|
||||
toINI = {
|
||||
# apply transformations (e.g. escapes) to section names
|
||||
mkSectionName ? (name: libStr.escape [ "[" "]" ] name),
|
||||
# format a setting line from key and value
|
||||
mkKeyValue ? mkKeyValueDefault "="
|
||||
}: attrsOfAttrs:
|
||||
let
|
||||
# map function to string for each key val
|
||||
mapAttrsToStringsSep = sep: mapFn: attrs:
|
||||
libStr.concatStringsSep sep
|
||||
(libAttr.mapAttrsToList mapFn attrs);
|
||||
mkSection = sectName: sectValues: ''
|
||||
[${mkSectionName sectName}]
|
||||
'' + toKeyValue { inherit mkKeyValue; } sectValues;
|
||||
in
|
||||
# map input to ini sections
|
||||
mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
|
||||
|
||||
|
||||
/* Generates JSON from an arbitrary (non-function) value.
|
||||
* For more information see the documentation of the builtin.
|
||||
*/
|
||||
toJSON = {}: builtins.toJSON;
|
||||
|
||||
|
||||
/* YAML has been a strict superset of JSON since 1.2, so we
|
||||
* use toJSON. Before it only had a few differences referring
|
||||
* to implicit typing rules, so it should work with older
|
||||
* parsers as well.
|
||||
*/
|
||||
toYAML = {}@args: toJSON args;
|
||||
}
|
159
modules/programs/bash.nix
Normal file
159
modules/programs/bash.nix
Normal file
|
@ -0,0 +1,159 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.bash;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.bash = {
|
||||
enable = mkEnableOption "GNU Bourne-Again SHell";
|
||||
|
||||
historySize = mkOption {
|
||||
type = types.int;
|
||||
default = 10000;
|
||||
description = "Number of history lines to keep in memory.";
|
||||
};
|
||||
|
||||
historyFileSize = mkOption {
|
||||
type = types.int;
|
||||
default = 100000;
|
||||
description = "Number of history lines to keep on file.";
|
||||
};
|
||||
|
||||
historyControl = mkOption {
|
||||
type = types.listOf (types.enum [
|
||||
"erasedups"
|
||||
"ignoredups"
|
||||
"ignorespace"
|
||||
]);
|
||||
default = [];
|
||||
description = "Controlling how commands are saved on the history list.";
|
||||
};
|
||||
|
||||
historyIgnore = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "List of commands that should not be saved to the history list.";
|
||||
};
|
||||
|
||||
shellOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
# Append to history file rather than replacing it.
|
||||
"histappend"
|
||||
|
||||
# check the window size after each command and, if
|
||||
# necessary, update the values of LINES and COLUMNS.
|
||||
"checkwinsize"
|
||||
|
||||
# Extended globbing.
|
||||
"extglob"
|
||||
"globstar"
|
||||
|
||||
# Warn if closing shell with running jobs.
|
||||
"checkjobs"
|
||||
];
|
||||
description = "Shell options to set.";
|
||||
};
|
||||
|
||||
shellAliases = mkOption {
|
||||
default = {};
|
||||
example = { ll = "ls -l"; ".." = "cd .."; };
|
||||
description = ''
|
||||
An attribute set that maps aliases (the top level attribute names in
|
||||
this option) to command strings or directly to build outputs. The
|
||||
aliases are added to all users' shells.
|
||||
'';
|
||||
type = types.attrs;
|
||||
};
|
||||
|
||||
enableAutojump = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Enable the autojump navigation tool.";
|
||||
};
|
||||
|
||||
profileExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = "Extra commands that should be added to .profile.";
|
||||
};
|
||||
|
||||
initExtra = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = "Extra commands that should be added to .bashrc.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = (
|
||||
let
|
||||
aliasesStr = concatStringsSep "\n" (
|
||||
mapAttrsToList (k: v: "alias ${k}='${v}'") cfg.shellAliases
|
||||
);
|
||||
|
||||
shoptsStr = concatStringsSep "\n" (
|
||||
map (v: "shopt -s ${v}") cfg.shellOptions
|
||||
);
|
||||
|
||||
export = n: v: "export ${n}=\"${toString v}\"";
|
||||
exportIfNonNull = n: v: optionalString (v != null) (export n v);
|
||||
exportIfNonEmpty = n: v: optionalString (v != "") (export n v);
|
||||
|
||||
histControlStr = concatStringsSep ":" cfg.historyControl;
|
||||
histIgnoreStr = concatStringsSep ":" cfg.historyIgnore;
|
||||
|
||||
envVarsStr = concatStringsSep "\n" (
|
||||
mapAttrsToList export config.home.sessionVariables
|
||||
);
|
||||
in mkIf cfg.enable {
|
||||
home.file.".bash_profile".text = ''
|
||||
# -*- mode: sh -*-
|
||||
|
||||
# include .profile if it exists
|
||||
[[ -f ~/.profile ]] && . ~/.profile
|
||||
|
||||
# include .bashrc if it exists
|
||||
[[ -f ~/.bashrc ]] && . ~/.bashrc
|
||||
'';
|
||||
|
||||
home.file.".profile".text = ''
|
||||
# -*- mode: sh -*-
|
||||
|
||||
${envVarsStr}
|
||||
|
||||
${cfg.profileExtra}
|
||||
'';
|
||||
|
||||
home.file.".bashrc".text = ''
|
||||
# -*- mode: sh -*-
|
||||
|
||||
# Skip if not running interactively.
|
||||
[ -z "$PS1" ] && return
|
||||
|
||||
${export "HISTSIZE" cfg.historySize}
|
||||
${export "HISTFILESIZE" cfg.historyFileSize}
|
||||
${exportIfNonEmpty "HISTCONTROL" histControlStr}
|
||||
${exportIfNonEmpty "HISTIGNORE" histIgnoreStr}
|
||||
|
||||
${shoptsStr}
|
||||
|
||||
${aliasesStr}
|
||||
|
||||
${cfg.initExtra}
|
||||
|
||||
${optionalString cfg.enableAutojump
|
||||
". ${pkgs.autojump}/share/autojump/autojump.bash"}
|
||||
'';
|
||||
|
||||
home.packages =
|
||||
optional (cfg.enableAutojump) pkgs.autojump;
|
||||
}
|
||||
);
|
||||
}
|
28
modules/programs/beets.nix
Normal file
28
modules/programs/beets.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.beets;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.beets = {
|
||||
settings = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = "Configuration written to ~/.config/beets/config.yaml";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.settings != {}) {
|
||||
home.packages = [ pkgs.beets ];
|
||||
|
||||
home.file.".config/beets/config.yaml".text =
|
||||
builtins.toJSON config.programs.beets.settings;
|
||||
};
|
||||
}
|
39
modules/programs/eclipse.nix
Normal file
39
modules/programs/eclipse.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.eclipse;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.eclipse = {
|
||||
enable = mkEnableOption "Eclipse";
|
||||
|
||||
jvmArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "JVM arguments to use for the Eclipse process.";
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
description = "Plugins that should be added to Eclipse.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [
|
||||
(pkgs.eclipses.eclipseWithPlugins {
|
||||
eclipse = pkgs.eclipses.eclipse-platform;
|
||||
jvmArgs = cfg.jvmArgs;
|
||||
plugins = cfg.plugins;
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
29
modules/programs/emacs.nix
Normal file
29
modules/programs/emacs.nix
Normal file
|
@ -0,0 +1,29 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.emacs;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.emacs = {
|
||||
enable = mkEnableOption "Emacs";
|
||||
|
||||
extraPackages = mkOption {
|
||||
default = self: [];
|
||||
example = literalExample ''
|
||||
epkgs: [ epkgs.emms epkgs.magit ]
|
||||
'';
|
||||
description = "Extra packages available to Emacs.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [ (pkgs.emacsWithPackages cfg.extraPackages) ];
|
||||
};
|
||||
}
|
102
modules/programs/git.nix
Normal file
102
modules/programs/git.nix
Normal file
|
@ -0,0 +1,102 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.git;
|
||||
|
||||
toINI = (import ../lib/generators.nix).toINI {};
|
||||
|
||||
signModule = types.submodule (
|
||||
{ ... }: {
|
||||
options = {
|
||||
key = mkOption {
|
||||
type = types.str;
|
||||
default = null;
|
||||
description = "The default GPG signing key fingerprint.";
|
||||
};
|
||||
|
||||
signByDefault = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether commits should be signed by default.";
|
||||
};
|
||||
|
||||
gpgPath = mkOption {
|
||||
type = types.str;
|
||||
default = "${pkgs.gnupg}/bin/gpg2";
|
||||
defaultText = "''${pkgs.gnupg}/bin/gpg2";
|
||||
description = "Path to GnuPG binary to use.";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.git = {
|
||||
enable = mkEnableOption "Git";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.git;
|
||||
defaultText = "pkgs.git";
|
||||
description = "Git package to install.";
|
||||
};
|
||||
|
||||
userName = mkOption {
|
||||
type = types.str;
|
||||
description = "Default user name to use.";
|
||||
};
|
||||
|
||||
userEmail = mkOption {
|
||||
type = types.str;
|
||||
description = "Default user email to use.";
|
||||
};
|
||||
|
||||
aliases = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = "Git aliases to define.";
|
||||
};
|
||||
|
||||
signing = mkOption {
|
||||
type = types.nullOr signModule;
|
||||
default = null;
|
||||
description = "Options related to signing commits using GnuPG.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = null;
|
||||
description = "Additional configuration to add.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (
|
||||
let
|
||||
ini = {
|
||||
user = {
|
||||
name = cfg.userName;
|
||||
email = cfg.userEmail;
|
||||
} // optionalAttrs (cfg.signing != null) {
|
||||
signingKey = cfg.signing.key;
|
||||
};
|
||||
} // optionalAttrs (cfg.signing != null) {
|
||||
commit.gpgSign = cfg.signing.signByDefault;
|
||||
gpg.program = cfg.signing.gpgPath;
|
||||
} // optionalAttrs (cfg.aliases != {}) {
|
||||
alias = cfg.aliases;
|
||||
};
|
||||
in
|
||||
{
|
||||
home.packages = [ cfg.package ];
|
||||
|
||||
home.file.".gitconfig".text = toINI ini + "\n" + cfg.extraConfig;
|
||||
}
|
||||
);
|
||||
}
|
186
modules/programs/gnome-terminal.nix
Normal file
186
modules/programs/gnome-terminal.nix
Normal file
|
@ -0,0 +1,186 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.gnome-terminal;
|
||||
|
||||
profileColorsSubModule = types.submodule (
|
||||
{ ... }: {
|
||||
options = {
|
||||
foregroundColor = mkOption {
|
||||
type = types.str;
|
||||
description = "The foreground color.";
|
||||
};
|
||||
|
||||
backgroundColor = mkOption {
|
||||
type = types.str;
|
||||
description = "The background color.";
|
||||
};
|
||||
|
||||
boldColor = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = "The bold color, null to use same as foreground.";
|
||||
};
|
||||
|
||||
palette = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "The terminal palette.";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
profileSubModule = types.submodule (
|
||||
{ name, config, ... }: {
|
||||
options = {
|
||||
default = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Whether this should be the default profile.";
|
||||
};
|
||||
|
||||
visibleName = mkOption {
|
||||
type = types.str;
|
||||
description = "The profile name.";
|
||||
};
|
||||
|
||||
colors = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr profileColorsSubModule;
|
||||
description = "The terminal colors, null to use system default.";
|
||||
};
|
||||
|
||||
cursorShape = mkOption {
|
||||
default = "block";
|
||||
type = types.enum [ "block" "ibeam" "underline" ];
|
||||
description = "The cursor shape.";
|
||||
};
|
||||
|
||||
font = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = "The font name, null to use system default.";
|
||||
};
|
||||
|
||||
scrollOnOutput = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = "Whether to scroll when output is written.";
|
||||
};
|
||||
|
||||
showScrollbar = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = "Whether the scroll bar should be visible.";
|
||||
};
|
||||
|
||||
scrollbackLines = mkOption {
|
||||
default = 10000;
|
||||
type = types.nullOr types.int;
|
||||
description =
|
||||
''
|
||||
The number of scrollback lines to keep, null for infinite.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
toINI = (import ../lib/generators.nix).toINI { mkKeyValue = mkIniKeyValue; };
|
||||
|
||||
mkIniKeyValue = key: value:
|
||||
let
|
||||
tweakVal = v:
|
||||
if isString v then "'${v}'"
|
||||
else if isList v then "[" + concatStringsSep "," (map tweakVal v) + "]"
|
||||
else if isBool v && v then "true"
|
||||
else if isBool v && !v then "false"
|
||||
else toString v;
|
||||
in
|
||||
"${key}=${tweakVal value}";
|
||||
|
||||
buildProfileSet = pcfg:
|
||||
{
|
||||
visible-name = pcfg.visibleName;
|
||||
scrollbar-policy = if pcfg.showScrollbar then "always" else "never";
|
||||
scrollback-lines = pcfg.scrollbackLines;
|
||||
cursor-shape = pcfg.cursorShape;
|
||||
}
|
||||
// (
|
||||
if (pcfg.font == null)
|
||||
then { use-system-font = true; }
|
||||
else { use-system-font = false; font = pcfg.font; }
|
||||
) // (
|
||||
if (pcfg.colors == null)
|
||||
then { use-theme-colors = true; }
|
||||
else (
|
||||
{
|
||||
use-theme-colors = false;
|
||||
foreground-color = pcfg.colors.foregroundColor;
|
||||
background-color = pcfg.colors.backgroundColor;
|
||||
palette = pcfg.colors.palette;
|
||||
}
|
||||
// (
|
||||
if (pcfg.colors.boldColor == null)
|
||||
then { bold-color-same-as-fg = true; }
|
||||
else {
|
||||
bold-color-same-as-fg = false;
|
||||
bold-color = pcfg.colors.boldColor;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
buildIniSet = cfg:
|
||||
{
|
||||
"/" = {
|
||||
default-show-menubar = cfg.showMenubar;
|
||||
schema-version = 3;
|
||||
};
|
||||
}
|
||||
//
|
||||
{
|
||||
"profiles:" = {
|
||||
default = head (attrNames (filterAttrs (n: v: v.default) cfg.profile));
|
||||
list = attrNames cfg.profile; #mapAttrsToList (n: v: n) cfg.profile;
|
||||
};
|
||||
}
|
||||
//
|
||||
mapAttrs' (name: value:
|
||||
nameValuePair ("profiles:/:${name}") (buildProfileSet value)
|
||||
) cfg.profile;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.gnome-terminal = {
|
||||
enable = mkEnableOption "Gnome Terminal";
|
||||
|
||||
showMenubar = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = "Whether to show the menubar by default";
|
||||
};
|
||||
|
||||
profile = mkOption {
|
||||
default = {};
|
||||
type = types.loaOf profileSubModule;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.activation.gnome-terminal =
|
||||
let
|
||||
sf = pkgs.writeText "gnome-terminal.ini" (toINI (buildIniSet cfg));
|
||||
dconfPath = "/org/gnome/terminal/legacy/";
|
||||
in
|
||||
''
|
||||
${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} < ${sf}
|
||||
'';
|
||||
};
|
||||
}
|
17
modules/programs/lesspipe.nix
Normal file
17
modules/programs/lesspipe.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.lesspipe = {
|
||||
enable = mkEnableOption "lesspipe preprocessor for less";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.programs.lesspipe.enable {
|
||||
home.sessionVariables = {
|
||||
LESSOPEN = "|${pkgs.lesspipe}/bin/lesspipe.sh %s";
|
||||
};
|
||||
};
|
||||
}
|
32
modules/programs/texlive.nix
Normal file
32
modules/programs/texlive.nix
Normal file
|
@ -0,0 +1,32 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.texlive;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
programs.texlive = {
|
||||
enable = mkEnableOption "Texlive";
|
||||
|
||||
extraPackages = mkOption {
|
||||
default = self: {};
|
||||
example = literalExample ''
|
||||
tpkgs: { inherit (tpkgs) collection-fontsrecommended algorithms; }
|
||||
'';
|
||||
description = "Extra packages available to Texlive.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [
|
||||
(pkgs.texlive.combine (cfg.extraPackages pkgs.texlive))
|
||||
];
|
||||
|
||||
};
|
||||
}
|
35
modules/services/dunst.nix
Normal file
35
modules/services/dunst.nix
Normal file
|
@ -0,0 +1,35 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
services.dunst = {
|
||||
enable = mkEnableOption "the dunst notification daemon";
|
||||
|
||||
settings = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = "Configuration written to ~/.config/dunstrc";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.dunst.enable {
|
||||
systemd.user.services.dunst = {
|
||||
Unit = {
|
||||
Description = "Dunst notification daemon";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "xorg.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
# Type = "dbus";
|
||||
# BusName = "org.freedesktop.Notifications";
|
||||
ExecStart = "${pkgs.dunst}/bin/dunst";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
52
modules/services/gnome-keyring.nix
Normal file
52
modules/services/gnome-keyring.nix
Normal file
|
@ -0,0 +1,52 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.gnome-keyring;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
services.gnome-keyring = {
|
||||
enable = mkEnableOption "GNOME Keyring";
|
||||
|
||||
components = mkOption {
|
||||
type = types.listOf (types.enum ["pkcs11" "secrets" "ssh"]);
|
||||
default = [];
|
||||
description = ''
|
||||
The GNOME keyring components to start. If empty then the
|
||||
default set of components will be started.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.user.services.gnome-keyring = {
|
||||
Unit = {
|
||||
Description = "GNOME Keyring";
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart =
|
||||
let
|
||||
args = concatStringsSep " " (
|
||||
[ "--start" "--foreground" ]
|
||||
++ optional (cfg.components != []) (
|
||||
"--components=" + concatStringsSep "," cfg.components
|
||||
)
|
||||
);
|
||||
in
|
||||
"${pkgs.gnome3.gnome_keyring}/bin/gnome-keyring-daemon ${args}";
|
||||
Restart = "on-abort";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "xorg.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
69
modules/services/gpg-agent.nix
Normal file
69
modules/services/gpg-agent.nix
Normal file
|
@ -0,0 +1,69 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.gpg-agent;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
services.gpg-agent = {
|
||||
enable = mkEnableOption "GnuPG private key agent";
|
||||
|
||||
defaultCacheTtl = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
description = ''
|
||||
Set the time a cache entry is valid to the given number of seconds.
|
||||
'';
|
||||
};
|
||||
|
||||
enableSshSupport = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to use the GnuPG key agent for SSH keys.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.file.".gnupg/gpg-agent.conf".text = concatStringsSep "\n" (
|
||||
optional cfg.enableSshSupport
|
||||
"enable-ssh-support"
|
||||
++
|
||||
optional (cfg.defaultCacheTtl != null)
|
||||
"default-cache-ttl ${toString cfg.defaultCacheTtl}"
|
||||
);
|
||||
|
||||
home.sessionVariables =
|
||||
optionalAttrs cfg.enableSshSupport {
|
||||
SSH_AUTH_SOCK = "\${XDG_RUNTIME_DIR}/gnupg/S.gpg-agent.ssh";
|
||||
};
|
||||
|
||||
programs.bash.initExtra = ''
|
||||
GPG_TTY="$(tty)"
|
||||
export GPG_TTY
|
||||
gpg-connect-agent updatestartuptty /bye > /dev/null
|
||||
'';
|
||||
|
||||
systemd.user.services.gpg-agent = {
|
||||
Unit = {
|
||||
Description = "GnuPG private key agent";
|
||||
IgnoreOnIsolate = true;
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "forking";
|
||||
ExecStart = "${pkgs.gnupg}/bin/gpg-agent --daemon --use-standard-socket";
|
||||
Restart = "on-abort";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
27
modules/services/keepassx.nix
Normal file
27
modules/services/keepassx.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
services.keepassx = {
|
||||
enable = mkEnableOption "the KeePassX password manager";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.keepassx.enable {
|
||||
systemd.user.services.keepassx = {
|
||||
Unit = {
|
||||
Description = "KeePassX password manager";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "xorg.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${pkgs.keepassx}/bin/keepassx -min -lock";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
27
modules/services/network-manager-applet.nix
Normal file
27
modules/services/network-manager-applet.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
services.network-manager-applet = {
|
||||
enable = mkEnableOption "the Network Manager applet";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.network-manager-applet.enable {
|
||||
systemd.user.services.network-manager-applet = {
|
||||
Unit = {
|
||||
Description = "Network Manager applet";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "xorg.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${pkgs.networkmanagerapplet}/bin/nm-applet --sm-disable";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
74
modules/services/random-background.nix
Normal file
74
modules/services/random-background.nix
Normal file
|
@ -0,0 +1,74 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.random-background;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
services.random-background = {
|
||||
enable = mkEnableOption "random desktop background";
|
||||
|
||||
imageDirectory = mkOption {
|
||||
type = types.str;
|
||||
description =
|
||||
''
|
||||
The directory of images from which a background should be
|
||||
chosen. Should be formatted in a way understood by
|
||||
systemd, e.g., '%h' is the home directory.
|
||||
'';
|
||||
};
|
||||
|
||||
interval = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The duration between changing background image, set to null
|
||||
to only set background when logging in.
|
||||
|
||||
Should be formatted as a duration understood by systemd.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (
|
||||
mkMerge ([
|
||||
{
|
||||
systemd.user.services.random-background = {
|
||||
Unit = {
|
||||
Description = "Set random desktop background using feh";
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.feh}/bin/feh --randomize --bg-fill %h/backgrounds/";
|
||||
IOSchedulingClass = "idle";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "xorg.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
(mkIf (cfg.interval != null) {
|
||||
systemd.user.timers.random-background = {
|
||||
Unit = {
|
||||
Description = "Set random desktop background using feh";
|
||||
};
|
||||
|
||||
Timer = {
|
||||
OnUnitActiveSec = cfg.interval;
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
})
|
||||
]));
|
||||
}
|
41
modules/services/taffybar.nix
Normal file
41
modules/services/taffybar.nix
Normal file
|
@ -0,0 +1,41 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.taffybar;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
services.taffybar = {
|
||||
enable = mkEnableOption "Taffybar";
|
||||
|
||||
package = mkOption {
|
||||
default = pkgs.taffybar;
|
||||
defaultText = "pkgs.taffybar";
|
||||
type = types.package;
|
||||
example = literalExample "pkgs.taffybar";
|
||||
description = "The package to use for the Taffybar binary.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.taffybar.enable {
|
||||
systemd.user.services.taffybar = {
|
||||
Unit = {
|
||||
Description = "Taffybar desktop bar";
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${cfg.package}/bin/taffybar";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "xorg.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
23
modules/services/tahoe-lafs.nix
Normal file
23
modules/services/tahoe-lafs.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
services.tahoe-lafs = {
|
||||
enable = mkEnableOption "Tahoe-LAFS";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.tahoe-lafs.enable {
|
||||
systemd.user.services.tahoe-lafs = {
|
||||
Unit = {
|
||||
Description = "Tahoe-LAFS";
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${pkgs.tahoelafs}/bin/tahoe run -C %h/.tahoe";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
29
modules/services/udiskie.nix
Normal file
29
modules/services/udiskie.nix
Normal file
|
@ -0,0 +1,29 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
services.udiskie = {
|
||||
enable = mkEnableOption "Udiskie mount daemon";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.udiskie.enable {
|
||||
systemd.user.services.udiskie = {
|
||||
Unit = {
|
||||
Description = "Udiskie mount daemon";
|
||||
Requires = [ "taffybar.service" ];
|
||||
After = [ "taffybar.service" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${pkgs.pythonPackages.udiskie}/bin/udiskie -2 -A -n -s";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "xorg.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
27
modules/services/xscreensaver.nix
Normal file
27
modules/services/xscreensaver.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
services.xscreensaver = {
|
||||
enable = mkEnableOption "XScreenSaver";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.xscreensaver.enable {
|
||||
systemd.user.services.xscreensaver = {
|
||||
Unit = {
|
||||
Description = "XScreenSaver";
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${pkgs.xscreensaver}/bin/xscreensaver -no-splash";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "xorg.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
119
modules/systemd.nix
Normal file
119
modules/systemd.nix
Normal file
|
@ -0,0 +1,119 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
toSystemdIni = (import lib/generators.nix).toINI {
|
||||
mkKeyValue = key: value:
|
||||
let
|
||||
value' =
|
||||
if isBool value then (if value then "true" else "false")
|
||||
else toString value;
|
||||
in
|
||||
"${key}=${value'}";
|
||||
};
|
||||
|
||||
buildService = style: name: serviceCfg:
|
||||
let
|
||||
source = pkgs.writeText "${name}.${style}" (toSystemdIni serviceCfg);
|
||||
|
||||
wantedBy = target:
|
||||
{
|
||||
name = ".config/systemd/user/${target}.wants/${name}.${style}";
|
||||
value = { inherit source; };
|
||||
};
|
||||
in
|
||||
singleton {
|
||||
name = ".config/systemd/user/${name}.${style}";
|
||||
value = { inherit source; };
|
||||
}
|
||||
++
|
||||
map wantedBy (serviceCfg.Install.WantedBy or []);
|
||||
|
||||
buildServices = style: serviceCfgs:
|
||||
concatLists (mapAttrsToList (buildService style) serviceCfgs);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
systemd.user = {
|
||||
services = mkOption {
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
description = "Definition of systemd per-user service units.";
|
||||
};
|
||||
|
||||
timers = mkOption {
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
description = "Definition of systemd per-user timers";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
home.file =
|
||||
listToAttrs (
|
||||
(buildServices "service" config.systemd.user.services)
|
||||
++
|
||||
(buildServices "timer" config.systemd.user.timers)
|
||||
);
|
||||
|
||||
home.activation.reloadSystemD = stringAfter ["linkages"] ''
|
||||
function systemdPostReload() {
|
||||
local servicesDiffFile="$(mktemp)"
|
||||
|
||||
diff \
|
||||
--new-line-format='+%L' \
|
||||
--old-line-format='-%L' \
|
||||
--unchanged-line-format=' %L' \
|
||||
<(basename -a $(echo "$oldGenPath/.config/systemd/user/*.service") | sort) \
|
||||
<(basename -a $(echo "$newGenPath/.config/systemd/user/*.service") | sort) \
|
||||
> $servicesDiffFile
|
||||
|
||||
local -a maybeRestart=( $(grep '^ ' $servicesDiffFile | cut -c2-) )
|
||||
local -a toStop=( $(grep '^-' $servicesDiffFile | cut -c2-) )
|
||||
local -a toStart=( $(grep '^+' $servicesDiffFile | cut -c2-) )
|
||||
local -a toRestart=( )
|
||||
|
||||
for f in ''${maybeRestart[@]} ; do
|
||||
if systemctl --quiet --user is-active "$f" \
|
||||
&& ! cmp --quiet \
|
||||
"$oldGenPath/.config/systemd/user/$f" \
|
||||
"$newGenPath/.config/systemd/user/$f" ; then
|
||||
echo "Adding '$f' to restart list";
|
||||
toRestart+=("$f")
|
||||
fi
|
||||
done
|
||||
|
||||
rm $servicesDiffFile
|
||||
|
||||
sugg=""
|
||||
|
||||
if [[ -n "''${toRestart[@]}" ]] ; then
|
||||
sugg="$sugg\nsystemctl --user restart ''${toRestart[@]}"
|
||||
fi
|
||||
|
||||
if [[ -n "''${toStop[@]}" ]] ; then
|
||||
sugg="$sugg\nsystemctl --user stop ''${toStop[@]}"
|
||||
fi
|
||||
|
||||
if [[ -n "''${toStart[@]}" ]] ; then
|
||||
sugg="$sugg\nsystemctl --user start ''${toStart[@]}"
|
||||
fi
|
||||
|
||||
if [[ -n "$sugg" ]] ; then
|
||||
echo "Suggested commands:"
|
||||
echo -e "$sugg"
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "$oldGenPath" != "$newGenPath" ]] ; then
|
||||
systemctl --user daemon-reload
|
||||
systemdPostReload
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
77
modules/xsession.nix
Normal file
77
modules/xsession.nix
Normal file
|
@ -0,0 +1,77 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xsession;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
xsession = {
|
||||
enable = mkEnableOption "X Session";
|
||||
|
||||
windowManager = mkOption {
|
||||
default = {};
|
||||
type = types.str;
|
||||
description = "Path to window manager to exec.";
|
||||
};
|
||||
|
||||
initExtra = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "Extra shell commands to run during initialization.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.user.services.setxkbmap = {
|
||||
Unit = {
|
||||
Description = "Set up keyboard in X";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "xorg.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart =
|
||||
let
|
||||
args = concatStringsSep " " (
|
||||
[
|
||||
"-layout '${config.home.keyboard.layout}'"
|
||||
"-variant '${config.home.keyboard.variant}'"
|
||||
] ++
|
||||
(map (v: "-option '${v}'") config.home.keyboard.options)
|
||||
);
|
||||
in
|
||||
"${pkgs.xorg.setxkbmap}/bin/setxkbmap ${args}";
|
||||
};
|
||||
};
|
||||
|
||||
home.file.".xsession" = {
|
||||
mode = "555";
|
||||
text = ''
|
||||
# Rely on Bash to set session variables.
|
||||
. "$HOME/.profile"
|
||||
|
||||
systemctl --user import-environment DBUS_SESSION_BUS_ADDRESS
|
||||
systemctl --user import-environment DISPLAY
|
||||
systemctl --user import-environment SSH_AUTH_SOCK
|
||||
systemctl --user import-environment XDG_DATA_DIRS
|
||||
systemctl --user import-environment XDG_RUNTIME_DIR
|
||||
systemctl --user start xorg.target
|
||||
|
||||
${cfg.initExtra}
|
||||
|
||||
${cfg.windowManager}
|
||||
|
||||
systemctl --user stop xorg.target
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue