diff options
Diffstat (limited to 'users/grfn/system')
59 files changed, 4666 insertions, 0 deletions
diff --git a/users/grfn/system/.gitignore b/users/grfn/system/.gitignore new file mode 100644 index 000000000000..41fbeb02c47d --- /dev/null +++ b/users/grfn/system/.gitignore @@ -0,0 +1 @@ +**/result diff --git a/users/grfn/system/home/.skip-subtree b/users/grfn/system/home/.skip-subtree new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/users/grfn/system/home/.skip-subtree diff --git a/users/grfn/system/home/common/solarized.nix b/users/grfn/system/home/common/solarized.nix new file mode 100644 index 000000000000..554ee0523e46 --- /dev/null +++ b/users/grfn/system/home/common/solarized.nix @@ -0,0 +1,18 @@ +rec { + base03 = "#002B36"; + base02 = "#073642"; + base01 = "#586e75"; + base00 = "#657b83"; + base0 = "#839496"; + base1 = "#93a1a1"; + base2 = "#eee8d5"; + base3 = "#fdf6e3"; + yellow = "#b58900"; + orange = "#cb4b16"; + red = "#dc322f"; + magenta = "#d33682"; + violet = "#6c71c4"; + blue = "#268bd2"; + cyan = "#2aa198"; + green = "#859900"; +} diff --git a/users/grfn/system/home/default.nix b/users/grfn/system/home/default.nix new file mode 100644 index 000000000000..874d7b2cb281 --- /dev/null +++ b/users/grfn/system/home/default.nix @@ -0,0 +1,32 @@ +{ pkgs, depot, lib, ... }: + +with lib; + +rec { + home = confPath: (import (pkgs.home-manager.src + "/modules") { + inherit pkgs; + + configuration = { config, lib, ... }: { + imports = [ confPath ]; + lib.depot = depot; + + # home-manager exposes no API to override the package set that + # is used, unless called from the NixOS module. + # + # To get around it, the module argument is overridden here. + _module.args.pkgs = mkForce pkgs; + }; + }); + + dobharchu = home ./machines/dobharchu.nix; + + dobharchuHome = dobharchu.activation-script; + + yeren = home ./machines/yeren.nix; + + yerenHome = yeren.activation-script; + + meta.ci.targets = [ + "yerenHome" + ]; +} diff --git a/users/grfn/system/home/home.nix b/users/grfn/system/home/home.nix new file mode 100644 index 000000000000..39045c147d76 --- /dev/null +++ b/users/grfn/system/home/home.nix @@ -0,0 +1,20 @@ +{ config, pkgs, ... }: + +{ + imports = [ + (throw "Pick a machine from ./machines") + ]; + + # Let Home Manager install and manage itself. + programs.home-manager.enable = true; + + # This value determines the Home Manager release that your + # configuration is compatible with. This helps avoid breakage + # when a new Home Manager release introduces backwards + # incompatible changes. + # + # You can update Home Manager without changing this value. See + # the Home Manager release notes for a list of state version + # changes in each release. + home.stateVersion = "19.09"; +} diff --git a/users/grfn/system/home/machines/dobharchu.nix b/users/grfn/system/home/machines/dobharchu.nix new file mode 100644 index 000000000000..0b8503a00e98 --- /dev/null +++ b/users/grfn/system/home/machines/dobharchu.nix @@ -0,0 +1,17 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ../platforms/darwin.nix + ../modules/common.nix + ../modules/games.nix + ]; + + home.packages = with pkgs; [ + coreutils + gnupg + nix-prefetch-github + pass + pinentry_mac + ]; +} diff --git a/users/grfn/system/home/machines/roswell.nix b/users/grfn/system/home/machines/roswell.nix new file mode 100644 index 000000000000..ee3a557fa047 --- /dev/null +++ b/users/grfn/system/home/machines/roswell.nix @@ -0,0 +1,55 @@ +{ pkgs, lib, config, ... }: + +let + laptopKeyboardId = "5"; +in + +{ + imports = [ + ../platforms/linux.nix + ../modules/shell.nix + ../modules/development.nix + ../modules/emacs.nix + ../modules/vim.nix + ]; + + home.packages = with pkgs; [ + # System utilities + bat + htop + killall + bind + zip + unzip + tree + nmap + bc + pv + + # Security + gnupg + keybase + openssl + + # Nix things + nixfmt + nix-prefetch-github + nix-review + cachix + ]; + + programs.password-store.enable = true; + + programs.home-manager.enable = true; + home.stateVersion = "20.03"; + + xsession.enable = lib.mkForce false; + + services.lorri.enable = true; + + programs.direnv = { + enable = true; + enableBashIntegration = true; + enableZshIntegration = true; + }; +} diff --git a/users/grfn/system/home/machines/yeren.nix b/users/grfn/system/home/machines/yeren.nix new file mode 100644 index 000000000000..7f5b610f9b0f --- /dev/null +++ b/users/grfn/system/home/machines/yeren.nix @@ -0,0 +1,82 @@ +{ pkgs, lib, config, ... }: + +let + inherit (builtins) pathExists; + laptopKeyboardId = "5"; +in + +{ + imports = [ + ../platforms/linux.nix + ../modules/common.nix + ../modules/development/readyset.nix + ] ++ (lib.optional (pathExists ../modules/private.nix) ../modules/private.nix); + + # for when hacking + programs.home-manager.enable = true; + home.stateVersion = "20.03"; + + system.machine = { + wirelessInterface = "wlp0s20f3"; + i3FontSize = 9; + }; + + home.packages = with pkgs; [ + zoom-us + slack + mysql + graphviz + gnuplot + mypaint + xdot + tdesktop + subsurface + + (discord.override rec { + version = "0.0.16"; + src = fetchurl { + url = "https://dl.discordapp.net/apps/linux/${version}/discord-${version}.tar.gz"; + sha256 = "1s9qym58cjm8m8kg3zywvwai2i3adiq6sdayygk2zv72ry74ldai"; + }; + }) + + steam + ]; + + systemd.user.services.laptop-keyboard = { + Unit = { + Description = "Swap caps+escape and alt+super, but only on the built-in laptop keyboard"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + + Service = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = ( + "${pkgs.xorg.setxkbmap}/bin/setxkbmap " + + "-device ${laptopKeyboardId} " + + "-option caps:swapescape " + + "-option compose:ralt " + + "-option altwin:swap_alt_win" + ); + }; + }; + + xsession.windowManager.i3.config.keybindings.F9 = "exec lock"; + + xdg.mimeApps.defaultApplications."x-scheme-handler/tg" = + "telegramdesktop.desktop"; + + programs.zsh.shellAliases = { + "graph" = "curl -s localhost:6033/graph | dot -Tpng | feh -"; + }; + + programs.ssh.matchBlocks."grfn-dev" = { + host = "grfn-dev"; + forwardAgent = true; + user = "ubuntu"; + }; +} diff --git a/users/grfn/system/home/modules/alacritty.nix b/users/grfn/system/home/modules/alacritty.nix new file mode 100644 index 000000000000..67d6638a31f8 --- /dev/null +++ b/users/grfn/system/home/modules/alacritty.nix @@ -0,0 +1,56 @@ +{ config, lib, pkgs, ... }: + +{ + programs.alacritty = { + enable = true; + settings = { + font.size = 6; + font.normal.family = "Meslo LGSDZ Nerd Font"; + + draw_bold_text_with_bright_colors = false; + + key_bindings = [ + { + key = "Escape"; + mods = "Control"; + action = "ToggleViMode"; + } + ]; + + colors = with import ../common/solarized.nix; rec { + # Default colors + primary = { + background = base3; + foreground = base00; + }; + + cursor = { + text = base3; + cursor = base00; + }; + + # Normal colors + normal = { + inherit red green yellow blue magenta cyan; + black = base02; + white = base2; + }; + + # Bright colors + # bright = normal; + bright = { + black = base03; + red = orange; + green = base01; + yellow = base00; + blue = base0; + magenta = violet; + cyan = base1; + white = base3; + }; + + vi_mode_cursor.cursor = red; + }; + }; + }; +} diff --git a/users/grfn/system/home/modules/alsi.nix b/users/grfn/system/home/modules/alsi.nix new file mode 100644 index 000000000000..204f9c8e1428 --- /dev/null +++ b/users/grfn/system/home/modules/alsi.nix @@ -0,0 +1,58 @@ +{ config, lib, pkgs, ... }: +{ + home.packages = [ config.lib.depot.third_party.alsi ]; + + xdg.configFile."alsi/alsi.logo" = { + source = ./nixos-logo.txt; + force = true; + }; + + xdg.configFile."alsi/alsi.conf" = { + force = true; + text = '' + #!${pkgs.perl}/bin/perl + + scalar { + ALSI_VERSION => "0.4.8", + COLORS_FILE => "/home/grfn/.config/alsi/alsi.colors", + DE_FILE => "/home/grfn/.config/alsi/alsi.de", + DEFAULT_COLOR_BOLD => "blue", + DEFAULT_COLOR_NORMAL => "blue", + DF_COMMAND => "df -Th -x sys -x tmpfs -x devtmpfs &>/dev/stdout", + GTK2_RC_FILE => "/home/grfn/.gtkrc-2.0", + GTK3_RC_FILE => "/home/grfn/.config/gtk-3.0/settings.ini", + LOGO_FILE => "/home/grfn/.config/alsi/alsi.logo", + OUTPUT_FILE => "/home/grfn/.config/alsi/alsi.output", + # PACKAGES_PATH => "/var/lib/pacman/local/", + PS_COMMAND => "ps -A", + USAGE_COLORS => 0, + USAGE_COLORS_BOLD => 0, + USAGE_PRECENT_GREEN => 50, + USAGE_PRECENT_RED => 100, + USAGE_PRECENT_YELLOW => 85, + USE_LOGO_FROM_FILE => 1, + USE_VALUES_COLOR => 0, + WM_FILE => "/home/grfn/.config/alsi/alsi.wm", + } + ''; + }; + + xdg.configFile."alsi/alsi.colors".text = '' + #!${pkgs.perl}/bin/perl + + # Colors for alsi + + scalar { + black => {normal => "\e[0;30m", bold => "\e[1;30m"}, + red => {normal => "\e[0;31m", bold => "\e[1;31m"}, + green => {normal => "\e[0;32m", bold => "\e[1;32m"}, + yellow => {normal => "\e[0;33m", bold => "\e[1;33m"}, + default => {normal => "\e[0;34m", bold => "\e[1;34m"}, + blue => {normal => "\e[0;34m", bold => "\e[1;34m"}, + purple => {normal => "\e[0;35m", bold => "\e[1;35m"}, + cyan => {normal => "\e[0;36m", bold => "\e[1;36m"}, + white => {normal => "\e[0;37m", bold => "\e[1;37m"}, + reset => "\e[0m", + } + ''; +} diff --git a/users/grfn/system/home/modules/common.nix b/users/grfn/system/home/modules/common.nix new file mode 100644 index 000000000000..a24c5961de8a --- /dev/null +++ b/users/grfn/system/home/modules/common.nix @@ -0,0 +1,109 @@ +{ config, lib, pkgs, ... }: + +# Everything in here needs to work on linux or darwin + +{ + imports = [ + ../modules/shell.nix + ../modules/development.nix + ../modules/emacs.nix + ../modules/vim.nix + ../modules/tarsnap.nix + ../modules/twitter.nix + ../modules/lib/cloneRepo.nix + ]; + + home.username = "grfn"; + home.homeDirectory = "/home/grfn"; + + programs.password-store.enable = true; + + grfn.impure.clonedRepos.passwordStore = { + github = "glittershark/pass"; + path = ".local/share/password-store"; + }; + + home.packages = with pkgs; [ + # System utilities + bat + htop + killall + bind + zip + unzip + tree + nmap + bc + pv + + # Security + gnupg + keybase + openssl + + # Nix things + nixfmt + nix-prefetch-github + nix-review + cachix + (writeShellScriptBin "rebuild-mugwump" '' + set -eo pipefail + cd ~/code/depot + nix build -f . users.grfn.system.system.mugwumpSystem -o /tmp/mugwump + nix copy -f . users.grfn.system.system.mugwumpSystem \ + --to ssh://mugwump + system=$(readlink -ef /tmp/mugwump) + ssh mugwump sudo nix-env -p /nix/var/nix/profiles/system --set $system + ssh mugwump sudo $system/bin/switch-to-configuration switch + '') + (writeShellScriptBin "rebuild-home" '' + set -eo pipefail + cd ~/code/depot + nix build -f . users.grfn.system.home.$(hostname)Home -o /tmp/home + /tmp/home/activate + '') + ]; + + programs.ssh = { + enable = true; + + matchBlocks = { + "home" = { + host = "home.gws.fyi"; + forwardAgent = true; + }; + + "dobharchu" = { + host = "dobharchu"; + hostname = "172.16.0.4"; + forwardAgent = true; + user = "griffin"; + }; + + "cerberus" = { + host = "cerberus"; + hostname = "172.16.0.3"; + forwardAgent = true; + user = "griffin"; + }; + + "mugwump" = { + host = "mugwump"; + hostname = "172.16.0.5"; + forwardAgent = true; + }; + + "roswell" = { + host = "roswell"; + hostname = "18.223.118.13"; + forwardAgent = true; + }; + }; + }; + + programs.direnv = { + enable = true; + enableBashIntegration = true; + enableZshIntegration = true; + }; +} diff --git a/users/grfn/system/home/modules/development.nix b/users/grfn/system/home/modules/development.nix new file mode 100644 index 000000000000..3420fd652231 --- /dev/null +++ b/users/grfn/system/home/modules/development.nix @@ -0,0 +1,210 @@ +{ config, lib, pkgs, ... }: + +let + + clj2nix = pkgs.callPackage + (pkgs.fetchFromGitHub { + owner = "hlolli"; + repo = "clj2nix"; + rev = "3ab3480a25e850b35d1f532a5e4e7b3202232383"; + sha256 = "1lry026mlpxp1j563qs13nhxf37i2zpl7lh0lgfdwc44afybqka6"; + }) + { }; + + pg-dump-upsert = pkgs.buildGoModule rec { + pname = "pg-dump-upsert"; + version = "165258deaebded5e9b88f7a0acf3a4b7350e7bf4"; + + src = pkgs.fetchFromGitHub { + owner = "tomyl"; + repo = "pg-dump-upsert"; + rev = version; + sha256 = "1an4h8jjbj3r618ykjwk9brii4h9cxjqy47c4c8rivnvhimgf4wm"; + }; + + vendorSha256 = "1a5fx6mrv30cl46kswicd8lf5i5shn1fykchvbnbhdpgxhbz6qi4"; + }; + +in + +with lib; + +{ + imports = [ + ./lib/zshFunctions.nix + ./development/kube.nix + # TODO(grfn): agda build is broken in the nixpkgs checkout + # ./development/agda.nix + ./development/rust.nix + ]; + + home.packages = with pkgs; [ + jq + yq + gron + gitAndTools.tig + gitAndTools.gh + shellcheck + httpie + entr + gnumake + inetutils + tokei + jsonnet + ngrok + amber + + gdb + lldb + hyperfine + clang-tools_11 + rr + + clj2nix + clojure + leiningen + clj-kondo + + pg-dump-upsert + + nodePackages.prettier + + linuxPackages.perf + ] ++ optionals (stdenv.isLinux) [ + # TODO(grfn): replace with stable again once the current julia debacle + # is resolved upstream, see https://github.com/NixOS/nixpkgs/pull/121114 + julia_16-bin + valgrind + ]; + + programs.git = { + enable = true; + package = pkgs.gitFull; + userEmail = "root@gws.fyi"; + userName = "Griffin Smith"; + ignores = [ + "*.sw*" + ".classpath" + ".project" + ".settings/" + ".dir-locals.el" + ".stack-work-profiling" + ".projectile" + ]; + extraConfig = { + github.user = "glittershark"; + merge.conflictstyle = "diff3"; + rerere.enabled = "true"; + advice.skippedCherryPicks = "false"; + }; + + delta = { + enable = true; + options = { + syntax-theme = "Solarized (light)"; + hunk-style = "plain"; + commit-style = "box"; + }; + }; + }; + + home.file.".gdbinit".text = '' + set history filename ~/.gdb_history + set history save on + set history size unlimited + set history remove-duplicates unlimited + set history expansion on + ''; + + home.file.".psqlrc".text = '' + \set QUIET 1 + \timing + \set ON_ERROR_ROLLBACK interactive + \set VERBOSITY verbose + \x auto + \set PROMPT1 '%[%033[1m%]%M/%/%R%[%033[0m%]%# ' + \set PROMPT2 '...%# ' + \set HISTFILE ~/.psql_history- :DBNAME + \set HISTCONTROL ignoredups + \pset null [null] + \unset QUIET + ''; + + programs.readline = { + enable = true; + extraConfig = '' + set editing-mode vi + ''; + }; + + programs.zsh = { + shellAliases = { + # Git + "gwip" = "git add . && git commit -am wip"; + "gpr" = "g pull-request"; + "gcl" = "git clone"; + "grs" = "gr --soft"; + "grhh" = "grh HEAD"; + "grh" = "gr --hard"; + "gr" = "git reset"; + "gcb" = "gc -b"; + "gco" = "gc"; + "gcd" = "gc development"; + "gcm" = "gc master"; + "gcc" = "gc canon"; + "gc" = "git checkout"; + "gbg" = "git branch | grep"; + "gba" = "git branch -a"; + "gb" = "git branch"; + "gcv" = "git commit --verbose"; + "gci" = "git commit"; + "gm" = "git merge"; + "gdc" = "gd --cached"; + "gd" = "git diff"; + "gsl" = "git stash list"; + "gss" = "git show stash"; + "gsad" = "git stash drop"; + "gsa" = "git stash"; + "gst" = "gs"; + "gs" = "git status"; + "gg" = "gl --decorate --oneline --graph --date-order --all"; + "gl" = "git log"; + "gf" = "git fetch"; + "gur" = "gu --rebase"; + "gu" = "git pull"; + "gpf" = "gp -f"; + "gpa" = "gp --all"; + "gpu" = "git push -u origin \"$(git symbolic-ref --short HEAD)\""; + "gp" = "git push"; + "ganw" = "git diff -w --no-color | git apply --cached --ignore-whitespace"; + "ga" = "git add"; + "gnp" = "git --no-pager"; + "g" = "git"; + "grim" = "git fetch && git rebase -i --autostash origin/master"; + "grom" = "git fetch && git rebase --autostash origin/master"; + "groc" = "git fetch && git rebase --autostash origin/canon"; + "grc" = "git rebase --continue"; + "gcan" = "git commit --amend --no-edit"; + "grl" = "git reflog"; + + # Haskell + "crl" = "cabal repl"; + "cr" = "cabal run"; + "cnb" = "cabal new-build"; + "cob" = "cabal old-build"; + "cnr" = "cabal new-run"; + "cor" = "cabal old-run"; + "ho" = "hoogle"; + }; + + functions = { + gdelmerged = '' + git branch --merged | egrep -v 'master' | tr -d '+ ' | xargs git branch -d + ''; + + gref = '' + git show -s --pretty=reference "$1" | xclip -selection clipboard + ''; + }; + }; +} diff --git a/users/grfn/system/home/modules/development/agda.nix b/users/grfn/system/home/modules/development/agda.nix new file mode 100644 index 000000000000..afd22a306dc9 --- /dev/null +++ b/users/grfn/system/home/modules/development/agda.nix @@ -0,0 +1,58 @@ +{ config, lib, pkgs, ... }: + +let + agda-categories = with pkgs.agdaPackages; mkDerivation rec { + pname = "agda-categories"; + version = "2128fab"; + src = pkgs.fetchFromGitHub { + owner = "agda"; + repo = "agda-categories"; + rev = version; + sha256 = "08mc20qaz9vp5rhi60rh8wvjkg5aby3bgwwdhfnxha1663qf1q24"; + }; + + buildInputs = [ standard-library ]; + }; + +in + +{ + imports = [ + ../lib/cloneRepo.nix + ]; + + home.packages = with pkgs; [ + (pkgs.agda.withPackages + (p: with p; [ + p.standard-library + + ])) + ]; + + grfn.impure.clonedRepos = { + agda-stdlib = { + github = "agda/agda-stdlib"; + path = "code/agda-stdlib"; + }; + + agda-categories = { + github = "agda/agda-categories"; + path = "code/agda-categories"; + }; + + categories-examples = { + github = "agda/categories-examples"; + path = "code/categories-examples"; + }; + }; + + home.file.".agda/defaults".text = '' + standard-library + ''; + + home.file.".agda/libraries".text = '' + /home/grfn/code/agda-stdlib/standard-library.agda-lib + /home/grfn/code/agda-categories/agda-categories.agda-lib + ''; + +} diff --git a/users/grfn/system/home/modules/development/kube.nix b/users/grfn/system/home/modules/development/kube.nix new file mode 100644 index 000000000000..876b0c08df1d --- /dev/null +++ b/users/grfn/system/home/modules/development/kube.nix @@ -0,0 +1,34 @@ +{ config, lib, pkgs, ... }: +{ + home.packages = with pkgs; [ + kubectl + kubetail + sops + kubie + # pkgs-unstable.argocd # provided by urbos + ]; + + programs.zsh.shellAliases = { + "kc" = "kubectl"; + "kg" = "kc get"; + "kga" = "kc get --all-namespaces"; + "kpd" = "kubectl get pods"; + "kpa" = "kubectl get pods --all-namespaces"; + "klf" = "kubectl logs -f"; + "kdep" = "kubectl get deployments"; + "ked" = "kubectl edit deployment"; + "kpw" = "kubectl get pods -w"; + "kew" = "kubectl get events -w"; + "kdel" = "kubectl delete"; + "knw" = "kubectl get nodes -w"; + "kev" = "kubectl get events --sort-by='.metadata.creationTimestamp'"; + + "arsy" = "argocd app sync --prune"; + }; + + home.file.".kube/kubie.yaml".text = '' + shell: zsh + prompt: + zsh_use_rps1: true + ''; +} diff --git a/users/grfn/system/home/modules/development/readyset.nix b/users/grfn/system/home/modules/development/readyset.nix new file mode 100644 index 000000000000..7b1b8368375d --- /dev/null +++ b/users/grfn/system/home/modules/development/readyset.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./rust.nix + ]; + + home.packages = with pkgs; [ + # This goes in $PATH so I can run it from rofi and parent to my WM + (writeShellScriptBin "dotclip" "xclip -out -selection clipboard | dot -Tpng | feh -") + (buildGoModule rec { + pname = "rain"; + version = "1.2.0"; + + src = fetchFromGitHub { + owner = "aws-cloudformation"; + repo = pname; + rev = "v${version}"; + sha256 = "168gkchshl5f1awqi1cgvdkm6q707702rnn0v4i5djqxmg5rk0p9"; + }; + + vendorSha256 = "16bx7cjh5cq9zlis8lf28i016avgqf3j9fmcvkqzd8db2vxpqx3v"; + }) + awscli2 + amazon-ecr-credential-helper + ]; + + programs.zsh.shellAliases = { + "tf" = "terraform"; + }; +} diff --git a/users/grfn/system/home/modules/development/rust.nix b/users/grfn/system/home/modules/development/rust.nix new file mode 100644 index 000000000000..4ae5bc3bcc18 --- /dev/null +++ b/users/grfn/system/home/modules/development/rust.nix @@ -0,0 +1,34 @@ +{ config, lib, pkgs, ... }: + + +{ + home.packages = with pkgs; [ + rustup + rust-analyzer + cargo-edit + cargo-expand + cargo-flamegraph + cargo-rr + cargo-udeps + cargo-bloat + sccache + evcxr + ]; + + programs.zsh.shellAliases = { + "cg" = "cargo"; + "cb" = "cargo build"; + "ct" = "cargo test"; + "ctw" = "fd -e rs | entr cargo test"; + "cch" = "cargo check"; + }; + + home.file.".cargo/config".text = '' + [build] + rustc-wrapper = "${pkgs.sccache}/bin/sccache" + + [target.x86_64-unknown-linux-gnu] + linker = "clang" + rustflags = ["-C", "link-arg=-fuse-ld=${pkgs.mold}/bin/mold"] + ''; +} diff --git a/users/grfn/system/home/modules/emacs.nix b/users/grfn/system/home/modules/emacs.nix new file mode 100644 index 000000000000..f3d08a49ce42 --- /dev/null +++ b/users/grfn/system/home/modules/emacs.nix @@ -0,0 +1,109 @@ +{ pkgs, lib, config, ... }: + +with lib; + +let + # doom-emacs = pkgs.callPackage (builtins.fetchTarball { + # url = https://github.com/vlaci/nix-doom-emacs/archive/master.tar.gz; + # }) { + # doomPrivateDir = ./doom.d; # Directory containing your config.el init.el + # # and packages.el files + # }; + + depot = config.lib.depot; + +in +{ + imports = [ + ./lib/cloneRepo.nix + ]; + + # home.packages = [ doom-emacs ]; + # home.file.".emacs.d/init.el".text = '' + # (load "default.el") + # ''; + # + + config = mkMerge [ + { + home.packages = with pkgs; [ + # LaTeX (for org export) + (pkgs.texlive.combine { + inherit (pkgs.texlive) + capt-of + collection-fontsrecommended + dvipng + fancyvrb + float + fncychap + framed + mathpartir + needspace + parskip + scheme-basic + semantic + tabulary + titlesec + ulem + upquote + varwidth + wrapfig + ; + }) + + ispell + + ripgrep + coreutils + fd + clang + gnutls + emacsPackages.telega + ]; + + programs.emacs = { + enable = true; + package = pkgs.emacsUnstable; + extraPackages = (epkgs: + (with epkgs; [ + tvlPackages.dottime + tvlPackages.tvl + vterm + telega + ]) + ); + }; + + grfn.impure.clonedRepos = { + orgClubhouse = { + github = "glittershark/org-clubhouse"; + path = "code/org-clubhouse"; + }; + + doomEmacs = { + github = "hlissner/doom-emacs"; + path = ".emacs.d"; + after = [ "emacs.d" ]; + onClone = "bin/doom install"; + }; + + "emacs.d" = { + github = "glittershark/emacs.d"; + path = ".doom.d"; + after = [ "orgClubhouse" ]; + }; + }; + + programs.zsh.shellAliases = { + "ec" = "emacsclient"; + }; + } + (mkIf pkgs.stdenv.isLinux { + # Notes + services.syncthing = { + enable = true; + tray.enable = true; + }; + }) + ]; +} diff --git a/users/grfn/system/home/modules/email.nix b/users/grfn/system/home/modules/email.nix new file mode 100644 index 000000000000..63dfeeb6f480 --- /dev/null +++ b/users/grfn/system/home/modules/email.nix @@ -0,0 +1,93 @@ +{ lib, pkgs, config, ... }: + +with lib; + +let + + # from home-manager/modules/services/lieer.nix + escapeUnitName = name: + let + good = upperChars ++ lowerChars ++ stringToCharacters "0123456789-_"; + subst = c: if any (x: x == c) good then c else "-"; + in + stringAsChars subst name; + + accounts = { + personal = { + primary = true; + address = "root@gws.fyi"; + aliases = [ "grfn@gws.fyi" ]; + passEntry = "root-gws-msmtp"; + }; + + work = { + address = "griffin@readyset.io"; + passEntry = "readyset/msmtp"; + }; + + }; + +in +{ + programs.lieer.enable = true; + programs.notmuch.enable = true; + services.lieer.enable = true; + programs.msmtp.enable = true; + + home.packages = with pkgs; [ + mu + msmtp + ]; + + systemd.user.services = mapAttrs' + (name: account: { + name = escapeUnitName "lieer-${name}"; + value.Service = { + ExecStart = mkForce "${pkgs.writeShellScript "sync-${name}" '' + ${pkgs.gmailieer}/bin/gmi sync --path ~/mail/${name} + ''}"; + Environment = "NOTMUCH_CONFIG=${config.home.sessionVariables.NOTMUCH_CONFIG}"; + }; + + }) + accounts; + + # xdg.configFile."notifymuch/notifymuch.cfg".text = generators.toINI {} { + # notifymuch = { + # query = "is:unread and is:important"; + # mail_client = ""; + # recency_interval_hours = "48"; + # hidden_tags = "inbox unread attachment replied sent encrypted signed"; + # }; + # }; + + accounts.email.maildirBasePath = "mail"; + accounts.email.accounts = mapAttrs + (_: params@{ passEntry, ... }: { + realName = "Griffin Smith"; + passwordCommand = "pass ${passEntry}"; + + flavor = "gmail.com"; + + imapnotify = { + enable = true; + boxes = [ "Inbox" ]; + }; + + gpg = { + key = "0F11A989879E8BBBFDC1E23644EF5B5E861C09A7"; + signByDefault = true; + }; + + notmuch.enable = true; + lieer = { + enable = true; + sync = { + enable = true; + frequency = "*:*"; + }; + }; + msmtp.enable = true; + } // builtins.removeAttrs params [ "passEntry" ]) + accounts; +} diff --git a/users/grfn/system/home/modules/firefox.nix b/users/grfn/system/home/modules/firefox.nix new file mode 100644 index 000000000000..c7e78685a5a3 --- /dev/null +++ b/users/grfn/system/home/modules/firefox.nix @@ -0,0 +1,22 @@ +{ config, lib, pkgs, ... }: + +{ + + xdg.mimeApps = rec { + enable = true; + defaultApplications = { + "text/html" = [ "firefox.desktop" ]; + "x-scheme-handler/http" = [ "firefox.desktop" ]; + "x-scheme-handler/https" = [ "firefox.desktop" ]; + "x-scheme-handler/ftp" = [ "firefox.desktop" ]; + "x-scheme-handler/chrome" = [ "firefox.desktop" ]; + "application/x-extension-htm" = [ "firefox.desktop" ]; + "application/x-extension-html" = [ "firefox.desktop" ]; + "application/x-extension-shtml" = [ "firefox.desktop" ]; + "application/xhtml+xml" = [ "firefox.desktop" ]; + "application/x-extension-xhtml" = [ "firefox.desktop" ]; + "application/x-extension-xht" = [ "firefox.desktop" ]; + }; + associations.added = defaultApplications; + }; +} diff --git a/users/grfn/system/home/modules/games.nix b/users/grfn/system/home/modules/games.nix new file mode 100644 index 000000000000..5272ac9330fc --- /dev/null +++ b/users/grfn/system/home/modules/games.nix @@ -0,0 +1,61 @@ +{ config, lib, pkgs, ... }: + +with pkgs; +with lib; + +let + + df-orig = dwarf-fortress-packages.dwarf-fortress-original; + + df-full = (dwarf-fortress-packages.dwarf-fortress-full.override { + theme = null; + enableIntro = false; + enableFPS = true; + enableDFHack = false; # Fails to build currently + }); + + init = runCommand "init.txt" { } '' + substitute "${df-orig}/data/init/init.txt" $out \ + --replace "[INTRO:YES]" "[INTRO:NO]" \ + --replace "[VOLUME:255]" "[VOLUME:0]" \ + --replace "[FPS:NO]" "[FPS:YES]" + ''; + + d_init = runCommand "d_init.txt" { } '' + substitute "${df-orig}/data/init/d_init.txt" $out \ + --replace "[AUTOSAVE:NONE]" "[AUTOSAVE:SEASONAL]" \ + --replace "[AUTOSAVE_PAUSE:NO]" "[AUTOSAVE_PAUSE:YES]" \ + --replace "[INITIAL_SAVE:NO]" "[INITIAL_SAVE:YES]" \ + --replace "[EMBARK_WARNING_ALWAYS:NO]" "[EMBARK_WARNING_ALWAYS:YES]" \ + --replace "[VARIED_GROUND_TILES:YES]" "[VARIED_GROUND_TILES:NO]" \ + --replace "[SHOW_FLOW_AMOUNTS:NO]" "[SHOW_FLOW_AMOUNTS:YES]" + ''; + + df = runCommand "dwarf-fortress" { } '' + mkdir -p $out/bin + sed \ + -e '4icp -f ${init} "$DF_DIR/data/init/init.txt"' \ + -e '4icp -f ${d_init} "$DF_DIR/data/init/d_init.txt"' \ + < "${df-full}/bin/dwarf-fortress" >"$out/bin/dwarf-fortress" + + shopt -s extglob + ln -s ${df-full}/bin/!(dwarf-fortress) $out/bin + + chmod +x $out/bin/dwarf-fortress + ''; + +in +mkMerge [ + { + home.packages = [ + crawl + xonotic + ]; + } + (mkIf stdenv.isLinux { + home.packages = [ + df + polymc + ]; + }) +] diff --git a/users/grfn/system/home/modules/i3.nix b/users/grfn/system/home/modules/i3.nix new file mode 100644 index 000000000000..c6e198c98a31 --- /dev/null +++ b/users/grfn/system/home/modules/i3.nix @@ -0,0 +1,380 @@ +{ config, lib, pkgs, ... }: +let + mod = "Mod4"; + solarized = import ../common/solarized.nix; + # TODO pull this out into lib + emacsclient = eval: pkgs.writeShellScript "emacsclient-eval" '' + msg=$(emacsclient --eval '${eval}' 2>&1) + echo "''${msg:1:-1}" + ''; + screenlayout = { + home = pkgs.writeShellScript "screenlayout_home.sh" '' + xrandr \ + --output eDP-1 --mode 1920x1200 --pos 0x960 --rotate normal \ + --output DP-3 --primary --mode 3840x2160 --pos 1920x0 --rotate normal \ + --output DP-1 --off \ + --output DP-2 --off \ + --output DP-4 --off + ''; + }; + + inherit (builtins) map; + inherit (lib) mkMerge range; +in +{ + options = with lib; { + system.machine.wirelessInterface = mkOption { + description = '' + Name of the primary wireless interface. Used by i3status, etc. + ''; + default = "wlp3s0"; + type = types.str; + }; + + system.machine.i3FontSize = mkOption { + description = "Font size to use in i3 window decorations etc."; + default = 6; + type = types.int; + }; + }; + + config = + let + fontName = "MesloLGSDZ"; + fontSize = config.system.machine.i3FontSize; + fonts = { + names = [ fontName ]; + size = fontSize * 1.0; + }; + decorationFont = "${fontName} ${toString fontSize}"; + in + { + home.packages = with pkgs; [ + rofi + rofi-pass + python3Packages.py3status + i3lock + i3status + dconf # for gtk + + # Screenshots + maim + + # GIFs + picom + peek + + (pkgs.writeShellScriptBin "lock" '' + playerctl pause + ${pkgs.i3lock}/bin/i3lock -c 222222 + '') + ]; + + xsession.scriptPath = ".xsession"; + + xsession.windowManager.i3 = { + enable = true; + config = { + modifier = mod; + keybindings = + mkMerge ( + (map + (n: { + "${mod}+${toString n}" = + "workspace ${toString n}"; + "${mod}+Shift+${toString n}" = + "move container to workspace ${toString n}"; + }) + (range 0 9)) + ++ [ + (rec { + "${mod}+h" = "focus left"; + "${mod}+j" = "focus down"; + "${mod}+k" = "focus up"; + "${mod}+l" = "focus right"; + "${mod}+semicolon" = "focus parent"; + + "${mod}+Shift+h" = "move left"; + "${mod}+Shift+j" = "move down"; + "${mod}+Shift+k" = "move up"; + "${mod}+Shift+l" = "move right"; + + "${mod}+Shift+x" = "kill"; + + "${mod}+Return" = "exec alacritty"; + + "${mod}+Shift+s" = "split h"; + "${mod}+Shift+v" = "split v"; + "${mod}+e" = "layout toggle split"; + "${mod}+w" = "layout tabbed"; + "${mod}+s" = "layout stacking"; + + "${mod}+f" = "fullscreen"; + + "${mod}+Shift+r" = "restart"; + + "${mod}+r" = "mode resize"; + + # Marks + "${mod}+Shift+m" = ''exec i3-input -F "mark %s" -l 1 -P 'Mark: ' ''; + "${mod}+m" = ''exec i3-input -F '[con_mark="%s"] focus' -l 1 -P 'Go to: ' ''; + + # Screenshots + "${mod}+q" = "exec \"maim | xclip -selection clipboard -t image/png\""; + "${mod}+Shift+q" = "exec \"maim -s | xclip -selection clipboard -t image/png\""; + "${mod}+Ctrl+q" = "exec ${pkgs.writeShellScript "peek.sh" '' + ${pkgs.picom}/bin/picom & + picom_pid=$! + ${pkgs.peek}/bin/peek || true + kill -SIGINT $picom_pid + ''}"; + + # Launching applications + "${mod}+u" = "exec ${pkgs.writeShellScript "rofi" '' + rofi \ + -modi 'combi' \ + -combi-modi "window,drun,ssh,run" \ + -font '${decorationFont}' \ + -show combi + ''}"; + + # Passwords + "${mod}+p" = "exec rofi-pass -font '${decorationFont}'"; + + # Media + "XF86AudioPlay" = "exec playerctl play-pause"; + "XF86AudioNext" = "exec playerctl next"; + "XF86AudioPrev" = "exec playerctl previous"; + "XF86AudioRaiseVolume" = "exec pulseaudio-ctl up"; + "XF86AudioLowerVolume" = "exec pulseaudio-ctl down"; + "XF86AudioMute" = "exec pulseaudio-ctl mute"; + + # Lock + Pause = "exec lock"; + + # Brightness + "XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl -q s 5%-"; + "XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl -q s 5%+"; + + # Sleep/hibernate + # "${mod}+Escape" = "exec systemctl suspend"; + # "${mod}+Shift+Escape" = "exec systemctl hibernate"; + + # Scratch buffer + "${mod}+minus" = "scratchpad show"; + "${mod}+Shift+minus" = "move scratchpad"; + "${mod}+space" = "focus mode_toggle"; + "${mod}+Shift+space" = "floating toggle"; + + # Screen Layout + "${mod}+Shift+t" = "exec xrandr --auto"; + "${mod}+t" = "exec ${screenlayout.home}"; + "${mod}+Ctrl+t" = "exec ${pkgs.writeShellScript "fix_term.sh" '' + xrandr --output eDP-1 --off && ${screenlayout.home} + ''}"; + + # Notifications + "${mod}+Shift+n" = "exec killall -SIGUSR1 .dunst-wrapped"; + "${mod}+n" = "exec killall -SIGUSR2 .dunst-wrapped"; + "Control+space" = "exec ${pkgs.dunst}/bin/dunstctl close"; + "Control+Shift+space" = "exec ${pkgs.dunst}/bin/dunstctl close-all"; + "Control+grave" = "exec ${pkgs.dunst}/bin/dunstctl history-pop"; + "Control+Shift+period" = "exec ${pkgs.dunst}/bin/dunstctl action"; + }) + ] + ); + + inherit fonts; + + colors = with solarized; rec { + focused = { + border = base01; + background = base01; + text = base3; + indicator = red; + childBorder = base02; + }; + focusedInactive = focused // { + border = base03; + background = base03; + # text = base1; + }; + unfocused = focusedInactive; + background = base03; + }; + + modes.resize = { + l = "resize shrink width 5 px or 5 ppt"; + k = "resize grow height 5 px or 5 ppt"; + j = "resize shrink height 5 px or 5 ppt"; + h = "resize grow width 5 px or 5 ppt"; + + Return = "mode \"default\""; + }; + + bars = [{ + statusCommand = + let + i3status-conf = pkgs.writeText "i3status.conf" '' + general { + output_format = i3bar + colors = true + color_good = "#859900" + + interval = 1 + } + + order += "external_script current_task" + order += "external_script inbox" + order += "spotify" + order += "volume_status" + order += "wireless ${config.system.machine.wirelessInterface}" + # order += "ethernet enp3s0f0" + order += "cpu_usage" + order += "battery 0" + # order += "volume master" + order += "time" + order += "tztime utc" + + mpd { + format = "%artist - %album - %title" + } + + wireless ${config.system.machine.wirelessInterface} { + format_up = "W: (%quality - %essid - %bitrate) %ip" + format_down = "W: -" + } + + ethernet enp3s0f0 { + format_up = "E: %ip" + format_down = "E: -" + } + + battery 0 { + format = "%status %percentage" + path = "/sys/class/power_supply/BAT%d/uevent" + low_threshold = 10 + } + + cpu_usage { + format = "CPU: %usage" + } + + load { + format = "%5min" + } + + time { + format = " %a %h %d โ %I:%M " + } + + spotify { + color_playing = "#fdf6e3" + color_paused = "#93a1a1" + format_stopped = "" + format_down = "" + format = "{title} - {artist} ({album})" + } + + external_script inbox { + script_path = '${emacsclient "(grfn/num-inbox-items-message)"}' + format = 'Inbox: {output}' + cache_timeout = 120 + color = "#93a1a1" + } + + external_script current_task { + script_path = '${emacsclient "(grfn/org-current-clocked-in-task-message)"}' + # format = '{output}' + cache_timeout = 60 + color = "#93a1a1" + } + + tztime utc { + timezone = "UTC" + format = " %Hยท%M " + } + + volume_status { + format = "โ {percentage}" + format_muted = "โ X" + # device = "default" + # mixer_idx = 0 + } + ''; + in + "py3status -c ${i3status-conf}"; + inherit fonts; + position = "top"; + colors = with solarized; rec { + background = base03; + statusline = base3; + separator = base1; + activeWorkspace = { + border = base03; + background = base1; + text = base3; + }; + focusedWorkspace = activeWorkspace; + inactiveWorkspace = activeWorkspace // { + background = base01; + }; + urgentWorkspace = activeWorkspace // { + background = red; + }; + }; + }]; + }; + }; + + services.dunst = { + enable = true; + settings = with solarized; { + global = { + font = "MesloLGSDZ ${toString (config.system.machine.i3FontSize * 1.5)}"; + allow_markup = true; + format = "<b>%s</b>\n%b"; + sort = true; + alignment = "left"; + geometry = "600x15-40+40"; + idle_threshold = 120; + separator_color = "frame"; + separator_height = 1; + word_wrap = true; + padding = 8; + horizontal_padding = 8; + max_icon_size = 45; + }; + + frame = { + width = 0; + color = "#aaaaaa"; + }; + + urgency_low = { + background = base03; + foreground = base3; + timeout = 5; + }; + + urgency_normal = { + background = base02; + foreground = base3; + timeout = 7; + }; + + urgency_critical = { + background = red; + foreground = base3; + timeout = 0; + }; + }; + }; + + gtk = { + enable = true; + iconTheme.name = "Adwaita"; + theme.name = "Adwaita"; + }; + }; +} diff --git a/users/grfn/system/home/modules/lib/cloneRepo.nix b/users/grfn/system/home/modules/lib/cloneRepo.nix new file mode 100644 index 000000000000..54992bd69bae --- /dev/null +++ b/users/grfn/system/home/modules/lib/cloneRepo.nix @@ -0,0 +1,73 @@ +{ lib, config, ... }: +with lib; +{ + options = { + grfn.impure.clonedRepos = mkOption { + description = "Repositories to clone"; + default = { }; + type = with types; loaOf ( + let + sm = submodule { + options = { + url = mkOption { + type = nullOr str; + description = "URL of repository to clone"; + default = null; + }; + + github = mkOption { + type = nullOr str; + description = "Github owner/repo of repository to clone"; + default = null; + }; + + path = mkOption { + type = str; + description = "Path to clone to"; + }; + + onClone = mkOption { + type = str; + description = '' + Shell command to run after cloning the repo for the first time. + Runs inside the repo itself. + ''; + default = ""; + }; + + after = mkOption { + type = listOf str; + description = "Activation hooks that this repository must be cloned after"; + default = [ ]; + }; + }; + }; + in + addCheck sm (cr: (! isNull cr.url || ! isNull cr.github)) + ); + }; + }; + + config = { + home.activation = + mapAttrs + (_: { url + , path + , github + , onClone + , after + , ... + }: + let repoURL = if isNull url then "git@github.com:${github}" else url; + in hm.dag.entryAfter ([ "writeBoundary" ] ++ after) '' + $DRY_RUN_CMD mkdir -p $(dirname "${path}") + if [[ ! -d ${path} ]]; then + $DRY_RUN_CMD git clone "${repoURL}" "${path}" + pushd ${path} + $DRY_RUN_CMD ${onClone} + popd + fi + '') + config.grfn.impure.clonedRepos; + }; +} diff --git a/users/grfn/system/home/modules/lib/zshFunctions.nix b/users/grfn/system/home/modules/lib/zshFunctions.nix new file mode 100644 index 000000000000..228dc6379fd6 --- /dev/null +++ b/users/grfn/system/home/modules/lib/zshFunctions.nix @@ -0,0 +1,23 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + options = { + programs.zsh.functions = mkOption { + description = "An attribute set that maps function names to their source"; + default = { }; + type = with types; attrsOf (either str path); + }; + }; + + config.programs.zsh.initExtra = concatStringsSep "\n" ( + mapAttrsToList + (name: funSrc: '' + function ${name}() { + ${funSrc} + } + '') + config.programs.zsh.functions + ); +} diff --git a/users/grfn/system/home/modules/nixos-logo.txt b/users/grfn/system/home/modules/nixos-logo.txt new file mode 100644 index 000000000000..d4b16b44f0bf --- /dev/null +++ b/users/grfn/system/home/modules/nixos-logo.txt @@ -0,0 +1,26 @@ + [38;5;m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;m( [38;5;m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# [38;5;m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m/ + [38;5;m,[38;5;068m([38;5;067m([38;5;068m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;061m/[38;5;m( [38;5;m#[38;5;110m%[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m%[38;5;m# [38;5;m.[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m%[38;5;m# + [38;5;m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;061m/[38;5;061m/[38;5;m/ [38;5;m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;m. [38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m/ + [38;5;m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;061m/[38;5;067m([38;5;061m/[38;5;061m/[38;5;m, [38;5;m/[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# + [38;5;m([38;5;067m([38;5;067m([38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m/ [38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m( + [38;5;m.[38;5;068m([38;5;068m([38;5;068m([38;5;068m([38;5;068m([38;5;068m([38;5;068m([38;5;068m([38;5;068m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;061m([38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m#[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# [38;5;m([38;5;m( + [38;5;m([38;5;067m([38;5;067m([38;5;067m([38;5;068m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m/[38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# [38;5;m.[38;5;m([38;5;067m([38;5;067m([38;5;m( + [38;5;m([38;5;068m([38;5;067m([38;5;067m([38;5;067m([38;5;068m([38;5;067m([38;5;067m([38;5;067m([38;5;068m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;061m/[38;5;061m([38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m/[38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# [38;5;m([38;5;068m([38;5;067m([38;5;067m([38;5;067m([38;5;068m([38;5;067m([38;5;m( + [38;5;m([38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;074m#[38;5;m# [38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# [38;5;m([38;5;067m([38;5;068m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;m( + [38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# [38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m/[38;5;m([38;5;067m([38;5;068m([38;5;067m([38;5;068m([38;5;067m([38;5;068m([38;5;067m([38;5;068m([38;5;m( + [38;5;m*[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# [38;5;m.[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m#[38;5;m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;m( + [38;5;m#[38;5;m#[38;5;m#[38;5;m%[38;5;m#[38;5;m#[38;5;m#[38;5;m#[38;5;m#[38;5;m#[38;5;m#[38;5;m#[38;5;m#[38;5;m#[38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# [38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m([38;5;061m/[38;5;061m/[38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;m([38;5;m([38;5;m([38;5;m([38;5;m([38;5;m([38;5;m([38;5;m([38;5;m([38;5;m( +[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# [38;5;m.[38;5;m#[38;5;m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;m( +[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m([38;5;m( [38;5;m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;m( + [38;5;m#[38;5;m#[38;5;m#[38;5;m%[38;5;m#[38;5;m#[38;5;m#[38;5;m#[38;5;m#[38;5;m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m#[38;5;m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m. [38;5;m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m/[38;5;m/[38;5;m/[38;5;m/[38;5;m/[38;5;m/[38;5;m/[38;5;m/[38;5;m/[38;5;m/[38;5;m([38;5;m([38;5;m([38;5;m( + [38;5;m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m( [38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m/ + [38;5;m.[38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# [38;5;m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m/ [38;5;m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m, + [38;5;m%[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m%[38;5;m* [38;5;m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m( [38;5;m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m/ + [38;5;m.[38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;m# [38;5;m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m([38;5;m#[38;5;074m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m, + [38;5;m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m# [38;5;m([38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m% + [38;5;m.[38;5;m# [38;5;m([38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m/[38;5;061m([38;5;061m/[38;5;061m/[38;5;067m([38;5;m([38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;m% + [38;5;m([38;5;061m/[38;5;061m/[38;5;061m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m( [38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m%[38;5;110m%[38;5;110m%[38;5;m( + [38;5;m/[38;5;061m/[38;5;067m([38;5;061m/[38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;m( [38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;m# + [38;5;m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;m( [38;5;m([38;5;067m([38;5;067m([38;5;067m([38;5;068m([38;5;067m([38;5;067m([38;5;067m([38;5;068m( [38;5;m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m/ + [38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;m( [38;5;m/[38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;067m([38;5;068m([38;5;067m([38;5;m( [38;5;m.[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m#[38;5;110m#[38;5;110m#[38;5;m% + [38;5;m([38;5;068m([38;5;067m([38;5;068m([38;5;067m([38;5;m( [38;5;m([38;5;068m([38;5;067m([38;5;068m([38;5;067m([38;5;068m([38;5;067m([38;5;068m([38;5;m( [38;5;m%[38;5;110m#[38;5;110m%[38;5;110m#[38;5;110m%[38;5;110m#[38;5;m/ diff --git a/users/grfn/system/home/modules/obs.nix b/users/grfn/system/home/modules/obs.nix new file mode 100644 index 000000000000..e85a7ba9a006 --- /dev/null +++ b/users/grfn/system/home/modules/obs.nix @@ -0,0 +1,68 @@ +{ config, lib, pkgs, ... }: + +with pkgs; + +let + libuiohook = stdenv.mkDerivation rec { + pname = "libuiohook"; + version = "1.1"; + src = fetchFromGitHub { + owner = "kwhat"; + repo = "libuiohook"; + rev = version; + sha256 = "1isfxn3cfrdqq22d3mlz2lzm4asf9gprs7ww2xy9c3j3srk9kd7r"; + }; + + preConfigure = '' + ./bootstrap.sh + ''; + + nativeBuildInputs = [ pkg-config ]; + buildInputs = [ + libtool + autoconf + automake + xlibsWrapper + xorg.libXtst + xorg.libXinerama + xorg.libxkbfile + libxkbcommon + ]; + }; + + obs-input-overlay = stdenv.mkDerivation rec { + pname = "obs-input-overlay"; + version = "4.8"; + src = fetchFromGitHub { + owner = "univrsal"; + repo = "input-overlay"; + rev = "v${version}"; + sha256 = "1dklg0dx9ijwyhgwcaqz859rbpaivmqxqvh9w3h4byrh5pnkz8bf"; + fetchSubmodules = true; + }; + + nativeBuildInputs = [ cmake ]; + buildInputs = [ obs-studio libuiohook ]; + + postPatch = '' + sed -i CMakeLists.txt \ + -e '2iinclude(${obs-studio.src}/cmake/Modules/ObsHelpers.cmake)' \ + -e '2ifind_package(LibObs REQUIRED)' + ''; + + cmakeFlags = [ + "-Wno-dev" + ]; + }; +in +{ + home.packages = [ + obs-studio + obs-input-overlay + ]; + + xdg.configFile."obs-studio/plugins/input-overlay/bin/64bit/input-overlay.so".source = + "${obs-input-overlay}/lib/obs-plugins/input-overlay.so"; + xdg.configFile."obs-studio/plugins/input-overlay/data".source = + "${obs-input-overlay}/share/obs/obs-plugins/input-overlay"; +} diff --git a/users/grfn/system/home/modules/ptt.nix b/users/grfn/system/home/modules/ptt.nix new file mode 100644 index 000000000000..436c8f261797 --- /dev/null +++ b/users/grfn/system/home/modules/ptt.nix @@ -0,0 +1,44 @@ +{ config, lib, pkgs, ... }: + +let + + pttKeycode = "152"; + sourceID = "3"; + + mute = pkgs.writeShellScript "mute-mic" '' + xset -r ${pttKeycode} + ${pkgs.pulseaudio}/bin/pactl set-source-mute ${sourceID} 1 + ''; + + unmute = pkgs.writeShellScript "unmute-mic" '' + xset -r ${pttKeycode} + ${pkgs.pulseaudio}/bin/pactl set-source-mute ${sourceID} 0 + ''; + +in + +{ + home.packages = with pkgs; [ + xbindkeys + ]; + + + home.file.".xbindkeysrc.scm".text = '' + (xbindkey '("c:${pttKeycode}") "${unmute}") + (xbindkey '(release "c:${pttKeycode}") "${mute}") + ''; + + systemd.user.services."xbindkeys" = { + Unit = { + Description = "Keybind daemon for push-to-talk"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + + Service = { + ExecStart = "${pkgs.xbindkeys}/bin/xbindkeys -n -v"; + }; + }; +} diff --git a/users/grfn/system/home/modules/pure.zsh-theme b/users/grfn/system/home/modules/pure.zsh-theme new file mode 100755 index 000000000000..b4776e81596d --- /dev/null +++ b/users/grfn/system/home/modules/pure.zsh-theme @@ -0,0 +1,151 @@ +#!/bin/zsh -f +# vim: ft=zsh: +# MIT License +# For my own and others sanity +# git: +# %b => current branch +# %a => current action (rebase/merge) +# prompt: +# %F => color dict +# %f => reset color +# %~ => current path +# %* => time +# %n => username +# %m => shortname host +# %(?..) => prompt conditional - %(condition.true.false) + +# turns seconds into human readable time +# 165392 => 1d 21h 56m 32s +prompt_pure_human_time() { + local tmp=$1 + local days=$(( tmp / 60 / 60 / 24 )) + local hours=$(( tmp / 60 / 60 % 24 )) + local minutes=$(( tmp / 60 % 60 )) + local seconds=$(( tmp % 60 )) + (( $days > 0 )) && echo -n "${days}d " + (( $hours > 0 )) && echo -n "${hours}h " + (( $minutes > 0 )) && echo -n "${minutes}m " + echo "${seconds}s" +} + +is_git_repo() { + command git rev-parse --is-inside-work-tree &>/dev/null + return $? +} + +# fastest possible way to check if repo is dirty +prompt_pure_git_dirty() { + # check if we're in a git repo + is_git_repo || return + # check if it's dirty + [[ "$PURE_GIT_UNTRACKED_DIRTY" == 0 ]] && local umode="-uno" || local umode="-unormal" + command test -n "$(git status --porcelain --ignore-submodules ${umode})" + + (($? == 0)) && echo '*' +} + +prompt_pure_git_wip() { + is_git_repo || return + local subject="$(command git show --pretty=%s --quiet HEAD 2>/dev/null)" + [ "$subject" == 'wip' ] && echo '[WIP]' +} + +# displays the exec time of the last command if set threshold was exceeded +prompt_pure_cmd_exec_time() { + local stop=$EPOCHSECONDS + local start=${cmd_timestamp:-$stop} + integer elapsed=$stop-$start + (($elapsed > ${PURE_CMD_MAX_EXEC_TIME:=5})) && prompt_pure_human_time $elapsed +} + +prompt_pure_preexec() { + cmd_timestamp=$EPOCHSECONDS + + # shows the current dir and executed command in the title when a process is active + print -Pn "\e]0;" + echo -nE "$PWD:t: $2" + print -Pn "\a" +} + +# string length ignoring ansi escapes +prompt_pure_string_length() { + echo ${#${(S%%)1//(\%([KF1]|)\{*\}|\%[Bbkf])}} +} + +prompt_pure_nix_info() { + local packages_info='' + if [[ -z $NIX_SHELL_PACKAGES ]]; then + packages_info='[nix-shell]' + else + packages_info="{ $NIX_SHELL_PACKAGES }" + fi + + case $IN_NIX_SHELL in + 'pure') + echo "$fg_bold[green][nix-shell] " + ;; + 'impure') + echo "$fg_bold[magenta][nix-shell] " + ;; + *) ;; + esac +} + +prompt_pure_precmd() { + # shows the full path in the title + print -Pn '\e]0;%~\a' + + # git info + vcs_info + + local prompt_pure_preprompt="\n$(prompt_pure_nix_info)$fg_bold[green]$prompt_pure_username%F{blue}%~%F{yellow}$vcs_info_msg_0_`prompt_pure_git_dirty` $fg_no_bold[red]`prompt_pure_git_wip`%f %F{yellow}`prompt_pure_cmd_exec_time`%f " + print -P $prompt_pure_preprompt + + # check async if there is anything to pull + # (( ${PURE_GIT_PULL:-1} )) && { + # # check if we're in a git repo + # command git rev-parse --is-inside-work-tree &>/dev/null && + # # make sure working tree is not $HOME + # [[ "$(command git rev-parse --show-toplevel)" != "$HOME" ]] && + # # check check if there is anything to pull + # command git fetch &>/dev/null && + # # check if there is an upstream configured for this branch + # command git rev-parse --abbrev-ref @'{u}' &>/dev/null && { + # local arrows='' + # (( $(command git rev-list --right-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows='โฃ' + # (( $(command git rev-list --left-only --count HEAD...@'{u}' 2>/dev/null) > 0 )) && arrows+='โก' + # print -Pn "\e7\e[A\e[1G\e[`prompt_pure_string_length $prompt_pure_preprompt`C%F{cyan}${arrows}%f\e8" + # } + # } &! + + # reset value since `preexec` isn't always triggered + unset cmd_timestamp +} + + +prompt_pure_setup() { + # prevent percentage showing up + # if output doesn't end with a newline + export PROMPT_EOL_MARK='' + + prompt_opts=(cr subst percent) + + zmodload zsh/datetime + autoload -Uz add-zsh-hook + autoload -Uz vcs_info + + add-zsh-hook precmd prompt_pure_precmd + add-zsh-hook preexec prompt_pure_preexec + + zstyle ':vcs_info:*' enable git + zstyle ':vcs_info:git*' formats ' %b' + zstyle ':vcs_info:git*' actionformats ' %b|%a' + + # show username@host if logged in through SSH + [[ "$SSH_CONNECTION" != '' ]] && prompt_pure_username='%n@%m ' + + # prompt turns red if the previous command didn't exit with 0 + PROMPT='%(?.%F{green}.%F{red})โฏ%f ' +} + +prompt_pure_setup "$@" diff --git a/users/grfn/system/home/modules/rtlsdr.nix b/users/grfn/system/home/modules/rtlsdr.nix new file mode 100644 index 000000000000..c8a404a1f49e --- /dev/null +++ b/users/grfn/system/home/modules/rtlsdr.nix @@ -0,0 +1,23 @@ +{ config, lib, pkgs, ... }: + +let + + nixpkgs-gnuradio = import + (pkgs.fetchFromGitHub { + owner = "doronbehar"; + repo = "nixpkgs"; + rev = "712561aa5f10bfe6112a1726a912585612a70d1f"; + sha256 = "04yqflbwjcfl9vlplphpj82csqqz9k6m3nj1ybhwgmsc4by7vivl"; + }) + { }; + +in + +{ + home.packages = with pkgs; [ + rtl-sdr + nixpkgs-gnuradio.gnuradio + nixpkgs-gnuradio.gnuradio.plugins.osmosdr + nixpkgs-gnuradio.gqrx + ]; +} diff --git a/users/grfn/system/home/modules/shell.nix b/users/grfn/system/home/modules/shell.nix new file mode 100644 index 000000000000..ed82292b0aab --- /dev/null +++ b/users/grfn/system/home/modules/shell.nix @@ -0,0 +1,185 @@ +{ config, lib, pkgs, ... }: +let + shellAliases = rec { + # NixOS stuff + hms = "home-manager switch"; + nor = "sudo nixos-rebuild switch"; + nrs = nor; + nrb = "sudo nixos-rebuild boot"; + ncg = "nix-collect-garbage"; + vihome = "vim ~/.config/nixpkgs/home.nix && home-manager switch"; + virc = "vim ~/code/system/home/modules/shell.nix && home-manager switch && source ~/.zshrc"; + visystem = "sudo vim /etc/nixos/configuration.nix && sudo nixos-rebuild switch"; + + # Nix + ns = "nix-shell"; + nb = "nix build -f ."; + nbl = "nix build -f . --builders ''"; # nix build local + lwo = "lorri watch --once"; + + # Docker and friends + "dcu" = "docker-compose up"; + "dcud" = "docker-compose up -d"; + "dc" = "docker-compose"; + "dcr" = "docker-compose restart"; + "dclf" = "docker-compose logs -f"; + "dck" = "docker"; + "dockerclean" = "dockercleancontainers && dockercleanimages"; + "dockercleanimages" = "docker images -a --no-trunc | grep none | awk '{print \$$3}' | xargs -L 1 -r docker rmi"; + "dockercleancontainers" = "docker ps -a --no-trunc| grep 'Exit' | awk '{print \$$1}' | xargs -L 1 -r docker rm"; + + # Directories + stck = "dirs -v"; + b = "cd ~1"; + ".." = "cd .."; + "..." = "cd ../.."; + "...." = "cd ../../.."; + "....." = "cd ../../../.."; + + # Aliases from old config + "http" = "http --style solarized"; + "grep" = "grep $GREP_OPTIONS"; + "bak" = "~/bin/backup.sh"; + "xmm" = "xmodmap ~/.Xmodmap"; + "asdflkj" = "asdf"; + "asdf" = "asdfghjkl"; + "asdfghjkl" = "echo \"Having some trouble?\""; + "ift" = "sudo iftop -i wlp3s0"; + "first" = "awk '{print \$$1}'"; + "cmt" = "git log --oneline | fzf-tmux | awk '{print \$$1}'"; + "workmon" = "xrandr --output DP-2 --pos 1440x900 --primary"; + "vi" = "vim"; + "adbdev" = "adb devices"; + "adbcon" = "adb connect $GNEX_IP"; + "mpalb" = "mpc search album"; + "mpart" = "mpc search artist"; + "mps" = "mpc search"; + "mpa" = "mpc add"; + "mpt" = "mpc toggle"; + "mpl" = "mpc playlist"; + "dsstore" = "find . -name '*.DS_Store' -type f -ls -delete"; + "df" = "df -h"; + "fs" = "stat -f '%z bytes'"; + "ll" = "ls -al"; + "la" = "ls -a"; + }; +in +{ + home.packages = with pkgs; [ + zsh + autojump + ntfy + ]; + + home.sessionVariables = { + EDITOR = "vim"; + LS_COLORS = "no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:"; + BROWSER = "firefox"; + BAT_THEME = "ansi-light"; + }; + + programs.bash = { + enable = true; + inherit shellAliases; + }; + + programs.zsh = { + enable = true; + enableAutosuggestions = true; + autocd = true; + + inherit shellAliases; + + history = rec { + save = 100000; + size = save; + }; + + oh-my-zsh = { + enable = true; + + plugins = [ + "battery" + "colorize" + "command-not-found" + "github" + "gitignore" + "postgres" + "systemd" + "themes" + "vi-mode" + ]; + + custom = "${pkgs.stdenv.mkDerivation { + name = "oh-my-zsh-custom"; + unpackPhase = ":"; + installPhase = '' + mkdir -p $out/themes + mkdir -p $out/custom/plugins + ln -s ${./pure.zsh-theme} $out/themes/pure.zsh-theme + ''; + }}"; + + theme = "pure"; + }; + + plugins = [{ + name = "pure-theme"; + src = pkgs.fetchFromGitHub { + owner = "sindresorhus"; + repo = "pure"; + rev = "0a92b02dd4172f6c64fdc9b81fe6cd4bddb0a23b"; + sha256 = "0l8jqhmmjn7p32hdjnv121xsjnqd2c0plhzgydv2yzrmqgyvx7cc"; + }; + }]; + + initExtraBeforeCompInit = '' + zstyle ':completion:*' completer _complete _ignored _correct _approximate + zstyle ':completion:*' matcher-list \'\' 'm:{[:lower:]}={[:upper:]} m:{[:lower:][:upper:]}={[:upper:][:lower:]} r:|[._- :]=** r:|=**' 'l:|=* r:|=*' + zstyle ':completion:*' max-errors 5 + zstyle ':completion:*' use-cache yes + zstyle ':completion::complete:grunt::options:' expire 1 + zstyle ':completion:*' prompt '%e errors' + # zstyle :compinstall filename '~/.zshrc' + autoload -Uz compinit + ''; + + initExtra = '' + source ${./zshrc} + source ${pkgs.fetchFromGitHub { + owner = "zsh-users"; + repo = "zsh-syntax-highlighting"; + rev = "7678a8a22780141617f809002eeccf054bf8f448"; + sha256 = "0xh4fbd54kvwwpqvabk8lpw7m80phxdzrd75q3y874jw0xx1a9q6"; + }}/zsh-syntax-highlighting.zsh + source ${pkgs.autojump}/share/autojump/autojump.zsh + source ${pkgs.fetchFromGitHub { + owner = "chisui"; + repo = "zsh-nix-shell"; + rev = "a65382a353eaee5a98f068c330947c032a1263bb"; + sha256 = "0l41ac5b7p8yyjvpfp438kw7zl9dblrpd7icjg1v3ig3xy87zv0n"; + }}/nix-shell.plugin.zsh + + eval "$(${pkgs.ntfy}/bin/ntfy shell-integration)" + + export RPS1="" + autoload -U promptinit; promptinit + prompt pure + + if [[ "$TERM" == "dumb" ]]; then + unsetopt zle + unsetopt prompt_cr + unsetopt prompt_subst + unfunction precmd + unfunction preexec + export PS1='$ ' + fi + ''; + }; + + programs.fzf = { + enable = true; + enableBashIntegration = true; + enableZshIntegration = true; + }; +} diff --git a/users/grfn/system/home/modules/tarsnap.nix b/users/grfn/system/home/modules/tarsnap.nix new file mode 100644 index 000000000000..87002610cbcf --- /dev/null +++ b/users/grfn/system/home/modules/tarsnap.nix @@ -0,0 +1,64 @@ +{ config, lib, pkgs, ... }: + +{ + home.packages = with pkgs; [ + tarsnap + ]; + + home.file.".tarsnaprc".text = '' + ### Recommended options + + # Tarsnap cache directory + cachedir /home/grfn/.cache/tarsnap + + # Tarsnap key file + keyfile /home/grfn/.private/tarsnap.key + + # Don't archive files which have the nodump flag set. + nodump + + # Print statistics when creating or deleting archives. + print-stats + + # Create a checkpoint once per GB of uploaded data. + checkpoint-bytes 1G + + ### Commonly useful options + + # Use SI prefixes to make numbers printed by --print-stats more readable. + humanize-numbers + + ### Other options, not applicable to most systems + + # Aggressive network behaviour: Use multiple TCP connections when + # writing archives. Use of this option is recommended only in + # cases where TCP congestion control is known to be the limiting + # factor in upload performance. + #aggressive-networking + + # Exclude files and directories matching specified patterns. + # Only one file or directory per command; multiple "exclude" + # commands may be given. + #exclude + + # Include only files and directories matching specified patterns. + # Only one file or directory per command; multiple "include" + # commands may be given. + #include + + # Attempt to reduce tarsnap memory consumption. This option + # will slow down the process of creating archives, but may help + # on systems where the average size of files being backed up is + # less than 1 MB. + #lowmem + + # Try even harder to reduce tarsnap memory consumption. This can + # significantly slow down tarsnap, but reduces its memory usage + # by an additional factor of 2 beyond what the lowmem option does. + #verylowmem + + # Snapshot time. Use this option if you are backing up files + # from a filesystem snapshot rather than from a "live" filesystem. + #snaptime <file> + ''; +} diff --git a/users/grfn/system/home/modules/twitter.nix b/users/grfn/system/home/modules/twitter.nix new file mode 100644 index 000000000000..3cb2e90adc34 --- /dev/null +++ b/users/grfn/system/home/modules/twitter.nix @@ -0,0 +1,23 @@ +{ pkgs, lib, ... }: + +{ + home.packages = with pkgs; [ + t + ]; + + home.sessionVariables = { + TWITTER_WHOAMI = "glittershark1"; + }; + + programs.zsh = { + shellAliases = { + "mytl" = "t tl $TWITTER_WHOAMI"; + }; + + functions = { + favelast = "t fave $(t tl -l $1 | head -n1 | cut -d' ' -f1)"; + rtlast = "t rt $(t tl -l $1 | head -n1 | cut -d' ' -f1)"; + tthread = "t reply $(t tl -l $TWITTER_WHOAMI | head -n1 | cut -d' ' -f1) $@"; + }; + }; +} diff --git a/users/grfn/system/home/modules/vim.nix b/users/grfn/system/home/modules/vim.nix new file mode 100644 index 000000000000..b87cb09ad125 --- /dev/null +++ b/users/grfn/system/home/modules/vim.nix @@ -0,0 +1,48 @@ +{ config, pkgs, ... }: +{ + programs.neovim = { + enable = true; + viAlias = true; + vimAlias = true; + plugins = with pkgs.vimPlugins; [ + ctrlp + deoplete-nvim + syntastic + vim-abolish + vim-airline + vim-airline-themes + vim-bufferline + vim-closetag + # vim-colors-solarized + # solarized + (pkgs.vimUtils.buildVimPlugin { + pname = "vim-colors-solarized"; + version = "git"; + src = pkgs.fetchFromGitHub { + owner = "glittershark"; + repo = "vim-colors-solarized"; + rev = "4857c3221ec3f2693a45855154cb61a2cefb514d"; + sha256 = "0kqp5w14g7adaiinmixm7z3x4w74lv1lcgbqjbirx760f0wivf9y"; + }; + }) + vim-commentary + vim-dispatch + vim-endwise + vim-repeat + vim-fugitive + vim-markdown + vim-nix + vim-rhubarb + vim-sexp + vim-sexp-mappings-for-regular-people + vim-sleuth + vim-startify + vim-surround + vim-unimpaired + vinegar + ]; + extraConfig = '' + source ${./vimrc} + ''; + }; +} diff --git a/users/grfn/system/home/modules/vimrc b/users/grfn/system/home/modules/vimrc new file mode 100644 index 000000000000..3e33b5e2bee7 --- /dev/null +++ b/users/grfn/system/home/modules/vimrc @@ -0,0 +1,1121 @@ +" vim:set fdm=marker fmr={{{,}}} ts=2 sts=2 sw=2 expandtab: + + +" Basic Options {{{ +set nocompatible +set modeline +set modelines=10 +syntax enable +filetype plugin indent on +set ruler +set showcmd +set number +set incsearch +set smartcase +set ignorecase +set scrolloff=10 +set tabstop=4 +set shiftwidth=4 +set softtabstop=4 +set nosmartindent +set expandtab +set noerrorbells visualbell t_vb= +set laststatus=2 +set hidden +let mapleader = ',' +let maplocalleader = '\' +set undofile +" set undodir=~/.vim/undo +set wildignore=*.pyc,*.o,.git +set clipboard=unnamedplus +" set backupdir=$HOME/.vim/backup +" set directory=$HOME/.vim/tmp +set foldmarker={{{,}}} +set colorcolumn=+1 +set concealcursor= +set formatoptions+=j +set wildmenu +set wildmode=longest,list:full +set noincsearch +" }}} + +" GUI options {{{ +set go-=m +set go-=T +set go-=r +set go-=L +set go-=e +set guifont=Meslo\ LG\ S\ DZ\ 9 +" }}} + +" Colors {{{ +" set t_Co=256 + +fu! ReverseBackground() + if &bg=="light" + se bg=dark + else + se bg=light + endif +endf +com! BgToggle call ReverseBackground() +nm <F12> :BgToggle<CR> + +set background=light +colorscheme solarized +" }}} + +" --------------------------------------------------------------------------- + +" CtrlP {{{ +let g:ctrlp_custom_ignore = { + \ 'dir': '(node_modules|target)' + \ } +let g:ctrlp_max_files = 0 +let g:ctrlp_max_depth = 100 +" }}} + +" YouCompleteMe {{{ +let g:ycm_semantic_triggers = { + \ 'c' : ['->', '.'], + \ 'objc' : ['->', '.'], + \ 'ocaml' : ['.', '#'], + \ 'cpp,objcpp' : ['->', '.', '::'], + \ 'perl' : ['->'], + \ 'php' : ['->', '::'], + \ 'cs,java,javascript,d,python,perl6,scala,vb,elixir,go' : ['.'], + \ 'vim' : ['re![_a-zA-Z]+[_\w]*\.'], + \ 'lua' : ['.', ':'], + \ 'erlang' : [':'], + \ 'clojure' : [], + \ 'haskell' : ['re!.*', '.', ' ', '('] + \ } + " \ 'haskell' : ['.', '(', ' '] + " \ 'ruby' : ['.', '::'], + " \ 'clojure' : ['(', '.', '/', '['] +" }}} + +" Neocomplete {{{ +if !has('nvim') + " Use neocomplete. + let g:neocomplete#enable_at_startup = 1 + " Use smartcase. + let g:neocomplete#enable_smart_case = 1 + " Set minimum syntax keyword length. + let g:neocomplete#sources#syntax#min_keyword_length = 3 + let g:neocomplete#lock_buffer_name_pattern = '\*ku\*' + + " Define dictionary. + " let g:neocomplete#sources#dictionary#dictionaries = { + " \ 'default' : '', + " \ 'vimshell' : $HOME.'/.vimshell_hist', + " \ 'scheme' : $HOME.'/.gosh_completions' + " \ } + + " Define keyword. + if !exists('g:neocomplete#keyword_patterns') + let g:neocomplete#keyword_patterns = {} + endif + let g:neocomplete#keyword_patterns['default'] = '\h\w*' + + " Plugin key-mappings. + inoremap <expr><C-g> neocomplete#undo_completion() + inoremap <expr><C-l> neocomplete#complete_common_string() + + " Recommended key-mappings. + " <CR>: close popup and save indent. + inoremap <silent> <CR> <C-r>=<SID>my_cr_function()<CR> + function! s:my_cr_function() + return (pumvisible() ? "\<C-y>" : "" ) . "\<CR>" + " For no inserting <CR> key. + "return pumvisible() ? "\<C-y>" : "\<CR>" + endfunction + " <TAB>: completion. + inoremap <expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>" + " <C-h>, <BS>: close popup and delete backword char. + inoremap <expr><C-h> neocomplete#smart_close_popup()."\<C-h>" + inoremap <expr><BS> neocomplete#smart_close_popup()."\<C-h>" + " Close popup by <Space>. + "inoremap <expr><Space> pumvisible() ? "\<C-y>" : "\<Space>" + + " AutoComplPop like behavior. + "let g:neocomplete#enable_auto_select = 1 + + " Shell like behavior(not recommended). + "set completeopt+=longest + "let g:neocomplete#enable_auto_select = 1 + "let g:neocomplete#disable_auto_complete = 1 + "inoremap <expr><TAB> pumvisible() ? "\<Down>" : "\<C-x>\<C-u>" + + " Enable omni completion. + " autocmd FileType css setlocal omnifunc=csscomplete#CompleteCSS + " autocmd FileType html,markdown setlocal omnifunc=htmlcomplete#CompleteTags + " autocmd FileType javascript setlocal omnifunc=javascriptcomplete#CompleteJS + " autocmd FileType python setlocal omnifunc=pythoncomplete#Complete + " autocmd FileType xml setlocal omnifunc=xmlcomplete#CompleteTags + + " Enable heavy omni completion. + if !exists('g:neocomplete#sources#omni#input_patterns') + let g:neocomplete#sources#omni#input_patterns = {} + endif +endif +" }}} + +" Deoplete {{{ +if has('nvim') + let g:deoplete#enable_at_startup = 1 + + inoremap <silent> <CR> <C-r>=<SID>my_cr_function()<CR> + function! s:my_cr_function() + return (pumvisible() ? "\<C-y>" : "" ) . "\<CR>" + " For no inserting <CR> key. + "return pumvisible() ? "\<C-y>" : "\<CR>" + endfunction + " <TAB>: completion. + inoremap <expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>" + inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<TAB>" +endif +" }}} + +" Neovim Terminal mode {{{ +if has('nvim') + tnoremap <Esc> <C-\><C-n> + nnoremap \\ :tabedit term://zsh<CR> + nnoremap q\ :call <SID>OpenRepl()<CR> + + if !exists('g:repl_size') + let g:repl_size=9 + endif + + function! s:OpenRepl() " {{{ + " Check if buffer exists and is open + if exists('s:repl_bufname') && bufexists(s:repl_bufname) && bufwinnr(s:repl_bufname) >=? 0 + " If so, just switch to it + execute bufwinnr(s:repl_bufname) . 'wincmd' 'w' + norm i + return + endif + + if !exists('b:console') + let b:console=$SHELL + endif + + let l:console_cmd = b:console + + execute 'bot' g:repl_size . 'new' + set winfixheight nobuflisted + call termopen(l:console_cmd) + let s:repl_bufname = bufname('%') + norm i + endfunction " }}} +endif +" }}} + +" Tagbar options {{{ +let g:tagbar_autoclose = 1 +let g:tagbar_autofocus = 1 +let g:tagbar_compact = 1 +" }}} + +" delimitMate options {{{ +let g:delimitMate_expand_cr = 1 +" }}} + +" UltiSnips options {{{ +let g:UltiSnipsExpandTrigger = '<c-j>' + "g:UltiSnipsJumpForwardTrigger <c-j> + "g:UltiSnipsJumpBackwardTrigger <c-k> +" }}} + +" VDebug Options {{{ +let g:vdebug_options = {'server': '192.168.56.1'} +" }}} + +" Statusline {{{ +let g:airline_powerline_fonts=1 + +if !exists('g:airline_symbols') + let g:airline_symbols = {} +endif +let g:airline_symbols.space = "\ua0" + +let g:airline#extensions#tagbar#flags = 'f' +let g:airline#extensions#tabline#enabled = 1 +let g:airline#extensions#tabline#show_buffers = 0 +let g:airline#extensions#tabline#show_tabs = 1 +let g:airline#extensions#tabline#tab_min_count = 2 +let g:airline#extensions#tmuxline#enabled = 0 + +let g:tmuxline_theme = 'airline' +let g:tmuxline_preset = 'full' + +"set statusline= +"set statusline+=%2*[%n%H%M%R%W]%*\ " flags and buf no +"set statusline+=%-40f%<\ " path +"set statusline+=%=%40{fugitive#statusline()}\ " Vim status +"set statusline+=%1*%y%*%*\ " file type +"set statusline+=%10((%l,%c)%)\ " line and column +"set statusline+=%P " percentage of file +" }}} + +" Code review mode {{{ +fun! GetFontName() + return substitute(&guifont, '^\(.\{-}\)[0-9]*$', '\1', '') +endfun + +fun! <SID>CodeReviewMode() + let &guifont = GetFontName() . ' 15' +endfun +com! CodeReviewMode call <SID>CodeReviewMode() +" }}} + +" Syntastic {{{ +let g:syntastic_enable_signs = 0 + +" Python {{{ +let g:syntastic_python_checkers = ['flake8'] +let g:syntastic_python_flake8_post_args = "--ignore=E101,E223,E224,E301,E302,E303,E501,E701,W,F401,E111,E261" + +" }}} +" Javascript {{{ +let g:syntastic_javascript_checkers = ['eslint'] +let g:flow#autoclose = 1 +let g:flow#enable = 1 + +" augroup syntastic_javascript_jsx +" autocmd! +" autocmd BufReadPre,BufNewFile *.js +" autocmd BufReadPre,BufNewFile *.jsx +" \ let g:syntastic_javascript_checkers = ['jsxhint'] +" augroup END + +" }}} +" Haml {{{ +let g:syntastic_haml_checkers = ['haml_lint'] + +" }}} +" Html {{{ +let g:syntastic_html_checkers = [] + +" }}} +" Ruby {{{ +let g:syntastic_ruby_checkers = ['rubocop'] +" }}} +" SASS/SCSS {{{ +let g:syntastic_scss_checkers = ['scss_lint'] +" }}} +" Haskell {{{ +" let g:syntastic_haskell_checkers = ['ghc-mod'] +" }}} +" Elixir {{{ +let g:syntastic_elixir_checkers = ['elixir'] +let g:syntastic_enable_elixir_checker = 1 +" }}} +" }}} + +" Bufferline {{{ +let g:bufferline_echo=0 +" }}} + +" Eclim {{{ +let g:EclimCompletionMethod = 'omnifunc' +augroup eclim + au! + au FileType java call <SID>JavaSetup() + au FileType java set textwidth=120 +augroup END + +function! s:JavaSetup() abort + noremap <C-I> :JavaImport<CR> + nnoremap K :JavaDocPreview<CR> + nnoremap ]d :JavaSearchContext<CR> + nnoremap [d :JavaSearchContext<CR> + nnoremap g<CR> :JUnit<CR> + nnoremap g\ :Mvn test<CR> +endfunction +" }}} + +" Signify options {{{ +let g:signify_mapping_next_hunk = ']h' +let g:signify_mapping_prev_hunk = '[h' +let g:signify_vcs_list = ['git'] +let g:signify_sign_change = '~' +let g:signify_sign_delete = '-' +" }}} + +" Simplenote {{{ +let g:SimplenoteFiletype = 'markdown' +let g:SimplenoteSortOrder = 'pinned,modifydate,tagged,createdate' +let g:SimplenoteVertical = 1 + +nnoremap <Leader>nn :Simplenote -n<CR> +nnoremap <Leader>nl :Simplenote -l<CR> +nnoremap <Leader>nw :Simplenote -l work<CR> +nnoremap <Leader>nt :Simplenote -t<CR> +" }}} + +" Emmet {{{ +" Expand abbreviation +let g:user_emmet_leader_key = '<C-y>' +" }}} + +" Startify {{{ +let g:startify_bookmarks=[ '~/.vimrc', '~/.zshrc' ] +" }}} + +" Abolish {{{ +let g:abolish_save_file = expand('~/.vim/after/plugin/abolish.vim') +" }}} + +" Rails projections {{{ + +if !exists('g:rails_projections') + let g:rails_projections = {} +endif + +call extend(g:rails_projections, { + \ "config/routes.rb": { "command": "routes" }, + \ "config/structure.sql": { "command": "structure" } + \ }, 'keep') + +if !exists('g:rails_gem_projections') + let g:rails_gem_projections = {} +endif + +call extend(g:rails_gem_projections, { + \ "active_model_serializers": { + \ "app/serializers/*_serializer.rb": { + \ "command": "serializer", + \ "template": "class %SSerializer < ActiveModel::Serializer\nend", + \ "affinity": "model"}}, + \ "react-rails": { + \ "app/assets/javascripts/components/*.jsx": { + \ "command": "component", + \ "template": "var %S = window.%S = React.createClass({\n render: function() {\n }\n});", + \ "alternate": "spec/javascripts/components/%s_spec.jsx" }, + \ "spec/javascripts/components/*_spec.jsx": { + \ "alternate": "app/assets/javascripts/components/{}.jsx" }}, + \ "rspec": { + \ "spec/**/support/*.rb": { + \ "command": "support"}}, + \ "cucumber": { + \ "features/*.feature": { + \ "command": "feature", + \ "template": "Feature: %h"}, + \ "features/support/*.rb": { + \ "command": "support"}, + \ "features/support/env.rb": { + \ "command": "support"}, + \ "features/step_definitions/*_steps.rb": { + \ "command": "steps"}}, + \ "carrierwave": { + \ "app/uploaders/*_uploader.rb": { + \ "command": "uploader", + \ "template": "class %SUploader < CarrierWave::Uploader::Base\nend"}}, + \ "draper": { + \ "app/decorators/*_decorator.rb": { + \ "command": "decorator", + \ "affinity": "model", + \ "template": "class %SDecorator < Draper::Decorator\nend"}}, + \ "fabrication": { + \ "spec/fabricators/*_fabricator.rb": { + \ "command": ["fabricator", "factory"], + \ "alternate": "app/models/%s.rb", + \ "related": "db/schema.rb#%p", + \ "test": "spec/models/%s_spec.rb", + \ "template": "Fabricator :%s do\nend", + \ "affinity": "model"}}, + \ "factory_girl": { + \ "spec/factories/*.rb": { + \ "command": "factory", + \ "alternate": "app/models/%i.rb", + \ "related": "db/structure.sql#%s", + \ "test": "spec/models/%s_spec.rb", + \ "template": "FactoryGirl.define do\n factory :%i do\n end\nend", + \ "affinity": "model"}, + \ "spec/factories.rb": { + \ "command": "factory"}, + \ "test/factories.rb": { + \ "command": "factory"}} + \ }, 'keep') +" }}} + +" Other projections {{{ +let g:projectionist_heuristics = { + \ "config.ru&docker-compose.yml&app/&config/&OWNERS": { + \ "app/jobs/*.rb": { + \ "type": "job", + \ "alternate": "spec/jobs/{}_spec.rb" + \ }, + \ "app/models/*.rb": { + \ "type": "model", + \ "alternate": "spec/models/{}_spec.rb" + \ }, + \ "app/resources/*_resource.rb": { + \ "type": "resource", + \ "alternate": "spec/resources/{}_resource_spec.rb" + \ }, + \ "config/*.yml": { + \ "type": "config" + \ }, + \ "spec/*_spec.rb": { + \ "type": "spec", + \ "alternate": "app/{}.rb" + \ }, + \ "spec/factories/*.rb": { + \ "type": "factory", + \ } + \ }, + \ "svc-gateway.cabal": { + \ "src/*.hs": { + \ "type": "src", + \ "alternate": "test/{}Spec.hs" + \ }, + \ "test/*Spec.hs": { + \ "type": "spec", + \ "alternate": "src/{}.hs", + \ "template": [ + \ "module Gateway.Resource.HierarchySpec (main, spec) where", + \ "", + \ "import Prelude", + \ "import Test.Hspec", + \ "import Data.Aeson", + \ "", + \ "import Gateway.Resource.Hierarchy", + \ "", + \ "main :: IO ()", + \ "main = hspec spec", + \ "", + \ "spec :: Spec", + \ "spec = do", + \ " describe \"something\" $ undefined" + \ ] + \ }, + \ "svc-gateway.cabal": { + \ "type": "cabal" + \ } + \ }, + \ "package.json&.flowconfig": { + \ "src/*.*": { + \ "type": "src", + \ "alternate": "test/{}_spec.js" + \ } + \ }, + \ "pom.xml&src/main/clj/|src/main/cljs": { + \ "*": { + \ "start": "USE_NREPL=1 bin/run -m elephant.dev-system" , + \ "connect": "nrepl://localhost:5554", + \ "piggieback": "(figwheel-sidecar.repl-api/repl-env)" + \ }, + \ "pom.xml": { "type": "pom" }, + \ "src/main/clj/*.clj": { + \ "alternate": "src/test/clj/{}_test.clj", + \ "template": ["(ns {dot|hyphenate})"] + \ }, + \ "src/test/clj/*_test.clj": { + \ "alternate": "src/main/clj/{}.clj", + \ "dispatch": ":RunTests {dot|hyphenate}-test", + \ "template": ["(ns {dot|hyphenate}-test", + \ " (:require [clojure.test :refer :all]))"] + \ }, + \ "src/main/cljs/*.cljs": { + \ "alternate": "src/test/cljs/{}_test.cljs" + \ }, + \ "src/main/cljs/*_test.cljs": { + \ "alternate": "src/main/cljs/{}.cljs", + \ "dispatch": ":RunTests {dot|hyphenate}-test" + \ }, + \ "src/main/clj/*.cljc": { + \ "alternate": "src/test/clj/{}_test.cljc" + \ }, + \ "src/main/clj/*_test.cljc": { + \ "alternate": "src/test/clj/{}.cljc", + \ "dispatch": ":RunTests {dot|hyphenate}-test" + \ } + \ }} +" }}} + +" AutoPairs {{{ +let g:AutoPairsCenterLine = 0 +" }}} + +" Filetypes {{{ + +" Python {{{ +aug Python + au! + au FileType python set tabstop=4 shiftwidth=4 softtabstop=4 expandtab +aug END +let g:python_highlight_all=1 +" }}} + +" PHP {{{ +aug PHP + au! + "au FileType php setlocal fdm=marker fmr={{{,}}} +aug END " }}} + +" Mail {{{ +aug Mail + au FileType mail setlocal spell +aug END " }}} + +" Haskell {{{ +let g:haskell_conceal_wide = 1 +let g:haskellmode_completion_ghc = 0 +let g:necoghc_enable_detailed_browse = 1 + +augroup Haskell + autocmd! + autocmd FileType haskell setlocal textwidth=110 shiftwidth=2 + autocmd FileType haskell setlocal omnifunc=necoghc#omnifunc + autocmd FileType haskell call <SID>HaskellSetup() + autocmd FileType haskell setlocal keywordprg=hoogle\ -cie +augroup END + +function! s:HaskellSetup() + set sw=4 + " compiler cabal + " let b:start='cabal run' + " let b:console='cabal repl' + " let b:dispatch='cabal test' + compiler stack + let b:start='stack run' + let b:console='stack ghci' + let b:dispatch='stack test' + nnoremap <buffer> gy :HdevtoolsType<CR> + nnoremap <buffer> yu :HdevtoolsClear<CR> +endfunction +" }}} + +" Ruby {{{ + +function! s:RSpecSyntax() + syn keyword rspecMethod describe context it its specify shared_context + \ shared_examples shared_examples_for shared_context include_examples + \ include_context it_should_behave_like it_behaves_like before after + \ around fixtures controller_name helper_name scenario feature + \ background given described_class + syn match rspecMethod '\<let\>!\=' + syn match rspecMethod '\<subject\>!\=' + syn keyword rspecMethod violated pending expect expect_any_instance_of allow + \ allow_any_instance_of double instance_double mock mock_model + \ stub_model xit + syn match rspecMethod '\.\@<!\<stub\>!\@!' + + call s:RSpecHiDefaults() +endfunction + +function! s:RSpecHiDefaults() + hi def link rspecMethod rubyFunction +endfunction + +augroup Ruby + au! + " au FileType ruby let b:surround_114 = "\\(module|class,def,if,unless,case,while,until,begin,do) \r end" + " au FileType ruby set fdm=syntax + au FileType ruby set tw=110 + au FileType ruby set omnifunc= + au FileType ruby nnoremap <buffer> gy orequire 'pry'; binding.pry<ESC>^ + au FileType ruby nnoremap <buffer> gY Orequire 'pry'; binding.pry<ESC>^ + au FileType ruby nnoremap <buffer> yu :g/require 'pry'; binding.pry/d<CR> + au BufNewFile,BufRead *_spec.rb call <SID>RSpecSyntax() +augroup END + +let ruby_operators = 1 +let ruby_space_errors = 1 + +let g:rubycomplete_rails = 1 +command! -range ConvertHashSyntax <line1>,<line2>s/:(\S{-})(\s{-})=> /\1:\2/ +" }}} + +" Clojure {{{ + +aug Clojure + au! + autocmd FileType clojure nnoremap <C-S> :Slamhound<CR> + autocmd FileType clojure nnoremap <silent> gr :w <bar> Require <bar> e<CR> + let g:clojure_align_multiline_strings = 1 + let g:clojure_fuzzy_indent_patterns = + \ ['^with', '^def', '^let', '^fact'] + let g:clojure_special_indent_words = + \ 'deftype,defrecord,reify,proxy,extend-type,extend-protocol,letfn,html' + + autocmd FileType clojure setlocal textwidth=80 + autocmd FileType clojure setlocal lispwords+=GET,POST,PATCH,PUT,DELETE | + \ setlocal lispwords+=context,select + autocmd BufNewFile,BufReadPost *.cljx setfiletype clojure + autocmd BufNewFile,BufReadPost *.cljx setlocal omnifunc= + autocmd BufNewFile,BufReadPost *.cljs setlocal omnifunc= + autocmd FileType clojure call <SID>TangentInit() + autocmd FileType clojure call <SID>sexp_mappings() + autocmd BufRead *.cljc ClojureHighlightReferences + autocmd FileType clojure let b:AutoPairs = { + \ '"': '"', + \ '{': '}', + \ '(': ')', + \ '[': ']'} + " Don't auto-pair quote reader macros + " \'`': '`', + " \ '''': '''', + + autocmd User ProjectionistActivate call s:projectionist_connect() + + function! s:projectionist_connect() abort + let connected = !empty(fireplace#path()) + if !connected + for [root, value] in projectionist#query('connect') + try + silent execute "FireplaceConnect" value root + let connected = 1 + break + catch /.*Connection refused.*/ + endtry + endfor + endif + + " if connected && exists(':Piggieback') + " for [root, value] in projectionist#query('piggieback') + " silent execute "Piggieback" value + " break + " endfor + " endif + endfunction + + " autocmd BufNewFile,BufReadPost *.cljx setlocal omnifunc= + " autocmd BufNewFile,BufReadPost *.cljs setlocal omnifunc= + + autocmd FileType clojure let b:console='lein repl' + autocmd FileType clojure call <SID>ClojureMaps() + + function! s:ClojureMaps() abort + nnoremap <silent> <buffer> [m :call search('^(def', 'Wzb')<CR> + nnoremap <silent> <buffer> ]m :call search('^(def', 'Wz')<CR> + endfunction + + command! Scratch call <SID>OpenScratch() + autocmd FileType clojure nnoremap <buffer> \s :Scratch<CR> + + let g:scratch_buffer_name = 'SCRATCH' + + function! s:OpenScratch() + if bufwinnr(g:scratch_buffer_name) > 0 + execute bufwinnr(g:scratch_buffer_name) . 'wincmd' 'w' + return + endif + + vsplit SCRATCH + set buftype=nofile + set filetype=clojure + let b:scratch = 1 + endfunction +aug END + +function! s:sexp_mappings() abort + if !exists('g:sexp_loaded') + return + endif + + nmap <buffer> cfo <Plug>(sexp_raise_list) + nmap <buffer> cfO <Plug>(sexp_raise_element) + nmap <buffer> cfe <Plug>(sexp_raise_element) +endfunction + +function! s:TangentInit() abort + set textwidth=80 + command! TReset call fireplace#session_eval('(user/reset)') + command! TGo call fireplace#session_eval('(user/go)') + command! TMigrate call fireplace#session_eval('(user/migrate)') + command! TRollback call fireplace#session_eval('(user/rollback)') + nnoremap g\ :TReset<CR> +endfunction + +" }}} + +" Go {{{ + +let g:go_highlight_functions = 1 +let g:go_highlight_methods = 1 +let g:go_highlight_structs = 1 +let g:go_highlight_operators = 1 +let g:go_highlight_build_constraints = 1 + +augroup Go + autocmd! + autocmd FileType go setlocal omnifunc=go#complete#Complete + autocmd FileType go setlocal foldmethod=syntax + autocmd FileType go setlocal foldlevel=100 + autocmd FileType go nnoremap <buffer> <F9> :GoTest<CR> + autocmd FileType go inoremap <buffer> <F9> <ESC>:GoTest<CR>i +augroup END + +" }}} + +" RAML {{{ + +function! s:buffer_syntax() " {{{ + syn keyword ramlRAML RAML contained + syn match ramlVersionString '^#%RAML \d\.\d' contains=ramlRAML +endfunction " }}} + +augroup RAML + autocmd! + autocmd BufRead,BufNewFile *.raml set filetype=yaml + autocmd BufRead,BufNewFile *.raml call s:buffer_syntax() +augroup END + +hi def link ramlVersionString Special +hi def link ramlRAML Error +" }}} + +" Mustache/Handlebars {{{ +let g:mustache_abbreviations = 1 +" }}} + +" Netrw {{{ +augroup netrw + autocmd! + autocmd FileType netrw nnoremap <buffer> Q :Rexplore<CR> + + " Hee hee, oil and vinegar + function! s:setup_oil() abort + nnoremap <buffer> q <C-6> + xnoremap <buffer> q <C-6> + endfunction +augroup END +" }}} +" }}} + +" Remove trailing whitespace {{{ +fun! <SID>StripTrailingWhitespaces() + let l = line(".") + let c = col(".") + %s/\s\+$//e + call cursor(l, c) +endfun + +augroup striptrailingwhitespaces " {{{ +autocmd FileType c,cpp,java,php,ruby,python,sql,javascript,sh,jst,less,haskell,haml,coffee,scss,clojure,objc,elixir,yaml,json,eruby + \ autocmd BufWritePre <buffer> :call <SID>StripTrailingWhitespaces() +augroup END " }}} + +" }}} + +" Goyo {{{ +let g:limelight_conceal_ctermfg = "10" +let g:limelight_conceal_guifg = "#586e75" +autocmd! User GoyoEnter Limelight +autocmd! User GoyoLeave Limelight! +" }}} + +"----------------------------------------------------------------------------- + +" Commands {{{ + +" Edit temporary SQL files {{{ +let s:curr_sql = 0 +fun! <SID>EditSqlTempFile() + let l:fname = '/tmp/q' . s:curr_sql . '.sql' + execute 'edit' l:fname + let s:curr_sql = s:curr_sql + 1 +endfun +com! EditSqlTempFile call <SID>EditSqlTempFile() +" }}} + +" Double Indentation +command! -range DoubleIndentation <line1>,<line2>s/^\(\s.\{-}\)\(\S\)/\1\1\2/ + +" Quick-and-dirty fix capitalization of sql files +command! -range FixSqlCapitalization <line1>,<line2>v/\v(^\s*--.*$)|(TG_)/norm guu + +" VimPipe Commands {{{ +" let g:sql_type_default = 'pgsql' +command! SqlLive let b:vimpipe_command="vagrant ssh -c '~/mysql'" +command! SqlRails let b:vimpipe_command="bin/rails dbconsole" +command! SqlHeroku let b:vimpipe_command="heroku pg:psql" +command! SqlEntities let b:vimpipe_command="psql -h 127.1 entities nomi" +command! SqlUsers let b:vimpipe_command="psql -h 127.1 users nomi" +command! SqlTangent let b:vimpipe_command="psql -h local.docker tangent super" +" }}} + +" Git commands {{{ +command! -nargs=* Gpf Gpush -f <args> +command! -nargs=* Gcv Gcommit --verbose <args> +" }}} + +" Focus dispatch to only the last failures +command! -nargs=* FocusFailures FocusDispatch rspec --only-failures <args> + +" }}} + +" Autocommands {{{ + +augroup fugitive " {{{ + au! + autocmd BufNewFile,BufRead fugitive://* set bufhidden=delete +augroup END " }}} + +augroup omni " {{{ + au! + " autocmd FileType javascript setlocal omnifunc=tern#Complete + "autocmd FileType python setlocal omnifunc=pythoncomplete#Complete + autocmd FileType php setlocal omnifunc= +augroup END " }}} + +augroup sql " {{{ + au! + autocmd FileType sql let b:vimpipe_command="psql -h 127.0.0.1 landlordsny_development landlordsny" + autocmd FileType sql let b:vimpipe_filetype="postgresql" + autocmd FileType sql set syntax=postgresql + autocmd FileType postgresql set nowrap + autocmd BufNewFile,BufReadPost *.sql set syntax=pgsql +augroup END " }}} + +augroup markdown " {{{ + au! + autocmd FileType markdown let b:vimpipe_command='markdown' + autocmd FileType markdown let b:vimpipe_filetype='html' + autocmd FileType markdown set tw=80 +augroup END " }}} + +augroup typescript " {{{ + au! + autocmd FileType typescript let b:vimpipe_command='tsc' + autocmd FileType typescript let b:vimpipe_filetype='javascript' + autocmd FileType typescript TSSstarthere + autocmd FileType typescript nnoremap <buffer> gd :TSSdef<CR> +augroup END " }}} + +augroup jsx " {{{ + au! + " autocmd FileType jsx set syntax=javascript + autocmd FileType javascript set filetype=javascript.jsx +augroup END " }}} + +augroup nicefoldmethod " {{{ + au! + " Don't screw up folds when inserting text that might affect them, until + " leaving insert mode. Foldmethod is local to the window. Protect against + " screwing up folding when switching between windows. + autocmd InsertEnter * + \ if !exists('w:last_fdm') | + \ let w:last_fdm=&foldmethod | + \ setlocal foldmethod=manual | + \ endif + autocmd InsertLeave,WinLeave * + \ if exists('w:last_fdm') | + \ let &l:foldmethod=w:last_fdm | + \ unlet w:last_fdm | + \ endif +augroup END " }}} + +augroup visualbell " {{{ + au! + autocmd GUIEnter * set visualbell t_vb= +augroup END +" }}} + +augroup quickfix " {{{ + au! + autocmd QuickFixCmdPost grep cwindow +augroup END " }}} + +augroup php " {{{ + au! +augroup END "}}} + +augroup rubylang " {{{ + au! + autocmd FileType ruby compiler rake +augroup END " }}} + +augroup javascript "{{{ + au! + autocmd FileType javascript let &errorformat = + \ '%E%.%#%n) %s:,' . + \ '%C%.%#Error: %m,' . + \ '%C%.%#at %s (%f:%l:%c),' . + \ '%Z%.%#at %s (%f:%l:%c),' . + \ '%-G%.%#,' +augroup END " }}} + +augroup git " {{{ + autocmd! + autocmd FileType gitcommit set textwidth=72 +augroup END +" }}} +" }}} + +" Leader commands {{{ + +" Edit specific files {{{ +nnoremap <silent> <leader>ev :split $MYVIMRC<CR> +nnoremap <silent> <leader>eb :split ~/.vim_bundles<CR> +nnoremap <silent> <leader>es :UltiSnipsEdit<CR> +nnoremap <silent> <leader>ea :split ~/.vim/after/plugin/abolish.vim<CR> + +nnoremap <silent> <leader>sv :so $MYVIMRC<CR> +nnoremap <silent> <leader>sb :so ~/.vim_bundles<CR> +nnoremap <silent> <leader>sa :so ~/.vim/after/plugin/abolish.vim<CR> + +nnoremap <Leader>el :EditSqlTempFile<CR> +" }}} + +" Toggle navigation panels {{{ +nnoremap <Leader>l :TagbarToggle<CR> +nnoremap <Leader>mb :MBEToggle<CR> +nnoremap <Leader>u :GundoToggle<CR> + +nnoremap <Leader>t :CtrlP<CR> +nnoremap <Leader>z :FZF<CR> +nnoremap <Leader>b :CtrlPBuffer<CR> +nnoremap <Leader>a :CtrlPTag<CR> +nnoremap <Leader>r :CtrlPGitBranch<CR> +" }}} + +" CtrlP {{{ +let g:ctrlp_custom_ignore = { + \ 'dir': 'node_modules', + \ } +" }}} + +" Git leader commands {{{ +noremap <Leader>g :Git<SPACE> +noremap <Leader>gu :Gpull<CR> +noremap <Leader>gp :Gpush<CR> +noremap <Leader>s :Gstatus<CR> +noremap <Leader>cv :Gcommit --verbose<CR> +noremap <Leader>ca :Gcommit --verbose --amend<CR> + +nnoremap <Leader>dl :diffg LOCAL<CR> +nnoremap <Leader>dr :diffg REMOTE<CR> +nnoremap <Leader>db :diffg BASE<CR> +nnoremap <Leader>du :diffu<CR> +nnoremap <Leader>dg :diffg<CR> + +nnoremap <Leader>d2 :diffg //2<CR>:diffu<CR> +nnoremap <Leader>d3 :diffg //3<CR>:diffu<CR> + +nnoremap <Leader>yt :SignifyToggle<CR> +" }}} + +" Breakpoint Leader Commands {{{ +nnoremap <Leader>x :Breakpoint<CR> +nnoremap <Leader>dx :BreakpointRemove *<CR> +" }}} + +" Tabularize {{{ + " Leader Commands {{{ + nnoremap <localleader>t= :Tabularize /=<CR> + vmap <localleader>t= :Tabularize /=<CR> + + nnoremap <localleader>t> :Tabularize /=><CR> + vmap <localleader>t> :Tabularize /=><CR> + " }}} + + " => Aligning {{{ + function! s:rocketalign() + let l:p = '^.*=>\s.*$' + echo l:p + if exists(':Tabularize') && getline('.') =~# '^.*=' && + \ (getline(line('.')-1) =~# l:p || getline(line('.')+1) =~# l:p) + let column = strlen(substitute(getline('.')[0:col('.')],'[^=>]','','g')) + let position = strlen(matchstr(getline('.')[0:col('.')],'.*=>\s*\zs.*')) + Tabularize/=>/l1 + normal! $ + call search(repeat('[^=>]*=>',column).'\s\{-\}'.repeat('.',position),'ce',line('.')) + endif + endfunction + "inoremap <buffer> <space>=><space> =><Esc>:call <SID>rocketalign()<CR>a + " }}} + + " = Aligning {{{ + function! s:eqalign() + let l:p = '^.*=\s.*$' + if exists(':Tabularize') && getline('.') =~# '^.*=' && + \ (getline(line('.')-1) =~# l:p || getline(line('.')+1) =~# l:p) + let column = strlen(substitute(getline('.')[0:col('.')],'[^=]','','g')) + let position = strlen(matchstr(getline('.')[0:col('.')],'.*=\s*\zs.*')) + Tabularize/=/l1 + normal! $ + call search(repeat('[^=]*=',column).'\s\{-\}'.repeat('.',position),'ce',line('.')) + endif + endfunction + "inoremap <buffer><silent> <space>=<space> =<Esc>:call <SID>eqalign()<CR>a + " }}} + + " : Aligning {{{ + function! s:colonalign() + let l:p : '^.*:\s.*$' + if exists(':Tabularize') && getline('.') :~# '^.*:' && + \ (getline(line('.')-1) :~# l:p || getline(line('.')+1) :~# l:p) + let column : strlen(substitute(getline('.')[0:col('.')],'[^:]','','g')) + let position : strlen(matchstr(getline('.')[0:col('.')],'.*:\s*\zs.*')) + Tabularize/:/l1 + normal! $ + call search(repeat('[^:]*:',column).'\s\{-\}'.repeat('.',position),'ce',line('.')) + endif + endfunction + "inoremap <buffer><silent> <space>:<space> :<Esc>:call <SID>colonalign()<CR>a + " }}} +" }}} + +" }}} + +" Mappings {{{ +" 'delete current' +nnoremap dc 0d$ +nnoremap com :silent !tmux set status<CR> +nnoremap <F9> :Make<CR> +nnoremap g<CR> :Dispatch<CR> +nnoremap g\ :Start<CR> +inoremap <F9> <ESC>:Make<CR>i + +" Navigate buffers {{{ +nnoremap gb :bn<CR> +nnoremap gB :bp<CR> +" }}} + +" Window Navigation {{{ +nnoremap <space>w <C-w> +nnoremap <space>h <C-w>h +nnoremap <space>j <C-w>j +nnoremap <space>k <C-w>k +nnoremap <space>l <C-w>l +nnoremap <space>z <C-w>z +" }}} + + +" Sort with motion {{{ +if !exists("g:sort_motion_flags") + let g:sort_motion_flags = "" +endif +function! s:sort_motion(mode) abort + if a:mode == 'line' + execute "'[,']sort " . g:sort_motion_flags + elseif a:mode == 'char' + execute "normal! `[v`]y" + let sorted = join(sort(split(@@, ', ')), ', ') + execute "normal! v`]c" . sorted + elseif a:mode == 'V' || a:mode == '' + execute "'<,'>sort " . g:sort_motion_flags + endif +endfunction + +function! s:sort_lines() + let beginning = line('.') + let end = v:count + beginning - 1 + execute beginning . ',' . end . 'sort' +endfunction + +xnoremap <silent> <Plug>SortMotionVisual :<C-U>call <SID>sort_motion(visualmode())<CR> +nnoremap <silent> <Plug>SortMotion :<C-U>set opfunc=<SID>sort_motion<CR>g@ +nnoremap <silent> <Plug>SortLines :<C-U>call <SID>sort_lines()<CR> + +map go <Plug>SortMotion +vmap go <Plug>SortMotionVisual +map goo <Plug>SortLines +" }}} +" }}} + +let g:hare_executable = 'cabal exec -- ghc-hare' diff --git a/users/grfn/system/home/modules/zshrc b/users/grfn/system/home/modules/zshrc new file mode 100644 index 000000000000..a12173d6842d --- /dev/null +++ b/users/grfn/system/home/modules/zshrc @@ -0,0 +1,327 @@ +#!/usr/bin/zsh +# vim: set fdm=marker fmr={{{,}}}: + +stty -ixon + +# Compinstall {{{ +zstyle ':completion:*' completer _complete _ignored _correct _approximate +zstyle ':completion:*' matcher-list '' 'm:{[:lower:]}={[:upper:]} m:{[:lower:][:upper:]}={[:upper:][:lower:]} r:|[._- :]=** r:|=**' 'l:|=* r:|=*' +zstyle ':completion:*' max-errors 5 +zstyle ':completion:*' use-cache yes +zstyle ':completion::complete:grunt::options:' expire 1 +zstyle ':completion:*' prompt '%e errors' +zstyle :compinstall filename '~/.zshrc' +autoload -Uz compinit +compinit +# }}} + +# Zsh-newuser-install {{{ +HISTFILE=~/.histfile +HISTSIZE=1000 +SAVEHIST=1000 +setopt appendhistory autocd extendedglob notify autopushd +unsetopt beep nomatch +bindkey -v +# }}} + +# Basic options {{{ +set -o vi +umask 022 +export VIRTUAL_ENV_DISABLE_PROMPT=1 +# export PATH=~/.local/bin:~/.cabal/bin:$PATH:~/code/go/bin:~/bin:~/npm/bin:~/.gem/ruby/2.1.0/bin:~/.gem/ruby/2.0.0/bin:/home/smith/bin +# }}} + +# Zsh highlight highlighters {{{ +ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets pattern root) +# }}} + +# More basic options {{{ +setopt no_hist_verify +setopt histignorespace +# }}} + +# Utility Functions {{{ + +# Set the terminal's title bar. +function titlebar() { +echo -ne "\033]0;$*\007" +} + +function quiet() { +"$@" >/dev/null +} + +function quieter() { +"$@" >/dev/null 2>&1 +} + +# From http://stackoverflow.com/questions/370047/#370255 +function path_remove() { +IFS=: +# convert it to an array +t=($PATH) +unset IFS +# perform any array operations to remove elements from the array +t=(${t[@]%%$1}) +IFS=: +# output the new array +echo "${t[*]}" +} + +# }}} + +# Force screen to use zsh {{{ +# }}} + +# Environment {{{ +# }}} + +# Directory Stuff {{{ + +# Always use color output for `ls` + +# Directory listing + +# Easier navigation: .., ..., - + +# File size + +# Recursively delete `.DS_Store` files + +# Create a new directory and enter it +function md() { + mkdir -p "$@" && cd "$@" +} + +# }}} + +# MPD/MPC stuff {{{ +function mp() { +# Test if drive is already mounted +if ! lsblk | grep /media/external >/dev/null; then + if ! sudo mount /media/external; then + echo "External drive not plugged in, or could not mount" + return 1 + fi +fi +if (mpc >/dev/null 2>&1); then + ncmpcpp +else + mpd && + (pgrep mpdscribble || mpdscribble) && + ncmpcpp +fi +} + +# kill mp +function kmp() { +killall ncmpcpp +mpd --kill + +local files + +if (files=$(lsof 2>&1 | grep -v docker | grep external)); then + echo + echo "==> Still processes using external drive:" + echo + echo $files +else + sudo umount /media/external +fi +} + + +function mppal() { +mpc search album "$1" | mpc add && + mpc play; +} +# }}} + +# Git stuff {{{ +# function ga() { git add "${@:-.}"; } # Add all files by default +# Add non-whitespace changes +# function gc() { git checkout "${@:-master}"; } # Checkout master by default + +# open all changed files (that still actually exist) in the editor +function ged() { +local files=() +for f in $(git diff --name-only "$@"); do + [[ -e "$f" ]] && files=("${files[@]}" "$f") +done +local n=${#files[@]} +echo "Opening $n $([[ "$@" ]] || echo "modified ")file$([[ $n != 1 ]] && \ + echo s)${@:+ modified in }$@" +q "${files[@]}" +} + +# git find-replace +function gfr() { +if [[ "$#" == "0" ]]; then + echo 'Usage:' + echo ' gg_replace term replacement file_mask' + echo + echo 'Example:' + echo ' gg_replace cappuchino cappuccino *.html' + echo +else + find=$1; shift + replace=$1; shift + + ORIG_GLOBIGNORE=$GLOBIGNORE + GLOBIGNORE=*.* + if [[ "$#" = "0" ]]; then + set -- ' ' $@ + fi + + while [[ "$#" -gt "0" ]]; do + for file in `git grep -l $find -- $1`; do + sed -e "s/$find/$replace/g" -i'' $file + done + shift + done + + GLOBIGNORE=$ORIG_GLOBIGNORE +fi +} + +function vconflicts() { +$EDITOR $(git status --porcelain | awk '/^UU/ { print $2 }') +} +# }}} + +# fzf {{{ +v() { + local file + file=$(fzf-tmux --query="$1" --select-1 --exit-0) + [ -n "$file" ] && ${EDITOR:-vim} "$file" +} + +c() { + local dir + dir=$(find ${1:-*} -path '*/\.*' -prune -o -type d -print 2> /dev/null | fzf +m) && cd "$dir" +} + +co() { + local branch + branch=$(git branch -a | sed -s "s/\s*\**//g" | fzf --query="$1" --select-1 --exit-0) && git checkout "$branch" +} + + +# fh - repeat history +# h() { +# eval $(([ -n "$ZSH_NAME" ] && fc -l 1 || history) | fzf +s | sed 's/ *[0-9]* *//') +# } + +# fkill - kill process +fkill() { + ps -ef | sed 1d | fzf-tmux -m | awk '{print $2}' | xargs kill -${1:-9} +} +# }}} + +# Tmux utils {{{ +kill_detached() { + for sess in $(tmux ls | grep -v attached | sed -s "s/:.*$//"); do + tmux kill-session -t $sess; + done +} +# }}} + +# Docker {{{ + + +# dbp foo/bar . +function dbp () { + docker build -t $1 ${@:2} && docker push $1 +} + +# }}} + +# Twitter! {{{ + + +# favelast <username> +function favelast() { + t fave $(t tl -l $1 | head -n1 | first) +} + +function rtlast() { + t rt $(t tl -l $1 | head -n1 | first) +} + +function tthread() { + t reply $(t tl -l $TWITTER_WHOAMI | head -n1 | first) $@ +} +# }}} + +# Geeknote {{{ +gnc() { + gn create --title $1 --content '' && + gn find --count=1 "$1" + gn edit 1 +} +# }}} + +# Misc aliases {{{ + +function fw() { # fix white + local substitution + local substitution='s/\x1b\[90m/\x1b[92m/g' + $@ > >(perl -pe "$substitution") 2> >(perl -pe "$substitution" 1>&2) +} +# }}} + +# Grep options {{{ +unset GREP_OPTIONS +export GREP_OPTIONS= +# }}} + + +# Run docker containers {{{ + # -d \ + # -v $HOME/.pentadactyl:/home/firefox/.pentadactyl:rw \ + # -v $HOME/.pentadactylrc:/home/firefox/.pentadactylrc:rw \ + # -v $HOME/.mozilla:/home/firefox/.mozilla:rw \ + # -v $HOME/.config:/home/firefox/.config \ + # -v $HOME/Downloads:/home/firefox/Downloads:rw \ + # -v /etc/fonts:/etc/fonts \ + # -v /tmp/.X11-unix:/tmp/.X11-unix \ + # -v /dev/snd:/dev/snd \ + # --net=host \ + # -v $XDG_RUNTIME_DIR:$XDG_RUNTIME_DIR \ + # -e uid=$(id -u) \ + # -e gid=$(id -g) \ + # -e DISPLAY=$DISPLAY \ + # -e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \ + # --name firefox \ + # --rm -it \ + # glittershark/firefox +# }}} + +# Change cursor shape on insert/normal mode {{{ +# (https://unix.stackexchange.com/q/433273/64261) + +KEYTIMEOUT=5 + +_fix_cursor() { + echo -ne '\e[5 q' +} + +precmd_functions+=(_fix_cursor) + +function zle-keymap-select { + if [[ ${KEYMAP} == vicmd ]] || + [[ $1 = 'block' ]]; then + echo -ne '\e[1 q' + + elif [[ ${KEYMAP} == main ]] || + [[ ${KEYMAP} == viins ]] || + [[ ${KEYMAP} = '' ]] || + [[ $1 = 'beam' ]]; then + echo -ne '\e[5 q' + fi +} +zle -N zle-keymap-select + +# }}} + +[ -f ./.localrc ] && source ./.localrc diff --git a/users/grfn/system/home/platforms/darwin.nix b/users/grfn/system/home/platforms/darwin.nix new file mode 100644 index 000000000000..f98b80f26915 --- /dev/null +++ b/users/grfn/system/home/platforms/darwin.nix @@ -0,0 +1,26 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + home.packages = with pkgs; [ + coreutils + gnupg + pinentry_mac + ]; + + home.activation.linkApplications = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + $DRY_RUN_CMD ln -sf $VERBOSE_ARG \ + ~/.nix-profile/Applications/* ~/Applications/ + ''; + + programs.zsh.initExtra = '' + export NIX_PATH=$HOME/.nix-defexpr/channels:$NIX_PATH + + if [[ "$TERM" == "alacritty" ]]; then + export TERM="xterm-256color" + fi + ''; + }; +} diff --git a/users/grfn/system/home/platforms/linux.nix b/users/grfn/system/home/platforms/linux.nix new file mode 100644 index 000000000000..decc8b8c2e9d --- /dev/null +++ b/users/grfn/system/home/platforms/linux.nix @@ -0,0 +1,92 @@ +{ config, pkgs, ... }: + +let + + depot = config.lib.depot; + +in + +{ + imports = [ + ../modules/alacritty.nix + ../modules/alsi.nix + ../modules/development.nix + ../modules/emacs.nix + ../modules/email.nix + ../modules/firefox.nix + ../modules/games.nix + ../modules/obs.nix + ../modules/i3.nix + ../modules/shell.nix + ../modules/tarsnap.nix + ../modules/vim.nix + ]; + + xsession.enable = true; + + home.packages = with pkgs; [ + # Desktop stuff + arandr + firefox + feh + chromium + xclip + xorg.xev + picom + peek + signal-desktop + apvlv # pdf viewer + vlc + irssi + gnutls + pandoc + barrier + depot.tools.nsfv-setup + glimpse # fork of gimp + + # System utilities + powertop + usbutils + pciutils + gdmap + lsof + tree + nmap + iftop + + # Security + gnupg + keybase + openssl + yubikey-manager + yubikey-manager-qt + + # Spotify...etc + spotify + playerctl + ]; + + services.redshift = { + enable = true; + provider = "geoclue2"; + }; + + services.pasystray.enable = true; + + services.gpg-agent = { + enable = true; + }; + + gtk = { + enable = true; + gtk3.bookmarks = [ + "file:///home/grfn/code" + ]; + }; + + programs.zsh.initExtra = '' + [[ ! $IN_NIX_SHELL ]] && alsi -l + ''; + + services.lorri.enable = true; +} diff --git a/users/grfn/system/install b/users/grfn/system/install new file mode 100755 index 000000000000..a9a45953da07 --- /dev/null +++ b/users/grfn/system/install @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +set -eo pipefail + +if [[ -f /etc/nixos/.system-installed ]]; then + echo "=== System config already installed, skipping" +else + echo "==> Installing system config" + + [[ -d /etc/nixos ]] && sudo mv /etc/nixos{,.bak} + sudo mkdir -p /etc/nixos + sudo cp /etc/nixos.bak/hardware-configuration.nix /etc/nixos + + sudo cp ./system/configuration.nix /etc/nixos/ + sudo ln -s $(pwd)/system/{machines,modules,pkgs} /etc/nixos + sudo touch /etc/nixos/.system-installed + + echo "==> System config installed, your old configuration is at /etc/nixos.bak" +fi +echo + +if [[ -f ~/.config/nixpkgs/system-installed ]]; then + echo "=== home-manager config already installed, skipping" +else + echo "==> Installing home-manager config" + nix-channel --add https://github.com/rycee/home-manager/archive/master.tar.gz home-manager + nix-channel --update + # nix-shell '<home-manager>' -A install + + [[ -d ~/.config/nixpkgs ]] && mv ~/.config/{nixpkgs,nixpkgs.bak} + mkdir -p ~/.config/nixpkgs + ln -s $(pwd)/home/* ~/.config/nixpkgs + + echo "==> home-manager config installed" +fi diff --git a/users/grfn/system/system/.skip-subtree b/users/grfn/system/system/.skip-subtree new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/users/grfn/system/system/.skip-subtree diff --git a/users/grfn/system/system/configuration.nix b/users/grfn/system/system/configuration.nix new file mode 100644 index 000000000000..eae567015b73 --- /dev/null +++ b/users/grfn/system/system/configuration.nix @@ -0,0 +1,11 @@ +{ config, pkgs, ... }: + +let machine = throw "Pick a machine from ./machines"; in +{ + imports = + [ + /etc/nixos/hardware-configuration.nix + ./modules/common.nix + machine + ]; +} diff --git a/users/grfn/system/system/default.nix b/users/grfn/system/system/default.nix new file mode 100644 index 000000000000..9196758e64db --- /dev/null +++ b/users/grfn/system/system/default.nix @@ -0,0 +1,38 @@ +args @ { depot, pkgs, ... }: + +rec { + mugwump = import ./machines/mugwump.nix; + + mugwumpSystem = (depot.ops.nixos.nixosFor mugwump).system; + + roswell = import ./machines/roswell.nix; + + roswellSystem = (depot.ops.nixos.nixosFor ({ ... }: { + imports = [ + ./machines/roswell.nix + "${pkgs.home-manager.src}/nixos" + ]; + + # Use the same nixpkgs as everything else + home-manager.useGlobalPkgs = true; + + home-manager.users.grfn = { config, lib, ... }: { + imports = [ ../home/machines/roswell.nix ]; + lib.depot = depot; + }; + })).system; + + yeren = import ./machines/yeren.nix; + + yerenSystem = (depot.ops.nixos.nixosFor yeren).system; + + iso = import ./iso.nix args; + + meta.ci.targets = [ + "mugwumpSystem" + "roswellSystem" + "yerenSystem" + + "iso" + ]; +} diff --git a/users/grfn/system/system/iso.nix b/users/grfn/system/system/iso.nix new file mode 100644 index 000000000000..9fa8e7ec7e3b --- /dev/null +++ b/users/grfn/system/system/iso.nix @@ -0,0 +1,18 @@ +{ depot, lib, pkgs, ... }: + +let + configuration = { ... }: { + imports = [ + (pkgs.path + "/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix") + (pkgs.path + "/nixos/modules/installer/cd-dvd/channel.nix") + ]; + + networking.networkmanager.enable = true; + networking.useDHCP = false; + networking.firewall.enable = false; + networking.wireless.enable = lib.mkForce false; + }; +in +(depot.third_party.nixos { + inherit configuration; +}).config.system.build.isoImage diff --git a/users/grfn/system/system/machines/bumblebee.nix b/users/grfn/system/system/machines/bumblebee.nix new file mode 100644 index 000000000000..0fec21409255 --- /dev/null +++ b/users/grfn/system/system/machines/bumblebee.nix @@ -0,0 +1,23 @@ +{ config, lib, pkgs, ... }: +{ + imports = [ + ../modules/reusable/battery.nix + ]; + + networking.hostName = "bumblebee"; + + powerManagement = { + enable = true; + cpuFreqGovernor = "powersave"; + powertop.enable = true; + }; + + # Hibernate on low battery + laptop.onLowBattery = { + enable = true; + action = "hibernate"; + thresholdPercentage = 5; + }; + + services.xserver.xkbOptions = "caps:swapescape"; +} diff --git a/users/grfn/system/system/machines/mugwump.nix b/users/grfn/system/system/machines/mugwump.nix new file mode 100644 index 000000000000..0774e0611957 --- /dev/null +++ b/users/grfn/system/system/machines/mugwump.nix @@ -0,0 +1,291 @@ +{ config, lib, pkgs, modulesPath, depot, ... }: + +with lib; + +{ + imports = [ + ../modules/common.nix + (modulesPath + "/installer/scan/not-detected.nix") + (depot.path.origSrc + "/ops/modules/prometheus-fail2ban-exporter.nix") + (depot.path.origSrc + "/users/grfn/xanthous/server/module.nix") + (depot.third_party.agenix.src + "/modules/age.nix") + (depot.path.origSrc + "/users/grfn/bbbg/module.nix") + ]; + + networking.hostName = "mugwump"; + + boot = { + loader.systemd-boot.enable = true; + + kernelModules = [ "kvm-intel" ]; + extraModulePackages = [ ]; + + initrd = { + availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ]; + kernelModules = [ + "uas" + "usbcore" + "usb_storage" + "vfat" + "nls_cp437" + "nls_iso8859_1" + ]; + + postDeviceCommands = pkgs.lib.mkBefore '' + mkdir -m 0755 -p /key + sleep 2 + mount -n -t vfat -o ro `findfs UUID=9048-A9D5` /key + ''; + + luks.devices."cryptroot" = { + device = "/dev/disk/by-uuid/803a9028-339c-4617-a213-4fe138161f6d"; + keyFile = "/key/keyfile"; + preLVM = false; + }; + }; + }; + + fileSystems = { + "/" = { + device = "/dev/mapper/cryptroot"; + fsType = "btrfs"; + }; + "/boot" = { + device = "/dev/disk/by-uuid/7D74-0E4B"; + fsType = "vfat"; + }; + }; + + networking.interfaces = { + enp0s25.useDHCP = false; + wlp2s0.useDHCP = false; + }; + + networking.firewall.enable = true; + networking.firewall.allowedTCPPorts = [ 22 80 443 ]; + + security.sudo.extraRules = [{ + groups = [ "wheel" ]; + commands = [{ command = "ALL"; options = [ "NOPASSWD" ]; }]; + }]; + + nix.gc.dates = "monthly"; + + age.secrets = + let + secret = name: depot.users.grfn.secrets."${name}.age"; + in + { + bbbg.file = secret "bbbg"; + cloudflare.file = secret "cloudflare"; + ddclient-password.file = secret "ddclient-password"; + + buildkite-ssh-key = { + file = secret "buildkite-ssh-key"; + group = "keys"; + mode = "0440"; + }; + + buildkite-token = { + file = secret "buildkite-token"; + group = "keys"; + mode = "0440"; + }; + }; + + services.fail2ban = { + enable = true; + ignoreIP = [ + "172.16.0.0/16" + ]; + }; + + services.openssh = { + allowSFTP = false; + passwordAuthentication = false; + permitRootLogin = "no"; + }; + + services.grafana = { + enable = true; + port = 3000; + domain = "metrics.gws.fyi"; + rootUrl = "https://metrics.gws.fyi"; + dataDir = "/var/lib/grafana"; + analytics.reporting.enable = false; + + provision = { + enable = true; + datasources = [{ + name = "Prometheus"; + type = "prometheus"; + url = "http://localhost:9090"; + }]; + }; + }; + + security.acme.defaults.email = "root@gws.fyi"; + security.acme.acceptTerms = true; + + services.nginx = { + enable = true; + statusPage = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedTlsSettings = true; + recommendedProxySettings = true; + + virtualHosts = { + "metrics.gws.fyi" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://localhost:${toString config.services.grafana.port}"; + }; + }; + }; + }; + + services.ddclient = { + enable = true; + domains = [ "home.gws.fyi" ]; + interval = "1d"; + zone = "gws.fyi"; + protocol = "cloudflare"; + username = "root@gws.fyi"; + passwordFile = config.age.secretsDir + "/ddclient-password"; + quiet = true; + }; + + systemd.services.ddclient.serviceConfig.DynamicUser = lib.mkForce false; + + security.acme.certs."metrics.gws.fyi" = { + dnsProvider = "cloudflare"; + credentialsFile = config.age.secretsDir + "/cloudflare"; + webroot = mkForce null; + }; + + services.prometheus = { + enable = true; + exporters = { + node = { + enable = true; + openFirewall = false; + + enabledCollectors = [ + "processes" + "systemd" + "tcpstat" + "wifi" + ]; + }; + + nginx = { + enable = true; + openFirewall = true; + sslVerify = false; + constLabels = [ "host=mugwump" ]; + }; + + blackbox = { + enable = true; + openFirewall = true; + configFile = pkgs.writeText "blackbox-exporter.yaml" (builtins.toJSON { + modules = { + https_2xx = { + prober = "http"; + http = { + method = "GET"; + fail_if_ssl = false; + fail_if_not_ssl = true; + preferred_ip_protocol = "ip4"; + }; + }; + }; + }); + }; + }; + + scrapeConfigs = [ + { + job_name = "node"; + scrape_interval = "5s"; + static_configs = [{ + targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ]; + }]; + } + { + job_name = "nginx"; + scrape_interval = "5s"; + static_configs = [{ + targets = [ "localhost:${toString config.services.prometheus.exporters.nginx.port}" ]; + }]; + } + { + job_name = "xanthous_server"; + scrape_interval = "1s"; + static_configs = [{ + targets = [ "localhost:${toString config.services.xanthous-server.metricsPort}" ]; + }]; + } + { + job_name = "blackbox"; + metrics_path = "/probe"; + params.module = [ "https_2xx" ]; + scrape_interval = "5s"; + static_configs = [{ + targets = [ + "https://gws.fyi" + "https://windtunnel.ci" + "https://app.windtunnel.ci" + "https://metrics.gws.fyi" + ]; + }]; + relabel_configs = [{ + source_labels = [ "__address__" ]; + target_label = "__param_target"; + } + { + source_labels = [ "__param_target" ]; + target_label = "instance"; + } + { + target_label = "__address__"; + replacement = "localhost:${toString config.services.prometheus.exporters.blackbox.port}"; + }]; + } + ]; + }; + + services.xanthous-server.enable = true; + + services.bbbg.enable = true; + services.bbbg.domain = "staging.bbbg.gws.fyi"; + services.bbbg.database.enable = true; + services.bbbg.proxy.enable = true; + + virtualisation.docker.enable = true; + + services.buildkite-agents = listToAttrs (map + (n: rec { + name = "mugwump-${toString n}"; + value = { + inherit name; + enable = true; + tokenPath = config.age.secretsDir + "/buildkite-token"; + privateSshKeyPath = config.age.secretsDir + "/buildkite-ssh-key"; + runtimePackages = with pkgs; [ + docker + nix + gnutar + gzip + ]; + }; + }) + (range 1 1)); + + users.users."buildkite-agent-mugwump-1" = { + isSystemUser = true; + extraGroups = [ "docker" ]; + }; +} diff --git a/users/grfn/system/system/machines/roswell.nix b/users/grfn/system/system/machines/roswell.nix new file mode 100644 index 000000000000..6eb4a510b8cd --- /dev/null +++ b/users/grfn/system/system/machines/roswell.nix @@ -0,0 +1,17 @@ +{ depot, config, lib, pkgs, modulesPath, ... }: + +{ + imports = [ + ../modules/common.nix + "${modulesPath}/installer/scan/not-detected.nix" + "${modulesPath}/virtualisation/amazon-image.nix" + ]; + + ec2.hvm = true; + + networking.hostName = "roswell"; + + users.users.grfn.openssh.authorizedKeys.keys = [ + depot.users.grfn.keys.main + ]; +} diff --git a/users/grfn/system/system/machines/yeren.nix b/users/grfn/system/system/machines/yeren.nix new file mode 100644 index 000000000000..228631c8cc6f --- /dev/null +++ b/users/grfn/system/system/machines/yeren.nix @@ -0,0 +1,137 @@ +{ depot, modulesPath, config, lib, pkgs, ... }: + +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ../modules/common.nix + ../modules/laptop.nix + ../modules/xserver.nix + ../modules/fonts.nix + ../modules/sound.nix + ../modules/tvl.nix + ../modules/development.nix + ../modules/work/kolide.nix + ]; + + networking.hostName = "yeren"; + + system.stateVersion = "21.03"; + + boot = { + initrd = { + availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ]; + kernelModules = [ ]; + + luks.devices = { + "cryptroot".device = "/dev/disk/by-uuid/dcfbc22d-e0d2-411b-8dd3-96704d3aae2e"; + }; + }; + + kernelPackages = pkgs.linuxPackages_5_15; + + kernelModules = [ "kvm-intel" ]; + blacklistedKernelModules = [ "psmouse" ]; + extraModulePackages = [ + config.boot.kernelPackages.digimend + ]; + kernelParams = [ + "i915.preliminary_hw_support=1" + "pcie_aspm=force" + ]; + + # https://bbs.archlinux.org/viewtopic.php?pid=1933643#p1933643 + extraModprobeConfig = '' + options snd-intel-dspcfg dsp_driver=1 + ''; + + kernel.sysctl = { + "kernel.perf_event_paranoid" = -1; + }; + }; + + fileSystems = { + "/" = { + device = "/dev/mapper/cryptroot"; + fsType = "btrfs"; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/53A9-248B"; + fsType = "vfat"; + }; + }; + + swapDevices = [{ + device = "/dev/disk/by-uuid/b627cb0e-0451-4f25-94d0-6497e01f0da4"; + }]; + + services.earlyoom = { + enable = true; + freeMemThreshold = 5; + }; + + services.xserver = { + exportConfiguration = true; + extraConfig = '' + Section "Device" + Identifier "Intel Graphics" + Driver "intel" + Option "TripleBuffer" "true" + Option "TearFree" "true" + Option "DRI" "true" + Option "AccelMethod" "sna" + EndSection + ''; + }; + + hardware.firmware = with pkgs; [ + alsa-firmware + sof-firmware + ]; + + hardware.opengl.extraPackages = with pkgs; [ + vaapiIntel + vaapiVdpau + libvdpau-va-gl + intel-media-driver + ]; + + # Disabled for now until libfprint-tod can get a version bump + # services.fprintd = { + # enable = true; + # package = pkgs.fprintd-tod; + # }; + + systemd.services.fprintd.environment.FP_TOD_DRIVERS_DIR = + "${pkgs.libfprint-2-tod1-goodix}/usr/lib/libfprint-2/tod-1"; + + security.pam.loginLimits = [ + { + domain = "grfn"; + type = "soft"; + item = "nofile"; + value = "65535"; + } + ]; + + security.pam.services = { + login.fprintAuth = true; + sudo.fprintAuth = true; + i3lock.fprintAuth = false; + i3lock-color.fprintAuth = false; + lightdm.fprintAuth = true; + lightdm-greeter.fprintAuth = true; + }; + + hardware.opengl.driSupport32Bit = true; + + hardware.pulseaudio.extraConfig = '' + load-module module-remap-source source_name=KompleteAudio6_1 source_properties=device.description=KompleteAudio6Input1 master=alsa_input.usb-Native_Instruments_Komplete_Audio_6_458E0FFD-00.multichannel-input remix=no channels=1 master_channel_map=front-left channel_map=mono + load-module module-remap-source source_name=KompleteAudio6_2 source_properties=device.description=KompleteAudio6Input2 master=alsa_input.usb-Native_Instruments_Komplete_Audio_6_458E0FFD-00.multichannel-input remix=no channels=1 master_channel_map=front-right channel_map=mono + load-module module-remap-sink sink_name=KompleteAudio6_12 sink_properties=device.description=KompleteAudio6_12 remix=no master=alsa_output.usb-Native_Instruments_Komplete_Audio_6_458E0FFD-00.analog-surround-21 channels=2 master_channel_map=front-left,front-right channel_map=front-left,front-right + ''; + + services.fwupd.enable = true; + + services.tailscale.enable = true; +} diff --git a/users/grfn/system/system/modules/common.nix b/users/grfn/system/system/modules/common.nix new file mode 100644 index 000000000000..a7d5a62e686c --- /dev/null +++ b/users/grfn/system/system/modules/common.nix @@ -0,0 +1,87 @@ +{ config, lib, pkgs, ... }: + +let + + depot = import ../../../../.. { }; + +in + +with lib; + +{ + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.useDHCP = false; + networking.networkmanager.enable = true; + + i18n = { + defaultLocale = "en_US.UTF-8"; + }; + + time.timeZone = lib.mkDefault "America/New_York"; + + environment.systemPackages = with pkgs; [ + wget + vim + zsh + git + w3m + libnotify + file + lm_sensors + dnsutils + htop + man-pages + man-pages-posix + ]; + + documentation.dev.enable = true; + documentation.man.generateCaches = true; + + services.openssh.enable = true; + + programs.ssh.startAgent = true; + + networking.firewall.enable = mkDefault false; + + users.mutableUsers = true; + programs.zsh.enable = true; + environment.pathsToLink = [ "/share/zsh" ]; + users.users.grfn = { + isNormalUser = true; + initialPassword = "password"; + extraGroups = [ + "wheel" + "networkmanager" + "audio" + "docker" + ]; + shell = pkgs.zsh; + }; + + nix = { + settings.trusted-users = [ "grfn" ]; + distributedBuilds = true; + + gc = { + automatic = true; + dates = mkDefault "weekly"; + options = "--delete-older-than 30d"; + }; + }; + + services.udev.packages = with pkgs; [ + yubikey-personalization + ]; + + services.pcscd.enable = true; + + services.udev.extraRules = '' + # UDEV rules for Teensy USB devices + ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1" + ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1" + SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666" + KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666" + ''; +} diff --git a/users/grfn/system/system/modules/desktop.nix b/users/grfn/system/system/modules/desktop.nix new file mode 100644 index 000000000000..3adbd9d9b07f --- /dev/null +++ b/users/grfn/system/system/modules/desktop.nix @@ -0,0 +1,19 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./xserver.nix + ./fonts.nix + ./sound.nix + ./kernel.nix + ]; + + programs.nm-applet.enable = true; + + users.users.grfn.extraGroups = [ + "audio" + "video" + ]; + + services.geoclue2.enable = true; +} diff --git a/users/grfn/system/system/modules/development.nix b/users/grfn/system/system/modules/development.nix new file mode 100644 index 000000000000..bfa0e22cff0a --- /dev/null +++ b/users/grfn/system/system/modules/development.nix @@ -0,0 +1,6 @@ +{ config, lib, pkgs, ... }: + +{ + virtualisation.docker.enable = true; + users.users.grfn.extraGroups = [ "docker" ]; +} diff --git a/users/grfn/system/system/modules/fcitx.nix b/users/grfn/system/system/modules/fcitx.nix new file mode 100644 index 000000000000..812f598f9f47 --- /dev/null +++ b/users/grfn/system/system/modules/fcitx.nix @@ -0,0 +1,10 @@ +{ config, lib, pkgs, ... }: + +{ + i18n.inputMethod = { + enabled = "fcitx"; + fcitx.engines = with pkgs.fcitx-engines; [ + cloudpinyin + ]; + }; +} diff --git a/users/grfn/system/system/modules/fonts.nix b/users/grfn/system/system/modules/fonts.nix new file mode 100644 index 000000000000..f30600b28b39 --- /dev/null +++ b/users/grfn/system/system/modules/fonts.nix @@ -0,0 +1,12 @@ +{ config, lib, pkgs, ... }: +{ + fonts = { + fonts = with pkgs; [ + nerdfonts + noto-fonts-emoji + twitter-color-emoji + ]; + + fontconfig.defaultFonts.emoji = [ "Twitter Color Emoji" ]; + }; +} diff --git a/users/grfn/system/system/modules/laptop.nix b/users/grfn/system/system/modules/laptop.nix new file mode 100644 index 000000000000..05c5333e513f --- /dev/null +++ b/users/grfn/system/system/modules/laptop.nix @@ -0,0 +1,15 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./reusable/battery.nix + ]; + + laptop.onLowBattery.enable = true; + + services.logind.extraConfig = '' + HandlePowerKey=hibernate + ''; + + services.tlp.enable = true; +} diff --git a/users/grfn/system/system/modules/reusable/README.org b/users/grfn/system/system/modules/reusable/README.org new file mode 100644 index 000000000000..34d9bfdcb729 --- /dev/null +++ b/users/grfn/system/system/modules/reusable/README.org @@ -0,0 +1,2 @@ +This directory contains things I'm eventually planning on contributing upstream +to nixpkgs diff --git a/users/grfn/system/system/modules/reusable/battery.nix b/users/grfn/system/system/modules/reusable/battery.nix new file mode 100644 index 000000000000..151c2a246f32 --- /dev/null +++ b/users/grfn/system/system/modules/reusable/battery.nix @@ -0,0 +1,32 @@ +{ config, lib, pkgs, ... }: +with lib; +{ + options = { + laptop.onLowBattery = { + enable = mkEnableOption "Perform action on low battery"; + + thresholdPercentage = mkOption { + description = "Threshold battery percentage on which to perform the action"; + default = 8; + type = types.int; + }; + + action = mkOption { + description = "Action to perform on low battery"; + default = "hibernate"; + type = types.enum [ "hibernate" "suspend" "suspend-then-hibernate" ]; + }; + }; + }; + + config = + let cfg = config.laptop.onLowBattery; + in mkIf cfg.enable { + services.udev.extraRules = concatStrings [ + ''SUBSYSTEM=="power_supply", '' + ''ATTR{status}=="Discharging", '' + ''ATTR{capacity}=="[0-${toString cfg.thresholdPercentage}]", '' + ''RUN+="${pkgs.systemd}/bin/systemctl ${cfg.action}"'' + ]; + }; +} diff --git a/users/grfn/system/system/modules/rtlsdr.nix b/users/grfn/system/system/modules/rtlsdr.nix new file mode 100644 index 000000000000..ce58ebb0dcda --- /dev/null +++ b/users/grfn/system/system/modules/rtlsdr.nix @@ -0,0 +1,17 @@ +{ config, lib, pkgs, ... }: + +{ + + environment.systemPackages = with pkgs; [ + rtl-sdr + ]; + + services.udev.packages = with pkgs; [ + rtl-sdr + ]; + + # blacklist for rtl-sdr + boot.blacklistedKernelModules = [ + "dvb_usb_rtl28xxu" + ]; +} diff --git a/users/grfn/system/system/modules/sound.nix b/users/grfn/system/system/modules/sound.nix new file mode 100644 index 000000000000..07a67a1ec43b --- /dev/null +++ b/users/grfn/system/system/modules/sound.nix @@ -0,0 +1,16 @@ +{ config, lib, pkgs, ... }: + +{ + # Enable sound. + sound.enable = true; + hardware.pulseaudio.enable = true; + + environment.systemPackages = with pkgs; [ + pulseaudio-ctl + paprefs + pasystray + pavucontrol + ]; + + hardware.pulseaudio.package = pkgs.pulseaudioFull; +} diff --git a/users/grfn/system/system/modules/tvl.nix b/users/grfn/system/system/modules/tvl.nix new file mode 100644 index 000000000000..3c0326c66412 --- /dev/null +++ b/users/grfn/system/system/modules/tvl.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: + +{ + nix = { + buildMachines = [{ + hostName = "whitby.tvl.fyi"; + sshUser = "grfn"; + sshKey = "/root/.ssh/id_rsa"; + system = "x86_64-linux"; + maxJobs = 64; + supportedFeatures = [ "big-parallel" "kvm" "nixos-test" "benchmark" ]; + }]; + + extraOptions = '' + builders-use-substitutes = true + ''; + + settings = { + substituters = [ + "https://cache.nixos.org" + "ssh://nix-ssh@whitby.tvl.fyi" + ]; + trusted-substituters = [ + "https://cache.nixos.org" + "ssh://nix-ssh@whitby.tvl.fyi" + ]; + trusted-public-keys = [ + "cache.tvl.fyi:fd+9d1ceCPvDX/xVhcfv8nAa6njEhAGAEe+oGJDEeoc=" + ]; + }; + }; + + programs.ssh.knownHosts.whitby = { + extraHostNames = [ "whitby" "whitby.tvl.fyi" "49.12.129.211" ]; + publicKeyFile = pkgs.writeText "whitby.pub" '' + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILNh/w4BSKov0jdz3gKBc98tpoLta5bb87fQXWBhAl2I + ''; + }; +} diff --git a/users/grfn/system/system/modules/work/kolide.deb b/users/grfn/system/system/modules/work/kolide.deb new file mode 100644 index 000000000000..a319a5806fca --- /dev/null +++ b/users/grfn/system/system/modules/work/kolide.deb Binary files differdiff --git a/users/grfn/system/system/modules/work/kolide.nix b/users/grfn/system/system/modules/work/kolide.nix new file mode 100644 index 000000000000..e4ee786f0cbe --- /dev/null +++ b/users/grfn/system/system/modules/work/kolide.nix @@ -0,0 +1,51 @@ +{ config, lib, pkgs, ... }: + +let + deb = ./kolide.deb; + + kolide = pkgs.runCommand "kolide-data" + { + buildInputs = [ pkgs.binutils-unwrapped ]; + } '' + cp ${deb} ./kolide.deb + ar x kolide.deb + mkdir result + tar xzf data.tar.gz -C result + patchelf \ + --set-interpreter ${pkgs.glibc}/lib/ld-linux-x86-64.so.2 \ + --set-rpath "${lib.makeLibraryPath (with pkgs; [ + zlib + ])}" \ + result/usr/local/kolide-k2/bin/osqueryd + mv result $out + ''; + +in +{ + systemd.services."launcher.kolide-k2" = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "syslog.service" ]; + description = "The Kolide Launcher"; + serviceConfig = { + ExecStart = '' + ${kolide}/usr/local/kolide-k2/bin/launcher \ + -config \ + ${pkgs.writeText "launcher.flags" '' + with_initial_runner + control + autoupdate + root_directory /var/lib/kolide + osqueryd_path ${kolide}/usr/local/kolide-k2/bin/osqueryd + enroll_secret_path ${kolide}/etc/kolide-k2/secret + control_hostname k2control.kolide.com + update_channel stable + transport jsonrpc + hostname k2device.kolide.com + ''} + ''; + StateDirectory = "kolide"; + Restart = "on-failure"; + RestartSec = 3; + }; + }; +} diff --git a/users/grfn/system/system/modules/xserver.nix b/users/grfn/system/system/modules/xserver.nix new file mode 100644 index 000000000000..35ee44112ea1 --- /dev/null +++ b/users/grfn/system/system/modules/xserver.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: +{ + # Enable the X11 windowing system. + services.xserver = { + enable = true; + layout = "us"; + + libinput.enable = true; + + displayManager = { + defaultSession = "none+i3"; + }; + + windowManager.i3.enable = true; + }; +} |