diff --git a/home-manager/home.nix b/home-manager/home.nix index 3a3fe22..5aa2c1f 100755 --- a/home-manager/home.nix +++ b/home-manager/home.nix @@ -32,6 +32,7 @@ package = pkgs.runCommand "moveUp" { } '' mkdir -p $out/share/icons ln -s ${ + pkgs.fetchzip { url = url; hash = hash; diff --git a/home-manager/modules/hypr/hypr.nix b/home-manager/modules/hypr/hypr.nix index 77c460a..6ea67f1 100644 --- a/home-manager/modules/hypr/hypr.nix +++ b/home-manager/modules/hypr/hypr.nix @@ -21,10 +21,22 @@ hyprland brightnessctl playerctl - wl-clipboard hyprshot - tesseract + nemo + hyprpaper + pywal ]; + services.hyprpaper = { + enable = true; + settings = { + preload = "~/Pictures/wallpaper.png"; + wallpaper = [ + "eDP-2,~/Pictures/wallpaper.png" + "eDP-1,~/Pictures/wallpaper.png" + "HDMI-A-1,~/Pictures/wallpaper.png" + ]; + }; + }; programs.hyprpanel = { enable = true; settings = builtins.fromJSON (builtins.readFile ./hyprpanel.json); @@ -44,6 +56,9 @@ exec-once = [ # "hyprlock" + "wal -R &" + "hyprpaper &" + # "hyprctl hyprpaper reload ,~/Pictures/wallpaper.png" "hyprpanel &" "gsettings set org.gnome.desktop.interface cursor-theme '${config.home.pointerCursor.name}'" "gsettings set org.gnome.desktop.interface cursor-size ${ @@ -188,7 +203,7 @@ mouse_move_enables_dpms = true; key_press_enables_dpms = true; disable_splash_rendering = true; - focus_on_activate = true; + focus_on_activate = false; # TODO: enable after rules.nix diff --git a/home-manager/modules/hypr/hyprland/keybinds.nix b/home-manager/modules/hypr/hyprland/keybinds.nix index 0414c30..796d2d2 100644 --- a/home-manager/modules/hypr/hyprland/keybinds.nix +++ b/home-manager/modules/hypr/hyprland/keybinds.nix @@ -59,7 +59,7 @@ ${super}, Return, exec, ~/.config/hypr/scripts/launch_first_available.sh "kitty" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm"'' "${super}, T, exec, telegram-desktop" '' - ${super}, E, exec, ~/.config/hypr/scripts/launch_first_available.sh "dolphin" "nautilus" "nemo" "thunar" "kitty -1 fish -c yazi"'' + ${super}, E, exec, ~/.config/hypr/scripts/launch_first_available.sh "nemo" "dolphin" "nautilus" "thunar" "kitty -1 zsh -c yazi"'' '' ${super}, W, exec, ~/.config/hypr/scripts/launch_first_available.sh "google-chrome-stable" "zen" "firefox" "brave" "chromium" "microsoft-edge-stable" "opera" "librewolf"'' '' diff --git a/home-manager/modules/hypr/hyprpanel.json b/home-manager/modules/hypr/hyprpanel.json index 52ec653..708d0c4 100644 --- a/home-manager/modules/hypr/hyprpanel.json +++ b/home-manager/modules/hypr/hyprpanel.json @@ -90,7 +90,7 @@ "theme.bar.transparent": true, "theme.bar.buttons.background_opacity": 45, "theme.bar.menus.opacity": 90, - "theme.matugen": false, + "theme.matugen": true, "wallpaper.pywal": true, "wallpaper.image": "/home/krosh/Pictures/wallpaper.png", "theme.bar.border.width": "0.15em", diff --git a/home-manager/modules/programs.nix b/home-manager/modules/programs.nix index 46f3bcd..73ee445 100644 --- a/home-manager/modules/programs.nix +++ b/home-manager/modules/programs.nix @@ -15,6 +15,10 @@ python312 python312Packages.virtualenv python312Packages.pip + libreoffice + imagemagick + wl-clipboard + tesseract ]; # do i really need it? diff --git a/home-manager/modules/zsh/move_avatar.sh b/home-manager/modules/zsh/move_avatar.sh new file mode 100755 index 0000000..e71e864 --- /dev/null +++ b/home-manager/modules/zsh/move_avatar.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +set -euo pipefail + +PICS="$HOME/Pictures" +AVATAR="$PICS/avatar.png" +BCKP="$PICS/.bckp" + +NO_BCKP=0 +DEL_SRC=0 + +while getopts ":nr" opt; do + case "$opt" in + n) NO_BCKP=1 ;; + r) DEL_SRC=1 ;; + *) echo "Usage: $0 [-n] [-r] " >&2; exit 2 ;; + esac +done +shift $((OPTIND-1)) + +src=${1:-} +if [ -z "$src" ]; then + echo "Usage: $0 [-n] [-r] " >&2 + exit 2 +fi +if [ ! -f "$src" ]; then + echo "Error: '$src' not found" >&2 + exit 3 +fi + +orig_src="$src" + +if command -v magick >/dev/null 2>&1; then + IM_CMD="magick" +else + echo "Error: ImageMagick 'convert' not found" >&2 + exit 5 +fi + +tmp=$(mktemp --suffix=.png) || { echo "Error: mktemp failed" >&2; exit 6; } + +if ! $IM_CMD -- "$src" "$tmp" >/dev/null 2>&1; then + echo "Error: ImageMagick conversion failed" >&2 + rm -f -- "$tmp" + exit 7 +fi + +src="$tmp" +case "${src,,}" in + *.png) ;; + *) echo "Error: only .png files are accepted" >&2; exit 4 ;; +esac + +if [ "$NO_BCKP" -eq 0 ] && [ -f "$AVATAR" ]; then + mkdir -p "$BCKP" + ts=$(date +%Y%m%d_%H%M%S) + mv -f -- "$AVATAR" "$BCKP/avatar${ts}.png" +fi + +cp -f -- "$src" "$AVATAR" + +if [ "$DEL_SRC" -eq 1 ]; then + rm -f -- "$orig_src" +fi diff --git a/home-manager/modules/zsh/move_wallpaper.sh b/home-manager/modules/zsh/move_wallpaper.sh new file mode 100755 index 0000000..a2eed96 --- /dev/null +++ b/home-manager/modules/zsh/move_wallpaper.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +set -euo pipefail + +dest_dir="$HOME/Pictures/Wallpapers" +rmflag=0 + +usage() { + echo "Usage: $0 [-r] [src-file ...]" + echo " -r remove source file after successful conversion" + exit 2 +} + +while getopts ":r" opt; do + case "$opt" in + r) rmflag=1 ;; + *) usage ;; + esac +done +shift $((OPTIND-1)) + +# Require at least one file +if [ "$#" -lt 1 ]; then + echo "Error: no source files provided" + usage +fi + +# Check ImageMagick +if ! command -v magick >/dev/null 2>&1; then + echo "Error: ImageMagick 'magick' command not found" + exit 1 +fi + +mkdir -p "$dest_dir" +timestamp=$(date +%Y%m%d%H%M%S) +counter=0 + +# Process each file one by one +for src in "$@"; do + if [ ! -e "$src" ]; then + echo "Error: '$src' does not exist, skipping" + continue + fi + + counter=$((counter + 1)) + + dst="$dest_dir/wallpaper${timestamp}_${counter}.png" + + if magick -- "$src" "$dst"; then + echo "Created: $dst" + if [ "$rmflag" -eq 1 ]; then + rm -f -- "$src" + fi + else + echo "Error: conversion failed for '$src'" + fi +done + +exit 0 diff --git a/home-manager/modules/zsh/next_wallpaper.sh b/home-manager/modules/zsh/next_wallpaper.sh new file mode 100755 index 0000000..8afad90 --- /dev/null +++ b/home-manager/modules/zsh/next_wallpaper.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash +# /home/krosh/Documents/Github/nixos-config/home-manager/modules/zsh/next_wallpaper.sh +# Pick next or random wallpaper from ~/Pictures/Wallpapers and update symlink ~/Pictures/wallpaper.png +# Then call: hyprctl hyprpaper reload ,"$WALLPAPER" + +set -euo pipefail + +RANDOM_MODE=0 +while getopts "r" opt; do + case "$opt" in + r) RANDOM_MODE=1 ;; + *) echo "Usage: $0 [-r]" >&2; exit 2 ;; + esac +done + +WALLPAPERS_DIR="$HOME/Pictures/Wallpapers" +SYMLINK="$HOME/Pictures/wallpaper.png" + +if [ ! -d "$WALLPAPERS_DIR" ]; then + echo "Wallpapers directory not found: $WALLPAPERS_DIR" >&2 + exit 1 +fi + +# Resolve current wallpaper (target of symlink). If not a symlink or missing, CUR will be empty. +CUR="$(readlink -f "$SYMLINK" 2>/dev/null || true)" + +# Collect png files; sort by timestamp ascending (oldest first) using ls -tr. +# If there are spaces in names, ls handles them, but filenames with newlines are unsupported. +mapfile -t FILES < <(find "$WALLPAPERS_DIR" -maxdepth 1 -type f -iname '*.png' -print0 | xargs -0 ls -1tr 2>/dev/null || true) + +if [ "${#FILES[@]}" -eq 0 ]; then + echo "No png wallpapers found in $WALLPAPERS_DIR" >&2 + exit 1 +fi + +choose_random() { + # pick random file different from CUR if possible + candidates=() + for f in "${FILES[@]}"; do + [ "$(readlink -f "$f")" = "$CUR" ] && continue + candidates+=("$f") + done + if [ "${#candidates[@]}" -eq 0 ]; then + # only current exists + echo "No other wallpaper to choose (only current exists)." >&2 + exit 1 + fi + idx=$((RANDOM % ${#candidates[@]})) + echo "${candidates[$idx]}" +} + +choose_next() { + # find current in sorted list and pick next (wrap). If current not found, choose first. + n=${#FILES[@]} + if [ "$n" -eq 1 ]; then + # only one file + if [ "$(readlink -f "${FILES[0]}")" = "$CUR" ]; then + echo "No other wallpaper to choose (only current exists)." >&2 + exit 1 + else + echo "${FILES[0]}" + return + fi + fi + + # find index of current + idx=-1 + for i in "${!FILES[@]}"; do + if [ "$(readlink -f "${FILES[i]}")" = "$CUR" ]; then + idx="$i" + break + fi + done + + if [ "$idx" -eq -1 ]; then + # current not in list: choose first + echo "${FILES[0]}" + return + fi + + # next index with wrap + next=$(( (idx + 1) % n )) + # if next equals current (possible if only one), error handled above + echo "${FILES[$next]}" +} + +if [ "$RANDOM_MODE" -eq 1 ]; then + NEW="$(choose_random)" +else + NEW="$(choose_next)" +fi + +# Ensure absolute path +NEW="$(readlink -f "$NEW")" + +# Create symlink (atomic-ish): create temporary symlink and move +TMP_SYMLINK="$(mktemp -u "${SYMLINK}.tmp.XXXX")" +ln -sfn -- "$NEW" "$TMP_SYMLINK" +mv -f "$TMP_SYMLINK" "$SYMLINK" + +# Export for hyprctl command (and run it) +WALLPAPER="$NEW" +# run exactly as requested +hyprctl hyprpaper reload ,"$WALLPAPER" +hyprpanel -q ; hyprpanel & disown +wal -c +wal -n -i "$WALLPAPER" + +exit 0 \ No newline at end of file diff --git a/home-manager/modules/zsh/select_command.sh b/home-manager/modules/zsh/select_command.sh index 06a99f9..912ecfe 100755 --- a/home-manager/modules/zsh/select_command.sh +++ b/home-manager/modules/zsh/select_command.sh @@ -1,6 +1,9 @@ SAVED_MODES_FILE=".saved_modes" TEMP_FILE=".saved_modes.tmp" +# TODO: упростить работу с fzf +# либо сделать вход сразу с fuzzy + # Function to display the menu show_menu() { printf "\n\n=== Saved Modes ===\n" @@ -117,10 +120,11 @@ main() { show_menu echo "Options:" - echo " [number] - Execute mode" - echo " n - Add new mode" + echo " f - Search with fzf" + echo " [number] - Execute mode" + echo " n - Add new mode" echo " r[number] - Remove mode (e.g., r1)" - echo " e - Exit" + echo " e - Exit" echo "" read -p "Enter choice: " input @@ -133,6 +137,21 @@ main() { [nN]) add_mode ;; + [fF]) + if command -v fzf >/dev/null 2>&1; then + local selected=$(cut -d' ' -f1 "$SAVED_MODES_FILE" | fzf --prompt="Select mode: ") + if [[ -n "$selected" ]]; then + local line_num=$(grep -n "^$selected " "$SAVED_MODES_FILE" | cut -d: -f1) + execute_mode "$line_num" + else + echo "No mode selected." + echo "" + fi + else + echo "Error: fzf is not installed." + echo "" + fi + ;; r[0-9]*) # Extract number after 'r' local mode_num="${input#r}" diff --git a/home-manager/modules/zsh/zsh.nix b/home-manager/modules/zsh/zsh.nix index b169ee3..a18af57 100644 --- a/home-manager/modules/zsh/zsh.nix +++ b/home-manager/modules/zsh/zsh.nix @@ -4,11 +4,19 @@ home.packages = with pkgs; [ (writeShellScriptBin "select_command" (builtins.readFile ./select_command.sh)) + (writeShellScriptBin "move_wallpaper" + (builtins.readFile ./move_wallpaper.sh)) + (writeShellScriptBin "move_avatar" (builtins.readFile ./move_avatar.sh)) + (writeShellScriptBin "next_wallpaper" + (builtins.readFile ./next_wallpaper.sh)) zsh-powerlevel10k fzf fd eza zoxide + bat + neofetch + yazi ]; home.file.".p10k.zsh".source = ./p10k.zsh; @@ -70,20 +78,20 @@ gitpa = ''f() { git add -A && git commit -m "$1" && git push; }; f''; - # home-cnfg = "nvim ~/.config/home-manager/home.nix"; - # home-rr = "home-manager switch"; - # cnfg = "sudo nvim /nixos/configuration.nix"; - # rr = "sudo nixos-rebuild switch"; - amnezia = '' (pgrep -x ".AmneziaVPN-ser" > /dev/null 2>&1 || sudo AmneziaVPN-service > /dev/null 2>&1 &) & AmneziaVPN > /dev/null 2>&1 & - ''; # TODO: start system with service + ''; # TODO: start system with serviceps://github.com/dylanaraps/pywal/wiki/Customization cnfg = "cd nixos-config && code . && exit"; x = "select_command"; + + mv_w = "move_wallpaper"; + next_w = "next_wallpaper"; + mv_avatar = "move_avatar"; }; initContent = '' + (cat ~/.cache/wal/sequences &) zstyle ':omz:plugins:eza' 'git-status' yes zstyle ':omz:plugins:eza' 'header' yes zstyle ':omz:plugins:eza' 'icons' yes