aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/base/default.nix8
-rw-r--r--modules/base/fish/alias.fish19
-rw-r--r--modules/base/fish/binds.fish1
-rw-r--r--modules/base/fish/config.fish28
-rw-r--r--modules/base/fish/config.nix29
-rw-r--r--modules/base/fish/default.nix10
-rw-r--r--modules/base/fish/functions/__fancy_history.fish5
-rw-r--r--modules/base/fish/functions/__history_previous_command.fish8
-rw-r--r--modules/base/fish/functions/__history_previous_command_arguments.fish9
-rw-r--r--modules/base/fish/functions/__kakoune.fish28
-rw-r--r--modules/base/fish/functions/__skim_cd.fish6
-rw-r--r--modules/base/fish/functions/e.fish12
-rw-r--r--modules/base/fish/functions/fish_prompt.fish34
-rw-r--r--modules/base/fish/functions/fish_right_prompt.fish1
-rw-r--r--modules/base/fish/functions/fish_user_key_bindings.fish6
-rw-r--r--modules/base/fish/functions/gen-shell.fish22
-rw-r--r--modules/base/fish/functions/k.fish18
-rw-r--r--modules/base/fish/functions/nrepl.fish7
-rw-r--r--modules/base/fish/functions/nxs.fish12
-rw-r--r--modules/base/fish/functions/restart.fish3
-rw-r--r--modules/base/fish/functions/rvm.fish40
-rw-r--r--modules/base/fish/functions/search.fish4
-rw-r--r--modules/base/user.nix19
-rw-r--r--modules/nix/default.nix17
-rw-r--r--modules/workstation/chat/default.nix15
-rw-r--r--modules/workstation/default.nix34
-rw-r--r--modules/workstation/devel/default.nix8
-rw-r--r--modules/workstation/devel/java/default.nix7
-rw-r--r--modules/workstation/devel/java/gdx.nix32
-rw-r--r--modules/workstation/devel/java/lwjgl.nix33
-rw-r--r--modules/workstation/devel/rust.nix5
-rw-r--r--modules/workstation/emacs/default.nix41
-rw-r--r--modules/workstation/emacs/init.el85
-rw-r--r--modules/workstation/git/default.nix9
-rw-r--r--modules/workstation/graphics/browser.nix5
-rw-r--r--modules/workstation/graphics/default.nix31
-rw-r--r--modules/workstation/graphics/fonts.nix10
-rw-r--r--modules/workstation/graphics/fun.nix8
-rw-r--r--modules/workstation/graphics/i3/compton.conf20
-rw-r--r--modules/workstation/graphics/i3/config.nix166
-rw-r--r--modules/workstation/graphics/i3/default.nix22
-rwxr-xr-xmodules/workstation/graphics/i3/dynamic-tags/move.sh13
-rwxr-xr-xmodules/workstation/graphics/i3/dynamic-tags/switch.sh9
-rw-r--r--modules/workstation/graphics/i3/i3status.conf47
-rw-r--r--modules/workstation/graphics/i3/locker25
-rw-r--r--modules/workstation/hardware/ckb/default.nix10
-rw-r--r--modules/workstation/hardware/default.nix16
-rw-r--r--modules/workstation/hardware/xkblayout/default.nix16
-rw-r--r--modules/workstation/hardware/yubikey/default.nix14
-rw-r--r--modules/workstation/input/trackpoint.nix17
-rw-r--r--modules/workstation/kitty/default.nix7
-rw-r--r--modules/workstation/kitty/kitty.conf52
-rw-r--r--modules/workstation/mail/default.nix9
-rw-r--r--modules/workstation/mail/pkgs.nix16
-rw-r--r--modules/workstation/mail/timer.nix41
-rw-r--r--modules/workstation/networking/default.nix14
-rw-r--r--modules/workstation/pass/default.nix1
-rw-r--r--modules/workstation/printing/default.nix9
-rw-r--r--modules/workstation/redshift/default.nix7
-rw-r--r--modules/workstation/sound/default.nix5
-rw-r--r--modules/workstation/syncthing/default.nix10
61 files changed, 1215 insertions, 0 deletions
diff --git a/modules/base/default.nix b/modules/base/default.nix
new file mode 100644
index 00000000000..3c135ad5f30
--- /dev/null
+++ b/modules/base/default.nix
@@ -0,0 +1,8 @@
+{ config, ... }:
+
+{
+ imports = [
+ ./fish
+ ./user.nix
+ ];
+}
diff --git a/modules/base/fish/alias.fish b/modules/base/fish/alias.fish
new file mode 100644
index 00000000000..f309b1764ae
--- /dev/null
+++ b/modules/base/fish/alias.fish
@@ -0,0 +1,19 @@
+# Useful
+alias todo="void /home/.local/todo.db"
+alias debug="env RUST_BACKTRACE=1"
+alias stalk="watch -n 0.1"
+alias hib="systemctl hibernate"
+
+# alias nxs="nix run -f '<nixpkgs>'"
+alias hm="home-manager -f $HOME/sys/nixcfg/home.nix"
+
+alias c="cargo"
+alias g="git"
+alias e="emacs"
+alias em="emacs (fzf --height=15 --reverse)"
+alias skcd="cd (sk ~)"
+
+# Jokes
+alias nb="man"
+alias woman="man"
+alias acetrace="ranger"
diff --git a/modules/base/fish/binds.fish b/modules/base/fish/binds.fish
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/modules/base/fish/binds.fish
@@ -0,0 +1 @@
+
diff --git a/modules/base/fish/config.fish b/modules/base/fish/config.fish
new file mode 100644
index 00000000000..633ccbca4fc
--- /dev/null
+++ b/modules/base/fish/config.fish
@@ -0,0 +1,28 @@
+# source $HOME/.cargo/env
+set -gx PATH $HOME/.cargo/bin $PATH
+set -gx PATH $HOME/.local/bin $PATH
+set -gx PATH /usr/sbin $PATH
+set -gx GRAAL_HOME ~/.local/share/graalvm/
+
+# The o bit is a bit of a hack
+# umask u=rw,g=rw,o-rwx
+
+# direnv hook fish | source
+
+# gnome-keyring insists on setting this to itself, even if ssh support is disabled
+set -x SSH_AUTH_SOCK "/run/user/1000/gnupg/S.gpg-agent.ssh"
+
+# Fix some utf-8 errors
+set -x LC_ALL en_GB.utf8
+
+# Include the nix environment
+# fenv source /home/spacekookie/.nix-profile/etc/profile.d/nix.sh
+
+# Better nix-shell support!
+any-nix-shell fish --info-right | source
+
+# Make git use emacs
+set -x EDITOR kak
+
+# tuuuuuuuurbofish!
+set fish_greeting 'Welcome to the '(set_color FF66CC)'::<>' (set_color normal)'...'
diff --git a/modules/base/fish/config.nix b/modules/base/fish/config.nix
new file mode 100644
index 00000000000..85c1c259920
--- /dev/null
+++ b/modules/base/fish/config.nix
@@ -0,0 +1,29 @@
+
+{ pkgs }:
+''
+set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path
+
+
+${builtins.readFile ./functions/__fancy_history.fish }
+
+${builtins.readFile ./config.fish }
+${builtins.readFile ./alias.fish }
+
+${builtins.readFile ./functions/fish_prompt.fish }
+${builtins.readFile ./functions/fish_right_prompt.fish }
+${builtins.readFile ./functions/fish_user_key_bindings.fish }
+${builtins.readFile ./functions/gen-shell.fish }
+${builtins.readFile ./functions/__history_previous_command_arguments.fish }
+${builtins.readFile ./functions/__history_previous_command.fish }
+${builtins.readFile ./functions/__kakoune.fish }
+${builtins.readFile ./functions/e.fish }
+${builtins.readFile ./functions/k.fish }
+${builtins.readFile ./functions/nrepl.fish }
+${builtins.readFile ./functions/nxs.fish }
+${builtins.readFile ./functions/restart.fish }
+${builtins.readFile ./functions/rvm.fish }
+${builtins.readFile ./functions/search.fish }
+${builtins.readFile ./functions/__skim_cd.fish }
+
+${builtins.readFile ./binds.fish}
+''
diff --git a/modules/base/fish/default.nix b/modules/base/fish/default.nix
new file mode 100644
index 00000000000..e73a0acb632
--- /dev/null
+++ b/modules/base/fish/default.nix
@@ -0,0 +1,10 @@
+{ pkgs, ... }:
+
+{
+ home-manager.users.spacekookie = { ... }: {
+ programs.fish.enable = true;
+ programs.fish.shellInit = import ./config.nix { inherit pkgs; };
+ };
+
+ programs.fish.enable = true;
+}
diff --git a/modules/base/fish/functions/__fancy_history.fish b/modules/base/fish/functions/__fancy_history.fish
new file mode 100644
index 00000000000..7ea5a12d417
--- /dev/null
+++ b/modules/base/fish/functions/__fancy_history.fish
@@ -0,0 +1,5 @@
+function __fancy_history --description "history(1) but cool!"
+ set __queried_cmd (history | fzf --height=15 --reverse)
+ commandline -t $__queried_cmd
+ commandline -f repaint
+end
diff --git a/modules/base/fish/functions/__history_previous_command.fish b/modules/base/fish/functions/__history_previous_command.fish
new file mode 100644
index 00000000000..40555452230
--- /dev/null
+++ b/modules/base/fish/functions/__history_previous_command.fish
@@ -0,0 +1,8 @@
+function __history_previous_command
+ switch (commandline -t)
+ case "!"
+ commandline -t $history[1]; commandline -f repaint
+ case "*"
+ commandline -i !
+ end
+end
diff --git a/modules/base/fish/functions/__history_previous_command_arguments.fish b/modules/base/fish/functions/__history_previous_command_arguments.fish
new file mode 100644
index 00000000000..adc8fbd273d
--- /dev/null
+++ b/modules/base/fish/functions/__history_previous_command_arguments.fish
@@ -0,0 +1,9 @@
+function __history_previous_command_arguments
+ switch (commandline -t)
+ case "!"
+ commandline -t ""
+ commandline -f history-token-search-backward
+ case "*"
+ commandline -i '$'
+ end
+end
diff --git a/modules/base/fish/functions/__kakoune.fish b/modules/base/fish/functions/__kakoune.fish
new file mode 100644
index 00000000000..2515edaa00a
--- /dev/null
+++ b/modules/base/fish/functions/__kakoune.fish
@@ -0,0 +1,28 @@
+function __kakoune --description "Wrapper around starting and re-attaching to kakoune sessions"
+ set server_name (basename (pwd) | sed 's/\./-/g')
+ set socket_file (kak -l | grep $server_name)
+ set seek_point $argv[1]
+
+ if test -n ! $seek_point
+ return 130
+ end
+
+ if test -z $socket_file
+ kak -d -s $server_name
+ end
+
+ kak -e "edit $seek_point" -c $server_name
+end
+
+function __kakoune_get_file_list --description "Get list of files to consider for fzf"
+ git status ^ /dev/null > /dev/null
+ if test $status -eq 0
+ git ls-files -oc --exclude-standard
+ else
+ find .
+ end
+end
+
+function __kakoune_get_folder_list --description "Get list of folder to consider for fzf"
+ find . -type d
+end
diff --git a/modules/base/fish/functions/__skim_cd.fish b/modules/base/fish/functions/__skim_cd.fish
new file mode 100644
index 00000000000..b4ae4234bed
--- /dev/null
+++ b/modules/base/fish/functions/__skim_cd.fish
@@ -0,0 +1,6 @@
+function __skim_cd --description "run fzf to find a directory to `cd` into"
+ set directory (find . -type d | fzf --reverse --height=15)
+ if test $status -eq 0
+ cd $directory
+ end
+end
diff --git a/modules/base/fish/functions/e.fish b/modules/base/fish/functions/e.fish
new file mode 100644
index 00000000000..cb3f2d6aaf4
--- /dev/null
+++ b/modules/base/fish/functions/e.fish
@@ -0,0 +1,12 @@
+# Spawn an emacs daemon for a project directory
+function e --description='Setup emacs server and open emacsclient'
+ set session (basename (pwd))
+
+ ps x | grep emacs | grep $session > /dev/null
+
+ if test $status != 0
+ emacs --daemon=$session
+ end
+
+ emacsclient -c -s $session --eval '(fzf)' ^ /dev/null > /dev/null &
+end
diff --git a/modules/base/fish/functions/fish_prompt.fish b/modules/base/fish/functions/fish_prompt.fish
new file mode 100644
index 00000000000..b6280bfbda6
--- /dev/null
+++ b/modules/base/fish/functions/fish_prompt.fish
@@ -0,0 +1,34 @@
+function fish_prompt --description 'Write out the prompt'
+ # Save our status
+ set -l last_status $status
+
+ set -l last_status_string ""
+ if [ $last_status -ne 0 ]
+ printf "%s(%d)%s " (set_color red --bold) $last_status (set_color normal)
+ end
+
+ if not set -q __hostname
+ set -g __hostname (hostname|cut -d . -f 1)
+ end
+
+ set -l color_cwd
+ set -l suffix
+ set -l CLOSEBRAC ]
+ set -l OPENBRAC [
+
+ switch $USER
+ case root toor
+ if set -q fish_color_cwd_root
+ set color_cwd $fish_color_cwd_root
+ else
+ set color_cwd $fish_color_cwd
+ end
+ set suffix '#'
+ case '*'
+ set color_cwd $fish_color_cwd
+ set suffix '>'
+ end
+
+ echo -n -s (set_color FF66CC) ' ❤ ' (set_color normal) '(' "$__hostname" ') ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix "
+ # echo -n -s (set_color FF66CC) ' I love you Kookie <3 Alyssa ' (set_color normal) '(' "$__hostname" ') ' (set_color $color_cwd) (prompt_pwd) (set_color normal) "$suffix "
+end
diff --git a/modules/base/fish/functions/fish_right_prompt.fish b/modules/base/fish/functions/fish_right_prompt.fish
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/modules/base/fish/functions/fish_right_prompt.fish
@@ -0,0 +1 @@
+
diff --git a/modules/base/fish/functions/fish_user_key_bindings.fish b/modules/base/fish/functions/fish_user_key_bindings.fish
new file mode 100644
index 00000000000..9799d461120
--- /dev/null
+++ b/modules/base/fish/functions/fish_user_key_bindings.fish
@@ -0,0 +1,6 @@
+function fish_user_key_bindings
+ # Make `!!` and `!$` work
+ bind ! __history_previous_command
+ bind '$' __history_previous_command_arguments
+ bind \cr __fancy_history
+end
diff --git a/modules/base/fish/functions/gen-shell.fish b/modules/base/fish/functions/gen-shell.fish
new file mode 100644
index 00000000000..0c48fe2a5c3
--- /dev/null
+++ b/modules/base/fish/functions/gen-shell.fish
@@ -0,0 +1,22 @@
+function gen-shell
+ if not test $argv[1]
+ echo "Usage: gen-shell <name>"
+ return 1
+ end
+
+ if test -e default.nix
+ echo "Refusing to override existing `default.nix`!"
+ return 1
+ end
+
+ set name $argv[1]
+ echo "with import <nixpkgs> {};
+
+stdenv.mkDerivation {
+ name = \"$name\";
+ buildInputs = with pkgs; [
+ # Hier könnte Ihre Werbung stehen
+ ];
+}" > default.nix
+ bat default.nix
+end
diff --git a/modules/base/fish/functions/k.fish b/modules/base/fish/functions/k.fish
new file mode 100644
index 00000000000..55b43ad5107
--- /dev/null
+++ b/modules/base/fish/functions/k.fish
@@ -0,0 +1,18 @@
+# Spawn a kak daemon in a project directory and fuzzy open a file
+function k --description='Open kakoune via fzf'
+ # Select a file with `fzf`
+ set file (__kakoune_get_file_list | fzf --height=25 --reverse)
+
+ # Open the file
+ __kakoune $file
+end
+
+function ksm --description "Open a file at an exact line of code"
+ set file (sk --ansi -c 'rg --color=always --line-number "{}"')
+ set entry (echo $file | sed 's/\(\:[0-9]*\).*/\1/' | tr ':' ' ')
+
+ echo $entry
+
+ # Then open the file!
+ __kakoune $entry
+end
diff --git a/modules/base/fish/functions/nrepl.fish b/modules/base/fish/functions/nrepl.fish
new file mode 100644
index 00000000000..75febe575e4
--- /dev/null
+++ b/modules/base/fish/functions/nrepl.fish
@@ -0,0 +1,7 @@
+function nrepl
+ if test $argv[1]
+ nix repl $argv
+ else
+ nix repl '<nixpkgs>'
+ end
+end
diff --git a/modules/base/fish/functions/nxs.fish b/modules/base/fish/functions/nxs.fish
new file mode 100644
index 00000000000..a3fd915bbcc
--- /dev/null
+++ b/modules/base/fish/functions/nxs.fish
@@ -0,0 +1,12 @@
+function nxs
+ if test $argv[1]
+ nix run -f '<nixpkgs>' $argv
+ else
+ if test -e default.nix
+ nix-shell
+ else
+ echo "No `default.nix`"
+ return 1
+ end
+ end
+end
diff --git a/modules/base/fish/functions/restart.fish b/modules/base/fish/functions/restart.fish
new file mode 100644
index 00000000000..191fe791e81
--- /dev/null
+++ b/modules/base/fish/functions/restart.fish
@@ -0,0 +1,3 @@
+function restart
+ clear; exec fish
+end
diff --git a/modules/base/fish/functions/rvm.fish b/modules/base/fish/functions/rvm.fish
new file mode 100644
index 00000000000..834e73e5f75
--- /dev/null
+++ b/modules/base/fish/functions/rvm.fish
@@ -0,0 +1,40 @@
+function rvm --description='Ruby enVironment Manager'
+ # run RVM and capture the resulting environment
+ set --local env_file (mktemp -t rvm.fish.XXXXXXXXXX)
+ # This finds where RVM's root directory is and sources scripts/rvm from within it. Then loads RVM in a clean environment and dumps the environment variables it generates out for us to use.
+ bash -c 'PATH=$GEM_HOME/bin:$PATH;RVMA=$(which rvm);RVMB=$(whereis rvm | sed "s/rvm://");source $(if test $RVMA;then echo $RVMA | sed "s/\/bin\//\/scripts\//";elif test $RVMB; then echo $RVMB | sed "s/rvm/rvm\/scripts\/rvm/"; else echo ~/.rvm/scripts/rvm; fi); rvm "$@"; status=$?; env > "$0"; exit $status' $env_file $argv
+
+ # apply rvm_* and *PATH variables from the captured environment
+ and eval (grep -E '^rvm|^PATH|^GEM_PATH|^GEM_HOME' $env_file | grep -v '_clr=' | sed '/^[^=]*PATH/s/:/" "/g; s/^/set -xg /; s/=/ "/; s/$/" ;/; s/(//; s/)//')
+ # needed under fish >= 2.2.0
+ and set -xg GEM_PATH (echo $GEM_PATH | sed 's/ /:/g')
+
+ # clean up
+ rm -f $env_file
+end
+
+function __handle_rvmrc_stuff --on-variable PWD
+ # Source a .rvmrc file in a directory after changing to it, if it exists.
+ # To disable this feature, set rvm_project_rvmrc=0 in $HOME/.rvmrc
+ if test "$rvm_project_rvmrc" != 0
+ set -l cwd $PWD
+ while true
+ if contains $cwd "" $HOME "/"
+ if test "$rvm_project_rvmrc_default" = 1
+ rvm default 1>/dev/null 2>&1
+ end
+ break
+ else
+ if test -e .rvmrc -o -e .ruby-version -o -e .ruby-gemset
+ eval "rvm reload" > /dev/null
+ eval "rvm rvmrc load" >/dev/null
+ break
+ else
+ set cwd (dirname "$cwd")
+ end
+ end
+ end
+
+ set -e cwd
+ end
+end
diff --git a/modules/base/fish/functions/search.fish b/modules/base/fish/functions/search.fish
new file mode 100644
index 00000000000..11c89dc575d
--- /dev/null
+++ b/modules/base/fish/functions/search.fish
@@ -0,0 +1,4 @@
+function search --description "Finding some code with sk(1) and rg(1)"
+ set SELECTED (sk --ansi -c 'rg --color=always --line-number \"{}\"')
+ echo (cat $SELECTED | sed 's/\(\:[0-9]*\).*/\1/' | tr ':' ' ')
+end
diff --git a/modules/base/user.nix b/modules/base/user.nix
new file mode 100644
index 00000000000..73d4db62461
--- /dev/null
+++ b/modules/base/user.nix
@@ -0,0 +1,19 @@
+{ pkgs, lib, ... }:
+
+let
+ mkDefault = lib.mkOverride ((lib.mkDefault null).priority - 1);
+in
+{
+ users.mutableUsers = false;
+ users.groups.spacekookie = {};
+ users.users.spacekookie = {
+ createHome = true;
+ description = "Katharina Fey";
+ home = mkDefault "/home";
+ uid = mkDefault 1000;
+ group = "qyliss";
+ extraGroups = [ "wheel" ];
+ shell = lib.mkDefault pkgs.fish;
+ };
+}
+
diff --git a/modules/nix/default.nix b/modules/nix/default.nix
new file mode 100644
index 00000000000..cb79a0f2652
--- /dev/null
+++ b/modules/nix/default.nix
@@ -0,0 +1,17 @@
+{ config, pkgs, lib, ... }:
+
+{
+ nix.trustedUsers = [ "@wheel" ];
+
+ nix.nixPath = [
+ "home-manager=/run/current-system/libkookie/home-manager"
+ "nixos-config=/run/current-system/libkookie/configuration.nix"
+ "nixpkgs-overlays=/run/current-system/libkookie/overlays"
+ "nixpkgs=/run/current-system/libkookie/nixpkgs"
+ ];
+
+ system.extraSystemBuilderCmds = ''
+ ln -s ${lib.cleanSource ../..} $out/libkookie
+ '';
+
+}
diff --git a/modules/workstation/chat/default.nix b/modules/workstation/chat/default.nix
new file mode 100644
index 00000000000..5d1a7214d1d
--- /dev/null
+++ b/modules/workstation/chat/default.nix
@@ -0,0 +1,15 @@
+/* REAL-TIME COMMUNICATION CLIENTS
+ *
+ * A bit of a mix of applications and no real configuration
+ */
+
+{ pkgs, ... }:
+
+{
+ home.packages = with pkgs; [
+ dino
+ quasselClient
+ signal-desktop
+ weechat
+ ];
+}
diff --git a/modules/workstation/default.nix b/modules/workstation/default.nix
new file mode 100644
index 00000000000..2b9543dc5f5
--- /dev/null
+++ b/modules/workstation/default.nix
@@ -0,0 +1,34 @@
+/* GENERAL WORKSTATION CONFIGURATION
+ *
+ * A workstation is a computer with it's own screen,
+ * keyboard and (sometimes) mouse. It can also sometimes
+ * play music or print (provided the correct satanic
+ * sacrifice was precured first).
+ *
+ * Some of the modules included by this file depend on
+ * root access on a system (nixos-rebuild), while some
+ * can be operated entirely in userspace.
+ */
+
+{ pkgs, home-manager, ... }:
+
+{
+ home-manager.users.spacekookie = { ... }: {
+ imports = [
+ ./chat
+ ./devel
+ ./emacs
+ ./git
+ ./pass
+ ];
+ };
+
+ imports = [
+ ./graphics
+ ./hardware
+ ./mail
+ ./networking
+ ./sound
+ ./syncthing
+ ];
+}
diff --git a/modules/workstation/devel/default.nix b/modules/workstation/devel/default.nix
new file mode 100644
index 00000000000..cfbdd05d421
--- /dev/null
+++ b/modules/workstation/devel/default.nix
@@ -0,0 +1,8 @@
+{ ... }:
+
+{
+ imports = [
+ ./java
+ ./rust.nix
+ ];
+}
diff --git a/modules/workstation/devel/java/default.nix b/modules/workstation/devel/java/default.nix
new file mode 100644
index 00000000000..aa2cf8d7264
--- /dev/null
+++ b/modules/workstation/devel/java/default.nix
@@ -0,0 +1,7 @@
+/* JAVA DEVELOPMENT MODE
+ *
+ * FIXME: Integrate building libgdx/ lwjgl with nix
+ */
+{ pkgs, ... }: {
+ home.packages = with pkgs; [ eclipses.eclipse-java lombok ];
+}
diff --git a/modules/workstation/devel/java/gdx.nix b/modules/workstation/devel/java/gdx.nix
new file mode 100644
index 00000000000..2e1649fb2a9
--- /dev/null
+++ b/modules/workstation/devel/java/gdx.nix
@@ -0,0 +1,32 @@
+{ stdenv, pkgs, ... }:
+
+with pkgs;
+stdenv.mkDerivation rec {
+ name = "libgdx-${version}";
+ version = "1.9.6";
+
+ src = fetchurl {
+ url = "https://github.com/libgdx/libgdx/archive/${version}.tar.gz";
+ sha256 = "1lxky0cz4qjpw4x06cf2kpa00cj0n0jp3vfsp67jy1d42dqyshgb";
+ };
+
+ buildInputs = [ ant openjdk gcc ];
+
+ buildPhase = "find . -name '*.so' -delete && cd gdx/jni && ant -f build-linux64.xml && cd ../../extensions/gdx-box2d/gdx-box2d/jni && ant -f build-linux64.xml && cd ../../../../";
+
+ installPhase = ''
+ mkdir -p $out/lib
+ cp gdx/libs/linux64/*.so $out/lib
+ cp extensions/gdx-box2d/gdx-box2d/libs/linux64/*.so $out/lib
+ '';
+
+ meta = with stdenv.lib; {
+ description = "Desktop/Android/BlackBerry/iOS/HTML5 Java game development framework";
+ longDescription = '''';
+ homepage = http://libgdx.badlogicgames.com/;
+ license = licenses.asl20;
+ maintainers = with maintainers; [ pmiddend ];
+ platforms = platforms.linux;
+ };
+}
+
diff --git a/modules/workstation/devel/java/lwjgl.nix b/modules/workstation/devel/java/lwjgl.nix
new file mode 100644
index 00000000000..77ab765f207
--- /dev/null
+++ b/modules/workstation/devel/java/lwjgl.nix
@@ -0,0 +1,33 @@
+{ stdenv, pkgs, ... }:
+
+with pkgs;
+stdenv.mkDerivation rec {
+ name = "lwjgl-${version}";
+ version = "2.9.2";
+
+ src = fetchurl {
+ url = "https://github.com/LWJGL/lwjgl/archive/lwjgl${version}.tar.gz";
+ sha256 = "1m396ply3kspym3r00s1rbk77irn2f9vgr76xsy7272k649y3wky";
+ };
+
+ buildInputs = with xorg; [ ant openjdk gcc libX11 libXt libXcursor
+ libXxf86vm libXrandr libXext ];
+
+ buildPhase = "mkdir -p bin && ant generate-all && ant compile && ant compile_native";
+
+ installPhase = ''
+ mkdir -p $out/lib
+ cp bin/lwjgl/*.so $out/lib
+ '';
+
+ meta = with stdenv.lib; {
+ description = "The Lightweight Java Game Library";
+ longDescription = ''
+ LWJGL is a Java library that enables cross-platform access to popular native APIs useful in the development of graphics (OpenGL), audio (OpenAL) and parallel computing (OpenCL) applications. This access is direct and high-performance, yet also wrapped in a type-safe and user-friendly layer, appropriate for the Java ecosystem.
+ '';
+ homepage = http://legacy.lwjgl.org/;
+ license = licenses.bsd3;
+ maintainers = with maintainers; [ pmiddend ];
+ platforms = platforms.linux;
+ };
+}
diff --git a/modules/workstation/devel/rust.nix b/modules/workstation/devel/rust.nix
new file mode 100644
index 00000000000..99758059973
--- /dev/null
+++ b/modules/workstation/devel/rust.nix
@@ -0,0 +1,5 @@
+{ pkgs, ... }:
+
+{
+ home.packages = with pkgs; [ rustup ];
+}
diff --git a/modules/workstation/emacs/default.nix b/modules/workstation/emacs/default.nix
new file mode 100644
index 00000000000..edcf067ae76
--- /dev/null
+++ b/modules/workstation/emacs/default.nix
@@ -0,0 +1,41 @@
+{ pkgs, ... }:
+
+let
+ package = with pkgs; emacsWithPackages (epkgs:
+ (with epkgs; [
+ (runCommand "init.el" {} ''
+ mkdir -p $out/share/emacs/site-lisp
+ cp ${./init.el} $out/share/emacs/site-lisp/default.el
+ '')
+
+ # Custom patched mode
+ pkgs.emacs-ergoemacs-mode
+
+ # Language support
+ fish-mode
+ lsp-mode
+ markdown-mode
+ nim-mode
+ nix-mode
+ python-mode
+ rust-mode
+
+ # Some general improvements
+ company
+ company-lsp
+ color-theme-sanityinc-tomorrow
+ fzf
+ ledger-mode
+ lsp-ui
+ magit
+ notmuch
+ org
+ smex
+ sublimity
+ visual-fill-column
+ yasnippet
+ ]));
+in
+{
+ home.packages = [ package ];
+}
diff --git a/modules/workstation/emacs/init.el b/modules/workstation/emacs/init.el
new file mode 100644
index 00000000000..301ce00a0df
--- /dev/null
+++ b/modules/workstation/emacs/init.el
@@ -0,0 +1,85 @@
+;; Kookie's emacs config
+
+;; More sane line-number behaviour
+(setq display-line-numbers-grow-only 1)
+(setq display-line-numbers-width-start 1)
+(global-display-line-numbers-mode 1)
+
+;; I just need my personal space
+(setq tab-width 2)
+(setq-default indent-tabs-mode nil)
+(defvaralias 'c-basic-offset 'tab-width)
+(defvaralias 'cperl-indent-level 'tab-width)
+
+;;disable splash screen and startup message
+(setq inhibit-startup-message 1)
+(setq initial-scratch-message nil)
+
+;; Swap/Backup files are annoying AF
+(setq make-backup-files nil)
+(setq auto-save-default nil)
+
+;; Some editing niceties
+(delete-selection-mode 1)
+(show-paren-mode 1)
+
+;; Explicitly enable lsp-mode for certain languages
+(add-hook 'rust-mode-hook #'lsp)
+(add-hook 'c-mode-hook #'lsp)
+(add-hook 'c++-mode-hook #'lsp)
+
+(menu-bar-mode -1)
+(tool-bar-mode -1)
+(scroll-bar-mode -1)
+
+(add-hook 'java-mode-hook (local-unset-key "M-a"))
+;; (add-hook 'prog-mode-hook (local-unset-key "M-a"))
+
+(column-number-mode 1)
+(ido-mode 1)
+(add-hook 'find-file-hook (lambda () (ruler-mode 1)))
+
+(require 'color-theme-sanityinc-tomorrow)
+(load-theme 'sanityinc-tomorrow-eighties)
+
+;; More ergonomic keybindings
+(require 'ergoemacs-mode)
+(setq ergoemacs-theme nil)
+(setq ergoemacs-keyboard-layout "us")
+(ergoemacs-mode 1)
+
+;; VTerm integration
+(require 'vterm)
+
+;; Distraction free mode and minimap
+(require 'sublimity)
+(require 'sublimity-map)
+(require 'sublimity-attractive)
+
+(setq sublimity-map-size 10)
+(setq sublimity-map-fraction 0.5)
+(setq sublimity-map-text-scale -7)
+
+;; Display minimap without delay
+(sublimity-map-set-delay nil)
+
+;; This is require for lsp-mode
+(require 'yasnippet)
+
+;; Better completion handling with lsp-mode
+(require 'company-lsp)
+(push 'company-lsp company-backends)
+(setq lsp-ui-doc-max-width 45)
+(setq lsp-ui-doc-max-height 10)
+
+;; Turns out I'm a huge dork
+(setq emacs-anchor default-directory)
+(defun mitosis () (interactive) (make-frame))
+
+;; Setup RSS feeds
+(setq elfeed-feeds
+ '(("https://alyssa.is/feed.xml" girlfriend blog)
+ ("https://spacekookie.de/rss.xml" self blog)
+ ("https://xkcd.com/rss.xml" webcomic)
+ ("https://deterministic.space/feed.xml" rust blog)
+ ))
diff --git a/modules/workstation/git/default.nix b/modules/workstation/git/default.nix
new file mode 100644
index 00000000000..c5a6d854850
--- /dev/null
+++ b/modules/workstation/git/default.nix
@@ -0,0 +1,9 @@
+{ pkgs, ... }:
+
+let
+ git = (pkgs.git.override { svnSupport = true; sendEmailSupport = true; });
+in
+{
+ home.packages = [ git ]
+ ++ (with pkgs; [ gitAndTools.hub ]);
+}
diff --git a/modules/workstation/graphics/browser.nix b/modules/workstation/graphics/browser.nix
new file mode 100644
index 00000000000..8fc60dd03df
--- /dev/null
+++ b/modules/workstation/graphics/browser.nix
@@ -0,0 +1,5 @@
+{ pkgs, ... }:
+
+{
+ home.packages = [ pkgs.firefox ];
+}
diff --git a/modules/workstation/graphics/default.nix b/modules/workstation/graphics/default.nix
new file mode 100644
index 00000000000..5f902759d8f
--- /dev/null
+++ b/modules/workstation/graphics/default.nix
@@ -0,0 +1,31 @@
+{ pkgs, ... }:
+
+{
+ services.xserver = {
+ enable = true;
+ desktopManager = {
+ default = "xfce";
+ xfce = {
+ enable = true;
+ noDesktop = true;
+ enableXfwm = false;
+ };
+ };
+ windowManager.i3.enable = true;
+
+ videoDrivers = [ "intel" ];
+ deviceSection = ''
+ Option "DRI" "2"
+ Option "TearFree" "true"
+ '';
+ useGlamor = true;
+ };
+
+ home-manager.users.spacekookie = { ... }: {
+ imports = [
+ ./i3
+ ./browser.nix
+ ./fun.nix
+ ];
+ };
+}
diff --git a/modules/workstation/graphics/fonts.nix b/modules/workstation/graphics/fonts.nix
new file mode 100644
index 00000000000..a754da54b43
--- /dev/null
+++ b/modules/workstation/graphics/fonts.nix
@@ -0,0 +1,10 @@
+{ pkgs, ... }:
+
+{
+ fonts.fonts = with pkgs; [
+ google-fonts
+ inconsolata
+ iosevka
+ twemoji-color-font
+ ];
+}
diff --git a/modules/workstation/graphics/fun.nix b/modules/workstation/graphics/fun.nix
new file mode 100644
index 00000000000..56a6b4c0aef
--- /dev/null
+++ b/modules/workstation/graphics/fun.nix
@@ -0,0 +1,8 @@
+{ pkgs, ... }:
+
+{
+ home.packages = with pkgs; [
+ spotify
+ steam
+ ];
+}
diff --git a/modules/workstation/graphics/i3/compton.conf b/modules/workstation/graphics/i3/compton.conf
new file mode 100644
index 00000000000..a632c022593
--- /dev/null
+++ b/modules/workstation/graphics/i3/compton.conf
@@ -0,0 +1,20 @@
+unredir-if-possible = false;
+vsync = "opengl";
+
+### Opacity
+menu-opacity = 0.90;
+frame-opacity = 0.90; # i.e. titlebars, borders
+inactive-opacity-override = false;
+alpha-step = 0.06;
+
+### Blur options
+blur-background = true;
+blur-background-frame = true;
+# blur-kern = "3x3box"
+# blur-kern = "5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"
+# blur-background-fixed = true;
+blur-background-exclude = [ "window_type = 'dock'", "window_type = 'desktop'" ];
+
+# # Detect rounded corners and treat them as rectangular when --shadow-ignore-shaped is on.
+detect-rounded-corners = true;
+detect-client-opacity = true
diff --git a/modules/workstation/graphics/i3/config.nix b/modules/workstation/graphics/i3/config.nix
new file mode 100644
index 00000000000..746c2a47698
--- /dev/null
+++ b/modules/workstation/graphics/i3/config.nix
@@ -0,0 +1,166 @@
+{ pkgs, wallpaper }:
+
+{
+ enable = true;
+ package = pkgs.i3;
+ config = rec {
+ modifier = "Mod4";
+
+ # Use iosevka as default font
+ fonts = [ "iosevka-term-ss09 10" ];
+
+ keybindings = {
+
+ # Start a terminal
+ "${modifier}+Return" = "exec kitty";
+
+ # Close individual windows
+ "${modifier}+Shift+q" = "kill";
+
+ # Full-screen window
+ "${modifier}+f" = "fullscreen";
+
+ # Start software on <this> or <other> workspace
+ "${modifier}+d" = "exec dmenu_run";
+ "${modifier}+Shift+d" = "exec ~/.config/i3/dynamic-tags/move.sh";
+
+ # Move focus around - vim style
+ "${modifier}+h" = "focus left";
+ "${modifier}+j" = "focus down";
+ "${modifier}+k" = "focus up";
+ "${modifier}+l" = "focus right";
+
+ # Move focus around - boring style
+ "${modifier}+Up" = "focus up";
+ "${modifier}+Down" = "focus down";
+ "${modifier}+Left" = "focus left";
+ "${modifier}+Right" = "focus right";
+
+ # Move windows - vim style
+ "${modifier}+Shift+k" = "move up";
+ "${modifier}+Shift+j" = "move down";
+ "${modifier}+Shift+h" = "move left";
+ "${modifier}+Shift+l" = "move right";
+
+ # Move windows - boring style
+ "${modifier}+Shift+Up" = "move up";
+ "${modifier}+Shift+Down" = "move down";
+ "${modifier}+Shift+Left" = "move left";
+ "${modifier}+Shift+Right" = "move right";
+
+ # Move workspaces between multi-monitor setups
+ "${modifier}+Ctrl+Shift+Up" = "move workspace to output up";
+ "${modifier}+Ctrl+Shift+Down" = "move workspace to output down";
+ "${modifier}+Ctrl+Shift+Left" = " move workspace to output left";
+ "${modifier}+Ctrl+Shift+Right" = "move workspace to output right";
+
+ # Define split behaviours
+ "${modifier}+2" = "split h";
+ "${modifier}+1" = "split v";
+
+ # A very fortunate lockscreen
+ "${modifier}+Ctrl+l" = "exec --no-startup-id i3lock -c 333333";
+ "${modifier}+Ctrl+Shift+l" = "exec --no-startup-id systemctl hibernate";
+
+ # Rename workspaces
+ "${modifier}+Ctrl+r" = "exec i3-input -F 'rename workspace to \"%s\"' -P 'New name: '";
+
+ # Switch to workspace (optionally dragging windows with)
+ "${modifier}+s" = "exec ~/.config/i3/dynamic-tags/switch.sh -fn '$dfont'";
+ "${modifier}+Shift+s" = "exec ~/.config/i3/dynamic-tags/move.sh -fn '$dfont'";
+
+ # Some layout modifiers
+ "${modifier}+e" = "layout default";
+ "${modifier}+w" = "layout tabbed";
+ "${modifier}+q" = "layout stacked";
+
+ # Do I even use this?!
+ "${modifier}+Shift+space" = "floating toggle";
+ "${modifier}+space" = "focus mode_toggle";
+
+ # Focus the parent containers
+ "${modifier}+a" = "focus parent";
+
+ # Audio is good actually
+ "XF86AudioRaiseVolume" = "exec --no-startup-id pactl set-sink-volume 0 +5%";
+ "XF86AudioLowerVolume" = "exec --no-startup-id pactl set-sink-volume 0 -5%";
+ "XF86AudioMute" = "exec --no-startup-id pactl set-sink-mute 0 toggle";
+
+ # Reload, restart and quit i3
+ "${modifier}+Shift+c" = "reload";
+ "${modifier}+Shift+r" = "restart";
+ "${modifier}+Shift+e" = ''
+ exec i3-nagbar -t warning -m "Workspaces are sentient, you know. \
+ We just have a lot of them" "i3-msg exit"
+ '';
+
+ # Switch to resize mode (defined below)
+ "${modifier}+r" = "mode \"resize\"";
+
+ # FIXME: What was this again?!
+ "button4" = "nop";
+ "button5" = "nop";
+ };
+
+ modes = {
+
+ # Explicitly handle the resize mode
+ resize = {
+ "h" = "resize shrink width 5 px or 5 ppt";
+ "j" = "resize grow height 5 px or 5 ppt";
+ "k" = "resize shrink height 5 px or 5 ppt";
+ "l" = "resize grow width 5 px or 5 ppt";
+
+ # same bindings, but for the arrow keys
+ "Left" = "resize shrink width 5 px or 5 ppt";
+ "Down" = "resize grow height 5 px or 5 ppt";
+ "Up" = "resize shrink height 5 px or 5 ppt";
+ "Right" = "resize grow width 5 px or 5 ppt";
+
+ # back to normal: Enter or Escape or $mod+r
+ "Return" = "mode \"default\"";
+ "Escape" = "mode \"default\"";
+ "${modifier}+r" = "mode \"default\"";
+ } ;
+ };
+
+ # The `bars` module does weird stuff so we init it ourselves
+ bars = [];
+ };
+
+ extraConfig = with pkgs; ''
+ # Compton
+ exec_always --no-startup-id "pkill compton; ${compton}/bin/compton \
+ --config ~/.config/i3/compton.conf"
+
+ # Make CAPSLOCK into ESC because it's 2018
+ #
+ # Okay actually this is slightly more complicated than that. Actually I'm
+ # binding CAPSLOCK to HYPER, so that I can use it as a modifier in emacs,
+ # but then using xcape(1) to also make short CAPSLOCK presses into ESCAPE.
+
+ exec_always --no-startup-id "${xorg.xmodmap}/bin/setxkbmap \
+ -layout us -variant altgr-intl -option caps:hyper"
+ exec ${xcape}/bin/xcape -e "#66=Escape" -t 150
+
+ # Always set a wallpaper
+ exec_always --no-startup-id ${feh}/bin/feh --bg-fill ${wallpaper}
+
+ bar {
+ status_command i3status -c ~/.config/i3/i3status.conf
+ position bottom
+ bindsym button4 nop
+ bindsym button5 nop
+ colors {
+ background #0F0F0F
+ statusline #D5D5D5
+ }k
+ }
+
+ focus_follows_mouse no
+
+ # Layout and design settings that should _really_ be in the module
+ default_border pixel 3
+ client.focused #4c7899 #285577 #ffffff #F73E5F #666666
+ '';
+}
diff --git a/modules/workstation/graphics/i3/default.nix b/modules/workstation/graphics/i3/default.nix
new file mode 100644
index 00000000000..251b04ec202
--- /dev/null
+++ b/modules/workstation/graphics/i3/default.nix
@@ -0,0 +1,22 @@
+{ pkgs, ... }:
+
+let
+ wallpaper = "~/pictures/wallpaper/my-cyber-city-4k-28-2560x1440.jpg";
+in
+{
+ xsession.windowManager.i3 = import ./config.nix { inherit pkgs wallpaper; };
+
+ xdg.configFile."i3/dynamic-tags/" = {
+ recursive = true;
+ executable = true;
+ source = ./dynamic-tags;
+ };
+
+ xdg.configFile."i3/compton.conf" = {
+ source = ./compton.conf;
+ };
+
+ xdg.configFile."i3/i3status.conf" = {
+ source = ./i3status.conf;
+ };
+}
diff --git a/modules/workstation/graphics/i3/dynamic-tags/move.sh b/modules/workstation/graphics/i3/dynamic-tags/move.sh
new file mode 100755
index 00000000000..84f39fdc3ac
--- /dev/null
+++ b/modules/workstation/graphics/i3/dynamic-tags/move.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+### Move a window to a given workspace. If it doesn't exist it creates it.
+
+I3MSG=$(command -v i3-msg) || exit 1
+JQ=$(command -v jq) || exit 2
+
+WORKSPACE=$($I3MSG -t get_workspaces | $JQ -M '.[] | .name' | tr -d '"' | sort -u | dmenu -b -i "$@")
+
+# Move the window first
+$I3MSG -t command move workspace $WORKSPACE
+
+# Then move the user
+$I3MSG workspace $WORKSPACE
diff --git a/modules/workstation/graphics/i3/dynamic-tags/switch.sh b/modules/workstation/graphics/i3/dynamic-tags/switch.sh
new file mode 100755
index 00000000000..9c50eb48083
--- /dev/null
+++ b/modules/workstation/graphics/i3/dynamic-tags/switch.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+### Move the focus to a particular workspace using dmenu.
+
+set -u
+
+I3MSG=$(command -v i3-msg) || exit 1
+JQ=$(command -v jq) || exit 2
+
+$I3MSG workspace $($I3MSG -t get_workspaces | $JQ -M '.[] | .name' | tr -d '"' | sort -u | dmenu -b -i "$@")
diff --git a/modules/workstation/graphics/i3/i3status.conf b/modules/workstation/graphics/i3/i3status.conf
new file mode 100644
index 00000000000..fb36d20e7a0
--- /dev/null
+++ b/modules/workstation/graphics/i3/i3status.conf
@@ -0,0 +1,47 @@
+# i3status configuration file.
+# see "man i3status" for documentation.
+
+# It is important that this file is edited as UTF-8.
+# The following line should contain a sharp s:
+# ß
+# If the above line is not correctly displayed, fix your editor first!
+
+general {
+ colors = true
+ interval = 5
+}
+
+order += "ipv6"
+order += "disk /"
+order += "wireless _first_"
+order += "ethernet _first_"
+order += "battery all"
+order += "load"
+order += "tztime local"
+
+wireless _first_ {
+ format_up = "W: (%quality at %essid) %ip"
+ format_down = "W: <down>"
+}
+
+ethernet _first_ {
+ # if you use %speed, i3status requires root privileges
+ format_up = "E: %ip (%speed)"
+ format_down = "E: <down>"
+}
+
+battery all {
+ format = "%status %percentage"
+}
+
+tztime local {
+ format = "%Y-%m-%d %H:%M:%S"
+}
+
+load {
+ format = "%1min"
+}
+
+disk "/" {
+ format = "%avail"
+}
diff --git a/modules/workstation/graphics/i3/locker b/modules/workstation/graphics/i3/locker
new file mode 100644
index 00000000000..af64e74eb6b
--- /dev/null
+++ b/modules/workstation/graphics/i3/locker
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+BASEDIR="/tmp/i3lock"
+ICON="/usr/share/i3lock-fancy/icons/lock.png"
+IMAGE="$BASEDIR/lock.png"
+FORTUNE=$(fortune | sed -e 's/\t/ /g')
+TMP_RES=$(xrandr | grep \* | cut -d' ' -f4 | sed ':a;N;$!ba;s/\n/ /g')
+RESOLUTION=(`echo $TMP_RES | sed 's/ /\n/g'`)
+
+mkdir -p "$BASEDIR"
+convert -size 0x0 canvas:black "$IMAGE"
+
+for monitor in "${RESOLUTION[@]}"
+do
+ echo "Running for monitor $monitor"
+ TMPLOCK="/tmp/i3lock/tmplock.png"
+ convert -size "$monitor" canvas:black -font Inconsolata -pointsize 18 \
+ -fill white -gravity center -annotate +0+250 "$FORTUNE" \
+ "$ICON" -gravity center -composite "$TMPLOCK"
+ convert "$IMAGE" "$TMPLOCK" +append "$IMAGE"
+ rm "$TMPLOCK"
+done
+
+i3lock -i "$IMAGE"
+
diff --git a/modules/workstation/hardware/ckb/default.nix b/modules/workstation/hardware/ckb/default.nix
new file mode 100644
index 00000000000..88d8592d48a
--- /dev/null
+++ b/modules/workstation/hardware/ckb/default.nix
@@ -0,0 +1,10 @@
+/* CORSAIR KEYBOARD SUPPORT
+ *
+ * Setup the K65 corsair keyboard daemon
+ * with themes properly
+ */
+{ config, ... }:
+
+{
+ (builtins.abort "CKB module not implemented!")
+}
diff --git a/modules/workstation/hardware/default.nix b/modules/workstation/hardware/default.nix
new file mode 100644
index 00000000000..28f684b5906
--- /dev/null
+++ b/modules/workstation/hardware/default.nix
@@ -0,0 +1,16 @@
+/* HARDWARE SUPPORT MODULE
+ *
+ * This module doesn't include ALL submodules because
+ * some are only relevant for specific platforms. Still
+ * the general support should be provided by the
+ * WORKSTATION module, not be bound to be device specific
+ */
+
+{ ... }:
+
+{
+ imports = [
+ ./yubikey
+ ./xkblayout
+ ];
+}
diff --git a/modules/workstation/hardware/xkblayout/default.nix b/modules/workstation/hardware/xkblayout/default.nix
new file mode 100644
index 00000000000..1fa51cc0527
--- /dev/null
+++ b/modules/workstation/hardware/xkblayout/default.nix
@@ -0,0 +1,16 @@
+/* KEYBOARD LAYOUT MODULE
+ *
+ * (INCOMPLETE) Setup keyboard layout
+ * and overrides. Currently this is
+ * mostly handled by GRAPHICS/I3 but
+ * should maybe be moved here?
+ */
+{ pkgs, config, ... }:
+
+{
+ i18n.consoleUseXkbConfig = true;
+ services.xserver.layout = "us";
+
+ # environment.variables.XKB_DEFAULT_LAYOUT = xcfg.layout;
+ # environment.variables.XKB_DEFAULT_OPTIONS = xcfg.xkbOptions;
+}
diff --git a/modules/workstation/hardware/yubikey/default.nix b/modules/workstation/hardware/yubikey/default.nix
new file mode 100644
index 00000000000..851f9acea39
--- /dev/null
+++ b/modules/workstation/hardware/yubikey/default.nix
@@ -0,0 +1,14 @@
+{ pkgs, ... }:
+
+{
+ services.udev.packages = with pkgs; [ yubikey-personalization ];
+
+ # FIXME: Can I remove these?
+ # Previously these rules were required to make
+ # Yubikey support work on `uwu`, but maybe this
+ # is redundant with special udev rules?
+ environment.systemPackages = with pkgs; [
+ yubikey-manager
+ yubikey-personalization
+ ];
+}
diff --git a/modules/workstation/input/trackpoint.nix b/modules/workstation/input/trackpoint.nix
new file mode 100644
index 00000000000..e4019d6361d
--- /dev/null
+++ b/modules/workstation/input/trackpoint.nix
@@ -0,0 +1,17 @@
+/* TRACKPOINT INPUT CONFIGURATION
+ *
+ * This is a compatibility module for Thinkpad computers
+ */
+
+{ config, .... }: {
+ services.xserver.libinput = {
+ accelProfile = "flat";
+ accelSpeed = "-0.2";
+ scrollButton = 2;
+ };
+
+ hardware.trackpoint = {
+ enable = true;
+ emulateWheel = true;
+ };
+}
diff --git a/modules/workstation/kitty/default.nix b/modules/workstation/kitty/default.nix
new file mode 100644
index 00000000000..aa7f697b3f8
--- /dev/null
+++ b/modules/workstation/kitty/default.nix
@@ -0,0 +1,7 @@
+{ pkgs, ... }: {
+ home.packages = [ pkgs.kitty ];
+
+ xdg.configFile."kitty/kitty.conf" = {
+ source = ./kitty.conf;
+ };
+}
diff --git a/modules/workstation/kitty/kitty.conf b/modules/workstation/kitty/kitty.conf
new file mode 100644
index 00000000000..ab8c6a059f7
--- /dev/null
+++ b/modules/workstation/kitty/kitty.conf
@@ -0,0 +1,52 @@
+font_size 10
+font_familt twemoji-color-font
+
+open_url_modifiers ctrl+shift
+open_url_with default
+
+term xterm-256color
+
+background_opacity 0.85
+
+selection_foreground #93a1a1
+selection_background #073642
+active_border_color #00ff00
+inactive_border_color #cccccc
+cursor #ffffff
+cursor_shape block
+
+foreground #c5c8c6
+background #1d1f21
+
+# black
+color0 #1d1f21
+color8 #969896
+
+# red
+color1 #cc6666
+color9 #cc6666
+
+# green
+color2 #b5bd68
+color10 #b5bd68
+
+# yellow
+color3 #f0c674
+color11 #f0c674
+
+# blue
+color4 #81a2be
+color12 #81a2be
+
+# magenta
+color5 #b294bb
+color13 #b294bb
+
+# cyan
+color6 #8abeb7
+color14 #8abeb7
+
+# white
+color7 #c5c8c6
+color15 #ffffff
+
diff --git a/modules/workstation/mail/default.nix b/modules/workstation/mail/default.nix
new file mode 100644
index 00000000000..eda0ecf609c
--- /dev/null
+++ b/modules/workstation/mail/default.nix
@@ -0,0 +1,9 @@
+{ pkgs, ... }:
+
+{
+ home-manager.users.spacekookie = { ... }: {
+ imports = [ ./pkgs.nix ];
+ };
+
+ imports = [ ./timer.nix ];
+}
diff --git a/modules/workstation/mail/pkgs.nix b/modules/workstation/mail/pkgs.nix
new file mode 100644
index 00000000000..380e1b530a6
--- /dev/null
+++ b/modules/workstation/mail/pkgs.nix
@@ -0,0 +1,16 @@
+/* USERSPACE MAIL CONFIGURATION
+ *
+ * This module depends on the `ext` hook in the repo
+ * root, because it includes private config files
+ * that contain sensitive information.
+ */
+
+{ pkgs, ... }:
+
+{
+ home.packages = with pkgs; [ neomutt notmuch ];
+# imports = [
+# ../../../ext/mail/neomutt.nix
+# ../../../ext/mail/notmuch.nix
+# ];
+}
diff --git a/modules/workstation/mail/timer.nix b/modules/workstation/mail/timer.nix
new file mode 100644
index 00000000000..468ae263cd0
--- /dev/null
+++ b/modules/workstation/mail/timer.nix
@@ -0,0 +1,41 @@
+{ pkgs, config, ... }:
+
+{
+ environment.systemPackages = with pkgs; [ isync ];
+
+ systemd.services.isync =
+ let
+ maildir = "${config.users.users.spacekookie.home}/office/mail";
+ mbsyncrc = pkgs.writeText "mbsyncrc"
+ (import ../../../ext/mail/mbsyncrc.nix { inherit maildir; });
+ in with pkgs; {
+ serviceConfig.Type = "oneshot";
+ script = ''
+ ${sudo}/bin/sudo -u spacekookie-mail \
+ ${isync}/bin/mbsync -a -V -c ${mbsyncrc}
+ '';
+ postStart = ''
+ ${findutils}/bin/find \
+ "${maildir}" \
+ \! -name .mbsyncstate* \
+ \( \
+ \( \! -user spacekookie -o \! -group spacekookie \) \
+ -exec ${coreutils}/bin/chown spacekookie:spacekookie '{}' \; \
+ , \
+ -type f \! -perm 660 \
+ -exec ${coreutils}/bin/chmod 0660 '{}' \; \
+ , \
+ -type d \! -perm 770 \
+ -exec ${coreutils}/bin/chmod 0770 '{}' \; \
+ \)
+ '';
+ };
+
+ systemd.timers.isync = {
+ timerConfig.Unit = "isync.service";
+ timerConfig.OnCalendar = "*:0/5";
+ timerConfig.Persistent = "true";
+ after = [ "network-online.target" ];
+ wantedBy = [ "timers.target" ];
+ };
+}
diff --git a/modules/workstation/networking/default.nix b/modules/workstation/networking/default.nix
new file mode 100644
index 00000000000..c90ad9b81fc
--- /dev/null
+++ b/modules/workstation/networking/default.nix
@@ -0,0 +1,14 @@
+{ config, ... }:
+
+{
+ networking = {
+ networkmanager = {
+ enable = true;
+ extraConfig = ''
+ rc-manager="resolvconf";
+ '';
+ };
+
+ firewall.enable = true;
+ };
+}
diff --git a/modules/workstation/pass/default.nix b/modules/workstation/pass/default.nix
new file mode 100644
index 00000000000..c157af788ee
--- /dev/null
+++ b/modules/workstation/pass/default.nix
@@ -0,0 +1 @@
+{ ... }: {}
diff --git a/modules/workstation/printing/default.nix b/modules/workstation/printing/default.nix
new file mode 100644
index 00000000000..72a0c54e893
--- /dev/null
+++ b/modules/workstation/printing/default.nix
@@ -0,0 +1,9 @@
+{ pkgs, ... }:
+
+{
+ services.printing = {
+ enable = true;
+ drivers = [ pkgs.foo2zjs ];
+ };
+}
+
diff --git a/modules/workstation/redshift/default.nix b/modules/workstation/redshift/default.nix
new file mode 100644
index 00000000000..3649b2a38d7
--- /dev/null
+++ b/modules/workstation/redshift/default.nix
@@ -0,0 +1,7 @@
+{ ... }: {
+ services.redshift = {
+ enable = true;
+ temperatre.night = 3500;
+ provider = "geoclue2";
+ };
+}
diff --git a/modules/workstation/sound/default.nix b/modules/workstation/sound/default.nix
new file mode 100644
index 00000000000..5d10b71ffdc
--- /dev/null
+++ b/modules/workstation/sound/default.nix
@@ -0,0 +1,5 @@
+{ ... }: {
+ sound.enable = true;
+ hardware.pulseaudio.enable = true;
+ hardware.pulseaudio.zeroconf.discovery.enable = true;
+}
diff --git a/modules/workstation/syncthing/default.nix b/modules/workstation/syncthing/default.nix
new file mode 100644
index 00000000000..28aee522801
--- /dev/null
+++ b/modules/workstation/syncthing/default.nix
@@ -0,0 +1,10 @@
+{ pkgs, ... }: {
+ services.syncthing = {
+ enable = true;
+ dataDir = "/home/.local/syncthing/";
+ user = "spacekookie";
+ group = "spacekookie";
+ openDefaultPorts = false;
+ guiAddress = "localhost:1234";
+ };
+}