diff options
Diffstat (limited to 'home/profiles')
-rw-r--r-- | home/profiles/alacritty.nix | 51 | ||||
-rw-r--r-- | home/profiles/dev.nix | 49 | ||||
-rw-r--r-- | home/profiles/emacs.nix | 13 | ||||
-rw-r--r-- | home/profiles/firefox.nix | 59 | ||||
-rw-r--r-- | home/profiles/git.nix | 73 | ||||
-rw-r--r-- | home/profiles/gtk.nix | 35 | ||||
-rw-r--r-- | home/profiles/home.nix | 69 | ||||
-rw-r--r-- | home/profiles/mako.nix | 25 | ||||
-rw-r--r-- | home/profiles/nas.nix | 67 | ||||
-rw-r--r-- | home/profiles/ssh.nix | 18 | ||||
-rw-r--r-- | home/profiles/sway.nix | 172 | ||||
-rw-r--r-- | home/profiles/tmux.nix | 20 | ||||
-rw-r--r-- | home/profiles/waybar.nix | 155 | ||||
-rw-r--r-- | home/profiles/wofi.nix | 13 | ||||
-rw-r--r-- | home/profiles/workstation.nix | 113 | ||||
-rw-r--r-- | home/profiles/ytdlp.nix | 37 | ||||
-rw-r--r-- | home/profiles/yubikey.nix | 28 | ||||
-rw-r--r-- | home/profiles/zsh/completion-style.zsh | 42 | ||||
-rw-r--r-- | home/profiles/zsh/default.nix | 51 | ||||
-rw-r--r-- | home/profiles/zsh/new-go-project.zsh | 19 | ||||
-rw-r--r-- | home/profiles/zsh/options.zsh | 27 | ||||
-rw-r--r-- | home/profiles/zsh/prompt.zsh | 17 | ||||
-rw-r--r-- | home/profiles/zsh/tmux.zsh | 9 |
23 files changed, 1162 insertions, 0 deletions
diff --git a/home/profiles/alacritty.nix b/home/profiles/alacritty.nix new file mode 100644 index 0000000..2789f12 --- /dev/null +++ b/home/profiles/alacritty.nix @@ -0,0 +1,51 @@ +{ + programs.alacritty = { + enable = true; + settings = { + env = { + TERM = "xterm-256color"; + }; + + live_config_reload = true; + draw_bold_text_with_bright_colors = true; + selection = { save_to_clipboard = true; }; + + colors = { + primary = { + background = "#000000"; + foreground = "#D3D7CF"; + }; + + normal = { + black = "#2E3436"; + red = "#CC0000"; + green = "#4E9A06"; + yellow = "#C4A000"; + blue = "#3465A4"; + magenta = "#EF33C0"; + cyan = "#04B5B8"; + white = "#D3D7CF"; + }; + + bright = { + black = "#555753"; + red = "#EF2929"; + green = "#8AE234"; + yellow = "#FCE94F"; + blue = "#729FCF"; + magenta = "#EE38DA"; + cyan = "#34E2E2"; + white = "#EEEEEC"; + }; + }; + font = { + size = 13; + normal.family = "Source Code Pro"; + }; + cursor = { + style.blinking = "Never"; + unfocused_hollow = true; + }; + }; + }; +} diff --git a/home/profiles/dev.nix b/home/profiles/dev.nix new file mode 100644 index 0000000..c1323d6 --- /dev/null +++ b/home/profiles/dev.nix @@ -0,0 +1,49 @@ +{ pkgs, config, ... }: +let + ruststable = (pkgs.rust-bin.stable.latest.default.override { + extensions = [ + "rust-src" + "rust-analyzer-preview" + "rust-analysis" + "rustfmt-preview" + ]; + }); + pythonEnv = pkgs.python3.withPackages (p: with p; [ + black + isort + pylsp-mypy + requests + types-requests + pip + ipython + ]); +in +{ + programs.go = { + enable = true; + goPath = ".local/share/pkg.go"; + goBin = ".local/bin.go"; + goPrivate = [ "git.fcuny.net" "golang.fcuny.net" ]; + package = pkgs.go_1_18; + }; + + home.packages = with pkgs; [ + go-tools + pythonEnv + google-cloud-sdk + ruststable + ]; + + home.sessionPath = [ + config.home.sessionVariables.GOBIN + "$CARGO_HOME/bin" + ]; + + home.sessionVariables = with config.xdg; { + IPYTHONDIR = "${cacheHome}/ipython"; + PIP_LOG = "${cacheHome}/pip/pip.log"; + PYLINTHOME = "${cacheHome}/pylint"; + PYTHON_EGG_CACHE = "${cacheHome}/python-eggs"; + CARGO_HOME = "${dataHome}/cargo"; + }; +} diff --git a/home/profiles/emacs.nix b/home/profiles/emacs.nix new file mode 100644 index 0000000..17c751d --- /dev/null +++ b/home/profiles/emacs.nix @@ -0,0 +1,13 @@ +{ lib, config, pkgs, ... }: +{ + home.packages = with pkgs; [ + emacsPgtk + # see https://github.com/hlissner/doom-emacs/issues/4138 + (aspellWithDicts (dicts: with dicts; [ en en-computers en-science ])) + ]; + + home.sessionVariables = { + EDITOR = "emacsclient -a="; + VISUAL = "emacsclient -a="; + }; +} diff --git a/home/profiles/firefox.nix b/home/profiles/firefox.nix new file mode 100644 index 0000000..e74aaea --- /dev/null +++ b/home/profiles/firefox.nix @@ -0,0 +1,59 @@ +{ pkgs, lib, config, ... }: +{ + programs.firefox = { + enable = true; + profiles = { + default = { + extensions = with pkgs.nur.repos.rycee.firefox-addons; [ + pkgs.nur.repos.rycee.firefox-addons."1password-x-password-manager" + consent-o-matic + refined-github + sponsorblock + ublock-origin + ]; + settings = { + ## nix handle updates + "app.update.auto" = false; + "browser.bookmarks.showMobileBookmarks" = false; + "browser.compactmode.show" = true; + "browser.contentblocking.category" = "strict"; + "browser.search.countryCode" = "US"; + "browser.search.defaultenginename" = "DuckDuckGo"; + "browser.search.isUS" = true; + "browser.search.region" = "US"; + "browser.search.selectedEngine" = "DuckDuckGo"; + ## don't check if it's the default browser + "browser.shell.checkDefaultBrowser" = false; + "browser.startup.homepage" = "https://duckduckgo.com"; + "browser.urlbar.placeholderName" = "DuckDuckGo"; + ## keep this with ff 96 + "media.ffmpeg.vaapi.enabled" = true; + ## remove on ff 96 + "media.ffvpx.enabled" = false; + ## remove on ff 96 + "media.navigator.mediadatadecoder_vpx_enabled" = true; + "media.peerconnection.enabled" = true; + ## keep this with ff 96 + "media.rdd-ffmpeg.enabled" = true; + ## remove on ff 96 + "media.rdd-vpx.enabled" = false; + ## Block third-party cookies + "network.cookie.cookieBehavior" = 1; + "privacy.donottrackheader.enabled" = true; + "privacy.trackingprotection.enabled" = true; + "privacy.trackingprotection.socialtracking.enabled" = true; + + "font.name.monospace.x-western" = "Source Code Pro"; + "font.name.sans-serif.x-western" = "DejaVu Sans"; + "font.name.serif.x-western" = "DejaVu Serif"; + }; + + userChrome = '' + #TabsToolbar { + visibility: collapse; + } + ''; + }; + }; + }; +} diff --git a/home/profiles/git.nix b/home/profiles/git.nix new file mode 100644 index 0000000..de2cbf6 --- /dev/null +++ b/home/profiles/git.nix @@ -0,0 +1,73 @@ +{ self, lib, pkgs, config, ... }: +let + sshPub = builtins.fromTOML ( + builtins.readFile "${self}/configs/ssh-pubkeys.toml" + ); +in +{ + home.file.".ssh/allowed_signers".text = lib.concatMapStrings (x: "franck@fcuny.net ${x}\n") (with sshPub; [ aptos work git ykey-laptop ]); + + programs.git = { + enable = true; + userName = "Franck Cuny"; + userEmail = "franck@fcuny.net"; + + signing = { + key = "key::${sshPub.ykey-laptop}"; + signByDefault = true; + }; + + extraConfig = { + core.whitespace = "trailing-space,space-before-tab"; + color.ui = "true"; + + diff.age.textconv = "${pkgs.age}/bin/age --identity ${config.home.homeDirectory}/.age/key.txt --decrypt"; + + gpg.format = "ssh"; + gpg.ssh.allowedSignersFile = "~/.ssh/allowed_signers"; + + # abort if the remote branch does not match the local one + push.default = "simple"; + + init.defaultBranch = "main"; + + pull.rebase = true; + rebase = { + # Automatically create a temporary stash entry before the + # operation begins, and apply it after the operation ends. + autoStash = true; + # Print a warning if some commits are removed + missingCommitsCheck = "warn"; + }; + + branch.autosetuprebase = "remote"; + branch.sort = "authordate"; + + commit.template = "${config.xdg.dataHome}/git/commit.template"; + }; + + ignores = [ + "*~" + ".direnv" + ]; + }; + + xdg.dataFile."git/commit.template".source = pkgs.writeText "commit.template" '' + + # (If applied, this commit will...) <subject> + + # Explain why this change is being made + + # --- COMMIT END --- + # Remember to + # Use the imperative mood, present tense: `change' not `changed' nor `changes' + # Do not end the subject line with a period + # Use the body to explain what and why vs. how + # Can use multiple lines with "-" for bullet points in body +''; + + home.packages = with pkgs; [ + tools.git-blame-stats + gitAndTools.pre-commit + ]; +} diff --git a/home/profiles/gtk.nix b/home/profiles/gtk.nix new file mode 100644 index 0000000..a3fff9d --- /dev/null +++ b/home/profiles/gtk.nix @@ -0,0 +1,35 @@ +{ config, lib, pkgs, ... }: +{ + gtk = { + enable = true; + + iconTheme = { + name = "Papirus-Dark"; + package = pkgs.papirus-icon-theme; + }; + + theme = { + name = "palenight"; + package = pkgs.palenight-theme; + }; + + cursorTheme = { + name = "Numix-Cursor"; + package = pkgs.numix-cursor-theme; + }; + + gtk3.extraConfig = { + Settings = '' + gtk-application-prefer-dark-theme=1 + ''; + }; + + gtk4.extraConfig = { + Settings = '' + gtk-application-prefer-dark-theme=1 + ''; + }; + }; + + home.sessionVariables.GTK_THEME = "palenight"; +} diff --git a/home/profiles/home.nix b/home/profiles/home.nix new file mode 100644 index 0000000..1aa90cf --- /dev/null +++ b/home/profiles/home.nix @@ -0,0 +1,69 @@ +{ config, lib, pkgs, ... }: +{ + imports = [ + ./git.nix + ./ssh.nix + ./zsh + ]; + + home.packages = with pkgs; [ + dive # explore layers in docker images + jq + ripgrep + util-linux + xdg-utils + + age + rage + age-plugin-yubikey + + # tools inside the tools directory + tools.git-blame-stats + tools.git-broom + tools.ipconverter + tools.seqstat + + # tools from external repositories + # x509-info + # gh-ssh-keys + # masked-emails + ]; + + programs.direnv = { + enable = true; + nix-direnv.enable = true; + config = { + global.disable_stdin = true; + global.strict_env = true; + }; + }; + + xdg = { + enable = true; + # File types + mime.enable = true; + # File associatons + mimeApps = { enable = true; }; + # User directories + userDirs = { + enable = true; + createDirectories = true; + desktop = "${config.home.homeDirectory}/documents"; + documents = "${config.home.homeDirectory}/documents"; + download = "${config.home.homeDirectory}/downloads"; + music = "${config.home.homeDirectory}/media/music"; + pictures = "${config.home.homeDirectory}/media/pictures"; + publicShare = "${config.home.homeDirectory}/documents/public"; + templates = "${config.home.homeDirectory}/documents/templates"; + videos = "${config.home.homeDirectory}/media/videos"; + }; + }; + + home.sessionVariables = with config.xdg; { + LESS = "-FRSXM"; + LESSCHARSET = "utf-8"; + LESSHISTFILE = "${dataHome}/less/history"; + LESSKEY = "${configHome}/less/lesskey"; + PAGER = "less"; + }; +} diff --git a/home/profiles/mako.nix b/home/profiles/mako.nix new file mode 100644 index 0000000..d4e54fe --- /dev/null +++ b/home/profiles/mako.nix @@ -0,0 +1,25 @@ +{ config, lib, pkgs, ... }: +{ + home.packages = [ + pkgs.libnotify + ]; + + # All the options are documented via `man 5 mako` + services.mako = { + enable = true; + font = "Source Code Pro"; + backgroundColor = "#000021DD"; + textColor = "#FFFFFFFF"; + borderSize = 0; + borderRadius = 15; + icons = true; + iconPath = "${pkgs.moka-icon-theme}/share/icons/Moka"; + markup = true; + actions = true; + defaultTimeout = 3000; + padding = "20"; + height = 200; + width = 500; + layer = "overlay"; + }; +} diff --git a/home/profiles/nas.nix b/home/profiles/nas.nix new file mode 100644 index 0000000..c1e5ca9 --- /dev/null +++ b/home/profiles/nas.nix @@ -0,0 +1,67 @@ +{ config, lib, pkgs, ... }: +let + bc-to-beet = pkgs.writeShellApplication { + name = "bc-to-beet"; + runtimeInputs = [ pkgs.beets ]; + text = '' + ALBUM_PATH="$1" + ALBUM_NAME=$(basename "$ALBUM_PATH") + + mkdir -p ~/import + rm -rf ~/import/tmp-bc + unzip -d ~/import/tmp-bc ~/import/album.zip + beet import ~/import/tmp-bc + rm -rf ~/import/tmp-bc + rm -rf ~/import/album.zip + ''; + }; +in +{ + imports = [ + ./ytdlp.nix + ]; + + home.packages = with pkgs; [ + bc-to-beet + flac + abcde + (pkgs.writers.writeDashBin "rip-flac" '' + cd ~/import + ${pkgs.abcde}/bin/abcde -Vx -G -a "cddb,read,encode,tag,move,clean" -o flac + '') + ]; + + programs.beets = { + enable = true; + settings = { + directory = cfg.musicDirectory; + plugins = + "fromfilename discogs duplicates fetchart embedart badfiles lastgenre scrub"; + paths = { + default = "$albumartist/$album%aunique{}/$track $title"; + singleton = "Singles/$artist/$title"; + comp = "Compilations/$album%aunique{}/$track - $title"; + "albumtype:soundtrack" = "Soundtracks/$album ($year)/$track $title"; + }; + import = { + copy = true; + move = true; + }; + va_name = "Various Artists"; + embedart = { ifempty = true; }; + + lastgenre = { + auto = false; + canonical = true; + fallback = "unknown"; + force = true; + prefer_specific = true; + }; + + fetchart = { + cautious = true; + sources = "filesystem coverart itunes amazon lastfm wikipedia"; + }; + }; + }; +} diff --git a/home/profiles/ssh.nix b/home/profiles/ssh.nix new file mode 100644 index 0000000..576f451 --- /dev/null +++ b/home/profiles/ssh.nix @@ -0,0 +1,18 @@ +{ ... }: +{ + programs.ssh = { + enable = true; + forwardAgent = true; + serverAliveInterval = 60; + controlMaster = "auto"; + controlPersist = "30m"; + matchBlocks = { + "github.com" = { + hostname = "github.com"; + user = "git"; + forwardAgent = false; + extraOptions = { preferredAuthentications = "publickey"; }; + }; + }; + }; +} diff --git a/home/profiles/sway.nix b/home/profiles/sway.nix new file mode 100644 index 0000000..0665556 --- /dev/null +++ b/home/profiles/sway.nix @@ -0,0 +1,172 @@ +{ config, lib, pkgs, ... }: +let + modifier = "Mod4"; # `Super` key +in +{ + imports = [ + ./gtk.nix + ./mako.nix + ./waybar.nix + ./wofi.nix + ]; + + home.packages = with pkgs; [ + wlogout + brightnessctl + pulseaudio + grim + slurp + polkit_gnome + xsettingsd + swaylock + swayidle + wl-clipboard + ]; + + home.sessionVariables = { + MOZ_ENABLE_WAYLAND = "1"; + XDG_CURRENT_DESKTOP = "sway"; + XDG_SESSION_TYPE = "wayland"; + }; + + programs = { + zsh.loginExtra = '' + if [ $(ps ax | grep "[s]sh-agent" | wc -l) -eq 0 ] ; then + eval $(ssh-agent -s) > /dev/null + fi + if [ "$(tty)" = "/dev/tty1" ]; then + exec sway &> /dev/null + fi + ''; + + zsh.profileExtra = '' + if [ $(ps ax | grep "[s]sh-agent" | wc -l) -eq 0 ] ; then + eval $(ssh-agent -s) > /dev/null + fi + if [ "$(tty)" = "/dev/tty1" ]; then + exec sway &> /dev/null + fi + ''; + }; + + wayland.windowManager.sway = { + enable = true; + # in order to import some variables (e.g. PATH) so that all the + # units that will be started have all the required environment + # variables + extraSessionCommands = "systemctl --user import-environment"; + # this will start sway-session.target and run + # dbus-update-activation-environment + systemdIntegration = true; + config = { + # FIXME: this should be a variable + terminal = "alacritty"; + modifier = modifier; + menu = ''${pkgs.wofi}/bin/wofi -S drun -p "app:" -L 10''; + bars = [ ]; + fonts = { + names = [ "Source Code Pro" ]; + size = 10.0; + }; + keybindings = lib.mkOptionDefault { + # control the volume + "XF86AudioRaiseVolume" = + "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ +5%"; + "XF86AudioLowerVolume" = + "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ -5%"; + "XF86AudioMute" = + "exec ${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle"; + "XF86AudioMicMute" = + "exec ${pkgs.pulseaudio}/bin/pactl set-source-mute @DEFAULT_SOURCE@ toggle"; + + # control brightness + "XF86MonBrightnessDown" = + "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%-"; + "XF86MonBrightnessUp" = + "exec ${pkgs.brightnessctl}/bin/brightnessctl set +5%"; + + # logout + "${modifier}+Escape" = "exec ${pkgs.wlogout}/bin/wlogout"; + + # screenshot + "${modifier}+s" = + "exec ${pkgs.grim}/bin/grim $(xdg-user-dir DOCUMENTS)/screenshots/$(date +'%Y-%m-%d-%H%M%S_screenshot.png')"; + "${modifier}+Shift+s" = + "exec ${pkgs.slurp}/bin/slurp | ${pkgs.grim}/bin/grim -g - $(xdg-user-dir DOCUMENTS)/screenshots/$(date +'%Y-%m-%d-%H%M%S_screenshot.png')"; + + # File Manager + "${modifier}+p" = "exec ${pkgs.pcmanfm}/bin/pcmanfm"; + }; + + # use `swaymsg -t get_tree' to get the title/name/ID of the applications + window = { + commands = [ + { + criteria.class = ".blueman-manager-wrapped"; + command = "floating enable"; + } + { + criteria.class = "Pavucontrol"; + command = "floating enable"; + } + ]; + }; + + input = { + "*" = { + "xkb_layout" = "us,fr"; + # map capslock to ctrl, and switch layout using shift+caps + "xkb_options" = "ctrl:nocaps,grp:shift_caps_toggle"; + }; + }; + + assigns = { + "1" = [{ app_id = "emacs"; }]; + "2" = [{ app_id = "Alacritty"; }]; + "3" = [{ app_id = "firefox"; }]; + "4" = [{ app_id = "org.gnome.Fractal"; }]; + }; + + output = { + "*" = { + scale = "1.5"; + bg = "#2E3440 solid_color"; + }; + # This is for aptos + "eDP-1" = { scale = "1.3"; }; + }; + }; + }; + + xdg.configFile."swaylock/config".source = pkgs.writeText "config" '' + color=2E3440 + daemonize + indicator-caps-lock + hide-keyboard-layout + ''; + + services.swayidle = { + enable = true; + events = [ + { + event = "before-sleep"; + command = "${pkgs.swaylock}/bin/swaylock -fF"; + } + { + event = "lock"; + command = "${pkgs.swaylock}/bin/swaylock -fF"; + } + ]; + timeouts = [ + { + timeout = 300; + command = "${pkgs.sway}/bin/swaymsg \"output * dpms off\""; + resumeCommand = "${pkgs.sway}/bin/swaymsg \"output * dpms on\""; + } + { + timeout = 310; + command = "${pkgs.systemd}/bin/loginctl lock-session"; + } + ]; + }; +} diff --git a/home/profiles/tmux.nix b/home/profiles/tmux.nix new file mode 100644 index 0000000..22f8683 --- /dev/null +++ b/home/profiles/tmux.nix @@ -0,0 +1,20 @@ +{ ... }: +{ + programs.tmux = { + enable = true; + + terminal = "xterm-256color"; + escapeTime = 0; + aggressiveResize = true; + baseIndex = 1; + shortcut = "z"; + clock24 = true; + historyLimit = 50000; # Bigger buffer + + extraConfig = '' + setw -g mouse on + + set-option -g renumber-windows on + ''; + }; +} diff --git a/home/profiles/waybar.nix b/home/profiles/waybar.nix new file mode 100644 index 0000000..e6f6c3d --- /dev/null +++ b/home/profiles/waybar.nix @@ -0,0 +1,155 @@ +{ config, lib, pkgs, ... }: +let + # waybar-systemd = pkgs.writeShellApplication { + # name = "waybar-systemd.sh"; + # runtimeInputs = [ ]; + # text = '' + # failed_user="$(systemctl --plain --no-legend --user list-units --state=failed | awk '{ print $1 }')" + # failed_system="$(systemctl --plain --no-legend list-units --state=failed | awk '{ print $1 }')" + + # failed_systemd_count="$(echo -n "$failed_system" | grep -c '^')" + # failed_user_count="$(echo -n "$failed_user" | grep -c '^')" + + # text=$(( failed_systemd_count + failed_user_count )) + + # if [ "$text" -eq 0 ]; then + # printf '{"text": ""}\n' + # else + # tooltip="" + + # [ -n "$failed_system" ] && tooltip="Failed system services:\n\n${failed_system}\n\n${tooltip}" + # [ -n "$failed_user" ] && tooltip="Failed user services:\n\n${failed_user}\n\n${tooltip}" + + # tooltip="$(printf "%s" "$tooltip" | perl -pe 's/\n/\\n/g' | perl -pe 's/(?:\\n)+$//')" + + # printf '{"text": "%s", "tooltip": "%s" }\n' "$text" "$tooltip" + # fi + # ''; + # }; +in +{ + programs.waybar = { + enable = true; + systemd.enable = true; + + settings = [{ + layer = "bottom"; + height = 25; + position = "top"; + margin-top = 0; + margin-left = 0; + margin-right = 0; + margin-bottom = 0; + modules-left = [ "sway/workspaces" "sway/mode" ]; + modules-right = [ "pulseaudio" "network" "battery" "clock" "tray" ]; + "sway/workspaces" = { + format = "{name}"; + disable-scroll = true; + }; + "sway/mode" = { format = "{}"; }; + tray = { spacing = 10; }; + clock = { format = "{: %a %b %d %R}"; }; + battery = { + states = { + warning = 30; + critical = 15; + }; + format = "ac:{capacity}%"; + tooltip = true; + tooltip-format = "{timeTo} ({capacity}%)"; + }; + # "custom/systemd" = { + # exec = "${waybarSystemd}/bin/waybar-systemd"; + # return-type = "json"; + # interval = 10; + # }; + pulseaudio = { + format = "vol:{volume}%"; + format-bluetooth = "bt:{volume}%"; + format-bluetooth-muted = "bt:{volume}%"; + format-muted = "vol:{volume}%"; + on-click = "pavucontrol"; + }; + "network" = { + format-wifi = "{essid}:{signalStrength}%"; + format-ethernet = "{ipaddr}/{cidr}"; + format-linked = "{ifname} (No IP)"; + format-disconnected = "network unavailable"; + format-alt = "{ifname}: {ipaddr}/{cidr}"; + tooltip = false; + }; + }]; + }; + + programs.waybar.style = pkgs.writeText "style.css" '' + * { + border-radius: 0; + border: none; + margin: 0; + min-height: 0; + padding: 0; + font-family: Source Code Pro; + font-size: 15px; + } + window#waybar { + background-color: #282A36; + color: #eee; + } + #workspaces button { + padding: 0 3px; + background-color: transparent; + color: #eee; + } + #workspaces button.focused { + background-color: #285577; + border: 1px solid #4c7899; + } + #clock, + #battery, + #network, + #pulseaudio, + #tray, + #mode { + padding-left: 10px; + padding-right: 10px; + } + #mode { + /* No styles */ + } + #tray { + /* No styles */ + } + #clock { + /* No styles */ + } + #battery { + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; + } + #battery.discharging { + color: #90a1ad; + } + #battery.charging { + color: #fffff8; + } + #battery.warning { + border-bottom: 2px solid #ff9e21; + } + #battery.critical { + border-bottom: 2px solid #ff3121; + } + #network { + /* No styles */ + } + #network.disconnected { + color: orange; + } + #pulseaudio { + /* No styles */ + } + #pulseaudio.muted { + color: #90a1ad; + } + ''; +} diff --git a/home/profiles/wofi.nix b/home/profiles/wofi.nix new file mode 100644 index 0000000..7140650 --- /dev/null +++ b/home/profiles/wofi.nix @@ -0,0 +1,13 @@ +{ config, lib, pkgs, ... }: { + + home.packages = with pkgs; [ wofi ]; + + xdg.configFile."wofi/config".source = pkgs.writeText "config" '' + allow_images=true + image_size=25px + drun-display_generic=true + dynamic_lines=true + insensitive=true + run-cache_file=/dev/null + ''; +} diff --git a/home/profiles/workstation.nix b/home/profiles/workstation.nix new file mode 100644 index 0000000..acbbccb --- /dev/null +++ b/home/profiles/workstation.nix @@ -0,0 +1,113 @@ +{ config, lib, pkgs, ... }: +let + restic-nas = pkgs.writeShellApplication + { + name = "restic-nas"; + runtimeInputs = [ pkgs.restic pkgs.tailscale pkgs.jq ]; + text = '' + NAS=$(tailscale status --json | jq -r '.Peer | map(select(.HostName == "tahoe"))[0].TailscaleIPs[0]') + + RESTIC_REPOSITORY="sftp:''${NAS}:/$(hostname)" + export RESTIC_REPOSITORY + export RESTIC_PASSWORD_FILE=/run/agenix/restic/repo-users + + sudo -E restic -o sftp.command="ssh backup@''${NAS} -i /run/agenix/restic/ssh-key -s sftp" "$@" + ''; + }; + + album-to-nas = pkgs.writeShellApplication { + name = "album-to-nas"; + runtimeInputs = [ pkgs.jq pkgs.tailscale ]; + text = '' + ALBUM_PATH="$1" + + NAS=$(tailscale status --json | jq -r '.Peer | map(select(.HostName == "tahoe"))[0].TailscaleIPs[0]') + + scp "$ALBUM_PATH" "$NAS:~/import/album.zip" + ssh "$NAS" bc-to-beet ~/import/album.zip + ''; + }; +in +{ + imports = [ + ./alacritty.nix + ./dev.nix + ./emacs.nix + ./firefox.nix + ./tmux.nix + ./yubikey.nix + ./ytdlp.nix + ]; + + home.packages = with pkgs; [ + # media + gnome3.eog + gnome3.evince + sublime-music + vlc + yt-dlp + + passage + tree + + # scanning + tesseract + imagemagick + exiftool + sane-airscan + + transmission-remote-gtk + + # custom tools + album-to-nas + restic-nas + + # tools from external repositories + # x509-info + # gh-ssh-keys + # masked-emails + ]; + + programs.feh.enable = true; + programs.mpv = { + enable = true; + config = { + sub-auto = "fuzzy"; + vo = "gpu"; + hwdec = "auto-safe"; + gpu-context = "wayland"; + audio-display = "no"; + cache-pause = "no"; + cache = "yes"; + mute = "no"; + osc = "yes"; + screenshot-directory = "~/documents/screenshots/mpv-screenshots/"; + screenshot-format = "png"; + }; + scripts = lib.attrVals [ "sponsorblock" ] pkgs.mpvScripts; + }; + + services.gammastep = { + enable = true; + #TODO: this needs to come from locale.nix + latitude = 37.8715; + longitude = -122.273; + temperature = { + day = 5000; + night = 3700; + }; + }; + + home.sessionVariables = { + PASSAGE_DIR = "${config.xdg.dataHome}/passage/store"; + PASSAGE_IDENTITIES_FILE = "${config.xdg.dataHome}/passage/identities"; + # for now I have to default to rage, as the version of age is + # not recent enough to work with keys generated by + # age-plugin-yubikey + PASSAGE_AGE = "${pkgs.rage}/bin/rage"; + }; + + + # enable bluetooth + services.blueman-applet.enable = true; +} diff --git a/home/profiles/ytdlp.nix b/home/profiles/ytdlp.nix new file mode 100644 index 0000000..ce2e32c --- /dev/null +++ b/home/profiles/ytdlp.nix @@ -0,0 +1,37 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + yt-dlp + ]; + + xdg.configFile."yt-dlp/config".source = pkgs.writeText "config" '' + # Preferred formats: + # 1. 1080p, combined, mp4 (for some non-youtube sites). + # 2. 1080p, combined, any format (in case mp4 is not available). + # 3. 1080p, best video + best audio (only available with separate video and audio on youtube). + # 4. >30fps (any resolution), best video + best audio (only available with separate video and audio on youtube). + # 5. 720p, pre-joined, because it is available on youtube. + # 6. <720p, best video + best audio (480p and some other lower resolutions are only available with separate video and audio on youtube). + # 7. When all else fails, take whatever youtube-dl thinks is the best (mainly for non-YT websites). + --format="best[height=1080][ext=mp4]/best[height=1080]/bestvideo[height=1080][ext=mp4]+bestaudio[ext=m4a]/bestvideo[fps>30][ext=mp4]+bestaudio[ext=m4a]/best[height=720][ext=mp4]/bestvideo[ext=mp4]+bestaudio[ext=m4a]/best" + + --continue + + --sub-langs all + --write-subs + + --convert-subs=srt + + --restrict-filenames + --output="$HOME/media/videos/%(uploader)s/%(playlist)s/%(upload_date)s-%(title)s.%(ext)s" + --merge-output-format mkv + + --embed-metadata + --embed-chapters + --embed-info-json + # create chapter entries to mark sponsor segments + --sponsorblock-mark all + + --yes-playlist + ''; +} diff --git a/home/profiles/yubikey.nix b/home/profiles/yubikey.nix new file mode 100644 index 0000000..b18ce5d --- /dev/null +++ b/home/profiles/yubikey.nix @@ -0,0 +1,28 @@ +{ pkgs, lib, config, ... }: +{ + home.packages = with pkgs; [ yubikey-manager yubikey-touch-detector ]; + + systemd.user.sockets.yubikey-touch-detector = { + Unit.Description = "Unix socket activation for YubiKey touch detector service"; + Socket = { + ListenStream = "%t/yubikey-touch-detector.socket"; + RemoveOnStop = true; + }; + Install.WantedBy = [ "sockets.target" ]; + }; + + systemd.user.services.yubikey-touch-detector = { + Unit = { + Description = "Detects when your YubiKey is waiting for a touch"; + Requires = "yubikey-touch-detector.socket"; + }; + Service = { + ExecStart = "${pkgs.yubikey-touch-detector}/bin/yubikey-touch-detector --libnotify"; + EnvironmentFile = "-%E/yubikey-touch-detector/service.conf"; + }; + Install = { + Also = "yubikey-touch-detector.socket"; + WantedBy = [ "default.target" ]; + }; + }; +} diff --git a/home/profiles/zsh/completion-style.zsh b/home/profiles/zsh/completion-style.zsh new file mode 100644 index 0000000..79a4e68 --- /dev/null +++ b/home/profiles/zsh/completion-style.zsh @@ -0,0 +1,42 @@ +# 'ctrl-x r' will complete the 12 last modified (mtime) files/directories +zle -C newest-files menu-complete _generic +# Use "*newest-files" so that it matches both "newest-files" and +# "load-completion-and-newest-files". +zstyle ':completion:*newest-files:*' completer _files +zstyle ':completion:*newest-files:*' file-patterns '*(omN[1,12])' +zstyle ':completion:*newest-files:*' menu select yes +zstyle ':completion:*newest-files:*' sort false +zstyle ':completion:*newest-files:*' matcher-list 'b:=*' # important + +# colors for zsh file name completion +zmodload zsh/complist +zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS} + +# Show a prompt on selection +zstyle ':completion:*' select-prompt '%SScrolling active: current selection at %p%s' + +# Use arrow keys in completion list +zstyle ':completion:*' menu select + +# Group results by category +zstyle ':completion:*' group-name '' + +# Keep directories and files separated +zstyle ':completion:*' list-dirs-first true + +# match uppercase from lowercase +zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' + +# Filename suffixes to ignore during completion (except after rm command) +zstyle ':completion:*:*:(^rm):*:*files' ignored-patterns '*?.old' + +# command for process lists, the local web server details and host completion +# on processes completion complete all user processes +zstyle ':completion:*:processes' command 'ps -au$USER' + +# Completion formatting and messages +zstyle ':completion:*' verbose yes +zstyle ':completion:*:descriptions' format '%B%d%b' +zstyle ':completion:*:messages' format '%d' +zstyle ':completion:*:warnings' format 'No matches for: %d' +zstyle ':completion:*:corrections' format '%B%d (errors: %e)%b' diff --git a/home/profiles/zsh/default.nix b/home/profiles/zsh/default.nix new file mode 100644 index 0000000..38450ab --- /dev/null +++ b/home/profiles/zsh/default.nix @@ -0,0 +1,51 @@ +{ config, pkgs, lib, ... }: +{ + home.packages = with pkgs; [ zsh-completions ]; + + programs.zsh = { + enable = true; + dotDir = ".config/zsh"; + + enableCompletion = true; + enableAutosuggestions = true; + + history = { + size = 500000; + save = 500000; + extended = false; + ignoreSpace = true; + ignoreDups = true; + share = false; + # see + # https://github.com/nix-community/home-manager/blob/32a7da69dc53c9eb5ad0675eb7fdc58f7fe35272/modules/programs/zsh.nix#L537 + path = "${config.xdg.dataHome}/zsh/zsh_history"; + }; + + localVariables = { + # Print timing statistics for everything which takes longer than 5 seconds of + # user + system time. + REPORTTIME = 5; + }; + + shellAliases = { + ll = "ls -l --color=auto"; + lt = "ls -ltrh --color=auto"; + la = "ls -ltrha --color=auto"; + pkgsearch = "nix search nixpkgs"; + hms = "home-manager switch --flake ."; + nr = "sudo nixos-rebuild switch --flake ."; + flup = "nix flake update --commit-lock-file"; + dhcp-leasese = "xdg-open http://192.168.6.1:8067/"; + }; + + defaultKeymap = "emacs"; + + initExtra = lib.concatMapStrings builtins.readFile [ + ./completion-style.zsh + ./options.zsh + ./prompt.zsh + ./tmux.zsh + ./new-go-project.zsh + ]; + }; +} diff --git a/home/profiles/zsh/new-go-project.zsh b/home/profiles/zsh/new-go-project.zsh new file mode 100644 index 0000000..0b96a34 --- /dev/null +++ b/home/profiles/zsh/new-go-project.zsh @@ -0,0 +1,19 @@ +new-go-project() { + local project_name=$1 + + echo "> creating ${project_name}" + cd ~/workspace/ + mkdir $project_name + cd $project_name + + echo "> initializing the git repository" + git init . + + echo "> setting the default template for go projects" + nix flake init -t ~/workspace/world/templates#go + direnv allow + + echo "> creating initial commit, touch your yubikey" + git add . + git commit -m 'initial commit' +} diff --git a/home/profiles/zsh/options.zsh b/home/profiles/zsh/options.zsh new file mode 100644 index 0000000..6d39bc1 --- /dev/null +++ b/home/profiles/zsh/options.zsh @@ -0,0 +1,27 @@ +# Show an error when a globbing expansion doesn't find any match +setopt nomatch + +# List on ambiguous completion and Insert first match immediately +setopt autolist menucomplete + +# Use pushd when cd-ing around +setopt autopushd pushdminus pushdsilent + +# Use single quotes in string without the weird escape tricks +setopt rcquotes + +# Single word commands can resume an existing job +setopt autoresume + +# Append commands to history as they are exectuted +setopt inc_append_history_time + +# Remove useless whitespace from commands +setopt hist_reduce_blanks + +# Those options aren't wanted +unsetopt beep extendedglob notify + +# word select works like in bash +autoload -U select-word-style +select-word-style bash diff --git a/home/profiles/zsh/prompt.zsh b/home/profiles/zsh/prompt.zsh new file mode 100644 index 0000000..8a3efa9 --- /dev/null +++ b/home/profiles/zsh/prompt.zsh @@ -0,0 +1,17 @@ +setopt prompt_subst + +autoload -Uz vcs_info + +# display the name of the branch +zstyle ':vcs_info:git*' formats " [%b]" +zstyle ':vcs_info:*' enable git + +precmd () { vcs_info } +PROMPT='%m%f:%F{green}%~%f%F{yellow}$vcs_info_msg_0_ %F{reset}' + +# For tramp (emacs). +if [ "$TERM" = "dumb" ]; then + unset PROMPT + PS1='$ ' + unsetopt zle +fi diff --git a/home/profiles/zsh/tmux.zsh b/home/profiles/zsh/tmux.zsh new file mode 100644 index 0000000..97944f5 --- /dev/null +++ b/home/profiles/zsh/tmux.zsh @@ -0,0 +1,9 @@ +# If we're not in an ssh connection, and tmux is installed, and we're +# not already in a tmux session, attach to the session named +# 'default', and if the session does not exist, start one named +# 'default' +if [ -z "$SSH_CONNECTION" ]; then + if command -v tmux &> /dev/null && [ -z "$TMUX" ]; then + tmux attach -t default || tmux new -s default + fi +fi |