+16
.gitignore
+16
.gitignore
+4
README.md
+4
README.md
+39
config/theme.nix
+39
config/theme.nix
···
1
+
# hex codes for atom one dark pro colorscheme
2
+
# from helix onedark theme
3
+
{
4
+
colors = rec {
5
+
yellow = "E5C07B";
6
+
blue = "61AFEF";
7
+
red = "E06C75";
8
+
purple = "C678DD";
9
+
green = "98C379";
10
+
gold = "D19A66";
11
+
cyan = "56B6C2";
12
+
white = "ABB2BF";
13
+
black = "282C34";
14
+
light-black = "2C323C";
15
+
gray = "3E4452";
16
+
faint-gray = "3B4048";
17
+
light-gray = "5C6370";
18
+
linenr = "4B5263";
19
+
20
+
darker = "20252C";
21
+
22
+
bg-darker = darker;
23
+
bg-regular = black;
24
+
bg-light = light-black;
25
+
fg-regular = white;
26
+
fg-dim = light-gray;
27
+
};
28
+
29
+
# in px
30
+
lengths = {
31
+
font-lg = "14";
32
+
font-md = "12";
33
+
font-sm = "10";
34
+
border-radius = "8";
35
+
border-width = "2";
36
+
margin = "8";
37
+
padding = "8";
38
+
};
39
+
}
+44
flake.lock
+44
flake.lock
···
1
+
{
2
+
"nodes": {
3
+
"hardware": {
4
+
"locked": {
5
+
"lastModified": 1754564048,
6
+
"narHash": "sha256-dz303vGuzWjzOPOaYkS9xSW+B93PSAJxvBd6CambXVA=",
7
+
"owner": "nixos",
8
+
"repo": "nixos-hardware",
9
+
"rev": "26ed7a0d4b8741fe1ef1ee6fa64453ca056ce113",
10
+
"type": "github"
11
+
},
12
+
"original": {
13
+
"owner": "nixos",
14
+
"ref": "master",
15
+
"repo": "nixos-hardware",
16
+
"type": "github"
17
+
}
18
+
},
19
+
"nixpkgs": {
20
+
"locked": {
21
+
"lastModified": 1754725699,
22
+
"narHash": "sha256-iAcj9T/Y+3DBy2J0N+yF9XQQQ8IEb5swLFzs23CdP88=",
23
+
"owner": "nixos",
24
+
"repo": "nixpkgs",
25
+
"rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054",
26
+
"type": "github"
27
+
},
28
+
"original": {
29
+
"owner": "nixos",
30
+
"ref": "nixos-unstable",
31
+
"repo": "nixpkgs",
32
+
"type": "github"
33
+
}
34
+
},
35
+
"root": {
36
+
"inputs": {
37
+
"hardware": "hardware",
38
+
"nixpkgs": "nixpkgs"
39
+
}
40
+
}
41
+
},
42
+
"root": "root",
43
+
"version": 7
44
+
}
+52
flake.nix
+52
flake.nix
···
1
+
{
2
+
description = "Asa's personal NixOS configuration";
3
+
4
+
inputs = {
5
+
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
6
+
7
+
hardware.url = "github:nixos/nixos-hardware/master";
8
+
};
9
+
10
+
outputs =
11
+
{
12
+
nixpkgs,
13
+
hardware,
14
+
...
15
+
}@inputs:
16
+
let
17
+
forAllSystems =
18
+
function:
19
+
nixpkgs.lib.genAttrs [
20
+
"x86_64-linux" # <- useful
21
+
"aarch64-linux" # <- aspirational
22
+
# "risc64-linux" # <- aspirational
23
+
"aarch64-darwin" # <- useless
24
+
] (system: function nixpkgs.legacyPackages.${system});
25
+
in
26
+
rec {
27
+
nixosConfigurations.asa-fw = nixpkgs.lib.nixosSystem {
28
+
system = "x86_64-linux";
29
+
specialArgs = {
30
+
inherit inputs;
31
+
packages = packages."x86_64-linux";
32
+
};
33
+
modules = [
34
+
modules/system.nix
35
+
modules/desktop.nix
36
+
modules/apps.nix
37
+
modules/fonts.nix
38
+
modules/networking.nix
39
+
modules/audio.nix
40
+
modules/dev.nix
41
+
hardware/fw-13.nix
42
+
hardware.nixosModules.framework-13-7040-amd
43
+
];
44
+
};
45
+
46
+
packages = forAllSystems (pkgs: import ./programs { inherit pkgs; });
47
+
48
+
devShells = forAllSystems (pkgs: pkgs.nil);
49
+
50
+
formatter = forAllSystems (pkgs: pkgs.nixfmt-tree);
51
+
};
52
+
}
+53
hardware/fw-13.nix
+53
hardware/fw-13.nix
···
1
+
# Do not modify this file! It was generated by ‘nixos-generate-config’
2
+
# and may be overwritten by future invocations. Please make changes
3
+
# to /etc/nixos/configuration.nix instead.
4
+
{
5
+
config,
6
+
lib,
7
+
pkgs,
8
+
modulesPath,
9
+
...
10
+
}:
11
+
12
+
{
13
+
imports = [
14
+
(modulesPath + "/installer/scan/not-detected.nix")
15
+
];
16
+
17
+
boot.initrd.availableKernelModules = [
18
+
"nvme"
19
+
"xhci_pci"
20
+
"thunderbolt"
21
+
"usb_storage"
22
+
"sd_mod"
23
+
];
24
+
boot.initrd.kernelModules = [ ];
25
+
boot.kernelModules = [ "kvm-amd" ];
26
+
boot.extraModulePackages = [ ];
27
+
28
+
fileSystems."/" = {
29
+
device = "/dev/disk/by-uuid/5180e190-2e04-4a59-ae1e-1c7c5694960d";
30
+
fsType = "btrfs";
31
+
};
32
+
33
+
fileSystems."/boot" = {
34
+
device = "/dev/disk/by-uuid/3AD6-FBA1";
35
+
fsType = "vfat";
36
+
options = [
37
+
"fmask=0077"
38
+
"dmask=0077"
39
+
];
40
+
};
41
+
42
+
swapDevices = [ ];
43
+
44
+
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
45
+
# (the default) this is the recommended approach. When using systemd-networkd it's
46
+
# still possible to use this option, but it's recommended to use it in conjunction
47
+
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
48
+
networking.useDHCP = lib.mkDefault true;
49
+
# networking.interfaces.wlp1s0.useDHCP = lib.mkDefault true;
50
+
51
+
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
52
+
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
53
+
}
+97
modules/apps.nix
+97
modules/apps.nix
···
1
+
{
2
+
pkgs,
3
+
packages,
4
+
...
5
+
}:
6
+
{
7
+
services.flatpak.enable = true;
8
+
9
+
xdg.portal = {
10
+
enable = true;
11
+
xdgOpenUsePortal = true;
12
+
extraPortals = with pkgs; [
13
+
xdg-desktop-portal-gtk
14
+
xdg-desktop-portal-gnome
15
+
];
16
+
};
17
+
18
+
# default handlers
19
+
xdg.terminal-exec = {
20
+
enable = true;
21
+
settings = {
22
+
default = [ "com.mitchellh.ghostty.desktop" ];
23
+
};
24
+
};
25
+
26
+
xdg.mime.defaultApplications = {
27
+
"x-scheme-handler/http" = "org.mozilla.firefox.desktop";
28
+
"x-scheme-handler/https" = "org.mozilla.firefox.desktop";
29
+
"x-scheme-handler/ftp" = "org.mozilla.firefox.desktop";
30
+
"x-scheme-handler/mailto" = "org.mozilla.thunderbird.desktop";
31
+
"text/plain" = "Helix.desktop";
32
+
"application/pdf" = "org.mozilla.firefox.desktop";
33
+
# "image/png" = [
34
+
# "sxiv.desktop"
35
+
# "gimp.desktop"
36
+
# ];
37
+
};
38
+
39
+
# set up chromium config for pwas
40
+
programs.chromium = {
41
+
enable = true;
42
+
extensions = [
43
+
"cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin
44
+
];
45
+
extraOpts = {
46
+
"BrowserSignin" = 0;
47
+
"SyncDisabled" = true;
48
+
"PasswordManagerEnabled" = false;
49
+
"SpellcheckEnabled" = true;
50
+
"SpellcheckLanguage" = [ "en-US" ];
51
+
};
52
+
};
53
+
54
+
# Tell electron apps / chromium to use wayland
55
+
environment.sessionVariables.NIXOS_OZONE_WL = "1";
56
+
57
+
# List packages installed in system profile. To search, run:
58
+
# $ nix search wget
59
+
users.users.asa.packages = with pkgs; [
60
+
packages.ghostty-wrapped
61
+
packages.helix-wrapped
62
+
packages.mako-wrapped
63
+
packages.fuzzel-wrapped
64
+
wl-clipboard
65
+
# delete later
66
+
xwayland-satellite
67
+
68
+
yazi
69
+
wget
70
+
docker-compose
71
+
ungoogled-chromium
72
+
73
+
alacritty
74
+
75
+
# utilities
76
+
zip
77
+
unzip
78
+
zathura
79
+
btop
80
+
81
+
# vpn stuff
82
+
networkmanager-openconnect
83
+
globalprotect-openconnect
84
+
85
+
# stuff that should be wrapped with helix
86
+
nixd
87
+
pyright
88
+
rust-analyzer
89
+
llvmPackages_19.clang-tools
90
+
nixfmt-rfc-style
91
+
92
+
# gnome core apps
93
+
adwaita-icon-theme
94
+
nautilus
95
+
];
96
+
97
+
}
+9
modules/audio.nix
+9
modules/audio.nix
+45
modules/desktop.nix
+45
modules/desktop.nix
···
1
+
{
2
+
lib,
3
+
pkgs,
4
+
packages,
5
+
...
6
+
}:
7
+
{
8
+
systemd.user.services = {
9
+
swayidle = {
10
+
enable = true;
11
+
unitConfig = {
12
+
PartOf = "graphical-session.target";
13
+
After = "graphical-session.target";
14
+
Requisite = "graphical-session.target";
15
+
};
16
+
wantedBy = [ "graphical-session.target" ];
17
+
serviceConfig = {
18
+
ExecStart = "${lib.getExe pkgs.swayidle} -w timeout 300 '${lib.getExe pkgs.niri} msg action power-off-monitors' timeout 300 '${lib.getExe packages.swaylock-wrapped} -f' before-sleep '${lib.getExe packages.swaylock-wrapped} -f'";
19
+
Restart = "on-failure";
20
+
};
21
+
};
22
+
};
23
+
24
+
programs.niri = {
25
+
enable = true;
26
+
package = packages.niri-wrapped;
27
+
};
28
+
29
+
programs.waybar = {
30
+
enable = true;
31
+
package = packages.waybar-wrapped;
32
+
};
33
+
34
+
services.greetd = {
35
+
enable = true;
36
+
settings = {
37
+
default_session = {
38
+
command = "${lib.getExe pkgs.tuigreet} --time --cmd 'bash -l -c ${lib.getExe' packages.niri-wrapped "niri-session"}'";
39
+
user = "greeter";
40
+
};
41
+
};
42
+
};
43
+
44
+
services.libinput.enable = true;
45
+
}
+44
modules/dev.nix
+44
modules/dev.nix
···
1
+
{ ... }:
2
+
{
3
+
programs.git = {
4
+
enable = true;
5
+
config = {
6
+
init.defaultBranch = "main";
7
+
user.email = "asapaparo@gmail.com";
8
+
user.name = "Asa Paparo";
9
+
};
10
+
};
11
+
12
+
# programs.ssh.startAgent = true;
13
+
programs.ssh.extraConfig = "SetEnv TERM=xterm-256color";
14
+
15
+
virtualisation.containers.enable = true;
16
+
# virtualisation.docker.enable = true;
17
+
18
+
virtualisation.podman = {
19
+
enable = true;
20
+
dockerCompat = true;
21
+
dockerSocket.enable = true;
22
+
};
23
+
24
+
# Enable direnv
25
+
programs.direnv.enable = true;
26
+
27
+
# Configure helix for editor and viewing functionality
28
+
environment.variables = {
29
+
EDITOR = "hx";
30
+
VISUAL = "hx";
31
+
};
32
+
33
+
# Set up local llms
34
+
services.ollama = {
35
+
enable = true;
36
+
# radeon 780M igpu = gfx1103
37
+
# gfx1100 is closest working target
38
+
rocmOverrideGfx = "11.0.0";
39
+
acceleration = "rocm";
40
+
# loadModels = [
41
+
# "gemma3n:latest"
42
+
# ];
43
+
};
44
+
}
+67
modules/fonts.nix
+67
modules/fonts.nix
···
1
+
{
2
+
pkgs,
3
+
...
4
+
}:
5
+
{
6
+
fonts.packages = with pkgs; [
7
+
inter
8
+
jetbrains-mono
9
+
nerd-fonts.jetbrains-mono
10
+
noto-fonts
11
+
noto-fonts-cjk-sans
12
+
noto-fonts-color-emoji
13
+
noto-fonts-monochrome-emoji
14
+
font-awesome
15
+
];
16
+
17
+
fonts.fontconfig = {
18
+
enable = true;
19
+
hinting.enable = true;
20
+
defaultFonts = {
21
+
sansSerif = [
22
+
"Inter"
23
+
"Noto Sans"
24
+
"Noto Sans CJK SC"
25
+
"Noto Sans CJK TC"
26
+
"Noto Sans CJK JP"
27
+
"Noto Sans CJK KR"
28
+
"Noto Sans Devanagari"
29
+
"Noto Sans Arabic"
30
+
"Liberation Sans"
31
+
"DejaVu Sans"
32
+
];
33
+
34
+
serif = [
35
+
"Noto Serif"
36
+
"Noto Serif CJK SC"
37
+
"Noto Serif CJK TC"
38
+
"Noto Serif CJK JP"
39
+
"Noto Serif CJK KR"
40
+
"Noto Serif Devanagari"
41
+
"Noto Serif Arabic"
42
+
"Liberation Serif"
43
+
"DejaVu Serif"
44
+
];
45
+
46
+
monospace = [
47
+
"JetBrains Mono"
48
+
"Noto Sans Mono"
49
+
"Noto Sans Mono CJK SC"
50
+
"Noto Sans Mono CJK TC"
51
+
"Noto Sans Mono CJK JP"
52
+
"Noto Sans Mono CJK KR"
53
+
"Liberation Mono"
54
+
"DejaVu Sans Mono"
55
+
];
56
+
57
+
emoji = [
58
+
"Noto Color Emoji"
59
+
];
60
+
};
61
+
};
62
+
63
+
console = {
64
+
font = "Lat2-Terminus16";
65
+
useXkbConfig = true; # use xkb.options in tty.
66
+
};
67
+
}
+27
modules/networking.nix
+27
modules/networking.nix
···
1
+
{
2
+
...
3
+
}:
4
+
{
5
+
networking.hostName = "asa-fw"; # Define your hostname.
6
+
# Pick only one of the below networking options.
7
+
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
8
+
networking.networkmanager = {
9
+
enable = true;
10
+
wifi.backend = "wpa_supplicant";
11
+
};
12
+
programs.nm-applet.enable = true; # cursed wifi widget
13
+
14
+
# networking.firewall = {
15
+
# enable = true;
16
+
# allowedUDPPorts = [11311];
17
+
# };
18
+
19
+
# Enable CUPS to print documents.
20
+
# services.printing.enable = true;
21
+
22
+
# services.avahi = {
23
+
# enable = true;
24
+
# nssmdns4 = true;
25
+
# openFirewall = true;
26
+
# };
27
+
}
+80
modules/system.nix
+80
modules/system.nix
···
1
+
{
2
+
...
3
+
}:
4
+
5
+
{
6
+
nix.settings.trusted-users = [
7
+
"root"
8
+
"@wheel"
9
+
];
10
+
11
+
# Use the systemd-boot EFI boot loader.
12
+
boot.loader.systemd-boot = {
13
+
enable = true;
14
+
configurationLimit = 10;
15
+
};
16
+
boot.loader.efi.canTouchEfiVariables = true;
17
+
18
+
# Set your time zone.
19
+
time.timeZone = "America/New_York";
20
+
21
+
# why is this needed again?
22
+
systemd.user.extraConfig = ''
23
+
DefaultEnvironment="PATH=/run/current-system/sw/bin"
24
+
'';
25
+
26
+
# latest (not lts) kernel?
27
+
# boot.kernelPackages = pkgs.linuxPackages_latest;
28
+
29
+
programs.nh = {
30
+
enable = true;
31
+
clean.enable = true;
32
+
clean.extraArgs = "--keep-since 4d --keep 3";
33
+
flake = "/home/asa/system";
34
+
};
35
+
36
+
# Select internationalisation properties.
37
+
i18n.defaultLocale = "en_US.UTF-8";
38
+
39
+
nix.settings.experimental-features = [
40
+
"nix-command"
41
+
"flakes"
42
+
];
43
+
44
+
# For framework
45
+
services.fwupd.enable = true;
46
+
47
+
# Define a user account. Don't forget to set a password with ‘passwd’.
48
+
users.users.asa = {
49
+
isNormalUser = true;
50
+
extraGroups = [
51
+
"wheel"
52
+
"networkmanager"
53
+
"video"
54
+
"kvm"
55
+
"dialout"
56
+
];
57
+
};
58
+
59
+
hardware.graphics.enable = true;
60
+
61
+
# This option defines the first version of NixOS you have installed on this particular machine,
62
+
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
63
+
#
64
+
# Most users should NEVER change this value after the initial install, for any reason,
65
+
# even if you've upgraded your system to a new NixOS release.
66
+
#
67
+
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
68
+
# so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
69
+
# to actually do that.
70
+
#
71
+
# This value being lower than the current NixOS release does NOT mean your system is
72
+
# out of date, out of support, or vulnerable.
73
+
#
74
+
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
75
+
# and migrated your data accordingly.
76
+
#
77
+
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
78
+
system.stateVersion = "24.11"; # Did you read the comment?
79
+
80
+
}
+24
programs/default.nix
+24
programs/default.nix
···
1
+
{ pkgs }:
2
+
pkgs.lib.fix (
3
+
self:
4
+
let
5
+
callPackage = pkgs.lib.callPackageWith (
6
+
pkgs
7
+
// self
8
+
// {
9
+
mkWrapper = import ../utils/wrap.nix pkgs;
10
+
theme = import ../config/theme.nix;
11
+
}
12
+
);
13
+
allFiles = builtins.attrNames (builtins.readDir ./.);
14
+
packageFiles = builtins.filter (
15
+
file: pkgs.lib.hasSuffix ".nix" file && file != "default.nix"
16
+
) allFiles;
17
+
in
18
+
builtins.listToAttrs (
19
+
map (file: {
20
+
name = pkgs.lib.removeSuffix ".nix" file;
21
+
value = callPackage ./${file} { };
22
+
}) packageFiles
23
+
)
24
+
)
+48
programs/fuzzel-wrapped.nix
+48
programs/fuzzel-wrapped.nix
···
1
+
{
2
+
pkgs,
3
+
lib,
4
+
mkWrapper,
5
+
theme,
6
+
fuzzel,
7
+
ghostty-wrapped,
8
+
}:
9
+
let
10
+
cfg = pkgs.writeText "config.ini" ''
11
+
font=sans-serif:size=${theme.lengths.font-lg}
12
+
use-bold=true
13
+
dpi-aware=auto
14
+
placeholder="system search..."
15
+
prompt=""
16
+
terminal="${lib.getExe ghostty-wrapped} -e"
17
+
18
+
lines=12
19
+
width=24
20
+
21
+
horizontal-pad=16
22
+
vertical-pad=${theme.lengths.padding}
23
+
inner-pad=${theme.lengths.padding}
24
+
25
+
[colors]
26
+
background=${theme.colors.bg-darker}FF
27
+
text=${theme.colors.fg-dim}FF
28
+
prompt=${theme.colors.fg-dim}FF
29
+
placeholder=${theme.colors.fg-dim}FF
30
+
input=${theme.colors.fg-regular}FF
31
+
match=${theme.colors.fg-regular}FF
32
+
selection=${theme.colors.bg-regular}FF
33
+
selection-text=${theme.colors.fg-regular}FF
34
+
selection-match=${theme.colors.fg-regular}FF
35
+
border=${theme.colors.cyan}FF
36
+
37
+
[border]
38
+
width=${theme.lengths.border-width}
39
+
radius=${theme.lengths.border-radius}
40
+
'';
41
+
in
42
+
mkWrapper {
43
+
pkg = fuzzel;
44
+
fuzzel.prependFlags = [
45
+
"--config"
46
+
"${cfg}"
47
+
];
48
+
}
+36
programs/ghostty-wrapped.nix
+36
programs/ghostty-wrapped.nix
···
1
+
{
2
+
pkgs,
3
+
mkWrapper,
4
+
theme,
5
+
ghostty,
6
+
}:
7
+
let
8
+
cfg = pkgs.writeText "config" ''
9
+
# font-family = "Hack"
10
+
font-size = ${theme.lengths.font-sm}
11
+
12
+
theme = "OneHalfDark"
13
+
14
+
window-padding-x = 8
15
+
window-padding-y = 8
16
+
window-padding-balance = false
17
+
window-padding-color = extend
18
+
19
+
window-decoration = none
20
+
window-theme = auto
21
+
22
+
confirm-close-surface = false
23
+
24
+
shell-integration = detect
25
+
shell-integration-features = true
26
+
27
+
gtk-single-instance = true
28
+
quit-after-last-window-closed = false
29
+
'';
30
+
in
31
+
mkWrapper {
32
+
pkg = ghostty;
33
+
ghostty.prependFlags = [
34
+
"--config-file=${cfg}"
35
+
];
36
+
}
+41
programs/helix-wrapped.nix
+41
programs/helix-wrapped.nix
···
1
+
{
2
+
pkgs,
3
+
mkWrapper,
4
+
helix,
5
+
}:
6
+
let
7
+
cfg = pkgs.writeText "config.toml" ''
8
+
theme = "zed_onedark"
9
+
10
+
[keys.normal]
11
+
tab = "goto_next_buffer"
12
+
S-tab = "goto_previous_buffer"
13
+
14
+
[editor]
15
+
bufferline = "multiple"
16
+
idle-timeout = 5
17
+
completion-timeout = 5
18
+
end-of-line-diagnostics = "hint"
19
+
inline-diagnostics.cursor-line = "error"
20
+
21
+
[editor.cursor-shape]
22
+
insert = "bar"
23
+
normal = "block"
24
+
select = "underline"
25
+
26
+
[editor.file-picker]
27
+
hidden = true
28
+
ignore = true
29
+
# git-ignore = true
30
+
31
+
[editor.soft-wrap]
32
+
enable = true
33
+
'';
34
+
in
35
+
mkWrapper {
36
+
pkg = helix;
37
+
hx.prependFlags = [
38
+
"--config"
39
+
"${cfg}"
40
+
];
41
+
}
+26
programs/mako-wrapped.nix
+26
programs/mako-wrapped.nix
···
1
+
{
2
+
pkgs,
3
+
mkWrapper,
4
+
theme,
5
+
mako,
6
+
}:
7
+
let
8
+
cfg = pkgs.writeText "config.ini" ''
9
+
font=sans-serif medium ${theme.lengths.font-md}px
10
+
padding=${theme.lengths.padding}
11
+
background-color=#${theme.colors.bg-darker}
12
+
text-color=#${theme.colors.fg-regular}
13
+
border-size=${theme.lengths.border-width}
14
+
border-radius=${theme.lengths.border-radius}
15
+
border-color=#${theme.colors.purple}
16
+
default-timeout=5000
17
+
max-icon-size=32
18
+
'';
19
+
in
20
+
mkWrapper {
21
+
pkg = mako;
22
+
mako.prependFlags = [
23
+
"--config"
24
+
"${cfg}"
25
+
];
26
+
}
+619
programs/niri-wrapped.nix
+619
programs/niri-wrapped.nix
···
1
+
{
2
+
pkgs,
3
+
lib,
4
+
mkWrapper,
5
+
theme,
6
+
niri,
7
+
swaylock-wrapped,
8
+
ghostty-wrapped,
9
+
fuzzel-wrapped,
10
+
wireplumber,
11
+
brightnessctl,
12
+
flatpak,
13
+
}:
14
+
let
15
+
cfg = pkgs.writeText "config.kdl" ''
16
+
// This config is in the KDL format: https://kdl.dev
17
+
// "/-" comments out the following node.
18
+
// Check the wiki for a full description of the configuration:
19
+
// https://github.com/YaLTeR/niri/wiki/Configuration:-Overview
20
+
21
+
spawn-at-startup "xwayland-satellite"
22
+
23
+
// Temporary for xwayland
24
+
environment {
25
+
DISPLAY ":0"
26
+
}
27
+
28
+
// Input device configuration.
29
+
// Find the full list of options on the wiki:
30
+
// https://github.com/YaLTeR/niri/wiki/Configuration:-Input
31
+
input {
32
+
keyboard {
33
+
xkb {
34
+
// You can set rules, model, layout, variant and options.
35
+
// For more information, see xkeyboard-config(7).
36
+
37
+
// For example:
38
+
// layout "us,ru"
39
+
// options "grp:win_space_toggle,compose:ralt,ctrl:nocaps"
40
+
options "caps:escape"
41
+
}
42
+
repeat-delay 300
43
+
repeat-rate 32
44
+
}
45
+
46
+
// Next sections include libinput settings.
47
+
// Omitting settings disables them, or leaves them at their default values.
48
+
touchpad {
49
+
// off
50
+
// tap
51
+
// dwt
52
+
// dwtp
53
+
// drag-lock
54
+
natural-scroll
55
+
// accel-speed 0.2
56
+
accel-profile "adaptive"
57
+
scroll-method "two-finger"
58
+
click-method "clickfinger"
59
+
scroll-factor 0.3
60
+
// disabled-on-external-mouse
61
+
}
62
+
63
+
mouse {
64
+
// off
65
+
// natural-scroll
66
+
// accel-speed 0.2
67
+
// accel-profile "flat"
68
+
// scroll-method "no-scroll"
69
+
}
70
+
71
+
trackpoint {
72
+
// off
73
+
// natural-scroll
74
+
// accel-speed 0.2
75
+
// accel-profile "flat"
76
+
// scroll-method "on-button-down"
77
+
// scroll-button 273
78
+
// middle-emulation
79
+
}
80
+
81
+
// Uncomment this to make the mouse warp to the center of newly focused windows.
82
+
// warp-mouse-to-focus
83
+
84
+
// Focus windows and outputs automatically when moving the mouse into them.
85
+
// Setting max-scroll-amount="0%" makes it work only on windows already fully on screen.
86
+
// focus-follows-mouse max-scroll-amount="0%"
87
+
}
88
+
89
+
output "DP-3" {
90
+
mode "3840x2160@30.000"
91
+
}
92
+
93
+
// You can configure outputs by their name, which you can find
94
+
// by running `niri msg outputs` while inside a niri instance.
95
+
// The built-in laptop monitor is usually called "eDP-1".
96
+
// Find more information on the wiki:
97
+
// https://github.com/YaLTeR/niri/wiki/Configuration:-Outputs
98
+
// Remember to uncomment the node by removing "/-"!
99
+
output "eDP-1" {
100
+
// Uncomment this line to disable this output.
101
+
// off
102
+
103
+
// Resolution and, optionally, refresh rate of the output.
104
+
// The format is "<width>x<height>" or "<width>x<height>@<refresh rate>".
105
+
// If the refresh rate is omitted, niri will pick the highest refresh rate
106
+
// for the resolution.
107
+
// If the mode is omitted altogether or is invalid, niri will pick one automatically.
108
+
// Run `niri msg outputs` while inside a niri instance to list all outputs and their modes.
109
+
mode "2256x1504@60"
110
+
111
+
// You can use integer or fractional scale, for example use 1.5 for 150% scale.
112
+
scale 1.5
113
+
114
+
// Transform allows to rotate the output counter-clockwise, valid values are:
115
+
// normal, 90, 180, 270, flipped, flipped-90, flipped-180 and flipped-270.
116
+
transform "normal"
117
+
118
+
background-color "#${theme.colors.bg-darker}"
119
+
120
+
// Position of the output in the global coordinate space.
121
+
// This affects directional monitor actions like "focus-monitor-left", and cursor movement.
122
+
// The cursor can only move between directly adjacent outputs.
123
+
// Output scale and rotation has to be taken into account for positioning:
124
+
// outputs are sized in logical, or scaled, pixels.
125
+
// For example, a 3840×2160 output with scale 2.0 will have a logical size of 1920×1080,
126
+
// so to put another output directly adjacent to it on the right, set its x to 1920.
127
+
// If the position is unset or results in an overlap, the output is instead placed
128
+
// automatically.
129
+
// position x=1280 y=0
130
+
}
131
+
132
+
output "DP-3" {
133
+
// Uncomment this line to disable this output.
134
+
// off
135
+
136
+
// Resolution and, optionally, refresh rate of the output.
137
+
// The format is "<width>x<height>" or "<width>x<height>@<refresh rate>".
138
+
// If the refresh rate is omitted, niri will pick the highest refresh rate
139
+
// for the resolution.
140
+
// If the mode is omitted altogether or is invalid, niri will pick one automatically.
141
+
// Run `niri msg outputs` while inside a niri instance to list all outputs and their modes.
142
+
mode "2560x1440@60"
143
+
144
+
// You can use integer or fractional scale, for example use 1.5 for 150% scale.
145
+
scale 1.25
146
+
147
+
// Transform allows to rotate the output counter-clockwise, valid values are:
148
+
// normal, 90, 180, 270, flipped, flipped-90, flipped-180 and flipped-270.
149
+
transform "normal"
150
+
151
+
background-color "#${theme.colors.bg-darker}"
152
+
153
+
// Position of the output in the global coordinate space.
154
+
// This affects directional monitor actions like "focus-monitor-left", and cursor movement.
155
+
// The cursor can only move between directly adjacent outputs.
156
+
// Output scale and rotation has to be taken into account for positioning:
157
+
// outputs are sized in logical, or scaled, pixels.
158
+
// For example, a 3840×2160 output with scale 2.0 will have a logical size of 1920×1080,
159
+
// so to put another output directly adjacent to it on the right, set its x to 1920.
160
+
// If the position is unset or results in an overlap, the output is instead placed
161
+
// automatically.
162
+
// position x=1280 y=0
163
+
}
164
+
165
+
// Settings that influence how windows are positioned and sized.
166
+
// Find more information on the wiki:
167
+
// https://github.com/YaLTeR/niri/wiki/Configuration:-Layout
168
+
layout {
169
+
// Set gaps around windows in logical pixels.
170
+
gaps 4
171
+
172
+
// When to center a column when changing focus, options are:
173
+
// - "never", default behavior, focusing an off-screen column will keep at the left
174
+
// or right edge of the screen.
175
+
// - "always", the focused column will always be centered.
176
+
// - "on-overflow", focusing a column will center it if it doesn't fit
177
+
// together with the previously focused column.
178
+
center-focused-column "never"
179
+
180
+
// You can customize the widths that "switch-preset-column-width" (Mod+R) toggles between.
181
+
preset-column-widths {
182
+
// Proportion sets the width as a fraction of the output width, taking gaps into account.
183
+
// For example, you can perfectly fit four windows sized "proportion 0.25" on an output.
184
+
// The default preset widths are 1/3, 1/2 and 2/3 of the output.
185
+
proportion 0.33333
186
+
proportion 0.5
187
+
proportion 0.66667
188
+
189
+
// Fixed sets the width in logical pixels exactly.
190
+
// fixed 1920
191
+
}
192
+
193
+
// You can also customize the heights that "switch-preset-window-height" (Mod+Shift+R) toggles between.
194
+
// preset-window-heights { }
195
+
196
+
// You can change the default width of the new windows.
197
+
default-column-width { proportion 0.5; }
198
+
// If you leave the brackets empty, the windows themselves will decide their initial width.
199
+
// default-column-width {}
200
+
201
+
// By default focus ring and border are rendered as a solid background rectangle
202
+
// behind windows. That is, they will show up through semitransparent windows.
203
+
// This is because windows using client-side decorations can have an arbitrary shape.
204
+
//
205
+
// If you don't like that, you should uncomment `prefer-no-csd` below.
206
+
// Niri will draw focus ring and border *around* windows that agree to omit their
207
+
// client-side decorations.
208
+
//
209
+
// Alternatively, you can override it with a window rule called
210
+
// `draw-border-with-background`.
211
+
212
+
focus-ring {
213
+
off
214
+
}
215
+
216
+
// You can also add a border. It's similar to the focus ring, but always visible.
217
+
border {
218
+
width ${theme.lengths.border-width}
219
+
active-color "#${theme.colors.cyan}"
220
+
inactive-color "#${theme.colors.gray}"
221
+
}
222
+
223
+
// You can enable drop shadows for windows.
224
+
shadow {
225
+
// Uncomment the next line to enable shadows.
226
+
// on
227
+
228
+
// By default, the shadow draws only around its window, and not behind it.
229
+
// Uncomment this setting to make the shadow draw behind its window.
230
+
//
231
+
// Note that niri has no way of knowing about the CSD window corner
232
+
// radius. It has to assume that windows have square corners, leading to
233
+
// shadow artifacts inside the CSD rounded corners. This setting fixes
234
+
// those artifacts.
235
+
//
236
+
// However, instead you may want to set prefer-no-csd and/or
237
+
// geometry-corner-radius. Then, niri will know the corner radius and
238
+
// draw the shadow correctly, without having to draw it behind the
239
+
// window. These will also remove client-side shadows if the window
240
+
// draws any.
241
+
//
242
+
// draw-behind-window true
243
+
244
+
// You can change how shadows look. The values below are in logical
245
+
// pixels and match the CSS box-shadow properties.
246
+
247
+
// Softness controls the shadow blur radius.
248
+
softness 30
249
+
250
+
// Spread expands the shadow.
251
+
spread 5
252
+
253
+
// Offset moves the shadow relative to the window.
254
+
offset x=0 y=5
255
+
256
+
// You can also change the shadow color and opacity.
257
+
color "#0007"
258
+
}
259
+
260
+
// Struts shrink the area occupied by windows, similarly to layer-shell panels.
261
+
// You can think of them as a kind of outer gaps. They are set in logical pixels.
262
+
// Left and right struts will cause the next window to the side to always be visible.
263
+
// Top and bottom struts will simply add outer gaps in addition to the area occupied by
264
+
// layer-shell panels and regular gaps.
265
+
struts {
266
+
// left 64
267
+
// right 64
268
+
// top 64
269
+
// bottom 64
270
+
}
271
+
}
272
+
273
+
// Add lines like this to spawn processes at startup.
274
+
// Note that running niri as a session supports xdg-desktop-autostart,
275
+
// which may be more convenient to use.
276
+
// See the binds section below for more spawn examples.
277
+
// spawn-at-startup "alacritty" "-e" "bash"
278
+
279
+
// Uncomment this line to ask the clients to omit their client-side decorations if possible.
280
+
// If the client will specifically ask for CSD, the request will be honored.
281
+
// Additionally, clients will be informed that they are tiled, removing some client-side rounded corners.
282
+
// This option will also fix border/focus ring drawing behind some semitransparent windows.
283
+
// After enabling or disabling this, you need to restart the apps for this to take effect.
284
+
prefer-no-csd
285
+
286
+
// You can change the path where screenshots are saved.
287
+
// A ~ at the front will be expanded to the home directory.
288
+
// The path is formatted with strftime(3) to give you the screenshot date and time.
289
+
screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"
290
+
291
+
// You can also set this to null to disable saving screenshots to disk.
292
+
// screenshot-path null
293
+
294
+
// Animation settings.
295
+
// The wiki explains how to configure individual animations:
296
+
// https://github.com/YaLTeR/niri/wiki/Configuration:-Animations
297
+
animations {
298
+
// Uncomment to turn off all animations.
299
+
// off
300
+
301
+
// Slow down all animations by this factor. Values below 1 speed them up instead.
302
+
slowdown 0.8
303
+
}
304
+
305
+
// Window rules let you adjust behavior for individual windows.
306
+
// Find more information on the wiki:
307
+
// https://github.com/YaLTeR/niri/wiki/Configuration:-Window-Rules
308
+
309
+
// Work around WezTerm's initial configure bug
310
+
// by setting an empty default-column-width.
311
+
window-rule {
312
+
// This regular expression is intentionally made as specific as possible,
313
+
// since this is the default config, and we want no false positives.
314
+
// You can get away with just app-id="wezterm" if you want.
315
+
match app-id=r#"^org\.wezfurlong\.wezterm$"#
316
+
default-column-width {}
317
+
}
318
+
319
+
// Open the Firefox picture-in-picture player as floating by default.
320
+
window-rule {
321
+
// This app-id regular expression will work for both:
322
+
// - host Firefox (app-id is "firefox")
323
+
// - Flatpak Firefox (app-id is "org.mozilla.firefox")
324
+
match app-id=r#"firefox$"# title="^Picture-in-Picture$"
325
+
open-floating true
326
+
}
327
+
328
+
// Example: block out two password managers from screen capture.
329
+
// (This example rule is commented out with a "/-" in front.)
330
+
/-window-rule {
331
+
match app-id=r#"^org\.keepassxc\.KeePassXC$"#
332
+
match app-id=r#"^org\.gnome\.World\.Secrets$"#
333
+
334
+
block-out-from "screen-capture"
335
+
336
+
// Use this instead if you want them visible on third-party screenshot tools.
337
+
// block-out-from "screencast"
338
+
}
339
+
340
+
// Example: enable rounded corners for all windows.
341
+
// (This example rule is commented out with a "/-" in front.)
342
+
window-rule {
343
+
geometry-corner-radius ${theme.lengths.border-radius}
344
+
clip-to-geometry true
345
+
}
346
+
347
+
// window-rule {
348
+
// match is-floating=true
349
+
// baba-is-float true
350
+
// }
351
+
352
+
binds {
353
+
// Keys consist of modifiers separated by + signs, followed by an XKB key name
354
+
// in the end. To find an XKB name for a particular key, you may use a program
355
+
// like wev.
356
+
//
357
+
// "Mod" is a special modifier equal to Super when running on a TTY, and to Alt
358
+
// when running as a winit window.
359
+
//
360
+
// Most actions that you can bind here can also be invoked programmatically with
361
+
// `niri msg action do-something`.
362
+
363
+
// Mod-Shift-/, which is usually the same as Mod-?,
364
+
// shows a list of important hotkeys.
365
+
Mod+Shift+Slash { show-hotkey-overlay; }
366
+
367
+
// Suggested binds for running programs: terminal, app launcher, screen locker.
368
+
Mod+Return { spawn "${lib.getExe ghostty-wrapped}"; }
369
+
Mod+D { spawn "${lib.getExe fuzzel-wrapped}"; }
370
+
Mod+Shift+Return { spawn "${lib.getExe flatpak}" "run" "org.mozilla.firefox"; }
371
+
Super+Alt+L { spawn "${lib.getExe swaylock-wrapped}"; }
372
+
373
+
// You can also use a shell. Do this if you need pipes, multiple commands, etc.
374
+
// Note: the entire command goes as a single argument in the end.
375
+
// Mod+T { spawn "bash" "-c" "notify-send hello && exec alacritty"; }
376
+
377
+
// Example volume keys mappings for PipeWire & WirePlumber.
378
+
// The allow-when-locked=true property makes them work even when the session is locked.
379
+
XF86AudioRaiseVolume allow-when-locked=true { spawn "${lib.getExe' wireplumber "wpctl"}" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.08+"; }
380
+
XF86AudioLowerVolume allow-when-locked=true { spawn "${lib.getExe' wireplumber "wpctl"}" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.08-"; }
381
+
XF86AudioMute allow-when-locked=true { spawn "${lib.getExe' wireplumber "wpctl"}" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; }
382
+
XF86AudioMicMute allow-when-locked=true { spawn "${lib.getExe' wireplumber "wpctl"}" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; }
383
+
XF86MonBrightnessDown allow-when-locked=true {spawn "${lib.getExe' brightnessctl "brightnessctl"}" "-e" "set" "10%-"; }
384
+
XF86MonBrightnessUp allow-when-locked=true {spawn "${lib.getExe brightnessctl}" "-e" "set" "+10%"; }
385
+
386
+
Mod+Ctrl+Shift+Alt+L { spawn "${lib.getExe flatpak}" "run" "org.mozilla.firefox" "--new-window" "https://www.linkedin.com/"; }
387
+
388
+
Mod+Q { close-window; }
389
+
390
+
Mod+Left { focus-column-left; }
391
+
Mod+Down { focus-window-down; }
392
+
Mod+Up { focus-window-up; }
393
+
Mod+Right { focus-column-right; }
394
+
Mod+H { focus-column-left; }
395
+
Mod+J { focus-window-down; }
396
+
Mod+K { focus-window-up; }
397
+
Mod+L { focus-column-right; }
398
+
399
+
Mod+Shift+Left { move-column-left; }
400
+
Mod+Shift+Down { move-window-down; }
401
+
Mod+Shift+Up { move-window-up; }
402
+
Mod+Shift+Right { move-column-right; }
403
+
Mod+Shift+H { move-column-left; }
404
+
Mod+Shift+J { move-window-down; }
405
+
Mod+Shift+K { move-window-up; }
406
+
Mod+Shift+L { move-column-right; }
407
+
408
+
// Alternative commands that move across workspaces when reaching
409
+
// the first or last window in a column.
410
+
// Mod+J { focus-window-or-workspace-down; }
411
+
// Mod+K { focus-window-or-workspace-up; }
412
+
// Mod+Ctrl+J { move-window-down-or-to-workspace-down; }
413
+
// Mod+Ctrl+K { move-window-up-or-to-workspace-up; }
414
+
415
+
Mod+Home { focus-column-first; }
416
+
Mod+End { focus-column-last; }
417
+
Mod+Shift+Home { move-column-to-first; }
418
+
Mod+Shift+End { move-column-to-last; }
419
+
420
+
Mod+Control+Left { focus-monitor-left; }
421
+
Mod+Control+Down { focus-monitor-down; }
422
+
Mod+Control+Up { focus-monitor-up; }
423
+
Mod+Control+Right { focus-monitor-right; }
424
+
Mod+Control+H { focus-monitor-left; }
425
+
Mod+Control+J { focus-monitor-down; }
426
+
Mod+Control+K { focus-monitor-up; }
427
+
Mod+Control+L { focus-monitor-right; }
428
+
429
+
Mod+Shift+Ctrl+Left { move-column-to-monitor-left; }
430
+
Mod+Shift+Ctrl+Down { move-column-to-monitor-down; }
431
+
Mod+Shift+Ctrl+Up { move-column-to-monitor-up; }
432
+
Mod+Shift+Ctrl+Right { move-column-to-monitor-right; }
433
+
Mod+Shift+Ctrl+H { move-column-to-monitor-left; }
434
+
Mod+Shift+Ctrl+J { move-column-to-monitor-down; }
435
+
Mod+Shift+Ctrl+K { move-column-to-monitor-up; }
436
+
Mod+Shift+Ctrl+L { move-column-to-monitor-right; }
437
+
438
+
// Alternatively, there are commands to move just a single window:
439
+
// Mod+Shift+Ctrl+Left { move-window-to-monitor-left; }
440
+
// ...
441
+
442
+
// And you can also move a whole workspace to another monitor:
443
+
// Mod+Shift+Ctrl+Left { move-workspace-to-monitor-left; }
444
+
// ...
445
+
446
+
Mod+Page_Down { focus-workspace-down; }
447
+
Mod+Page_Up { focus-workspace-up; }
448
+
Mod+U { focus-workspace-down; }
449
+
Mod+I { focus-workspace-up; }
450
+
Mod+Shift+Page_Down { move-column-to-workspace-down; }
451
+
Mod+Shift+Page_Up { move-column-to-workspace-up; }
452
+
Mod+Shift+U { move-column-to-workspace-down; }
453
+
Mod+Shift+I { move-column-to-workspace-up; }
454
+
455
+
// Alternatively, there are commands to move just a single window:
456
+
// Mod+Ctrl+Page_Down { move-window-to-workspace-down; }
457
+
// ...
458
+
459
+
Mod+Ctrl+Page_Down { move-workspace-down; }
460
+
Mod+Ctrl+Page_Up { move-workspace-up; }
461
+
Mod+Ctrl+U { move-workspace-down; }
462
+
Mod+Ctrl+I { move-workspace-up; }
463
+
464
+
Mod+S { toggle-overview; }
465
+
466
+
// You can bind mouse wheel scroll ticks using the following syntax.
467
+
// These binds will change direction based on the natural-scroll setting.
468
+
//
469
+
// To avoid scrolling through workspaces really fast, you can use
470
+
// the cooldown-ms property. The bind will be rate-limited to this value.
471
+
// You can set a cooldown on any bind, but it's most useful for the wheel.
472
+
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
473
+
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
474
+
Mod+Shift+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; }
475
+
Mod+Shift+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; }
476
+
477
+
Mod+WheelScrollRight { focus-column-right; }
478
+
Mod+WheelScrollLeft { focus-column-left; }
479
+
Mod+Ctrl+WheelScrollRight { move-column-right; }
480
+
Mod+Ctrl+WheelScrollLeft { move-column-left; }
481
+
482
+
// Usually scrolling up and down with Shift in applications results in
483
+
// horizontal scrolling; these binds replicate that.
484
+
Mod+Ctrl+WheelScrollDown { focus-column-right; }
485
+
Mod+Ctrl+WheelScrollUp { focus-column-left; }
486
+
Mod+Ctrl+Shift+WheelScrollDown { move-column-right; }
487
+
Mod+Ctrl+Shift+WheelScrollUp { move-column-left; }
488
+
489
+
// Similarly, you can bind touchpad scroll "ticks".
490
+
// Touchpad scrolling is continuous, so for these binds it is split into
491
+
// discrete intervals.
492
+
// These binds are also affected by touchpad's natural-scroll, so these
493
+
// example binds are "inverted", since we have natural-scroll enabled for
494
+
// touchpads by default.
495
+
// Mod+TouchpadScrollDown { spawn "${lib.getExe' wireplumber "wpctl"}" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02+"; }
496
+
// Mod+TouchpadScrollUp { spawn "${lib.getExe' wireplumber "wpctl"}" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02-"; }
497
+
498
+
// You can refer to workspaces by index. However, keep in mind that
499
+
// niri is a dynamic workspace system, so these commands are kind of
500
+
// "best effort". Trying to refer to a workspace index bigger than
501
+
// the current workspace count will instead refer to the bottommost
502
+
// (empty) workspace.
503
+
//
504
+
// For example, with 2 workspaces + 1 empty, indices 3, 4, 5 and so on
505
+
// will all refer to the 3rd workspace.
506
+
Mod+1 { focus-workspace 1; }
507
+
Mod+2 { focus-workspace 2; }
508
+
Mod+3 { focus-workspace 3; }
509
+
Mod+4 { focus-workspace 4; }
510
+
Mod+5 { focus-workspace 5; }
511
+
Mod+6 { focus-workspace 6; }
512
+
Mod+7 { focus-workspace 7; }
513
+
Mod+8 { focus-workspace 8; }
514
+
Mod+9 { focus-workspace 9; }
515
+
Mod+Shift+1 { move-column-to-workspace 1; }
516
+
Mod+Shift+2 { move-column-to-workspace 2; }
517
+
Mod+Shift+3 { move-column-to-workspace 3; }
518
+
Mod+Shift+4 { move-column-to-workspace 4; }
519
+
Mod+Shift+5 { move-column-to-workspace 5; }
520
+
Mod+Shift+6 { move-column-to-workspace 6; }
521
+
Mod+Shift+7 { move-column-to-workspace 7; }
522
+
Mod+Shift+8 { move-column-to-workspace 8; }
523
+
Mod+Shift+9 { move-column-to-workspace 9; }
524
+
525
+
// Alternatively, there are commands to move just a single window:
526
+
// Mod+Ctrl+1 { move-window-to-workspace 1; }
527
+
528
+
// Switches focus between the current and the previous workspace.
529
+
// Mod+Tab { focus-workspace-previous; }
530
+
531
+
// The following binds move the focused window in and out of a column.
532
+
// If the window is alone, they will consume it into the nearby column to the side.
533
+
// If the window is already in a column, they will expel it out.
534
+
Mod+BracketLeft { consume-or-expel-window-left; }
535
+
Mod+BracketRight { consume-or-expel-window-right; }
536
+
537
+
// Consume one window from the right to the bottom of the focused column.
538
+
Mod+Comma { consume-window-into-column; }
539
+
// Expel the bottom window from the focused column to the right.
540
+
Mod+Period { expel-window-from-column; }
541
+
542
+
Mod+R { switch-preset-column-width; }
543
+
Mod+Shift+R { switch-preset-window-height; }
544
+
Mod+Ctrl+R { reset-window-height; }
545
+
Mod+F { maximize-column; }
546
+
Mod+Shift+F { fullscreen-window; }
547
+
548
+
// Expand the focused column to space not taken up by other fully visible columns.
549
+
// Makes the column "fill the rest of the space".
550
+
Mod+Ctrl+F { expand-column-to-available-width; }
551
+
552
+
Mod+C { center-column; }
553
+
554
+
// Finer width adjustments.
555
+
// This command can also:
556
+
// * set width in pixels: "1000"
557
+
// * adjust width in pixels: "-5" or "+5"
558
+
// * set width as a percentage of screen width: "25%"
559
+
// * adjust width as a percentage of screen width: "-10%" or "+10%"
560
+
// Pixel sizes use logical, or scaled, pixels. I.e. on an output with scale 2.0,
561
+
// set-column-width "100" will make the column occupy 200 physical screen pixels.
562
+
Mod+Minus { set-column-width "-10%"; }
563
+
Mod+Equal { set-column-width "+10%"; }
564
+
565
+
// Finer height adjustments when in column with other windows.
566
+
Mod+Shift+Minus { set-window-height "-10%"; }
567
+
Mod+Shift+Equal { set-window-height "+10%"; }
568
+
569
+
// Move the focused window between the floating and the tiling layout.
570
+
Mod+V { toggle-window-floating; }
571
+
Mod+Shift+V { switch-focus-between-floating-and-tiling; }
572
+
573
+
// Toggle tabbed column display mode.
574
+
// Windows in this column will appear as vertical tabs,
575
+
// rather than stacked on top of each other.
576
+
Mod+W { toggle-column-tabbed-display; }
577
+
578
+
// Actions to switch layouts.
579
+
// Note: if you uncomment these, make sure you do NOT have
580
+
// a matching layout switch hotkey configured in xkb options above.
581
+
// Having both at once on the same hotkey will break the switching,
582
+
// since it will switch twice upon pressing the hotkey (once by xkb, once by niri).
583
+
// Mod+Space { switch-layout "next"; }
584
+
// Mod+Shift+Space { switch-layout "prev"; }
585
+
586
+
Print { screenshot; }
587
+
Ctrl+Print { screenshot-screen; }
588
+
Alt+Print { screenshot-window; }
589
+
Super+P { screenshot; }
590
+
Ctrl+Super+P { screenshot-screen; }
591
+
Alt+Super+P { screenshot-window; }
592
+
593
+
// Applications such as remote-desktop clients and software KVM switches may
594
+
// request that niri stops processing the keyboard shortcuts defined here
595
+
// so they may, for example, forward the key presses as-is to a remote machine.
596
+
// It's a good idea to bind an escape hatch to toggle the inhibitor,
597
+
// so a buggy application can't hold your session hostage.
598
+
//
599
+
// The allow-inhibiting=false property can be applied to other binds as well,
600
+
// which ensures niri always processes them, even when an inhibitor is active.
601
+
Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
602
+
603
+
// The quit action will show a confirmation dialog to avoid accidental exits.
604
+
Mod+Shift+E { quit; }
605
+
Ctrl+Alt+Delete { quit; }
606
+
607
+
// Powers off the monitors. To turn them back on, do any input like
608
+
// moving the mouse or pressing any other key.
609
+
Mod+Shift+P { power-off-monitors; }
610
+
}
611
+
'';
612
+
in
613
+
mkWrapper {
614
+
pkg = niri;
615
+
niri.prependFlags = [
616
+
"--config"
617
+
"${cfg}"
618
+
];
619
+
}
+54
programs/swaylock-wrapped.nix
+54
programs/swaylock-wrapped.nix
···
1
+
{
2
+
pkgs,
3
+
mkWrapper,
4
+
theme,
5
+
swaylock,
6
+
}:
7
+
let
8
+
cfg = pkgs.writeText "config.ini" ''
9
+
scaling=fill
10
+
font="Inter Display"
11
+
font-size=30
12
+
indicator-radius=64px
13
+
indicator-thickness=6px
14
+
15
+
color=${theme.colors.bg-darker}
16
+
text-color=${theme.colors.fg-regular}
17
+
text-clear-color=${theme.colors.fg-regular}
18
+
text-wrong-color=${theme.colors.fg-regular}
19
+
text-ver-color=${theme.colors.fg-regular}
20
+
text-caps-lock-color=${theme.colors.fg-regular}
21
+
22
+
bs-hl-color=${theme.colors.red}
23
+
caps-lock-bs-hl-color=${theme.colors.red}
24
+
key-hl-color=${theme.colors.blue}
25
+
caps-lock-key-hl-color=${theme.colors.blue}
26
+
27
+
separator-color=${theme.colors.bg-darker}
28
+
29
+
layout-bg-color=${theme.colors.bg-darker}
30
+
layout-border-color=${theme.colors.bg-darker}
31
+
layout-text-color=${theme.colors.fg-regular}
32
+
33
+
inside-color=${theme.colors.bg-darker}
34
+
inside-clear-color=${theme.colors.bg-darker}
35
+
inside-caps-lock-color=${theme.colors.bg-darker}
36
+
inside-ver-color=${theme.colors.bg-darker}
37
+
inside-wrong-color=${theme.colors.bg-darker}
38
+
39
+
ring-color=${theme.colors.bg-darker}
40
+
ring-clear-color=${theme.colors.yellow}
41
+
ring-caps-lock-color=${theme.colors.purple}
42
+
ring-ver-color=${theme.colors.blue}
43
+
ring-wrong-color=${theme.colors.red}
44
+
45
+
line-uses-inside
46
+
'';
47
+
in
48
+
mkWrapper {
49
+
pkg = swaylock;
50
+
swaylock.prependFlags = [
51
+
"--config"
52
+
"${cfg}"
53
+
];
54
+
}
+370
programs/waybar-wrapped.nix
+370
programs/waybar-wrapped.nix
···
1
+
# additional @args needed to forward systemdSupport to mkWrapper
2
+
{
3
+
pkgs,
4
+
lib,
5
+
mkWrapper,
6
+
theme,
7
+
waybar,
8
+
pavucontrol,
9
+
networkmanagerapplet,
10
+
...
11
+
}@args:
12
+
let
13
+
cfg = pkgs.writeText "config.jsonc" ''
14
+
{
15
+
"layer": "top", // Waybar at top layer
16
+
// "position": "bottom", // Waybar position (top|bottom|left|right)
17
+
"height": 26, // Waybar height (to be removed for auto height)
18
+
// "width": 1280, // Waybar width
19
+
"spacing": 4, // Gaps between modules (4px)
20
+
"margin-top": 4,
21
+
"margin-left": 4,
22
+
"margin-right": 4,
23
+
24
+
"modules-left": [
25
+
"niri/workspaces"
26
+
],
27
+
28
+
"modules-center": [
29
+
"niri/window"
30
+
],
31
+
32
+
"modules-right": [
33
+
// "mpd",
34
+
// "idle_inhibitor",
35
+
// "power-profiles-daemon",
36
+
// "cpu",
37
+
// "memory",
38
+
// "temperature",
39
+
// "backlight",
40
+
// "keyboard-state",
41
+
// "sway/language",
42
+
"pulseaudio",
43
+
"network",
44
+
"battery",
45
+
// "battery#bat2",
46
+
"clock",
47
+
"tray"
48
+
],
49
+
50
+
"sway/mode": {
51
+
"format": "<span style=\"italic\">{}</span>"
52
+
},
53
+
54
+
"sway/scratchpad": {
55
+
"format": "{icon} {count}",
56
+
"show-empty": false,
57
+
"format-icons": ["", ""],
58
+
"tooltip": true,
59
+
"tooltip-format": "{app}: {title}"
60
+
},
61
+
62
+
"mpd": {
63
+
"format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ⸨{songPosition}|{queueLength}⸩ {volume}% ",
64
+
"format-disconnected": "Disconnected ",
65
+
"format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ",
66
+
"unknown-tag": "N/A",
67
+
"interval": 5,
68
+
"consume-icons": {
69
+
"on": " "
70
+
},
71
+
"random-icons": {
72
+
"off": "<span color=\"#f53c3c\"></span> ",
73
+
"on": " "
74
+
},
75
+
"repeat-icons": {
76
+
"on": " "
77
+
},
78
+
"single-icons": {
79
+
"on": "1 "
80
+
},
81
+
"state-icons": {
82
+
"paused": "",
83
+
"playing": ""
84
+
},
85
+
"tooltip-format": "MPD (connected)",
86
+
"tooltip-format-disconnected": "MPD (disconnected)"
87
+
},
88
+
"idle_inhibitor": {
89
+
"format": "{icon}",
90
+
"format-icons": {
91
+
"activated": "",
92
+
"deactivated": ""
93
+
}
94
+
},
95
+
"tray": {
96
+
"icon-size": 16,
97
+
"spacing": 10
98
+
},
99
+
"clock": {
100
+
"format": "{:%H:%M}",
101
+
"format-alt": "{:%A, %B %d, %R}",
102
+
"tooltip-format": "<tt><small>{calendar}</small></tt>",
103
+
"calendar": {
104
+
"mode" : "year",
105
+
"mode-mon-col" : 3,
106
+
"on-scroll" : 1,
107
+
"format": {
108
+
"months": "<span color='#ffead3'><b>{}</b></span>",
109
+
"days": "<span color='#ecc6d9'><b>{}</b></span>",
110
+
"weeks": "<span color='#99ffdd'><b>W{}</b></span>",
111
+
"weekdays": "<span color='#ffcc66'><b>{}</b></span>",
112
+
"today": "<span color='#ff6699'><b><u>{}</u></b></span>"
113
+
}
114
+
},
115
+
"actions": {
116
+
"on-click-right": "mode",
117
+
"on-scroll-up": "tz_up",
118
+
"on-scroll-down": "tz_down",
119
+
"on-scroll-up": "shift_up",
120
+
"on-scroll-down": "shift_down"
121
+
}
122
+
},
123
+
"cpu": {
124
+
"format": "{usage}% ",
125
+
"tooltip": false
126
+
},
127
+
"memory": {
128
+
"format": "{}% "
129
+
},
130
+
"temperature": {
131
+
// "thermal-zone": 2,
132
+
// "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
133
+
"critical-threshold": 80,
134
+
// "format-critical": "{temperatureC}°C {icon}",
135
+
"format": "{temperatureC}°C {icon}",
136
+
"format-icons": ["", "", ""]
137
+
},
138
+
"backlight": {
139
+
// "device": "acpi_video1",
140
+
"format": "{percent}% {icon}",
141
+
"format-icons": ["", "", "", "", "", "", "", "", ""]
142
+
},
143
+
"battery": {
144
+
"states": {
145
+
"good": 95,
146
+
"warning": 30,
147
+
"critical": 15
148
+
},
149
+
"format": "{capacity}% {icon} ",
150
+
"format-full": "{capacity}% {icon} ",
151
+
"format-charging": "{capacity}% ",
152
+
"format-plugged": "{capacity}% ",
153
+
"format-alt": "{time} {icon}",
154
+
"format-icons": ["", "", "", "", ""]
155
+
},
156
+
"power-profiles-daemon": {
157
+
"format": "{icon}",
158
+
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
159
+
"tooltip": true,
160
+
"format-icons": {
161
+
"default": "",
162
+
"performance": "",
163
+
"balanced": "",
164
+
"power-saver": ""
165
+
}
166
+
},
167
+
"network": {
168
+
// "interface": "wlp2*", // (Optional) To force the use of this interface
169
+
// "format-wifi": "{essid} ({signalStrength}%) ",
170
+
"format-wifi": "{signalStrength}% ",
171
+
"format-ethernet": "{ipaddr}/{cidr} ",
172
+
"tooltip-format": "{ifname} via {gwaddr} ",
173
+
"format-linked": "{ifname} (No IP) ",
174
+
"format-disconnected": "Disconnected ⚠",
175
+
// "format-alt": "{ifname}: {ipaddr}/{cidr}",
176
+
"on-click": "${lib.getExe' networkmanagerapplet "nm-connection-editor"}"
177
+
},
178
+
"pulseaudio": {
179
+
"scroll-step": 1, // %, can be a float
180
+
"format": "{volume}% {icon} {format_source}",
181
+
"format-bluetooth": "{volume}% {icon} {format_source}",
182
+
"format-bluetooth-muted": "{icon} {format_source}",
183
+
"format-muted": "{format_source}",
184
+
"format-source": "{volume}% ",
185
+
"format-source-muted": "",
186
+
"format-icons": {
187
+
"headphone": "",
188
+
"hands-free": "",
189
+
"headset": "",
190
+
"phone": "",
191
+
"portable": "",
192
+
"car": "",
193
+
"default": ["", "", ""]
194
+
},
195
+
"on-click": "${lib.getExe pavucontrol}"
196
+
},
197
+
"custom/media": {
198
+
"format": "{icon} {}",
199
+
"return-type": "json",
200
+
"max-length": 40,
201
+
"format-icons": {
202
+
"spotify": "",
203
+
"default": "🎜"
204
+
},
205
+
"escape": true,
206
+
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
207
+
// "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
208
+
},
209
+
"custom/power": {
210
+
"format" : "⏻ ",
211
+
"tooltip": false,
212
+
"menu": "on-click",
213
+
"menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder
214
+
"menu-actions": {
215
+
"shutdown": "shutdown",
216
+
"reboot": "reboot",
217
+
"suspend": "systemctl suspend",
218
+
"hibernate": "systemctl hibernate"
219
+
}
220
+
}
221
+
}
222
+
'';
223
+
style = pkgs.writeText "style.css" ''
224
+
* {
225
+
font-family: "sans-serif", "Noto Monochrome Emoji", "Font Awesome 5 Pro Solid", "Font Awesome 5 Brands";
226
+
font-size: ${theme.lengths.font-md}px;
227
+
font-weight: 600;
228
+
color: #${theme.colors.fg-regular};
229
+
}
230
+
231
+
/* Reset styling for buttons */
232
+
button {
233
+
all: unset;
234
+
}
235
+
236
+
window#waybar {
237
+
background: transparent;
238
+
}
239
+
240
+
#workspaces button.focused,
241
+
#workspaces button:hover {
242
+
border-color: #${theme.colors.cyan};
243
+
}
244
+
245
+
#workspaces button.urgent {
246
+
border-color: #${theme.colors.red};
247
+
}
248
+
249
+
#mode,
250
+
#clock,
251
+
#battery,
252
+
#cpu,
253
+
#memory,
254
+
#disk,
255
+
#temperature,
256
+
#backlight,
257
+
#network,
258
+
#pulseaudio,
259
+
#wireplumber,
260
+
#custom-media,
261
+
#tray,
262
+
#mode,
263
+
#idle_inhibitor,
264
+
#scratchpad,
265
+
#power-profiles-daemon,
266
+
#mpd,
267
+
#window,
268
+
#workspaces button {
269
+
padding: 4px 8px;
270
+
background-color: #${theme.colors.bg-regular};
271
+
border-style: solid;
272
+
border-width: ${theme.lengths.border-width}px;
273
+
border-radius: ${theme.lengths.border-radius}px;
274
+
border-color: #${theme.colors.gray};
275
+
}
276
+
277
+
/* Add spacing in between each workspace button */
278
+
#workspaces button {
279
+
margin-right: 4px;
280
+
}
281
+
282
+
/* Prevent duplicated margin from rightmost workspace button */
283
+
#workspaces button:last-child {
284
+
margin-right: 0;
285
+
}
286
+
287
+
#waybar.empty #window {
288
+
background-color: transparent;
289
+
border-width: 0px
290
+
}
291
+
292
+
#clock {
293
+
color: #${theme.colors.purple};
294
+
}
295
+
296
+
#clock:hover {
297
+
border-color: #${theme.colors.purple};
298
+
}
299
+
300
+
#battery {
301
+
color: #${theme.colors.green};
302
+
}
303
+
304
+
#battery:hover {
305
+
border-color: #${theme.colors.green};
306
+
}
307
+
308
+
#battery.charging {
309
+
border-color: #${theme.colors.green};
310
+
}
311
+
312
+
@keyframes blink {
313
+
to {
314
+
border-color: #${theme.colors.red};
315
+
}
316
+
}
317
+
318
+
/* Using steps() instead of linear as a timing function to limit cpu usage */
319
+
#battery.critical:not(.charging) {
320
+
color: #${theme.colors.red};
321
+
animation-name: blink;
322
+
animation-duration: 0.5s;
323
+
animation-timing-function: steps(12);
324
+
animation-iteration-count: infinite;
325
+
animation-direction: alternate;
326
+
}
327
+
328
+
#network {
329
+
color: #${theme.colors.blue};
330
+
}
331
+
332
+
#network:hover {
333
+
border-color: #${theme.colors.blue};
334
+
}
335
+
336
+
#network.disconnected {
337
+
border-color: #${theme.colors.red};
338
+
}
339
+
340
+
#pulseaudio {
341
+
color: #${theme.colors.yellow};
342
+
}
343
+
344
+
#pulseaudio:hover {
345
+
border-color: #${theme.colors.yellow};
346
+
}
347
+
348
+
#pulseaudio.muted {
349
+
border-color: #${theme.colors.red};
350
+
}
351
+
'';
352
+
passThruArgs = builtins.removeAttrs args [
353
+
"pkgs"
354
+
"lib"
355
+
"mkWrapper"
356
+
"theme"
357
+
"waybar"
358
+
"pavucontrol"
359
+
"networkmanagerapplet"
360
+
];
361
+
in
362
+
mkWrapper {
363
+
pkg = waybar.override passThruArgs;
364
+
waybar.prependFlags = [
365
+
"--config"
366
+
"${cfg}"
367
+
"--style"
368
+
"${style}"
369
+
];
370
+
}
+184
utils/wrap.nix
+184
utils/wrap.nix
···
1
+
/**
2
+
Wraps a package with flags and env vars.
3
+
4
+
The wrapper derivation has each specified binary in the original package replaced by a wrapper with the specified flags and environment variables.
5
+
Every other file from the original derivation is symlinked to by the new derivation, except any file referencing the original $pkg will be cloned and have that reference replaced by the wrapper derivation's $out.
6
+
7
+
# Example
8
+
9
+
```nix
10
+
mkWrapper = import ./wrap.nix;
11
+
editor = mkWrapper pkgs {
12
+
pkg = pkgs.helix;
13
+
hx = {
14
+
env.idk = "hi";
15
+
prependFlags = [
16
+
"--config"
17
+
"./helix.toml"
18
+
];
19
+
};
20
+
};
21
+
```
22
+
23
+
# Type
24
+
25
+
```
26
+
mkWrapper :: Pkgs -> {
27
+
pkg : Derivation,
28
+
pname? : String,
29
+
additionalDependencies? : [Derivation],
30
+
<bin> : {
31
+
env? : AttrSet String,
32
+
prependFlags? : [String]
33
+
appendFlags? : [String]
34
+
}
35
+
} -> Derivation
36
+
```
37
+
38
+
# Arguments
39
+
40
+
pkgs
41
+
: An instance of nixpkgs
42
+
43
+
pkg
44
+
: The derivation to wrap
45
+
46
+
pname
47
+
: An optional name for the wrapped package, defaults to `pkg.name`
48
+
49
+
additionalDependencies
50
+
: An optional list of additional derivations to include in the wrapped environment
51
+
52
+
<bin>
53
+
: Variadic number of attrsets in the form bin = { env?, flags? }, where `bin` is the name of the binary that `pkg` outputs that you want to wrap. `env` and `flags` are detailed below.
54
+
55
+
env
56
+
: An optional attrset specifying environment variables to set inside the wrapped environment, defaults to `{}`
57
+
58
+
prependFlags
59
+
: An optional list specifying flags to append to the wrapped binary, defaults to `[]`. These flags go before your arguments, in the form `bin --prepended $@`.
60
+
61
+
appendFlags
62
+
: An optional list specifying flags to append to the wrapped binary, defaults to `[]` These flags go after your arguments, in the form `bin $@ --appended`.
63
+
*/
64
+
pkgs:
65
+
let
66
+
wrap =
67
+
{
68
+
pkg,
69
+
pname ? pkg.pname,
70
+
version ? pkg.version,
71
+
additionalDependencies ? [ ],
72
+
...
73
+
}@args:
74
+
75
+
let
76
+
lib = pkgs.lib;
77
+
in
78
+
79
+
assert lib.isDerivation pkg || throw "'pkg' must be a derivation (e.g. pkgs.hello)";
80
+
assert lib.isString pname || throw "'name' must be a string";
81
+
82
+
let
83
+
# all keyword kwargs are bins
84
+
binaries = builtins.removeAttrs args [
85
+
"pkg"
86
+
"pname"
87
+
"version"
88
+
"additionalDependencies"
89
+
];
90
+
91
+
wrapCommands = lib.mapAttrsToList (
92
+
bin:
93
+
{
94
+
prependFlags ? [ ],
95
+
appendFlags ? [ ],
96
+
env ? { },
97
+
}:
98
+
assert
99
+
(lib.isList prependFlags && lib.all lib.isString prependFlags)
100
+
|| throw "'${bin}.addFlags' must be a list of strings";
101
+
assert
102
+
(lib.isList appendFlags && lib.all lib.isString appendFlags)
103
+
|| throw "'${bin}.addFlags' must be a list of strings";
104
+
assert
105
+
(lib.isAttrs env && lib.all lib.isString (lib.attrValues env))
106
+
|| throw "'${bin}.env' must be an attribute set of strings";
107
+
let
108
+
envArgs = lib.concatStringsSep " " (lib.mapAttrsToList (k: v: "--set '${k}' '${v}'") env);
109
+
in
110
+
''
111
+
wrapProgram $out/bin/${bin} \
112
+
--add-flags "${builtins.toString prependFlags}" \
113
+
--append-flags "${builtins.toString appendFlags}" \
114
+
${envArgs}
115
+
''
116
+
) binaries;
117
+
118
+
# nasty script to replace all text references to ${pkg} with ${out}
119
+
# this is necessary because some files that get symlinked into the new
120
+
# package directory ($out) will still reference ${pkg}, leading to
121
+
# unexpected behavior
122
+
fixReferences = ''
123
+
# iterate through every file/symlink in $out
124
+
find "$out" \( -type l -o -type f \) | while read -r item; do
125
+
# if item is a symlink, we want to (recursively) find the file it
126
+
# points to, read it, and if it contains $pkg, overwrite the symlink
127
+
# with a regular file to replace $pkg with $out
128
+
if [ -L "$item" ]; then
129
+
# redirection is to ignore broken symlinks
130
+
target=$(readlink -f "$item" 2>/dev/null || true)
131
+
132
+
# if our target is a nonempty file containing pkg, replace item with target
133
+
if [ -n "$target" ] && [ -f "$target" ] && grep -F -q "${pkg}" "$target"; then
134
+
rm "$item"
135
+
cp "$target" "$item"
136
+
# otherwise, skip the file replacement code
137
+
else
138
+
continue
139
+
fi
140
+
fi
141
+
142
+
# $item is guaranteed to be a regular file
143
+
if grep -F -q "${pkg}" "$item"; then
144
+
# ensure $item is writeable
145
+
[ -w "$item" ] || chmod +w "$item"
146
+
# replace all occurances of $pkg with $out
147
+
sed -i "s|${pkg}|$out|g" "$item" || true
148
+
fi
149
+
done
150
+
'';
151
+
in
152
+
pkgs.symlinkJoin {
153
+
inherit pname;
154
+
inherit version;
155
+
passthru = (pkg.passthru or { }) // {
156
+
unwrapped = pkg;
157
+
158
+
override =
159
+
overrideArgs:
160
+
let
161
+
newPkg = pkg.override overrideArgs;
162
+
newArgs = args // {
163
+
pkg = newPkg;
164
+
};
165
+
in
166
+
wrap newArgs;
167
+
168
+
overrideAttrs =
169
+
f:
170
+
let
171
+
newPkg = pkg.overrideAttrs f;
172
+
newArgs = args // {
173
+
pkg = newPkg;
174
+
};
175
+
in
176
+
wrap newArgs;
177
+
};
178
+
meta = pkg.meta or { };
179
+
paths = [ pkg ];
180
+
buildInputs = [ pkgs.makeWrapper ] ++ additionalDependencies;
181
+
postBuild = lib.concatStringsSep "\n" (wrapCommands ++ [ fixReferences ]);
182
+
};
183
+
in
184
+
wrap