This commit is contained in:
Riley Apeldoorn 2022-01-11 23:20:57 +00:00
parent fe0fdc63d9
commit 8580f19c5f
20 changed files with 440 additions and 225 deletions

View file

@ -109,9 +109,11 @@ let inherit (builtins) mapAttrs map; in rec {
};
hex = mapAttrs (name: value:
if name != "grayscales"
then mapAttrs (n: v: "#" + v) value
else map (v: "#" + v) value
if name == "grayscales"
then map (v: "#" + v) value
else if name == "hex"
then value
else mapAttrs (n: v: "#" + v) value
) (dark);
};

View file

@ -15,4 +15,39 @@
hostName = "thor";
interfaces.enp9s0.useDHCP = true;
};
devices = {
# Audio devices
audio = {
# Outputs
speakers = "alsa_output.pci-0000_0c_00.4.analog-stereo";
external = "alsa_output.pci-0000_0a_00.1.hdmi-stereo";
headset = null; # Thor doesn't have bluetooth support (yet)
# Inputs
main-mic = "alsa_input.usb-046d_C922_Pro_Stream_Webcam_CC9E75BF-02.analog-stereo";
};
# Displays
video.displays = {
# Connected to the ultrawide output
"HDMI-1" = {
primary = true;
position = [ 0 0 ];
};
# Vertical output to the right of HDMI-1
"DP-2" = {
rotate = "left";
position = [ 2560 ((1080 - 1920) / 2) ];
};
};
};
}

View file

@ -4,31 +4,32 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/f3cdd2ab-62ba-4d72-8a28-b3adc0ec3997";
fsType = "ext4";
fileSystems."/" = {
device = "/dev/disk/by-uuid/f3cdd2ab-62ba-4d72-8a28-b3adc0ec3997";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/3691-F2E6";
fsType = "vfat";
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/3691-F2E6";
fsType = "vfat";
};
fileSystems."/nix" =
{ device = "/dev/disk/by-uuid/e317d7a7-c11c-4f3a-afda-0fd949f5633c";
fsType = "btrfs";
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/e317d7a7-c11c-4f3a-afda-0fd949f5633c";
fsType = "btrfs";
};
swapDevices = [ { label = "swap"; } ];
swapDevices = [ { label = "swap"; } ];
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -2,6 +2,38 @@
{ config, lib, pkgs, ... }:
with lib; with types;
let named = submodule {
options = {
normal = mkOption { type = str; };
bright = mkOption { type = str; };
pastel = mkOption { type = str; };
};
};
special = submodule {
options = {
primary = mkOption { type = str; };
normal = mkOption { type = str; };
slight = mkOption { type = str; };
};
};
themeType = submodule {
options = {
foreground = mkOption { type = special; };
background = mkOption { type = special; };
grayscales = mkOption { type = listOf str; };
red = mkOption { type = named; };
green = mkOption { type = named; };
blue = mkOption { type = named; };
yellow = mkOption { type = named; };
purple = mkOption { type = named; };
cyan = mkOption { type = named; };
pink = mkOption { type = named; };
orange = mkOption { type = named; };
misc = mkOption { type = attrsOf str; };
hex = mkOption { type = themeType; };
};
}; in
{
options.riley = with lib; {
@ -10,7 +42,8 @@
type = types.bool;
description = ''
Enable IDE-like plugins such as language servers for Rust, Haskell and
Nix in the editor, and configure accordingly.
Nix in the editor, and configure accordingly. If disabled, the editor
will lack some features such as semantic highlighting.
'';
default = true;
};
@ -18,28 +51,92 @@
gui = mkOption {
type = types.bool;
description = ''
Enables GUI applications, a display server, audio server and related services.
Enable the display server and related graphical programs.
'';
default = true;
};
theme = mkOption {
type = themeType;
description = ''
The theme used across the installation. Not used if gui is disabled.
'';
};
};
options.devices = mkOption {
type = with types; submodule {
options = {
audio = mkOption {
type = nullOr (submodule {
options = {
speakers = mkOption { type = str; };
external = mkOption { type = str; };
headset = mkOption { type = nullOr str; };
main-mic = mkOption { type = nullOr str; };
};
});
description = ''
Known audio devices: outputs & microphones.
Each string should be a pulseaudio sink or source.
'';
};
video = mkOption {
type = submodule {
options = {
displays = let output = submodule {
options = {
primary = mkOption {
type = bool;
default = false;
};
position = mkOption {
type = nullOr (listOf int);
default = null;
};
rotate = mkOption {
type = enum [ "normal" "left" "right" "inverted" ];
default = "normal";
};
};
}; in mkOption {
type = attrsOf output;
description = ''
A list of outputs with information on how to place them.
'';
};
};
};
description = ''
Define the video devices (just the displays, for now).
'';
};
};
};
};
imports = [
<home-manager/nixos>
./kakoune
./display
./ide
./gui
./alacritty.nix
./fonts.nix
./git.nix
./ssh.nix
];
config = {
riley.theme = (import ../colors.nix)."dark";
environment.systemPackages = with pkgs; [
# Web utils

View file

@ -1,193 +0,0 @@
{ pkgs, config, lib, ... }:
let theme = (import ../../colors.nix)."dark".hex;
# Keybinds that launch an application.
launchers = ({ browser }: mod: {
"${mod}+Tab" = "exec ${browser}";
});
# Keybinds generated from a set of workspaces.
workspace = ({ numbered ? 0, named ? {} }: mod: with lib;
let nums = genAttrs (map toString (range 1 numbered)) id;
workspaces = named // nums;
genBinds = (n: k: {
# Focus the workspace
"${mod}+${k}" = "workspace ${n}";
# Move a window to the workspace
"${mod}+Shift+${k}" = "move window to workspace ${n}";
});
keybinds = mapAttrsToList genBinds workspaces; in
mkMerge (keybinds)
);
# Layout manipulation keybinds.
layout = (mod: {
"${mod}+A" = "split v";
"${mod}+S" = "split h";
"${mod}+F" = "fullscreen toggle";
});
# Directional keys are used for basic navigation.
directional = ({ left, right, up, down }: mod: {
# Change window focus
"${mod}+${left}" = "focus left";
"${mod}+${down}" = "focus down";
"${mod}+${up}" = "focus up";
"${mod}+${right}" = "focus right";
# Move windows
"${mod}+Shift+${left}" = "move left";
"${mod}+Shift+${down}" = "move down";
"${mod}+Shift+${up}" = "move up";
"${mod}+Shift+${right}" = "move right";
});
# Media controls.
media = ({ mpc ? null }: mod:
if (mpc != null)
then (let cmd = "${mpc}/bin/${mpc.pname}"; in {
"${mod}+comma" = "exec ${cmd} prev";
"${mod}+period" = "exec ${cmd} next";
"${mod}+slash" = "exec ${cmd} toggle";
})
else {}
);
# Utility scripts and such.
scripts = (mod: {}); in
{
services.xserver = {
enable = true;
windowManager.i3 = {
enable = true;
package = pkgs.i3; #-gaps;
};
};
home-manager.users."riley" =
let browser = pkgs.google-chrome;
term = pkgs.alacritty; in
{
home.packages = with pkgs; [
tdesktop
xclip
# Paste from clipboard
(writeShellApplication {
name = "xc.p";
runtimeInputs = [ xclip ];
text = "xclip -sel clip -o";
})
# Copy to clipboard
(writeShellApplication {
name = "xc.c";
runtimeInputs = [ xclip ];
text = "xclip -sel clip -i";
})
# Copy to clipboard with given mime type
(writeShellApplication {
name = "xc.t";
runtimeInputs = [ xclip ];
text = "xclip -sel clip -t \"$1\" -i";
})
] ++ [
term
browser
];
xsession.windowManager.i3 = {
enable = true;
package = pkgs.i3;
config = with lib; (rec {
modifier = "Mod4";
terminal = "${term}/bin/${term.pname}";
# Apply the modifier key to each of the keybinding generator functions
# and merge the resulting sets.
keybindings = let mod = modifier; in mkMerge (map (f: f (mod)) [
(mod: {
"${mod}+Return" = "exec ${terminal}";
"${mod}+BackSpace" = "kill";
})
(directional {
left = "H";
right = "L";
down = "J";
up = "K";
})
(workspace {
numbered = 5;
named = {
"dev" = "0";
"doc" = "minus";
"net" = "equal";
};
})
(launchers {
browser = "google-chrome-stable";
})
layout
(media {
mpc = pkgs.mpc_cli;
})
scripts
]);
colors = {
focused = rec {
background = theme.background.normal;
text = theme."red".bright;
border = background;
childBorder = border;
indicator = border;
};
unfocused = rec {
background = theme.background.normal;
text = theme.foreground.slight;
border = background;
childBorder = border;
indicator = border;
};
focusedInactive = colors.unfocused;
};
window = {
border = 2;
commands = [
{ command = "border pixel 2"; criteria = { class = ".*"; }; }
];
};
fonts = {
names = [ "Source Sans 3" ];
style = "Semibold";
size = 10.0;
};
});
};
};
}

7
modules/gui/README.md Normal file
View file

@ -0,0 +1,7 @@
# Display module
The display module defines configuration for the window manager and related programs,
as well as the audio server.
Currently, this sets up an environment with an X11 display server and the i3 window manager.
It also enables pulseaudio as the audio server.

View file

@ -1,6 +1,6 @@
{ pkgs, config, ... }:
{ pkgs, lib, config, ... }:
{
(lib.mkIf (config.riley.gui) {
home-manager.users."riley" = {
programs.alacritty = {
enable = true;
@ -13,7 +13,7 @@
bold = { family = "Fira Code"; style = "Medium"; };
};
colors = with (import ../colors.nix)."dark".hex; {
colors = with config.riley.theme.hex; {
primary = {
background = background.primary;
@ -42,4 +42,4 @@
};
};
}
})

24
modules/gui/clipboard.nix Normal file
View file

@ -0,0 +1,24 @@
{ config, lib, pkgs, ... }:
(lib.mkIf (config.riley.gui) {
# Add some shell scripts that abstract away the
# horrible reality that the clipboard is managed by
# the display server.
users.users."riley".packages = with pkgs; [
(writeShellApplication {
name = "copy";
runtimeInputs = [ xclip ];
text = "xclip -sel clip -i";
})
(writeShellApplication {
name = "paste";
runtimeInputs = [ xclip ];
text = "xclip -sel clip -o";
})
];
})

20
modules/gui/default.nix Normal file
View file

@ -0,0 +1,20 @@
{ pkgs, config, lib, ... }:
({
imports = [
./window-manager.nix
./pulseaudio.nix
./clipboard.nix
./alacritty.nix
];
}) // (lib.mkIf (config.riley.gui) {
# Graphical applications
users.users."riley".packages = with pkgs; [
google-chrome
tdesktop
];
})

110
modules/gui/keybinds.nix Normal file
View file

@ -0,0 +1,110 @@
{ lib, config, pkgs, modifier ? "Mod4", directional, workspace, launchers }:
with lib; let mod = modifier;
# Directional shortcuts.
#
# These are used to change focus and move windows around.
genDirectional = ({ left, right, up, down }: {
# Change window focus
"${mod}+${left}" = "focus left";
"${mod}+${down}" = "focus down";
"${mod}+${up}" = "focus up";
"${mod}+${right}" = "focus right";
# Move windows
"${mod}+Shift+${left}" = "move left";
"${mod}+Shift+${down}" = "move down";
"${mod}+Shift+${up}" = "move up";
"${mod}+Shift+${right}" = "move right";
});
# Workspace shortcuts.
#
# The `numbered` parameter defines the number of numbered workspaces,
# which can be no more than 8.
#
# The `named` parameter defines a set of named workspaces and the key
# used to navigate to it.
#
# For each entry this generates two keybindings:
# - `<mod>+<key>`: focus workspace
# - `<mod>+Shift+<key>`: move focused window to workspace
#
# `<key>` is set to the workspace number for numbered workspaces.
genWorkspaces = ({ numbered ? 0, named ? {} }: with lib;
let nums = genAttrs (map toString (range 1 (min numbered 9))) id;
workspaces = named // nums;
genBinds = (n: k: {
# Focus the workspace
"${mod}+${k}" = "workspace ${n}";
# Move a window to the workspace
"${mod}+Shift+${k}" = "move window to workspace ${n}";
});
keybinds = mapAttrsToList genBinds workspaces; in
mkMerge (keybinds)
);
# Application launchers
genLaunchers = ({ browser }: {
"${mod}+Tab" = "exec ${browser}";
"${mod}+Return" = "exec alacritty";
});
# Layout manipulation
layout = ({
"${mod}+A" = "split v";
"${mod}+S" = "split h";
"${mod}+F" = "fullscreen toggle";
"${mod}+BackSpace" = "kill";
});
# Media-related keys
media = ({ mpc_cli ? null, pulseaudio }: let cmd = "${mpc_cli}/bin/mpc"; in
(optionalAttrs (mpc_cli != null) {
"${mod}+comma" = "exec ${cmd} prev";
"${mod}+period" = "exec ${cmd} next";
"${mod}+slash" = "exec ${cmd} toggle";
}) // (with config.devices; optionalAttrs (audio != null) (with audio; {
# Main speakers
"${mod}+z" = "exec pactl set-sink-volume ${speakers} -10%";
"${mod}+x" = "exec pactl set-sink-volume ${speakers} +10%";
# Secondary output
"${mod}+Alt+z" = "exec pactl set-sink-volume ${external} -10%";
"${mod}+Alt+x" = "exec pactl set-sink-volume ${external} +10%";
} // (optionalAttrs (main-mic != null) {
# Microphone
"${mod}+c" = "exec pactl set-source-mute ${main-mic} toggle";
})))
);
in (mkMerge [
(media { inherit (pkgs) mpc_cli pulseaudio; })
(genDirectional directional)
(genWorkspaces workspace)
(genLaunchers launchers)
layout
])

View file

@ -0,0 +1,10 @@
{ lib, config, pkgs, ... }:
(lib.mkIf (config.riley.gui) {
sound.enable = true;
hardware.pulseaudio.enable = true;
users.users."riley".packages = with pkgs; [
pavucontrol
];
})

View file

@ -0,0 +1,80 @@
{ pkgs, config, lib, ... }:
let theme = config.riley.theme.hex;
modifier = "Mod4";
keybindings = (import ./keybinds.nix {
inherit modifier lib pkgs config;
directional = {
left = "H";
right = "L";
up = "K";
down = "J";
};
workspace = {
numbered = 5;
named = {
"web" = "equal";
"doc" = "minus";
"dev" = "0";
};
};
launchers = {
browser = "google-chrome-stable";
};
});
in (lib.mkIf (config.riley.gui) {
services.xserver = {
enable = true;
windowManager.i3.enable = true;
};
home-manager.users."riley" = {
xsession.windowManager.i3 = {
enable = true;
config = with lib; (rec {
inherit modifier keybindings;
terminal = "${pkgs.alacritty}/bin/alacritty";
colors = {
focused = rec {
background = theme.background.normal;
text = theme."red".bright;
border = background;
childBorder = border;
indicator = border;
};
unfocused = rec {
background = theme.background.normal;
text = theme.foreground.slight;
border = background;
childBorder = border;
indicator = border;
};
focusedInactive = colors.unfocused;
};
window = {
border = 2;
commands = [
{ command = "border pixel 2"; criteria = { class = ".*"; }; }
];
};
fonts = {
names = [ "Source Sans 3" ];
style = "Semibold";
size = 10.0;
};
});
};
};
})

4
modules/ide/README.md Normal file
View file

@ -0,0 +1,4 @@
# Kakoune
This module sets the kakoune editor up like an IDE using language server
modules and plugins.

View file

@ -3,7 +3,7 @@
let kakrc = pkgs.writeTextFile (rec {
name = "kakrc.kak";
destination = "/share/kak/autoload/${name}";
text = with (import ../../colors.nix)."dark"; ''
text = with config.riley.theme; ''
# Line numbering
add-highlighter global/ number-lines -separator ' ' -hlcursor
@ -105,7 +105,7 @@ let kakrc = pkgs.writeTextFile (rec {
# Syntax colors
colors = (import ./colors {
theme = (import ../../colors.nix)."dark";
theme = config.riley.theme;
inherit lib pkgs;
});

18
modules/ssh.nix Normal file
View file

@ -0,0 +1,18 @@
{ config, lib, pkgs, ... }:
{
services.openssh = {
enable = true;
passwordAuthentication = false;
};
users.users."riley" = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGk/nBXhr3xWtbXBBkCuwqE6OixpRXCfscfxibgcCsTR me@riley.lgbt"
];
packages = with pkgs; [ openssh ];
};
}