refactor: rename modules folder

This commit is contained in:
Mohammad Rafiq 2025-04-10 16:28:33 +08:00
parent f082ed8ac0
commit 2a80ef07bf
No known key found for this signature in database
69 changed files with 16 additions and 16 deletions

30
configs/boot.nix Normal file
View file

@ -0,0 +1,30 @@
{
pkgs,
modulesPath,
lib,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
loader = {
timeout = 5;
efi.canTouchEfiVariables = true;
};
kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
initrd.availableKernelModules = [
"ahci"
"nvme"
"sd_mod"
"usb_storage"
"usbhid"
"xhci_pci"
"rtsx_pci_sdmmc"
];
};
services.dbus = {
enable = true;
};
}

View file

@ -0,0 +1,6 @@
{
boot.loader = {
systemd-boot.enable = true;
systemd-boot.configurationLimit = 5;
};
}

View file

@ -0,0 +1,15 @@
{
fileSystems."/" = {
device = "/dev/disk/by-uuid/e5005ea6-6c5a-4ab3-9767-ce7772582024";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/6BBE-0E70";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
}

View file

@ -0,0 +1,128 @@
{
inputs,
lib,
bootDisk,
...
}:
{
imports = [
inputs.disko.nixosModules.disko
inputs.impermanence.nixosModules.impermanence
];
# Disk Partitioning
disko.devices.disk.main = {
device = bootDisk;
type = "disk";
content.type = "gpt";
content.partitions = {
boot = {
name = "boot";
type = "EF02";
size = "1M";
priority = 1;
};
esp = {
name = "ESP";
type = "EF00";
size = "500M";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
swap = {
size = "4G";
content = {
type = "swap";
resumeDevice = true;
};
};
root = {
name = "root";
size = "100%";
content = {
type = "lvm_pv";
vg = "root_vg";
};
};
};
};
# Logical Volume Set up
disko.devices.lvm_vg.root_vg = {
type = "lvm_vg";
lvs.root = {
size = "100%FREE";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"/root".mountpoint = "/";
"/persist".mountpoint = "/persist";
"/persist".mountOptions = [
"subvol=persist"
"noatime"
];
"/nix".mountpoint = "/nix";
"/nix".mountOptions = [
"subvol=nix"
"noatime"
];
};
};
};
};
# Back up old roots and delete older ones
boot.initrd.postDeviceCommands = lib.mkAfter ''
mkdir /btrfs_tmp
mount /dev/root_vg/root /btrfs_tmp
if [[ -e /btrfs_tmp/root ]]; then
mkdir -p /btrfs_tmp/old_roots
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%M-%D_%H:%M:%S")
mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp"
fi
delete_subvolume_recursively() {
IFS=$'\n'
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
delete_subvolume_recursively "/btrfs_tmp/$i"
done
btrfs subvolume delete "$1"
}
for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do
delete_subvolume_recursively "$i"
done
btrfs subvolume create /btrfs_tmp/root
umount /btrfs_tmp
'';
# Directories to persist between boots
programs.fuse.userAllowOther = true;
fileSystems."/persist".neededForBoot = true;
environment.persistence."/persist" = {
# Hide the mounts from showing up in the file manager.
hideMounts = true;
files = [
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub"
"/etc/machine-id"
];
};
home-manager.users.rafiq = {
imports = [ inputs.impermanence.homeManagerModules.impermanence ];
home.persistence."/persist/home/rafiq" = {
files = [
".config/sops/age/keys.txt"
".ssh/id_ed25519"
];
# Allows root and other users to access the bindfs files.
allowOther = true;
};
};
}

29
configs/graphical.nix Normal file
View file

@ -0,0 +1,29 @@
{ pkgs, inputs, ... }:
with pkgs;
{
imports = [
./programs/clipse.nix
./programs/dunst.nix
./programs/firefox.nix
./programs/fuzzel.nix
./programs/getty.nix
./programs/hyprland.nix
./programs/hyprlock.nix
./programs/hyprshade.nix
./programs/kitty.nix
./programs/spicetify.nix
./programs/spotifyd.nix
./hardware/audio.nix
./hardware/bluetooth.nix
./hardware/udev.nix
];
environment.systemPackages = [
wl-clipboard
];
home-manager.users.rafiq.home.packages = [
hyprpicker
inputs.hyprcloser.packages.${pkgs.stdenv.hostPlatform.system}.default
];
}

View file

@ -0,0 +1,13 @@
{
security.rtkit.enable = true;
services.pipewire = {
enable = true;
extraConfig = { };
jack.enable = true;
pulse.enable = true;
alsa = {
enable = true;
support32Bit = true;
};
};
}

View file

@ -0,0 +1,6 @@
{
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
};
}

View file

@ -0,0 +1,6 @@
{ lib, config, ... }:
{
boot.kernelModules = [ "kvm-amd" ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,6 @@
{ lib, config, ... }:
{
boot.kernelModules = [ "kvm-intel" ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,45 @@
{
inputs,
pkgs,
config,
...
}:
{
# Accept the license by default; needed for some packages.
nixpkgs.config.nvidia.acceptLicense = true;
nix.settings = {
substituters = [ "https://cuda-maintainers.cachix.org" ];
trusted-public-keys = [
"cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E="
];
};
services.xserver.videoDrivers = [ "nvidia" ];
environment.variables = {
GBM_BACKEND = "nvidia-drm";
LIBVA_DRIVER_NAME = "nvidia";
__GLX_VENDOR_LIBRARY_NAME = "nvidia";
};
hardware = {
enableRedistributableFirmware = true;
nvidia-container-toolkit.enable = true;
graphics = {
enable = true;
extraPackages = with pkgs; [
nvidia-vaapi-driver # hardware acceleration
];
};
nvidia = {
modesetting.enable = true;
open = false;
nvidiaSettings = true;
nvidiaPersistenced = true;
package = config.boot.kernelPackages.nvidiaPackages.latest;
};
};
boot.initrd.availableKernelModules = [
"nvidia"
"nvidia_modeset"
"nvidia_uvm"
"nvidia_drm"
];
}

13
configs/hardware/udev.nix Normal file
View file

@ -0,0 +1,13 @@
{ pkgs, ... }:
{
hardware.keyboard.qmk.enable = true;
services.udev = {
packages = with pkgs; [
vial
via
qmk
qmk-udev-rules
qmk_hid
];
};
}

74
configs/networking.nix Normal file
View file

@ -0,0 +1,74 @@
{
hostname,
lib,
config,
...
}:
{
systemd.services.NetworkManager-dispatcher.serviceConfig = {
ProtectClock = true; # Prevents the service from changing the system time or timezone.
ProtectKernelTunables = true; # Restricts the service's ability to modify kernel parameters via sysctl.
ProtectKernelModules = true; # Prevents the service from loading or unloading kernel modules.
ProtectKernelLogs = true; # Prevents the service from reading kernel logs directly.
SystemCallFilter = "~@clock @cpu-emulation @debug @obsolete @module @mount @raw-io @reboot @swap"; # Whitelists system calls, blocking all others based on specified groups.
ProtectControlGroups = true; # Prevents the service from joining or modifying control groups other than its own.
RestrictNamespaces = true; # Enforces stricter namespace isolation, preventing user namespace creation/joining.
LockPersonality = true; # Disables the `personality()` system call, preventing execution domain changes.
MemoryDenyWriteExecute = true; # Prevents the service from mapping memory pages as both writable and executable (W^X).
RestrictRealtime = true; # Prevents the service from using real-time scheduling policies.
RestrictSUIDSGID = true; # Prevents the service from utilizing setuid/setgid functionality.
};
systemd.services.NetworkManager.serviceConfig = {
ProtectClock = true; # Prevents the service from changing the system time or timezone.
ProtectKernelTunables = true; # Restricts the service's ability to modify kernel parameters via sysctl.
ProtectKernelModules = true; # Prevents the service from loading or unloading kernel modules.
ProtectKernelLogs = true; # Prevents the service from reading kernel logs directly.
SystemCallFilter = "~@clock @cpu-emulation @debug @obsolete @module @mount @raw-io @reboot @swap"; # Whitelists system calls, blocking all others based on specified groups.
ProtectControlGroups = true; # Prevents the service from joining or modifying control groups other than its own.
RestrictNamespaces = true; # Enforces stricter namespace isolation, preventing user namespace creation/joining.
LockPersonality = true; # Disables the `personality()` system call, preventing execution domain changes.
MemoryDenyWriteExecute = true; # Prevents the service from mapping memory pages as both writable and executable (W^X).
RestrictRealtime = true; # Prevents the service from using real-time scheduling policies.
RestrictSUIDSGID = true; # Prevents the service from utilizing setuid/setgid functionality.
};
networking = {
hostName = hostname;
useDHCP = lib.mkDefault true;
networkmanager.enable = true;
networkmanager.wifi.backend = "iwd";
# Configures a simple stateful firewall.
# By default, it doesn't allow any incoming connections.
firewall = {
enable = true;
allowedTCPPorts = [
22 # SSH
5353 # spotifyd
];
allowedUDPPorts = [
5353 # spotifyd
];
};
interfaces.enp12s0.wakeOnLan.policy = [
"phy"
"unicast"
"multicast"
"broadcast"
"arp"
"magic"
"secureon"
];
interfaces.enp12s0.wakeOnLan.enable = true;
};
services.openssh = {
enable = true;
settings.PrintMotd = true;
};
services.tailscale = {
enable = true;
authKeyFile = config.sops.secrets.ts_auth_key.path;
};
}

25
configs/nix-config.nix Normal file
View file

@ -0,0 +1,25 @@
{
system.stateVersion = "24.11";
nixpkgs.config.allowUnfree = true;
nix.settings = {
experimental-features = [
"nix-command"
"flakes"
"pipe-operators"
];
trusted-users = [ "@wheel" ];
# Add binary caches to avoid having to compile them
substituters = [
"https://cache.nixos.org"
"https://nix-community.cachix.org"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
}

View file

@ -0,0 +1,21 @@
{ pkgs, ... }:
{
home-manager.users.rafiq = {
home.shellAliases = {
ai = "aichat -r %shell% -e";
};
home.packages = with pkgs; [
aichat
];
xdg.configFile."aichat/config.yaml" = {
text = ''
model: gemini:gemini-2.0-flash
clients:
- type: gemini
'';
};
};
}

View file

@ -0,0 +1,9 @@
{
home-manager.users.rafiq = {
services.clipse = {
enable = true;
historySize = 1000;
imageDisplay.type = "kitty";
};
};
}

View file

@ -0,0 +1,11 @@
{ inputs, ... }:
{
home-manager.users.rafiq = {
imports = [
inputs.nix-index-database.hmModules.nix-index
];
programs.nix-index.enable = true;
programs.nix-index-database.comma.enable = true;
};
}

View file

@ -0,0 +1,12 @@
{
# direnv lets us declare a .envrc in each project directory
# and updates the shell with the packages specified.
home-manager.users.rafiq = {
programs.direnv = {
enable = true;
enableBashIntegration = true;
nix-direnv.enable = true;
};
};
}

View file

@ -0,0 +1,5 @@
{
home-manager.users.rafiq = {
services.dunst.enable = true;
};
}

View file

@ -0,0 +1,23 @@
{
home-manager.users.rafiq = {
editorconfig = {
enable = true;
settings = {
"*" = {
end_of_line = "lf";
insert_final_newline = true;
trim_trailing_whitespace = true;
charset = "utf-8";
indent_style = "space";
indent_size = 2;
};
"package.json" = {
indent_style = "unset";
};
"*.lock" = {
indent_size = "unset";
};
};
};
};
}

View file

@ -0,0 +1,7 @@
{
home-manager.users.rafiq = {
programs.firefox = {
enable = true;
};
};
}

View file

@ -0,0 +1,15 @@
{
home-manager.users.rafiq = {
programs.fuzzel = {
enable = true;
settings = {
main = {
terminal = "kitty -1 -e";
layer = "top";
keyboard-focus = "on-demand";
list-executables-in-path = true;
};
};
};
};
}

7
configs/programs/fzf.nix Normal file
View file

@ -0,0 +1,7 @@
{
home-manager.users.rafiq = {
programs.fzf = {
enable = true;
};
};
}

View file

@ -0,0 +1,5 @@
{
services.getty = {
autologinUser = "rafiq";
};
}

21
configs/programs/git.nix Normal file
View file

@ -0,0 +1,21 @@
{
home-manager.users.rafiq = {
home.sessionVariables.GIT_CONFIG_GLOBAL = "$HOME/.config/git/config";
programs.git = {
enable = true;
userName = "Mohammad Rafiq";
userEmail = "mohammadrafiq567@gmail.com";
# Thanks to https://blog.notashelf.dev/posts/2025-02-24-ssh-signing-commits.html!
signing.key = "~/.ssh/id_ed25519.pub";
signing.signByDefault = true;
extraConfig = {
init.defaultBranch = "prime";
push.autoSetupRemote = true;
pull.rebase = false;
core.editor = "nvim";
gpg.format = "ssh";
};
};
};
}

View file

@ -0,0 +1,22 @@
{ pkgs, ... }:
{
home-manager.users.rafiq = {
home.packages = [ pkgs.fastfetch ];
home.shellAliases.fetch = "hyfetch";
programs.hyfetch = {
enable = true;
settings = {
preset = "bisexual";
mode = "rgb";
light_dark = "dark";
lightness = 0.5;
color_align = {
mode = "horizontal";
custom_colors = [ ];
fore_back = null;
};
backend = "fastfetch";
};
};
};
}

View file

@ -0,0 +1,152 @@
{ pkgs, ... }:
{
environment.loginShellInit = # sh
''
if [[ -z "$SSH_CLIENT" && -z "$SSH_CONNECTION" ]]; then
if uwsm check may-start; then
exec uwsm start hyprland-uwsm.desktop
fi
fi
'';
programs.hyprland = {
enable = true;
withUWSM = true;
};
home-manager.users.rafiq = {
xdg.configFile."uwsm/env".text = # sh
''
export XCURSOR_SIZE=32
# Nvidia Settings
export LIBVA_DRIVER_NAME=nvidia
export __GLX_VENDOR_LIBRARY_NAME=nvidia
export NVD_BACKEND=direct # needed for running vaapi-driver on later drivers"
export NIXOS_OZONE_WL=1
'';
wayland.windowManager.hyprland = {
enable = true;
package = null;
portalPackage = null;
systemd.enable = false;
settings = {
"$mainMonitor" = "desc:OOO AN-270W04K";
"$vertMonitor" = "desc:Philips Consumer Electronics Company PHL 246V5 AU11330000086";
"$mainMod" = "SUPER";
"$terminal" = "uwsm app -- kitty -1";
"$browser" = "uwsm app -- firefox";
"$launcher" = "uwsm app -- fuzzel";
"$lockscreen" = "uwsm app -- hyprlock";
"$clipboard" = "$terminal --class clipse -e clipse";
"$multiplexer" = "$terminal -e zellij";
# Programs to run at startup
exec-once = [
"uwsm app -- hyprlock"
"uwsm app -- clipse -listen"
"uwsm app -- hyprcloser"
"uwsm app -- hyprshade auto"
];
# Monitors
monitor = [
"$mainMonitor, 3840x2160@60, auto, 2"
"$vertMonitor, 1920x1080@60, auto-left, auto, transform, 3"
", preferred, auto, 1"
];
# Switching to the current workspace will switch to the previous
binds.workspace_back_and_forth = true;
cursor.default_monitor = "$mainMonitor";
# Windows
general = {
# Make there be no gaps in between windows or edges
border_size = 0;
no_border_on_floating = true;
gaps_in = 0;
gaps_out = 0;
resize_on_border = true;
};
decoration = {
active_opacity = 1;
inactive_opacity = 0.9;
};
windowrulev2 = [
"float, class:firefox, title:Picture-in-Picture"
"float, class:(clipse)"
"move cursor 0 0, class:(clipse)"
"size 622 652, class:(clipse)"
"noanim, class:(clipse)"
];
animation = [
"workspaces, 0, , "
];
# Keybinds
bind = [
"$mainMod, W, killactive"
"$mainMod, M, exec, uwsm stop"
# Launch utilities
"$mainMod, return, exec, $multiplexer"
"$mainMod, O, exec, $browser"
"$mainMod, Escape, exec, $lockscreen"
"$mainMod, Space, exec, $launcher"
"$mainMod, V, exec, $clipboard"
"$mainMod_SHIFT, A, exec, hyprpicker -a"
# move between windows
"$mainMod, H, cyclenext, visible"
"$mainMod, L, cyclenext, visible prev"
# HJKL to move a window
"$mainMod_ALT, H, movewindow, l"
"$mainMod_ALT, J, movewindow, d"
"$mainMod_ALT, K, movewindow, u"
"$mainMod_ALT, L, movewindow, r"
# HJKL to resize a window
"ALT_SHIFT, H, resizeactive, -10% 0"
"ALT_SHIFT, J, resizeactive, 0 -10%"
"ALT_SHIFT, K, resizeactive, 0 10%"
"ALT_SHIFT, L, resizeactive, 10% 0"
# H and L to move between workspaces on the current monitor including creation
"$mainMod_CTRL, H, workspace, r-1"
"$mainMod_CTRL, L, workspace, r+1"
"SUPER, 7, exec, ${pkgs.playerctl}/bin/playerctl previous"
"SUPER, 8, exec, ${pkgs.playerctl}/bin/playerctl play-pause"
"SUPER, 9, exec, ${pkgs.playerctl}/bin/playerctl next"
];
# Repeat when held
bindle = [
# Keyboard Media Keys
"SUPER, equal, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"
"SUPER, minus, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%-"
];
bindm = [
"ALT, mouse:272, movewindow"
];
input = {
numlock_by_default = true;
follow_mouse = 2; # Click on a window to change focus
};
debug = {
damage_tracking = 0;
};
};
};
};
}

View file

@ -0,0 +1,62 @@
{
inputs,
hostname,
pkgs,
...
}:
let
cfg =
if hostname == "nemesis" then
{
mainMonitor = "HDMI-A-1";
}
else
{
mainMonitor = "";
};
in
{
security.pam.services.hyprlock = { };
home-manager.users.rafiq = {
programs.hyprlock = {
enable = true;
settings = {
general = {
hide_cursor = true;
ignore_empty_input = true;
};
background = {
blur_passes = 5;
blur_size = 5;
};
label = {
monitor = cfg.mainMonitor;
text = ''hi, $USER.'';
font_size = 32;
halign = "center";
valign = "center";
position = "0, 0";
zindex = 1;
shadow_passes = 5;
shadow_size = 5;
};
input-field = {
monitor = cfg.mainMonitor;
fade_on_empty = true;
size = "200, 45";
halign = "center";
valign = "center";
position = "0, -5%";
placeholder_text = "";
zindex = 1;
shadow_passes = 5;
shadow_size = 5;
};
};
};
};
}

View file

@ -0,0 +1,25 @@
{ inputs, pkgs, ... }:
{
home-manager.users.rafiq = {
home.packages = [ pkgs.hyprshade ];
xdg.configFile."hypr/hyprshade.toml" = {
enable = true;
text = # toml
''
[[shades]]
name = "vibrance"
default = true # will be activated when no other shader is scheduled
[[shades]]
name = "blue-light-filter"
start_time = 22:00:00
end_time = 08:00:00 # optional if more than one shader has start_time
'';
};
xdg.configFile."hypr/shaders" = {
enable = true;
recursive = true;
source = "${inputs.hyprshaders}/shaders";
};
};
}

View file

@ -0,0 +1,27 @@
{
services.kanata = {
enable = true;
keyboards.k14 = {
devices = [ "/dev/input/by-id/usb-Keychron_Keychron_K14-event-kbd" ];
extraDefCfg = "process-unmapped-keys yes";
config = # lisp
''
(defsrc)
(defvar
tap-timeout 200
home-row-hold-timeout 200
tt $tap-timeout
hrht $home-row-hold-timeout
)
(deflayermap (base)
;; tap caps lock as enter, hold as left ctrl
;; tap-hold-release will activate the hold action early
;; if another key is pressed while it is held.
CapsLock (tap-hold-release 200 200 Escape ControlLeft)
)
'';
};
};
}

View file

@ -0,0 +1,16 @@
{
home-manager.users.rafiq = {
home.sessionVariables.TERMINAL = "kitty";
programs.kitty = {
enable = true;
keybindings = {
"ctrl+equal" = "change_font_size current +2.0";
"ctrl+minus" = "change_font_size current -2.0";
};
settings = {
window_padding_width = 10;
confirm_os_window_close = 0;
};
};
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

7
configs/programs/nh.nix Normal file
View file

@ -0,0 +1,7 @@
{
home-manager.users.rafiq = {
programs.nh = {
enable = true;
};
};
}

93
configs/programs/nvf.nix Normal file
View file

@ -0,0 +1,93 @@
{ inputs, pkgs, ... }:
{
nix.settings.substituters = [ "https://nvf.cachix.org" ];
nix.settings.trusted-public-keys = [
"nvf.cachix.org-1:GMQWiUhZ6ux9D5CvFFMwnc2nFrUHTeGaXRlVBXo+naI="
];
home-manager.users.rafiq = {
imports = [
inputs.nvf.homeManagerModules.default
./nvf/input.nix
./nvf/languages.nix
./nvf/ui.nix
./nvf/utilities.nix
];
home.sessionVariables.EDITOR = "nvim";
programs.nvf = {
enable = true;
enableManpages = true;
settings.vim = {
viAlias = true;
vimAlias = true;
options = {
# Indentation
autoindent = true;
smartindent = true;
expandtab = true;
smarttab = true;
wrap = true;
shiftwidth = 2;
tabstop = 2;
foldlevel = 1000; # Open all folds by default
# Search
hlsearch = true;
ignorecase = true;
incsearch = true;
smartcase = true; # case-sensitive if search contains uppercase
# Visual
number = true;
cursorline = true;
visualbell = true;
termguicolors = true;
# Input
backspace = "indent,eol,start";
};
keymaps = [
{
desc = "Open the file path under the cursor, making the file if it doesn't exist.";
key = "gf";
mode = "n";
action = ":cd %:p:h<CR>:e <cfile><CR>";
silent = true;
}
{
desc = "Delete the previous word.";
key = "<C-BS>";
mode = "i";
action = "<C-W>";
silent = true;
}
{
desc = "Open the filetree.";
key = "t";
mode = "n";
action = ":Yazi<CR>";
silent = true;
}
];
luaConfigRC.turn_off_inline_diagnostics =
# lua
''
vim.diagnostic.config({
virtual_text = false -- turn off inline diagnostics
})
'';
extraPlugins = with pkgs.vimPlugins; {
yuck-vim = {
package = yuck-vim;
};
nvim-treesitter-parsers = {
package = nvim-treesitter-parsers.yuck;
};
nvim-parinfer = {
package = nvim-parinfer;
};
};
};
};
};
}

View file

@ -0,0 +1,69 @@
{ lib, ... }:
{
programs.nvf.settings.vim = {
autopairs.nvim-autopairs.enable = true;
snippets.luasnip = {
enable = true;
setupOpts.enable_autosnippets = true;
};
autocomplete = {
blink-cmp = {
enable = true;
friendly-snippets.enable = true;
setupOpts = {
enabled =
lib.generators.mkLuaInline
# lua
''
--- Disable completion for markdown
function()
return not vim.tbl_contains({"markdown"}, vim.bo.filetype)
and vim.bo.buftype ~= "prompt"
and vim.b.completion ~= false
end
'';
cmdline = {
enabled = true;
sources = null;
completion.menu.auto_show = false;
};
#completion.menu.auto_show =
# lib.generators.mkLuaInline
# # lua
# ''
# function(ctx)
# --- Get the cursor position from the current window
# local row, column = unpack(vim.api.nvim_win_get_cursor(0))
# --- Get the current row (1 is Neovim API giving us 1-based indexing)
# --- Get the current column but don't return negative numbers
# --- ignore_injections are to ignore embedded code
# --- success is the result, node is the syntax node object
# local success, node = pcall(vim.treesitter.get_node, {
# pos = {row - 1, math.max(0, column - 1)},
# ignore_injections = false
# })
# --- Types of nodes to ignore
# local reject = {"comment", "line_comment", "block_comment", "string_start", "string_content", "string_end" }
# --- If the node type is in the reject table, don't show the completion
# if success and node and vim.tbl_contains(reject, node:type()) then
# return false;
# end
# -- whatever other logic you want beyond this
# return true
# end
# '';
# menu.auto_show = false;
completion.documentation.auto_show_delay_ms = 0;
signature.enabled = true;
};
};
};
utility = {
motion = {
hop.enable = true; # <leader>h
precognition.enable = false;
};
yanky-nvim.enable = true;
};
};
}

View file

@ -0,0 +1,34 @@
{
programs.nvf.settings.vim.languages = {
# The below settings enable defaults for all languages
enableDAP = true;
enableExtraDiagnostics = true;
enableFormat = true;
enableLSP = true;
enableTreesitter = true;
# Enable specific languages
clang.enable = true;
css.enable = true;
lua.enable = true;
markdown.enable = true;
markdown.extensions.render-markdown-nvim.enable = true;
nix.enable = true;
nix.format.type = "nixfmt";
python.enable = true;
python.lsp.server = "python-lsp-server";
rust.enable = true;
rust.crates.enable = true;
ts.enable = true;
# Did not really check these
bash.enable = true;
csharp.enable = true;
go.enable = true;
haskell.enable = true;
html.enable = true;
java.enable = true;
sql.enable = true;
yaml.enable = true;
};
}

View file

@ -0,0 +1,52 @@
{
programs.nvf.settings.vim = {
lsp = {
formatOnSave = true;
lightbulb.enable = true;
lspkind.enable = true;
otter-nvim.enable = true;
trouble.enable = true;
};
binds = {
cheatsheet.enable = true;
whichKey.enable = true;
};
debugger.nvim-dap = {
enable = true;
ui.enable = true;
};
notes.todo-comments.enable = true;
telescope.enable = true;
statusline.lualine.enable = true;
treesitter = {
enable = true;
autotagHtml = true;
fold = true;
};
notify.nvim-notify.enable = true;
visuals = {
fidget-nvim.enable = true;
indent-blankline.enable = true;
rainbow-delimiters.enable = true;
nvim-web-devicons.enable = true;
tiny-devicons-auto-colors.enable = true;
};
ui = {
borders.enable = true;
breadcrumbs.enable = true;
breadcrumbs.navbuddy.enable = true;
colorizer.enable = true;
noice.enable = true;
nvim-ufo.enable = true;
};
utility = {
ccc.enable = true;
images.image-nvim = {
enable = true;
setupOpts.backend = "kitty";
};
yazi-nvim.enable = true;
yazi-nvim.setupOpts.open_for_directories = true; # FIXME: does this work with neotree?
};
};
}

View file

@ -0,0 +1,22 @@
{
programs.nvf.settings.vim = {
utility = {
direnv.enable = true;
nix-develop.enable = true;
leetcode-nvim = {
enable = true;
setupOpts = {
image_support = true; # requires image.nvim
lang = "rust";
};
};
mkdir.enable = true;
new-file-template = {
enable = true;
# add a directory containing lua/tempaltes/*.lua to vim.additionalRuntimePaths
# TODO: add for nix
};
};
session.nvim-session-manager.enable = true;
};
}

View file

@ -0,0 +1,40 @@
# Set up the terminal to read input immediately, without waiting for Enter.
# This is done using the `stty` command.
# `stty` controls terminal settings.
# `-icanon` disables canonical mode. In canonical mode, the terminal buffers input until a newline is received. Disabling it makes input available immediately.
# `min 1` specifies that at least 1 character should be read.
# `time 0` specifies that the read should return immediately if a character is available.
stty -icanon min 1 time 0
# Prompt the user to enter 'y' or 'n' to confirm or cancel the poweroff.
# `echo -n` prints the prompt without a trailing newline, so the input will appear on the same line.
echo -n "Poweroff system? (y/n) [n]: "
# Read a single character from the input and store it in the 'answer' variable.
# `read -n 1 answer` reads only 1 character.
read -n 1 answer
# Print a newline character after the input has been read.
# This makes the output more readable, as the subsequent messages will appear on a new line.
echo
# Restore the terminal settings to their default values.
# This is important, as leaving the terminal in non-canonical mode can cause unexpected behavior.
# `stty icanon` re-enables canonical mode.
stty icanon
# Check the value of the 'answer' variable.
# `[[ ... ]]` is a more robust and feature-rich way to perform conditional tests than `[ ... ]`.
# `"y"` matches only the lowercase "y". If you want case-insensitive matching, consider using `[[ ${answer,,} == "y" ]]` (converts answer to lowercase).
if [[ "$answer" == "y" ]]; then
# If the user entered 'y', proceed with the poweroff.
echo "Powering off..."
# Execute the systemctl poweroff command with root privileges using sudo.
# `sudo` allows you to run commands as the superuser (root).
# `systemctl poweroff` sends the command to the systemd init system to shut down the machine.
sudo systemctl poweroff
else
# If the user entered anything other than 'y', cancel the poweroff.
echo "Poweroff cancelled."
fi

View file

@ -0,0 +1,68 @@
{ pkgs, ... }:
{
home-manager.users.rafiq = {
home.packages = [
(pkgs.writers.writePython3Bin "git-extract" {
libraries = with pkgs.python3Packages; [
magic
chardet
];
} (builtins.readFile ./git-extract.py))
(pkgs.writeShellScriptBin "rebuild" # sh
''
rebuild_remote() {
git add .
hostname=$1
builder="nemesis"
if [[ "''${hostname}" == "''${builder}" ]]; then
nh os switch .
else
nixos-rebuild switch \
--flake .#"''${hostname}" \
--target-host "$(whoami)"@"''${hostname}" \
--build-host "''${builder}" \
--use-remote-sudo
fi
}
main() {
if [[ $# -gt 1 ]]; then
echo "Only one argument is allowed. Pass in a hostname or all."
exit 1
elif [[ $# -lt 1 ]]; then
rebuild_remote "$HOSTNAME"
exit 0
fi
case "$1" in
all)
# Create a list of hostnames to rebuild
hosts=("nemesis" "apollo")
# Use parallel to rebuild each host
, parallel rebuild ::: "''${hosts[@]}"
# Check the exit code of parallel
if [[ $? -ne 0 ]]; then
echo "One or more rebuilds failed."
exit 1
else
exit 0
fi
;;
*)
rebuild_remote "$1"
exit 0
;;
esac
}
main "$@"
''
)
(pkgs.writeShellScriptBin "byebye" (builtins.readFile ./byebye.sh))
(pkgs.writeShellScriptBin "deploy" (builtins.readFile ./deploy.sh))
];
};
}

View file

@ -0,0 +1,81 @@
# Set default values
flake=".#default" # Default flake attribute if none is provided
target_host="nixos@<hostname>" # Default target host
# Process command-line arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--flake)
flake="$2"
shift # past argument
shift # past value
;;
--target-host)
target_host="$2"
shift # past argument
shift # past value
;;
*)
echo "Unknown option: $1" >&2
exit 1
;;
esac
done
# Prepare temporary directory and copy necessary files
root=$(mktemp -d)
# Files should be copied to the persist directory
# because that's where impermanence looks for them in.
mkdir -p "${root}"/persist
root_persist=${root}/persist
sudo cp --verbose --archive --parents /etc/ssh/ssh_host_* "${root_persist}"
sudo cp --verbose --archive --parents /home/rafiq/.ssh/id_ed25519 "${root_persist}"
sudo cp --verbose --archive --parents /home/rafiq/.config/sops/age/keys.txt "${root_persist}"
# Run nixos-anywhere
# Copy over the necesary files to the persist directory.
sudo nix run github:nix-community/nixos-anywhere -- \
--flake "${flake}" \
--target-host "${target_host}" \
--copy-host-keys \
--extra-files "${root}" \
--chown /persist/home/rafiq 1000:100 \
--chown /home/rafiq 1000:100
# Clean up the temporary directory
sudo rm -rf "$root"
# Wait for SSH to be back up
MAX_TRIES=60 # Maximum attempts
SLEEP_SECONDS=5 # Time to wait between attempts
tries=0
while true; do
tries=$((tries + 1))
# Check network reachability with ping
ping -c 1 "$(echo "${target_host}" | awk -F'@' '{print $NF}')" >/dev/null 2>&1 #Extract IP/hostname from username@host
if [ $? -eq 0 ]; then
# Network is reachable, try SSH
ssh -q -o "ConnectTimeout=5" "${target_host}" 'exit 0'
if [ $? -eq 0 ]; then
echo "SSH is up. Connecting..."
ssh "${target_host}" &&
nixos-rebuild switch --flake "${flake}" --use-remote-sudo --target-host "${target_host}"
exit 0
else
echo "SSH not yet available (attempt $tries/$MAX_TRIES). Waiting..."
fi
else
echo "Host is not reachable via ping (attempt $tries/$MAX_TRIES). Waiting..."
fi
if [ $tries -ge $MAX_TRIES ]; then
echo "Maximum attempts reached. SSH still not available."
exit 1
fi
sleep "$SLEEP_SECONDS"
done
echo "---DEPLOYMENT DONE!---"

View file

@ -0,0 +1,317 @@
# flake8: noqa: E501
import subprocess
import os
import tempfile
import shutil
import argparse
import magic
import chardet
import math
def is_ascii(file_path):
"""
Checks if a file contains only ASCII characters.
Args:
file_path (str): The path to the file.
Returns:
bool: True if the file contains only ASCII characters, False otherwise.
None: If the file does not exist.
"""
if not os.path.exists(file_path):
return None # Indicate file not found.
try:
with open(file_path, "r", encoding="ascii") as f:
f.read() # Attempt to read the entire file as ASCII
return True
except UnicodeDecodeError:
return False
def has_high_entropy(file_path, threshold=0.7):
"""
Checks if a file has high entropy, which might indicate it's not text.
Args:
file_path (str): The path to the file.
threshold (float): Entropy threshold above which it's considered high entropy.
Returns:
bool: True if entropy is above the threshold, False otherwise.
None: If the file does not exist.
"""
if not os.path.exists(file_path):
return None
try:
with open(file_path, "rb") as f: # Important: Read as binary
data = f.read()
except IOError:
return True # Treat as non-text if there is an I/O error
if not data:
return False # empty files considered text
entropy = calculate_entropy(data)
return entropy > threshold
def calculate_entropy(data):
"""
Calculates the entropy of a byte string.
Args:
data (bytes): The byte string.
Returns:
float: The entropy.
"""
if not data:
return 0.0 # Avoid log(0)
entropy = 0
data_length = len(data)
seen_bytes = bytearray(range(256)) # All possible byte values
counts = [0] * 256
for byte in data:
counts[byte] += 1
for byte in seen_bytes:
probability = float(counts[byte]) / data_length
if probability > 0:
entropy -= probability * math.log(probability, 2)
return entropy
def check_chardet_encoding(file_path, confidence_threshold=0.8):
"""
Checks the file encoding using chardet library.
Args:
file_path (str): The path to the file.
confidence_threshold (float): The minimum confidence level for encoding detection.
Returns:
bool: True if the encoding is detected with high confidence and is a text encoding, False otherwise.
None: If the file does not exist.
"""
if not os.path.exists(file_path):
return None
try:
with open(file_path, "rb") as f: # Important: Read as binary
data = f.read()
except IOError:
return False # If file can't be opened, assume it's not a simple text file.
if not data:
return True # Empty files are usually considered text
result = chardet.detect(data)
encoding = result["encoding"]
confidence = result["confidence"]
if encoding and confidence > confidence_threshold:
# Check if it's a recognized text encoding (not binary or None)
if encoding != "binary" and encoding is not None:
return True
return False
def is_text_file(file_path, aggressive=False):
"""
Wrapper function to check if a file is a text file using multiple methods.
Args:
file_path (str): The path to the file.
aggressive (bool, optional): If True, combines all checks for stricter verification.
If False, returns True if any check passes. Defaults to False.
Returns:
bool: True if the file is a text file, False otherwise.
None: If the file does not exist.
"""
if not os.path.exists(file_path):
return None
# Basic checks
ascii_check = is_ascii(file_path)
if ascii_check is None:
return None # File not found
if aggressive:
# Run all checks and require them all to pass
high_entropy_check = not has_high_entropy(
file_path
) # Invert because we want to know if it DOESN'T have high entropy
chardet_check = check_chardet_encoding(file_path)
return ascii_check and high_entropy_check and chardet_check
else:
# Run checks and return True if any of them pass
high_entropy_check = not has_high_entropy(file_path)
chardet_check = check_chardet_encoding(file_path)
return ascii_check or high_entropy_check or chardet_check
def get_latest_text_files_to_stdout(remote_repo_url=None, ignored_files=None):
"""
Checks out the latest commit from a remote Git repository or the current
working directory (if no URL is provided) to a temporary folder,
and then prints the contents of all files identified as text files to stdout,
prepended by their relative paths from the repository root, excluding specified
ignored files. Supports "!" to specify includes only.
Args:
remote_repo_url: The URL of the remote Git repository (optional). If None,
the current working directory is assumed to be a Git repo.
ignored_files: A list of files or directories to ignore (relative to the repo root).
If a list contains a value starting with "!", it means "include only".
"""
temp_dir = None
if ignored_files is None:
ignored_files = []
# Ensure .git and .gitignore are always ignored (unless include only is specified)
include_only = any(item.startswith("!") for item in ignored_files)
if not include_only:
ignored_files.extend([".git", ".gitignore"])
ignored_files = list(set(ignored_files)) # remove duplicates
# Determine if "include only" is active and extract the include paths
include_only = any(item.startswith("!") for item in ignored_files)
include_paths = [item[1:] for item in ignored_files if item.startswith("!")]
ignore_paths = [item for item in ignored_files if not item.startswith("!")]
try:
# Create a temporary directory
temp_dir = tempfile.mkdtemp()
# Clone the repository, but only the latest commit (shallow clone)
clone_command = ["git", "clone", "--depth", "1"]
if remote_repo_url:
clone_command.extend([remote_repo_url, temp_dir])
else:
# Check if the current directory is a Git repository.
try:
subprocess.run(
["git", "rev-parse", "--is-inside-work-tree"],
check=True,
capture_output=True,
text=True,
cwd=os.getcwd(),
) # run in current directory
except subprocess.CalledProcessError:
raise ValueError(
"No Git repository URL provided and current directory is not a Git repository."
)
clone_command.extend([os.getcwd(), temp_dir]) # clone current dir to temp
subprocess.run(clone_command, check=True, capture_output=True, text=True)
# Find all files and filter for text files
text_files = []
for root, _, files in os.walk(temp_dir):
for file in files:
file_path = os.path.join(root, file)
relative_path = os.path.relpath(file_path, temp_dir)
if include_only:
# Include only logic
include = False
for include_path in include_paths:
if relative_path.startswith(include_path):
include = True
break
if not include:
continue # Skip if not in include paths
else:
# Ignore logic (standard ignore)
ignore = False
path_components = relative_path.split(
os.sep
) # split based on OS-specific path separator
current_path = ""
for component in path_components:
current_path = (
os.path.join(current_path, component)
if current_path
else component
) # prevent empty first join
if current_path in ignore_paths:
ignore = True
break
if ignore:
continue
if is_text_file(file_path): # Use the is_text_file function
text_files.append(file_path)
# Print the contents of each text file, prepended by its relative path
for file_path in text_files:
relative_path = os.path.relpath(file_path, temp_dir)
print(f"--- {relative_path} ---")
try:
with open(file_path, "r", encoding="utf-8") as f: # Use UTF-8 encoding
print(f.read())
except UnicodeDecodeError:
print(
f"Error: Could not decode file {relative_path} using UTF-8. Skipping file contents."
) # handle binary or other non-UTF-8 encodings
print() # Add a blank line between files
except subprocess.CalledProcessError as e:
print(f"Error executing Git command: {e.stderr}")
except ValueError as e:
print(e)
except Exception as e:
print(f"An error occurred: {e}")
finally:
# Clean up the temporary directory
if temp_dir:
shutil.rmtree(temp_dir)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Checkout and print text files from a remote Git repository."
)
parser.add_argument(
"-r",
"--repo",
required=False,
help="The URL of the remote Git repository. If not provided, the current directory is used if it's a Git repository.",
)
parser.add_argument(
"-i",
"--ignored-files",
nargs="+",
default=[],
help="Files or directories to ignore (space-separated). Use !<path> to specify include only.",
)
args = parser.parse_args()
remote_repository_url = args.repo
ignored_files = args.ignored_files
# Verify the URL only if it's provided
if remote_repository_url:
if (
"github.com" not in remote_repository_url
and "gitlab.com" not in remote_repository_url
and "bitbucket.org" not in remote_repository_url
):
print(
"Warning: This script is designed for common public repository hosting providers. Ensure the Git URL is correct."
)
get_latest_text_files_to_stdout(remote_repository_url, ignored_files)

View file

@ -0,0 +1,23 @@
{
inputs,
pkgs,
...
}:
let
spicePkgs = inputs.spicetify-nix.legacyPackages.${pkgs.stdenv.system};
in
{
home-manager.users.rafiq = {
imports = [
inputs.spicetify-nix.homeManagerModules.spicetify
];
programs.spicetify = {
enable = true;
spotifyLaunchFlags = "--enable-features=UseOzonePlatform --ozone-platform=wayland";
windowManagerPatch = true;
enabledCustomApps = with spicePkgs.apps; [
marketplace
];
};
};
}

View file

@ -0,0 +1,13 @@
{ hostname, ... }:
{
home-manager.users.rafiq.services.spotifyd = {
enable = true;
settings = {
global = {
device_name = "${hostname}";
device_type = "computer";
zeroconf_port = 5353;
};
};
};
}

View file

@ -0,0 +1,16 @@
{
home-manager.users.rafiq = {
programs.starship = {
enable = true;
settings = {
add_newline = false;
format = "$character";
right_format = "$all";
character = {
success_symbol = "[\\$](bold green)";
error_symbol = "[\\$](bold red)";
};
};
};
};
}

View file

@ -0,0 +1,36 @@
{ inputs, ... }:
let
opacity = 0.8;
toImport = [
./themes/cursors/banana-cursor.nix
./themes/colourschemes/darkviolet.nix
./themes/fonts/sauce-code-pro.nix
{
# Put options that exist in both NixOS and home-manager modules here.
stylix = {
enable = true;
image = ./media/wallpaper.jpg;
opacity = {
applications = opacity;
desktop = opacity;
popups = opacity;
terminal = opacity;
};
};
}
];
in
{
# Enable basic fonts for reasonable Unicode coverage
fonts.enableDefaultPackages = true;
imports = [ inputs.stylix.nixosModules.stylix ] ++ toImport;
home-manager.users.rafiq.imports = [ inputs.stylix.homeManagerModules.stylix ] ++ toImport;
# Put options that only exist in the NixOS module here.
stylix.homeManagerIntegration.autoImport = false;
stylix.homeManagerIntegration.followSystem = false;
# Put options that only exist in the home-manager module here.
# home-manager.users.rafiq.stylix = {};
}

View file

@ -0,0 +1,8 @@
{
home-manager.users.rafiq = {
programs.tealdeer = {
enable = true;
enableAutoUpdates = true;
};
};
}

View file

@ -0,0 +1,4 @@
{ pkgs, ... }:
{
stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/3024.yaml";
}

View file

@ -0,0 +1,4 @@
{ pkgs, ... }:
{
stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/black-metal.yaml";
}

View file

@ -0,0 +1,4 @@
{ pkgs, ... }:
{
stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/bright.yaml";
}

View file

@ -0,0 +1,4 @@
{ pkgs, ... }:
{
stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/catppuccin-mocha.yaml";
}

View file

@ -0,0 +1,4 @@
{ pkgs, ... }:
{
stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/darkviolet.yaml";
}

View file

@ -0,0 +1,8 @@
{ pkgs, ... }:
{
stylix.cursor = {
name = "Banana";
package = pkgs.banana-cursor;
size = 22;
};
}

View file

@ -0,0 +1,29 @@
{pkgs, ...}: {
fonts.packages = with pkgs; [
nerd-fonts._0xproto
];
stylix.fonts = {
serif = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "0xProto Nerd Font";
};
sansSerif = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "0xProto Nerd Font";
};
emoji = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "0xProto Nerd Font";
};
monospace = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "0xProto Nerd Font Mono";
};
sizes = {
applications = 16;
desktop = 12;
popups = 12;
terminal = 16;
};
};
}

View file

@ -0,0 +1,29 @@
{pkgs, ...}: {
fonts.packages = with pkgs; [
nerd-fonts._3270
];
stylix.fonts = {
serif = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "3270 Nerd Font";
};
sansSerif = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "3270 Nerd Font";
};
emoji = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "3270 Nerd Font";
};
monospace = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "3270 Nerd Font Mono";
};
sizes = {
applications = 16;
desktop = 12;
popups = 12;
terminal = 16;
};
};
}

View file

@ -0,0 +1,21 @@
{ pkgs, ... }:
{
stylix.fonts = {
# packages = [ pkgs.nerd-fonts.sauce-code-pro ];
emoji.name = "SauceCodePro Nerd Font";
emoji.package = pkgs.nerd-fonts.sauce-code-pro;
monospace.name = "SauceCodePro Nerd Font Mono";
monospace.package = pkgs.nerd-fonts.sauce-code-pro;
sansSerif.name = "SauceCodePro Nerd Font";
sansSerif.package = pkgs.nerd-fonts.sauce-code-pro;
serif.name = "SauceCodePro Nerd Font";
serif.package = pkgs.nerd-fonts.sauce-code-pro;
sizes = {
applications = 16;
desktop = 12;
popups = 12;
terminal = 16;
};
};
}

View file

@ -0,0 +1,29 @@
{pkgs, ...}: {
fonts.packages = with pkgs; [
nerd-fonts.terminess-ttf
];
stylix.fonts = {
serif = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "Terminess Nerd Font";
};
sansSerif = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "Terminess Nerd Font";
};
emoji = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "Terminess Nerd Font";
};
monospace = {
package = pkgs.nerd-fonts.terminess-ttf;
name = "Terminess Nerd Font Mono";
};
sizes = {
applications = 16;
desktop = 12;
popups = 12;
terminal = 16;
};
};
}

128
configs/programs/yazi.nix Normal file
View file

@ -0,0 +1,128 @@
{
inputs,
pkgs,
...
}:
let
yazi-plugins = pkgs.fetchFromGitHub {
owner = "yazi-rs";
repo = "plugins";
rev = "273019910c1111a388dd20e057606016f4bd0d17";
hash = "sha256-80mR86UWgD11XuzpVNn56fmGRkvj0af2cFaZkU8M31I=";
};
in
{
home-manager.users.rafiq = {
programs.yazi = {
enable = true;
shellWrapperName = "y";
# yazi.toml
settings = {
manager = {
sort_by = "natural"; # Sort naturally, e.g. 1.md < 2.md < 10.md
sort_translit = true; # Transliterate filenames for sorting
show_hidden = true;
};
plugin = {
prepend_preloaders = [
{
mime = "{audio,video,image}/*";
run = "mediainfo";
}
{
mime = "application/subrip";
run = "mediainfo";
}
];
prepend_previewers = [
{
name = "*.md";
run = "glow";
}
{
mime = "{audio,video,image}/*";
run = "mediainfo";
}
{
mime = "application/subrip";
run = "mediainfo";
}
];
prepend_fetchers = [
{
id = "git";
name = "*";
run = "git";
}
{
id = "git";
name = "*/";
run = "git";
}
];
};
};
# ~/.config/yazi/keymap.toml
keymap = {
manager.prepend_keymap = [
{
on = "l";
run = "plugin smart-enter";
desc = "Enter the child directory or open the file.";
}
{
on = "M";
run = "plugin mount";
desc = "Open the mount.yazi menu.";
}
];
};
plugins = {
full-border = "${yazi-plugins}/full-border.yazi";
smart-enter = "${yazi-plugins}/smart-enter.yazi";
git = "${yazi-plugins}/git.yazi";
mount = "${yazi-plugins}/mount.yazi";
glow = pkgs.fetchFromGitHub {
owner = "Reledia";
repo = "glow.yazi";
rev = "c76bf4fb612079480d305fe6fe570bddfe4f99d3";
sha256 = "sha256-DPud1Mfagl2z490f5L69ZPnZmVCa0ROXtFeDbEegBBU=";
};
mediainfo = pkgs.fetchFromGitHub {
owner = "boydaihungst";
repo = "mediainfo.yazi";
rev = "447fe95239a488459cfdbd12f3293d91ac6ae0d7";
sha256 = "sha256-U6rr3TrFTtnibrwJdJ4rN2Xco4Bt4QbwEVUTNXlWRps=";
};
starship = pkgs.fetchFromGitHub {
owner = "Rolv-Apneseth";
repo = "starship.yazi";
rev = "6c639b474aabb17f5fecce18a4c97bf90b016512";
sha256 = "sha256-bhLUziCDnF4QDCyysRn7Az35RAy8ibZIVUzoPgyEO1A=";
};
};
initLua = ''
require("full-border"):setup()
require("git"):setup()
require("starship"):setup({
config_file = "${./yazi/starship.toml}",
})
'';
};
home.packages = with pkgs; [
jq # JSON preview
poppler_utils # PDF preview
_7zz # archive extraction and preview
ffmpeg
ffmpegthumbnailer # video thumbnails
fd # file searching
ripgrep # file content searching
fzf # quick file subtree navigation
zoxide # historical directories navigation
imagemagick # SVG, font, HEIC, JPEG preview
chafa # image/gif preview
glow # markdown preview
mediainfo # media metadata
];
};
}

View file

@ -0,0 +1 @@
format = "$all"

View file

@ -0,0 +1,27 @@
{
home-manager.users.rafiq = {
programs.zellij = {
enable = true;
attachExistingSession = true;
settings = {
show_startup_tips = false;
pane_frames = false;
keybinds.unbind = [
"Ctrl h"
];
};
};
xdg.configFile."zellij/layouts/default.kdl".text = # kdl
''
layout {
pane
pane size=1 borderless=true {
plugin location="tab-bar"
}
pane size=1 borderless=true {
plugin location="status-bar"
}
}
'';
};
}

View file

@ -0,0 +1,7 @@
{
home-manager.users.rafiq = {
programs.zoxide = {
enable = true;
};
};
}

36
configs/programs/zsh.nix Normal file
View file

@ -0,0 +1,36 @@
{
pkgs,
config,
...
}:
{
programs.zsh = {
enable = true;
};
users.defaultUserShell = pkgs.zsh;
environment.pathsToLink = [ "/share/zsh" ]; # enables completion
home-manager.users.rafiq = {
programs.zsh = {
enable = true;
enableCompletion = true;
enableVteIntegration = true;
dirHashes = {
repos = "$HOME/GitRepos";
dl = "$HOME/Downloads";
};
initContent = # zsh
''
# Bind CTRL+Backspace to delete whole word
bindkey '^H' backward-kill-word
'';
# TODO: Look into whether we need to add the history attribute
plugins = [
{
name = "vi-mode";
src = pkgs.zsh-vi-mode;
file = "share/zsh-vi-mode/zsh-vi-mode.plugin.zsh";
}
];
};
};
}

View file

@ -0,0 +1,13 @@
keys:
- &admin age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6
- &nemesis age1sq4n2ywk6h94a0r5rye6vzkqy5x6ae736faqregz8u2ku8ttepeqqh5crh
- &apollo age1yputfxttcyw9w6e9l3tkdyw73tr6z20r90twmrpktl44alywnu5s934fx9
- &orpheus age18jrr030n2u3wn4pvrsxv0jwgyr20pr0fqhtyk3pk4880pd3a69wqhz8rec
creation_rules:
- path_regex: .(yaml|json|env|ini)$
key_groups:
- age:
- *admin
- *nemesis
- *apollo
- *orpheus

View file

@ -0,0 +1,48 @@
ts_auth_key: ENC[AES256_GCM,data:2/pabfBT8KAGLKDytTMrhSBX8xr/TyJbX0mAsMlzmniyK9GT0xTAq3LsRfNLyCitSVauWIXwPYFia78NCw==,iv:PBDp4+SP9yVRJtmMmvJxUQju6qTOB7cJGSQZIbRSLm8=,tag:ZYDRlMrmmwwvxs71IV3dmQ==,type:str]
cwp_jira_link: ENC[AES256_GCM,data:7YwR5ajQDcyZgUGgMonajBV7DG/wlxsbxpiagMaPCBk=,iv:loFSGCV4no/azjIRYxjZHDkrrJmH0nzGlF8t0o0yfo4=,tag:pQYLLq4fu7T8Z03GvrJ+3A==,type:str]
cwp_jira_pat: ENC[AES256_GCM,data:+4VnPikwuSPHdPj9xihuFeht1FPYdZHcHxYNjKMwU2MU7VC4cOUA9vpcEgk=,iv:8f8Z/V9LnuTFdCsqJhaa55BL0ibgSW8PUQoW7FxAOZE=,tag:XL/Xf1QaNLiLT2m/dWcrKw==,type:str]
gemini_api_key: ENC[AES256_GCM,data:Kh1Kya8O6lqN0MMK1OMn/BHw51XDOAroSrOL3h4K8r6VorAwHTZw,iv:Gxg13mHBID7Gv4du+484IF1q7LFOCvtyzWMHG+IBUVM=,tag:jcjmKveybkET4RFOV4F8PQ==,type:str]
rafiq:
password: ENC[AES256_GCM,data:jzCXis5eIJpbWjsPMDVNZvMCbqp7QCUd7Drya0Al3QO0ExsoE6CNVzrbw4AyvKEgiUd0y9a5rKiwUBwGUoYVwxK0tkrOnB37+g==,iv:SsQIUB8OxgnxvjAyrfZzgEdGbaGGrL7zVwO5Of9D/Xw=,tag:iHNY8+nI9RnuM58SmGrV6Q==,type:str]
sops:
age:
- recipient: age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpeDl4RWdJS0l5UXZ0VWZH
WGRJNUR5aFk4NE5BUHNZcWpqdE05Q3hadFU0CkQ3VnZFbnl2RmRxcS96ZUJvYkVM
dXlrTFNMVmlrdEJTanFxem92bWFzVDAKLS0tIHVpRC9jOWs4STVhME1udU9Vb1Ni
eHZTcTcwaDZUTVU2STZuZlMwanZmd1UKHUsjun7v6OtEXoGM62H90e2fIX0ree6D
QWIGmAd8ZrzmfcgduPnq0h77TTBG7OGnVfeSNpG+l3s2U7RvNLBH5A==
-----END AGE ENCRYPTED FILE-----
- recipient: age1sq4n2ywk6h94a0r5rye6vzkqy5x6ae736faqregz8u2ku8ttepeqqh5crh
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCSXRIUURHQ2MrN3RjNyta
N0xJSjRPRjBwNTdHWXByeVprTjBndE1GVG1ZCi9HZXFqOFhOSU5CcEdGdnhLcHJI
RUlKSDJzNkJiZTMydERITmM0Z3JSTVEKLS0tIDFMUFovWFFYY0xLQW9aL0Q3RVph
eHpJK2dUMzVva0hiT2NqcDlKUTJ3cVkKfg18Tyi3vZRCb/7drrfH78ymow1N0/y3
QPwadV/rddQypO4tsags7z1POP3ryhSwPonjGacR99ziKWAsfYso5A==
-----END AGE ENCRYPTED FILE-----
- recipient: age1yputfxttcyw9w6e9l3tkdyw73tr6z20r90twmrpktl44alywnu5s934fx9
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3VEFwbXQ2T3pCMUg4ZXpL
OFlHZkJXOUpEVWFxSERqczQ5eDZpMExrQVRBCnlqYkhVY2QxSnBzRUJtTjR1dWpZ
VzZUbTVNMzFDMXpUQmNrWmIweEFSQkEKLS0tIDJOMjhNa2lYOGs2czVnNktVTk9F
eDM3eUhMRzFWMGV1aXV6dVhCd3V5SFUKKPAh+O5Sha63HNhCu73Zyy3qmkowD9Ro
Zfw6rioUMofa9TZX7D1hX4HsNTGUhyMgx9qoTGOJoED3H31D/+fRVw==
-----END AGE ENCRYPTED FILE-----
- recipient: age18jrr030n2u3wn4pvrsxv0jwgyr20pr0fqhtyk3pk4880pd3a69wqhz8rec
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBseXc4SDBtYTNEUERkUDJz
MnhjZk5hSGt6WUdXWnNhRWhSRytIeFpId2owCjdoWEFBNEIyNk5HYmVHbHNNdkpJ
cU45cytTQXpEaEIzaHg5dFZqNkxLUk0KLS0tIE43emd6b1pqOE1ndDhHYnY3TUNM
TktUSFpxTXdKMUhFQ1BOMmR1VVFWNVkKwy3T9QCsg6gXZilufMtbls0HB5of38Pr
YPzVeadsYlglg3/gBtDP4WyKBwYOQks2BbMTijqlMXBIl5JP7odVuw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-04-06T08:16:09Z"
mac: ENC[AES256_GCM,data:yQKGknVO8HEfYqmbINBro7gXePyjInx7jGhLTbsAoXLyxJuUQHAbieswAeLkTLgBqyfeAQHjYHro+s9eDPDitEi+/5fP/uLHK1HqyqZC9cAH35+8Th70hKxP7GAie9FQGkgcHYZYGe9nqFKHWwqu//l3UmdIdsnnxgC5dxnX2PI=,iv:E2a4GHVfXI6aGEsmkU9p7LRktPPJRUnYBgM9Qd3VayE=,tag:ot1AgSR+wzSD1orOnhROQQ==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.1

20
configs/security.nix Normal file
View file

@ -0,0 +1,20 @@
{ inputs, ... }:
{
imports = [
inputs.sops-nix.nixosModules.sops
];
sops = {
defaultSopsFile = ./secrets/secrets.yaml;
age.sshKeyPaths = [ "/home/rafiq/.ssh/id_ed25519" ];
secrets = {
"rafiq/password".neededForUsers = true;
ts_auth_key = { };
cwp_jira_link = { };
cwp_jira_pat = { };
gemini_api_key = { };
};
};
security.sudo.wheelNeedsPassword = false;
}

5
configs/services.nix Normal file
View file

@ -0,0 +1,5 @@
{
imports = [
./services/glance.nix
];
}

View file

@ -0,0 +1,55 @@
let
glancePort = 8080;
homeColumn = {
size = "full";
widgets = [
{
title = "Services";
type = "monitor";
cache = "1m";
sites = [
# https://simpleicons.org/
{
title = "Gitea";
icon = "si:gitea";
url = "https://gitea.bwfiq.com";
}
{
title = "LibreChat";
icon = "si:googlechat";
url = "https://chat.bwfiq.com";
}
];
}
{
title = "Feed";
type = "rss";
style = "detailed-list";
feeds = [
{
title = "selfh.st";
url = "https://selfh.st/rss/";
}
];
}
];
};
in
{
home-manager.users.rafiq.services.glance = {
enable = true;
settings.server = {
host = "0.0.0.0";
port = glancePort;
};
settings.pages = [
{
name = "Home";
columns = [
homeColumn
];
}
];
};
networking.firewall.allowedTCPPorts = [ glancePort ];
}

51
configs/shell.nix Normal file
View file

@ -0,0 +1,51 @@
{ pkgs, config, ... }:
{
imports = [
./programs/scripts
./programs/aichat.nix
./programs/comma.nix
./programs/direnv.nix
./programs/editorconfig.nix
./programs/fzf.nix
./programs/git.nix
./programs/hyfetch.nix
./programs/kanata.nix
./programs/nh.nix
./programs/nvf.nix
./programs/starship.nix
./programs/tealdeer.nix
./programs/yazi.nix
./programs/zellij.nix
./programs/zoxide.nix
./programs/zsh.nix
];
environment.shellInit = # sh
''
export CWP_JIRA_LINK=$(sudo cat ${config.sops.secrets.cwp_jira_link.path})
export CWP_JIRA_PAT=$(sudo cat ${config.sops.secrets.cwp_jira_pat.path})
export GEMINI_API_KEY=$(sudo cat ${config.sops.secrets.gemini_api_key.path})
'';
home-manager.users.rafiq.home = {
shell.enableShellIntegration = true;
shellAliases = {
gs = "git status";
cd = "z";
v = "$EDITOR";
g = "git";
l = "eza -1lah --git --time-style '+%Y-%m-%d %H:%M'";
# Thanks to https://www.reddit.com/r/NixOS/comments/fsummx/comment/fm3jbcm/!
list-all-packages = "nix-store --query --requisites /run/current-system | cut -d- -f2- | sort | uniq";
};
packages = with pkgs; [
bat
btop # add settings as home-manager module
devenv
ripgrep
ttyper
eza
];
};
}

51
configs/users.nix Normal file
View file

@ -0,0 +1,51 @@
{
inputs,
config,
specialArgs,
...
}:
{
imports = [
inputs.home-manager.nixosModules.home-manager
];
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = specialArgs;
};
time.timeZone = "Asia/Singapore";
i18n.defaultLocale = "en_SG.UTF-8";
users = {
mutableUsers = false; # Always reset users on system activation
groups.users = {
gid = 100;
members = [ "rafiq" ];
};
users.rafiq = {
isNormalUser = true;
description = "rafiq";
hashedPasswordFile = config.sops.secrets."rafiq/password".path;
uid = 1000;
linger = true; # keep user services running
extraGroups = [
"networkmanager"
"wheel"
"audio" # Pipewire
];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILdsZyY3gu8IGB8MzMnLdh+ClDxQQ2RYG9rkeetIKq8n"
];
};
};
home-manager.users.rafiq.home = {
username = "rafiq";
homeDirectory = "/home/rafiq";
stateVersion = "25.05";
};
}