Totally new ai.nix, integrating MIstral with ZED
This commit is contained in:
+447
-409
File diff suppressed because it is too large
Load Diff
+83
-26
@@ -467,6 +467,7 @@ The tree below shows the full repository layout, with the standardized internal
|
|||||||
├── assets
|
├── assets
|
||||||
│ ├── conf
|
│ ├── conf
|
||||||
│ │ ├── apps
|
│ │ ├── apps
|
||||||
|
│ │ ├── ai.nix
|
||||||
│ │ │ ├── flatpaks.conf
|
│ │ │ ├── flatpaks.conf
|
||||||
│ │ │ └── packages.conf
|
│ │ │ └── packages.conf
|
||||||
│ │ ├── core
|
│ │ ├── core
|
||||||
@@ -524,7 +525,6 @@ The tree below shows the full repository layout, with the standardized internal
|
|||||||
│ └── scripts
|
│ └── scripts
|
||||||
├── configuration
|
├── configuration
|
||||||
│ ├── apps
|
│ ├── apps
|
||||||
│ │ ├── ai.nix
|
|
||||||
│ │ ├── install_flatpaks.nix
|
│ │ ├── install_flatpaks.nix
|
||||||
│ │ └── install_packages.nix
|
│ │ └── install_packages.nix
|
||||||
│ ├── core
|
│ ├── core
|
||||||
@@ -858,7 +858,6 @@ This section describes the main system configuration for the computers that I ha
|
|||||||
{ pkgs, user, ... } :
|
{ pkgs, user, ... } :
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./apps/ai.nix
|
|
||||||
./apps/install_flatpaks.nix
|
./apps/install_flatpaks.nix
|
||||||
./apps/install_packages.nix
|
./apps/install_packages.nix
|
||||||
./core/files.nix
|
./core/files.nix
|
||||||
@@ -894,30 +893,6 @@ This section describes the main system configuration for the computers that I ha
|
|||||||
** Apps section
|
** Apps section
|
||||||
This section describes a way of installing packages, either through nixpkgs orr flatpak. What apps to instal is decided in the files ./assets/conf/apps/packages.conf and flatpaks.conf
|
This section describes a way of installing packages, either through nixpkgs orr flatpak. What apps to instal is decided in the files ./assets/conf/apps/packages.conf and flatpaks.conf
|
||||||
|
|
||||||
** ai.nix
|
|
||||||
This module enables and configures the Ollama system service on NixOS, including optional GPU acceleration (CUDA or ROCm).
|
|
||||||
It ensures the Ollama CLI is available system-wide for interacting with local models.
|
|
||||||
It automatically pulls and prepares selected coding models (e.g., Qwen2.5-Coder and StarCoder2) at system activation.
|
|
||||||
|
|
||||||
#+begin_src nix :tangle configuration/apps/ai.nix :noweb tangle :mkdirp yes
|
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
{
|
|
||||||
services.ollama = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.ollama-vulkan;
|
|
||||||
loadModels = [
|
|
||||||
"qwen2.5-coder:7b"
|
|
||||||
"qwen2.5-coder:32b"
|
|
||||||
"starcoder2:15b"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
environment.systemPackages = [
|
|
||||||
pkgs.ollama-vulkan
|
|
||||||
];
|
|
||||||
}
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
|
|
||||||
** install_packages.nix
|
** install_packages.nix
|
||||||
#+begin_src nix :tangle configuration/apps/install_packages.nix :noweb tangle :mkdirp yes
|
#+begin_src nix :tangle configuration/apps/install_packages.nix :noweb tangle :mkdirp yes
|
||||||
{ config, lib, pkgs, flakeRoot, inputs, ... }:
|
{ config, lib, pkgs, flakeRoot, inputs, ... }:
|
||||||
@@ -1674,6 +1649,88 @@ This module will import all necessities.
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
** AI integrated with ZED
|
||||||
|
This module enables and configures the Ollama system service on NixOS, including optional GPU acceleration (CUDA or ROCm).
|
||||||
|
It ensures the Ollama CLI is available system-wide for interacting with local models.
|
||||||
|
It automatically pulls and prepares selected coding models (e.g., Qwen2.5-Coder and StarCoder2) at system activation.
|
||||||
|
|
||||||
|
#+begin_src nix :tangle home/apps/ai.nix :noweb tangle :mkdirp yes
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Install ZED and Ollama (Vulkan for CPU/AMD, use `ollama` for NVIDIA or `ollama-rocm` for AMD ROCm)
|
||||||
|
home.packages = [
|
||||||
|
pkgs.ollama-vulkan # For Vulkan (CPU/AMD). For NVIDIA: pkgs.ollama. For AMD ROCm: pkgs.ollama-rocm
|
||||||
|
pkgs.zed
|
||||||
|
];
|
||||||
|
|
||||||
|
# Environment variables for ZED and Ollama
|
||||||
|
home.sessionVariables = {
|
||||||
|
OLLAMA_HOST = "http://127.0.0.1:11434";
|
||||||
|
MISTRAL_API_KEY = "CWo91GHwIClzLj6bCLQ69IioSi54PpTZ"; # Replace with your actual Mistral API key
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure Ollama as a user service (starts with login)
|
||||||
|
home.services.ollama = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.ollama-vulkan;
|
||||||
|
onStart = ''
|
||||||
|
# Start Ollama server
|
||||||
|
${pkgs.ollama-vulkan}/bin/ollama serve > /dev/null 2>&1 &
|
||||||
|
sleep 5 # Wait for server to start
|
||||||
|
|
||||||
|
# Pull coding and chat models at startup
|
||||||
|
${pkgs.ollama-vulkan}/bin/ollama pull codellama:70b # Best for coding
|
||||||
|
${pkgs.ollama-vulkan}/bin/ollama pull mixtral:8x7b # Best for chat
|
||||||
|
|
||||||
|
# To pull additional models, uncomment or add lines below:
|
||||||
|
# ${pkgs.ollama-vulkan}/bin/ollama pull llama3:8b # General-purpose
|
||||||
|
# ${pkgs.ollama-vulkan}/bin/ollama pull qwen2.5-coder:7b # Multilingual coding
|
||||||
|
# ${pkgs.ollama-vulkan}/bin/ollama pull qwen2.5-coder:32b # Larger coding model
|
||||||
|
# ${pkgs.ollama-vulkan}/bin/ollama pull starcoder2:15b # Alternative for code
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure ZED to use Ollama and Mistral API
|
||||||
|
home.file.".config/zed/settings.json".text = lib.mkForce ''
|
||||||
|
{
|
||||||
|
"mistral": {
|
||||||
|
"apiKey": "$MISTRAL_API_KEY", # Uses the environment variable set above
|
||||||
|
"defaultModel": "mistral-pro" # Default model for Mistral API calls
|
||||||
|
},
|
||||||
|
"ollama": {
|
||||||
|
"endpoint": "$OLLAMA_HOST", # Connects to local Ollama instance
|
||||||
|
"defaultModel": "codellama:70b" # Default model for Ollama plugin
|
||||||
|
},
|
||||||
|
# Add other ZED plugin configurations here if needed
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# --- Notes ---
|
||||||
|
# 1. Pulling Additional Models:
|
||||||
|
# To pull more models later, run:
|
||||||
|
# ollama pull <model-name>
|
||||||
|
# Example: ollama pull llama3:8b
|
||||||
|
|
||||||
|
# 2. Switching GPU Backends:
|
||||||
|
# - For NVIDIA: Replace `ollama-vulkan` with `ollama` (uses CUDA)
|
||||||
|
# - For AMD: Use `ollama-rocm` and ensure ROCm is installed
|
||||||
|
|
||||||
|
# 3. ZED Plugin Setup:
|
||||||
|
# - Install the Ollama and Mistral plugins in ZED via the plugin marketplace
|
||||||
|
# - The Ollama plugin will use the models pulled above
|
||||||
|
# - The Mistral plugin will use the MISTRAL_API_KEY for cloud access
|
||||||
|
|
||||||
|
# 4. Custom Prompts:
|
||||||
|
# To add custom prompts for Ollama, create a prompts.json file or
|
||||||
|
# configure prompts directly in the ZED Ollama plugin settings
|
||||||
|
|
||||||
|
# 5. Resource Management:
|
||||||
|
# Ollama runs as a user service and stops when you log out
|
||||||
|
# To run Ollama persistently, consider a systemd user service with `systemctl --user`
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
** NCSway
|
** NCSway
|
||||||
Takes care of notifications
|
Takes care of notifications
|
||||||
#+begin_src nix :tangle home/desktop/ncsway.nix :noweb tangle :mkdirp yes
|
#+begin_src nix :tangle home/desktop/ncsway.nix :noweb tangle :mkdirp yes
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
{
|
||||||
|
services.ollama = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.ollama-vulkan;
|
||||||
|
loadModels = [
|
||||||
|
"qwen2.5-coder:7b"
|
||||||
|
"qwen2.5-coder:32b"
|
||||||
|
"starcoder2:15b"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.ollama-vulkan
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
{ config, pkgs, lib, flakeRoot, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
moduleName = "install-flatpaks";
|
||||||
|
flatpakConfPath = flakeRoot + "/assets/conf/apps/flatpaks.conf";
|
||||||
|
raw = builtins.readFile flatpakConfPath;
|
||||||
|
|
||||||
|
# Explicit "\n" so we never accidentally split into characters
|
||||||
|
rawLines = lib.splitString "\n" raw;
|
||||||
|
|
||||||
|
# Guard: if we accidentally split into characters, rawLines length ~= stringLength raw
|
||||||
|
_guard = assert !(
|
||||||
|
builtins.stringLength raw > 1 &&
|
||||||
|
builtins.length rawLines == builtins.stringLength raw
|
||||||
|
); true;
|
||||||
|
|
||||||
|
cleanLine = l:
|
||||||
|
let
|
||||||
|
noCR = lib.replaceStrings [ "\r" ] [ "" ] l;
|
||||||
|
noInlineComment = lib.head (lib.splitString "#" noCR);
|
||||||
|
in
|
||||||
|
lib.strings.trim noInlineComment;
|
||||||
|
|
||||||
|
entries =
|
||||||
|
builtins.filter (l: l != "")
|
||||||
|
(map cleanLine rawLines);
|
||||||
|
|
||||||
|
# Flatpak app IDs are reverse-DNS style like org.example.App (at least 2 dots).
|
||||||
|
# We'll validate and fail early with a clear message.
|
||||||
|
dotCount = s: builtins.length (lib.splitString "." s) - 1;
|
||||||
|
|
||||||
|
isValidId = s:
|
||||||
|
(dotCount s) >= 2; # matches the error you're seeing: "at least 2 periods"
|
||||||
|
|
||||||
|
_validate =
|
||||||
|
builtins.seq _guard (
|
||||||
|
builtins.map (id:
|
||||||
|
if isValidId id then true else
|
||||||
|
throw ''
|
||||||
|
${moduleName}: invalid Flatpak ID in flatpaks.conf (needs reverse-DNS with at least 2 dots)
|
||||||
|
|
||||||
|
Token : ${builtins.toJSON id}
|
||||||
|
flatpaks.conf : ${toString flatpakConfPath}
|
||||||
|
|
||||||
|
Fix: remove stray tokens/headers, or comment them out with '#'.
|
||||||
|
''
|
||||||
|
) entries
|
||||||
|
);
|
||||||
|
|
||||||
|
# Use validated entries
|
||||||
|
flatpakApps = builtins.seq _validate entries;
|
||||||
|
|
||||||
|
syncFlatpaks = pkgs.writeShellScript "sync-flatpaks" ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Use the deployed config path (matches environment.etc below)
|
||||||
|
CONF="/etc/flatpak/flatpaks.conf"
|
||||||
|
if [[ -f "$CONF" ]]; then
|
||||||
|
echo "flatpak-sync: using $CONF"
|
||||||
|
else
|
||||||
|
echo "flatpak-sync: WARNING: $CONF not found, using embedded list"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! flatpak remotes --system --columns=name | grep -qx flathub; then
|
||||||
|
flatpak remote-add --system --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||||
|
fi
|
||||||
|
|
||||||
|
desired_apps=(
|
||||||
|
${lib.concatStringsSep "\n" (map (a: ''"${a}"'') flatpakApps)}
|
||||||
|
)
|
||||||
|
|
||||||
|
for app in "''${desired_apps[@]}"; do
|
||||||
|
if ! flatpak info --system "$app" >/dev/null 2>&1; then
|
||||||
|
flatpak install --system -y --noninteractive flathub "$app"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.flatpak.enable = true;
|
||||||
|
|
||||||
|
xdg.portal = {
|
||||||
|
enable = true;
|
||||||
|
extraPortals = with pkgs; [
|
||||||
|
xdg-desktop-portal-hyprland
|
||||||
|
xdg-desktop-portal-gtk
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Deploy the config file for runtime visibility/debugging
|
||||||
|
environment.etc."flatpak/flatpaks.conf".source = flatpakConfPath;
|
||||||
|
|
||||||
|
systemd.services.flatpak-sync = {
|
||||||
|
description = "Install Flatpak apps listed in flatpaks.conf";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = syncFlatpaks;
|
||||||
|
};
|
||||||
|
|
||||||
|
restartTriggers = [ flatpakConfPath ];
|
||||||
|
path = [ pkgs.flatpak pkgs.coreutils pkgs.gnugrep pkgs.gnused ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
{ config, lib, pkgs, flakeRoot, inputs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
packagesConfPath = flakeRoot + "/assets/conf/apps/packages.conf";
|
||||||
|
raw = builtins.readFile packagesConfPath;
|
||||||
|
|
||||||
|
# IMPORTANT: explicit "\n" so we never accidentally split into characters
|
||||||
|
rawLines = lib.splitString "\n" raw;
|
||||||
|
|
||||||
|
# Guard: if we accidentally split into characters, rawLines length ~= stringLength raw
|
||||||
|
_guard = assert !(
|
||||||
|
builtins.stringLength raw > 1 &&
|
||||||
|
builtins.length rawLines == builtins.stringLength raw
|
||||||
|
); true;
|
||||||
|
|
||||||
|
cleanLine = l:
|
||||||
|
let
|
||||||
|
noCR = lib.replaceStrings [ "\r" ] [ "" ] l;
|
||||||
|
noInlineComment = lib.head (lib.splitString "#" noCR);
|
||||||
|
in
|
||||||
|
lib.strings.trim noInlineComment;
|
||||||
|
|
||||||
|
entries =
|
||||||
|
builtins.filter (l: l != "")
|
||||||
|
(map cleanLine rawLines);
|
||||||
|
|
||||||
|
resolvePkg = name:
|
||||||
|
let
|
||||||
|
parts = lib.splitString "." name;
|
||||||
|
found = lib.attrByPath parts null pkgs;
|
||||||
|
in
|
||||||
|
if found == null then
|
||||||
|
throw ''
|
||||||
|
install_packages.nix: package not found in pkgs
|
||||||
|
|
||||||
|
Token : ${builtins.toJSON name}
|
||||||
|
packages.conf : ${toString packagesConfPath}
|
||||||
|
Hint : check the attribute name on search.nixos.org/packages
|
||||||
|
''
|
||||||
|
else
|
||||||
|
found;
|
||||||
|
|
||||||
|
packages = builtins.seq _guard (map resolvePkg entries);
|
||||||
|
|
||||||
|
zenBrowser =
|
||||||
|
inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
environment.systemPackages =
|
||||||
|
packages
|
||||||
|
++ [ zenBrowser ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{ pkgs, ... } :
|
||||||
|
{
|
||||||
|
boot = {
|
||||||
|
initrd = {
|
||||||
|
verbose = false; # its a lot of logs. dont need it, unless we do.
|
||||||
|
kernelModules = [ ]; # no kernel modules on boot
|
||||||
|
};
|
||||||
|
|
||||||
|
extraModulePackages = [ ]; # no extra packages on boot either
|
||||||
|
kernelPackages = pkgs.linuxPackages_latest; # latest greatest linux kernel
|
||||||
|
kernelParams = [ "silent" ]; # quiet those logs
|
||||||
|
|
||||||
|
consoleLogLevel = 0; # quiten more logs
|
||||||
|
plymouth.enable = true; # graphical boot animation instead
|
||||||
|
|
||||||
|
supportedFilesystems = [ "ntfs" ]; # should see the ntfs (windows)
|
||||||
|
|
||||||
|
loader = {
|
||||||
|
systemd-boot.enable = true; # systemd-boot
|
||||||
|
systemd-boot.configurationLimit = 10;
|
||||||
|
efi.canTouchEfiVariables = true; # allow editing efi to edit the boot loader
|
||||||
|
|
||||||
|
|
||||||
|
timeout = 5; # grub timeout to make a selection
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
{ pkgs, user, config, ... }:
|
||||||
|
{
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
zip
|
||||||
|
unzip
|
||||||
|
p7zip
|
||||||
|
usbutils
|
||||||
|
udiskie
|
||||||
|
file-roller
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.thunar = {
|
||||||
|
enable = true;
|
||||||
|
plugins = with pkgs; [
|
||||||
|
thunar-archive-plugin
|
||||||
|
thunar-media-tags-plugin
|
||||||
|
thunar-volman
|
||||||
|
thunar-vcs-plugin
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.xfconf.enable = true; # to save thunar settings
|
||||||
|
|
||||||
|
services = {
|
||||||
|
gvfs.enable = true; # Mount, trash, and other functionalities
|
||||||
|
tumbler.enable = true; # Thumbnail support for images
|
||||||
|
udisks2.enable = true; # Auto mount usb drives
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{ user, ... } :
|
||||||
|
let
|
||||||
|
locale = user.locale;
|
||||||
|
defaultLocale = "nl_NL.UTF-8";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Set your time zone.
|
||||||
|
time.timeZone = "Europe/Amsterdam";
|
||||||
|
|
||||||
|
# Select internationalisation properties.
|
||||||
|
i18n.defaultLocale = defaultLocale;
|
||||||
|
|
||||||
|
i18n.extraLocaleSettings = {
|
||||||
|
LC_ADDRESS = locale;
|
||||||
|
LC_IDENTIFICATION = locale;
|
||||||
|
LC_MEASUREMENT = locale;
|
||||||
|
LC_MONETARY = locale;
|
||||||
|
LC_NAME = locale;
|
||||||
|
LC_NUMERIC = locale;
|
||||||
|
LC_PAPER = locale;
|
||||||
|
LC_TELEPHONE = locale;
|
||||||
|
LC_TIME = defaultLocale;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
lightdmConf = builtins.readFile ../../assets/conf/core/lightdm.conf;
|
||||||
|
lockPng = ../../assets/lock.png;
|
||||||
|
|
||||||
|
greeterConfPath = ../../assets/conf/core/lightdm-gtk-greeter.conf;
|
||||||
|
greeterRaw = builtins.readFile greeterConfPath;
|
||||||
|
|
||||||
|
# Extract "key = value" from the greeter conf.
|
||||||
|
# Returns null if not found.
|
||||||
|
getIniValue = key:
|
||||||
|
let
|
||||||
|
lines = lib.splitString "\n" greeterRaw;
|
||||||
|
|
||||||
|
# Captures the value part (group 0) from a single line.
|
||||||
|
# We match line-by-line because Nix regex does NOT support PCRE flags like (?s).
|
||||||
|
m =
|
||||||
|
let
|
||||||
|
ms = builtins.filter (x: x != null) (map (line:
|
||||||
|
builtins.match
|
||||||
|
("^[[:space:]]*" + key + "[[:space:]]*=[[:space:]]*([^#;]+).*$")
|
||||||
|
line
|
||||||
|
) lines);
|
||||||
|
in
|
||||||
|
if ms == [] then null else builtins.elemAt ms 0;
|
||||||
|
in
|
||||||
|
if m == null then null else lib.strings.trim (builtins.elemAt m 0);
|
||||||
|
|
||||||
|
# In your greeter.conf these are *package keys*, not theme names.
|
||||||
|
themePkgKey = getIniValue "theme-name";
|
||||||
|
iconPkgKey = getIniValue "icon-theme-name";
|
||||||
|
cursorPkgKey = getIniValue "cursor-theme-name";
|
||||||
|
|
||||||
|
cursorSizeStr = getIniValue "cursor-theme-size";
|
||||||
|
cursorSize =
|
||||||
|
if cursorSizeStr == null then null
|
||||||
|
else lib.toInt (lib.strings.trim cursorSizeStr);
|
||||||
|
|
||||||
|
# Map package-keys (from greeter.conf) -> { package, name }
|
||||||
|
#
|
||||||
|
# IMPORTANT:
|
||||||
|
# - "name" must be the real theme/icon/cursor NAME as seen under share/themes or share/icons.
|
||||||
|
# - "package" is the Nixpkgs derivation providing it.
|
||||||
|
pkgMap = {
|
||||||
|
catppuccinThemePkg = {
|
||||||
|
package = pkgs.catppuccin-gtk.override {
|
||||||
|
accents = [ "blue" ];
|
||||||
|
variant = "mocha";
|
||||||
|
size = "standard";
|
||||||
|
tweaks = [ ];
|
||||||
|
};
|
||||||
|
name = "Catppuccin-Mocha-Standard-Blue-Dark";
|
||||||
|
};
|
||||||
|
|
||||||
|
papirus-icon-theme = {
|
||||||
|
package = pkgs.papirus-icon-theme;
|
||||||
|
name = "Papirus-Dark";
|
||||||
|
};
|
||||||
|
|
||||||
|
bibata-cursors = {
|
||||||
|
package = pkgs.bibata-cursors;
|
||||||
|
name = "Bibata-Modern-Ice";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pick = key:
|
||||||
|
if key == null then
|
||||||
|
throw "lightdm: missing required key in ${toString greeterConfPath}"
|
||||||
|
else if !(pkgMap ? "${key}") then
|
||||||
|
throw "lightdm: unknown package key '${key}' in ${toString greeterConfPath}. Known keys: ${lib.concatStringsSep ", " (builtins.attrNames pkgMap)}"
|
||||||
|
else
|
||||||
|
pkgMap."${key}";
|
||||||
|
|
||||||
|
themeSel = pick themePkgKey;
|
||||||
|
iconSel = pick iconPkgKey;
|
||||||
|
cursorSel = pick cursorPkgKey;
|
||||||
|
|
||||||
|
# Rewrite greeter.conf so LightDM sees REAL names, not package keys.
|
||||||
|
# Also force background to lockPng.
|
||||||
|
greeterFixed =
|
||||||
|
''
|
||||||
|
[greeter]
|
||||||
|
theme-name = ${themeSel.name}
|
||||||
|
icon-theme-name = ${iconSel.name}
|
||||||
|
cursor-theme-name = ${cursorSel.name}
|
||||||
|
${lib.optionalString (cursorSize != null) "cursor-theme-size = ${toString cursorSize}"}
|
||||||
|
''
|
||||||
|
+ "\n"
|
||||||
|
+ greeterRaw;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.greetd.enable = false;
|
||||||
|
|
||||||
|
services.xserver = {
|
||||||
|
enable = true;
|
||||||
|
desktopManager.xterm.enable = false;
|
||||||
|
|
||||||
|
displayManager.lightdm = {
|
||||||
|
enable = true;
|
||||||
|
background = lockPng;
|
||||||
|
|
||||||
|
greeters.gtk = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
theme = {
|
||||||
|
name = themeSel.name;
|
||||||
|
package = themeSel.package;
|
||||||
|
};
|
||||||
|
|
||||||
|
iconTheme = {
|
||||||
|
name = iconSel.name;
|
||||||
|
package = iconSel.package;
|
||||||
|
};
|
||||||
|
|
||||||
|
cursorTheme = {
|
||||||
|
name = cursorSel.name;
|
||||||
|
package = cursorSel.package;
|
||||||
|
} // lib.optionalAttrs (cursorSize != null) {
|
||||||
|
size = cursorSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
# This includes your (rewritten) greeter config.
|
||||||
|
extraConfig = greeterFixed;
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = lightdmConf;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.hyprland.enable = true;
|
||||||
|
|
||||||
|
# Optional: make them available system-wide as well
|
||||||
|
environment.systemPackages = [
|
||||||
|
themeSel.package
|
||||||
|
iconSel.package
|
||||||
|
cursorSel.package
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{ pkgs, user, ... } :
|
||||||
|
{
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
tuigreet
|
||||||
|
];
|
||||||
|
services.greetd = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
default_session = {
|
||||||
|
command = pkgs.lib.mkForce "${pkgs.tuigreet}/bin/tuigreet --remember --time --time-format '%I:%M %p | %a • %h | %F'";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{ pkgs, lib, ... }:
|
||||||
|
{
|
||||||
|
networking = {
|
||||||
|
useDHCP = lib.mkDefault true;
|
||||||
|
networkmanager.enable = true;
|
||||||
|
networkmanager.wifi.backend = "iwd";
|
||||||
|
wireless.iwd.enable = true;
|
||||||
|
wireless.userControlled.enable = true;
|
||||||
|
firewall = {
|
||||||
|
enable = true;
|
||||||
|
# KDE Connect: discovery + encrypted connections
|
||||||
|
allowedTCPPortRanges = [
|
||||||
|
{ from = 1714; to = 1764; }
|
||||||
|
];
|
||||||
|
allowedUDPPortRanges = [
|
||||||
|
{ from = 1714; to = 1764; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
environment.systemPackages = with pkgs; [ impala ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{ pkgs, user, ... } :
|
||||||
|
{
|
||||||
|
nix.settings = {
|
||||||
|
# enable flakes
|
||||||
|
experimental-features = ["nix-command" "flakes"];
|
||||||
|
|
||||||
|
# add a cache that speed up new applications by downloading binaries
|
||||||
|
# from the trusted cache instead of compiling from sourcer
|
||||||
|
substituters = [
|
||||||
|
"https://nix-community.cachix.org"
|
||||||
|
];
|
||||||
|
# trust the cache public key
|
||||||
|
trusted-public-keys = [
|
||||||
|
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# allow proprietary software on this machine. I'm not a purist.
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
# unityhub depends on this... for now
|
||||||
|
nixpkgs.config.permittedInsecurePackages = [ "libxml2-2.13.8" ];
|
||||||
|
|
||||||
|
# this declares how often old configurations are cleared up.
|
||||||
|
# i cleanup anything older than a week, every week.
|
||||||
|
nix.gc = {
|
||||||
|
automatic = true;
|
||||||
|
options = "--delete-older-than 7d";
|
||||||
|
dates = "weekly";
|
||||||
|
};
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
# command line utility that makes applying changes easy and pretty
|
||||||
|
nh = {
|
||||||
|
enable = true;
|
||||||
|
flake = "/home/${user.username}/system";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
{ pkgs, user, ... } :
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./apps/install_flatpaks.nix
|
||||||
|
./apps/install_packages.nix
|
||||||
|
./core/files.nix
|
||||||
|
./core/locale.nix
|
||||||
|
./core/networking.nix
|
||||||
|
./core/nix-settings.nix
|
||||||
|
#./core/login-tuigreeter.nix
|
||||||
|
./core/login-lightdm.nix
|
||||||
|
./desktop/audio.nix
|
||||||
|
./desktop/hyprland.nix
|
||||||
|
./dev/terminal.nix
|
||||||
|
./core/boot.nix
|
||||||
|
./services/services.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
users.users.${user.username} = {
|
||||||
|
isNormalUser = true;
|
||||||
|
description = "henrov";
|
||||||
|
extraGroups = [
|
||||||
|
"networkmanager" # allow editing network connections
|
||||||
|
"wheel" # can do sudo
|
||||||
|
"scanner" # access to the network scanner
|
||||||
|
"lp" # access to the printer
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fonts.packages = with pkgs; [
|
||||||
|
aporetic
|
||||||
|
nerd-fonts.iosevka
|
||||||
|
];
|
||||||
|
|
||||||
|
# enable the catppuccin theme for everything with mocha + blue accents
|
||||||
|
catppuccin.enable = true;
|
||||||
|
catppuccin.flavor = "mocha";
|
||||||
|
catppuccin.accent = "blue";
|
||||||
|
|
||||||
|
system.stateVersion = user.stateVersion;
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
pipewire
|
||||||
|
wireplumber
|
||||||
|
alsa-utils
|
||||||
|
pulseaudio
|
||||||
|
pamixer
|
||||||
|
pavucontrol
|
||||||
|
];
|
||||||
|
|
||||||
|
services.pipewire = {
|
||||||
|
enable = true;
|
||||||
|
alsa.enable = true;
|
||||||
|
alsa.support32Bit = true;
|
||||||
|
pulse.enable = true;
|
||||||
|
jack.enable = true;
|
||||||
|
wireplumber.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
security.rtkit.enable = true;
|
||||||
|
|
||||||
|
# Helps on many laptops (Intel SOF etc.)
|
||||||
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
|
||||||
|
# Prefer analog over HDMI/DP in a machine-agnostic way
|
||||||
|
services.pipewire.wireplumber.extraConfig."51-audio-priorities" = {
|
||||||
|
"monitor.alsa.rules" = [
|
||||||
|
# De-prioritize HDMI / DisplayPort sinks
|
||||||
|
{
|
||||||
|
matches = [
|
||||||
|
{ "node.name" = "~alsa_output\\..*HDMI.*"; }
|
||||||
|
{ "node.name" = "~alsa_output\\..*DisplayPort.*"; }
|
||||||
|
];
|
||||||
|
actions.update-props = {
|
||||||
|
"priority.session" = 100;
|
||||||
|
"priority.driver" = 100;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prefer analog sinks (speakers/headphones)
|
||||||
|
{
|
||||||
|
matches = [
|
||||||
|
{ "node.name" = "~alsa_output\\..*analog.*"; }
|
||||||
|
{ "node.name" = "~alsa_output\\..*Headphones.*"; }
|
||||||
|
{ "node.name" = "~alsa_output\\..*Speaker.*"; }
|
||||||
|
];
|
||||||
|
actions.update-props = {
|
||||||
|
"priority.session" = 2000;
|
||||||
|
"priority.driver" = 2000;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Optional: clear "sticky" user-selected defaults so priority rules win
|
||||||
|
systemd.user.services.wireplumber-clear-default-nodes = {
|
||||||
|
description = "Clear WirePlumber saved default nodes (avoid HDMI becoming sticky)";
|
||||||
|
|
||||||
|
after = [ "wireplumber.service" ];
|
||||||
|
partOf = [ "wireplumber.service" ];
|
||||||
|
wantedBy = [ "default.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${pkgs.coreutils}/bin/rm -f %h/.local/state/wireplumber/default-nodes";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
nix.settings = {
|
||||||
|
substituters = [ "https://hyprland.cachix.org" ];
|
||||||
|
trusted-public-keys = [
|
||||||
|
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
services.dbus.enable = true;
|
||||||
|
security.polkit.enable = true;
|
||||||
|
services.flatpak.enable = true;
|
||||||
|
services.pipewire = {
|
||||||
|
enable = true;
|
||||||
|
alsa.enable = true;
|
||||||
|
alsa.support32Bit = true;
|
||||||
|
pulse.enable = true;
|
||||||
|
wireplumber.enable = true;
|
||||||
|
};
|
||||||
|
services.gvfs.enable = true;
|
||||||
|
xdg.portal = {
|
||||||
|
enable = true;
|
||||||
|
extraPortals = with pkgs; [
|
||||||
|
xdg-desktop-portal-hyprland
|
||||||
|
xdg-desktop-portal-gtk
|
||||||
|
];
|
||||||
|
config.common.default = [ "hyprland" "gtk" ];
|
||||||
|
};
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
walker
|
||||||
|
uwsm
|
||||||
|
hyprland-qtutils
|
||||||
|
hyprpolkitagent
|
||||||
|
grimblast
|
||||||
|
];
|
||||||
|
programs = {
|
||||||
|
uwsm.enable = true;
|
||||||
|
uwsm.waylandCompositors.hyprland = {
|
||||||
|
prettyName = "Hyprland";
|
||||||
|
comment = "Hyprland compositor managed by UWSM";
|
||||||
|
binPath = "/run/current-system/sw/bin/Hyprland";
|
||||||
|
};
|
||||||
|
hyprland = {
|
||||||
|
withUWSM = true;
|
||||||
|
enable = true;
|
||||||
|
xwayland.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
environment.sessionVariables = {
|
||||||
|
XDG_SESSION_TYPE = "wayland";
|
||||||
|
XDG_CURRENT_DESKTOP = "Hyprland";
|
||||||
|
XDG_SESSION_DESKTOP = "Hyprland";
|
||||||
|
NIXOS_OZONE_WL = "1";
|
||||||
|
XCURSOR_SIZE = "24";
|
||||||
|
};
|
||||||
|
security.pam.services.hyprlock = { };
|
||||||
|
# Optional; GNOME-specific (keep only if you really use gnome-keyring integration)
|
||||||
|
security.pam.services.gdm.enableGnomeKeyring = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{ pkgs, user, ... }:
|
||||||
|
{
|
||||||
|
console.useXkbConfig = true;
|
||||||
|
users.users.${user.username}.shell = pkgs.zsh;
|
||||||
|
programs.zsh.enable = true;
|
||||||
|
environment.shells = [ pkgs.zsh ];
|
||||||
|
environment.pathsToLink = [ "/share/zsh" ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{ user, ...} :
|
||||||
|
{
|
||||||
|
services = {
|
||||||
|
blueman.enable = true; # bluetooth manager
|
||||||
|
fwupd.enable = true; # firmware updating service
|
||||||
|
fstrim.enable = true; # ssd maintenance service
|
||||||
|
thermald.enable = true; # thermal regulation service
|
||||||
|
printing.enable = true; # printing services, cups
|
||||||
|
gnome.gnome-keyring.enable = true; # keyring
|
||||||
|
flatpak.enable = true; # allow installing things from flatpaks
|
||||||
|
#flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||||
|
|
||||||
|
# printer discovery
|
||||||
|
avahi = {
|
||||||
|
enable = true;
|
||||||
|
nssmdns4 = true;
|
||||||
|
openFirewall = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation.docker.enable = true; # enable docker
|
||||||
|
users.users.${user.username}.extraGroups = [ "docker" ]; # add self to docker user group
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Install ZED and Ollama (Vulkan for CPU/AMD, use `ollama` for NVIDIA or `ollama-rocm` for AMD ROCm)
|
||||||
|
home.packages = [
|
||||||
|
pkgs.ollama-vulkan # For Vulkan (CPU/AMD). For NVIDIA: pkgs.ollama. For AMD ROCm: pkgs.ollama-rocm
|
||||||
|
pkgs.zed
|
||||||
|
];
|
||||||
|
|
||||||
|
# Environment variables for ZED and Ollama
|
||||||
|
home.sessionVariables = {
|
||||||
|
OLLAMA_HOST = "http://127.0.0.1:11434";
|
||||||
|
MISTRAL_API_KEY = "CWo91GHwIClzLj6bCLQ69IioSi54PpTZ"; # Replace with your actual Mistral API key
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure Ollama as a user service (starts with login)
|
||||||
|
home.services.ollama = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.ollama-vulkan;
|
||||||
|
onStart = ''
|
||||||
|
# Start Ollama server
|
||||||
|
${pkgs.ollama-vulkan}/bin/ollama serve > /dev/null 2>&1 &
|
||||||
|
sleep 5 # Wait for server to start
|
||||||
|
|
||||||
|
# Pull coding and chat models at startup
|
||||||
|
${pkgs.ollama-vulkan}/bin/ollama pull codellama:70b # Best for coding
|
||||||
|
${pkgs.ollama-vulkan}/bin/ollama pull mixtral:8x7b # Best for chat
|
||||||
|
|
||||||
|
# To pull additional models, uncomment or add lines below:
|
||||||
|
# ${pkgs.ollama-vulkan}/bin/ollama pull llama3:8b # General-purpose
|
||||||
|
# ${pkgs.ollama-vulkan}/bin/ollama pull qwen2.5-coder:7b # Multilingual coding
|
||||||
|
# ${pkgs.ollama-vulkan}/bin/ollama pull qwen2.5-coder:32b # Larger coding model
|
||||||
|
# ${pkgs.ollama-vulkan}/bin/ollama pull starcoder2:15b # Alternative for code
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure ZED to use Ollama and Mistral API
|
||||||
|
home.file.".config/zed/settings.json".text = lib.mkForce ''
|
||||||
|
{
|
||||||
|
"mistral": {
|
||||||
|
"apiKey": "$MISTRAL_API_KEY", # Uses the environment variable set above
|
||||||
|
"defaultModel": "mistral-pro" # Default model for Mistral API calls
|
||||||
|
},
|
||||||
|
"ollama": {
|
||||||
|
"endpoint": "$OLLAMA_HOST", # Connects to local Ollama instance
|
||||||
|
"defaultModel": "codellama:70b" # Default model for Ollama plugin
|
||||||
|
},
|
||||||
|
# Add other ZED plugin configurations here if needed
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# --- Notes ---
|
||||||
|
# 1. Pulling Additional Models:
|
||||||
|
# To pull more models later, run:
|
||||||
|
# ollama pull <model-name>
|
||||||
|
# Example: ollama pull llama3:8b
|
||||||
|
|
||||||
|
# 2. Switching GPU Backends:
|
||||||
|
# - For NVIDIA: Replace `ollama-vulkan` with `ollama` (uses CUDA)
|
||||||
|
# - For AMD: Use `ollama-rocm` and ensure ROCm is installed
|
||||||
|
|
||||||
|
# 3. ZED Plugin Setup:
|
||||||
|
# - Install the Ollama and Mistral plugins in ZED via the plugin marketplace
|
||||||
|
# - The Ollama plugin will use the models pulled above
|
||||||
|
# - The Mistral plugin will use the MISTRAL_API_KEY for cloud access
|
||||||
|
|
||||||
|
# 4. Custom Prompts:
|
||||||
|
# To add custom prompts for Ollama, create a prompts.json file or
|
||||||
|
# configure prompts directly in the ZED Ollama plugin settings
|
||||||
|
|
||||||
|
# 5. Resource Management:
|
||||||
|
# Ollama runs as a user service and stops when you log out
|
||||||
|
# To run Ollama persistently, consider a systemd user service with `systemctl --user`
|
||||||
|
}
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
# Continue gebruikt tegenwoordig bij voorkeur config.yaml; config.json bestaat nog
|
||||||
|
# maar is “deprecated” in de docs. We schrijven hier bewust config.json omdat jij dat vroeg.
|
||||||
|
continueConfigJson = builtins.toJSON {
|
||||||
|
models = [
|
||||||
|
{
|
||||||
|
title = "Qwen2.5-Coder 7B";
|
||||||
|
provider = "ollama";
|
||||||
|
model = "qwen2.5-coder:7b";
|
||||||
|
apiBase = "http://localhost:11434";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
title = "Qwen2.5-Coder 32B";
|
||||||
|
provider = "ollama";
|
||||||
|
model = "qwen2.5-coder:32b";
|
||||||
|
apiBase = "http://localhost:11434";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
title = "StarCoder2 15B";
|
||||||
|
provider = "ollama";
|
||||||
|
model = "starcoder2:15b";
|
||||||
|
apiBase = "http://localhost:11434";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
# Tab-autocomplete model (pas aan naar smaak/VRAM)
|
||||||
|
tabAutocompleteModel = {
|
||||||
|
title = "Qwen2.5-Coder 7B";
|
||||||
|
provider = "ollama";
|
||||||
|
model = "qwen2.5-coder:7b";
|
||||||
|
apiBase = "http://localhost:11434";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.zed-editor = {
|
||||||
|
enable = true;
|
||||||
|
# Zed-extensies (taal/LS/etc). "Continue" bestaat (nog) niet als Zed-extensie.
|
||||||
|
# Dit is de officiële HM interface voor Zed extensions.
|
||||||
|
extensions = [
|
||||||
|
"nix"
|
||||||
|
"toml"
|
||||||
|
"rust"
|
||||||
|
"org-mode"
|
||||||
|
];
|
||||||
|
# Zed AI: Ollama als provider
|
||||||
|
# Zed kan modellen auto-discoveren die jij met Ollama gepulld hebt.
|
||||||
|
userSettings = {
|
||||||
|
language_models = {
|
||||||
|
ollama = {
|
||||||
|
api_url = "http://localhost:11434";
|
||||||
|
auto_discover = true;
|
||||||
|
# Optioneel: zet een grotere context voor alle Ollama modellen
|
||||||
|
# (Zed stuurt dit als `num_ctx` naar Ollama)
|
||||||
|
context_window = 8192;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# Continue config.json neerzetten (voor Continue in VS Code / JetBrains)
|
||||||
|
# Pad: ~/.config/continue/config.json
|
||||||
|
xdg.configFile."continue/config.json".text = continueConfigJson;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
{
|
||||||
|
xdg.mimeApps.enable = true;
|
||||||
|
xdg.mimeApps.defaultApplications = {
|
||||||
|
"x-scheme-handler/http" = [ "app.zen_browser.zen.desktop" ];
|
||||||
|
"x-scheme-handler/https" = [ "app.zen_browser.zen.desktop" ];
|
||||||
|
"text/html" = [ "app.zen_browser.zen.desktop" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{ pkgs, ...}:
|
||||||
|
{
|
||||||
|
gtk = {
|
||||||
|
enable = true;
|
||||||
|
colorScheme = "dark";
|
||||||
|
theme = {
|
||||||
|
name = "Catppuccin-GTK-Grey-Dark-Compact";
|
||||||
|
package = (pkgs.magnetic-catppuccin-gtk.override {
|
||||||
|
accent = [ "grey" ];
|
||||||
|
shade = "dark";
|
||||||
|
tweaks = [ "black" ];
|
||||||
|
size = "compact";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
iconTheme.name = "Papirus-Dark";
|
||||||
|
};
|
||||||
|
catppuccin.enable = true;
|
||||||
|
catppuccin.flavor = "mocha";
|
||||||
|
catppuccin.accent = "blue";
|
||||||
|
catppuccin.gtk.icon.enable = true;
|
||||||
|
catppuccin.cursors.enable = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{ pkgs, user, ... } :
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./apps/ai.nix
|
||||||
|
#./apps/default-apps.nix
|
||||||
|
./apps/theme.nix
|
||||||
|
./desktop/hypridle.nix
|
||||||
|
./desktop/hyprland.nix
|
||||||
|
./desktop/hyprexpo.nix
|
||||||
|
./desktop/hyprlock.nix
|
||||||
|
./desktop/hyprscrolling.nix
|
||||||
|
./desktop/hyprshell.nix
|
||||||
|
./desktop/ncsway.nix
|
||||||
|
./desktop/powermenu.nix
|
||||||
|
#./desktop/animated_wallpaper.nix
|
||||||
|
#./desktop/rotating_wallpaper.nix
|
||||||
|
./desktop/workspace_wallpaper.nix
|
||||||
|
./desktop/waybar.nix
|
||||||
|
./desktop/walker.nix
|
||||||
|
./dev/dev.nix
|
||||||
|
./dev/kitty.nix
|
||||||
|
./dev/shells.nix
|
||||||
|
./dev/starship.nix
|
||||||
|
./dev/zsh.nix
|
||||||
|
./dev/emacs
|
||||||
|
];
|
||||||
|
|
||||||
|
home.username = "${user.username}";
|
||||||
|
home.homeDirectory = pkgs.lib.mkDefault "/home/${user.username}";
|
||||||
|
home.stateVersion = user.stateVersion;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
programs.home-manager.enable = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
{ config, pkgs, lib, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
repoWallpaperDir = flakeRoot + "/assets/conf/desktop/wallpaper";
|
||||||
|
userRelRoot = "nixos_conf/wallpaperstuff";
|
||||||
|
userAbsRoot = "${config.home.homeDirectory}/${userRelRoot}";
|
||||||
|
# The video file you want as wallpaper (must exist under the synced dir)
|
||||||
|
userVideoPath = "${userAbsRoot}/videos/myWallpaper.mp4";
|
||||||
|
# (keep your existing approach: sync the repo wallpaper dir to the user dir)
|
||||||
|
repoWallpapersOnly = lib.cleanSourceWith {
|
||||||
|
src = repoWallpaperDir;
|
||||||
|
filter = path: type: true;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
pkgs.mpvpaper
|
||||||
|
pkgs.mpv
|
||||||
|
];
|
||||||
|
# Sync repo wallpapers (including videos/) into ~/nixos_conf/wallpaperstuff
|
||||||
|
home.file."${userRelRoot}" = {
|
||||||
|
source = repoWallpapersOnly;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
systemd.user.services.mpvpaper-wallpaper = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Video wallpaper (mpvpaper)";
|
||||||
|
After = [ "graphical-session.target" ];
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
Type = "simple";
|
||||||
|
# -p auto-pause saves resources when the wallpaper surface is hidden.
|
||||||
|
# '*' applies to all outputs.
|
||||||
|
# Stretch-to-fill (cover) behavior:
|
||||||
|
# --panscan=1.0 fills the entire output by cropping (no letterboxing).
|
||||||
|
# If you literally want distortion-stretch (ignore aspect ratio), use --keepaspect=no instead.
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.mpvpaper}/bin/mpvpaper \
|
||||||
|
-p \
|
||||||
|
-o "no-audio --loop-file=inf --no-terminal --really-quiet --panscan=1.0 --keepaspect=yes" \
|
||||||
|
'*' "${userVideoPath}"
|
||||||
|
'';
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 1;
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
{
|
||||||
|
wayland.windowManager.hyprland = {
|
||||||
|
# Load the Hyprexpo plugin (from nixpkgs)
|
||||||
|
plugins = [
|
||||||
|
pkgs.hyprlandPlugins.hyprexpo
|
||||||
|
];
|
||||||
|
|
||||||
|
# Append plugin config + keybind after your existing hyprland.conf
|
||||||
|
extraConfig = lib.mkAfter ''
|
||||||
|
############################
|
||||||
|
# Hyprexpo (workspace/window overview)
|
||||||
|
############################
|
||||||
|
|
||||||
|
# Basic plugin config (tweak as you like)
|
||||||
|
plugin {
|
||||||
|
hyprexpo {
|
||||||
|
columns = 3
|
||||||
|
gaps_in = 5
|
||||||
|
gaps_out = 20
|
||||||
|
|
||||||
|
# Optional; comment out if you don't want it
|
||||||
|
# workspace_method = center current
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{ config, lib, pkgs, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
hypridleConf = flakeRoot + "/assets/conf/desktop/hypr/hypridle.conf";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.hypridle ];
|
||||||
|
xdg.configFile."hypr/hypridle.conf".source = hypridleConf;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{ config, lib, pkgs, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
hyprConf = flakeRoot + "/assets/conf/desktop/hypr/hyprland.conf";
|
||||||
|
bindingsConf = flakeRoot + "/assets/conf/desktop/hypr/bindings.conf";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
wayland.windowManager.hyprland = {
|
||||||
|
enable = true;
|
||||||
|
# Load base config + bindings from repo files
|
||||||
|
extraConfig =
|
||||||
|
(builtins.readFile hyprConf)
|
||||||
|
+ "\n\n# --- Repo keybindings ---\n"
|
||||||
|
+ (builtins.readFile bindingsConf)
|
||||||
|
+ "\n";
|
||||||
|
settings = {
|
||||||
|
windowrule = [
|
||||||
|
"match:class nm-connection-editor, float 1, center 1, size 900 700"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
xdg.configFile."hypr/scripts/lid-lock.sh" = {
|
||||||
|
source = flakeRoot + "/assets/conf/desktop/hypr/scripts/lid-lock.sh";
|
||||||
|
executable = true;
|
||||||
|
};
|
||||||
|
xdg.portal = {
|
||||||
|
enable = true;
|
||||||
|
extraPortals = with pkgs; [
|
||||||
|
xdg-desktop-portal-gtk
|
||||||
|
xdg-desktop-portal-hyprland
|
||||||
|
];
|
||||||
|
# GTK als algemene backend (OpenURI is daar betrouwbaar)
|
||||||
|
config.common.default = [ "gtk" ];
|
||||||
|
# Hyprland alleen voor screensharing / remote desktop
|
||||||
|
config.hyprland = {
|
||||||
|
"org.freedesktop.impl.portal.Screencast" = [ "hyprland" ];
|
||||||
|
"org.freedesktop.impl.portal.RemoteDesktop" = [ "hyprland" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{config, lib, pkgs, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
lockPngSrc = flakeRoot + "/assets/lock.png";
|
||||||
|
hyprlockConf = flakeRoot + "/assets/conf/desktop/hypr/hyprlock.conf";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.hyprlock ];
|
||||||
|
xdg.configFile."hypr/lock.png".source = lockPngSrc;
|
||||||
|
xdg.configFile."hypr/hyprlock.conf".source = hyprlockConf;
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
{ config, lib, pkgs, flakeRoot,...}:
|
||||||
|
let
|
||||||
|
# Hyprscrolling drop-in config (repo -> ~/.config)
|
||||||
|
repoConf = flakeRoot + "/assets/conf/desktop/hypr/hyprscrolling.conf";
|
||||||
|
targetRel = "hypr/conf.d/90-hyprscrolling.conf";
|
||||||
|
# Overflow indicator script (repo -> ~/.config)
|
||||||
|
repoOverflowScript = flakeRoot + "/assets/conf/desktop/hypr/scripts/hyprscroll-overflow.sh";
|
||||||
|
targetOverflowRel = "hypr/scripts/hyprscroll-overflow.sh";
|
||||||
|
# Adapt columnsize to monitor
|
||||||
|
repoPerMonitorScript = flakeRoot + "/assets/conf/desktop/hypr/scripts/hyprscrolling-per-monitor.sh";
|
||||||
|
targetPerMonitor = "hypr/scripts/hyprscrolling-per-monitor.sh";
|
||||||
|
# Facilitate switching between scrolling and dwindle
|
||||||
|
repoSwitchScript =
|
||||||
|
flakeRoot + "/assets/conf/desktop/hypr/scripts/toggle-layout-scrolling-dwindle.sh";
|
||||||
|
targetSwitchScript = "hypr/scripts/toggle-layout-scrolling-dwindle.sh";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Ensure deps for the script exist at runtime
|
||||||
|
# (hyprctl comes with Hyprland; jq is often not installed by default)
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
jq
|
||||||
|
];
|
||||||
|
wayland.windowManager.hyprland = {
|
||||||
|
enable = true;
|
||||||
|
plugins = [
|
||||||
|
pkgs.hyprlandPlugins.hyprscrolling
|
||||||
|
];
|
||||||
|
extraConfig = ''
|
||||||
|
source = ~/.config/${targetRel}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
# Copy repo configs/scripts into ~/.config
|
||||||
|
xdg.configFile."${targetRel}".source = repoConf;
|
||||||
|
|
||||||
|
xdg.configFile."${targetOverflowRel}" = {
|
||||||
|
source = repoOverflowScript;
|
||||||
|
executable = true; # makes it chmod +x
|
||||||
|
};
|
||||||
|
xdg.configFile."${targetPerMonitor}" = {
|
||||||
|
source = repoPerMonitorScript;
|
||||||
|
executable = true; # makes it chmod +x
|
||||||
|
};
|
||||||
|
xdg.configFile."${targetSwitchScript}" = {
|
||||||
|
source = repoSwitchScript;
|
||||||
|
executable = true; # makes it chmod +x
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# home/desktop/hyprshell.nix (Home-Manager module)
|
||||||
|
{ config, pkgs, lib, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
repoDir = flakeRoot + "/assets/conf/desktop/hypr/hyprshell";
|
||||||
|
cfgRon = repoDir + "/config.ron";
|
||||||
|
cssFile = repoDir + "/styles.css";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
xdg.enable = true;
|
||||||
|
home.packages = [ pkgs.hyprshell ];
|
||||||
|
# Link repo -> ~/.config/hyprshell/...
|
||||||
|
xdg.configFile."hyprshell/config.ron".source = cfgRon;
|
||||||
|
xdg.configFile."hyprshell/styles.css".source = cssFile;
|
||||||
|
# Autostart (systemd user service)
|
||||||
|
systemd.user.services.hyprshell = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Hyprshell (window switcher / launcher)";
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
After = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart = "${pkgs.hyprshell}/bin/hyprshell";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 1;
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{ config, pkgs, lib, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
repoConf = flakeRoot + "/assets/conf/desktop/notifications/swaync/config.json";
|
||||||
|
repoStyle = flakeRoot + "/assets/conf/desktop/notifications/swaync/style.css";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
pkgs.swaynotificationcenter
|
||||||
|
pkgs.libnotify
|
||||||
|
];
|
||||||
|
# Ensure config directory exists in ~/.config
|
||||||
|
xdg.configFile."swaync/config.json".source = repoConf;
|
||||||
|
xdg.configFile."swaync/style.css".source = repoStyle;
|
||||||
|
# Start swaync automatically (systemd user service)
|
||||||
|
systemd.user.services.swaync = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Sway Notification Center";
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart = "${pkgs.swaynotificationcenter}/bin/swaync";
|
||||||
|
Restart = "always";
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{ config, lib, pkgs, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
repoScript =
|
||||||
|
flakeRoot + "/assets/conf/desktop/hypr/scripts/powermenu.sh";
|
||||||
|
targetRel = "hypr/scripts/powermenu.sh";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Ensure script exists in ~/.config/hypr/scripts/
|
||||||
|
xdg.configFile."${targetRel}" = {
|
||||||
|
source = repoScript;
|
||||||
|
executable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#+begin_src nix :tangle home/desktop/wallpaper.nix :noweb tangle :mkdirp yes
|
||||||
|
{ config, pkgs, lib, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
repoWallpaperDir = flakeRoot + "/assets/conf/desktop/wallpaper";
|
||||||
|
repoWallpaperConf = flakeRoot + "/assets/conf/desktop/wallpaper/wallpaper.conf";
|
||||||
|
userRelRoot = "nixos_conf/wallpaperstuff";
|
||||||
|
userAbsRoot = "${config.home.homeDirectory}/${userRelRoot}";
|
||||||
|
userConfPath = "${userAbsRoot}/wallpaper.conf";
|
||||||
|
# Exclude wallpaper.conf so HM does NOT manage it (avoids backup collisions)
|
||||||
|
repoWallpapersOnly = lib.cleanSourceWith {
|
||||||
|
src = repoWallpaperDir;
|
||||||
|
filter = path: type:
|
||||||
|
(builtins.baseNameOf path) != "wallpaper.conf";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [ pkgs.wpaperd ];
|
||||||
|
# Sync everything *except* wallpaper.conf into ~/nixos_conf/wallpaperstuff
|
||||||
|
home.file."${userRelRoot}" = {
|
||||||
|
source = repoWallpapersOnly;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
# Now safely overwrite the config every activation (no HM collision)
|
||||||
|
home.activation.wallpaperConfForce =
|
||||||
|
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
|
set -euo pipefail
|
||||||
|
mkdir -p "${userAbsRoot}"
|
||||||
|
install -m 0644 "${repoWallpaperConf}" "${userConfPath}"
|
||||||
|
'';
|
||||||
|
systemd.user.services.wpaperd = {
|
||||||
|
Unit = {
|
||||||
|
Description = "wpaperd wallpaper daemon";
|
||||||
|
After = [ "default.target" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${pkgs.wpaperd}/bin/wpaperd --config ${userConfPath}";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 1;
|
||||||
|
};
|
||||||
|
Install.WantedBy = [ "default.target" ];
|
||||||
|
;
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{ config, pkgs, lib, flakeRoot, inputs ? null, ... }:
|
||||||
|
let
|
||||||
|
walkerPkg =
|
||||||
|
if inputs != null && inputs ? walker
|
||||||
|
then inputs.walker.packages.${pkgs.system}.default
|
||||||
|
else pkgs.walker;
|
||||||
|
elephantPkg =
|
||||||
|
if inputs != null && inputs ? elephant
|
||||||
|
then inputs.elephant.packages.${pkgs.system}.default
|
||||||
|
else pkgs.elephant;
|
||||||
|
sessionTarget = "graphical-session.target";
|
||||||
|
# All theme files now live here
|
||||||
|
repoThemesDir = flakeRoot + "/assets/conf/desktop/walker";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
xdg.enable = true;
|
||||||
|
home.packages = [ walkerPkg elephantPkg ];
|
||||||
|
# ~/.config/walker/themes/*
|
||||||
|
xdg.configFile."walker/themes/frosted/default.css".source = repoThemesDir + "/themes/frosted/default.css";
|
||||||
|
xdg.configFile."walker/themes/frosted/style.css".source = repoThemesDir + "/themes/frosted/style.css";
|
||||||
|
xdg.configFile."walker/config.toml".source = repoThemesDir + "/config.toml";
|
||||||
|
# xdg.configFile."walker/themes/default.html".source = repoThemesDir + "/default.html";
|
||||||
|
# (services unchanged)
|
||||||
|
systemd.user.services.elephant = { /* ... your existing service ... */ };
|
||||||
|
systemd.user.services.walker = { /* ... your existing service ... */ };
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{ config, lib, pkgs, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
repoWaybarDir = flakeRoot + "/assets/conf/desktop/waybar";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.waybar.enable = true;
|
||||||
|
# Ensure config matches repo (HM-managed symlink, not user-editable)
|
||||||
|
xdg.configFile."waybar/config" = {
|
||||||
|
source = repoWaybarDir + "/config.jsonc";
|
||||||
|
force = true;
|
||||||
|
};
|
||||||
|
# Override HM's internally-generated waybar-style.css derivation
|
||||||
|
# and use your repo file instead.
|
||||||
|
xdg.configFile."waybar/style.css" = {
|
||||||
|
source = lib.mkForce (repoWaybarDir + "/style.css");
|
||||||
|
force = true;
|
||||||
|
};
|
||||||
|
# Prevent HM from also trying to generate style content via programs.waybar.style
|
||||||
|
# (not strictly required once mkForce is in place, but keeps intent clear)
|
||||||
|
programs.waybar.style = "";
|
||||||
|
}
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
{ config, lib, pkgs, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
# Where your numbered wallpapers live (1.*, 2.*, ... 9.*)
|
||||||
|
userRelRoot = "nixos_conf/wallpaperstuff";
|
||||||
|
userAbsRoot = "${config.home.homeDirectory}/${userRelRoot}";
|
||||||
|
picturesDir = "${userAbsRoot}/pictures";
|
||||||
|
# (Optional) still sync your repo wallpapers/scripts into ~/nixos_conf/wallpaperstuff
|
||||||
|
repoWallpaperDir = flakeRoot + "/assets/conf/desktop/wallpaper";
|
||||||
|
repoWallpapersOnly = lib.cleanSourceWith {
|
||||||
|
src = repoWallpaperDir;
|
||||||
|
filter = path: type: true;
|
||||||
|
};
|
||||||
|
daemonRel = "hypr/scripts/hyprpaper-ws-daemon.sh";
|
||||||
|
setRel = "hypr/scripts/set-wallpaper.sh";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [
|
||||||
|
pkgs.hyprpaper
|
||||||
|
pkgs.socat
|
||||||
|
pkgs.jq
|
||||||
|
pkgs.findutils
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.gnused
|
||||||
|
pkgs.gawk
|
||||||
|
];
|
||||||
|
# Keep your existing "sync wallpapers into a writable dir" pattern
|
||||||
|
home.file."${userRelRoot}" = {
|
||||||
|
source = repoWallpapersOnly;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
# Hyprpaper config (hyprpaper reads this; it does NOT need to write it)
|
||||||
|
# `ipc = true` enables `hyprctl hyprpaper ...` commands. :contentReference[oaicite:0]{index=0}
|
||||||
|
xdg.configFile."hypr/hyprpaper.conf".text = ''
|
||||||
|
ipc = true
|
||||||
|
splash = false
|
||||||
|
'';
|
||||||
|
# Workspace wallpaper daemon: listens to socket2, applies w-<id>=... mapping
|
||||||
|
# Uses workspacev2 to get numeric workspace id. :contentReference[oaicite:1]{index=1}
|
||||||
|
xdg.configFile."${daemonRel}" = {
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
: "''${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}"
|
||||||
|
: "''${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}"
|
||||||
|
SOCK="''${XDG_RUNTIME_DIR}/hypr/''${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock"
|
||||||
|
[[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; }
|
||||||
|
PICTURES_DIR="''${1:-${picturesDir}}"
|
||||||
|
FIT_MODE="fill" # hyprpaper fit_mode: contain|cover|tile|fill :contentReference[oaicite:2]{index=2}
|
||||||
|
HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
|
||||||
|
MAP_ROOT="''${HYPR_DIR}/hyprpaper/config"
|
||||||
|
focused_monitor() {
|
||||||
|
hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1
|
||||||
|
}
|
||||||
|
map_file_for_monitor() {
|
||||||
|
local mon="''${1}"
|
||||||
|
echo "''${MAP_ROOT}/''${mon}/defaults.conf"
|
||||||
|
}
|
||||||
|
ensure_map_file() {
|
||||||
|
local mon="''${1}"
|
||||||
|
local f
|
||||||
|
f="$(map_file_for_monitor "''${mon}")"
|
||||||
|
mkdir -p "$(dirname "''${f}")"
|
||||||
|
if [[ ! -f "''${f}" ]]; then
|
||||||
|
# Seed with 1..9 from picturesDir if present, else empty entries
|
||||||
|
{
|
||||||
|
for i in 1 2 3 4 5 6 7 8 9; do
|
||||||
|
seed="$(ls -1 "''${PICTURES_DIR}/''${i}."* 2>/dev/null | head -n 1 || true)"
|
||||||
|
echo "w-''${i}= ''${seed}"
|
||||||
|
done
|
||||||
|
} > "''${f}"
|
||||||
|
fi
|
||||||
|
echo "''${f}"
|
||||||
|
}
|
||||||
|
get_wall_for_ws() {
|
||||||
|
local mon="''${1}"
|
||||||
|
local wsid="''${2}"
|
||||||
|
local f key val
|
||||||
|
f="$(ensure_map_file "''${mon}")"
|
||||||
|
key="w-''${wsid}"
|
||||||
|
# accept "w-1=/path" or "w-1= /path"
|
||||||
|
val="$(awk -F= -v k="''${key}" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "''${f}" || true)"
|
||||||
|
echo "''${val}"
|
||||||
|
}
|
||||||
|
apply_wallpaper() {
|
||||||
|
local mon="''${1}"
|
||||||
|
local wsid="''${2}"
|
||||||
|
local file
|
||||||
|
file="$(get_wall_for_ws "''${mon}" "''${wsid}")"
|
||||||
|
[[ -n "''${file}" ]] || return 0
|
||||||
|
[[ -f "''${file}" ]] || return 0
|
||||||
|
# Apply via IPC
|
||||||
|
# hyprpaper “wallpaper { monitor path fit_mode }” model is per monitor. :contentReference[oaicite:3]{index=3}
|
||||||
|
hyprctl hyprpaper wallpaper "''${mon}, ''${file}, ''${FIT_MODE}" >/dev/null
|
||||||
|
}
|
||||||
|
# Initial apply on startup
|
||||||
|
mon="$(focused_monitor || true)"
|
||||||
|
wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
|
||||||
|
[[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
|
||||||
|
handle() {
|
||||||
|
local line="''${1}"
|
||||||
|
case "''${line}" in
|
||||||
|
workspacev2* )
|
||||||
|
# workspacev2>>ID,NAME :contentReference[oaicite:4]{index=4}
|
||||||
|
local payload wsid
|
||||||
|
payload="''${line#*>>}"
|
||||||
|
wsid="''${payload%%,*}"
|
||||||
|
mon="$(focused_monitor || true)"
|
||||||
|
[[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
|
||||||
|
;;
|
||||||
|
focusedmon* )
|
||||||
|
# focusedmon>>MON,WORKSPACENAME :contentReference[oaicite:5]{index=5}
|
||||||
|
# When monitor focus changes, re-apply for the active workspace id.
|
||||||
|
mon="$(focused_monitor || true)"
|
||||||
|
wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
|
||||||
|
[[ -n "''${mon}" && -n "''${wsid}" ]] && apply_wallpaper "''${mon}" "''${wsid}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
socat -U - UNIX-CONNECT:"''${SOCK}" | while read -r line; do
|
||||||
|
handle "''${line}" || true
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# CLI setter in the style of your inspiration script.
|
||||||
|
# Usage: set-wallpaper.sh <workspace_id> <monitor> [wallpaper]
|
||||||
|
xdg.configFile."${setRel}" = {
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
HYPR_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr"
|
||||||
|
MAP_ROOT="''${HYPR_DIR}/hyprpaper/config"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: set-wallpaper.sh <workspace_id> <monitor> [wallpaper_path]"
|
||||||
|
}
|
||||||
|
|
||||||
|
wsid="''${1:-}"
|
||||||
|
mon="''${2:-}"
|
||||||
|
wp="''${3:-}"
|
||||||
|
|
||||||
|
[[ -n "''${wsid}" ]] || { usage; exit 1; }
|
||||||
|
[[ -n "''${mon}" ]] || { usage; exit 1; }
|
||||||
|
|
||||||
|
cfg="''${MAP_ROOT}/''${mon}/defaults.conf"
|
||||||
|
mkdir -p "$(dirname "''${cfg}")"
|
||||||
|
[[ -f "''${cfg}" ]] || touch "''${cfg}"
|
||||||
|
|
||||||
|
if [[ -z "''${wp}" ]]; then
|
||||||
|
# Random pick from your defaults folder if you want; adjust path if needed:
|
||||||
|
wp="$(find "$HOME/.config/wallpapers/defaults" -type f 2>/dev/null | shuf -n 1 || true)"
|
||||||
|
[[ -n "''${wp}" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure key exists; if not, append it
|
||||||
|
key="w-''${wsid}"
|
||||||
|
if ! grep -q "^''${key}=" "''${cfg}"; then
|
||||||
|
echo "''${key}=" >> "''${cfg}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set mapping
|
||||||
|
${pkgs.gnused}/bin/sed -i "s|^''${key}=.*|''${key}= ''${wp}|g" "''${cfg}"
|
||||||
|
|
||||||
|
# If this monitor is currently showing that workspace id, apply immediately
|
||||||
|
curws="$(hyprctl -j monitors | jq -r --arg m "''${mon}" '.[] | select(.name==$m) | .activeWorkspace.id' | head -n 1 || true)"
|
||||||
|
if [[ "''${curws}" == "''${wsid}" ]]; then
|
||||||
|
hyprctl hyprpaper wallpaper "''${mon}, ''${wp}, fill" >/dev/null
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Services
|
||||||
|
systemd.user.services.hyprpaper = {
|
||||||
|
Unit = {
|
||||||
|
Description = "hyprpaper wallpaper daemon";
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
After = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart = "${pkgs.hyprpaper}/bin/hyprpaper";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 1;
|
||||||
|
};
|
||||||
|
Install = { WantedBy = [ "graphical-session.target" ]; };
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.hyprpaper-ws-daemon = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)";
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
After = [ "graphical-session.target" "hyprpaper.service" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart = "${pkgs.bash}/bin/bash ${config.xdg.configHome}/${daemonRel} ${picturesDir}";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 1;
|
||||||
|
};
|
||||||
|
Install = { WantedBy = [ "graphical-session.target" ]; };
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{ config, pkgs, lib, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
repoAlacrittyConf = flakeRoot + "/assets/conf/dev/alacritty.toml";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
xdg.enable = true;
|
||||||
|
programs.alacritty.enable = true;
|
||||||
|
# Override the config generated by programs.alacritty
|
||||||
|
xdg.configFile."alacritty/alacritty.toml".source = lib.mkForce repoAlacrittyConf;
|
||||||
|
catppuccin.alacritty.enable = true;
|
||||||
|
catppuccin.alacritty.flavor = "mocha";
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
{
|
||||||
|
programs = {
|
||||||
|
vscode.enable = true;
|
||||||
|
vim.enable = true;
|
||||||
|
ripgrep.enable = true;
|
||||||
|
btop.enable = true;
|
||||||
|
fzf = {
|
||||||
|
enable = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
enableBashIntegration = true;
|
||||||
|
};
|
||||||
|
zoxide = {
|
||||||
|
enable = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
enableBashIntegration = true;
|
||||||
|
};
|
||||||
|
eza = {
|
||||||
|
enable = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
enableBashIntegration = true;
|
||||||
|
};
|
||||||
|
direnv = {
|
||||||
|
enable = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
enableBashIntegration = true;
|
||||||
|
nix-direnv.enable = true;
|
||||||
|
};
|
||||||
|
# Zsh-specific config belongs here
|
||||||
|
zsh = {
|
||||||
|
# for emacs-eat package
|
||||||
|
initContent = lib.mkOrder 1200 ''
|
||||||
|
[ -n "$EAT_SHELL_INTEGRATION_DIR" ] && \
|
||||||
|
source "$EAT_SHELL_INTEGRATION_DIR/zsh"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
git = {
|
||||||
|
enable = true;
|
||||||
|
lfs.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
programs.emacs = {
|
||||||
|
enable = true;
|
||||||
|
# install with tree sitter enabled
|
||||||
|
package = (pkgs.emacs-pgtk.override { withTreeSitter = true; });
|
||||||
|
extraPackages = epkgs: [
|
||||||
|
# also install all tree sitter grammars
|
||||||
|
epkgs.manualPackages.treesit-grammars.with-all-grammars
|
||||||
|
epkgs.nerd-icons # nerd fonts support
|
||||||
|
epkgs.doom-modeline # model line
|
||||||
|
epkgs.diminish # hides modes from modeline
|
||||||
|
epkgs.eldoc # doc support
|
||||||
|
epkgs.pulsar # pulses the cursor when jumping about
|
||||||
|
epkgs.which-key # help porcelain
|
||||||
|
epkgs.expreg # expand region
|
||||||
|
epkgs.vundo # undo tree
|
||||||
|
epkgs.puni # structured editing
|
||||||
|
epkgs.avy # jumping utility
|
||||||
|
epkgs.consult # emacs right click
|
||||||
|
epkgs.vertico # minibuffer completion
|
||||||
|
epkgs.marginalia # annotations for completions
|
||||||
|
epkgs.crux # utilities
|
||||||
|
epkgs.magit # git porcelain
|
||||||
|
epkgs.nerd-icons-corfu # nerd icons for completion
|
||||||
|
epkgs.corfu # completion
|
||||||
|
epkgs.cape # completion extensions
|
||||||
|
epkgs.orderless # search paradigm
|
||||||
|
epkgs.yasnippet # snippets support
|
||||||
|
epkgs.yasnippet-snippets # commonly used snippets
|
||||||
|
epkgs.rg # ripgrep
|
||||||
|
epkgs.exec-path-from-shell # load env and path
|
||||||
|
epkgs.eat # better shell
|
||||||
|
epkgs.rust-mode # rust mode (when rust-ts doesn't cut it)
|
||||||
|
epkgs.rustic # more rust things
|
||||||
|
epkgs.nix-mode # nix lang
|
||||||
|
epkgs.hcl-mode # hashicorp file mode
|
||||||
|
epkgs.shell-pop # quick shell popup
|
||||||
|
epkgs.envrc # support for loading .envrc
|
||||||
|
epkgs.nixpkgs-fmt # format nix files
|
||||||
|
epkgs.f # string + file utilities
|
||||||
|
epkgs.gptel # llm chat (mainly claude)
|
||||||
|
epkgs.catppuccin-theme # catppuccin theme
|
||||||
|
epkgs.eldoc-box # docs in a box
|
||||||
|
epkgs.sideline # mainly for flymake errors on the side
|
||||||
|
epkgs.sideline-flymake # mainly for flymake errors on the side
|
||||||
|
epkgs.sideline-eglot # mainly for flymake errors on the side
|
||||||
|
];
|
||||||
|
};
|
||||||
|
home.sessionVariables = {
|
||||||
|
EDITOR = "emacs";
|
||||||
|
XDG_SCREENSHOTS_DIR = "~/screenshots";
|
||||||
|
};
|
||||||
|
home.file = {
|
||||||
|
emacs-init = {
|
||||||
|
source = ./early-init.el;
|
||||||
|
target = ".emacs.d/early-init.el";
|
||||||
|
};
|
||||||
|
emacs = {
|
||||||
|
source = ./init.el;
|
||||||
|
target = ".emacs.d/init.el";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.nextcloud-client = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
;;; package --- early init -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Prevents white flash and better Emacs defaults
|
||||||
|
;;; Code:
|
||||||
|
(set-language-environment "UTF-8")
|
||||||
|
(setq-default
|
||||||
|
default-frame-alist
|
||||||
|
'((background-color . "#1e1e2e")
|
||||||
|
(bottom-divider-width . 1) ; Thin horizontal window divider
|
||||||
|
(foreground-color . "#bac2de") ; Default foreground color
|
||||||
|
(fullscreen . maximized) ; Maximize the window by default
|
||||||
|
(horizontal-scroll-bars . nil) ; No horizontal scroll-bars
|
||||||
|
(left-fringe . 8) ; Thin left fringe
|
||||||
|
(menu-bar-lines . 0) ; No menu bar
|
||||||
|
(right-divider-width . 1) ; Thin vertical window divider
|
||||||
|
(right-fringe . 8) ; Thin right fringe
|
||||||
|
(tool-bar-lines . 0) ; No tool bar
|
||||||
|
(undecorated . t) ; Remove extraneous X decorations
|
||||||
|
(vertical-scroll-bars . nil)) ; No vertical scroll-bars
|
||||||
|
user-full-name "Henrov henrov" ; ME!
|
||||||
|
;; memory configuration
|
||||||
|
;; Higher garbage collection threshold, prevents frequent gc locks, reset later
|
||||||
|
gc-cons-threshold most-positive-fixnum
|
||||||
|
;; Ignore warnings for (obsolete) elisp compilations
|
||||||
|
byte-compile-warnings '(not obsolete)
|
||||||
|
;; And other log types completely
|
||||||
|
warning-suppress-log-types '((comp) (bytecomp))
|
||||||
|
;; Large files are okay in the new millenium.
|
||||||
|
large-file-warning-threshold 100000000
|
||||||
|
;; dont show garbage collection messages at startup, will reset later
|
||||||
|
garbage-collection-messages nil
|
||||||
|
;; native compilation
|
||||||
|
package-native-compile t
|
||||||
|
native-comp-warning-on-missing-source nil
|
||||||
|
native-comp-async-report-warnings-errors 'silent
|
||||||
|
;; Read more based on system pipe capacity
|
||||||
|
read-process-output-max (max (* 10240 10240) read-process-output-max)
|
||||||
|
;; scroll configuration
|
||||||
|
scroll-margin 0 ; Lets scroll to the end of the margin
|
||||||
|
scroll-conservatively 100000 ; Never recenter the window
|
||||||
|
scroll-preserve-screen-position 1 ; Scrolling back and forth
|
||||||
|
;; frame config
|
||||||
|
;; Improve emacs startup time by not resizing to adjust for custom settings
|
||||||
|
frame-inhibit-implied-resize t
|
||||||
|
;; Dont resize based on character height / width but to exact pixels
|
||||||
|
frame-resize-pixelwise t
|
||||||
|
;; backups & files
|
||||||
|
backup-directory-alist '(("." . "~/.backups/")) ; Don't clutter
|
||||||
|
backup-by-copying t ; Don't clobber symlinks
|
||||||
|
create-lockfiles nil ; Don't have temp files
|
||||||
|
delete-old-versions t ; Cleanup automatically
|
||||||
|
kept-new-versions 6 ; Update every few times
|
||||||
|
kept-old-versions 2 ; And cleanup even more
|
||||||
|
version-control t ; Version them backups
|
||||||
|
delete-by-moving-to-trash t ; Dont delete, send to trash instead
|
||||||
|
;; startup
|
||||||
|
inhibit-startup-screen t ; I have already done the tutorial. Twice
|
||||||
|
inhibit-startup-message t ; I know I am ready
|
||||||
|
inhibit-startup-echo-area-message t ; Yep, still know it
|
||||||
|
initial-scratch-message nil ; I know it is the scratch buffer!
|
||||||
|
initial-buffer-choice nil
|
||||||
|
inhibit-startup-buffer-menu t
|
||||||
|
inhibit-x-resources t
|
||||||
|
initial-major-mode 'fundamental-mode
|
||||||
|
pgtk-wait-for-event-timeout 0.001 ; faster child frames
|
||||||
|
ad-redefinition-action 'accept ; dont care about legacy things being redefined
|
||||||
|
inhibit-compacting-font-caches t
|
||||||
|
;; tabs
|
||||||
|
tab-width 4 ; Always tab 4 spaces.
|
||||||
|
indent-tabs-mode nil ; Never use actual tabs.
|
||||||
|
;; rendering
|
||||||
|
cursor-in-non-selected-windows nil ; dont render cursors other windows
|
||||||
|
;; packages
|
||||||
|
use-package-always-defer t
|
||||||
|
load-prefer-newer t
|
||||||
|
default-input-method nil
|
||||||
|
use-dialog-box nil
|
||||||
|
use-file-dialog nil
|
||||||
|
use-package-expand-minimally t
|
||||||
|
package-enable-at-startup nil
|
||||||
|
use-package-enable-imenu-support t
|
||||||
|
auto-mode-case-fold nil ; No second pass of case-insensitive search over auto-mode-alist.
|
||||||
|
package-archives '(("melpa" . "https://melpa.org/packages/")
|
||||||
|
("gnu" . "https://elpa.gnu.org/packages/")
|
||||||
|
("nongnu" . "https://elpa.nongnu.org/nongnu/")
|
||||||
|
("melpa-stable" . "https://stable.melpa.org/packages/"))
|
||||||
|
package-archive-priorities '(("gnu" . 99)
|
||||||
|
("nongnu" . 80)
|
||||||
|
("melpa" . 70)
|
||||||
|
("melpa-stable" . 50))
|
||||||
|
)
|
||||||
|
;;; early-init.el ends here
|
||||||
@@ -0,0 +1,400 @@
|
|||||||
|
;;; package --- Summary - My minimal Emacs init file -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Simple Emacs setup I carry everywhere
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(setq custom-file (locate-user-emacs-file "custom.el"))
|
||||||
|
(load custom-file 'noerror) ;; no error on missing custom file
|
||||||
|
|
||||||
|
(require 'package)
|
||||||
|
(package-initialize)
|
||||||
|
|
||||||
|
(defun reset-custom-vars ()
|
||||||
|
"Resets the custom variables that were set to crazy numbers"
|
||||||
|
(setopt gc-cons-threshold (* 1024 1024 100))
|
||||||
|
(setopt garbage-collection-messages t))
|
||||||
|
|
||||||
|
(use-package emacs
|
||||||
|
:custom
|
||||||
|
(native-comp-async-query-on-exit t)
|
||||||
|
(read-answer-short t)
|
||||||
|
(use-short-answers t)
|
||||||
|
(enable-recursive-minibuffers t)
|
||||||
|
(which-func-update-delay 1.0)
|
||||||
|
(visible-bell nil)
|
||||||
|
(custom-buffer-done-kill t)
|
||||||
|
(whitespace-line-column nil)
|
||||||
|
(x-underline-at-descent-line t)
|
||||||
|
(imenu-auto-rescan t)
|
||||||
|
(uniquify-buffer-name-style 'forward)
|
||||||
|
(confirm-nonexistent-file-or-buffer nil)
|
||||||
|
(create-lockfiles nil)
|
||||||
|
(make-backup-files nil)
|
||||||
|
(kill-do-not-save-duplicates t)
|
||||||
|
(sentence-end-double-space nil)
|
||||||
|
(treesit-enabled-modes t)
|
||||||
|
:init
|
||||||
|
;; base visual
|
||||||
|
(menu-bar-mode -1) ;; no menu bar
|
||||||
|
(toggle-scroll-bar -1) ;; no scroll bar
|
||||||
|
(tool-bar-mode -1) ;; no tool bar either
|
||||||
|
(blink-cursor-mode -1) ;; stop blinking
|
||||||
|
|
||||||
|
;; font of the century
|
||||||
|
(set-frame-font "Aporetic Sans Mono 12" nil t)
|
||||||
|
|
||||||
|
:bind
|
||||||
|
(("C-<wheel-up>" . pixel-scroll-precision) ; dont zoom in please, just scroll
|
||||||
|
("C-<wheel-down>" . pixel-scroll-precision) ; dont zoom in either, just scroll
|
||||||
|
("C-x k" . kill-current-buffer)) ; kill the buffer, dont ask
|
||||||
|
:hook
|
||||||
|
(text-mode . delete-trailing-whitespace-mode)
|
||||||
|
(prog-mode . delete-trailing-whitespace-mode)
|
||||||
|
(after-init . global-display-line-numbers-mode) ;; always show line numbers
|
||||||
|
(after-init . column-number-mode) ;; column number in the mode line
|
||||||
|
(after-init . size-indication-mode) ;; file size in the mode line
|
||||||
|
(after-init . pixel-scroll-precision-mode) ;; smooth mouse scroll
|
||||||
|
(after-init . electric-pair-mode) ;; i mean ... parens should auto create
|
||||||
|
(after-init . reset-custom-vars)
|
||||||
|
)
|
||||||
|
|
||||||
|
(use-package autorevert
|
||||||
|
:ensure nil
|
||||||
|
:custom
|
||||||
|
(auto-revert-interval 3)
|
||||||
|
(auto-revert-remote-files nil)
|
||||||
|
(auto-revert-use-notify t)
|
||||||
|
(auto-revert-avoid-polling nil)
|
||||||
|
(auto-revert-verbose t)
|
||||||
|
:hook
|
||||||
|
(after-init . global-auto-revert-mode))
|
||||||
|
|
||||||
|
(use-package recentf
|
||||||
|
:ensure nil
|
||||||
|
:commands (recentf-mode recentf-cleanup)
|
||||||
|
:hook
|
||||||
|
(after-init . recentf-mode)
|
||||||
|
:custom
|
||||||
|
(recentf-auto-cleanup 'never)
|
||||||
|
(recentf-exclude
|
||||||
|
(list "\\.tar$" "\\.tbz2$" "\\.tbz$" "\\.tgz$" "\\.bz2$"
|
||||||
|
"\\.bz$" "\\.gz$" "\\.gzip$" "\\.xz$" "\\.zip$"
|
||||||
|
"\\.7z$" "\\.rar$"
|
||||||
|
"COMMIT_EDITMSG\\'"
|
||||||
|
"\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\|bmp\\|xpm\\)$"
|
||||||
|
"-autoloads\\.el$" "autoload\\.el$"))
|
||||||
|
|
||||||
|
:config
|
||||||
|
;; A cleanup depth of -90 ensures that `recentf-cleanup' runs before
|
||||||
|
;; `recentf-save-list', allowing stale entries to be removed before the list
|
||||||
|
;; is saved by `recentf-save-list', which is automatically added to
|
||||||
|
;; `kill-emacs-hook' by `recentf-mode'.
|
||||||
|
(add-hook 'kill-emacs-hook #'recentf-cleanup -90))
|
||||||
|
|
||||||
|
(use-package savehist
|
||||||
|
:ensure nil
|
||||||
|
:commands (savehist-mode savehist-save)
|
||||||
|
:hook
|
||||||
|
(after-init . savehist-mode)
|
||||||
|
:custom
|
||||||
|
(savehist-autosave-interval 600)
|
||||||
|
(savehist-additional-variables
|
||||||
|
'(kill-ring ; clipboard
|
||||||
|
register-alist ; macros
|
||||||
|
mark-ring global-mark-ring ; marks
|
||||||
|
search-ring regexp-search-ring)))
|
||||||
|
|
||||||
|
(use-package hl-line
|
||||||
|
:ensure nil
|
||||||
|
:custom
|
||||||
|
(hl-line-sticky-flag nil)
|
||||||
|
(global-hl-line-sticky-flag nil)
|
||||||
|
:hook
|
||||||
|
(after-init . global-hl-line-mode))
|
||||||
|
|
||||||
|
(use-package saveplace
|
||||||
|
:ensure nil
|
||||||
|
:commands (save-place-mode save-place-local-mode)
|
||||||
|
:hook
|
||||||
|
(after-init . save-place-mode)
|
||||||
|
:custom
|
||||||
|
(save-place-limit 400))
|
||||||
|
|
||||||
|
(use-package nerd-icons
|
||||||
|
:custom
|
||||||
|
;; disable bright icon colors
|
||||||
|
(nerd-icons-color-icons nil))hells.nix
|
||||||
|
|
||||||
|
(use-package doom-modeline
|
||||||
|
:custom
|
||||||
|
(inhibit-compacting-font-caches t) ;; speed
|
||||||
|
(doom-modeline-buffer-file-name-style 'relative-from-project)
|
||||||
|
(doom-modeline-major-mode-icon nil) ;; distracting icons, no thank you
|
||||||
|
(doom-modeline-buffer-encoding nil) ;; everything is utf-8 anyway
|
||||||
|
(doom-modeline-buffer-state-icon nil) ;; the filename already shows me
|
||||||
|
(doom-modeline-lsp nil) ;; lsp state is too distracting, too often
|
||||||
|
:hook (after-init . doom-modeline-mode))
|
||||||
|
|
||||||
|
(load-theme 'catppuccin :no-confirm)
|
||||||
|
|
||||||
|
(use-package diminish :demand t) ;; declutter the modeline
|
||||||
|
(use-package eldoc
|
||||||
|
:diminish eldoc-mode
|
||||||
|
:custom
|
||||||
|
(eldoc-echo-area-use-multiline-p nil)) ;; docs for everything
|
||||||
|
|
||||||
|
(use-package eldoc-box
|
||||||
|
:defer t
|
||||||
|
:config
|
||||||
|
(set-face-background 'eldoc-box-border (catppuccin-color 'green))
|
||||||
|
(set-face-background 'eldoc-box-body (catppuccin-color 'base))
|
||||||
|
:bind
|
||||||
|
(("M-h" . eldoc-box-help-at-point)))
|
||||||
|
|
||||||
|
(use-package pulsar
|
||||||
|
:commands pulsar-global-mode pulsar-recenter-top pulsar-reveal-entry
|
||||||
|
:init
|
||||||
|
(defface pulsar-catppuccin
|
||||||
|
`((default :extend t)
|
||||||
|
(((class color) (min-colors 88) (background light))
|
||||||
|
:background ,(catppuccin-color 'sapphire))
|
||||||
|
(((class color) (min-colors 88) (background dark))
|
||||||
|
:background ,(catppuccin-color 'sapphire))
|
||||||
|
(t :inverse-video t))
|
||||||
|
"Alternative nord face for `pulsar-face'."
|
||||||
|
:group 'pulsar-faces)
|
||||||
|
:custom
|
||||||
|
(pulsar-face 'pulsar-catppuccin)
|
||||||
|
:hook
|
||||||
|
(after-init . pulsar-global-mode))
|
||||||
|
|
||||||
|
(use-package which-key
|
||||||
|
:commands which-key-mode
|
||||||
|
:diminish which-key-mode
|
||||||
|
:hook
|
||||||
|
(after-init . which-key-mode))
|
||||||
|
|
||||||
|
(use-package expreg
|
||||||
|
:bind ("M-m" . expreg-expand))
|
||||||
|
|
||||||
|
(use-package vundo) ;; undo tree
|
||||||
|
|
||||||
|
;; better structured editing
|
||||||
|
(use-package puni
|
||||||
|
:commands puni-global-mode
|
||||||
|
:hook
|
||||||
|
(after-init . puni-global-mode))
|
||||||
|
|
||||||
|
(use-package avy
|
||||||
|
:bind
|
||||||
|
("M-i" . avy-goto-char-2)
|
||||||
|
:custom
|
||||||
|
(avy-background t))
|
||||||
|
|
||||||
|
(use-package consult
|
||||||
|
:bind
|
||||||
|
("C-x b" . consult-buffer) ;; orig. switch-to-buffer
|
||||||
|
("M-y" . consult-yank-pop) ;; orig. yank-pop
|
||||||
|
("M-g M-g" . consult-goto-line) ;; orig. goto-line
|
||||||
|
("M-g i" . consult-imenu) ;; consult version is interactive
|
||||||
|
("M-g r" . consult-ripgrep) ;; find in project also works
|
||||||
|
:custom
|
||||||
|
(consult-narrow-key "<"))
|
||||||
|
|
||||||
|
(use-package vertico
|
||||||
|
:commands vertico-mode
|
||||||
|
:custom
|
||||||
|
(read-file-name-completion-ignore-case t)
|
||||||
|
(read-buffer-completion-ignore-case t)
|
||||||
|
(completion-ignore-case t)
|
||||||
|
(enable-recursive-minibuffers t)
|
||||||
|
(minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt))
|
||||||
|
:init
|
||||||
|
(vertico-mode)
|
||||||
|
:hook
|
||||||
|
(minibuffer-setup-hook . cursor-intangible-mode))
|
||||||
|
|
||||||
|
(use-package marginalia
|
||||||
|
:commands marginalia-mode
|
||||||
|
:hook (after-init . marginalia-mode))
|
||||||
|
|
||||||
|
(use-package crux
|
||||||
|
:bind
|
||||||
|
("C-c M-e" . crux-find-user-init-file)
|
||||||
|
("C-c C-w" . crux-transpose-windows)
|
||||||
|
("C-c M-d" . crux-find-current-directory-dir-locals-file)
|
||||||
|
("C-a" . crux-move-beginning-of-line))
|
||||||
|
|
||||||
|
(use-package magit
|
||||||
|
:bind (("C-M-g" . magit-status)))
|
||||||
|
|
||||||
|
(use-package nerd-icons-corfu
|
||||||
|
:commands nerd-icons-corfu-formatter
|
||||||
|
:defines corfu-margin-formatters)
|
||||||
|
|
||||||
|
(use-package corfu
|
||||||
|
:commands global-corfu-mode
|
||||||
|
:custom
|
||||||
|
(corfu-cycle t)
|
||||||
|
(corfu-auto t)
|
||||||
|
(corfu-auto-delay 1)
|
||||||
|
(corfu-auto-prefix 3)
|
||||||
|
(corfu-separator ?_)
|
||||||
|
:hook
|
||||||
|
(after-init . global-corfu-mode)
|
||||||
|
:config
|
||||||
|
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
|
||||||
|
|
||||||
|
(use-package cape)
|
||||||
|
|
||||||
|
(use-package orderless
|
||||||
|
:custom
|
||||||
|
(completion-styles '(orderless partial-completion basic))
|
||||||
|
(completion-category-defaults nil)
|
||||||
|
(completion-category-overrides nil))
|
||||||
|
|
||||||
|
(use-package yasnippet
|
||||||
|
:commands yas-global-mode
|
||||||
|
:diminish yas-minor-mode
|
||||||
|
:hook
|
||||||
|
(after-init . yas-global-mode))
|
||||||
|
|
||||||
|
(use-package yasnippet-snippets :after yasnippet)
|
||||||
|
|
||||||
|
(use-package exec-path-from-shell
|
||||||
|
:commands exec-path-from-shell-initialize
|
||||||
|
:custom
|
||||||
|
(exec-path-from-shell-arguments nil)
|
||||||
|
:hook
|
||||||
|
(after-init . exec-path-from-shell-initialize))
|
||||||
|
|
||||||
|
(use-package nixpkgs-fmt
|
||||||
|
:custom
|
||||||
|
(nixpkgs-fmt-command "nixfmt"))
|
||||||
|
|
||||||
|
(use-package eat
|
||||||
|
:bind
|
||||||
|
(("C-c e p" . eat-project)
|
||||||
|
("C-c e t" . eat)))
|
||||||
|
|
||||||
|
(use-package f :demand t)
|
||||||
|
|
||||||
|
(use-package envrc
|
||||||
|
:commands envrc-global-mode
|
||||||
|
:hook
|
||||||
|
(after-init . envrc-global-mode))
|
||||||
|
|
||||||
|
(use-package gptel
|
||||||
|
:commands gptel-make-anthropic f-read-text
|
||||||
|
:config
|
||||||
|
(gptel-make-anthropic "Claude"
|
||||||
|
:stream t :key (f-read-text "/run/secrets/claude_key")))
|
||||||
|
|
||||||
|
(use-package sideline-flymake)
|
||||||
|
(use-package sideline-eglot)
|
||||||
|
(use-package sideline
|
||||||
|
:custom
|
||||||
|
(sideline-backends-right '(sideline-flymake sideline-eglot))
|
||||||
|
:hook
|
||||||
|
(eglot-managed-mode . sideline-mode)
|
||||||
|
(flymake-mode . sideline-mode))
|
||||||
|
|
||||||
|
(use-package eglot
|
||||||
|
:custom
|
||||||
|
(eglot-extend-to-xref t)
|
||||||
|
(eglot-ignored-server-capabilities '(:inlayHintProvider))
|
||||||
|
(jsonrpc-event-hook nil)
|
||||||
|
:hook
|
||||||
|
(eglot-managed-mode . eldoc-box-hover-mode)
|
||||||
|
(before-save . eldoc-format-buffer)
|
||||||
|
:bind
|
||||||
|
(:map eglot-mode-map
|
||||||
|
("C-c l a" . eglot-code-actions)
|
||||||
|
("C-c l r" . eglot-rename)
|
||||||
|
("C-c l h" . eldoc)
|
||||||
|
("C-c l g" . xref-find-references)
|
||||||
|
("C-c l w" . eglot-reconnect)))
|
||||||
|
|
||||||
|
(use-package proced
|
||||||
|
:custom
|
||||||
|
(proced-auto-update-flag t)
|
||||||
|
(proced-auto-update-interval 3)
|
||||||
|
(proced-enable-color-flag t)
|
||||||
|
(proced-show-remote-processes t))
|
||||||
|
|
||||||
|
(use-package org
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:commands (org-mode org-capture org-agenda)
|
||||||
|
:init
|
||||||
|
(defvar org-journal-file "~/nextcloud/org/journal.org")
|
||||||
|
(defvar org-archive-file "~/nextcloud/org/archive.org")
|
||||||
|
(defvar org-notes-file "~/nextcloud/org/notes.org")
|
||||||
|
(defvar org-inbox-file "~/nextcloud/org/inbox.org")
|
||||||
|
(defvar org-work-file "~/nextcloud/org/work.org")
|
||||||
|
(defun my/org-capture-project-target-heading ()
|
||||||
|
"Determine Org target headings from the current file's project path.
|
||||||
|
|
||||||
|
This function assumes a directory structure like '~/projects/COMPANY/PROJECT/'.
|
||||||
|
It extracts 'COMPANY' and 'PROJECT' to use as nested headlines
|
||||||
|
for an Org capture template.
|
||||||
|
|
||||||
|
If the current buffer is not visi
|
||||||
|
ting a file within such a
|
||||||
|
project structure, it returns nil, causing capture to default to
|
||||||
|
the top of the file."
|
||||||
|
(when-let* ((path (buffer-file-name))) ; Ensure we are in a file-visiting buffer
|
||||||
|
(let ((path-parts (split-string path "/" t " ")))
|
||||||
|
(when-let* ((projects-pos (cl-position "projects" path-parts :test #'string=))
|
||||||
|
(company (nth (+ 1 projects-pos) path-parts))
|
||||||
|
(project (nth (+ 2 projects-pos) path-parts)))
|
||||||
|
;; Return a list of headlines for Org to find or create.
|
||||||
|
(list company project)))))
|
||||||
|
:bind
|
||||||
|
(("C-c c" . org-capture)
|
||||||
|
("C-c i" . org-store-link)
|
||||||
|
("C-c a" . org-agenda)
|
||||||
|
:map org-mode-map
|
||||||
|
("C-c t" . org-toggle-inline-images)
|
||||||
|
("C-c l" . org-toggle-link-display))
|
||||||
|
:custom
|
||||||
|
(org-agenda-files (list org-inbox-file org-journal-file))
|
||||||
|
(org-directory "~/nextcloud/org")
|
||||||
|
(org-default-notes-file org-inbox-file)
|
||||||
|
(org-archive-location (concat org-archive-file "::* From %s"))
|
||||||
|
(org-log-done 'time)
|
||||||
|
(org-log-into-drawer t)
|
||||||
|
(org-hide-emphasis-markers t)
|
||||||
|
(org-src-fontify-natively t)
|
||||||
|
(org-src-tab-acts-natively t)
|
||||||
|
(org-capture-templates '(("t" "Todo" entry (file org-inbox-file)
|
||||||
|
"* TODO %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n)")
|
||||||
|
("j" "Journal" entry (file+olp+datetree org-journal-file)
|
||||||
|
"* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
|
||||||
|
("n" "Note" entry (file org-notes-file)
|
||||||
|
"* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n%a\n\n")
|
||||||
|
("p" "Project Task" item
|
||||||
|
(file+function org-work-file my/org-capture-project-target-heading)
|
||||||
|
"* TODO %? \n CLOCK: %U"
|
||||||
|
))
|
||||||
|
)
|
||||||
|
:config
|
||||||
|
;; Enable syntax highlighting in code blocks
|
||||||
|
(add-hook 'org-mode-hook 'turn-on-font-lock)
|
||||||
|
(add-hook 'org-mode-hook 'org-indent-mode))
|
||||||
|
|
||||||
|
;; extras
|
||||||
|
(use-package comp-run
|
||||||
|
:ensure nil
|
||||||
|
:config
|
||||||
|
(push "tramp-loaddefs.el.gz" native-comp-jit-compilation-deny-list)
|
||||||
|
(push "cl-loaddefs.el.gz" native-comp-jit-compilation-deny-list))
|
||||||
|
|
||||||
|
(use-package rustic
|
||||||
|
:custom
|
||||||
|
(rustic-lsp-client 'eglot))
|
||||||
|
|
||||||
|
(provide 'init)
|
||||||
|
|
||||||
|
;;; init.el ends here
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
{ config, pkgs, lib, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
catppuccinMochaConf =
|
||||||
|
builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/Catppuccin-Mocha.conf");
|
||||||
|
# Your own keymaps / other settings (but we will NOT rely on it for opacity)
|
||||||
|
repoKittyConfText =
|
||||||
|
builtins.readFile (flakeRoot + "/assets/conf/dev/terminal/kitty.conf");
|
||||||
|
in
|
||||||
|
{
|
||||||
|
xdg.enable = true;
|
||||||
|
# Stable theme file so kitty.conf can include it without /nix/store paths
|
||||||
|
xdg.configFile."kitty/themes/Catppuccin-Mocha.conf".text = catppuccinMochaConf;
|
||||||
|
programs.kitty = {
|
||||||
|
enable = true;
|
||||||
|
# Home Manager generates ~/.config/kitty/kitty.conf; we append in-order:
|
||||||
|
# 1) include theme
|
||||||
|
# 2) your repo config (keymaps etc.)
|
||||||
|
# 3) force opacity LAST so it always wins
|
||||||
|
extraConfig = ''
|
||||||
|
# 1) Theme first (stable path)
|
||||||
|
include themes/Catppuccin-Mocha.conf
|
||||||
|
# 2) Your repo config (may also include theme; harmless if duplicated)
|
||||||
|
${repoKittyConfText}
|
||||||
|
# 3) Force transparency last (wins)
|
||||||
|
#background_opacity 0.60
|
||||||
|
#dynamic_background_opacity yes
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
# shells.nix — Home-Manager module
|
||||||
|
#
|
||||||
|
# Reads:
|
||||||
|
# ${flakeRoot}/assets/conf/shells.nixdev/terminal/enabled_shells.conf
|
||||||
|
# ${flakeRoot}/assets/conf/dev/terminal/aliases.conf
|
||||||
|
#
|
||||||
|
# For each enabled shell in [enabled_shells]:
|
||||||
|
# - installs/enables shell (where HM has an enable option)
|
||||||
|
# - if ${flakeRoot}/assets/conf/dev/terminal/<shell>.conf exists, sources it
|
||||||
|
# - ensures a *user-editable* aliases file exists in the shell’s default location
|
||||||
|
# - if a shell is disabled, its aliases file is removed
|
||||||
|
# .
|
||||||
|
# Notes on “editable”:
|
||||||
|
# - We do NOT manage the aliases file with xdg.configFile/home.file (those would be overwritten).
|
||||||
|
# - Instead, we create/remove files via home.activation (create only if missing).
|
||||||
|
{ config, pkgs, lib, flakeRoot, ... }:
|
||||||
|
let
|
||||||
|
terminalDir = flakeRoot + "/assets/conf/dev/terminal";
|
||||||
|
enabledFile = terminalDir + "/enabled_shells.conf";
|
||||||
|
aliasesFile = terminalDir + "/aliases.conf";
|
||||||
|
trim = lib.strings.trim;
|
||||||
|
# ---------- minimal INI-ish parser (sections + raw lines) ----------
|
||||||
|
readMaybe = p: if builtins.pathExists p then builtins.readFile p else "";
|
||||||
|
normalizeLine = l: trim (lib.replaceStrings [ "\r" ] [ "" ] l);
|
||||||
|
parseSections = text:
|
||||||
|
let
|
||||||
|
lines = map normalizeLine (lib.splitString "\n" text);
|
||||||
|
isHeader = l:
|
||||||
|
let s = l;
|
||||||
|
in lib.hasPrefix "[" s
|
||||||
|
&& lib.hasSuffix "]" s
|
||||||
|
&& builtins.stringLength s >= 3;
|
||||||
|
nameOf = l: lib.removeSuffix "]" (lib.removePrefix "[" l);
|
||||||
|
folded =
|
||||||
|
builtins.foldl'
|
||||||
|
(st: l:
|
||||||
|
if l == "" then st else
|
||||||
|
if isHeader l then st // { current = nameOf l; }
|
||||||
|
else
|
||||||
|
let
|
||||||
|
cur = st.current;
|
||||||
|
prev = st.sections.${cur} or [];
|
||||||
|
in
|
||||||
|
st // { sections = st.sections // { ${cur} = prev ++ [ l ]; }; }
|
||||||
|
)
|
||||||
|
{ current = "__root__"; sections = {}; }
|
||||||
|
lines;
|
||||||
|
in
|
||||||
|
folded.sections;
|
||||||
|
enabledSections = parseSections (readMaybe enabledFile);
|
||||||
|
aliasSections = parseSections (readMaybe aliasesFile);
|
||||||
|
# [enabled_shells] lines: key = yes/no
|
||||||
|
enabledShells =
|
||||||
|
let
|
||||||
|
raw = enabledSections.enabled_shells or [];
|
||||||
|
parseKV = l:
|
||||||
|
let m = builtins.match ''^([A-Za-z0-9_-]+)[[:space:]]*=[[:space:]]*(.*)$'' l;
|
||||||
|
in if m == null then null else {
|
||||||
|
k = trim (builtins.elemAt m 0);
|
||||||
|
v = lib.toLower (trim (builtins.elemAt m 1));
|
||||||
|
};
|
||||||
|
kvs = builtins.filter (x: x != null) (map parseKV raw);
|
||||||
|
in
|
||||||
|
map (x: x.k) (builtins.filter (x: x.v == "yes" || x.v == "true" || x.v == "1") kvs);
|
||||||
|
shellEnabled = shell: builtins.elem shell enabledShells;
|
||||||
|
# ---------- per-shell repo config file (<shell>.conf) ----------
|
||||||
|
shellConfPath = shell: terminalDir + "/${shell}.conf";
|
||||||
|
shellConfExists = shell: builtins.pathExists (shellConfPath shell);
|
||||||
|
sourceIfExistsSh = p: ''
|
||||||
|
if [ -f "${toString p}" ]; then
|
||||||
|
source "${toString p}"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
# ---------- aliases section helpers ----------
|
||||||
|
secLines = name: aliasSections.${name} or [];
|
||||||
|
secText = name: lib.concatStringsSep "\n" (secLines name);
|
||||||
|
# Default alias-file locations
|
||||||
|
bashAliasesPath = "${config.home.homeDirectory}/.bash_aliases";
|
||||||
|
zshAliasesPath = "${config.home.homeDirectory}/.zsh_aliases";
|
||||||
|
fishAliasesPath = "${config.xdg.configHome}/fish/conf.d/aliases.fish";
|
||||||
|
# Seeds (created once; user can edit afterwards)
|
||||||
|
bashSeed = ''
|
||||||
|
# Created once from: ${toString aliasesFile}
|
||||||
|
# Edit freely; Home Manager will not overwrite this file.
|
||||||
|
#
|
||||||
|
${secText "bash_zsh"}
|
||||||
|
${secText "bash_specific"}
|
||||||
|
'';
|
||||||
|
zshSeed = ''
|
||||||
|
# Created once from: ${toString aliasesFile}
|
||||||
|
# Edit freely; Home Manager will not overwrite this file.
|
||||||
|
${secText "bash_zsh"}
|
||||||
|
${secText "zsh_specific"}
|
||||||
|
'';
|
||||||
|
# Fish: translate [bash_zsh] POSIX alias lines + append [fish_specific] as-is
|
||||||
|
parsePosixAlias = l:
|
||||||
|
let
|
||||||
|
m = builtins.match ''^[[:space:]]*alias[[:space:]]+([A-Za-z0-9_+-]+)=(.*)$'' l;
|
||||||
|
in
|
||||||
|
if m == null then null else
|
||||||
|
let
|
||||||
|
name = trim (builtins.elemAt m 0);
|
||||||
|
rhs0 = trim (builtins.elemAt m 1);
|
||||||
|
unquote =
|
||||||
|
if lib.hasPrefix "'" rhs0 && lib.hasSuffix "'" rhs0 then
|
||||||
|
lib.removeSuffix "'" (lib.removePrefix "'" rhs0)
|
||||||
|
else if lib.hasPrefix "\"" rhs0 && lib.hasSuffix "\"" rhs0 then
|
||||||
|
lib.removeSuffix "\"" (lib.removePrefix "\"" rhs0)
|
||||||
|
else
|
||||||
|
rhs0;
|
||||||
|
in
|
||||||
|
{ inherit name; cmd = unquote; };
|
||||||
|
escapeForFish = s:
|
||||||
|
lib.replaceStrings
|
||||||
|
[ "\\" "\"" "$" "`" ]
|
||||||
|
[ "\\\\" "\\\"" "\\$" "\\`" ]
|
||||||
|
s;
|
||||||
|
fishTranslated =
|
||||||
|
let
|
||||||
|
parsed = builtins.filter (x: x != null) (map parsePosixAlias (secLines "bash_zsh"));
|
||||||
|
in
|
||||||
|
lib.concatStringsSep "\n" (map (a: ''alias ${a.name} "${escapeForFish a.cmd}"'') parsed);
|
||||||
|
fishSeed = ''
|
||||||
|
# Created once from: ${toString aliasesFile}
|
||||||
|
# Edit freely; Home Manager will not overwrite this file.
|
||||||
|
status is-interactive; or exit
|
||||||
|
# Translated from [bash_zsh]:
|
||||||
|
${fishTranslated}
|
||||||
|
# From [fish_specific]:
|
||||||
|
${secText "fish_specific"}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
xdg.enable = true;
|
||||||
|
# Install/enable shells (no login-shell changes)
|
||||||
|
programs.bash.enable = shellEnabled "bash";
|
||||||
|
programs.zsh.enable = shellEnabled "zsh";
|
||||||
|
programs.fish.enable = shellEnabled "fish";
|
||||||
|
home.packages =
|
||||||
|
(lib.optionals (shellEnabled "dash") [ pkgs.dash ]) ++
|
||||||
|
(lib.optionals (shellEnabled "nushell") [ pkgs.nushell ]);
|
||||||
|
# Source per-shell repo config (if present) AND source the user alias file (if it exists).
|
||||||
|
# Important: define each option only ONCE.
|
||||||
|
programs.bash.bashrcExtra = lib.mkIf (shellEnabled "bash") (lib.mkAfter ''
|
||||||
|
${lib.optionalString (shellConfExists "bash") (sourceIfExistsSh (shellConfPath "bash"))}
|
||||||
|
if [ -f "${bashAliasesPath}" ]; then
|
||||||
|
source "${bashAliasesPath}"
|
||||||
|
fi
|
||||||
|
'');
|
||||||
|
programs.zsh.initContent = lib.mkIf (shellEnabled "zsh") (lib.mkAfter ''
|
||||||
|
${lib.optionalString (shellConfExists "zsh") (sourceIfExistsSh (shellConfPath "zsh"))}
|
||||||
|
if [ -f "${zshAliasesPath}" ]; then
|
||||||
|
source "${zshAliasesPath}"
|
||||||
|
fi
|
||||||
|
'');
|
||||||
|
programs.fish.interactiveShellInit = lib.mkIf (shellEnabled "fish") (lib.mkAfter ''
|
||||||
|
${lib.optionalString (shellConfExists "fish") ''
|
||||||
|
if test -f "${toString (shellConfPath "fish")}"
|
||||||
|
source "${toString (shellConfPath "fish")}"
|
||||||
|
end
|
||||||
|
''}
|
||||||
|
if test -f "${fishAliasesPath}"
|
||||||
|
source "${fishAliasesPath}"
|
||||||
|
end
|
||||||
|
'');
|
||||||
|
# Create/remove alias files based on enabled shells
|
||||||
|
home.activation.shellAliasesFiles = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
|
set -euo pipefail
|
||||||
|
# bash -------------------------------------------------------
|
||||||
|
if ${if shellEnabled "bash" then "true" else "false"}; then
|
||||||
|
cat > "${bashAliasesPath}" <<'EOF'
|
||||||
|
${bashSeed}
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
rm -f "${bashAliasesPath}"
|
||||||
|
fi
|
||||||
|
# zsh -------------------------------------------------------
|
||||||
|
if ${if shellEnabled "zsh" then "true" else "false"}; then
|
||||||
|
cat > "${zshAliasesPath}" <<'EOF'
|
||||||
|
${zshSeed}
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
rm -f "${zshAliasesPath}"
|
||||||
|
fi
|
||||||
|
# fish -------------------------------------------------------
|
||||||
|
if ${if shellEnabled "fish" then "true" else "false"}; then
|
||||||
|
mkdir -p "$(dirname "${fishAliasesPath}")"
|
||||||
|
cat > "${fishAliasesPath}" <<'EOF'
|
||||||
|
${fishSeed}
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
rm -f "${fishAliasesPath}"
|
||||||
|
fi
|
||||||
|
# fish
|
||||||
|
if ${if shellEnabled "fish" then "true" else "false"}; then
|
||||||
|
mkdir -p "$(dirname "${fishAliasesPath}")"
|
||||||
|
if [ ! -f "${fishAliasesPath}" ]; then
|
||||||
|
cat > "${fishAliasesPath}" <<'EOF'
|
||||||
|
${fishSeed}
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
rm -f "${fishAliasesPath}"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{ config, pkgs, lib, flakeRoot, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
repoStarshipToml = flakeRoot + "/assets/conf/dev/terminal/starship.toml";
|
||||||
|
|
||||||
|
# The exact key that appears in the error:
|
||||||
|
targetKey = "${config.home.homeDirectory}/.config/starship.toml";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
xdg.enable = true;
|
||||||
|
|
||||||
|
programs.starship = {
|
||||||
|
enable = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
enableBashIntegration = true;
|
||||||
|
enableFishIntegration = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Force the *actual conflicting option* (home.file."<abs path>".source)
|
||||||
|
home.file."${targetKey}".source = lib.mkForce repoStarshipToml;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{ config, pkgs, lib, flakeRoot, ... }:
|
||||||
|
{
|
||||||
|
programs.zsh = {
|
||||||
|
enable = true;
|
||||||
|
enableCompletion = true;
|
||||||
|
autocd = true;
|
||||||
|
# Optional but recommended: keep zsh config in one dir (relative to $HOME)
|
||||||
|
dotDir = ".config/zsh";
|
||||||
|
oh-my-zsh = {
|
||||||
|
enable = true;
|
||||||
|
theme = "";
|
||||||
|
plugins = [
|
||||||
|
"git"
|
||||||
|
"sudo"
|
||||||
|
"extract"
|
||||||
|
"colored-man-pages"
|
||||||
|
"command-not-found"
|
||||||
|
"history"
|
||||||
|
"docker"
|
||||||
|
"kubectl"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
autosuggestion.enable = true;
|
||||||
|
syntaxHighlighting.enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -10,16 +10,16 @@ emacs README.org --batch -f org-babel-tangle
|
|||||||
|
|
||||||
git add .
|
git add .
|
||||||
git commit -m "experiment: local change"
|
git commit -m "experiment: local change"
|
||||||
sudo nixos-rebuild test --flake .#your_hostname
|
sudo nixos-rebuild test --flake .#YOUR_HOSTNAME
|
||||||
|
|
||||||
emacs README.org --batch -f org-babel-tangle && emacs --batch -l org -l ox-html README.org -f org-html-export-to-html --kill
|
emacs README.org --batch -f org-babel-tangle && emacs --batch -l org -l ox-html README.org -f org-html-export-to-html --kill
|
||||||
git add .
|
git add .
|
||||||
git commit -m "literate: structural update"
|
git commit -m "literate: structural update"
|
||||||
sudo nixos-rebuild test --flake .#your_hostname
|
sudo nixos-rebuild test --flake .#YOUR_HOSTNAME
|
||||||
|
|
||||||
- a NIXOS system installed with a user with sudo rights.
|
- a NIXOS system installed with a user with sudo rights.
|
||||||
- an internet connection
|
- an internet connection
|
||||||
- the folder henrovnix as you find it here
|
- the folder henrovnix_ok as you find it here
|
||||||
|
|
||||||
# Check if NetworkManager service is running
|
# Check if NetworkManager service is running
|
||||||
systemctl status NetworkManager
|
systemctl status NetworkManager
|
||||||
@@ -36,18 +36,18 @@ nmcli connection show --active
|
|||||||
# Optional: show device status
|
# Optional: show device status
|
||||||
nmcli device status
|
nmcli device status
|
||||||
|
|
||||||
find ~/Repos/nixos/henrovnix \
|
find ~/Repos/nixos/henrovnix_ok \
|
||||||
-type d -name ".*" -prune -o \
|
-type d -name ".*" -prune -o \
|
||||||
-type f -print0 \
|
-type f -print0 \
|
||||||
| xargs -0 sed -i 's/=<defaultUser>=/your_user/g'
|
| xargs -0 sed -i 's/=<defaultUser>=/YOUR_USER/g'
|
||||||
|
|
||||||
find ~/Repos/nixos/henrovnix \
|
find ~/Repos/nixos/henrovnix_ok \
|
||||||
-type d -name ".*" -prune -o \
|
-type d -name ".*" -prune -o \
|
||||||
-type f -print0 \
|
-type f -print0 \
|
||||||
| xargs -0 sed -i 's/machine1/your_hostname/g'
|
| xargs -0 sed -i 's/machine1/YOUR_HOSTNAME/g'
|
||||||
|
|
||||||
mv ./machines/machine1 ./machines/your_hostname
|
mv ./machines/machine1 ./machines/YOUR_HOSTNAME
|
||||||
|
|
||||||
nixos-generate-config
|
nixos-generate-config
|
||||||
|
|
||||||
sudo nixos-rebuild switch --flake .#your_hostname
|
sudo nixos-rebuild switch --flake .#YOUR_HOSTNAME
|
||||||
|
|||||||
Reference in New Issue
Block a user