home: Modularise configuration

This commit is contained in:
Mikael 2024-08-25 19:10:52 +02:00
parent 608f689b69
commit 9acbf395fd
Signed by: mikael
SSH key fingerprint: SHA256:21QyD2Meiot7jOUVitIR5YkGB/XuXdCvLW1hE6dsri0
15 changed files with 853 additions and 929 deletions

297
home/config/nil/bar.nix Normal file
View file

@ -0,0 +1,297 @@
{ ... }: { config, lib, pkgs, ... }@args:
let
osConfig = args.osConfig or { };
busctl = osConfig.systemd.package + /bin/busctl;
gammarelay = lib.getExe pkgs.wl-gammarelay-rs;
pwvucontrol = lib.getExe pkgs.pwvucontrol;
wpctl = osConfig.services.pipewire.wireplumber.package + /bin/wpctl;
gr = cmd: "${busctl} --user -- ${cmd} rs.wl-gammarelay / rs.wl.gammarelay";
gr-get = gr "get-property";
gr-set = gr "set-property";
gr-call = gr "call";
gr-inv = let
pkg = pkgs.writeShellApplication {
name = "gammarelay-inverted";
text = ''
state="$(${gr-get} Inverted)";
if [[ "$state" == "b false" ]]; then
echo 󰹊
elif [[ "$state" == "b true" ]]; then
echo 󰌁
else
exit 1
fi
'';
};
in lib.getExe pkg;
in lib.mkIf (osConfig.hardware.graphics.enable or false) {
programs.waybar = {
enable = true;
package = pkgs.waybar.override {
cavaSupport = false;
hyprlandSupport = false;
jackSupport = false;
mpdSupport = false;
sndioSupport = false;
};
settings = {
main = {
layer = "top";
position = "bottom";
modules-left = [
"tray"
];
modules-center = [ ];
modules-right = [
"network#down"
"network#up"
"bluetooth"
"cpu"
"memory"
"memory#swap"
"temperature"
"disk"
"battery"
"idle_inhibitor"
"custom/gammarelay-temperature"
"custom/gammarelay-brightness"
"custom/gammarelay-gamma"
"custom/gammarelay-invert"
"mpris"
"pulseaudio#sink"
"pulseaudio#source"
"clock"
];
"network#down" = {
format = "󰅃 {bandwidthDownBytes}";
};
"network#up" = {
format = "󰅀 {bandwidthUpBytes}";
};
bluetooth = {
format-connected-battery = "󰂯 {device_battery_percentage}%";
tooltip-format-connected-battery = "{device_enumerate}";
tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_battery_percentage}%";
};
cpu = {
format = " {usage}%";
};
memory = {
format = " {percentage}%";
tooltip-format = "{used:0.1f}/{total:0.1f}GiB";
};
"memory#swap" = {
format = " {swapPercentage}%";
tooltip-format = "{swapUsed:0.1f}/{swapTotal:0.1f}GiB";
};
temperature = let
fmt = "{temperatureC}°C";
in {
format = "󰔏 ${fmt}";
format-critical = "󰸁 ${fmt}";
tooltip-format = fmt;
};
disk = {
format = " {percentage_used}%";
path = "/home";
tooltip-format = "{used}/{total}";
};
idle_inhibitor = {
format = "{icon}";
format-icons = {
activated = "󱎴";
deactivated = "󰷛";
};
timeout = 15.0;
};
"custom/gammarelay-temperature" = {
format = " {}K";
exec = "${gammarelay} watch {t}";
on-click-right = "${gr-set} Temperature q 6500";
on-scroll-up = "${gr-call} UpdateTemperature n +100";
on-scroll-down = "${gr-call} UpdateTemperature n -100";
};
"custom/gammarelay-brightness" = {
format = " {}%";
exec = "${gammarelay} watch {bp}";
on-click-right = "${gr-set} Brightness d 1";
on-scroll-up = "${gr-call} UpdateBrightness d +0.01";
on-scroll-down = "${gr-call} UpdateBrightness d -0.01";
};
"custom/gammarelay-gamma" = {
format = "γ {}";
exec = "${gammarelay} watch {g}";
on-click-right = "${gr-set} Gamma d 1";
on-scroll-up = "${gr-call} UpdateGamma d +0.01";
on-scroll-down = "${gr-call} UpdateGamma d -0.01";
};
"custom/gammarelay-invert" = {
exec = gr-inv;
exec-on-event = true;
interval = 60;
on-click = "${gr-call} ToggleInverted";
on-click-right = "${gr-set} Inverted b false";
};
battery = let
fmt = "{capacity}%";
dis = {
"5" = "󱃍";
"10" = "󰁺";
"20" = "󰁻";
"30" = "󰁼";
"40" = "󰁽";
"50" = "󰁿";
"60" = "󰁿";
"70" = "󰂀";
"80" = "󰂁";
"90" = "󰂂";
"100" = "󰁹";
};
chr = {
"5" = "󰢟";
"10" = "󰢜";
"20" = "󰂆";
"30" = "󰂇";
"40" = "󰂈";
"50" = "󰢝";
"60" = "󰂉";
"70" = "󰢞";
"80" = "󰂊";
"90" = "󰂋";
"100" = "󰂅";
};
in {
states = {
"5" = 5;
"10" = 10;
"20" = 20;
"30" = 30;
"40" = 40;
"50" = 50;
"60" = 60;
"70" = 70;
"80" = 80;
"90" = 90;
"100" = 100;
};
format-full = "󰚥 ${fmt}";
format-time = "{H}:{M}";
weighted-average = true;
}
// lib.mapAttrs' (state: icon: {
name = "format-discharging-${state}";
value = "${icon} ${fmt}";
}) dis
// lib.mapAttrs' (state: icon: {
name = "format-charging-${state}";
value = "${icon} ${fmt}";
}) chr;
mpris = {
format = "{status}";
status-icons = {
playing = "";
paused = "";
stopped = "";
};
};
"pulseaudio#sink" = let
fmt = "{volume}%";
in {
format = "{icon} ${fmt}";
format-bluetooth = "󰂰 ${fmt}";
format-muted = " ${fmt}";
format-icons = {
headphone = "";
default = [ "" "" ];
};
on-click = pwvucontrol;
on-click-right = "${wpctl} set-mute @DEFAULT_AUDIO_SINK@ toggle";
on-scroll-up = "${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 1%+";
on-scroll-down = "${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 1%-";
};
"pulseaudio#source" = let
fmt = "{volume}%";
in {
format = "{format_source}";
format-source = "󰍬 ${fmt}";
format-source-muted = "󰍭 ${fmt}";
on-click = pwvucontrol;
on-click-right = "${wpctl} set-mute @DEFAULT_AUDIO_SOURCE@ toggle";
on-scroll-up = "${wpctl} set-volume @DEFAULT_AUDIO_SOURCE@ 1%+";
on-scroll-down = "${wpctl} set-volume @DEFAULT_AUDIO_SOURCE@ 1%-";
};
clock = {
format = " {:%H:%M %Z}";
format-alt = "󰃭 {:%Y-%m-%d}";
tooltip-format = "<tt><small>{calendar}</small></tt>";
calendar = {
mode = "month";
weeks-pos = "left";
on-scroll = 1;
format = {
weeks = "{:%W}";
};
};
};
};
};
};
systemd.user.services = {
waybar = {
Unit = {
PartOf = [ "graphical-session.target" ];
After = [ "graphical-session.target" ];
BindsTo = [ "tray.target" ];
Before = [ "tray.target" ];
};
Service = {
Type = "exec";
ExecStart = lib.getExe config.programs.waybar.package;
};
};
};
systemd.user.targets = {
tray = {
Unit = {
PartOf = [ "graphical-session.target" ];
After = [ "graphical-session.target" ];
};
};
};
}

198
home/config/nil/desktop.nix Normal file
View file

@ -0,0 +1,198 @@
{ ... }: { config, lib, pkgs, ... }@args:
let
osConfig = args.osConfig or { };
busctl = osConfig.systemd.package + /bin/busctl;
fish = lib.getExe osConfig.programs.fish.package;
fuzzel = lib.getExe config.programs.fuzzel.package;
kitty = lib.getExe config.programs.kitty.package;
loginctl = osConfig.systemd.package + /bin/loginctl;
playerctl = config.services.playerctld.package + /bin/playerctl;
swaylock = lib.getExe config.programs.swaylock.package;
wpctl = osConfig.services.pipewire.wireplumber.package + /bin/wpctl;
xdg-open = pkgs.xdg-utils + /bin/xdg-open;
busctl-gr = [ busctl "--user" "--" "call" "rs.wl-gammarelay" "/" "rs.wl.gammarelay" ];
niri-each-output = let
pkg = pkgs.writeShellApplication {
name = "niri-each-output";
runtimeInputs = [
config.programs.niri.package
pkgs.findutils
pkgs.jq
];
text = ''
niri msg --json outputs \
| jq --raw-output0 '. | keys | .[]' \
| xargs -0 I {} niri msg output -- {} "$1"
'';
};
in lib.getExe pkg;
in lib.mkIf (osConfig.hardware.graphics.enable or false) {
home.packages = with pkgs; [
calibre
fractal
inkscape
jellyfin-mpv-shim
keepassxc
libreoffice
obsidian
restic
signal-desktop
];
programs.fuzzel = {
enable = true;
settings = {
main = {
prompt = " ";
};
};
};
programs.niri.settings = {
prefer-no-csd = true;
input = {
keyboard = {
xkb = with config.home.keyboard; {
inherit layout;
options = options |> lib.concatStringsSep ",";
};
};
focus-follows-mouse.enable = true;
touchpad = {
dwt = true;
dwtp = true;
};
};
outputs = {
eDP-1 = {
scale = 1;
variable-refresh-rate = true;
};
DP-6 = {
mode = { width = 5120; height = 2160; };
scale = 1;
position = { x = 0; y = 0; };
variable-refresh-rate = true;
};
};
layout = {
border.enable = lib.mkForce false;
focus-ring = {
enable = true;
width = 1;
};
default-column-width.proportion = 1. / 3.;
gaps = 5;
preset-column-widths = [
{ proportion = 1. / 3.; }
{ proportion = 1. / 2.; }
{ proportion = 2. / 3.; }
];
};
binds = with config.lib.niri.actions; {
"Mod+Return".action = spawn [ kitty ];
"Mod+Shift+Return".action = spawn [ kitty fish "--private" ];
"Mod+e".action = spawn [ fuzzel ];
"Mod+Up".action = focus-window-or-workspace-up;
"Mod+Down".action = focus-window-or-workspace-down;
"Mod+Left".action = focus-column-left;
"Mod+Right".action = focus-column-right;
"Mod+Ctrl+Up".action = move-window-up-or-to-workspace-up;
"Mod+Ctrl+Down".action = move-window-up-or-to-workspace-up;
"Mod+Ctrl+Left".action = move-column-left;
"Mod+Ctrl+Right".action = move-column-right;
"Mod+WheelScrollUp".action = focus-window-up-or-column-left;
"Mod+WheelScrollDown".action = focus-window-down-or-column-right;
"Mod+g".action = consume-window-into-column;
"Mod+b".action = expel-window-from-column;
"Mod+Print".action = screenshot;
"Mod+Ctrl+Print".action = screenshot-window;
"Mod+Shift+Print".action = screenshot-screen;
XF86Explorer.action = spawn [ xdg-open "https:" ];
} // lib.mapAttrs (n: v: v // { allow-when-locked = true; }) {
XF86MonBrightnessUp.action = spawn (busctl-gr ++ [ "UpdateBrightness" "d" "0.05" ]);
XF86MonBrightnessDown.action = spawn (busctl-gr ++ [ "UpdateBrightness" "d" "-0.05" ]);
XF86AudioRaiseVolume.action = spawn [ wpctl "set-volume" "@DEFAULT_AUDIO_SINK@" "+2dB" ];
XF86AudioLowerVolume.action = spawn [ wpctl "set-volume" "@DEFAULT_AUDIO_SINK@" "-2dB" ];
XF86AudioMute.action = spawn [ wpctl "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle" ];
XF86AudioMicMute.action = spawn [ wpctl "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle" ];
XF86AudioNext.action = spawn [ playerctl "next" ];
XF86AudioPrev.action = spawn [ playerctl "previous" ];
XF86AudioPlay.action = spawn [ playerctl "play" ];
XF86AudioStop.action = spawn [ playerctl "pause" ];
};
environment = {
NIXOS_OZONE_WL = "1";
TERMINAL = kitty;
};
};
programs.swaylock = {
enable = true;
package = pkgs.swaylock-effects;
settings = {
screenshots = true;
effect-blur = "5x3";
grace = 2;
};
};
services.mako = {
enable = true;
defaultTimeout = 5000;
};
services.playerctld.enable = true;
services.swayidle = {
enable = true;
events = [
{ event = "lock"; command = "${swaylock} -f"; }
{ event = "before-sleep"; command = "${loginctl} lock-session"; }
];
timeouts = [
{
timeout = 240;
command = "${loginctl} lock-session";
}
{
timeout = 270;
command = "${niri-each-output} off";
resumeCommand = "${niri-each-output} on";
}
];
};
xdg.mimeApps.enable = true;
xdg.portal = {
enable = true;
configPackages = [ config.programs.niri.package ];
extraPortals = with pkgs; [
xdg-desktop-portal-gnome
xdg-desktop-portal-gtk
];
};
}

View file

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
<match target="font">
<test name="family" compare="eq" ignore-blanks="true">
<string>Fira Code</string>
</test>
<edit name="fontfeatures" mode="append">
<string>cv01</string>
<string>cv06</string>
<string>onum</string>
<string>ss01</string>
<string>ss03</string>
<string>ss06</string>
<string>ss07</string>
<string>ss08</string>
<string>zero</string>
</edit>
</match>
</fontconfig>

View file

@ -243,4 +243,8 @@ in lib.mkIf (osConfig.hardware.graphics.enable or false) {
};
};
};
xdg.mimeApps.defaultApplications = {
default-web-browser = [ "firefox.desktop" ];
};
}

View file

@ -0,0 +1,68 @@
{ ... }: { config, lib, pkgs, ... }@args:
let
osConfig = args.osConfig or { };
in lib.mkIf (osConfig.hardware.graphics.enable or false) {
fonts.fontconfig = {
enable = true;
defaultFonts = {
sansSerif = [
"Lato"
"M PLUS 1"
"Noto Sans"
"Symbols Nerd Font"
"Unifont"
"Unifont Upper"
];
serif = [ "Noto Serif" ];
monospace = [
"Fira Code"
"M PLUS 1 Code"
"Noto Sans Mono"
"Symbols Nerd Font Mono"
];
emoji = [ "Noto Color Emoji" ];
};
};
home.packages = with pkgs; [
lato
fira-code
mplus-outline-fonts.githubRelease
(nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; })
noto-fonts
noto-fonts-color-emoji
unifont
];
stylix.fonts = {
sansSerif = {
package = pkgs.lato;
name = "sans-serif";
};
serif = {
package = pkgs.noto-fonts;
name = "serif";
};
monospace = {
package = pkgs.fira-code;
name = "monospace";
};
emoji = {
package = pkgs.noto-fonts-color-emoji;
name = "emoji";
};
sizes = {
terminal = 11;
};
};
xdg.configFile."fontconfig/conf.d/80-fira-code.conf".source = ./fira-code.xml;
}

View file

@ -0,0 +1,22 @@
{ ... }: { config, lib, pkgs, ... }@args:
let
osConfig = args.osConfig or { };
in lib.mkIf (osConfig.hardware.graphics.enable or false) {
systemd.user.services = {
gammarelay = {
Unit = {
Description = "Display temperature and brightness control";
};
Service = {
BusName = "rs.wl-gammarelay";
ExecStart = lib.getExe pkgs.wl-gammarelay-rs;
Restart = "on-failure";
};
Install = {
WantedBy = [ "default.target" ];
};
};
};
}

View file

@ -1,73 +0,0 @@
xkb_symbols "greedy" {
name[Group1]= "Greedy";
// Modifier keys
include "ctrl(nocaps)"
include "altwin(alt_super_win)"
include "level3(ralt_switch)"
include "level5(rctrl_switch)"
include "compose(lwin-altgr)"
include "compose(102)"
include "nbsp(level3n)"
include "keypad(future)"
key <TAB> { [ Escape ] };
key <ESC> { [ Tab ] };
key <TLDE> { [ dollar, asciitilde, EuroSign, dead_tilde ] };
key <AE01> { [ ampersand, percent, dead_breve, dead_caron ] };
key <AE02> { [ bracketleft, 7, 0x100201E, 0x100201A ] };
key <AE03> { [ braceleft, 5, 0x100201C, 0x1002018 ] };
key <AE04> { [ braceright, 3, 0x100201D, 0x1002019 ] };
key <AE05> { [ parenleft, 1, 0x1002039, NoSymbol ] };
key <AE06> { [ equal, 9, 0x1002260, NoSymbol ] };
key <AE07> { [ asterisk, 0, 0x10022C5, NoSymbol ] };
key <AE08> { [ parenright, 2, 0x100203A, NoSymbol ] };
key <AE09> { [ plus, 4, plusminus, NoSymbol ] };
key <AE10> { [ bracketright, 6, endash, emdash ] };
key <AE11> { [ exclam, 8, exclamdown, infinity ] };
key <AE12> { [ numbersign, grave, numerosign, dead_grave ] };
key <AD01> { [ k, K, odiaeresis, Odiaeresis ] };
key <AD02> { [ comma, less, dead_cedilla, guillemotleft ] };
key <AD03> { [ u, U, oacute, Oacute ] };
key <AD04> { [ y, Y, udiaeresis, Udiaeresis ] };
key <AD05> { [ p, P, NoSymbol, NoSymbol ] };
key <AD06> { [ w, W, NoSymbol, NoSymbol ] };
key <AD07> { [ l, L, NoSymbol, NoSymbol ] };
key <AD08> { [ m, M, mu, NoSymbol ] };
key <AD09> { [ f, F, NoSymbol, NoSymbol ] };
key <AD10> { [ c, C, copyright, NoSymbol ] };
key <AD11> { [ slash, question, division, questiondown ] };
key <AD12> { [ at, asciicircum, 0x100203D, dead_circumflex ] };
key <AC01> { [ o, O, oacute, Oacute ] };
key <AC02> { [ a, A, aacute, Aacute ] };
key <AC03> { [ e, E, eacute, Eacute ] };
key <AC04> { [ i, I, iacute, Iacute ] };
key <AC05> { [ d, D, eth, ETH ] };
key <AC06> { [ r, R, NoSymbol, NoSymbol ] };
key <AC07> { [ n, N, ntilde, Ntilde ] };
key <AC08> { [ t, T, thorn, Thorn ] };
key <AC09> { [ h, H, NoSymbol, NoSymbol ] };
key <AC10> { [ s, S, ssharp, section ] };
key <AC11> { [ minus, underscore, 0x1002010, dead_macron ] };
key <BKSL> { [ backslash, bar, NoSymbol, NoSymbol ] };
key <AB01> { [ q, Q, adiaeresis, Adiaeresis ] };
key <AB02> { [ period, greater, ellipsis, guillemotright ] };
key <AB03> { [ apostrophe, quotedbl, dead_acute, dead_diaeresis ] };
key <AB04> { [ semicolon, colon, periodcentered, NoSymbol ] };
key <AB05> { [ z, Z, NoSymbol, NoSymbol ] };
key <AB06> { [ x, X, multiply, NoSymbol ] };
key <AB07> { [ v, V, NoSymbol, NoSymbol ] };
key <AB08> { [ g, G, NoSymbol, NoSymbol ] };
key <AB09> { [ b, B, NoSymbol, NoSymbol ] };
key <AB10> { [ j, J, NoSymbol, NoSymbol ] };
key <UP> { [ Up, NoSymbol, uparrow, 0x10021D1 ] };
key <LEFT> { [ Left, NoSymbol, leftarrow, 0x10021D0 ] };
key <DOWN> { [ Down, NoSymbol, downarrow, 0x10021D3 ] };
key <RGHT> { [ Right, NoSymbol, rightarrow, 0x10021D2 ] };
};

View file

@ -4,6 +4,7 @@ let
in {
imports = [
nur.hmModules.nur
self.homeModules.greedy
self.homeModules.locale-en_EU
nix-index-database.hmModules.nix-index
stylix.homeManagerModules.stylix
@ -11,8 +12,16 @@ in {
niri.homeModules.config
niri.homeModules.stylix
] ++ self.lib.mods [
./gammarelay.nix
./founts.nix
./stylix.nix
./desktop.nix
./bar.nix
./terminal.nix
./firefox.nix
./wayland.nix
./thunderbird.nix
./sioyek.nix
./texlive.nix
];
home.stateVersion = "24.11";

57
home/config/nil/mpv.nix Normal file
View file

@ -0,0 +1,57 @@
{ ... }: { config, lib, pkgs, ... }@args:
let
osConfig = args.osConfig or { };
in lib.mkIf (osConfig.hardware.graphics.enable or false) {
programs.mpv = {
enable = true;
defaultProfiles = [ "high-quality" ];
config = {
#access-references = false;
# Video output
vo = "gpu";
#gpu-api = "vulkan";
hwdec = "vulkan,vaapi,auto-safe";
vd-lavc-dr = true;
scale = "ewa_lanczos4sharpest";
cscale = "spline64";
dscale = "mitchell";
tscale = "oversample";
# A/V sync
video-sync = "display-resample";
interpolation = true;
# Audio
volume = 100;
volume-max = 100;
# Subtitles
sub-auto = "fuzzy";
# Screenshots
screenshot-format = "avif";
# Cache
demuxer-max-bytes = "768MiB";
demuxer-max-back-bytes = "256MiB";
};
profiles = {
highres = {
scale = "spline64";
};
};
scripts = with pkgs.mpvScripts; [
mpris
autocrop
autodeint
];
scriptOpts = {
autocrop.auto = false;
};
};
}

View file

@ -0,0 +1,20 @@
{ ... }: { config, lib, ... }@args:
let
osConfig = args.osConfig or { };
in lib.mkIf (osConfig.hardware.graphics.enable or false) {
programs.sioyek = {
enable = true;
bindings = {
"command" = "-";
"move_up" = [ "<up>" "t" ];
"move_down" = [ "<down>" "n" ];
"move_left" = [ "<right>" "h" ];
"move_right" = [ "<left>" "r" ];
};
};
xdg.mimeApps.defaultApplications = {
"application/pdf" = [ "sioyek.desktop" ];
};
}

View file

@ -0,0 +1,8 @@
{ ... }: { config, lib, pkgs, ... }: {
stylix = {
enable = true;
base16Scheme = "${pkgs.base16-schemes}/share/themes/catppuccin-macchiato.yaml";
image = ./wallpaper.png;
polarity = "dark";
};
}

View file

@ -0,0 +1,97 @@
{ ... }: { config, lib, pkgs, ... }@args:
let
osConfig = args.osConfig or { };
mdless = pkgs.mdcat + /bin/mdless;
mpv = lib.getExe config.programs.mpv.package;
xdg-open = pkgs.xdg-utils + /bin/xdg-open;
in lib.mkIf (osConfig.hardware.graphics.enable or false) {
programs.eza.extraOptions = lib.mkAfter [ "--hyperlink" ];
programs.kitty = {
enable = true;
theme = "Catppuccin-Mocha";
settings = {
disable_ligatures = "cursor";
cursor_blink_interval = 0;
scrollback_lines = 65536;
scrollback_fill_enlarged_window = true;
enable_audio_bell = false;
close_on_child_death = true;
clear_all_shortcuts = true;
# Mouse
click_interval = "0.2";
};
keybindings = {
"ctrl+shift+c" = "copy_to_clipboard";
"ctrl+shift+v" = "paste_from_clipboard";
"ctrl+shift+s" = "paste_from_selection";
"shift+insert" = "paste_from_selection";
"ctrl+up" = "scroll_line_up";
"ctrl+down" = "scroll_line_down";
"ctrl+page_up" = "scroll_page_up";
"ctrl+page_down" = "scroll_page_down";
"shift+page_up" = "scroll_page_up";
"shift+page_down" = "scroll_page_down";
"ctrl+home" = "scroll_home";
"ctrl+end" = "scroll_end";
"ctrl+print_screen" = "show_scrollback";
"ctrl+equal" = "change_font_size all 0";
"ctrl+plus" = "change_font_size all +1";
"ctrl+minus" = "change_font_size all -1";
"ctrl+shift+u" = "kitten unicode_input";
};
extraConfig = let
mouse = {
"left click ungrabbed" = "mouse_handle_click selection prompt";
"ctrl+left click ungrabbed" = "mouse_handle_click link";
"left press ungrabbed" = "mouse_selection normal";
"shift+left press ungrabbed" = "mouse_selection line";
"ctrl+left press ungrabbed" = "mouse_selection rectangle";
"left doublepress ungrabbed" = "mouse_selection word";
"left triplepress ungrabbed" = " mouse_selection line";
} |> lib.mapAttrsToList (n: v: "mouse_map ${n} ${v}\n")
|> lib.concatStrings;
in ''
clear_all_mouse_actions yes
${mouse}
'';
};
xdg.configFile."kitty/open-actions.conf".text = ''
protocol file
mime image/*
action launch --type overlay kitten icat --hold -- "$FILE_PATH"
protocol file
mime text/markdown
action launch --type overlay ${mdless} -- "$FILE_PATH"
protocol file
mime text/*
action launch --type overlay $EDITOR -- "$FILE_PATH"
protocol file
mime video/*
action launch --type background ${mpv} -- "$FILE_PATH"
protocol file
mime audio/*
action launch --type overlay ${mpv} -- "$FILE_PATH"
protocol
action launch --type background ${xdg-open} "$FILE_PATH"
'';
}

View file

@ -0,0 +1,42 @@
{ ... }: { config, lib, ... }@args:
let
osConfig = args.osConfig or { };
in lib.mkIf (osConfig.hardware.graphics.enable or false) {
programs.texlive = {
enable = true;
extraPackages = tpkgs: {
inherit (tpkgs)
texlive-scripts
xelatex-dev
fontspec
polyglossia
hyphen-english
hyphen-french
hyphen-german
hyphen-portuguese
hyphen-spanish
koma-script
amsmath
bookmark
booktabs
csquotes
hyperref
multirow
paralist
preprint
realscripts
textpos
unicode-math
units
xecjk
xecolor
xltxtra
xtab
;
};
};
}

View file

@ -0,0 +1,10 @@
{ ... }: { config, lib, pkgs, ... }@args:
let
osConfig = args.osConfig or { };
in lib.mkIf (osConfig.hardware.graphics.enable or false) {
programs.thunderbird = {
enable = true;
package = pkgs.thunderbird;
profiles = { };
};
}

View file

@ -1,855 +0,0 @@
{ ... }: { config, lib, pkgs, ... }@args:
let
osConfig = args.osConfig or { };
fira-code-features = [
"cv01"
"cv06"
"onum"
"ss01"
"ss03"
"ss06"
"ss07"
"ss08"
"zero"
];
cmd = {
brightnessctl = "${pkgs.brightnessctl}/bin/brightnessctl";
fish = "${osConfig.programs.fish.package}/bin/fish";
fuzzel = "${config.programs.fuzzel.package}/bin/fuzzel";
grim = "${pkgs.grim}/bin/grim -l 9";
jq = "${config.programs.jq.package}/bin/jq";
keepassxc = "${pkgs.keepassxc}/bin/keepassxc";
kill = "${pkgs.procps}/bin/kill";
kitty = ''${config.programs.kitty.package}/bin/kitty --single-instance --instance-group "$XDG_SESSION_ID"'';
loginctl = "${osConfig.systemd.package}/bin/loginctl";
mdless = "${pkgs.mdcat}/bin/mdless";
mpv = "${config.programs.mpv.package}/bin/mpv";
pidof = "${pkgs.procps}/bin/pidof";
playerctl = "${pkgs.playerctl}/bin/playerctl";
pwvucontrol = "${pkgs.pwvucontrol}/bin/pwvucontrol";
slurp = "${pkgs.slurp}/bin/slurp";
swaylock = "${config.programs.swaylock.package}/bin/swaylock";
waybar = "${config.programs.waybar.package}/bin/waybar";
wl-copy = "${pkgs.wl-clipboard}/bin/wl-copy";
wpctl = "${osConfig.services.pipewire.wireplumber.package}/bin/wpctl";
xargs = "${pkgs.findutils}/bin/xargs";
xdg-open = "${pkgs.xdg-utils}/bin/xdg-open";
};
in lib.mkIf (osConfig.hardware.graphics.enable or false) {
fonts.fontconfig = {
enable = true;
defaultFonts = {
sansSerif = [
"Lato"
"M PLUS 1"
"Noto Sans"
"Symbols Nerd Font"
"Unifont"
"Unifont Upper"
];
serif = [ "Noto Serif"];
monospace = [
"Fira Code"
"M PLUS 1 Code"
"Noto Sans Mono"
"Symbols Nerd Font Mono"
];
emoji = [ "Noto Color Emoji" ];
};
};
home.file.".xkb/symbols/greedy".source = ./greedy.xkb;
home.keyboard = {
layout = "greedy";
options = [ "ctrl:nocaps" ];
};
home.packages = with pkgs; [
# Founts
lato
fira-code
mplus-outline-fonts.githubRelease
(nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; })
noto-fonts
noto-fonts-color-emoji
unifont
# Image processing
oxipng
# Documentation
linux-manual
man-pages
man-pages-posix
# System operations
restic
# Cryptography
rage
# Messaging
fractal
signal-desktop
# Audio control
pwvucontrol
inkscape
obsidian
kicad
calibre
keepassxc
# Multimedia
jellyfin-mpv-shim
libreoffice
];
programs.beets = {
enable = true;
settings = {
directory = "~/msc";
import.reflink = "auto";
plugins = [
"chroma"
"spotify"
"fromfilename"
"fetchart"
"lyrics"
"replaygain"
"duplicates"
"hook"
];
hook.hooks = [
{
event = "import";
command = "systemctl --user start mopidy-scan.service";
}
];
};
};
programs.eza.extraOptions = lib.mkAfter [ "--hyperlink" ];
programs.fuzzel = {
enable = true;
};
programs.imv.enable = true;
programs.kitty = {
enable = true;
theme = "Catppuccin-Mocha";
settings = {
disable_ligatures = "cursor";
cursor_blink_interval = 0;
scrollback_lines = 65536;
scrollback_fill_enlarged_window = true;
enable_audio_bell = false;
close_on_child_death = true;
clear_all_shortcuts = true;
# Mouse
click_interval = "0.2";
};
keybindings = {
"ctrl+shift+c" = "copy_to_clipboard";
"ctrl+shift+v" = "paste_from_clipboard";
"ctrl+shift+s" = "paste_from_selection";
"shift+insert" = "paste_from_selection";
"ctrl+up" = "scroll_line_up";
"ctrl+down" = "scroll_line_down";
"ctrl+page_up" = "scroll_page_up";
"ctrl+page_down" = "scroll_page_down";
"shift+page_up" = "scroll_page_up";
"shift+page_down" = "scroll_page_down";
"ctrl+home" = "scroll_home";
"ctrl+end" = "scroll_end";
"ctrl+print_screen" = "show_scrollback";
"ctrl+equal" = "change_font_size all 0";
"ctrl+plus" = "change_font_size all +1";
"ctrl+minus" = "change_font_size all -1";
"ctrl+shift+u" = "kitten unicode_input";
};
extraConfig = let
mouse = {
"left click ungrabbed" = "mouse_handle_click selection prompt";
"ctrl+left click ungrabbed" = "mouse_handle_click link";
"left press ungrabbed" = "mouse_selection normal";
"shift+left press ungrabbed" = "mouse_selection line";
"ctrl+left press ungrabbed" = "mouse_selection rectangle";
"left doublepress ungrabbed" = "mouse_selection word";
"left triplepress ungrabbed" = " mouse_selection line";
} |> lib.mapAttrsToList (n: v: "mouse_map ${n} ${v}\n")
|> lib.concatStrings;
in ''
clear_all_mouse_actions yes
${mouse}
'';
};
programs.mpv = {
enable = true;
defaultProfiles = [ "high-quality" ];
config = {
#access-references = false;
# Video output
vo = "gpu";
#gpu-api = "vulkan";
hwdec = "vulkan,vaapi,auto-safe";
vd-lavc-dr = true;
scale = "ewa_lanczos4sharpest";
cscale = "spline64";
dscale = "mitchell";
tscale = "oversample";
# A/V sync
video-sync = "display-resample";
interpolation = true;
# Audio
volume = 100;
volume-max = 100;
# Subtitles
sub-auto = "fuzzy";
# Screenshots
screenshot-format = "avif";
# Cache
demuxer-max-bytes = "768MiB";
demuxer-max-back-bytes = "256MiB";
};
profiles = {
highres = {
scale = "spline64";
};
};
scripts = with pkgs.mpvScripts; [
mpris
autocrop
autodeint
];
scriptOpts = {
autocrop.auto = false;
};
};
programs.niri = {
settings = {
prefer-no-csd = true;
input = {
keyboard = {
xkb = with config.home.keyboard; {
inherit layout;
options = lib.concatStringsSep "," options;
};
};
focus-follows-mouse.enable = true;
touchpad = {
dwt = true;
dwtp = true;
};
};
outputs = {
eDP-1 = {
scale = 1;
variable-refresh-rate = true;
};
DP-6 = {
mode = { width = 5120; height = 2160; };
scale = 1;
position = { x = 0; y = 0; };
variable-refresh-rate = true;
};
};
layout = {
border.enable = lib.mkForce false;
focus-ring = {
enable = true;
width = 1;
};
default-column-width.proportion = 1. / 3.;
gaps = 5;
preset-column-widths = [
{ proportion = 1. / 3.; }
{ proportion = 1. / 2.; }
{ proportion = 2. / 3.; }
];
};
binds = with config.lib.niri.actions; with cmd; lib.mkOptionDefault {
"Mod+Return".action = spawn "kitty";
"Mod+Shift+Return".action = spawn "${kitty} fish --private";
"Mod+e".action = spawn "${fuzzel}";
"Mod+Up".action = focus-window-or-workspace-up;
"Mod+Down".action = focus-window-or-workspace-down;
"Mod+Left".action = focus-column-left;
"Mod+Right".action = focus-column-right;
"Mod+Ctrl+Up".action = move-window-up-or-to-workspace-up;
"Mod+Ctrl+Down".action = move-window-up-or-to-workspace-up;
"Mod+Ctrl+Left".action = move-column-left;
"Mod+Ctrl+Right".action = move-column-right;
"Mod+WheelScrollUp".action = focus-window-up-or-column-left;
"Mod+WheelScrollDown".action = focus-window-down-or-column-right;
"Mod+g".action = consume-window-into-column;
"Mod+b".action = expel-window-from-column;
};
};
};
programs.sioyek = {
enable = true;
bindings = {
"command" = "-";
"move_up" = [ "<up>" "t" ];
"move_down" = [ "<down>" "n" ];
"move_left" = [ "<right>" "h" ];
"move_right" = [ "<left>" "r" ];
};
};
programs.swaylock = {
enable = true;
package = pkgs.swaylock-effects;
settings = {
screenshots = true;
effect-blur = "5x3";
grace = 2;
};
};
programs.texlive = {
enable = true;
extraPackages = tpkgs: {
inherit (tpkgs)
texlive-scripts
xelatex-dev
fontspec
polyglossia
hyphen-english
hyphen-french
hyphen-german
hyphen-portuguese
hyphen-spanish
koma-script
amsmath
bookmark
booktabs
csquotes
hyperref
multirow
paralist
preprint
realscripts
textpos
unicode-math
units
xecjk
xecolor
xltxtra
xtab
;
};
};
programs.thunderbird = {
enable = true;
package = pkgs.thunderbird;
profiles = { };
};
programs.tofi = {
enable = true;
settings = {
history = true;
fuzzy-match = true;
num-results = 8;
font = pkgs.runCommand "fount-path" {
preferLocal = true;
nativeBuildInputs = with pkgs; [ fontconfig fira-code ];
} ''
fc-match -f "%{file}" "Fira Code" >"$out"
'' |> builtins.readFile |> lib.mkForce;
font-size = lib.mkForce 14;
font-features = fira-code-features |> lib.concatStringsSep ",";
font-variations = "wght 450";
font-hint = true;
anchor = "top";
horizontal = true;
width = "100%";
height = 30;
min-input-width = 120;
result-spacing = 20;
border-width = 0;
outline-width = 0;
padding-top = 4;
padding-bottom = 4;
padding-left = 12;
padding-right = 12;
};
};
programs.waybar = {
enable = true;
package = pkgs.waybar.override {
cavaSupport = false;
hyprlandSupport = false;
jackSupport = false;
mpdSupport = false;
sndioSupport = false;
};
settings = {
main = {
layer = "top";
position = "bottom";
modules-left = [
"tray"
];
modules-center = [ ];
modules-right = [
"network#down"
"network#up"
"bluetooth"
"cpu"
"memory"
"memory#swap"
"temperature"
"disk"
"battery"
"idle_inhibitor"
"backlight"
"mpris"
"pulseaudio#sink"
"pulseaudio#source"
"clock"
];
ipc = true;
"network#down" = {
format = "󰅀 {bandwidthDownBytes}";
};
"network#up" = {
format = "󰅃 {bandwidthUpBytes}";
};
bluetooth = {
format-connected-battery = "󰂯 {device_battery_percentage}%";
tooltip-format-connected-battery = "{device_enumerate}";
tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_battery_percentage}%";
};
cpu = {
format = " {usage}%";
};
memory = {
format = " {percentage}%";
tooltip-format = "{used:0.1f}/{total:0.1f}GiB";
};
"memory#swap" = {
format = " {swapPercentage}%";
tooltip-format = "{swapUsed:0.1f}/{swapTotal:0.1f}GiB";
};
temperature = let
fmt = "{temperatureC}°C";
in {
format = "󰔏 ${fmt}";
format-critical = "󰸁 ${fmt}";
tooltip-format = fmt;
};
disk = {
format = " {percentage_used}%";
path = "/home";
tooltip-format = "{used}/{total}";
};
idle_inhibitor = {
format = "{icon}";
format-icons = {
activated = "󱎴";
deactivated = "󰷛";
};
timeout = 15.0;
};
battery = let
fmt = "{capacity}%";
dis = {
"5" = "󱃍";
"10" = "󰁺";
"20" = "󰁻";
"30" = "󰁼";
"40" = "󰁽";
"50" = "󰁿";
"60" = "󰁿";
"70" = "󰂀";
"80" = "󰂁";
"90" = "󰂂";
"100" = "󰁹";
};
chr = {
"5" = "󰢟";
"10" = "󰢜";
"20" = "󰂆";
"30" = "󰂇";
"40" = "󰂈";
"50" = "󰢝";
"60" = "󰂉";
"70" = "󰢞";
"80" = "󰂊";
"90" = "󰂋";
"100" = "󰂅";
};
in {
states = {
"5" = 5;
"10" = 10;
"20" = 20;
"30" = 30;
"40" = 40;
"50" = 50;
"60" = 60;
"70" = 70;
"80" = 80;
"90" = 90;
"100" = 100;
};
format-full = "󰚥 ${fmt}";
format-time = "{H}:{M}";
weighted-average = true;
}
// lib.mapAttrs' (state: icon: {
name = "format-discharging-${state}";
value = "${icon} ${fmt}";
}) dis
// lib.mapAttrs' (state: icon: {
name = "format-charging-${state}";
value = "${icon} ${fmt}";
}) chr;
backlight = {
format = " {percent}%";
on-scroll-up = with cmd; "${brightnessctl} s +1%";
on-scroll-down = with cmd; "${brightnessctl} s 1%-";
};
mpris = {
format = "{status}";
status-icons = {
playing = "";
paused = "";
stopped = "";
};
};
"pulseaudio#sink" = let
fmt = "{volume}%";
in {
format = "{icon} ${fmt}";
format-bluetooth = "󰂰 ${fmt}";
format-muted = " ${fmt}";
format-icons = {
headphone = "";
default = [ "" "" ];
};
format-source = "󰍬 ${fmt}";
format-source-muted = "󰍭 ${fmt}";
on-click = cmd.pwvucontrol;
on-click-right = with cmd; "${wpctl} set-mute @DEFAULT_AUDIO_SINK@ toggle";
on-scroll-up = with cmd; "${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 1%+";
on-scroll-down = with cmd; "${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 1%-";
};
"pulseaudio#source" = let
fmt = "{volume}%";
in {
format = "{format_source}";
format-source = "󰍬 ${fmt}";
format-source-muted = "󰍭 ${fmt}";
on-click = cmd.pwvucontrol;
on-click-right = with cmd; "${wpctl} set-mute @DEFAULT_AUDIO_SOURCE@ toggle";
on-scroll-up = with cmd; "${wpctl} set-volume @DEFAULT_AUDIO_SOURCE@ 1%+";
on-scroll-down = with cmd; "${wpctl} set-volume @DEFAULT_AUDIO_SOURCE@ 1%-";
};
clock = {
format = " {:%H:%M %Z}";
format-alt = "󰃭 {:%Y-%m-%d}";
tooltip-format = "<tt><small>{calendar}</small></tt>";
calendar = {
mode = "month";
weeks-pos = "left";
on-scroll = 1;
format = {
weeks = "{:%W}";
};
};
};
};
};
};
programs.yt-dlp.enable = true;
services.gammastep = lib.optionalAttrs (osConfig ? location) (
let inherit (osConfig) location; in {
inherit (location) provider;
enable = true;
settings = {
general.adjustment-method = "wayland";
};
} // lib.optionalAttrs (location.provider == "manual") {
#inherit (location) latitude longitude;
});
services.mako = {
enable = true;
defaultTimeout = 5000;
};
services.mopidy = {
enable = true;
extensionPackages = with pkgs; [
mopidy-iris
mopidy-local
mopidy-mpd
mopidy-mpris
];
settings = {
core = {
cache_dir = "$XDG_CACHE_DIR/mopidy";
config_dir = "$XDG_CONFIG_DIR/mopidy";
data_dir = "$XDG_DATA_DIR/mopidy";
};
audio.mixer = "none";
file.media_dirs = [ "$XDG_MUSIC_DIR" ];
local.media_dir = "$XDG_MUSIC_DIR";
mpd.hostname = "localhost";
http = {
hostname = "localhost";
port = 6680;
default_app = "iris";
};
};
};
services.swayidle = {
enable = true;
events = with cmd; [
{ event = "lock"; command = "${swaylock} -f"; }
{ event = "before-sleep"; command = "${loginctl} lock-session"; }
];
timeouts = with cmd; [
{
timeout = 210;
command = "${brightnessctl} --save -e set 20%-";
resumeCommand = "${brightnessctl} --restore";
}
{
timeout = 240;
command = "${loginctl} lock-session";
}
];
};
services.syncthing = {
enable = true;
tray.enable = true;
};
services.udiskie = {
enable = true;
automount = false;
};
stylix = {
enable = true;
image = ./wallpaper.png;
base16Scheme = "${pkgs.base16-schemes}/share/themes/catppuccin-macchiato.yaml";
polarity = "dark";
opacity = {
applications = 0.98;
desktop = 0.98;
popups = 0.99;
terminal = 0.98;
};
fonts = {
sansSerif = {
package = pkgs.lato;
name = "sans-serif";
};
serif = {
package = pkgs.noto-fonts;
name = "serif";
};
monospace = {
package = pkgs.fira-code;
name = "monospace";
};
emoji = {
package = pkgs.noto-fonts-color-emoji;
name = "emoji";
};
sizes = {
terminal = 11;
};
};
};
systemd.user.services = lib.genAttrs [ "syncthing" ] (service: {
Unit = {
ConditionACPower = true;
StopPropagatedFrom = [ "power-external.target" ];
};
});
xdg.configFile."fontconfig/conf.d/80-fira-code.conf".text = ''
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'urn:fontconfig:fonts.dtd'>
<fontconfig>
<match target="font">
<test name="family" compare="eq" ignore-blanks="true">
<string>Fira Code</string>
</test>
<edit name="fontfeatures" mode="append">
${fira-code-features
|> map (tag: "<string>${lib.escapeXML tag}</string>")
|> lib.concatStrings}
</edit>
</match>
</fontconfig>
'';
xdg.configFile."kitty/open-actions.conf".text = with cmd; ''
protocol file
mime image/*
action launch --type overlay kitten icat --hold -- "$FILE_PATH"
protocol file
mime text/markdown
action launch --type overlay ${mdless} -- "$FILE_PATH"
protocol file
mime text/*
action launch --type overlay $EDITOR -- "$FILE_PATH"
protocol file
mime video/*
action launch --type background ${mpv} -- "$FILE_PATH"
protocol file
mime audio/*
action launch --type overlay ${mpv} -- "$FILE_PATH"
protocol
action launch --type background ${xdg-open} "$FILE_PATH"
'';
xdg.desktopEntries = {
kitty = {
name = "kitty";
exec = builtins.replaceStrings [ "$" ] [ ''\\$'' ] cmd.kitty;
};
};
xdg.mimeApps = {
enable = true;
defaultApplications = {
"default-web-browser" = [ "firefox.desktop" ];
"application/pdf" = [ "sioyek.desktop" ];
};
};
xdg.portal = {
enable = true;
config.common.default = [ "wlr" "gtk" ];
extraPortals = with pkgs; [
xdg-desktop-portal-wlr
(xdg-desktop-portal-gtk.override { buildPortalsInGnome = false; })
];
};
}