From 2839045b9289f70460155546ef1a3559aa9f397e Mon Sep 17 00:00:00 2001 From: Crony Akatsuki Date: Mon, 12 Feb 2024 09:25:11 +0100 Subject: [PATCH] First commit. --- flake.lock | 235 ++++++++++ flake.nix | 33 ++ hosts/default/configuration.nix | 332 ++++++++++++++ hosts/default/confs/xmonad.hs | 305 +++++++++++++ hosts/default/hardware-configuration.nix | 39 ++ hosts/default/home.nix | 553 +++++++++++++++++++++++ 6 files changed, 1497 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 hosts/default/configuration.nix create mode 100644 hosts/default/confs/xmonad.hs create mode 100644 hosts/default/hardware-configuration.nix create mode 100644 hosts/default/home.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..c8c5794 --- /dev/null +++ b/flake.lock @@ -0,0 +1,235 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1706830856, + "narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "nixvim", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703887061, + "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1707467182, + "narHash": "sha256-/Bw/xgCXfj4nXDd8Xq+r1kaorfsYkkomMf5w5MpsDyA=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "5b9156fa9a8b8beba917b8f9adbfd27bf63e16af", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1706955260, + "narHash": "sha256-W3y0j77IDVbmbajudHoUr46RpswujUCl+D5Vru53UsI=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "880d9bc2110f7cae59698f715b8ca42cdc53670c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "nix-darwin": { + "inputs": { + "nixpkgs": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1706833576, + "narHash": "sha256-w7BL0EWRts+nD1lbLECIuz6fRzmmV+z8oWwoY7womR0=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "bdbae6ecff8fcc322bf6b9053c0b984912378af7", + "type": "github" + }, + "original": { + "owner": "lnl7", + "repo": "nix-darwin", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1707268954, + "narHash": "sha256-2en1kvde3cJVc3ZnTy8QeD2oKcseLFjYPLKhIGDanQ0=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "f8e2ebd66d097614d51a56a755450d4ae1632df1", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixvim": { + "inputs": { + "flake-parts": "flake-parts", + "home-manager": "home-manager_2", + "nix-darwin": "nix-darwin", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks": "pre-commit-hooks" + }, + "locked": { + "lastModified": 1707545157, + "narHash": "sha256-w4dubmw//nocfi2/KkvM1SLtDQUhIFfVsXDWf3zZTLk=", + "owner": "nix-community", + "repo": "nixvim", + "rev": "66c069c48db4b67fd0d536128b000684a5f72f5b", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixvim", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": [ + "nixvim", + "nixpkgs" + ], + "nixpkgs-stable": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1706424699, + "narHash": "sha256-Q3RBuOpZNH2eFA1e+IHgZLAOqDD9SKhJ/sszrL8bQD4=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "7c54e08a689b53c8a1e5d70169f2ec9e2a68ffaf", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "home-manager": "home-manager", + "nixpkgs": "nixpkgs", + "nixvim": "nixvim" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..84f8de8 --- /dev/null +++ b/flake.nix @@ -0,0 +1,33 @@ +{ + description = "Nixos config flake"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + nixvim = { + url = "github:nix-community/nixvim"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, ... }@inputs: + let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + in + { + + nixosConfigurations.default = nixpkgs.lib.nixosSystem { + specialArgs = {inherit inputs;}; + modules = [ + ./hosts/default/configuration.nix + inputs.home-manager.nixosModules.default + ]; + }; + }; +} diff --git a/hosts/default/configuration.nix b/hosts/default/configuration.nix new file mode 100644 index 0000000..fcef2c7 --- /dev/null +++ b/hosts/default/configuration.nix @@ -0,0 +1,332 @@ +{ config, pkgs, inputs, ... }: + +{ + imports = + [ + ./hardware-configuration.nix + inputs.home-manager.nixosModules.default + ]; + + # Bootloader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Modules + boot.blacklistedKernelModules = [ "rtl8xxxu" "iwlwifi"]; + boot.extraModulePackages = with config.boot.kernelPackages; [ + rtl8192eu + ]; + + # Use latest and greates kernel + # boot.kernelPackages = pkgs.linuxPackages_latest; + + # Set the hostname + networking.hostName = "nixos"; # Define your hostname. + + # Enable flakes + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + + # Disable hibernation, sleep and other friends + systemd.targets = { + sleep = { + enable = false; + unitConfig.DefaultDependencies = "no"; + }; + suspend = { + enable = false; + unitConfig.DefaultDependencies = "no"; + }; + hibernate = { + enable = false; + unitConfig.DefaultDependencies = "no"; + }; + "hybrid-sleep" = { + enable = false; + unitConfig.DefaultDependencies = "no"; + }; + }; + + # Enable networking + networking.networkmanager.enable = true; + networking.wireless.iwd.enable = true; + networking.networkmanager.wifi.backend = "iwd"; + networking.networkmanager.wifi.powersave = false; + networking.networkmanager.dns = "none"; + + # local nameservers + networking.nameservers = [ "127.0.0.1" "::1" ]; + + + # Dnscrypt for dns over https + services.dnscrypt-proxy2 = { + enable = true; + settings = { + ipv6_servers = true; + require_dnssec = true; + sources.public-resolvers = { + urls = [ + "https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md" + "https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md" + ]; + cache_file = "/var/lib/dnscrypt-proxy2/public-resolvers.md"; + minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3"; + }; + server_names = [ "mullvad-base-doh" ]; + }; + }; + + + # Set your time zone. + time.timeZone = "Europe/Zagreb"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + + i18n.extraLocaleSettings = { + LC_ADDRESS = "hr_HR.UTF-8"; + LC_IDENTIFICATION = "hr_HR.UTF-8"; + LC_MEASUREMENT = "hr_HR.UTF-8"; + LC_MONETARY = "hr_HR.UTF-8"; + LC_NAME = "hr_HR.UTF-8"; + LC_NUMERIC = "hr_HR.UTF-8"; + LC_PAPER = "hr_HR.UTF-8"; + LC_TELEPHONE = "hr_HR.UTF-8"; + LC_TIME = "hr_HR.UTF-8"; + }; + + # Enable the X11 windowing system. + services.xserver.enable = true; + + # Enable the KDE Plasma Desktop Environment. + services.xserver.displayManager.sddm = { + enable = true; + theme = "catppuccin-sddm-corners"; + # Fix keyboard showing up unnecesarilly + settings = { + General = { + InputMethod=""; + }; + }; + }; + services.xserver.desktopManager.plasma5.enable = true; + environment.plasma5.excludePackages = with pkgs.libsForQt5; [ + plasma-browser-integration + konsole + oxygen + ]; + + # Configure keymap in X11 + services.xserver.xkb = { + layout = "us"; + variant = ""; + options = "caps:escape"; + }; + + # Enable CUPS to print documents. + services.printing.enable = false; + + # Enable gvfs + services.gvfs.enable = true; + + # Enable sound with pipewire. + sound.enable = true; + hardware.pulseaudio.enable = false; + security.rtkit.enable = true; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + # If you want to use JACK applications, uncomment this + #jack.enable = true; + + # use the example session manager (no others are packaged yet so this is enabled by default, + # no need to redefine it in your config for now) + #media-session.enable = true; + }; + + # Enable touchpad support (enabled default in most desktopManager). + services.xserver.libinput.enable = true; + + # Enable OpenGL + hardware.opengl = { + enable = true; + driSupport = true; + driSupport32Bit = true; + }; + + hardware.nvidia = { + + # Modesetting is required. + modesetting.enable = true; + + # Nvidia power management. Experimental, and can cause sleep/suspend to fail. + powerManagement.enable = true; + # Fine-grained power management. Turns off GPU when not in use. + # Experimental and only works on modern Nvidia GPUs (Turing or newer). + powerManagement.finegrained = false; + + # Use the NVidia open source kernel module (not to be confused with the + # independent third-party "nouveau" open source driver). + # Support is limited to the Turing and later architectures. Full list of + # supported GPUs is at: + # https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus + # Only available from driver 515.43.04+ + # Currently alpha-quality/buggy, so false is currently the recommended setting. + open = false; + + # Enable the Nvidia settings menu, + # accessible via `nvidia-settings`. + nvidiaSettings = true; + + # Optionally, you may need to select the appropriate driver version for your specific GPU. + package = config.boot.kernelPackages.nvidiaPackages.stable; + }; + + hardware.nvidia.prime = { + reverseSync.enable = true; + # Make sure to use the correct Bus ID values for your system! + intelBusId = "PCI:5:0:0"; + nvidiaBusId = "PCI:1:0:0"; + }; + + # Enable bluetooth + hardware.bluetooth.enable = true; + + # Open Tablet Driver setup + hardware.opentabletdriver.enable = true; + + # Load nvidia driver for Xorg and Wayland + services.xserver.videoDrivers = [ "nvidia" ]; + + # Steam settings + programs.steam = { + enable = true; + remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play + dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server + }; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + neovim + usbutils + pciutils + lshw + vulkan-tools + restic + rsync + git + jq + wireguard-tools + unzip + gamemode + ipafont + ryzenadj + (catppuccin-kde.override { winDecStyles = ["classic" "modern"] ;}) + catppuccin-gtk + catppuccin-cursors.frappeRosewater + catppuccin-sddm-corners + (catppuccin-papirus-folders.override { flavor = "frappe"; accent = "pink"; }) + ]; + + networking.firewall = { + # if packets are still dropped, they will show up in dmesg + logReversePathDrops = true; + # wireguard trips rpfilter up + extraCommands = '' + ip46tables -t mangle -I nixos-fw-rpfilter -p udp -m udp --sport 51820 -j RETURN + ip46tables -t mangle -I nixos-fw-rpfilter -p udp -m udp --dport 51820 -j RETURN + ''; + extraStopCommands = '' + ip46tables -t mangle -D nixos-fw-rpfilter -p udp -m udp --sport 51820 -j RETURN || true + ip46tables -t mangle -D nixos-fw-rpfilter -p udp -m udp --dport 51820 -j RETURN || true + ''; + }; + + # Enable fstrim + services.fstrim.enable = true; + + # Enable ratbagd for mice configuration + services.ratbagd.enable = true; + + # Setup syncthing + services = { + syncthing = { + enable = true; + user = "crony"; + dataDir = "/home/crony/.local/sync"; + configDir = "/home/crony/.config/syncthing"; + }; + }; + + # Setting up zsh + programs.zsh.enable = true; + # For the completion plugin + environment.pathsToLink = [ "/share/zsh" ]; + + # Define a user account. Don't forget to set a password with ‘passwd’. + users.users.crony = { + isNormalUser = true; + description = "Crony"; + extraGroups = [ "networkmanager" "wheel" ]; + packages = with pkgs; [ + (retroarch.override { + cores = with libretro; [ + snes9x + ]; + }) + ]; + shell = pkgs.zsh; + }; + + home-manager = { + useGlobalPkgs = true; + extraSpecialArgs = {inherit inputs;}; + users = { + "crony" = import ./home.nix; + }; + }; + + # Allow for appimages + boot.binfmt.registrations.appimage = { + wrapInterpreterInShell = false; + interpreter = "${pkgs.appimage-run}/bin/appimage-run"; + recognitionType = "magic"; + offset = 0; + mask = ''\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff''; + magicOrExtension = ''\x7fELF....AI\x02''; + }; + + + # Some programs need SUID wrappers, can be configured further or are + # started in user sessions. + # programs.mtr.enable = true; + # programs.gnupg.agent = { + # enable = true; + # enableSSHSupport = true; + # }; + + # List services that you want to enable: + + # Enable the OpenSSH daemon. + # services.openssh.enable = true; + + # Open ports in the firewall. + # networking.firewall.allowedTCPPorts = [ ... ]; + # networking.firewall.allowedUDPPorts = [ ... ]; + # Or disable the firewall altogether. + # networking.firewall.enable = false; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "23.11"; # Did you read the comment? + +} diff --git a/hosts/default/confs/xmonad.hs b/hosts/default/confs/xmonad.hs new file mode 100644 index 0000000..0799112 --- /dev/null +++ b/hosts/default/confs/xmonad.hs @@ -0,0 +1,305 @@ +-- Base +import XMonad +import System.Exit +import qualified XMonad.StackSet as W + +-- Actions +import XMonad.Actions.CycleWS (toggleWS') +import XMonad.Actions.MouseResize +import XMonad.Actions.SinkAll (sinkAll) + +-- Data +import qualified Data.Map as M +import Data.Maybe (isJust) + +-- Hooks +import XMonad.Hooks.ManageHelpers +import XMonad.Hooks.StatusBar +import XMonad.Hooks.StatusBar.PP +import XMonad.Hooks.EwmhDesktops +import XMonad.Hooks.SetWMName +import XMonad.Hooks.InsertPosition + +-- Layout modifiers +import XMonad.Layout.Renamed +import XMonad.Layout.Spacing +import XMonad.Layout.NoBorders +import XMonad.Layout.SimplestFloat +import XMonad.Layout.LayoutModifier +import XMonad.Layout.ResizableTile +import XMonad.Layout.PerWorkspace +import XMonad.Layout.WindowArranger (windowArrange, WindowArrangerMsg(..)) + +-- Utils +import XMonad.Util.Loggers +import XMonad.Util.NamedScratchpad +import XMonad.Util.SpawnOnce +import XMonad.Util.EZConfig +import XMonad.Util.Hacks + +-- main loop +main :: IO () +main = xmonad + . ewmhFullscreen + . ewmh + . withEasySB (statusBarProp "xmobar ~/.config/xmobar/xmobarrc" (pure myXmobarPP)) toggleStrutsKey + $ myConfig + where + toggleStrutsKey :: XConfig Layout -> (KeyMask, KeySym) + toggleStrutsKey XConfig{ modMask = m } = (m, xK_F11) + +-- My config +myConfig = def + { modMask = myModMask + , layoutHook = myLayoutHook + , manageHook = insertPosition End Newer <+> myManageHook + , handleEventHook = trayerAboveXmobarEventHook + , focusFollowsMouse = myFocusFollowsMouse + , terminal = myTerminal + , borderWidth = myBorderWidth + , normalBorderColor = myNormalBorderColor + , focusedBorderColor = myFocusedBorderColor + , keys = myKeys + , workspaces = myWorkspaces + , startupHook = myStartupHook + } + +-- My variables +myModMask = mod4Mask +myTerminal = "alacritty" +myBorderWidth = 2 + +myFocusFollowsMouse :: Bool +myFocusFollowsMouse = False + +myNormalBorderColor = "#737994" +myFocusedBorderColor = "#c6d0f5" + +myWorkspaces = ["一","二","三","四","五","六","七","八","九"] + +-- My startup hook +myStartupHook :: X () +myStartupHook = do + spawn "killall trayer-srg" -- kill current trayer on each restart + spawnOnce "sxhkd -c $HOME/.config/sxhkd/general" + spawnOnce "gentoo-pipewire-launcher" + spawnOnce "transmission-daemon" + spawnOnce "syncthing" + spawnOnce "picom" + spawnOnce "clipmenud" + spawnOnce "dunst" + spawnOnce "keepassxc" + spawnOnce "/usr/libexec/polkit-gnome-authentication-agent-1" + spawn ("sleep 2 && trayer-srg --edge top --align right --widthtype request --padding 6 --iconspacing 7 --SetDockType true --SetPartialStrut true --expand true --monitor 1 --transparent true --alpha 0 --tint 0x303446 --height 24 -l") + setWMName "LG3D" -- Fix java programs + +-- My scratchpads +myScratchPads :: [NamedScratchpad] +myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm + , NS "wiki" spawnWiki findWiki manageWiki + , NS "notes" spawnNotes findNotes manageNotes + , NS "profanity" spawnProfanity findProfanity manageProfanity + , NS "godot" spawnGodot findGodot manageGodot + ] + where + spawnTerm = myTerminal ++ " --class scratchpad,scratchpad" + findTerm = className =? "scratchpad" + manageTerm = customFloating $ W.RationalRect l t w h + where + h = 0.8 + w = 0.8 + t = 0.9 -h + l = 0.9 -w + spawnWiki = myTerminal ++ " --class wiki,wiki -e wiki" + findWiki = className =? "wiki" + manageWiki = customFloating $ W.RationalRect l t w h + where + h = 0.8 + w = 0.8 + t = 0.9 -h + l = 0.9 -w + spawnNotes = myTerminal ++ " --class wiki,wiki -e notes" + findNotes = className =? "notes" + manageNotes = customFloating $ W.RationalRect l t w h + where + h = 0.8 + w = 0.8 + t = 0.9 -h + l = 0.9 -w + spawnProfanity = myTerminal ++ " --class profanity,profanity -e profanity" + findProfanity = className =? "profanity" + manageProfanity = customFloating $ W.RationalRect l t w h + where + h = 0.8 + w = 0.8 + t = 0.9 -h + l = 0.9 -w + spawnGodot = myTerminal ++ " --class godot,godot -e nvim --listen /tmp/godot.pipe" + findGodot = className =? "godot" + manageGodot = customFloating $ W.RationalRect l t w h + where + h = 0.8 + w = 0.8 + t = 0.9 -h + l = 0.9 -w + + +--Makes setting the spacingRaw simpler to write. The spacingRaw module adds a configurable amount of space around windows. +mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a +mySpacing i = spacingRaw False (Border i i i i) True (Border i i i i) True + +-- Below is a variation of the above except no borders are applied +-- if fewer than two windows. So a single window has no gaps. +mySpacing' :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a +mySpacing' i = spacingRaw True (Border i i i i) True (Border i i i i) True + +-- My layouts +tall = renamed [Replace "tall"] + $ withBorder myBorderWidth + $ mySpacing 4 + $ ResizableTall 1 (3/100) (1/2) [] +monocle = renamed [Replace "monocle"] + $ withBorder myBorderWidth + $ mySpacing 4 + $ Full +floats = renamed [Replace "floats"] + $ withBorder myBorderWidth + $ simplestFloat + +myLayoutHook = lessBorders OnlyScreenFloat + $ mouseResize + $ windowArrange + $ myDefaultLayout + where + myDefaultLayout = onWorkspaces [(myWorkspaces !! 0), (myWorkspaces !! 3), (myWorkspaces !! 4)] (monocle ||| floats ||| tall) + $ onWorkspace (myWorkspaces !! 5) (floats ||| tall ||| monocle) + $ tall + ||| monocle + ||| floats + +-- My manage hook +myManageHook :: ManageHook +myManageHook = composeAll + [ className =? "qutebrowser" --> doShiftAndGo ( myWorkspaces !! 0) + , className =? "newsboat" --> doShiftAndGo ( myWorkspaces !! 3) + , className =? "videos" --> doShiftAndGo ( myWorkspaces !! 3) + , className =? "ytfzf" --> doShiftAndGo ( myWorkspaces !! 3) + , className =? "lf" --> doShiftAndGo ( myWorkspaces !! 3) + , className =? "thunderbird" --> doShiftAndGo ( myWorkspaces !! 4) + , className =? "Ferdium" --> doShiftAndGo ( myWorkspaces !! 4) + , className =? "discord" --> doShiftAndGo ( myWorkspaces !! 4) + , className =? "tutanota-desktop" --> doShiftAndGo ( myWorkspaces !! 4) + , className =? "Lutris" --> doShiftAndGo ( myWorkspaces !! 5) + , className =? "steam" --> doShiftAndGo ( myWorkspaces !! 5) + , className =? "heroic" --> doShiftAndGo ( myWorkspaces !! 5) + , className =? "cartridges" --> doShiftAndGo ( myWorkspaces !! 5) + , className =? "Cemu" --> doShiftAndGo ( myWorkspaces !! 5) + , className =? "xemu" --> doShiftAndGo ( myWorkspaces !! 5) + , className =? "librewolf" --> doShiftAndGo ( myWorkspaces !! 8) + , isDialog --> doCenterFloat <+> doF W.swapUp + , className =? "Gimp" --> doFloat <+> doF W.swapUp + , className =? "confirm" --> doFloat <+> doF W.swapUp + , className =? "file_progress" --> doFloat <+> doF W.swapUp + , className =? "dialog" --> doFloat <+> doF W.swapUp + , className =? "download" --> doFloat <+> doF W.swapUp + , className =? "error" --> doFloat <+> doF W.swapUp + , className =? "notification" --> doFloat <+> doF W.swapUp + , className =? "splash" --> doFloat <+> doF W.swapUp + , className =? "toolbar" --> doFloat <+> doF W.swapUp + , className =? "pinentry-gtk-2" --> doFloat <+> doF W.swapUp + , className =? "Yad" --> doCenterFloat <+> doF W.swapUp + , className =? "badd" --> doCenterFloat <+> doF W.swapUp + , className =? "filepicker" --> doRectFloat (W.RationalRect (1/12) (1/12) (5/6) (5/6)) <+> doF W.swapUp + , isFullscreen --> doFullFloat + , namedScratchpadManageHook myScratchPads + ] + where + doShiftAndGo ws = doF (W.greedyView ws) <+> doShift ws + +-- My keybindings in a nice readable format +myKeys = \c -> mkKeymap c $ + [ ("M-S-q", kill) -- kill active window + , ("M-", sendMessage NextLayout) -- cycle layout + , ("M-S-", withFocused toggleFloat) -- toggle floating state of a window + , ("M-j", windows W.focusDown) -- Move focus down + , ("M-k", windows W.focusUp) -- Move focus up + , ("M-S-", windows W.swapMaster) -- Move Focused window to master + , ("M-S-j", windows W.swapDown) --Move window down the stack + , ("M-S-k", windows W.swapUp) -- Move window up the stack + , ("M-h", sendMessage Shrink) -- Shrink master + , ("M-l", sendMessage Expand) -- Expand master + , ("M-,", sendMessage (IncMasterN 1)) -- Increase master count + , ("M-.", sendMessage (IncMasterN (-1))) -- Decrease msaster count + , ("M-C-e", io (exitWith ExitSuccess)) -- Quit xmonad + , ("M-S-r", spawn "xmonad --recompile && xmonad --restart") -- Restart xmonad + , ("M-", toggleWS' ["NSP"]) -- Toogle last used workspace, ignoring named scratchpad + , ("M-s t", namedScratchpadAction myScratchPads "terminal") -- Toggle scratchpad + , ("M-s w", namedScratchpadAction myScratchPads "wiki") -- Toggle scratchpad + , ("M-s n", namedScratchpadAction myScratchPads "notes") -- Toggle scratchpad + , ("M-s p", namedScratchpadAction myScratchPads "profanity") -- Toggle scratchpad + , ("M-s g", namedScratchpadAction myScratchPads "godot") -- Toggle scratchpad + , ("M-1", viewDesktop 0) -- Check workspace 1 + , ("M-2", viewDesktop 1) -- Check workspace 2 + , ("M-3", viewDesktop 2) -- Check workspace 3 + , ("M-4", viewDesktop 3) -- Check workspace 4 + , ("M-5", viewDesktop 4) -- Check workspace 5 + , ("M-6", viewDesktop 5) -- Check workspace 6 + , ("M-7", viewDesktop 6) -- Check workspace 7 + , ("M-8", viewDesktop 7) -- Check workspace 8 + , ("M-9", viewDesktop 8) -- Check workspace 9 + , ("M-S-1", shiftWindow 0) -- Send window to workspace 1 + , ("M-S-2", shiftWindow 1) -- Send window to workspace 2 + , ("M-S-3", shiftWindow 2) -- Send window to workspace 3 + , ("M-S-4", shiftWindow 3) -- Send window to workspace 4 + , ("M-S-5", shiftWindow 4) -- Send window to workspace 5 + , ("M-S-6", shiftWindow 5) -- Send window to workspace 6 + , ("M-S-7", shiftWindow 6) -- Send window to workspace 7 + , ("M-S-8", shiftWindow 7) -- Send window to workspace 8 + , ("M-S-9", shiftWindow 8) -- Send window to workspace 9 + , ("M-C-1", shiftAndView 0) -- Send window and check workspace 1 + , ("M-C-2", shiftAndView 1) -- Send window and check workspace 2 + , ("M-C-3", shiftAndView 2) -- Send window and check workspace 3 + , ("M-C-4", shiftAndView 3) -- Send window and check workspace 4 + , ("M-C-5", shiftAndView 4) -- Send window and check workspace 5 + , ("M-C-6", shiftAndView 5) -- Send window and check workspace 6 + , ("M-C-7", shiftAndView 6) -- Send window and check workspace 7 + , ("M-C-8", shiftAndView 7) -- Send window and check workspace 8 + , ("M-C-9", shiftAndView 8) -- Send window and check workspace 9 + , ("M-f", sinkAll) -- Nuke solution for simplestFloat layout + ] + where + toggleFloat w = windows (\s -> if M.member w (W.floating s) + then W.sink w s + else (W.float w (W.RationalRect (1/6) (1/6) (2/3) (2/3)) s)) + viewDesktop d = windows $ W.greedyView $ myWorkspaces !! d + shiftWindow w = windows $ W.shift $ myWorkspaces !! w + shiftAndView w = windows $ W.greedyView (myWorkspaces !! w) . W.shift (myWorkspaces !! w) + +-- My xmobar workspace and other things config +myXmobarPP :: PP +myXmobarPP = filterOutWsPP ["NSP"] + $ def + { ppSep = magenta " • " + , ppWsSep = " " + , ppTitleSanitize = xmobarStrip + , ppCurrent = xmobarBorder "Bottom" "#89b4fa" 2 + , ppHidden = white + , ppHiddenNoWindows = lowWhite + , ppUrgent = red . wrap (yellow "!") (yellow "!") + , ppOrder = \[ws, l, _, wins] -> [ws, l, wins] + , ppExtras = [logTitles formatFocused formatUnfocused] + } + where + formatFocused = wrap (white "[") (white "]") . magenta . ppWindow + formatUnfocused = wrap (lowWhite "[") (lowWhite "]") . blue . ppWindow + + ppWindow :: String -> String + ppWindow = xmobarRaw . (\w -> if null w then "untitled" else w) . shorten 25 + + blue, lowWhite, magenta, red, white, yellow :: String -> String + magenta = xmobarColor "#eba0ac" "" + blue = xmobarColor "#cba6f7" "" + white = xmobarColor "#cdd6f4" "" + yellow = xmobarColor "#f9e2af" "" + red = xmobarColor "#f38ba8" "" + lowWhite = xmobarColor "#585b70" "" diff --git a/hosts/default/hardware-configuration.nix b/hosts/default/hardware-configuration.nix new file mode 100644 index 0000000..afb5a49 --- /dev/null +++ b/hosts/default/hardware-configuration.nix @@ -0,0 +1,39 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-amd" ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/378a2cc3-3885-4d83-98d6-cbbf5dfc73fd"; + fsType = "ext4"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/62C0-1109"; + fsType = "vfat"; + }; + + swapDevices = + [ { device = "/dev/disk/by-uuid/e76bb593-aa6c-4aa6-bf2d-723e3be01edc"; } + ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp3s0.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/default/home.nix b/hosts/default/home.nix new file mode 100644 index 0000000..ae7c0b0 --- /dev/null +++ b/hosts/default/home.nix @@ -0,0 +1,553 @@ +{ config, pkgs, inputs, ... }: + +{ + # Home Manager needs a bit of information about you and the paths it should + # manage. + home.username = "crony"; + home.homeDirectory = "/home/crony"; + + # This value determines the Home Manager release that your configuration is + # compatible with. This helps avoid breakage when a new Home Manager release + # introduces backwards incompatible changes. + # + # You should not change this value, even if you update Home Manager. If you do + # want to update the value, then make sure to first check the Home Manager + # release notes. + home.stateVersion = "23.11"; # Please read the comment before changing. + imports = + [ + inputs.nixvim.homeManagerModules.nixvim + ]; + + + # The home.packages option allows you to install Nix packages into your + # environment. + home.packages = [ + pkgs.librewolf + pkgs.thunderbird + pkgs.qutebrowser + pkgs.discord + pkgs.neofetch + pkgs.keepassxc + pkgs.buku + pkgs.bukubrow + pkgs.tmux + pkgs.rclone + pkgs.age + pkgs.alacritty + pkgs.nitch + pkgs.ripgrep + pkgs.libarchive + pkgs.nsxiv + pkgs.imagemagick + pkgs.ffmpeg + pkgs.glow + pkgs.piper + pkgs.krita + pkgs.tutanota-desktop + pkgs.delfin + pkgs.nurl + + (pkgs.nerdfonts.override { fonts = [ "CascadiaCode" ]; }) + + # My custom dmenu build + (pkgs.dmenu.overrideAttrs (oldAttrs: rec { + src = builtins.fetchGit { + url = "https://code.cronyakatsuki.xyz/crony/dmenu"; + rev = "10dcddf14b38cfd965ab27f084139513baed70bf"; + }; + })) + + # # You can also create simple shell scripts directly inside your + # # configuration. For example, this adds a command 'my-hello' to your + # # environment: + # (pkgs.writeShellScriptBin "my-hello" '' + # echo "Hello, ${config.home.username}!" + # '') + ]; + + # Home Manager is pretty good at managing dotfiles. The primary way to manage + # plain files is through 'home.file'. + home.file = { + # # Building this configuration will create a copy of 'dotfiles/screenrc' in + # # the Nix store. Activating the configuration will then make '~/.screenrc' a + # # symlink to the Nix store copy. ".screenrc".source = dotfiles/screenrc; + # # You can also set the file content immediately. + # ".gradle/gradle.properties".text = '' + # org.gradle.console=verbose + # org.gradle.daemon.idletimeout=3600000 + # ''; + }; + + # Home Manager can also manage your environment variables through + # 'home.sessionVariables'. If you don't want to manage your shell through Home + # Manager then you have to manually source 'hm-session-vars.sh' located at + # either + # + # ~/.nix-profile/etc/profile.d/hm-session-vars.sh + # or + # + # ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh + # + # or + # + # /etc/profiles/per-user/crony/etc/profile.d/hm-session-vars.sh + # + home.sessionVariables = { + EDITOR = "nvim"; + BROWSER = "qutebrowser"; + TERMINAL = "alacritty"; + }; + + # Let Home Manager install and manage itself. + programs.home-manager.enable = true; + + # gpg settings + programs.gpg = { + enable = true; + homedir = "${config.xdg.dataHome}/gnupg"; + }; + + # Make it use kde for flkdsjlkfdlsjflkdsjflsdjklfjdsklf + services.gpg-agent = { + enable = true; + pinentryFlavor = "qt"; + }; + + # Btop settings + programs.btop = { + enable = true; + settings = { + color_theme = "catppuccin_frappe"; + vim_keys = true; + }; + }; + + # Mpv settings + programs.mpv = { + enable = true; + config = { + ytdl-format="bestvideo[height<=?1080][fps<=?60][vcodec!=?vp9]+bestaudio/best"; + ytdl-raw-options="extractor-args=youtube:player-client=android"; + fs=true; + force-window="immediate"; + screenshot-template="%F - [%P]v%#01n"; + sub-file-paths="Subs;subs"; + sub-auto="all"; + slang="english,eng,en"; + }; + scripts = with pkgs.mpvScripts; [ mpris sponsorblock uosc thumbfast quality-menu ]; + }; + + # NNN Settings + programs.nnn = { + enable = true; + package = pkgs.nnn.override ({ withNerdIcons = true; }); + bookmarks = { d = "~/Documents"; D = "~/Downloads"; p = "~/Pictures"; v = "~/Videos";}; + extraPackages = with pkgs; [ pmount ffmpegthumbnailer mediainfo ueberzugpp poppler_utils gnome-epub-thumbnailer ]; + plugins.mappings = { u = "nmount"; c = "chksum"; r = "gitroot"; v = "imgview"; m = "mtpmount"; d = "xdgdefault"; x = "togglex"; p = "preview-tui"; }; + plugins.src = (pkgs.fetchFromGitHub { owner = "jarun"; repo = "nnn"; rev = "v4.9"; sha256 = "sha256-g19uI36HyzTF2YUQKFP4DE2ZBsArGryVHhX79Y0XzhU=";}) + "/plugins"; + }; + + # Mangohud settings + programs.mangohud = { + enable = true; + settings = { + # GPU SETTINGS + gpu_stats = true; + gpu_temp = true; + gpu_core_clock = true; + gpu_power = true; + gpu_text = "GPU"; + gpu_load_change = true; + gpu_load_color = "39F900,FDFD09,B22222"; + # CPU SETTINGS + cpu_stats = true; + cpu_temp = true; + cpu_text = "CPU"; + cpu_mhz = true; + cpu_load_change = true; + cpu_load_value = "60,90"; + cpu_load_color = "39F900,FDFD09,B22222"; + # Vram/Ram/Swap + vram = true; + ram = true; + swap = true; + # Fps settings + fps = true; + fps_sampling_period = "1000"; + fps_color_change = true; + fps_value = "30,60"; + fps_color = "B22222,FDFD09,39F900"; + frametime = true; + # Misc + gpu_name = true; + vulkan_driver = true; + show_fps_limit = true; + resolution = true; + round_corners = "5"; + }; + }; + + # But we all know I love zsh + programs.zsh = { + enable = true; + enableAutosuggestions = true; + enableCompletion = true; + history.path = "${config.xdg.dataHome}/zsh/history"; + dotDir = ".config/zsh"; + envExtra = '' + # NNN settings + export NNN_FIFO="/tmp/nnn.fifo" + export NNN_SSHFS="sshfs -o follow_symlinks" + export NNN_TERMINAL="alacritty --class preview,preview" + + # Catppuccin colors nnn + BLK="03" CHR="03" DIR="04" EXE="02" REG="07" HARDLINK="05" SYMLINK="05" MISSING="08" ORPHAN="01" FIFO="06" SOCK="03" UNKNOWN="01" + export NNN_COLORS="#04020301;4231" + export NNN_FCOLORS="$BLK$CHR$DIR$EXE$REG$HARDLINK$SYMLINK$MISSING$ORPHAN$FIFO$SOCK$UNKNOWN" + ''; + initExtra = '' + # VI Mode escape timeout fix + export KEYTIMEOUT=1 + + # Substring search settings + export HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND="bg=blue,fg=black,bold" + export HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=black,bold' + bindkey -M vicmd 'k' history-substring-search-up + bindkey -M vicmd 'j' history-substring-search-down + ''; + initExtraFirst = '' + nitch + ''; + zplug = { + enable = true; + plugins = [ + { name = "zap-zsh/supercharge"; } + { name = "zap-zsh/completions"; } + { name = "zap-zsh/vim"; } + { name = "chivalryq/git-alias"; } + { name = "zdharma-continuum/fast-syntax-highlighting"; } + { name = "MichaelAquilina/zsh-you-should-use"; } + { name = "zsh-users/zsh-history-substring-search"; } + ]; + }; + }; + + # Eza settings + programs.eza = { + enable = true; + enableAliases = true; + git = true; + icons = true; + }; + + # Zoxide settings + programs.zoxide = { + enable = true; + enableZshIntegration = true; + }; + + # Starhip settings + programs.starship = { + enable = true; + enableZshIntegration = true; + }; + + # Fzf settings + programs.fzf = { + enable = true; + enableZshIntegration = true; + }; + + # Nixvim + programs.nixvim = { + enable = true; + viAlias = true; + vimAlias = true; + + options = { + hlsearch = false; + incsearch = true; + number = true; + relativenumber = true; + tabstop = 4; + softtabstop = 4; + shiftwidth = 4; + expandtab = true; + smartindent = true; + mouse = ""; + breakindent = true; + undofile = true; + swapfile = true; + ignorecase = true; + smartcase = true; + signcolumn = "yes"; + completeopt = "menuone,noselect"; + updatetime = 50; + timeoutlen = 300; + colorcolumn = "80"; + showmode = false; + laststatus = 3; + splitbelow = true; + splitright = true; + }; + + globals = { + mapleader = " "; + maplocalleader = ";"; + }; + + extraConfigLuaPost = '' + vim.notify = require("mini.notify").make_notify() + ''; + plugins = { + harpoon = { + enable = true; + keymaps = { + addFile = "a"; + toggleQuickMenu = ""; + navFile = { "1" = ""; "2" = ""; "3" = ""; "4" = ""; }; + }; + }; + + oil = { + enable = true; + defaultFileExplorer = true; + extraOptions = { show_hidden = true; }; + }; + + treesitter.enable = true; + + gitsigns = { + enable = true; + signs = { + add.text = "▎"; + change.text = "▎"; + changedelete.text = "▎"; + delete.text = "▎"; + topdelete.text = "▎"; + untracked.text = "▎"; + }; + onAttach.function = '' + function(buffer) + local gs = package.loaded.gitsigns + + local function map(mode, l, r, desc) + vim.keymap.set(mode, l, r, { buffer = buffer, desc = desc }) + end + + -- stylua: ignore start + map("n", "]g", gs.next_hunk, "Next git hunk") + map("n", "[g", gs.prev_hunk, "Previous git hunk") + end + ''; + }; + + mini = { + enable = true; + modules = { + statusline = { + set_vim_settings = false; + }; + comment = {}; + notify = {}; + }; + }; + + telescope = { + enable = true; + extensions = { + fzf-native = { + enable = true; + fuzzy = true; + overrideGenericSorter = true; + overrideFileSorter = true; + caseMode = "smart_case"; + }; + ui-select.enable = true; + }; + keymaps = { + "pf" = "find_files"; + "" = "git_files"; + "vh" = "help_tags"; + "ps" = "grep_string"; + }; + }; + + lsp = { + enable = true; + servers = { + lua-ls.enable = true; + nil_ls.enable = true; + }; + keymaps = { + diagnostic = { + "vd" = "open_float"; + "[d" = "goto_next"; + "]d" = "goto_prev"; + }; + lspBuf = { + K = "hover"; + gd = "definition"; + gD = "declaration"; + gi = "implementation"; + "lca" = "code_action"; + "lrn" = "rename"; + "" = "signature_help"; + }; + }; + + preConfig = '' + local function sign_define(args) + vim.fn.sign_define(args.name, { + texthl = args.name, + text = args.text, + numhl = "", + }) + end + + sign_define({ name = "DiagnosticSignError", text = "E" }) + sign_define({ name = "DiagnosticSignWarn", text = "W" }) + sign_define({ name = "DiagnosticSignHint", text = "H" }) + sign_define({ name = "DiagnosticSignInfo", text = "I" }) + ''; + }; + + nvim-cmp = { + enable = true; + autoEnableSources = true; + sources = [ + {name = "nvim_lsp";} + {name = "path";} + {name = "snippy";} + ]; + snippet.expand = "snippy"; + mapping = { + "" = "cmp.mapping.confirm({ select = false })"; + "" = { + action = '' + function(fallback) + if cmp.visible then + cmp.select_next_item() + else + fallback() + end + end + ''; + modes = [ "i" "s" ]; + }; + "" = { + action = '' + function(fallback) + if cmp.visible then + cmp.select_prev_item() + else + fallback() + end + end + ''; + modes = [ "i" "s" ]; + }; + }; + }; + }; + + colorschemes.catppuccin = { + enable = true; + flavour = "frappe"; + styles = { + functions = [ "bold" ]; + keywords = [ "bold" ]; + }; + }; + extraPlugins = with pkgs.vimPlugins; [ + vim-snippets + ]; + }; + + ##-- Restic Timers And Services --## + + # Restic backup + systemd.user.services = { + restic_backup = { + Unit.Description = "Restic backup service"; + Service = { + Type = "oneshot"; + ExecStart = toString ( + pkgs.writeShellScript "restic-backup" '' + . /etc/restic/local + restic backup --files-from /home/crony/.config/restic/list --verbose && restic forget --keep-last 10 --keep-daily 7 --keep-weekly 5 --keep-monthly 12 + . /etc/restic/online + restic backup --files-from /home/crony/.config/restic/list --verbose && restic forget --keep-last 10 --keep-daily 7 --keep-weekly 5 --keep-monthly 12 + '' + ); + }; + Install.WantedBy = [ "default.target" ]; + }; + }; + systemd.user.timers = { + restic_backup = { + Unit.Description = "Restic backup timer"; + Timer = { + OnBootSec = "5m"; + OnUnitActiveSec = "6h"; + }; + Install.WantedBy = [ "timers.target" ]; + }; + }; + # Restic check + systemd.user.services = { + restic_check = { + Unit.Description = "Restic check service"; + Service = { + Type = "oneshot"; + ExecStart = toString ( + pkgs.writeShellScript "restic-check" '' + . /etc/restic/local + restic check --read-data-subset=10% + . /etc/restic/online + restic check --read-data-subset=10% + '' + ); + }; + Install.WantedBy = [ "default.target" ]; + }; + }; + systemd.user.timers = { + restic_check = { + Unit.Description = "Restic check timer"; + Timer = { + OnCalendar="Thu *-*-* 18:00:00"; + }; + Install.WantedBy = [ "timers.target" ]; + }; + }; + # Restic prune + systemd.user.services = { + restic_prune = { + Unit.Description = "Restic prune service"; + Service = { + Type = "oneshot"; + ExecStart = toString ( + pkgs.writeShellScript "restic-prune" '' + . /etc/restic/local + restic prune + . /etc/restic/online + restic prune + '' + ); + }; + Install.WantedBy = [ "default.target" ]; + }; + }; + systemd.user.timers = { + restic_prune = { + Unit.Description = "Restic prune timer"; + Timer = { + OnCalendar="Fri *-*-* 18:00:00"; + }; + Install.WantedBy = [ "timers.target" ]; + }; + }; +}