From d39a7aaa2902f20fde834c463851d845a20b084d Mon Sep 17 00:00:00 2001 From: caley <195605706+cqley@users.noreply.github.com> Date: Wed, 22 Jul 2026 01:56:55 +0200 Subject: changing folder name to from mdls to modules --- nixos/mdls/btop.nix | 86 --- nixos/mdls/colors.nix | 224 ------ nixos/mdls/gms/dayz.nix | 1808 -------------------------------------------- nixos/mdls/gms/mc.nix | 80 -- nixos/mdls/notes.nix | 55 -- nixos/mdls/qksh.nix | 992 ------------------------ nixos/mdls/vi.nix | 147 ---- nixos/mdls/wm.nix | 157 ---- nixos/mdls/yazi.nix | 50 -- nixos/modules/btop.nix | 86 +++ nixos/modules/colors.nix | 224 ++++++ nixos/modules/gms/dayz.nix | 1808 ++++++++++++++++++++++++++++++++++++++++++++ nixos/modules/gms/mc.nix | 80 ++ nixos/modules/notes.nix | 55 ++ nixos/modules/qksh.nix | 992 ++++++++++++++++++++++++ nixos/modules/vi.nix | 147 ++++ nixos/modules/wm.nix | 157 ++++ nixos/modules/yazi.nix | 50 ++ 18 files changed, 3599 insertions(+), 3599 deletions(-) delete mode 100644 nixos/mdls/btop.nix delete mode 100644 nixos/mdls/colors.nix delete mode 100644 nixos/mdls/gms/dayz.nix delete mode 100644 nixos/mdls/gms/mc.nix delete mode 100644 nixos/mdls/notes.nix delete mode 100644 nixos/mdls/qksh.nix delete mode 100644 nixos/mdls/vi.nix delete mode 100644 nixos/mdls/wm.nix delete mode 100644 nixos/mdls/yazi.nix create mode 100644 nixos/modules/btop.nix create mode 100644 nixos/modules/colors.nix create mode 100644 nixos/modules/gms/dayz.nix create mode 100644 nixos/modules/gms/mc.nix create mode 100644 nixos/modules/notes.nix create mode 100644 nixos/modules/qksh.nix create mode 100644 nixos/modules/vi.nix create mode 100644 nixos/modules/wm.nix create mode 100644 nixos/modules/yazi.nix diff --git a/nixos/mdls/btop.nix b/nixos/mdls/btop.nix deleted file mode 100644 index 6738384..0000000 --- a/nixos/mdls/btop.nix +++ /dev/null @@ -1,86 +0,0 @@ -{ config, pkgs, ... }: - -{ - xdg.configFile."btop/btop.conf".force = true; - - programs.btop = { - enable = true; - settings = { - color_theme = "TTY"; - theme_background = true; - truecolor = true; - force_tty = false; - presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"; - vim_keys = false; - rounded_corners = false; - terminal_sync = true; - update_ms = 2000; - background_update = true; - clock_format = "%X"; - base_10_sizes = false; - base_10_bitrate = "Auto"; - log_level = "WARNING"; - save_config_on_exit = true; - shown_boxes = "cpu mem net proc"; - graph_symbol = "braille"; - graph_symbol_cpu = "default"; - graph_symbol_gpu = "default"; - graph_symbol_mem = "default"; - graph_symbol_net = "default"; - graph_symbol_proc = "default"; - cpu_bottom = false; - cpu_graph_upper = "Auto"; - cpu_graph_lower = "Auto"; - cpu_invert_lower = true; - cpu_single_graph = false; - check_temp = true; - cpu_sensor = "Auto"; - show_coretemp = true; - cpu_core_map = ""; - temp_scale = "celsius"; - show_cpu_freq = true; - freq_mode = "first"; - show_cpu_watts = true; - show_uptime = true; - custom_cpu_name = ""; - proc_left = false; - proc_sorting = "cpu lazy"; - proc_reversed = false; - proc_tree = false; - proc_colors = true; - proc_gradient = true; - proc_per_core = false; - proc_mem_bytes = true; - proc_cpu_graphs = true; - proc_info_smaps = false; - proc_filter_kernel = false; - proc_aggregate = false; - keep_dead_proc_usage = false; - mem_graphs = true; - mem_below_net = false; - show_swap = true; - swap_disk = true; - zfs_arc_cached = true; - show_disks = true; - disks_filter = ""; - only_physical = true; - use_fstab = true; - disk_free_priv = false; - show_io_stat = true; - io_mode = false; - io_graph_combined = false; - io_graph_speeds = ""; - zfs_hide_datasets = false; - net_iface = ""; - net_auto = true; - net_sync = true; - net_download = 100; - net_upload = 100; - show_gpu_info = "Auto"; - shown_gpus = "amd nvidia intel"; - gpu_mirror_graph = true; - nvml_measure_pcie_speeds = true; - rsmi_measure_pcie_speeds = true; - }; - }; -} diff --git a/nixos/mdls/colors.nix b/nixos/mdls/colors.nix deleted file mode 100644 index 98ce1cc..0000000 --- a/nixos/mdls/colors.nix +++ /dev/null @@ -1,224 +0,0 @@ -{ pkgs, ... }: - -let - colors-script = pkgs.writeShellScriptBin "colors" '' - [ -z "$1" ] && echo "usage: colors " >&2 && exit 1 - [ ! -f "$1" ] && echo "colors: file not found: $1" >&2 && exit 1 - - colors="$HOME/.colors" - mkdir -p "$colors" - - awww_out=$(${pkgs.awww}/bin/awww img -o HDMI-A-1 "$1" --transition-type grow --transition-duration 1.5 --transition-fps 120 2>&1) - [ $? -ne 0 ] && echo "colors: awww: $awww_out" >&2 - ${pkgs.awww}/bin/awww clear --outputs DP-1 2>/dev/null - - raw=$(${pkgs.imagemagick}/bin/magick "$1" -thumbnail 50x50^ -colors 8 -unique-colors txt:- 2>&1) - - base=$(printf '%s\n' "$raw" \ - | ${pkgs.gnugrep}/bin/grep -oE '#[0-9A-Fa-f]{6}' \ - | ${pkgs.gawk}/bin/awk '{ - r = strtonum("0x" substr($0,2,2)) - g = strtonum("0x" substr($0,4,2)) - b = strtonum("0x" substr($0,6,2)) - printf "%d %s\n", int(0.299*r + 0.587*g + 0.114*b), $0 - }' \ - | ${pkgs.coreutils}/bin/sort -n \ - | ${pkgs.gawk}/bin/awk '{print $2}' \ - | ${pkgs.coreutils}/bin/head -8) - - [ -z "$base" ] && echo "colors: magick failed" >&2 && echo "$raw" >&2 && exit 1 - - n=$(printf '%s\n' "$base" | ${pkgs.coreutils}/bin/wc -l) - last=$(printf '%s\n' "$base" | ${pkgs.coreutils}/bin/tail -1) - while [ "$n" -lt 8 ]; do - base=$(printf '%s\n%s' "$base" "$last") - n=$((n+1)) - done - - bright=$(printf '%s\n' "$base" | ${pkgs.gawk}/bin/awk '{ - r = strtonum("0x" substr($0,2,2)) - g = strtonum("0x" substr($0,4,2)) - b = strtonum("0x" substr($0,6,2)) - r = int(r*1.4); if (r>255) r=255 - g = int(g*1.4); if (g>255) g=255 - b = int(b*1.4); if (b>255) b=255 - printf "#%02X%02X%02X\n", r, g, b - }') - - cols=$(printf '%s\n%s' "$base" "$bright") - - c0=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '1p') - c1=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '2p') - c2=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '3p') - c3=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '4p') - c4=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '5p') - c5=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '6p') - c6=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '7p') - c7=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '8p') - c8=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '9p') - c9=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '10p') - c10=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '11p') - c11=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '12p') - c12=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '13p') - c13=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '14p') - c14=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '15p') - c15=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '16p') - - bg="$c0" - fg=$(printf '%s\n' "$cols" | ${pkgs.gawk}/bin/awk -v bg="$c0" ' - function lum(hex, r,g,b,rs,gs,bs) { - r = strtonum("0x" substr(hex,2,2)) / 255 - g = strtonum("0x" substr(hex,4,2)) / 255 - b = strtonum("0x" substr(hex,6,2)) / 255 - rs = (r<=0.04045) ? r/12.92 : ((r+0.055)/1.055)^2.4 - gs = (g<=0.04045) ? g/12.92 : ((g+0.055)/1.055)^2.4 - bs = (b<=0.04045) ? b/12.92 : ((b+0.055)/1.055)^2.4 - return 0.2126*rs + 0.7152*gs + 0.0722*bs - } - function contrast(a,b, l1,l2,t) { - l1 = lum(a); l2 = lum(b) - if (l1 < l2) { t=l1; l1=l2; l2=t } - return (l1+0.05) / (l2+0.05) - } - BEGIN { best=""; bestc=0 } - { - c = contrast($0, bg) - if (c > bestc) { bestc=c; best=$0 } - } - END { print best } - ') - cursor="$fg" - - printf '%s' "$1" > "$colors/colors" - - printf '%s\n' "$cols" | ${pkgs.gawk}/bin/awk '{printf "color%d=%s\n", NR-1, $0}' > "$colors/colors.sh" - printf 'background="%s"\nforeground="%s"\ncursor="%s"\n' "$bg" "$fg" "$cursor" >> "$colors/colors.sh" - - cat > "$colors/colors.json" << ENDJSON - { - "wallpaper": "$1", - "alpha": "100", - "special": { - "background": "$bg", - "foreground": "$fg", - "cursor": "$cursor" - }, - "colors": { - "color0": "$c0", - "color1": "$c1", - "color2": "$c2", - "color3": "$c3", - "color4": "$c4", - "color5": "$c5", - "color6": "$c6", - "color7": "$c7", - "color8": "$c8", - "color9": "$c9", - "color10": "$c10", - "color11": "$c11", - "color12": "$c12", - "color13": "$c13", - "color14": "$c14", - "color15": "$c15" - } - } - ENDJSON - - printf '%s\n' "$cols" > "$colors/colors.txt" - - cat > "$colors/kitty.conf" << ENDKITTY - foreground $fg - background $bg - background_opacity 1.0 - cursor $cursor - - active_tab_foreground $bg - active_tab_background $fg - inactive_tab_foreground $fg - inactive_tab_background $bg - - active_border_color $fg - inactive_border_color $bg - bell_border_color $c1 - - color0 $c0 - color8 $c8 - color1 $c1 - color9 $c9 - color2 $c2 - color10 $c10 - color3 $c3 - color11 $c11 - color4 $c4 - color12 $c12 - color5 $c5 - color13 $c13 - color6 $c6 - color14 $c14 - color7 $c7 - color15 $c15 - ENDKITTY - - cat > "$colors/colors.fish" << ENDFISH - set fish_color_autosuggestion \$(echo "$c8" | sed 's/#//') - set fish_color_cancel \$(echo "$c1" | sed 's/#//') '--reverse' - set fish_color_command \$(echo "$c10" | sed 's/#//') - set fish_color_comment \$(echo "$c8" | sed 's/#//') - set fish_color_cwd \$(echo "$c2" | sed 's/#//') - set fish_color_cwd_root \$(echo "$c1" | sed 's/#//') - set fish_color_end \$(echo "$c3" | sed 's/#//') - set fish_color_error \$(echo "$c1" | sed 's/#//') - set fish_color_escape \$(echo "$c5" | sed 's/#//') - set fish_color_history_current --bold - set fish_color_host \$(echo "$c12" | sed 's/#//') - set fish_color_host_remote \$(echo "$c12" | sed 's/#//') - set fish_color_keyword \$(echo "$c5" | sed 's/#//') - set fish_color_match --background=\$(echo "$c4" | sed 's/#//') - set fish_color_normal \$(echo "$fg" | sed 's/#//') - set fish_color_operator \$(echo "$c6" | sed 's/#//') - set fish_color_option \$(echo "$c3" | sed 's/#//') - set fish_color_param \$(echo "$c12" | sed 's/#//') - set fish_color_quote \$(echo "$c11" | sed 's/#//') - set fish_color_redirection \$(echo "$c5" | sed 's/#//') - set fish_color_search_match --background=\$(echo "$c8" | sed 's/#//') - set fish_color_selection --background=\$(echo "$c8" | sed 's/#//') - set fish_color_status \$(echo "$c1" | sed 's/#//') - set fish_color_user \$(echo "$c10" | sed 's/#//') - set fish_color_valid_path --underline - set fish_pager_color_background \$(echo "$bg" | sed 's/#//') - set fish_pager_color_completion \$(echo "$fg" | sed 's/#//') - set fish_pager_color_description \--background=\$(echo "$c8" | sed 's/#//') - set fish_pager_color_prefix \$(echo "$c10" | sed 's/#//') - set fish_pager_color_progress \$(echo "$c8" | sed 's/#//') - set fish_pager_color_secondary_background \$(echo "$bg" | sed 's/#//') - set fish_pager_color_secondary_completion \$(echo "$fg" | sed 's/#//') - set fish_pager_color_secondary_description \$(echo "$c8" | sed 's/#//') - set fish_pager_color_secondary_prefix \$(echo "$c10" | sed 's/#//') - set fish_pager_color_selected_background --background=\$(echo "$c8" | sed 's/#//') - set fish_pager_color_selected_completion \$(echo "$fg" | sed 's/#//') - set fish_pager_color_selected_description \$(echo "$c8" | sed 's/#//') - set fish_pager_color_selected_prefix \$(echo "$c10" | sed 's/#//') - ENDFISH - - { - printf '%s\n' "$cols" | ${pkgs.gawk}/bin/awk '{printf "\033]4;%d;%s\007", NR-1, $0}' - printf '\033]10;%s\007' "$fg" - printf '\033]11;%s\007' "$bg" - printf '\033]12;%s\007' "$cursor" - } > "$colors/sequences" - - for pty in /proc/*/fd/0; do - [ -c "$pty" ] && [ -w "$pty" ] && ${pkgs.coreutils}/bin/cat "$colors/sequences" > "$pty" 2>/dev/null - done - - printf '%s\n' "$base" | ${pkgs.gawk}/bin/awk '{ - r = strtonum("0x" substr($0,2,2)) - g = strtonum("0x" substr($0,4,2)) - b = strtonum("0x" substr($0,6,2)) - printf "\033[48;2;%d;%d;%dm \033[0m %s\n", r, g, b, $0 - }' - ''; -in -{ - home.packages = [ colors-script ]; -} diff --git a/nixos/mdls/gms/dayz.nix b/nixos/mdls/gms/dayz.nix deleted file mode 100644 index 128a10c..0000000 --- a/nixos/mdls/gms/dayz.nix +++ /dev/null @@ -1,1808 +0,0 @@ -{ config, pkgs, ... }: - -let - dayzDir = "${config.home.homeDirectory}/.local/share/Steam/steamapps/compatdata/221100/pfx/drive_c/users/steamuser/Documents/DayZ"; -in -{ - home.packages = [ (pkgs.writeShellApplication { - name = "meowz"; - runtimeInputs = with pkgs; [ curl jq fzf steamcmd ]; - excludeShellChecks = [ "SC2155" "SC2162" "SC2207" "SC2086" "SC2178" "SC2128" ]; - text = '' - -config="$HOME/.config/dayz" -favfile="$config/favorites" -logfile="$config/last_launch.log" -steamapps="$HOME/.local/share/Steam/steamapps" -workshop="$steamapps/workshop/content/221100" -d=$'\x1f' - -mkdir -p "$config" -touch "$favfile" -sed -i '/^[[:space:]]*$/d' "$favfile" -awk -F"$d" 'NF==4' "$favfile" > "$favfile.tmp" && mv "$favfile.tmp" "$favfile" - -log() { printf '%s\n' "$*"; } -err() { printf '%s\n' "$*" >&2; } - -api() { - curl -sg -A "mozilla" "https://api.battlemetrics.com$1" -} - -fetch_servers() { - local path="/servers?filter[game]=dayz&page[size]=100$1" - local pages=0 - while [ -n "$path" ] && [ "$pages" -lt 4 ]; do - local resp=$(api "$path") - echo "$resp" | jq -e . >/dev/null 2>&1 || break - echo "$resp" | jq -r '.data[]? | "\(.id)|\(.attributes.ip):\(.attributes.port)|\(.attributes.name) [\(.attributes.players)/\(.attributes.maxPlayers)]"' - path=$(echo "$resp" | jq -r '.links.next // empty' | sed 's|.*battlemetrics.com||') - pages=$((pages + 1)) - done -} - -if [ "''${1:-}" = "--fetch" ]; then - fetch_servers "''${2:+&filter[search]=$2}" - exit 0 -fi - -steamuser="" -[ -f "$config/steamuser" ] && steamuser=$(cat "$config/steamuser") -if [ -z "$steamuser" ]; then - read -p "steam username: " steamuser - echo "$steamuser" > "$config/steamuser" -fi - -steampass="" -[ -f "$config/steampass" ] && steampass=$(cat "$config/steampass") -if [ -z "$steampass" ]; then - read -rsp "steam password (stored in plaintext, blank to skip caching): " steampass - echo - if [ -n "$steampass" ]; then - (umask 177; echo "$steampass" > "$config/steampass") - fi -fi - -loginmarker="$config/steam_authenticated" - -get_mods_by_id() { - api "/servers/$1" | jq -r '.data?.attributes?.details?.modIds[]? // empty' | paste -sd, - -} - -get_mods() { - local ip="$1" port="$2" - local m=$(curl -s "https://dayzsalauncher.com/api/v1/server/$ip:$port" | jq -r '.result?.mods[]?.steamWorkshopId // empty' | paste -sd, -) - if [ -z "$m" ]; then - local id=$(api "/servers?filter[game]=dayz&filter[search]=$ip:$port" | jq -r '.data[0]?.id // empty') - [ -n "$id" ] && m=$(get_mods_by_id "$id") - fi - echo "$m" -} - -download_mods() { - local mods=($(echo "$1" | tr ',' '\n')) - [ "''${#mods[@]}" -eq 0 ] && return 0 - - touch "$config/blacklist" - local missing=() - for mod in "''${mods[@]}"; do - grep -qx "$mod" "$config/blacklist" && continue - find "$workshop/$mod" -mindepth 1 2>/dev/null | grep -q . || missing+=("$mod") - done - [ "''${#missing[@]}" -eq 0 ] && { log "mods already present"; return 0; } - - local runner="steamcmd" - command -v steamcmd >/dev/null 2>&1 || { err "steamcmd not found"; return 1; } - - mods=("''${missing[@]}") - local cmds="" - for mod in "''${mods[@]}"; do - cmds="$cmds +workshop_download_item 221100 $mod" - done - - if pgrep -x steam >/dev/null; then - log "closing steam..." - steam -shutdown - while pgrep -x steam >/dev/null; do sleep 1; done - fi - - log "downloading mods..." - local attempt=1 - while [ "$attempt" -le 4 ]; do - [ "$attempt" -gt 1 ] && log "retry $attempt/4, ''${#mods[@]} mods" - local out - local login_args=("$steamuser") - if [ ! -f "$loginmarker" ] && [ -n "$steampass" ]; then - login_args=("$steamuser" "$steampass") - fi - out=$($runner +@sSteamCmdForcePlatformType linux -forceipv4 +login "''${login_args[@]}" $cmds +quit | tee /dev/tty) || true - - if echo "$out" | grep -q "Waiting for user info"; then - touch "$loginmarker" - fi - if echo "$out" | grep -q "FAILED"; then - rm -f "$loginmarker" - fi - - if echo "$out" | grep -q "Invalid Password"; then - err "wrong password, clearing cache" - rm -f "$config/steampass" - steampass="" - fi - - local failed=() - for mod in "''${mods[@]}"; do - if echo "$out" | grep -q "Success. Downloaded item $mod "; then - continue - fi - if echo "$out" | grep -qE "Download item $mod failed \((Access Denied|No match|File Not Found)\)"; then - err "mod $mod unavailable, blacklisting" - grep -qx "$mod" "$config/blacklist" || echo "$mod" >> "$config/blacklist" - continue - fi - failed+=("$mod") - done - - [ "''${#failed[@]}" -eq 0 ] && { log "mods downloaded"; return 0; } - - mods=("''${failed[@]}") - cmds="" - for mod in "''${mods[@]}"; do - cmds="$cmds +workshop_download_item 221100 $mod" - done - attempt=$((attempt + 1)) - sleep 3 - done - - err "failed to download: ''${mods[*]}" - return 1 -} - -launch() { - local ip="$1" port="$2" mods="$3" mod_arg="" - - if [ -z "$ip" ] || [ -z "$port" ]; then - err "invalid ip/port" - return 1 - fi - - log "verifying server..." - local verify - verify=$(api "/servers?filter[game]=dayz&filter[search]=$ip:$port" | jq -r --arg ip "$ip" --arg port "$port" '.data[]? | select(.attributes.ip == $ip and (.attributes.port | tostring) == $port) | "\(.attributes.name) [\(.attributes.players)/\(.attributes.maxPlayers)]"' | head -n 1) - if [ -n "$verify" ]; then - log "found: $verify" - else - err "server not found on battlemetrics, connecting anyway" - fi - - if [ -z "$mods" ]; then - log "no mod list found, may still require mods" - else - log "downloading mods..." - download_mods "$mods" || err "some mods failed, launching anyway" - for m in $(echo "$mods" | tr ',' '\n'); do - [ -z "$m" ] && continue - local folder=$(find "$workshop/$m" -maxdepth 1 -type d -name "@*" 2>/dev/null | head -n 1) - [ -z "$folder" ] && folder="$workshop/$m" - find "$folder" -iname "*.pbo" 2>/dev/null | grep -q . || { err "missing pbo for $m, skipping"; continue; } - mod_arg="$mod_arg;z:''${folder//\//\\}" - done - mod_arg="''${mod_arg#;}" - [ -n "$mod_arg" ] && mod_arg="-mod=$mod_arg" - sleep 3 - fi - - echo "$(date '+%F %T') connect=$ip:$port $mod_arg" >> "$logfile" - - if ! pgrep -x steam >/dev/null; then - log "starting steam..." - if [ ! -f "$loginmarker" ]; then - if [ -n "$steampass" ]; then - steam -login "$steamuser" "$steampass" >>"$config/steam.log" 2>&1 & disown - else - steam -login "$steamuser" >>"$config/steam.log" 2>&1 & disown - fi - else - steam >>"$config/steam.log" 2>&1 & disown - fi - while ! pgrep -x steam >/dev/null; do sleep 1; done - sleep 5 - fi - - log "connecting to $ip:$port..." - if [ -n "$mod_arg" ]; then - steam -applaunch 221100 -noLauncher "-connect=$ip" "-port=$port" "$mod_arg" >>"$config/steam.log" 2>&1 - else - steam -applaunch 221100 -noLauncher "-connect=$ip" "-port=$port" >>"$config/steam.log" 2>&1 - fi -} - -pick_server() { - fzf --prompt="server> " --delimiter="|" --with-nth=3.. --layout=reverse \ - --disabled --ansi \ - --bind "start:reload:$0 --fetch" \ - --bind "change:reload:sleep 0.4; $0 --fetch {q}" -} - -save_favorite() { - local ip="$1" port="$2" name="$3" - if grep -qF "$ip$d$port$d" "$favfile"; then - err "already saved" - return - fi - local mods=$(get_mods "$ip" "$port") - printf "%s%s%s%s%s%s%s\n" "$ip" "$d" "$port" "$d" "$mods" "$d" "$name" >> "$favfile" - log "saved $name" -} - -show_favorites() { - grep -vE '^[[:space:]]*$' "$favfile" | fzf --prompt="fav> " --delimiter="$d" --with-nth=4 --layout=reverse -} - -while true; do - action=$(printf "favorites\nbrowse\nadd manual\nremove\nrefresh mods\nquit\n" | fzf --prompt="dayz> " --layout=reverse) - - case "$action" in - browse) - selection=$(pick_server) - [ -z "$selection" ] && continue - id=$(echo "$selection" | cut -d'|' -f1) - ip_port=$(echo "$selection" | cut -d'|' -f2) - name=$(echo "$selection" | cut -d'|' -f3- | sed 's/ \[[0-9]*\/[0-9]*\]$//') - ip=''${ip_port%%:*} - port=''${ip_port##*:} - confirm=$(printf "play\nsave to favorites\n" | fzf --prompt="$name> " --layout=reverse) - case "$confirm" in - play) mods=$(get_mods_by_id "$id"); launch "$ip" "$port" "$mods"; exit 0 ;; - "save to favorites") save_favorite "$ip" "$port" "$name"; show_favorites ;; - esac - ;; - favorites) - selection=$(show_favorites) - [ -z "$selection" ] && continue - ip=$(echo "$selection" | cut -d"$d" -f1) - port=$(echo "$selection" | cut -d"$d" -f2) - mods=$(echo "$selection" | cut -d"$d" -f3) - launch "$ip" "$port" "$mods" - exit 0 - ;; - "add manual") - read -p "ip: " ip - read -p "port: " port - read -p "name: " name - save_favorite "$ip" "$port" "$name" - show_favorites - ;; - remove) - selection=$(show_favorites) - [ -z "$selection" ] && continue - grep -vF "$selection" "$favfile" | grep -vE '^[[:space:]]*$' > "$favfile.tmp" && mv "$favfile.tmp" "$favfile" - show_favorites - ;; - "refresh mods") - selection=$(show_favorites) - [ -z "$selection" ] && continue - ip=$(echo "$selection" | cut -d"$d" -f1) - port=$(echo "$selection" | cut -d"$d" -f2) - name=$(echo "$selection" | cut -d"$d" -f4) - mods=$(get_mods "$ip" "$port") - grep -vF "$selection" "$favfile" | grep -vE '^[[:space:]]*$' > "$favfile.tmp" && mv "$favfile.tmp" "$favfile" - printf "%s%s%s%s%s%s%s\n" "$ip" "$d" "$port" "$d" "$mods" "$d" "$name" >> "$favfile" - show_favorites - ;; - quit|"") break ;; - esac -done - ''; - }) ]; - - xdg.desktopEntries.meowz = { - name = "MeowZ"; - comment = "dayz server launcher"; - exec = "kitty --hold -e meowz"; - icon = "applications-games"; - terminal = false; - categories = [ "Game" ]; - }; - - home.file."${dayzDir}/DayZ.cfg".text = '' - language="English"; - adapter=-1; - 3D_Performance=57692; - Resolution_Bpp=32; - WinX=0; - WinY=0; - WindowWidth=1920; - WindowHeight=1080; - MSAA=0; - PostFX=0; - VSync=1; - FXAO=0; - AToC=0; - AnisoFilter=4; - TerrainDetail=2; - FXAA=0; - refreshMode=200; - maxGPUToRenderFrames=1; - ''; - - home.file."${dayzDir}/steamuser_settings.DayZProfile".text = '' - version=1; - blood=1; - singleVoice=0; - gamma=1; - lastMPServer=""; - lastMPServerName=""; - lastMPMission=""; - inputVersion=1; - perspective=1; - trackIR=1; - freeTrack=1; - mouseSmoothing=0; - maxSamplesPlayed=96; - vonInputMode=0; - TexQuality=1; - WaterQuality=1; - tripleHead=0; - showTitles=1; - vehicleFreelook=0; - pauseMode=0; - shadowQuality=1; - headBob=0; - fov=0.95993; - sceneComplexity=150000; - shadowZDistance=80; - viewDistance=1200; - preferredObjectViewDistance=1200; - terrainGrid=12.5; - volumeMaster=5; - volumeCD=0.5; - volumeFX=4; - volumeSpeech=5; - volumeVoN=10; - vonRecThreshold=0.029999999; - brightness=1; - uiTopLeftX=0.12500001; - uiTopLeftY=0; - uiBottomRightX=0.875; - uiBottomRightY=1; - IGUIScale=0.55000001; - showHUD=1; - hudBrightness=1.0; - showCrosshair=0; - showQuickbar=1; - showVehicleHUD=1; - showServerInfo=0; - ''; - - home.file."${dayzDir}/steamuser.dayz_preset_User.xml".text = '' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''; -} diff --git a/nixos/mdls/gms/mc.nix b/nixos/mdls/gms/mc.nix deleted file mode 100644 index d8c6734..0000000 --- a/nixos/mdls/gms/mc.nix +++ /dev/null @@ -1,80 +0,0 @@ -{ config, pkgs, ... }: - -{ - home.packages = [ pkgs.prismlauncher ]; - - home.file.".local/share/PrismLauncher/prismlauncher.cfg" = { - text = pkgs.lib.generators.toINI {} { - General = { - ApplicationTheme = "dark"; - AutoCloseConsole = false; - AutomaticJavaDownload = false; - AutomaticJavaSwitch = true; - CatFit = "fit"; - CatOpacity = 100; - CentralModsDir = "mods"; - CloseAfterLaunch = false; - ConfigVersion = "1.3"; - ConsoleFont = "DejaVu Sans Mono"; - ConsoleFontSize = 11; - ConsoleMaxLines = 100000; - ConsoleOverflowStop = true; - DownloadsDir = "/home/cat/Downloads"; - DownloadsDirWatchRecursive = false; - EnableFeralGamemode = false; - EnableMangoHud = false; - Env = "{}"; - FallbackMRBlockedMods = 2; - IconTheme = "OSX"; - IconsDir = "icons"; - IgnoreJavaCompatibility = false; - IgnoreJavaWizard = false; - InstRenamingMode = "AskEverytime"; - InstSortMode = "Name"; - InstanceDir = "instances"; - JavaArchitecture = "64"; - JavaDir = "java"; - JavaPath = "/nix/store/55mw2ly3dxh5008li72rx6ilc75hgvr0-openjdk-8u502-b01/bin/java"; - Language = "en_US"; - LaunchMaximized = false; - LowMemWarning = true; - MaxMemAlloc = 6016; - MinMemAlloc = 2048; - MinecraftWinHeight = 480; - MinecraftWinWidth = 854; - ModDependenciesDisabled = false; - ModMetadataDisabled = false; - MoveModsFromDownloadsDir = true; - NumberOfConcurrentDownloads = 6; - NumberOfConcurrentTasks = 10; - NumberOfManualRetries = 1; - OnlineFixes = false; - PastebinType = 3; - PermGen = 128; - ProxyAddr = "127.0.0.1"; - ProxyPort = 8080; - ProxyType = "None"; - QuitAfterGameStop = false; - RecordGameTime = true; - RequestTimeout = 60; - ShowConsole = false; - ShowConsoleOnError = true; - ShowGameTime = true; - ShowGameTimeWithoutDays = false; - ShowGlobalGameTime = true; - ShowModIncompat = false; - SkinsDir = "skins"; - SkipModpackUpdatePrompt = false; - StatusBarVisible = false; - TheCat = false; - ToolbarsLocked = true; - UseDiscreteGpu = false; - UseNativeGLFW = false; - UseNativeOpenAL = false; - UseZink = false; - UserAskedAboutAutomaticJavaDownload = true; - }; - }; - force = true; - }; -} diff --git a/nixos/mdls/notes.nix b/nixos/mdls/notes.nix deleted file mode 100644 index 01356d6..0000000 --- a/nixos/mdls/notes.nix +++ /dev/null @@ -1,55 +0,0 @@ -{ config, pkgs, ... }: - -{ - home.packages = [ pkgs.obsidian ]; - - home.file = { - ".documents/obsidian/.obsidian/app.json".text = builtins.toJSON { - readableLineLength = true; - foldHeading = true; - showLineNumber = true; - spellcheck = false; - vimMode = false; - newFileLocation = "current"; - promptDelete = false; - }; - ".documents/obsidian/.obsidian/appearance.json".text = builtins.toJSON { - accentColor = "#ffa8db"; - cssTheme = ""; - theme = "obsidian"; - }; - ".documents/obsidian/.obsidian/core-plugins.json".text = builtins.toJSON { - "file-explorer" = true; - "global-search" = true; - "switcher" = false; - "graph" = true; - "backlink" = false; - "canvas" = false; - "outgoing-link" = true; - "tag-pane" = true; - "footnotes" = false; - "properties" = false; - "page-preview" = true; - "daily-notes" = true; - "templates" = false; - "note-composer" = false; - "command-palette" = false; - "slash-command" = false; - "editor-status" = true; - "bookmarks" = false; - "markdown-importer" = false; - "zk-prefixer" = false; - "random-note" = false; - "outline" = true; - "word-count" = true; - "slides" = false; - "audio-recorder" = false; - "workspaces" = false; - "file-recovery" = true; - "publish" = false; - "sync" = false; - "bases" = false; - "webviewer" = false; - }; - }; -} diff --git a/nixos/mdls/qksh.nix b/nixos/mdls/qksh.nix deleted file mode 100644 index 9e9e85b..0000000 --- a/nixos/mdls/qksh.nix +++ /dev/null @@ -1,992 +0,0 @@ -{ pkgs, ... }: - -{ - xdg.configFile."quickshell/shell.qml".text = '' - import Quickshell - import Quickshell.Wayland - import Quickshell.Hyprland - import Quickshell.Io - import Quickshell.Services.Notifications - import QtQuick - import QtQuick.Layouts - import QtCore - - Scope { - id: configRoot - - property string colorBuf: "" - property var colors: { - "special": { "background": "#1c1c1c", "foreground": "#c0c0c0", "cursor": "#c0c0c0" }, - "colors": { - "color0": "#1c1c1c", "color1": "#cc2222", "color2": "#22cc22", "color3": "#cccc22", - "color4": "#2222cc", "color5": "#cc22cc", "color6": "#22cccc", "color7": "#aaaaaa", - "color8": "#555555", "color9": "#ff4444", "color10": "#44ff44", "color11": "#ffff44", - "color12": "#4444ff", "color13": "#ff44ff", "color14": "#44ffff", "color15": "#ffffff" - } - } - - component MText: Text { - font.family: "JetBrainsMono Nerd Font" - font.pixelSize: 12 - font.weight: Font.Normal - renderType: Text.NativeRendering - color: root.colors.special.foreground - } - - Settings { - id: barSettings - location: Qt.resolvedUrl("state") - property string position: "top" - property string layout: "minimal" - property string look: "float" - property string centerMode: "default" - } - - NotificationServer { - id: notifServer - keepOnReload: true - - onNotification: (notif) => { - if (notifModel.count >= 3) notifModel.remove(0) - notifModel.append({ - nid: notif.id, - app: notif.appName ?? "", - summary: notif.summary ?? "", - body: notif.body ?? "", - timeout: notif.expireTimeout > 0 ? notif.expireTimeout : 5000 - }) - } - } - - ListModel { id: notifModel } - - PanelWindow { - id: root - property string position: barSettings.position - property string layout: barSettings.layout - property string look: barSettings.look - - screen: Quickshell.screens.find(s => s.name === "HDMI-A-1") ?? Quickshell.screens[0] - - property string activeMode: "none" - property bool autoHideBar: false - - property var launcherTopApp: null - - property string sysStats: "cpu --% | mem --%" - property string micState: "󰍬" - - function removeNotif(nid) { - for (let i = 0; i < notifModel.count; i++) { - if (notifModel.get(i).nid === nid) { - notifModel.remove(i) - break - } - } - } - - function launcherRefilter(q) { - if (!DesktopEntries.applications?.values || q === "") { - launcherTopApp = null; return - } - let ql = q.toLowerCase() - let m = DesktopEntries.applications.values.filter( - a => a?.name && a.name.toLowerCase().includes(ql) - ).sort((a, b) => { - let an = a.name.toLowerCase() - let bn = b.name.toLowerCase() - if (an === ql) return -1 - if (bn === ql) return 1 - if (an.startsWith(ql) && !bn.startsWith(ql)) return -1 - if (!an.startsWith(ql) && bn.startsWith(ql)) return 1 - if (an.includes("steam") && an !== "steam" && bn === "steam") return 1 - if (bn.includes("steam") && bn !== "steam" && an === "steam") return -1 - return an.localeCompare(bn) - }) - launcherTopApp = m.length > 0 ? m[0] : null - } - - function launcherOpen() { - if (!root.visible) { autoHideBar = true; root.visible = true } - else autoHideBar = false - launcherTopApp = null - activeMode = "launcher" - } - - function launcherClose() { - activeMode = "none" - launcherTopApp = null - if (autoHideBar) { root.visible = false; autoHideBar = false } - } - - function launcherAccept() { - if (launcherTopApp !== null) { - let exec = launcherTopApp.execString.replace(/%[fFuU]/g, "") - launchProc.command = ["systemd-run", "--user", "--scope", "bash", "-c", exec] - launchProc.running = true - } - launcherClose() - } - - property string masterLevel: "root" - property var masterStack: [] - property var masterCurrent: [] - property var masterFiltered: [] - property int masterSelected: 0 - - property var masterRootItems: [ - { label: "sys", sub: "sys" }, - { label: "sts", sub: "sts" }, - { label: "rcd", sub: "rcd" }, - { label: "wp", sub: "wallpapers" }, - { label: "pw", sub: "pw" } - ] - property var masterSysItems: [ - { label: "nix", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/hosts/box/configuration.nix"] }, - { label: "box", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/hosts/box/box.nix"] }, - { label: "wm", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/mdls/wm.nix"] }, - { label: "qksh", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/mdls/qksh.nix"] }, - { label: "vi", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/mdls/vi.nix"] }, - { label: "yazi", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/mdls/yazi.nix"] }, - ] - property var masterStsItems: [ - { label: "animations", sub: "animations" }, - { label: "bar", sub: "bar" } - ] - property var masterAnimationsItems: [ - { label: "fade", cmd: ["sh", "-c", "hyprctl eval 'hl.animation({ leaf = \"workspaces\", enabled = true, speed = 1.94, bezier = \"almostLinear\", style = \"fade\" })' && hyprctl eval 'hl.animation({ leaf = \"specialWorkspace\", enabled = true, speed = 1.94, bezier = \"almostLinear\", style = \"fade\" })' && ${pkgs.libnotify}/bin/notify-send animations fade"] }, - { label: "vertical", cmd: ["sh", "-c", "hyprctl eval 'hl.animation({ leaf = \"workspaces\", enabled = true, speed = 5, bezier = \"hard\", style = \"slidevert\" })' && hyprctl eval 'hl.animation({ leaf = \"specialWorkspace\", enabled = true, speed = 5, bezier = \"hard\", style = \"slidevert\" })' && ${pkgs.libnotify}/bin/notify-send animations vertical"] }, - { label: "horizontal", cmd: ["sh", "-c", "hyprctl eval 'hl.animation({ leaf = \"workspaces\", enabled = true, speed = 5, bezier = \"hard\", style = \"slide\" })' && hyprctl eval 'hl.animation({ leaf = \"specialWorkspace\", enabled = true, speed = 5, bezier = \"hard\", style = \"slide\" })' && ${pkgs.libnotify}/bin/notify-send animations horizontal"] } - ] - property var masterBarItems: [{ label: "position", sub: "barPosition" }, { label: "layout", sub: "barLayout" }, { label: "mode", sub: "barMode" }, { label: "look", sub: "barLook" }] - property var masterBarPositionItems: [{ label: "top", barPos: "top" }, { label: "bottom", barPos: "bottom" }] - property var masterBarLayoutItems: [{ label: "minimal", barLyt: "minimal" }, { label: "full", barLyt: "full" }] - property var masterBarModeItems: [{ label: "performance", centerLyt: "performance" }, { label: "default", centerLyt: "default" }] - property var masterBarLookItems: [{ label: "float", barLook: "float" }, { label: "fill", barLook: "fill" }] - property var masterWpItems: [] - property string masterWpBuf: "" - property var masterRcdOutItems: [] - property string masterRcdOutBuf: "" - property var masterPwItems: [ - { label: "lock", cmd: [""] }, - { label: "logout", cmd: ["hyprctl", "dispatch", "hl.dsp.exit()"] }, - { label: "reboot", cmd: ["systemctl", "reboot"] }, - { label: "shutdown", cmd: ["systemctl", "poweroff"] } - ] - - function rcdItems() { - return recProc.running - ? [{ label: "stop", rcdStop: true }] - : [{ label: "start", sub: "rcdOutput" }] - } - - function masterItemsForLevel(l) { - let lookup = { sys: masterSysItems, sts: masterStsItems, animations: masterAnimationsItems, bar: masterBarItems, barPosition: masterBarPositionItems, barLayout: masterBarLayoutItems, barMode: masterBarModeItems, barLook: masterBarLookItems, wallpapers: masterWpItems, pw: masterPwItems, rcd: rcdItems(), rcdOutput: masterRcdOutItems } - return lookup[l] ?? masterRootItems - } - - function masterRefilter(q) { - masterFiltered = q === "" ? masterCurrent : masterCurrent.filter(i => i.label.toLowerCase().includes(q.toLowerCase())) - let max = masterFiltered.length - 1 - if (masterSelected > max) masterSelected = Math.max(0, max) - } - - function masterGoTo(l) { - masterLevel = l - masterSelected = 0 - if (l === "wallpapers") { - masterWpItems = []; masterWpBuf = "" - masterCurrent = []; masterFiltered = [] - wpLsProc.running = true - } else if (l === "rcdOutput") { - masterRcdOutItems = []; masterRcdOutBuf = "" - masterCurrent = []; masterFiltered = [] - rcdMonProc.running = true - } else { - masterCurrent = masterItemsForLevel(l) - masterFiltered = masterCurrent - } - } - - function masterOpen() { - if (!root.visible) { autoHideBar = true; root.visible = true } - else autoHideBar = false - masterStack = [] - masterGoTo("root") - activeMode = "master" - } - - function masterClose() { - activeMode = "none" - if (autoHideBar) { root.visible = false; autoHideBar = false } - } - - function masterBack() { - if (masterStack.length > 0) { - let prev = masterStack[masterStack.length - 1] - masterStack = masterStack.slice(0, -1) - masterLevel = prev - masterSelected = 0 - masterCurrent = masterItemsForLevel(prev) - masterFiltered = masterCurrent - } else { - masterClose() - } - } - - function masterAccept() { - let items = masterFiltered - let idx = masterSelected - if (items.length === 0 || idx < 0 || idx >= items.length) return - let item = items[idx] - - if (item.sub !== undefined) { - masterStack = masterStack.concat([masterLevel]) - masterGoTo(item.sub) - return - } - if (item.wp !== undefined) { - mProc.command = ["bash", "-c", "colors \"$HOME/.wallpapers/" + item.wp + "\""] - mProc.running = true - masterClose(); return - } - if (item.rcdOut !== undefined) { - recProc.command = ["bash", "-c", "mkdir -p \"$HOME/videos\" && exec ${pkgs.gpu-screen-recorder}/bin/gpu-screen-recorder -w " + item.rcdOut + " -f 60 -q ultra -k hevc -fm cfr -a default_output -o \"$HOME/videos/meow_$(date +%Y%m%d_%H%M%S).mp4\""] - recProc.running = true - mProc.command = ["${pkgs.libnotify}/bin/notify-send", "-t", "2000", "meow", "started on " + item.rcdOut] - mProc.running = true - masterClose(); return - } - if (item.rcdStop !== undefined) { - recProc.signal(2) - mProc.command = ["${pkgs.libnotify}/bin/notify-send", "-t", "2000", "meow", "saved"] - mProc.running = true - masterClose(); return - } - if (item.barPos !== undefined) { barSettings.position = item.barPos; masterClose(); return } - if (item.barLyt !== undefined) { barSettings.layout = item.barLyt; masterClose(); return } - if (item.barLook !== undefined) { barSettings.look = item.barLook; masterClose(); return } - if (item.centerLyt !== undefined) { barSettings.centerMode = item.centerLyt; masterClose(); return } - if (item.cmd !== undefined) { mProc.command = item.cmd; mProc.running = true } - masterClose() - } - - onActiveModeChanged: { - if (activeMode !== "none" && activeMode !== "calendar" && typeof barInput !== "undefined") { - barInput.text = "" - barInput.forceActiveFocus() - } - } - - WlrLayershell.keyboardFocus: activeMode !== "none" && activeMode !== "calendar" ? WlrLayershell.Exclusive : WlrLayershell.None - - anchors.top: position === "top" - anchors.bottom: position === "bottom" - - implicitWidth: look === "fill" ? (root.screen?.width ?? 1920) - : layout === "full" ? (root.screen?.width ?? 1920) - 12 - : 820 - implicitHeight: 22 - - margins.top: look === "fill" ? 0 : (position === "top" ? 6 : 0) - margins.bottom: look === "fill" ? 0 : (position === "bottom" ? 6 : 0) - - exclusiveZone: 22 - color: "transparent" - - IpcHandler { - target: "bar" - function toggle(): void { root.visible = !root.visible } - } - IpcHandler { - target: "menu" - function toggle(): void { - if (root.activeMode === "launcher") root.launcherClose() - else root.launcherOpen() - } - } - IpcHandler { - target: "master" - function toggle(): void { - if (root.activeMode === "master") root.masterClose() - else root.masterOpen() - } - } - IpcHandler { - target: "calendar" - function toggle(): void { - if (root.activeMode === "calendar") root.activeMode = "none" - else root.activeMode = "calendar" - } - } - IpcHandler { - target: "mic" - function toggle(): void { - micActProc.command = ["${pkgs.wireplumber}/bin/wpctl", "set-mute", "@DEFAULT_AUDIO_SOURCE@", "toggle"] - micActProc.running = true - } - } - - Connections { - target: Hyprland - function onFocusedWorkspaceChanged() { - if (root.activeMode !== "none") root.activeMode = "none" - } - } - - Process { - id: colorProc - command: ["sh", "-c", "cat $HOME/.colors/colors.json"] - running: true - stdout: SplitParser { - splitMarker: "" - onRead: data => { configRoot.colorBuf += data } - } - onRunningChanged: { - if (!running && configRoot.colorBuf !== "") { - try { - configRoot.colors = JSON.parse(configRoot.colorBuf) - } catch(e) { console.log("Failed to parse colors") } - configRoot.colorBuf = "" - } - } - } - - Process { id: launchProc; running: false } - Process { - id: mProc - running: false - onRunningChanged: if (!running) colorProc.running = true - } - Process { id: recProc; running: false } - - Process { - id: rcdMonProc - command: ["bash", "-c", "${pkgs.hyprland}/bin/hyprctl -j monitors | ${pkgs.jq}/bin/jq -r '.[].name'"] - running: false - stdout: SplitParser { - splitMarker: "" - onRead: data => { root.masterRcdOutBuf += data } - } - onRunningChanged: { - if (!running && root.masterRcdOutBuf !== "") { - let lines = root.masterRcdOutBuf.trim().split("\n").filter(l => l.length > 0) - lines.push("portal") - root.masterRcdOutItems = lines.map(l => ({ label: l, rcdOut: l })) - root.masterRcdOutBuf = "" - if (root.activeMode === "master" && root.masterLevel === "rcdOutput") { - root.masterCurrent = root.masterRcdOutItems - root.masterFiltered = root.masterRcdOutItems - } - } - } - } - - Process { - id: wpLsProc - command: ["bash", "-c", "ls $HOME/.wallpapers/"] - running: false - stdout: SplitParser { - splitMarker: "" - onRead: data => { root.masterWpBuf += data } - } - onRunningChanged: { - if (!running && root.masterWpBuf !== "") { - let lines = root.masterWpBuf.trim().split("\n").filter(l => l.length > 0) - root.masterWpItems = lines.map(l => ({ label: l, wp: l })) - root.masterWpBuf = "" - if (root.activeMode === "master" && root.masterLevel === "wallpapers") { - root.masterCurrent = root.masterWpItems - root.masterFiltered = root.masterWpItems - } - } - } - } - - Timer { - interval: 2000; running: true; repeat: true; triggeredOnStart: true - onTriggered: { - if (barSettings.centerMode === "performance" && !sysProc.running) sysProc.running = true - if (!micProc.running) micProc.running = true - } - } - - Process { - id: sysProc - command: ["sh", "-c", "echo \"cpu $(grep 'cpu ' /proc/stat | awk '{print int(($2+$4)*100/($2+$4+$5))}')% | mem $(free | awk '/Mem:/ {print int($3/$2*100)}')%\""] - running: false - stdout: SplitParser { - onRead: data => { root.sysStats = data.trim() } - } - } - - Process { - id: micProc - command: ["sh", "-c", "${pkgs.wireplumber}/bin/wpctl get-volume @DEFAULT_AUDIO_SOURCE@ | awk '{print ($3==\"[MUTED]\"?\"󰍭\":\"󰍬\")}'"] - running: false - stdout: SplitParser { - onRead: data => { root.micState = data.trim() } - } - } - - Process { - id: micActProc - running: false - onRunningChanged: if (!running) micProc.running = true - } - - FontMetrics { - id: fm - font.family: "JetBrainsMono Nerd Font" - font.pixelSize: 12 - font.weight: Font.Normal - } - - Rectangle { - anchors.fill: parent - color: configRoot.colors.special.background - - MText { - anchors.centerIn: parent - visible: root.activeMode === "none" || root.activeMode === "calendar" - text: barSettings.centerMode === "performance" ? root.sysStats : "" - color: configRoot.colors.special.foreground - } - - RowLayout { - anchors.fill: parent - spacing: 0 - - Row { - spacing: 0 - Layout.fillHeight: true - - Repeater { - model: 10 - - Item { - property int wsId: index + 1 - property var ws: Hyprland.workspaces?.values?.find(w => w.id === wsId) ?? null - property bool isActive: Hyprland.focusedWorkspace?.id === wsId - property bool isUrgent: ws?.urgent ?? false - property bool hovered: harea.containsMouse - property string kanji: (["一","二","三","四","五","六","七","八","九","十"])[index] - - visible: ws !== null || isActive - width: visible ? Math.round(fm.advanceWidth(kanji)) + 16 : 0 - height: parent.height - - Rectangle { - anchors.fill: parent - color: parent.isUrgent ? configRoot.colors.colors.color1 - : parent.isActive ? configRoot.colors.special.foreground - : parent.hovered ? configRoot.colors.colors.color8 - : "transparent" - } - MText { - anchors.centerIn: parent - color: parent.isUrgent ? configRoot.colors.special.background - : parent.isActive ? configRoot.colors.special.background - : parent.hovered ? configRoot.colors.special.foreground - : configRoot.colors.colors.color7 - text: parent.kanji - } - MouseArea { - id: harea - anchors.fill: parent - hoverEnabled: true - onClicked: Hyprland.dispatch('hl.dsp.focus({ workspace = "' + parent.wsId + '" })') - } - } - } - } - - Item { - Layout.fillWidth: true - Layout.fillHeight: true - - RowLayout { - anchors.fill: parent - anchors.leftMargin: 10 - anchors.rightMargin: 10 - spacing: 6 - visible: root.activeMode === "launcher" || root.activeMode === "master" - - MText { - Layout.alignment: Qt.AlignVCenter - color: configRoot.colors.colors.color7 - text: root.activeMode === "launcher" ? ">" : root.masterStack.concat([root.masterLevel]).join(" >") - } - - TextInput { - id: barInput - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter - height: parent.height - verticalAlignment: TextInput.AlignVCenter - font.family: "JetBrainsMono Nerd Font" - font.pixelSize: 12 - color: configRoot.colors.special.foreground - focus: root.activeMode === "launcher" || root.activeMode === "master" - - onTextChanged: { - if (root.activeMode === "launcher") root.launcherRefilter(text) - else if (root.activeMode === "master") root.masterRefilter(text) - } - onAccepted: { - if (root.activeMode === "launcher") root.launcherAccept() - else if (root.activeMode === "master") root.masterAccept() - } - Keys.onPressed: (event) => { - if (event.key === Qt.Key_Escape) { - if (root.activeMode === "launcher") root.launcherClose() - else if (root.activeMode === "master") root.masterBack() - event.accepted = true - } else if (root.activeMode === "master") { - if (event.key === Qt.Key_Down) { - if (root.masterSelected < root.masterFiltered.length - 1) root.masterSelected++ - event.accepted = true - } else if (event.key === Qt.Key_Up) { - if (root.masterSelected > 0) root.masterSelected-- - event.accepted = true - } - } - } - } - - MText { - Layout.alignment: Qt.AlignVCenter - Layout.rightMargin: 4 - color: configRoot.colors.colors.color7 - visible: root.activeMode === "launcher" ? root.launcherTopApp !== null : (root.activeMode === "master" ? root.masterFiltered.length > 0 : false) - text: root.activeMode === "launcher" ? (root.launcherTopApp?.name ?? "") : (root.activeMode === "master" && root.masterSelected < root.masterFiltered.length ? (root.masterFiltered[root.masterSelected]?.label ?? "") : "") - } - } - } - - Item { - Layout.fillHeight: true - implicitWidth: 26 - - Row { - anchors.centerIn: parent - spacing: 2 - - Item { - width: 20 - height: 22 - - MText { - id: micText - anchors.centerIn: parent - text: root.micState - color: configRoot.colors.special.foreground - } - - MouseArea { - anchors.fill: parent - onClicked: { - micActProc.command = ["${pkgs.wireplumber}/bin/wpctl", "set-mute", "@DEFAULT_AUDIO_SOURCE@", "toggle"] - micActProc.running = true - } - } - } - } - } - - Item { - Layout.fillHeight: true - implicitWidth: clockText.implicitWidth + 20 - - Rectangle { - anchors.horizontalCenter: parent.left - width: 1; height: parent.height - color: configRoot.colors.colors.color8 - } - MText { - id: clockText - anchors.centerIn: parent - font.letterSpacing: 0.02 * 11 - color: configRoot.colors.special.foreground - text: Qt.formatDateTime(new Date(), "dd/MM | HH:mm:ss") - - Timer { - interval: 1000; running: true; repeat: true - onTriggered: clockText.text = Qt.formatDateTime(new Date(), "dd/MM | HH:mm:ss") - } - } - MouseArea { - anchors.fill: parent - onClicked: { - if (root.activeMode === "calendar") root.activeMode = "none" - else root.activeMode = "calendar" - } - } - } - } - } - } - - PanelWindow { - id: masterOverlay - visible: root.activeMode === "master" && root.masterFiltered.length > 0 - - screen: Quickshell.screens.find(s => s.name === "HDMI-A-1") ?? Quickshell.screens[0] - - anchors.top: root.position === "top" - anchors.bottom: root.position === "bottom" - anchors.left: true - anchors.right: true - - margins.top: root.position === "top" ? (root.look === "fill" ? 0 : 6) : 0 - margins.bottom: root.position === "bottom" ? (root.look === "fill" ? 0 : 6) : 0 - - implicitWidth: root.implicitWidth - implicitHeight: root.masterFiltered.length * (root.masterLevel === "wallpapers" ? 38 : 22) - - exclusiveZone: 0 - color: "transparent" - WlrLayershell.layer: WlrLayershell.Overlay - - MouseArea { - anchors.fill: parent - onClicked: root.masterClose() - } - - Rectangle { - width: root.implicitWidth - height: parent.height - anchors.horizontalCenter: parent.horizontalCenter - color: configRoot.colors.special.background - - Column { - anchors.top: parent.top - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width - - Repeater { - model: root.masterFiltered - - Rectangle { - width: parent.width - height: root.masterLevel === "wallpapers" ? 38 : 22 - color: root.masterSelected === index ? configRoot.colors.colors.color8 : "transparent" - - Image { - visible: root.masterLevel === "wallpapers" - anchors.left: parent.left - anchors.leftMargin: 8 - anchors.verticalCenter: parent.verticalCenter - width: 46; height: 26 - fillMode: Image.PreserveAspectCrop - asynchronous: true - source: visible ? "file:///home/cat/.wallpapers/" + modelData.wp : "" - } - - Rectangle { - visible: root.masterSelected === index - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - width: 2; height: root.masterLevel === "wallpapers" ? 22 : 12 - color: configRoot.colors.colors.color4 - } - - MText { - anchors.verticalCenter: parent.verticalCenter - x: root.masterLevel === "wallpapers" ? 64 : 14 - text: modelData?.label ?? "" - color: root.masterSelected === index ? configRoot.colors.special.foreground : configRoot.colors.colors.color7 - } - - MText { - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 12 - visible: modelData?.sub !== undefined - text: "›" - color: root.masterSelected === index ? configRoot.colors.special.foreground : configRoot.colors.colors.color8 - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onEntered: root.masterSelected = index - onClicked: root.masterAccept() - } - } - } - } - } - } - - PanelWindow { - id: notifOverlay - visible: notifModel.count > 0 - - screen: Quickshell.screens.find(s => s.name === "HDMI-A-1") ?? Quickshell.screens[0] - - anchors.top: root.position === "top" - anchors.bottom: root.position === "bottom" - anchors.left: true - anchors.right: true - - margins.top: root.position === "top" ? (root.look === "fill" ? 0 : 6) : 0 - margins.bottom: root.position === "bottom" ? (root.look === "fill" ? 0 : 6) : 0 - - implicitWidth: Math.round(root.implicitWidth / 3) - implicitHeight: notifModel.count * 34 - - exclusiveZone: 0 - color: "transparent" - WlrLayershell.layer: WlrLayershell.Overlay - - Column { - anchors.horizontalCenter: parent.horizontalCenter - width: Math.round(root.implicitWidth / 3) - spacing: 0 - - Repeater { - model: notifModel - - Rectangle { - id: toastRect - width: Math.round(root.implicitWidth / 3) - height: 34 - color: configRoot.colors.special.background - - Rectangle { - visible: index > 0 - anchors.top: parent.top - width: parent.width; height: 1 - color: configRoot.colors.colors.color8 - } - - Rectangle { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - width: 2; height: 18 - color: configRoot.colors.colors.color3 - } - - Column { - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.right: parent.right - anchors.leftMargin: 12 - anchors.rightMargin: 10 - spacing: 2 - - MText { - width: parent.width - text: model.summary !== "" ? model.summary : model.app - font.pixelSize: 11 - font.weight: Font.Medium - color: configRoot.colors.special.foreground - elide: Text.ElideRight - } - - MText { - visible: model.body !== "" && model.summary !== "" - width: parent.width - text: model.body - font.pixelSize: 10 - color: configRoot.colors.colors.color7 - elide: Text.ElideRight - } - } - - Timer { - interval: model.timeout - running: true - repeat: false - onTriggered: root.removeNotif(model.nid) - } - - MouseArea { - anchors.fill: parent - onClicked: root.removeNotif(model.nid) - } - } - } - } - } - - PanelWindow { - id: calendarOverlay - visible: root.activeMode === "calendar" - - screen: Quickshell.screens.find(s => s.name === "HDMI-A-1") ?? Quickshell.screens[0] - - anchors.top: root.position === "top" - anchors.bottom: root.position === "bottom" - anchors.right: true - - margins.top: root.position === "top" ? (root.look === "fill" ? 0 : 6) : 0 - margins.bottom: root.position === "bottom" ? (root.look === "fill" ? 0 : 6) : 0 - margins.right: root.look === "fill" ? 0 : root.layout === "full" ? 6 : Math.round(((root.screen?.width ?? 1920) - 820) / 2) - - implicitWidth: 216 - implicitHeight: 186 - color: "transparent" - - WlrLayershell.layer: WlrLayershell.Overlay - WlrLayershell.keyboardFocus: visible ? WlrLayershell.Exclusive : WlrLayershell.None - - property int selectedDay: new Date().getDate() - property int viewYear: new Date().getFullYear() - property int viewMonth: new Date().getMonth() - - property var days: { - let today = new Date() - let first = new Date(viewYear, viewMonth, 1).getDay() - let total = new Date(viewYear, viewMonth + 1, 0).getDate() - let ptotal = new Date(viewYear, viewMonth, 0).getDate() - let res = [] - for (let i = first - 1; i >= 0; i--) { - res.push({ d: ptotal - i, cur: false, today: false, monthOffset: -1 }) - } - for (let i = 1; i <= total; i++) { - let isToday = (i === today.getDate() && viewMonth === today.getMonth() && viewYear === today.getFullYear()) - res.push({ d: i, cur: true, today: isToday, monthOffset: 0 }) - } - let n = 42 - res.length - for (let i = 1; i <= n; i++) { - res.push({ d: i, cur: false, today: false, monthOffset: 1 }) - } - return res - } - - property string title: { - let months = ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"] - return months[viewMonth] + " " + viewYear - } - - function prevMonth() { - if (viewMonth === 0) { viewMonth = 11; viewYear-- } - else viewMonth-- - } - - function nextMonth() { - if (viewMonth === 11) { viewMonth = 0; viewYear++ } - else viewMonth++ - } - - onVisibleChanged: { - if (visible) { - let d = new Date() - viewYear = d.getFullYear() - viewMonth = d.getMonth() - selectedDay = d.getDate() - calendarBox.forceActiveFocus() - } - } - - Rectangle { - id: calendarBox - anchors.fill: parent - color: configRoot.colors.special.background - border.color: configRoot.colors.colors.color8 - border.width: 1 - focus: true - - Keys.onPressed: (event) => { - if (event.key === Qt.Key_Escape) { - root.activeMode = "none" - event.accepted = true - } - } - - ColumnLayout { - anchors.fill: parent - anchors.margins: 10 - spacing: 8 - - RowLayout { - Layout.fillWidth: true - - MText { - text: calendarOverlay.title - color: configRoot.colors.special.foreground - } - - Item { Layout.fillWidth: true } - - Row { - spacing: 12 - - MText { - text: "<" - color: prevMouse.containsMouse ? configRoot.colors.special.foreground : configRoot.colors.colors.color7 - MouseArea { - id: prevMouse - anchors.fill: parent - hoverEnabled: true - onClicked: calendarOverlay.prevMonth() - } - } - - MText { - text: ">" - color: nextMouse.containsMouse ? configRoot.colors.special.foreground : configRoot.colors.colors.color7 - MouseArea { - id: nextMouse - anchors.fill: parent - hoverEnabled: true - onClicked: calendarOverlay.nextMonth() - } - } - } - } - - Grid { - columns: 7 - spacing: 4 - Layout.alignment: Qt.AlignHCenter - - Repeater { - model: ["s", "m", "t", "w", "t", "f", "s"] - MText { - width: 22; height: 14 - horizontalAlignment: Text.AlignHCenter - text: modelData - color: configRoot.colors.colors.color4 - } - } - } - - Grid { - columns: 7 - spacing: 4 - Layout.alignment: Qt.AlignHCenter - - Repeater { - model: calendarOverlay.days - - Rectangle { - width: 22; height: 22 - property bool isHovered: dayMouse.containsMouse - - color: modelData.today ? configRoot.colors.special.foreground : (isHovered ? configRoot.colors.colors.color8 : "transparent") - - MText { - anchors.centerIn: parent - text: modelData.d - color: modelData.today ? configRoot.colors.special.background - : (isHovered ? configRoot.colors.special.foreground - : (modelData.cur ? configRoot.colors.special.foreground : configRoot.colors.colors.color8)) - } - - MouseArea { - id: dayMouse - anchors.fill: parent - hoverEnabled: true - } - } - } - } - } - } - } - } - ''; -} diff --git a/nixos/mdls/vi.nix b/nixos/mdls/vi.nix deleted file mode 100644 index 293f44b..0000000 --- a/nixos/mdls/vi.nix +++ /dev/null @@ -1,147 +0,0 @@ -{ config, pkgs, ... }: - -{ - programs.neovim = { - enable = true; - defaultEditor = true; - viAlias = true; - vimAlias = true; - withRuby = false; - withPython3 = false; - - extraPackages = with pkgs; [ - ripgrep - ]; - - plugins = with pkgs.vimPlugins; [ - lualine-nvim - telescope-nvim - plenary-nvim - nvim-web-devicons - neo-tree-nvim - nui-nvim - alpha-nvim - ]; - - initLua = '' - vim.opt.number = true - vim.opt.relativenumber = false - vim.opt.numberwidth = 4 - vim.opt.statuscolumn = "%l %s" - vim.opt.tabstop = 2 - vim.opt.softtabstop = 2 - vim.opt.shiftwidth = 2 - vim.opt.expandtab = true - vim.opt.wrap = false - vim.opt.ignorecase = true - vim.opt.smartcase = true - vim.opt.hlsearch = false - vim.opt.termguicolors = false - vim.opt.signcolumn = "yes" - vim.opt.scrolloff = 8 - vim.opt.showmode = false - vim.opt.timeoutlen = 300 - vim.opt.updatetime = 250 - vim.opt.foldcolumn = "0" - vim.opt.directory = vim.fn.stdpath("state") .. "/swap//" - - vim.g.mapleader = " " - vim.g.maplocalleader = " " - - vim.keymap.set({"n", "i"}, "", "write", {desc = "save file"}) - vim.keymap.set("n", "", "quit", {desc = "quit neovim"}) - vim.keymap.set("n", "", "nohlsearch", {desc = "clear search highlight"}) - vim.keymap.set({"n", "x"}, "gy", '"+y', {desc = "copy to clipboard"}) - vim.keymap.set({"n", "x"}, "gp", '"+p', {desc = "paste from clipboard"}) - vim.keymap.set("n", "", "u", {desc = "undo"}) - vim.keymap.set("i", "", "u", {desc = "undo"}) - vim.keymap.set("n", "", "", {desc = "redo"}) - vim.keymap.set("i", "", "", {desc = "redo"}) - vim.keymap.set({"n", "i"}, "", "ggVG", {desc = "select all"}) - - vim.keymap.set("n", "", "Telescope current_buffer_fuzzy_find", {desc = "search buffer"}) - - vim.keymap.set("n", "ff", "Telescope find_files", {desc = "find files"}) - vim.keymap.set("n", "fg", "Telescope live_grep", {desc = "text search"}) - vim.keymap.set("n", "fb", "Telescope buffers", {desc = "find buffers"}) - vim.keymap.set("n", "", "Neotree toggle", {desc = "toggle file explorer"}) - - vim.keymap.set("n", "", "h", {desc = "move left"}) - vim.keymap.set("n", "", "j", {desc = "move down"}) - vim.keymap.set("n", "", "k", {desc = "move up"}) - vim.keymap.set("n", "", "l", {desc = "move right"}) - vim.keymap.set("n", "", "vsplit", {desc = "vertical split"}) - vim.keymap.set("n", "", "split", {desc = "horizontal split"}) - vim.keymap.set("n", "", "close", {desc = "close split"}) - - vim.cmd.colorscheme("default") - vim.opt.matchpairs = "" - vim.api.nvim_set_hl(0, "MatchParen", {}) - vim.cmd("highlight clear MatchParen") - vim.cmd("highlight MatchParen guifg=NONE guibg=NONE gui=NONE") - - require("lualine").setup({ - options = { - icons_enabled = true, - theme = "auto", - component_separators = { left = "", right = "" }, - section_separators = { left = "", right = "" }, - }, - }) - - require("telescope").setup({ - defaults = { - file_ignore_patterns = { "node_modules", ".git", "%.lock" }, - layout_strategy = "horizontal", - layout_config = { horizontal = { preview_width = 0.5 } }, - }, - }) - - require("neo-tree").setup({ - window = { - position = "right", - width = 30, - mappings = { - ["l"] = "open", - ["h"] = "close_node", - [""] = "open", - [""] = "revert_preview", - }, - }, - filesystem = { - filtered_items = { - visible = false, - hide_dotfiles = false, - hide_gitignored = false, - hide_by_name = { ".git", ".DS_Store", "thumbs.db" }, - }, - follow_current_file = { enabled = true }, - }, - }) - - local alpha = require("alpha") - local dashboard = require("alpha.themes.dashboard") - - dashboard.section.header.val = { - " ⠀⠀⠀⢀⡴⠲⣄⠀⠀⢀⡶⠲⡄⠀⣀⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", - " ⣀⣀⣀⣾⠁⠀⠹⠿⠟⠟⠀⠀⠙⣛⣉⡻⠿⠋⣿⣷⢦⣄⠀⠀⠀⠀⠀⠀", - " ⠭⠭⣽⠇⠀⠶⠀⢴⣦⠀⠶⠆⠸⠯⠭⠄⠀⠀⠀⠀⠀⠙⢧⡀⠀⢀⣤⣤", - "⠀⠀ ⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢷⣤⣾⣻⡟", - " ⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣧⠽⠋⠀", - " ⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⠀⠀⠀⠀", - " ⠀⠀⢷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡟⠀⠀⠀⠀", - "⠀ ⠀⠈⠳⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⠟⠀⠀⠀⠀⠀", - "⠀⠀ ⠀⠀⠉⠿⠟⠛⠛⠻⠾⠛⠛⠛⠛⠻⠟⠛⠛⠻⠾⠃⠀⠀⠀⠀⠀⠀", - } - - dashboard.section.buttons.val = { - dashboard.button("f", " > find file", "Telescope find_files"), - dashboard.button("n", " > new file", "enew"), - dashboard.button("r", " > recent files", "Telescope oldfiles"), - dashboard.button("q", " > quit", "qa"), - } - - alpha.setup(dashboard.opts) - ''; - }; -} diff --git a/nixos/mdls/wm.nix b/nixos/mdls/wm.nix deleted file mode 100644 index 3d9314a..0000000 --- a/nixos/mdls/wm.nix +++ /dev/null @@ -1,157 +0,0 @@ -{ pkgs, ... }: - -{ - xdg.configFile."hypr/hyprland.lua".force = true; - - wayland.windowManager.hyprland = { - enable = true; - configType = "lua"; - - extraConfig = '' - local hl = hl - local dsp = hl.dsp - local bind = hl.bind - local config = hl.config - local curve = hl.curve - local animation = hl.animation - local exec = dsp.exec_cmd - local focus = dsp.focus - local window = dsp.window - local workspace = dsp.workspace - - hl.monitor({ output = "HDMI-A-1", mode = "1920x1080@200", position = "0x0", scale = 1 }) - hl.monitor({ output = "DP-1", mode = "1920x1080@144", position = "-1080x-330", scale = 1, transform = 3 }) - - local mod = "SUPER" - local terminal = "kitty" - local browser = "helium" - - hl.on("hyprland.start", function () - hl.exec_cmd("systemctl --user start hyprpolkitagent") - hl.exec_cmd("bash -c 'awww-daemon & sleep 0.5 && awww clear --outputs DP-1'") - hl.exec_cmd("wl-paste --type text --watch cliphist store") - hl.exec_cmd("wl-paste --type image --watch cliphist store") - hl.exec_cmd("quickshell -p ~/.config/quickshell/shell.qml") - end) - - config({ - general = { - gaps_in = 2.5, - gaps_out = 5, - border_size = 1, - resize_on_border = false, - col = { active_border = "rgba(ffffffff)" }, - allow_tearing = false, - layout = "dwindle", - }, - }) - - config({ - decoration = { - rounding = 0, - rounding_power = 0, - active_opacity = 1.0, - inactive_opacity = 1.0, - shadow = { - enabled = true, - range = 4, - render_power = 3, - color = "rgba(1a1a1aee)", - }, - blur = { - enabled = true, - size = 3, - passes = 3, - vibrancy = 0, - }, - }, - }) - - config({ - input = { - kb_layout = "us", - follow_mouse = 1, - sensitivity = 0, - force_no_accel = false, - touchpad = { natural_scroll = false }, - }, - }) - - config({ - misc = { - force_default_wallpaper = 0, - disable_hyprland_logo = true, - disable_splash_rendering = true, - initial_workspace_tracking = true, - }, - }) - - config({ - dwindle = { - preserve_split = true, - }, - }) - - curve("easeOutQuint", { type = "bezier", points = { {0.20, 1}, {0.30, 1} } }) - curve("easeInOutCubic", { type = "bezier", points = { {0.65, 0.05}, {0.35, 1} } }) - curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } }) - curve("almostLinear", { type = "bezier", points = { {0.5, 0.5}, {0.75, 1} } }) - curve("quick", { type = "bezier", points = { {0.15, 0}, {0.1, 1} } }) - curve("hard", { type = "bezier", points = { {0, 1}, {0, 1} } }) - animation({ leaf = "global", enabled = true, speed = 5, bezier = "default" }) - animation({ leaf = "border", enabled = true, speed = 2.5, bezier = "easeOutQuint" }) - animation({ leaf = "windows", enabled = true, speed = 2.5, bezier = "easeOutQuint" }) - animation({ leaf = "windowsIn", enabled = true, speed = 2, bezier = "easeOutQuint", style = "popin 90%" }) - animation({ leaf = "windowsOut", enabled = true, speed = 1, bezier = "linear", style = "popin 90%" }) - animation({ leaf = "fadeIn", enabled = true, speed = 1, bezier = "almostLinear" }) - animation({ leaf = "fadeOut", enabled = true, speed = 1, bezier = "almostLinear" }) - animation({ leaf = "fade", enabled = true, speed = 1.5, bezier = "quick" }) - animation({ leaf = "layers", enabled = true, speed = 2, bezier = "easeOutQuint" }) - animation({ leaf = "layersIn", enabled = true, speed = 2, bezier = "easeOutQuint", style = "fade" }) - animation({ leaf = "layersOut", enabled = true, speed = 1, bezier = "linear", style = "fade" }) - animation({ leaf = "workspaces", enabled = true, speed = 5, bezier = "hard", style = "slidevert" }) - animation({ leaf = "specialWorkspace", enabled = true, speed = 5, bezier = "hard", style = "slidevert" }) - - hl.window_rule({ - match = { initial_class = "^(imv|mpv)$" }, - float = true, - center = true, - size = "600 600", - }) - - bind(mod .. " + Q", exec(terminal)) - bind(mod .. " + R", exec("quickshell ipc call menu toggle")) - bind(mod .. " + T", exec("quickshell ipc call master toggle")) - bind(mod .. " + W", exec("quickshell ipc call bar toggle")) - bind(mod .. " + X", exec("quickshell ipc call mic toggle")) - bind(mod .. " + B", exec(browser)) - bind(mod .. " + C", window.close()) - bind(mod .. " + V", window.float({ action = "toggle" })) - bind(mod .. " + F", window.fullscreen({ mode = 0 })) - bind(mod .. " + Tab", focus({ workspace = "m+1" })) - bind("ALT + S", exec('hyprshot -o .pictures/screenshots/ -f "$(date +%y-%m-%d_%H-%M-%S).png" -s -m region')) - - bind(mod .. " + left", focus({ direction = "left" })) - bind(mod .. " + right", focus({ direction = "right" })) - bind(mod .. " + up", focus({ direction = "up" })) - bind(mod .. " + down", focus({ direction = "down" })) - - bind("SHIFT + left", window.move({ direction = "left" })) - bind("SHIFT + right", window.move({ direction = "right" })) - bind("SHIFT + up", window.move({ direction = "up" })) - bind("SHIFT + down", window.move({ direction = "down" })) - - for i = 1, 10 do - local key = (i == 10) and "0" or tostring(i) - bind(mod .. " + " .. key, focus({ workspace = i })) - bind(mod .. " + SHIFT + " .. key, window.move({ workspace = i })) - end - - bind(mod .. " + S", workspace.toggle_special("magic")) - bind(mod .. " + SHIFT + " .. "S", window.move({ workspace = "special:magic" })) - - bind(mod .. " + mouse:272", window.drag(), { mouse = true }) - bind(mod .. " + mouse:273", window.resize(), { mouse = true }) - ''; - }; -} diff --git a/nixos/mdls/yazi.nix b/nixos/mdls/yazi.nix deleted file mode 100644 index 39c1402..0000000 --- a/nixos/mdls/yazi.nix +++ /dev/null @@ -1,50 +0,0 @@ -{ - programs.yazi = { - enable = true; - - settings = { - mgr = { - ratio = [ 1 4 3 ]; - sort_by = "alphabetical"; - sort_dir_first = true; - linemode = "none"; - show_hidden = true; - show_symlink = true; - }; - }; - - theme = { - mgr = { - border_symbol = " "; - }; - indicator = { - padding = { open = "█"; close = "█"; }; - }; - mode = { - normal_main = { fg = "black"; bg = "blue"; bold = true; }; - normal_alt = { fg = "blue"; bg = "black"; }; - select_main = { fg = "black"; bg = "green"; bold = true; }; - select_alt = { fg = "green"; bg = "black"; }; - unset_main = { fg = "black"; bg = "yellow"; bold = true; }; - unset_alt = { fg = "yellow"; bg = "black"; }; - }; - status = { - sep_left = { open = ""; close = ""; }; - sep_right = { open = ""; close = ""; }; - }; - }; - - keymap = { - manager = { - prepend_keymap = [ - { on = [ "x" ]; run = "yank --cut"; } - { on = [ "y" ]; run = "yank"; } - { on = [ "p" ]; run = "paste"; } - { on = [ "d" ]; run = "remove"; } - { on = [ "r" ]; run = "rename"; } - { on = [ "c" ]; run = "create"; } - ]; - }; - }; - }; -} diff --git a/nixos/modules/btop.nix b/nixos/modules/btop.nix new file mode 100644 index 0000000..6738384 --- /dev/null +++ b/nixos/modules/btop.nix @@ -0,0 +1,86 @@ +{ config, pkgs, ... }: + +{ + xdg.configFile."btop/btop.conf".force = true; + + programs.btop = { + enable = true; + settings = { + color_theme = "TTY"; + theme_background = true; + truecolor = true; + force_tty = false; + presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"; + vim_keys = false; + rounded_corners = false; + terminal_sync = true; + update_ms = 2000; + background_update = true; + clock_format = "%X"; + base_10_sizes = false; + base_10_bitrate = "Auto"; + log_level = "WARNING"; + save_config_on_exit = true; + shown_boxes = "cpu mem net proc"; + graph_symbol = "braille"; + graph_symbol_cpu = "default"; + graph_symbol_gpu = "default"; + graph_symbol_mem = "default"; + graph_symbol_net = "default"; + graph_symbol_proc = "default"; + cpu_bottom = false; + cpu_graph_upper = "Auto"; + cpu_graph_lower = "Auto"; + cpu_invert_lower = true; + cpu_single_graph = false; + check_temp = true; + cpu_sensor = "Auto"; + show_coretemp = true; + cpu_core_map = ""; + temp_scale = "celsius"; + show_cpu_freq = true; + freq_mode = "first"; + show_cpu_watts = true; + show_uptime = true; + custom_cpu_name = ""; + proc_left = false; + proc_sorting = "cpu lazy"; + proc_reversed = false; + proc_tree = false; + proc_colors = true; + proc_gradient = true; + proc_per_core = false; + proc_mem_bytes = true; + proc_cpu_graphs = true; + proc_info_smaps = false; + proc_filter_kernel = false; + proc_aggregate = false; + keep_dead_proc_usage = false; + mem_graphs = true; + mem_below_net = false; + show_swap = true; + swap_disk = true; + zfs_arc_cached = true; + show_disks = true; + disks_filter = ""; + only_physical = true; + use_fstab = true; + disk_free_priv = false; + show_io_stat = true; + io_mode = false; + io_graph_combined = false; + io_graph_speeds = ""; + zfs_hide_datasets = false; + net_iface = ""; + net_auto = true; + net_sync = true; + net_download = 100; + net_upload = 100; + show_gpu_info = "Auto"; + shown_gpus = "amd nvidia intel"; + gpu_mirror_graph = true; + nvml_measure_pcie_speeds = true; + rsmi_measure_pcie_speeds = true; + }; + }; +} diff --git a/nixos/modules/colors.nix b/nixos/modules/colors.nix new file mode 100644 index 0000000..98ce1cc --- /dev/null +++ b/nixos/modules/colors.nix @@ -0,0 +1,224 @@ +{ pkgs, ... }: + +let + colors-script = pkgs.writeShellScriptBin "colors" '' + [ -z "$1" ] && echo "usage: colors " >&2 && exit 1 + [ ! -f "$1" ] && echo "colors: file not found: $1" >&2 && exit 1 + + colors="$HOME/.colors" + mkdir -p "$colors" + + awww_out=$(${pkgs.awww}/bin/awww img -o HDMI-A-1 "$1" --transition-type grow --transition-duration 1.5 --transition-fps 120 2>&1) + [ $? -ne 0 ] && echo "colors: awww: $awww_out" >&2 + ${pkgs.awww}/bin/awww clear --outputs DP-1 2>/dev/null + + raw=$(${pkgs.imagemagick}/bin/magick "$1" -thumbnail 50x50^ -colors 8 -unique-colors txt:- 2>&1) + + base=$(printf '%s\n' "$raw" \ + | ${pkgs.gnugrep}/bin/grep -oE '#[0-9A-Fa-f]{6}' \ + | ${pkgs.gawk}/bin/awk '{ + r = strtonum("0x" substr($0,2,2)) + g = strtonum("0x" substr($0,4,2)) + b = strtonum("0x" substr($0,6,2)) + printf "%d %s\n", int(0.299*r + 0.587*g + 0.114*b), $0 + }' \ + | ${pkgs.coreutils}/bin/sort -n \ + | ${pkgs.gawk}/bin/awk '{print $2}' \ + | ${pkgs.coreutils}/bin/head -8) + + [ -z "$base" ] && echo "colors: magick failed" >&2 && echo "$raw" >&2 && exit 1 + + n=$(printf '%s\n' "$base" | ${pkgs.coreutils}/bin/wc -l) + last=$(printf '%s\n' "$base" | ${pkgs.coreutils}/bin/tail -1) + while [ "$n" -lt 8 ]; do + base=$(printf '%s\n%s' "$base" "$last") + n=$((n+1)) + done + + bright=$(printf '%s\n' "$base" | ${pkgs.gawk}/bin/awk '{ + r = strtonum("0x" substr($0,2,2)) + g = strtonum("0x" substr($0,4,2)) + b = strtonum("0x" substr($0,6,2)) + r = int(r*1.4); if (r>255) r=255 + g = int(g*1.4); if (g>255) g=255 + b = int(b*1.4); if (b>255) b=255 + printf "#%02X%02X%02X\n", r, g, b + }') + + cols=$(printf '%s\n%s' "$base" "$bright") + + c0=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '1p') + c1=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '2p') + c2=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '3p') + c3=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '4p') + c4=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '5p') + c5=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '6p') + c6=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '7p') + c7=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '8p') + c8=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '9p') + c9=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '10p') + c10=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '11p') + c11=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '12p') + c12=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '13p') + c13=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '14p') + c14=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '15p') + c15=$(printf '%s\n' "$cols" | ${pkgs.gnused}/bin/sed -n '16p') + + bg="$c0" + fg=$(printf '%s\n' "$cols" | ${pkgs.gawk}/bin/awk -v bg="$c0" ' + function lum(hex, r,g,b,rs,gs,bs) { + r = strtonum("0x" substr(hex,2,2)) / 255 + g = strtonum("0x" substr(hex,4,2)) / 255 + b = strtonum("0x" substr(hex,6,2)) / 255 + rs = (r<=0.04045) ? r/12.92 : ((r+0.055)/1.055)^2.4 + gs = (g<=0.04045) ? g/12.92 : ((g+0.055)/1.055)^2.4 + bs = (b<=0.04045) ? b/12.92 : ((b+0.055)/1.055)^2.4 + return 0.2126*rs + 0.7152*gs + 0.0722*bs + } + function contrast(a,b, l1,l2,t) { + l1 = lum(a); l2 = lum(b) + if (l1 < l2) { t=l1; l1=l2; l2=t } + return (l1+0.05) / (l2+0.05) + } + BEGIN { best=""; bestc=0 } + { + c = contrast($0, bg) + if (c > bestc) { bestc=c; best=$0 } + } + END { print best } + ') + cursor="$fg" + + printf '%s' "$1" > "$colors/colors" + + printf '%s\n' "$cols" | ${pkgs.gawk}/bin/awk '{printf "color%d=%s\n", NR-1, $0}' > "$colors/colors.sh" + printf 'background="%s"\nforeground="%s"\ncursor="%s"\n' "$bg" "$fg" "$cursor" >> "$colors/colors.sh" + + cat > "$colors/colors.json" << ENDJSON + { + "wallpaper": "$1", + "alpha": "100", + "special": { + "background": "$bg", + "foreground": "$fg", + "cursor": "$cursor" + }, + "colors": { + "color0": "$c0", + "color1": "$c1", + "color2": "$c2", + "color3": "$c3", + "color4": "$c4", + "color5": "$c5", + "color6": "$c6", + "color7": "$c7", + "color8": "$c8", + "color9": "$c9", + "color10": "$c10", + "color11": "$c11", + "color12": "$c12", + "color13": "$c13", + "color14": "$c14", + "color15": "$c15" + } + } + ENDJSON + + printf '%s\n' "$cols" > "$colors/colors.txt" + + cat > "$colors/kitty.conf" << ENDKITTY + foreground $fg + background $bg + background_opacity 1.0 + cursor $cursor + + active_tab_foreground $bg + active_tab_background $fg + inactive_tab_foreground $fg + inactive_tab_background $bg + + active_border_color $fg + inactive_border_color $bg + bell_border_color $c1 + + color0 $c0 + color8 $c8 + color1 $c1 + color9 $c9 + color2 $c2 + color10 $c10 + color3 $c3 + color11 $c11 + color4 $c4 + color12 $c12 + color5 $c5 + color13 $c13 + color6 $c6 + color14 $c14 + color7 $c7 + color15 $c15 + ENDKITTY + + cat > "$colors/colors.fish" << ENDFISH + set fish_color_autosuggestion \$(echo "$c8" | sed 's/#//') + set fish_color_cancel \$(echo "$c1" | sed 's/#//') '--reverse' + set fish_color_command \$(echo "$c10" | sed 's/#//') + set fish_color_comment \$(echo "$c8" | sed 's/#//') + set fish_color_cwd \$(echo "$c2" | sed 's/#//') + set fish_color_cwd_root \$(echo "$c1" | sed 's/#//') + set fish_color_end \$(echo "$c3" | sed 's/#//') + set fish_color_error \$(echo "$c1" | sed 's/#//') + set fish_color_escape \$(echo "$c5" | sed 's/#//') + set fish_color_history_current --bold + set fish_color_host \$(echo "$c12" | sed 's/#//') + set fish_color_host_remote \$(echo "$c12" | sed 's/#//') + set fish_color_keyword \$(echo "$c5" | sed 's/#//') + set fish_color_match --background=\$(echo "$c4" | sed 's/#//') + set fish_color_normal \$(echo "$fg" | sed 's/#//') + set fish_color_operator \$(echo "$c6" | sed 's/#//') + set fish_color_option \$(echo "$c3" | sed 's/#//') + set fish_color_param \$(echo "$c12" | sed 's/#//') + set fish_color_quote \$(echo "$c11" | sed 's/#//') + set fish_color_redirection \$(echo "$c5" | sed 's/#//') + set fish_color_search_match --background=\$(echo "$c8" | sed 's/#//') + set fish_color_selection --background=\$(echo "$c8" | sed 's/#//') + set fish_color_status \$(echo "$c1" | sed 's/#//') + set fish_color_user \$(echo "$c10" | sed 's/#//') + set fish_color_valid_path --underline + set fish_pager_color_background \$(echo "$bg" | sed 's/#//') + set fish_pager_color_completion \$(echo "$fg" | sed 's/#//') + set fish_pager_color_description \--background=\$(echo "$c8" | sed 's/#//') + set fish_pager_color_prefix \$(echo "$c10" | sed 's/#//') + set fish_pager_color_progress \$(echo "$c8" | sed 's/#//') + set fish_pager_color_secondary_background \$(echo "$bg" | sed 's/#//') + set fish_pager_color_secondary_completion \$(echo "$fg" | sed 's/#//') + set fish_pager_color_secondary_description \$(echo "$c8" | sed 's/#//') + set fish_pager_color_secondary_prefix \$(echo "$c10" | sed 's/#//') + set fish_pager_color_selected_background --background=\$(echo "$c8" | sed 's/#//') + set fish_pager_color_selected_completion \$(echo "$fg" | sed 's/#//') + set fish_pager_color_selected_description \$(echo "$c8" | sed 's/#//') + set fish_pager_color_selected_prefix \$(echo "$c10" | sed 's/#//') + ENDFISH + + { + printf '%s\n' "$cols" | ${pkgs.gawk}/bin/awk '{printf "\033]4;%d;%s\007", NR-1, $0}' + printf '\033]10;%s\007' "$fg" + printf '\033]11;%s\007' "$bg" + printf '\033]12;%s\007' "$cursor" + } > "$colors/sequences" + + for pty in /proc/*/fd/0; do + [ -c "$pty" ] && [ -w "$pty" ] && ${pkgs.coreutils}/bin/cat "$colors/sequences" > "$pty" 2>/dev/null + done + + printf '%s\n' "$base" | ${pkgs.gawk}/bin/awk '{ + r = strtonum("0x" substr($0,2,2)) + g = strtonum("0x" substr($0,4,2)) + b = strtonum("0x" substr($0,6,2)) + printf "\033[48;2;%d;%d;%dm \033[0m %s\n", r, g, b, $0 + }' + ''; +in +{ + home.packages = [ colors-script ]; +} diff --git a/nixos/modules/gms/dayz.nix b/nixos/modules/gms/dayz.nix new file mode 100644 index 0000000..128a10c --- /dev/null +++ b/nixos/modules/gms/dayz.nix @@ -0,0 +1,1808 @@ +{ config, pkgs, ... }: + +let + dayzDir = "${config.home.homeDirectory}/.local/share/Steam/steamapps/compatdata/221100/pfx/drive_c/users/steamuser/Documents/DayZ"; +in +{ + home.packages = [ (pkgs.writeShellApplication { + name = "meowz"; + runtimeInputs = with pkgs; [ curl jq fzf steamcmd ]; + excludeShellChecks = [ "SC2155" "SC2162" "SC2207" "SC2086" "SC2178" "SC2128" ]; + text = '' + +config="$HOME/.config/dayz" +favfile="$config/favorites" +logfile="$config/last_launch.log" +steamapps="$HOME/.local/share/Steam/steamapps" +workshop="$steamapps/workshop/content/221100" +d=$'\x1f' + +mkdir -p "$config" +touch "$favfile" +sed -i '/^[[:space:]]*$/d' "$favfile" +awk -F"$d" 'NF==4' "$favfile" > "$favfile.tmp" && mv "$favfile.tmp" "$favfile" + +log() { printf '%s\n' "$*"; } +err() { printf '%s\n' "$*" >&2; } + +api() { + curl -sg -A "mozilla" "https://api.battlemetrics.com$1" +} + +fetch_servers() { + local path="/servers?filter[game]=dayz&page[size]=100$1" + local pages=0 + while [ -n "$path" ] && [ "$pages" -lt 4 ]; do + local resp=$(api "$path") + echo "$resp" | jq -e . >/dev/null 2>&1 || break + echo "$resp" | jq -r '.data[]? | "\(.id)|\(.attributes.ip):\(.attributes.port)|\(.attributes.name) [\(.attributes.players)/\(.attributes.maxPlayers)]"' + path=$(echo "$resp" | jq -r '.links.next // empty' | sed 's|.*battlemetrics.com||') + pages=$((pages + 1)) + done +} + +if [ "''${1:-}" = "--fetch" ]; then + fetch_servers "''${2:+&filter[search]=$2}" + exit 0 +fi + +steamuser="" +[ -f "$config/steamuser" ] && steamuser=$(cat "$config/steamuser") +if [ -z "$steamuser" ]; then + read -p "steam username: " steamuser + echo "$steamuser" > "$config/steamuser" +fi + +steampass="" +[ -f "$config/steampass" ] && steampass=$(cat "$config/steampass") +if [ -z "$steampass" ]; then + read -rsp "steam password (stored in plaintext, blank to skip caching): " steampass + echo + if [ -n "$steampass" ]; then + (umask 177; echo "$steampass" > "$config/steampass") + fi +fi + +loginmarker="$config/steam_authenticated" + +get_mods_by_id() { + api "/servers/$1" | jq -r '.data?.attributes?.details?.modIds[]? // empty' | paste -sd, - +} + +get_mods() { + local ip="$1" port="$2" + local m=$(curl -s "https://dayzsalauncher.com/api/v1/server/$ip:$port" | jq -r '.result?.mods[]?.steamWorkshopId // empty' | paste -sd, -) + if [ -z "$m" ]; then + local id=$(api "/servers?filter[game]=dayz&filter[search]=$ip:$port" | jq -r '.data[0]?.id // empty') + [ -n "$id" ] && m=$(get_mods_by_id "$id") + fi + echo "$m" +} + +download_mods() { + local mods=($(echo "$1" | tr ',' '\n')) + [ "''${#mods[@]}" -eq 0 ] && return 0 + + touch "$config/blacklist" + local missing=() + for mod in "''${mods[@]}"; do + grep -qx "$mod" "$config/blacklist" && continue + find "$workshop/$mod" -mindepth 1 2>/dev/null | grep -q . || missing+=("$mod") + done + [ "''${#missing[@]}" -eq 0 ] && { log "mods already present"; return 0; } + + local runner="steamcmd" + command -v steamcmd >/dev/null 2>&1 || { err "steamcmd not found"; return 1; } + + mods=("''${missing[@]}") + local cmds="" + for mod in "''${mods[@]}"; do + cmds="$cmds +workshop_download_item 221100 $mod" + done + + if pgrep -x steam >/dev/null; then + log "closing steam..." + steam -shutdown + while pgrep -x steam >/dev/null; do sleep 1; done + fi + + log "downloading mods..." + local attempt=1 + while [ "$attempt" -le 4 ]; do + [ "$attempt" -gt 1 ] && log "retry $attempt/4, ''${#mods[@]} mods" + local out + local login_args=("$steamuser") + if [ ! -f "$loginmarker" ] && [ -n "$steampass" ]; then + login_args=("$steamuser" "$steampass") + fi + out=$($runner +@sSteamCmdForcePlatformType linux -forceipv4 +login "''${login_args[@]}" $cmds +quit | tee /dev/tty) || true + + if echo "$out" | grep -q "Waiting for user info"; then + touch "$loginmarker" + fi + if echo "$out" | grep -q "FAILED"; then + rm -f "$loginmarker" + fi + + if echo "$out" | grep -q "Invalid Password"; then + err "wrong password, clearing cache" + rm -f "$config/steampass" + steampass="" + fi + + local failed=() + for mod in "''${mods[@]}"; do + if echo "$out" | grep -q "Success. Downloaded item $mod "; then + continue + fi + if echo "$out" | grep -qE "Download item $mod failed \((Access Denied|No match|File Not Found)\)"; then + err "mod $mod unavailable, blacklisting" + grep -qx "$mod" "$config/blacklist" || echo "$mod" >> "$config/blacklist" + continue + fi + failed+=("$mod") + done + + [ "''${#failed[@]}" -eq 0 ] && { log "mods downloaded"; return 0; } + + mods=("''${failed[@]}") + cmds="" + for mod in "''${mods[@]}"; do + cmds="$cmds +workshop_download_item 221100 $mod" + done + attempt=$((attempt + 1)) + sleep 3 + done + + err "failed to download: ''${mods[*]}" + return 1 +} + +launch() { + local ip="$1" port="$2" mods="$3" mod_arg="" + + if [ -z "$ip" ] || [ -z "$port" ]; then + err "invalid ip/port" + return 1 + fi + + log "verifying server..." + local verify + verify=$(api "/servers?filter[game]=dayz&filter[search]=$ip:$port" | jq -r --arg ip "$ip" --arg port "$port" '.data[]? | select(.attributes.ip == $ip and (.attributes.port | tostring) == $port) | "\(.attributes.name) [\(.attributes.players)/\(.attributes.maxPlayers)]"' | head -n 1) + if [ -n "$verify" ]; then + log "found: $verify" + else + err "server not found on battlemetrics, connecting anyway" + fi + + if [ -z "$mods" ]; then + log "no mod list found, may still require mods" + else + log "downloading mods..." + download_mods "$mods" || err "some mods failed, launching anyway" + for m in $(echo "$mods" | tr ',' '\n'); do + [ -z "$m" ] && continue + local folder=$(find "$workshop/$m" -maxdepth 1 -type d -name "@*" 2>/dev/null | head -n 1) + [ -z "$folder" ] && folder="$workshop/$m" + find "$folder" -iname "*.pbo" 2>/dev/null | grep -q . || { err "missing pbo for $m, skipping"; continue; } + mod_arg="$mod_arg;z:''${folder//\//\\}" + done + mod_arg="''${mod_arg#;}" + [ -n "$mod_arg" ] && mod_arg="-mod=$mod_arg" + sleep 3 + fi + + echo "$(date '+%F %T') connect=$ip:$port $mod_arg" >> "$logfile" + + if ! pgrep -x steam >/dev/null; then + log "starting steam..." + if [ ! -f "$loginmarker" ]; then + if [ -n "$steampass" ]; then + steam -login "$steamuser" "$steampass" >>"$config/steam.log" 2>&1 & disown + else + steam -login "$steamuser" >>"$config/steam.log" 2>&1 & disown + fi + else + steam >>"$config/steam.log" 2>&1 & disown + fi + while ! pgrep -x steam >/dev/null; do sleep 1; done + sleep 5 + fi + + log "connecting to $ip:$port..." + if [ -n "$mod_arg" ]; then + steam -applaunch 221100 -noLauncher "-connect=$ip" "-port=$port" "$mod_arg" >>"$config/steam.log" 2>&1 + else + steam -applaunch 221100 -noLauncher "-connect=$ip" "-port=$port" >>"$config/steam.log" 2>&1 + fi +} + +pick_server() { + fzf --prompt="server> " --delimiter="|" --with-nth=3.. --layout=reverse \ + --disabled --ansi \ + --bind "start:reload:$0 --fetch" \ + --bind "change:reload:sleep 0.4; $0 --fetch {q}" +} + +save_favorite() { + local ip="$1" port="$2" name="$3" + if grep -qF "$ip$d$port$d" "$favfile"; then + err "already saved" + return + fi + local mods=$(get_mods "$ip" "$port") + printf "%s%s%s%s%s%s%s\n" "$ip" "$d" "$port" "$d" "$mods" "$d" "$name" >> "$favfile" + log "saved $name" +} + +show_favorites() { + grep -vE '^[[:space:]]*$' "$favfile" | fzf --prompt="fav> " --delimiter="$d" --with-nth=4 --layout=reverse +} + +while true; do + action=$(printf "favorites\nbrowse\nadd manual\nremove\nrefresh mods\nquit\n" | fzf --prompt="dayz> " --layout=reverse) + + case "$action" in + browse) + selection=$(pick_server) + [ -z "$selection" ] && continue + id=$(echo "$selection" | cut -d'|' -f1) + ip_port=$(echo "$selection" | cut -d'|' -f2) + name=$(echo "$selection" | cut -d'|' -f3- | sed 's/ \[[0-9]*\/[0-9]*\]$//') + ip=''${ip_port%%:*} + port=''${ip_port##*:} + confirm=$(printf "play\nsave to favorites\n" | fzf --prompt="$name> " --layout=reverse) + case "$confirm" in + play) mods=$(get_mods_by_id "$id"); launch "$ip" "$port" "$mods"; exit 0 ;; + "save to favorites") save_favorite "$ip" "$port" "$name"; show_favorites ;; + esac + ;; + favorites) + selection=$(show_favorites) + [ -z "$selection" ] && continue + ip=$(echo "$selection" | cut -d"$d" -f1) + port=$(echo "$selection" | cut -d"$d" -f2) + mods=$(echo "$selection" | cut -d"$d" -f3) + launch "$ip" "$port" "$mods" + exit 0 + ;; + "add manual") + read -p "ip: " ip + read -p "port: " port + read -p "name: " name + save_favorite "$ip" "$port" "$name" + show_favorites + ;; + remove) + selection=$(show_favorites) + [ -z "$selection" ] && continue + grep -vF "$selection" "$favfile" | grep -vE '^[[:space:]]*$' > "$favfile.tmp" && mv "$favfile.tmp" "$favfile" + show_favorites + ;; + "refresh mods") + selection=$(show_favorites) + [ -z "$selection" ] && continue + ip=$(echo "$selection" | cut -d"$d" -f1) + port=$(echo "$selection" | cut -d"$d" -f2) + name=$(echo "$selection" | cut -d"$d" -f4) + mods=$(get_mods "$ip" "$port") + grep -vF "$selection" "$favfile" | grep -vE '^[[:space:]]*$' > "$favfile.tmp" && mv "$favfile.tmp" "$favfile" + printf "%s%s%s%s%s%s%s\n" "$ip" "$d" "$port" "$d" "$mods" "$d" "$name" >> "$favfile" + show_favorites + ;; + quit|"") break ;; + esac +done + ''; + }) ]; + + xdg.desktopEntries.meowz = { + name = "MeowZ"; + comment = "dayz server launcher"; + exec = "kitty --hold -e meowz"; + icon = "applications-games"; + terminal = false; + categories = [ "Game" ]; + }; + + home.file."${dayzDir}/DayZ.cfg".text = '' + language="English"; + adapter=-1; + 3D_Performance=57692; + Resolution_Bpp=32; + WinX=0; + WinY=0; + WindowWidth=1920; + WindowHeight=1080; + MSAA=0; + PostFX=0; + VSync=1; + FXAO=0; + AToC=0; + AnisoFilter=4; + TerrainDetail=2; + FXAA=0; + refreshMode=200; + maxGPUToRenderFrames=1; + ''; + + home.file."${dayzDir}/steamuser_settings.DayZProfile".text = '' + version=1; + blood=1; + singleVoice=0; + gamma=1; + lastMPServer=""; + lastMPServerName=""; + lastMPMission=""; + inputVersion=1; + perspective=1; + trackIR=1; + freeTrack=1; + mouseSmoothing=0; + maxSamplesPlayed=96; + vonInputMode=0; + TexQuality=1; + WaterQuality=1; + tripleHead=0; + showTitles=1; + vehicleFreelook=0; + pauseMode=0; + shadowQuality=1; + headBob=0; + fov=0.95993; + sceneComplexity=150000; + shadowZDistance=80; + viewDistance=1200; + preferredObjectViewDistance=1200; + terrainGrid=12.5; + volumeMaster=5; + volumeCD=0.5; + volumeFX=4; + volumeSpeech=5; + volumeVoN=10; + vonRecThreshold=0.029999999; + brightness=1; + uiTopLeftX=0.12500001; + uiTopLeftY=0; + uiBottomRightX=0.875; + uiBottomRightY=1; + IGUIScale=0.55000001; + showHUD=1; + hudBrightness=1.0; + showCrosshair=0; + showQuickbar=1; + showVehicleHUD=1; + showServerInfo=0; + ''; + + home.file."${dayzDir}/steamuser.dayz_preset_User.xml".text = '' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''; +} diff --git a/nixos/modules/gms/mc.nix b/nixos/modules/gms/mc.nix new file mode 100644 index 0000000..d8c6734 --- /dev/null +++ b/nixos/modules/gms/mc.nix @@ -0,0 +1,80 @@ +{ config, pkgs, ... }: + +{ + home.packages = [ pkgs.prismlauncher ]; + + home.file.".local/share/PrismLauncher/prismlauncher.cfg" = { + text = pkgs.lib.generators.toINI {} { + General = { + ApplicationTheme = "dark"; + AutoCloseConsole = false; + AutomaticJavaDownload = false; + AutomaticJavaSwitch = true; + CatFit = "fit"; + CatOpacity = 100; + CentralModsDir = "mods"; + CloseAfterLaunch = false; + ConfigVersion = "1.3"; + ConsoleFont = "DejaVu Sans Mono"; + ConsoleFontSize = 11; + ConsoleMaxLines = 100000; + ConsoleOverflowStop = true; + DownloadsDir = "/home/cat/Downloads"; + DownloadsDirWatchRecursive = false; + EnableFeralGamemode = false; + EnableMangoHud = false; + Env = "{}"; + FallbackMRBlockedMods = 2; + IconTheme = "OSX"; + IconsDir = "icons"; + IgnoreJavaCompatibility = false; + IgnoreJavaWizard = false; + InstRenamingMode = "AskEverytime"; + InstSortMode = "Name"; + InstanceDir = "instances"; + JavaArchitecture = "64"; + JavaDir = "java"; + JavaPath = "/nix/store/55mw2ly3dxh5008li72rx6ilc75hgvr0-openjdk-8u502-b01/bin/java"; + Language = "en_US"; + LaunchMaximized = false; + LowMemWarning = true; + MaxMemAlloc = 6016; + MinMemAlloc = 2048; + MinecraftWinHeight = 480; + MinecraftWinWidth = 854; + ModDependenciesDisabled = false; + ModMetadataDisabled = false; + MoveModsFromDownloadsDir = true; + NumberOfConcurrentDownloads = 6; + NumberOfConcurrentTasks = 10; + NumberOfManualRetries = 1; + OnlineFixes = false; + PastebinType = 3; + PermGen = 128; + ProxyAddr = "127.0.0.1"; + ProxyPort = 8080; + ProxyType = "None"; + QuitAfterGameStop = false; + RecordGameTime = true; + RequestTimeout = 60; + ShowConsole = false; + ShowConsoleOnError = true; + ShowGameTime = true; + ShowGameTimeWithoutDays = false; + ShowGlobalGameTime = true; + ShowModIncompat = false; + SkinsDir = "skins"; + SkipModpackUpdatePrompt = false; + StatusBarVisible = false; + TheCat = false; + ToolbarsLocked = true; + UseDiscreteGpu = false; + UseNativeGLFW = false; + UseNativeOpenAL = false; + UseZink = false; + UserAskedAboutAutomaticJavaDownload = true; + }; + }; + force = true; + }; +} diff --git a/nixos/modules/notes.nix b/nixos/modules/notes.nix new file mode 100644 index 0000000..01356d6 --- /dev/null +++ b/nixos/modules/notes.nix @@ -0,0 +1,55 @@ +{ config, pkgs, ... }: + +{ + home.packages = [ pkgs.obsidian ]; + + home.file = { + ".documents/obsidian/.obsidian/app.json".text = builtins.toJSON { + readableLineLength = true; + foldHeading = true; + showLineNumber = true; + spellcheck = false; + vimMode = false; + newFileLocation = "current"; + promptDelete = false; + }; + ".documents/obsidian/.obsidian/appearance.json".text = builtins.toJSON { + accentColor = "#ffa8db"; + cssTheme = ""; + theme = "obsidian"; + }; + ".documents/obsidian/.obsidian/core-plugins.json".text = builtins.toJSON { + "file-explorer" = true; + "global-search" = true; + "switcher" = false; + "graph" = true; + "backlink" = false; + "canvas" = false; + "outgoing-link" = true; + "tag-pane" = true; + "footnotes" = false; + "properties" = false; + "page-preview" = true; + "daily-notes" = true; + "templates" = false; + "note-composer" = false; + "command-palette" = false; + "slash-command" = false; + "editor-status" = true; + "bookmarks" = false; + "markdown-importer" = false; + "zk-prefixer" = false; + "random-note" = false; + "outline" = true; + "word-count" = true; + "slides" = false; + "audio-recorder" = false; + "workspaces" = false; + "file-recovery" = true; + "publish" = false; + "sync" = false; + "bases" = false; + "webviewer" = false; + }; + }; +} diff --git a/nixos/modules/qksh.nix b/nixos/modules/qksh.nix new file mode 100644 index 0000000..9e9e85b --- /dev/null +++ b/nixos/modules/qksh.nix @@ -0,0 +1,992 @@ +{ pkgs, ... }: + +{ + xdg.configFile."quickshell/shell.qml".text = '' + import Quickshell + import Quickshell.Wayland + import Quickshell.Hyprland + import Quickshell.Io + import Quickshell.Services.Notifications + import QtQuick + import QtQuick.Layouts + import QtCore + + Scope { + id: configRoot + + property string colorBuf: "" + property var colors: { + "special": { "background": "#1c1c1c", "foreground": "#c0c0c0", "cursor": "#c0c0c0" }, + "colors": { + "color0": "#1c1c1c", "color1": "#cc2222", "color2": "#22cc22", "color3": "#cccc22", + "color4": "#2222cc", "color5": "#cc22cc", "color6": "#22cccc", "color7": "#aaaaaa", + "color8": "#555555", "color9": "#ff4444", "color10": "#44ff44", "color11": "#ffff44", + "color12": "#4444ff", "color13": "#ff44ff", "color14": "#44ffff", "color15": "#ffffff" + } + } + + component MText: Text { + font.family: "JetBrainsMono Nerd Font" + font.pixelSize: 12 + font.weight: Font.Normal + renderType: Text.NativeRendering + color: root.colors.special.foreground + } + + Settings { + id: barSettings + location: Qt.resolvedUrl("state") + property string position: "top" + property string layout: "minimal" + property string look: "float" + property string centerMode: "default" + } + + NotificationServer { + id: notifServer + keepOnReload: true + + onNotification: (notif) => { + if (notifModel.count >= 3) notifModel.remove(0) + notifModel.append({ + nid: notif.id, + app: notif.appName ?? "", + summary: notif.summary ?? "", + body: notif.body ?? "", + timeout: notif.expireTimeout > 0 ? notif.expireTimeout : 5000 + }) + } + } + + ListModel { id: notifModel } + + PanelWindow { + id: root + property string position: barSettings.position + property string layout: barSettings.layout + property string look: barSettings.look + + screen: Quickshell.screens.find(s => s.name === "HDMI-A-1") ?? Quickshell.screens[0] + + property string activeMode: "none" + property bool autoHideBar: false + + property var launcherTopApp: null + + property string sysStats: "cpu --% | mem --%" + property string micState: "󰍬" + + function removeNotif(nid) { + for (let i = 0; i < notifModel.count; i++) { + if (notifModel.get(i).nid === nid) { + notifModel.remove(i) + break + } + } + } + + function launcherRefilter(q) { + if (!DesktopEntries.applications?.values || q === "") { + launcherTopApp = null; return + } + let ql = q.toLowerCase() + let m = DesktopEntries.applications.values.filter( + a => a?.name && a.name.toLowerCase().includes(ql) + ).sort((a, b) => { + let an = a.name.toLowerCase() + let bn = b.name.toLowerCase() + if (an === ql) return -1 + if (bn === ql) return 1 + if (an.startsWith(ql) && !bn.startsWith(ql)) return -1 + if (!an.startsWith(ql) && bn.startsWith(ql)) return 1 + if (an.includes("steam") && an !== "steam" && bn === "steam") return 1 + if (bn.includes("steam") && bn !== "steam" && an === "steam") return -1 + return an.localeCompare(bn) + }) + launcherTopApp = m.length > 0 ? m[0] : null + } + + function launcherOpen() { + if (!root.visible) { autoHideBar = true; root.visible = true } + else autoHideBar = false + launcherTopApp = null + activeMode = "launcher" + } + + function launcherClose() { + activeMode = "none" + launcherTopApp = null + if (autoHideBar) { root.visible = false; autoHideBar = false } + } + + function launcherAccept() { + if (launcherTopApp !== null) { + let exec = launcherTopApp.execString.replace(/%[fFuU]/g, "") + launchProc.command = ["systemd-run", "--user", "--scope", "bash", "-c", exec] + launchProc.running = true + } + launcherClose() + } + + property string masterLevel: "root" + property var masterStack: [] + property var masterCurrent: [] + property var masterFiltered: [] + property int masterSelected: 0 + + property var masterRootItems: [ + { label: "sys", sub: "sys" }, + { label: "sts", sub: "sts" }, + { label: "rcd", sub: "rcd" }, + { label: "wp", sub: "wallpapers" }, + { label: "pw", sub: "pw" } + ] + property var masterSysItems: [ + { label: "nix", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/hosts/box/configuration.nix"] }, + { label: "box", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/hosts/box/box.nix"] }, + { label: "wm", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/mdls/wm.nix"] }, + { label: "qksh", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/mdls/qksh.nix"] }, + { label: "vi", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/mdls/vi.nix"] }, + { label: "yazi", cmd: ["kitty", "-e", "sudo", "nvim", "/etc/nixos/mdls/yazi.nix"] }, + ] + property var masterStsItems: [ + { label: "animations", sub: "animations" }, + { label: "bar", sub: "bar" } + ] + property var masterAnimationsItems: [ + { label: "fade", cmd: ["sh", "-c", "hyprctl eval 'hl.animation({ leaf = \"workspaces\", enabled = true, speed = 1.94, bezier = \"almostLinear\", style = \"fade\" })' && hyprctl eval 'hl.animation({ leaf = \"specialWorkspace\", enabled = true, speed = 1.94, bezier = \"almostLinear\", style = \"fade\" })' && ${pkgs.libnotify}/bin/notify-send animations fade"] }, + { label: "vertical", cmd: ["sh", "-c", "hyprctl eval 'hl.animation({ leaf = \"workspaces\", enabled = true, speed = 5, bezier = \"hard\", style = \"slidevert\" })' && hyprctl eval 'hl.animation({ leaf = \"specialWorkspace\", enabled = true, speed = 5, bezier = \"hard\", style = \"slidevert\" })' && ${pkgs.libnotify}/bin/notify-send animations vertical"] }, + { label: "horizontal", cmd: ["sh", "-c", "hyprctl eval 'hl.animation({ leaf = \"workspaces\", enabled = true, speed = 5, bezier = \"hard\", style = \"slide\" })' && hyprctl eval 'hl.animation({ leaf = \"specialWorkspace\", enabled = true, speed = 5, bezier = \"hard\", style = \"slide\" })' && ${pkgs.libnotify}/bin/notify-send animations horizontal"] } + ] + property var masterBarItems: [{ label: "position", sub: "barPosition" }, { label: "layout", sub: "barLayout" }, { label: "mode", sub: "barMode" }, { label: "look", sub: "barLook" }] + property var masterBarPositionItems: [{ label: "top", barPos: "top" }, { label: "bottom", barPos: "bottom" }] + property var masterBarLayoutItems: [{ label: "minimal", barLyt: "minimal" }, { label: "full", barLyt: "full" }] + property var masterBarModeItems: [{ label: "performance", centerLyt: "performance" }, { label: "default", centerLyt: "default" }] + property var masterBarLookItems: [{ label: "float", barLook: "float" }, { label: "fill", barLook: "fill" }] + property var masterWpItems: [] + property string masterWpBuf: "" + property var masterRcdOutItems: [] + property string masterRcdOutBuf: "" + property var masterPwItems: [ + { label: "lock", cmd: [""] }, + { label: "logout", cmd: ["hyprctl", "dispatch", "hl.dsp.exit()"] }, + { label: "reboot", cmd: ["systemctl", "reboot"] }, + { label: "shutdown", cmd: ["systemctl", "poweroff"] } + ] + + function rcdItems() { + return recProc.running + ? [{ label: "stop", rcdStop: true }] + : [{ label: "start", sub: "rcdOutput" }] + } + + function masterItemsForLevel(l) { + let lookup = { sys: masterSysItems, sts: masterStsItems, animations: masterAnimationsItems, bar: masterBarItems, barPosition: masterBarPositionItems, barLayout: masterBarLayoutItems, barMode: masterBarModeItems, barLook: masterBarLookItems, wallpapers: masterWpItems, pw: masterPwItems, rcd: rcdItems(), rcdOutput: masterRcdOutItems } + return lookup[l] ?? masterRootItems + } + + function masterRefilter(q) { + masterFiltered = q === "" ? masterCurrent : masterCurrent.filter(i => i.label.toLowerCase().includes(q.toLowerCase())) + let max = masterFiltered.length - 1 + if (masterSelected > max) masterSelected = Math.max(0, max) + } + + function masterGoTo(l) { + masterLevel = l + masterSelected = 0 + if (l === "wallpapers") { + masterWpItems = []; masterWpBuf = "" + masterCurrent = []; masterFiltered = [] + wpLsProc.running = true + } else if (l === "rcdOutput") { + masterRcdOutItems = []; masterRcdOutBuf = "" + masterCurrent = []; masterFiltered = [] + rcdMonProc.running = true + } else { + masterCurrent = masterItemsForLevel(l) + masterFiltered = masterCurrent + } + } + + function masterOpen() { + if (!root.visible) { autoHideBar = true; root.visible = true } + else autoHideBar = false + masterStack = [] + masterGoTo("root") + activeMode = "master" + } + + function masterClose() { + activeMode = "none" + if (autoHideBar) { root.visible = false; autoHideBar = false } + } + + function masterBack() { + if (masterStack.length > 0) { + let prev = masterStack[masterStack.length - 1] + masterStack = masterStack.slice(0, -1) + masterLevel = prev + masterSelected = 0 + masterCurrent = masterItemsForLevel(prev) + masterFiltered = masterCurrent + } else { + masterClose() + } + } + + function masterAccept() { + let items = masterFiltered + let idx = masterSelected + if (items.length === 0 || idx < 0 || idx >= items.length) return + let item = items[idx] + + if (item.sub !== undefined) { + masterStack = masterStack.concat([masterLevel]) + masterGoTo(item.sub) + return + } + if (item.wp !== undefined) { + mProc.command = ["bash", "-c", "colors \"$HOME/.wallpapers/" + item.wp + "\""] + mProc.running = true + masterClose(); return + } + if (item.rcdOut !== undefined) { + recProc.command = ["bash", "-c", "mkdir -p \"$HOME/videos\" && exec ${pkgs.gpu-screen-recorder}/bin/gpu-screen-recorder -w " + item.rcdOut + " -f 60 -q ultra -k hevc -fm cfr -a default_output -o \"$HOME/videos/meow_$(date +%Y%m%d_%H%M%S).mp4\""] + recProc.running = true + mProc.command = ["${pkgs.libnotify}/bin/notify-send", "-t", "2000", "meow", "started on " + item.rcdOut] + mProc.running = true + masterClose(); return + } + if (item.rcdStop !== undefined) { + recProc.signal(2) + mProc.command = ["${pkgs.libnotify}/bin/notify-send", "-t", "2000", "meow", "saved"] + mProc.running = true + masterClose(); return + } + if (item.barPos !== undefined) { barSettings.position = item.barPos; masterClose(); return } + if (item.barLyt !== undefined) { barSettings.layout = item.barLyt; masterClose(); return } + if (item.barLook !== undefined) { barSettings.look = item.barLook; masterClose(); return } + if (item.centerLyt !== undefined) { barSettings.centerMode = item.centerLyt; masterClose(); return } + if (item.cmd !== undefined) { mProc.command = item.cmd; mProc.running = true } + masterClose() + } + + onActiveModeChanged: { + if (activeMode !== "none" && activeMode !== "calendar" && typeof barInput !== "undefined") { + barInput.text = "" + barInput.forceActiveFocus() + } + } + + WlrLayershell.keyboardFocus: activeMode !== "none" && activeMode !== "calendar" ? WlrLayershell.Exclusive : WlrLayershell.None + + anchors.top: position === "top" + anchors.bottom: position === "bottom" + + implicitWidth: look === "fill" ? (root.screen?.width ?? 1920) + : layout === "full" ? (root.screen?.width ?? 1920) - 12 + : 820 + implicitHeight: 22 + + margins.top: look === "fill" ? 0 : (position === "top" ? 6 : 0) + margins.bottom: look === "fill" ? 0 : (position === "bottom" ? 6 : 0) + + exclusiveZone: 22 + color: "transparent" + + IpcHandler { + target: "bar" + function toggle(): void { root.visible = !root.visible } + } + IpcHandler { + target: "menu" + function toggle(): void { + if (root.activeMode === "launcher") root.launcherClose() + else root.launcherOpen() + } + } + IpcHandler { + target: "master" + function toggle(): void { + if (root.activeMode === "master") root.masterClose() + else root.masterOpen() + } + } + IpcHandler { + target: "calendar" + function toggle(): void { + if (root.activeMode === "calendar") root.activeMode = "none" + else root.activeMode = "calendar" + } + } + IpcHandler { + target: "mic" + function toggle(): void { + micActProc.command = ["${pkgs.wireplumber}/bin/wpctl", "set-mute", "@DEFAULT_AUDIO_SOURCE@", "toggle"] + micActProc.running = true + } + } + + Connections { + target: Hyprland + function onFocusedWorkspaceChanged() { + if (root.activeMode !== "none") root.activeMode = "none" + } + } + + Process { + id: colorProc + command: ["sh", "-c", "cat $HOME/.colors/colors.json"] + running: true + stdout: SplitParser { + splitMarker: "" + onRead: data => { configRoot.colorBuf += data } + } + onRunningChanged: { + if (!running && configRoot.colorBuf !== "") { + try { + configRoot.colors = JSON.parse(configRoot.colorBuf) + } catch(e) { console.log("Failed to parse colors") } + configRoot.colorBuf = "" + } + } + } + + Process { id: launchProc; running: false } + Process { + id: mProc + running: false + onRunningChanged: if (!running) colorProc.running = true + } + Process { id: recProc; running: false } + + Process { + id: rcdMonProc + command: ["bash", "-c", "${pkgs.hyprland}/bin/hyprctl -j monitors | ${pkgs.jq}/bin/jq -r '.[].name'"] + running: false + stdout: SplitParser { + splitMarker: "" + onRead: data => { root.masterRcdOutBuf += data } + } + onRunningChanged: { + if (!running && root.masterRcdOutBuf !== "") { + let lines = root.masterRcdOutBuf.trim().split("\n").filter(l => l.length > 0) + lines.push("portal") + root.masterRcdOutItems = lines.map(l => ({ label: l, rcdOut: l })) + root.masterRcdOutBuf = "" + if (root.activeMode === "master" && root.masterLevel === "rcdOutput") { + root.masterCurrent = root.masterRcdOutItems + root.masterFiltered = root.masterRcdOutItems + } + } + } + } + + Process { + id: wpLsProc + command: ["bash", "-c", "ls $HOME/.wallpapers/"] + running: false + stdout: SplitParser { + splitMarker: "" + onRead: data => { root.masterWpBuf += data } + } + onRunningChanged: { + if (!running && root.masterWpBuf !== "") { + let lines = root.masterWpBuf.trim().split("\n").filter(l => l.length > 0) + root.masterWpItems = lines.map(l => ({ label: l, wp: l })) + root.masterWpBuf = "" + if (root.activeMode === "master" && root.masterLevel === "wallpapers") { + root.masterCurrent = root.masterWpItems + root.masterFiltered = root.masterWpItems + } + } + } + } + + Timer { + interval: 2000; running: true; repeat: true; triggeredOnStart: true + onTriggered: { + if (barSettings.centerMode === "performance" && !sysProc.running) sysProc.running = true + if (!micProc.running) micProc.running = true + } + } + + Process { + id: sysProc + command: ["sh", "-c", "echo \"cpu $(grep 'cpu ' /proc/stat | awk '{print int(($2+$4)*100/($2+$4+$5))}')% | mem $(free | awk '/Mem:/ {print int($3/$2*100)}')%\""] + running: false + stdout: SplitParser { + onRead: data => { root.sysStats = data.trim() } + } + } + + Process { + id: micProc + command: ["sh", "-c", "${pkgs.wireplumber}/bin/wpctl get-volume @DEFAULT_AUDIO_SOURCE@ | awk '{print ($3==\"[MUTED]\"?\"󰍭\":\"󰍬\")}'"] + running: false + stdout: SplitParser { + onRead: data => { root.micState = data.trim() } + } + } + + Process { + id: micActProc + running: false + onRunningChanged: if (!running) micProc.running = true + } + + FontMetrics { + id: fm + font.family: "JetBrainsMono Nerd Font" + font.pixelSize: 12 + font.weight: Font.Normal + } + + Rectangle { + anchors.fill: parent + color: configRoot.colors.special.background + + MText { + anchors.centerIn: parent + visible: root.activeMode === "none" || root.activeMode === "calendar" + text: barSettings.centerMode === "performance" ? root.sysStats : "" + color: configRoot.colors.special.foreground + } + + RowLayout { + anchors.fill: parent + spacing: 0 + + Row { + spacing: 0 + Layout.fillHeight: true + + Repeater { + model: 10 + + Item { + property int wsId: index + 1 + property var ws: Hyprland.workspaces?.values?.find(w => w.id === wsId) ?? null + property bool isActive: Hyprland.focusedWorkspace?.id === wsId + property bool isUrgent: ws?.urgent ?? false + property bool hovered: harea.containsMouse + property string kanji: (["一","二","三","四","五","六","七","八","九","十"])[index] + + visible: ws !== null || isActive + width: visible ? Math.round(fm.advanceWidth(kanji)) + 16 : 0 + height: parent.height + + Rectangle { + anchors.fill: parent + color: parent.isUrgent ? configRoot.colors.colors.color1 + : parent.isActive ? configRoot.colors.special.foreground + : parent.hovered ? configRoot.colors.colors.color8 + : "transparent" + } + MText { + anchors.centerIn: parent + color: parent.isUrgent ? configRoot.colors.special.background + : parent.isActive ? configRoot.colors.special.background + : parent.hovered ? configRoot.colors.special.foreground + : configRoot.colors.colors.color7 + text: parent.kanji + } + MouseArea { + id: harea + anchors.fill: parent + hoverEnabled: true + onClicked: Hyprland.dispatch('hl.dsp.focus({ workspace = "' + parent.wsId + '" })') + } + } + } + } + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + + RowLayout { + anchors.fill: parent + anchors.leftMargin: 10 + anchors.rightMargin: 10 + spacing: 6 + visible: root.activeMode === "launcher" || root.activeMode === "master" + + MText { + Layout.alignment: Qt.AlignVCenter + color: configRoot.colors.colors.color7 + text: root.activeMode === "launcher" ? ">" : root.masterStack.concat([root.masterLevel]).join(" >") + } + + TextInput { + id: barInput + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter + height: parent.height + verticalAlignment: TextInput.AlignVCenter + font.family: "JetBrainsMono Nerd Font" + font.pixelSize: 12 + color: configRoot.colors.special.foreground + focus: root.activeMode === "launcher" || root.activeMode === "master" + + onTextChanged: { + if (root.activeMode === "launcher") root.launcherRefilter(text) + else if (root.activeMode === "master") root.masterRefilter(text) + } + onAccepted: { + if (root.activeMode === "launcher") root.launcherAccept() + else if (root.activeMode === "master") root.masterAccept() + } + Keys.onPressed: (event) => { + if (event.key === Qt.Key_Escape) { + if (root.activeMode === "launcher") root.launcherClose() + else if (root.activeMode === "master") root.masterBack() + event.accepted = true + } else if (root.activeMode === "master") { + if (event.key === Qt.Key_Down) { + if (root.masterSelected < root.masterFiltered.length - 1) root.masterSelected++ + event.accepted = true + } else if (event.key === Qt.Key_Up) { + if (root.masterSelected > 0) root.masterSelected-- + event.accepted = true + } + } + } + } + + MText { + Layout.alignment: Qt.AlignVCenter + Layout.rightMargin: 4 + color: configRoot.colors.colors.color7 + visible: root.activeMode === "launcher" ? root.launcherTopApp !== null : (root.activeMode === "master" ? root.masterFiltered.length > 0 : false) + text: root.activeMode === "launcher" ? (root.launcherTopApp?.name ?? "") : (root.activeMode === "master" && root.masterSelected < root.masterFiltered.length ? (root.masterFiltered[root.masterSelected]?.label ?? "") : "") + } + } + } + + Item { + Layout.fillHeight: true + implicitWidth: 26 + + Row { + anchors.centerIn: parent + spacing: 2 + + Item { + width: 20 + height: 22 + + MText { + id: micText + anchors.centerIn: parent + text: root.micState + color: configRoot.colors.special.foreground + } + + MouseArea { + anchors.fill: parent + onClicked: { + micActProc.command = ["${pkgs.wireplumber}/bin/wpctl", "set-mute", "@DEFAULT_AUDIO_SOURCE@", "toggle"] + micActProc.running = true + } + } + } + } + } + + Item { + Layout.fillHeight: true + implicitWidth: clockText.implicitWidth + 20 + + Rectangle { + anchors.horizontalCenter: parent.left + width: 1; height: parent.height + color: configRoot.colors.colors.color8 + } + MText { + id: clockText + anchors.centerIn: parent + font.letterSpacing: 0.02 * 11 + color: configRoot.colors.special.foreground + text: Qt.formatDateTime(new Date(), "dd/MM | HH:mm:ss") + + Timer { + interval: 1000; running: true; repeat: true + onTriggered: clockText.text = Qt.formatDateTime(new Date(), "dd/MM | HH:mm:ss") + } + } + MouseArea { + anchors.fill: parent + onClicked: { + if (root.activeMode === "calendar") root.activeMode = "none" + else root.activeMode = "calendar" + } + } + } + } + } + } + + PanelWindow { + id: masterOverlay + visible: root.activeMode === "master" && root.masterFiltered.length > 0 + + screen: Quickshell.screens.find(s => s.name === "HDMI-A-1") ?? Quickshell.screens[0] + + anchors.top: root.position === "top" + anchors.bottom: root.position === "bottom" + anchors.left: true + anchors.right: true + + margins.top: root.position === "top" ? (root.look === "fill" ? 0 : 6) : 0 + margins.bottom: root.position === "bottom" ? (root.look === "fill" ? 0 : 6) : 0 + + implicitWidth: root.implicitWidth + implicitHeight: root.masterFiltered.length * (root.masterLevel === "wallpapers" ? 38 : 22) + + exclusiveZone: 0 + color: "transparent" + WlrLayershell.layer: WlrLayershell.Overlay + + MouseArea { + anchors.fill: parent + onClicked: root.masterClose() + } + + Rectangle { + width: root.implicitWidth + height: parent.height + anchors.horizontalCenter: parent.horizontalCenter + color: configRoot.colors.special.background + + Column { + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + + Repeater { + model: root.masterFiltered + + Rectangle { + width: parent.width + height: root.masterLevel === "wallpapers" ? 38 : 22 + color: root.masterSelected === index ? configRoot.colors.colors.color8 : "transparent" + + Image { + visible: root.masterLevel === "wallpapers" + anchors.left: parent.left + anchors.leftMargin: 8 + anchors.verticalCenter: parent.verticalCenter + width: 46; height: 26 + fillMode: Image.PreserveAspectCrop + asynchronous: true + source: visible ? "file:///home/cat/.wallpapers/" + modelData.wp : "" + } + + Rectangle { + visible: root.masterSelected === index + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + width: 2; height: root.masterLevel === "wallpapers" ? 22 : 12 + color: configRoot.colors.colors.color4 + } + + MText { + anchors.verticalCenter: parent.verticalCenter + x: root.masterLevel === "wallpapers" ? 64 : 14 + text: modelData?.label ?? "" + color: root.masterSelected === index ? configRoot.colors.special.foreground : configRoot.colors.colors.color7 + } + + MText { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 12 + visible: modelData?.sub !== undefined + text: "›" + color: root.masterSelected === index ? configRoot.colors.special.foreground : configRoot.colors.colors.color8 + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onEntered: root.masterSelected = index + onClicked: root.masterAccept() + } + } + } + } + } + } + + PanelWindow { + id: notifOverlay + visible: notifModel.count > 0 + + screen: Quickshell.screens.find(s => s.name === "HDMI-A-1") ?? Quickshell.screens[0] + + anchors.top: root.position === "top" + anchors.bottom: root.position === "bottom" + anchors.left: true + anchors.right: true + + margins.top: root.position === "top" ? (root.look === "fill" ? 0 : 6) : 0 + margins.bottom: root.position === "bottom" ? (root.look === "fill" ? 0 : 6) : 0 + + implicitWidth: Math.round(root.implicitWidth / 3) + implicitHeight: notifModel.count * 34 + + exclusiveZone: 0 + color: "transparent" + WlrLayershell.layer: WlrLayershell.Overlay + + Column { + anchors.horizontalCenter: parent.horizontalCenter + width: Math.round(root.implicitWidth / 3) + spacing: 0 + + Repeater { + model: notifModel + + Rectangle { + id: toastRect + width: Math.round(root.implicitWidth / 3) + height: 34 + color: configRoot.colors.special.background + + Rectangle { + visible: index > 0 + anchors.top: parent.top + width: parent.width; height: 1 + color: configRoot.colors.colors.color8 + } + + Rectangle { + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + width: 2; height: 18 + color: configRoot.colors.colors.color3 + } + + Column { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 12 + anchors.rightMargin: 10 + spacing: 2 + + MText { + width: parent.width + text: model.summary !== "" ? model.summary : model.app + font.pixelSize: 11 + font.weight: Font.Medium + color: configRoot.colors.special.foreground + elide: Text.ElideRight + } + + MText { + visible: model.body !== "" && model.summary !== "" + width: parent.width + text: model.body + font.pixelSize: 10 + color: configRoot.colors.colors.color7 + elide: Text.ElideRight + } + } + + Timer { + interval: model.timeout + running: true + repeat: false + onTriggered: root.removeNotif(model.nid) + } + + MouseArea { + anchors.fill: parent + onClicked: root.removeNotif(model.nid) + } + } + } + } + } + + PanelWindow { + id: calendarOverlay + visible: root.activeMode === "calendar" + + screen: Quickshell.screens.find(s => s.name === "HDMI-A-1") ?? Quickshell.screens[0] + + anchors.top: root.position === "top" + anchors.bottom: root.position === "bottom" + anchors.right: true + + margins.top: root.position === "top" ? (root.look === "fill" ? 0 : 6) : 0 + margins.bottom: root.position === "bottom" ? (root.look === "fill" ? 0 : 6) : 0 + margins.right: root.look === "fill" ? 0 : root.layout === "full" ? 6 : Math.round(((root.screen?.width ?? 1920) - 820) / 2) + + implicitWidth: 216 + implicitHeight: 186 + color: "transparent" + + WlrLayershell.layer: WlrLayershell.Overlay + WlrLayershell.keyboardFocus: visible ? WlrLayershell.Exclusive : WlrLayershell.None + + property int selectedDay: new Date().getDate() + property int viewYear: new Date().getFullYear() + property int viewMonth: new Date().getMonth() + + property var days: { + let today = new Date() + let first = new Date(viewYear, viewMonth, 1).getDay() + let total = new Date(viewYear, viewMonth + 1, 0).getDate() + let ptotal = new Date(viewYear, viewMonth, 0).getDate() + let res = [] + for (let i = first - 1; i >= 0; i--) { + res.push({ d: ptotal - i, cur: false, today: false, monthOffset: -1 }) + } + for (let i = 1; i <= total; i++) { + let isToday = (i === today.getDate() && viewMonth === today.getMonth() && viewYear === today.getFullYear()) + res.push({ d: i, cur: true, today: isToday, monthOffset: 0 }) + } + let n = 42 - res.length + for (let i = 1; i <= n; i++) { + res.push({ d: i, cur: false, today: false, monthOffset: 1 }) + } + return res + } + + property string title: { + let months = ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"] + return months[viewMonth] + " " + viewYear + } + + function prevMonth() { + if (viewMonth === 0) { viewMonth = 11; viewYear-- } + else viewMonth-- + } + + function nextMonth() { + if (viewMonth === 11) { viewMonth = 0; viewYear++ } + else viewMonth++ + } + + onVisibleChanged: { + if (visible) { + let d = new Date() + viewYear = d.getFullYear() + viewMonth = d.getMonth() + selectedDay = d.getDate() + calendarBox.forceActiveFocus() + } + } + + Rectangle { + id: calendarBox + anchors.fill: parent + color: configRoot.colors.special.background + border.color: configRoot.colors.colors.color8 + border.width: 1 + focus: true + + Keys.onPressed: (event) => { + if (event.key === Qt.Key_Escape) { + root.activeMode = "none" + event.accepted = true + } + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: 10 + spacing: 8 + + RowLayout { + Layout.fillWidth: true + + MText { + text: calendarOverlay.title + color: configRoot.colors.special.foreground + } + + Item { Layout.fillWidth: true } + + Row { + spacing: 12 + + MText { + text: "<" + color: prevMouse.containsMouse ? configRoot.colors.special.foreground : configRoot.colors.colors.color7 + MouseArea { + id: prevMouse + anchors.fill: parent + hoverEnabled: true + onClicked: calendarOverlay.prevMonth() + } + } + + MText { + text: ">" + color: nextMouse.containsMouse ? configRoot.colors.special.foreground : configRoot.colors.colors.color7 + MouseArea { + id: nextMouse + anchors.fill: parent + hoverEnabled: true + onClicked: calendarOverlay.nextMonth() + } + } + } + } + + Grid { + columns: 7 + spacing: 4 + Layout.alignment: Qt.AlignHCenter + + Repeater { + model: ["s", "m", "t", "w", "t", "f", "s"] + MText { + width: 22; height: 14 + horizontalAlignment: Text.AlignHCenter + text: modelData + color: configRoot.colors.colors.color4 + } + } + } + + Grid { + columns: 7 + spacing: 4 + Layout.alignment: Qt.AlignHCenter + + Repeater { + model: calendarOverlay.days + + Rectangle { + width: 22; height: 22 + property bool isHovered: dayMouse.containsMouse + + color: modelData.today ? configRoot.colors.special.foreground : (isHovered ? configRoot.colors.colors.color8 : "transparent") + + MText { + anchors.centerIn: parent + text: modelData.d + color: modelData.today ? configRoot.colors.special.background + : (isHovered ? configRoot.colors.special.foreground + : (modelData.cur ? configRoot.colors.special.foreground : configRoot.colors.colors.color8)) + } + + MouseArea { + id: dayMouse + anchors.fill: parent + hoverEnabled: true + } + } + } + } + } + } + } + } + ''; +} diff --git a/nixos/modules/vi.nix b/nixos/modules/vi.nix new file mode 100644 index 0000000..293f44b --- /dev/null +++ b/nixos/modules/vi.nix @@ -0,0 +1,147 @@ +{ config, pkgs, ... }: + +{ + programs.neovim = { + enable = true; + defaultEditor = true; + viAlias = true; + vimAlias = true; + withRuby = false; + withPython3 = false; + + extraPackages = with pkgs; [ + ripgrep + ]; + + plugins = with pkgs.vimPlugins; [ + lualine-nvim + telescope-nvim + plenary-nvim + nvim-web-devicons + neo-tree-nvim + nui-nvim + alpha-nvim + ]; + + initLua = '' + vim.opt.number = true + vim.opt.relativenumber = false + vim.opt.numberwidth = 4 + vim.opt.statuscolumn = "%l %s" + vim.opt.tabstop = 2 + vim.opt.softtabstop = 2 + vim.opt.shiftwidth = 2 + vim.opt.expandtab = true + vim.opt.wrap = false + vim.opt.ignorecase = true + vim.opt.smartcase = true + vim.opt.hlsearch = false + vim.opt.termguicolors = false + vim.opt.signcolumn = "yes" + vim.opt.scrolloff = 8 + vim.opt.showmode = false + vim.opt.timeoutlen = 300 + vim.opt.updatetime = 250 + vim.opt.foldcolumn = "0" + vim.opt.directory = vim.fn.stdpath("state") .. "/swap//" + + vim.g.mapleader = " " + vim.g.maplocalleader = " " + + vim.keymap.set({"n", "i"}, "", "write", {desc = "save file"}) + vim.keymap.set("n", "", "quit", {desc = "quit neovim"}) + vim.keymap.set("n", "", "nohlsearch", {desc = "clear search highlight"}) + vim.keymap.set({"n", "x"}, "gy", '"+y', {desc = "copy to clipboard"}) + vim.keymap.set({"n", "x"}, "gp", '"+p', {desc = "paste from clipboard"}) + vim.keymap.set("n", "", "u", {desc = "undo"}) + vim.keymap.set("i", "", "u", {desc = "undo"}) + vim.keymap.set("n", "", "", {desc = "redo"}) + vim.keymap.set("i", "", "", {desc = "redo"}) + vim.keymap.set({"n", "i"}, "", "ggVG", {desc = "select all"}) + + vim.keymap.set("n", "", "Telescope current_buffer_fuzzy_find", {desc = "search buffer"}) + + vim.keymap.set("n", "ff", "Telescope find_files", {desc = "find files"}) + vim.keymap.set("n", "fg", "Telescope live_grep", {desc = "text search"}) + vim.keymap.set("n", "fb", "Telescope buffers", {desc = "find buffers"}) + vim.keymap.set("n", "", "Neotree toggle", {desc = "toggle file explorer"}) + + vim.keymap.set("n", "", "h", {desc = "move left"}) + vim.keymap.set("n", "", "j", {desc = "move down"}) + vim.keymap.set("n", "", "k", {desc = "move up"}) + vim.keymap.set("n", "", "l", {desc = "move right"}) + vim.keymap.set("n", "", "vsplit", {desc = "vertical split"}) + vim.keymap.set("n", "", "split", {desc = "horizontal split"}) + vim.keymap.set("n", "", "close", {desc = "close split"}) + + vim.cmd.colorscheme("default") + vim.opt.matchpairs = "" + vim.api.nvim_set_hl(0, "MatchParen", {}) + vim.cmd("highlight clear MatchParen") + vim.cmd("highlight MatchParen guifg=NONE guibg=NONE gui=NONE") + + require("lualine").setup({ + options = { + icons_enabled = true, + theme = "auto", + component_separators = { left = "", right = "" }, + section_separators = { left = "", right = "" }, + }, + }) + + require("telescope").setup({ + defaults = { + file_ignore_patterns = { "node_modules", ".git", "%.lock" }, + layout_strategy = "horizontal", + layout_config = { horizontal = { preview_width = 0.5 } }, + }, + }) + + require("neo-tree").setup({ + window = { + position = "right", + width = 30, + mappings = { + ["l"] = "open", + ["h"] = "close_node", + [""] = "open", + [""] = "revert_preview", + }, + }, + filesystem = { + filtered_items = { + visible = false, + hide_dotfiles = false, + hide_gitignored = false, + hide_by_name = { ".git", ".DS_Store", "thumbs.db" }, + }, + follow_current_file = { enabled = true }, + }, + }) + + local alpha = require("alpha") + local dashboard = require("alpha.themes.dashboard") + + dashboard.section.header.val = { + " ⠀⠀⠀⢀⡴⠲⣄⠀⠀⢀⡶⠲⡄⠀⣀⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", + " ⣀⣀⣀⣾⠁⠀⠹⠿⠟⠟⠀⠀⠙⣛⣉⡻⠿⠋⣿⣷⢦⣄⠀⠀⠀⠀⠀⠀", + " ⠭⠭⣽⠇⠀⠶⠀⢴⣦⠀⠶⠆⠸⠯⠭⠄⠀⠀⠀⠀⠀⠙⢧⡀⠀⢀⣤⣤", + "⠀⠀ ⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢷⣤⣾⣻⡟", + " ⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣧⠽⠋⠀", + " ⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⠀⠀⠀⠀", + " ⠀⠀⢷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡟⠀⠀⠀⠀", + "⠀ ⠀⠈⠳⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⠟⠀⠀⠀⠀⠀", + "⠀⠀ ⠀⠀⠉⠿⠟⠛⠛⠻⠾⠛⠛⠛⠛⠻⠟⠛⠛⠻⠾⠃⠀⠀⠀⠀⠀⠀", + } + + dashboard.section.buttons.val = { + dashboard.button("f", " > find file", "Telescope find_files"), + dashboard.button("n", " > new file", "enew"), + dashboard.button("r", " > recent files", "Telescope oldfiles"), + dashboard.button("q", " > quit", "qa"), + } + + alpha.setup(dashboard.opts) + ''; + }; +} diff --git a/nixos/modules/wm.nix b/nixos/modules/wm.nix new file mode 100644 index 0000000..3d9314a --- /dev/null +++ b/nixos/modules/wm.nix @@ -0,0 +1,157 @@ +{ pkgs, ... }: + +{ + xdg.configFile."hypr/hyprland.lua".force = true; + + wayland.windowManager.hyprland = { + enable = true; + configType = "lua"; + + extraConfig = '' + local hl = hl + local dsp = hl.dsp + local bind = hl.bind + local config = hl.config + local curve = hl.curve + local animation = hl.animation + local exec = dsp.exec_cmd + local focus = dsp.focus + local window = dsp.window + local workspace = dsp.workspace + + hl.monitor({ output = "HDMI-A-1", mode = "1920x1080@200", position = "0x0", scale = 1 }) + hl.monitor({ output = "DP-1", mode = "1920x1080@144", position = "-1080x-330", scale = 1, transform = 3 }) + + local mod = "SUPER" + local terminal = "kitty" + local browser = "helium" + + hl.on("hyprland.start", function () + hl.exec_cmd("systemctl --user start hyprpolkitagent") + hl.exec_cmd("bash -c 'awww-daemon & sleep 0.5 && awww clear --outputs DP-1'") + hl.exec_cmd("wl-paste --type text --watch cliphist store") + hl.exec_cmd("wl-paste --type image --watch cliphist store") + hl.exec_cmd("quickshell -p ~/.config/quickshell/shell.qml") + end) + + config({ + general = { + gaps_in = 2.5, + gaps_out = 5, + border_size = 1, + resize_on_border = false, + col = { active_border = "rgba(ffffffff)" }, + allow_tearing = false, + layout = "dwindle", + }, + }) + + config({ + decoration = { + rounding = 0, + rounding_power = 0, + active_opacity = 1.0, + inactive_opacity = 1.0, + shadow = { + enabled = true, + range = 4, + render_power = 3, + color = "rgba(1a1a1aee)", + }, + blur = { + enabled = true, + size = 3, + passes = 3, + vibrancy = 0, + }, + }, + }) + + config({ + input = { + kb_layout = "us", + follow_mouse = 1, + sensitivity = 0, + force_no_accel = false, + touchpad = { natural_scroll = false }, + }, + }) + + config({ + misc = { + force_default_wallpaper = 0, + disable_hyprland_logo = true, + disable_splash_rendering = true, + initial_workspace_tracking = true, + }, + }) + + config({ + dwindle = { + preserve_split = true, + }, + }) + + curve("easeOutQuint", { type = "bezier", points = { {0.20, 1}, {0.30, 1} } }) + curve("easeInOutCubic", { type = "bezier", points = { {0.65, 0.05}, {0.35, 1} } }) + curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } }) + curve("almostLinear", { type = "bezier", points = { {0.5, 0.5}, {0.75, 1} } }) + curve("quick", { type = "bezier", points = { {0.15, 0}, {0.1, 1} } }) + curve("hard", { type = "bezier", points = { {0, 1}, {0, 1} } }) + animation({ leaf = "global", enabled = true, speed = 5, bezier = "default" }) + animation({ leaf = "border", enabled = true, speed = 2.5, bezier = "easeOutQuint" }) + animation({ leaf = "windows", enabled = true, speed = 2.5, bezier = "easeOutQuint" }) + animation({ leaf = "windowsIn", enabled = true, speed = 2, bezier = "easeOutQuint", style = "popin 90%" }) + animation({ leaf = "windowsOut", enabled = true, speed = 1, bezier = "linear", style = "popin 90%" }) + animation({ leaf = "fadeIn", enabled = true, speed = 1, bezier = "almostLinear" }) + animation({ leaf = "fadeOut", enabled = true, speed = 1, bezier = "almostLinear" }) + animation({ leaf = "fade", enabled = true, speed = 1.5, bezier = "quick" }) + animation({ leaf = "layers", enabled = true, speed = 2, bezier = "easeOutQuint" }) + animation({ leaf = "layersIn", enabled = true, speed = 2, bezier = "easeOutQuint", style = "fade" }) + animation({ leaf = "layersOut", enabled = true, speed = 1, bezier = "linear", style = "fade" }) + animation({ leaf = "workspaces", enabled = true, speed = 5, bezier = "hard", style = "slidevert" }) + animation({ leaf = "specialWorkspace", enabled = true, speed = 5, bezier = "hard", style = "slidevert" }) + + hl.window_rule({ + match = { initial_class = "^(imv|mpv)$" }, + float = true, + center = true, + size = "600 600", + }) + + bind(mod .. " + Q", exec(terminal)) + bind(mod .. " + R", exec("quickshell ipc call menu toggle")) + bind(mod .. " + T", exec("quickshell ipc call master toggle")) + bind(mod .. " + W", exec("quickshell ipc call bar toggle")) + bind(mod .. " + X", exec("quickshell ipc call mic toggle")) + bind(mod .. " + B", exec(browser)) + bind(mod .. " + C", window.close()) + bind(mod .. " + V", window.float({ action = "toggle" })) + bind(mod .. " + F", window.fullscreen({ mode = 0 })) + bind(mod .. " + Tab", focus({ workspace = "m+1" })) + bind("ALT + S", exec('hyprshot -o .pictures/screenshots/ -f "$(date +%y-%m-%d_%H-%M-%S).png" -s -m region')) + + bind(mod .. " + left", focus({ direction = "left" })) + bind(mod .. " + right", focus({ direction = "right" })) + bind(mod .. " + up", focus({ direction = "up" })) + bind(mod .. " + down", focus({ direction = "down" })) + + bind("SHIFT + left", window.move({ direction = "left" })) + bind("SHIFT + right", window.move({ direction = "right" })) + bind("SHIFT + up", window.move({ direction = "up" })) + bind("SHIFT + down", window.move({ direction = "down" })) + + for i = 1, 10 do + local key = (i == 10) and "0" or tostring(i) + bind(mod .. " + " .. key, focus({ workspace = i })) + bind(mod .. " + SHIFT + " .. key, window.move({ workspace = i })) + end + + bind(mod .. " + S", workspace.toggle_special("magic")) + bind(mod .. " + SHIFT + " .. "S", window.move({ workspace = "special:magic" })) + + bind(mod .. " + mouse:272", window.drag(), { mouse = true }) + bind(mod .. " + mouse:273", window.resize(), { mouse = true }) + ''; + }; +} diff --git a/nixos/modules/yazi.nix b/nixos/modules/yazi.nix new file mode 100644 index 0000000..39c1402 --- /dev/null +++ b/nixos/modules/yazi.nix @@ -0,0 +1,50 @@ +{ + programs.yazi = { + enable = true; + + settings = { + mgr = { + ratio = [ 1 4 3 ]; + sort_by = "alphabetical"; + sort_dir_first = true; + linemode = "none"; + show_hidden = true; + show_symlink = true; + }; + }; + + theme = { + mgr = { + border_symbol = " "; + }; + indicator = { + padding = { open = "█"; close = "█"; }; + }; + mode = { + normal_main = { fg = "black"; bg = "blue"; bold = true; }; + normal_alt = { fg = "blue"; bg = "black"; }; + select_main = { fg = "black"; bg = "green"; bold = true; }; + select_alt = { fg = "green"; bg = "black"; }; + unset_main = { fg = "black"; bg = "yellow"; bold = true; }; + unset_alt = { fg = "yellow"; bg = "black"; }; + }; + status = { + sep_left = { open = ""; close = ""; }; + sep_right = { open = ""; close = ""; }; + }; + }; + + keymap = { + manager = { + prepend_keymap = [ + { on = [ "x" ]; run = "yank --cut"; } + { on = [ "y" ]; run = "yank"; } + { on = [ "p" ]; run = "paste"; } + { on = [ "d" ]; run = "remove"; } + { on = [ "r" ]; run = "rename"; } + { on = [ "c" ]; run = "create"; } + ]; + }; + }; + }; +} -- cgit v1.3.1