about summary refs log tree commit diff
path: root/alpine-river
diff options
context:
space:
mode:
authorvenomade <venomade@venomade.com>2025-02-27 17:06:42 +0000
committervenomade <venomade@venomade.com>2025-02-27 17:06:42 +0000
commit1cace80e4832a5d250ef4b7ccd687996563fb01b (patch)
treedb1ced91d1382ca3cabe37dbae00da51231d6a99 /alpine-river
Add old dotfiles
Diffstat (limited to 'alpine-river')
-rw-r--r--alpine-river/README.md45
-rw-r--r--alpine-river/build/emacs/.gitignore3
-rwxr-xr-xalpine-river/build/emacs/install-emacs.sh92
-rw-r--r--alpine-river/config/btop/.gitignore1
-rw-r--r--alpine-river/config/btop/btop.conf248
-rw-r--r--alpine-river/config/btop/themes/rose-pine.theme119
-rw-r--r--alpine-river/config/dunst/dunstrc42
-rw-r--r--alpine-river/config/fastfetch/config.jsonc49
-rw-r--r--alpine-river/config/fish/.gitignore1
-rw-r--r--alpine-river/config/fish/completions/fisher.fish7
-rw-r--r--alpine-river/config/fish/completions/fzf_configure_bindings.fish8
-rw-r--r--alpine-river/config/fish/completions/ya.fish52
-rw-r--r--alpine-river/config/fish/completions/yazi.fish9
-rw-r--r--alpine-river/config/fish/conf.d/fzf.fish28
-rw-r--r--alpine-river/config/fish/conf.d/rustup.fish1
-rw-r--r--alpine-river/config/fish/config.fish23
-rw-r--r--alpine-river/config/fish/fish_plugins3
-rw-r--r--alpine-river/config/fish/functions/_fzf_configure_bindings_help.fish43
-rw-r--r--alpine-river/config/fish/functions/_fzf_extract_var_info.fish15
-rw-r--r--alpine-river/config/fish/functions/_fzf_preview_changed_file.fish49
-rw-r--r--alpine-river/config/fish/functions/_fzf_preview_file.fish43
-rw-r--r--alpine-river/config/fish/functions/_fzf_report_diff_type.fish18
-rw-r--r--alpine-river/config/fish/functions/_fzf_report_file_type.fish6
-rw-r--r--alpine-river/config/fish/functions/_fzf_search_directory.fish33
-rw-r--r--alpine-river/config/fish/functions/_fzf_search_git_log.fish36
-rw-r--r--alpine-river/config/fish/functions/_fzf_search_git_status.fish41
-rw-r--r--alpine-river/config/fish/functions/_fzf_search_history.fish39
-rw-r--r--alpine-river/config/fish/functions/_fzf_search_processes.fish32
-rw-r--r--alpine-river/config/fish/functions/_fzf_search_variables.fish47
-rw-r--r--alpine-river/config/fish/functions/_fzf_wrapper.fish21
-rw-r--r--alpine-river/config/fish/functions/fisher.fish240
-rw-r--r--alpine-river/config/fish/functions/fzf_configure_bindings.fish46
-rw-r--r--alpine-river/config/fish/themes/Rosé Pine.theme41
-rw-r--r--alpine-river/config/foot/foot.ini34
-rw-r--r--alpine-river/config/fuzzel/fuzzel.ini22
-rw-r--r--alpine-river/config/gtk-3.0/gtk.css12
-rw-r--r--alpine-river/config/gtk-3.0/settings.ini5
-rw-r--r--alpine-river/config/gtk-4.0/gtk.css12
-rw-r--r--alpine-river/config/gtk-4.0/settings.ini6
-rw-r--r--alpine-river/config/kanata/config.kbd52
-rw-r--r--alpine-river/config/mpv/mpv.conf3
-rw-r--r--alpine-river/config/mpv/script-opts/uosc.conf237
-rw-r--r--alpine-river/config/mpv/scripts/thumbfast.lua951
-rw-r--r--alpine-river/config/nvim/.gitignore1
-rw-r--r--alpine-river/config/nvim/init.lua134
-rw-r--r--alpine-river/config/nvim/lua/config/cmp.lua30
-rw-r--r--alpine-river/config/nvim/lua/config/colemak.lua29
-rw-r--r--alpine-river/config/nvim/lua/config/lazy.lua35
-rw-r--r--alpine-river/config/nvim/lua/plugins.lua32
-rwxr-xr-xalpine-river/config/river/init200
-rwxr-xr-xalpine-river/config/river/theme19
-rw-r--r--alpine-river/config/swaylock/config48
-rw-r--r--alpine-river/config/waybar/config71
-rw-r--r--alpine-river/config/waybar/rose-pine.css23
-rw-r--r--alpine-river/config/waybar/style.css98
-rw-r--r--alpine-river/config/yazi/keymap.toml96
-rw-r--r--alpine-river/config/yazi/rose-pine.tmTheme959
-rw-r--r--alpine-river/config/yazi/theme.toml153
-rw-r--r--alpine-river/config/yazi/yazi.toml6
-rwxr-xr-xalpine-river/local/bin/drybin0 -> 19959796 bytes
-rwxr-xr-xalpine-river/local/bin/kanatabin0 -> 2349208 bytes
-rwxr-xr-xalpine-river/local/bin/kewbin0 -> 713488 bytes
-rwxr-xr-xalpine-river/local/bin/take-slurpshot18
-rwxr-xr-xalpine-river/local/bin/yabin0 -> 3099296 bytes
-rwxr-xr-xalpine-river/local/bin/yazibin0 -> 14089936 bytes
-rw-r--r--alpine-river/profile17
-rw-r--r--alpine-river/screenshot.pngbin0 -> 2176077 bytes
-rw-r--r--alpine-river/tmux.conf76
-rw-r--r--alpine-river/world93
69 files changed, 4953 insertions, 0 deletions
diff --git a/alpine-river/README.md b/alpine-river/README.md
new file mode 100644
index 0000000..9942daa
--- /dev/null
+++ b/alpine-river/README.md
@@ -0,0 +1,45 @@
+# Venomade's dotfiles
+These are my personal dotfiles for [Alpine Linux](https://alpinelinux.org/)
+
+This repository contains submodules so clone with: `git clone git@github.com:venomade/dotfiles ~/.dotfiles --recurse-submodules`
+
+## Screenshot
+![dotfiles screenshot](https://raw.githubusercontent.com/venomade/dotfiles/refs/heads/master/screenshot.png "Dotfiles Screenshot")
+
+## Software
+A basic overview of the software I use:
+
+| **Component**    | **Program/Tool**                                                   |
+|------------------|--------------------------------------------------------------------|
+| OS               | [Alpine Linux](https://alpinelinux.org/)                           |
+| Window Manager   | [River](https://isaacfreund.com/software/river/)                   |
+| App Launcher     | [Fuzzel](https://codeberg.org/dnkl/fuzzel/)                        |
+| Audio            | [Pipewire](https://pipewire.org/)                                  |
+| Audio Mixer      | [ncpamixer](https://github.com/fulhax/ncpamixer)                   |
+| Browser          | [Firefox ESR](https://www.mozilla.org/en-GB/firefox/enterprise/)   |
+| Clipboard        | [wl-clipboard](https://github.com/bugaevc/wl-clipboard/)           |
+| Containers       | [Docker](https://www.docker.com/) & [Dry](https://moncho.github.io/dry/) |
+| File Manager     | [Yazi](https://github.com/sxyazi/yazi/)                            |
+| Font             | [Fantasque Sans](https://github.com/belluzj/fantasque-sans/)       |
+| Idle Daemon      | [swayidle](https://github.com/swaywm/swayidle/)                    |
+| Image Viewer     | [mpv --pause](https://mpv.io/)                                     |
+| Life Manager     | [Emacs](https://www.gnu.org/software/emacs/)                       |
+| Login Manager    | [TTY](https://rickroll.it/)                                        |
+| Multiplexer      | [TMUX](https://github.com/tmux/tmux/)                              |
+| Music Player     | [kew](https://github.com/ravachol/kew)                             |
+| Notifications    | [Dunst](https://dunst-project.org/)                                |
+| Screen Locker    | [swaylock](https://github.com/swaywm/swaylock/)                    |
+| Screen Record    | [wf-recorder](https://github.com/ammen99/wf-recorder/)             |
+| Screenshot       | [wayshot](https://git.sr.ht/~shinyzenith/wayshot/) & [slurp](https://github.com/emersion/slurp/) |
+| Shell            | [Fish](https://fishshell.com/)                                     |
+| Sync Client      | [rclone](https://rclone.org/)                                      |
+| SysInfo Viewer   | [fastfetch](https://github.com/fastfetch-cli/fastfetch/)           |
+| System Monitor   | [Btop](https://github.com/aristocratos/btop/)                      |
+| Terminal         | [Foot](https://codeberg.org/dnkl/foot/)                            |
+| Text Editor      | [Neovim](https://neovim.io/)                                       |
+| Video Player     | [mpv](https://mpv.io/)                                             |
+| Wallpaper Util   | [swaybg](https://github.com/swaywm/swaybg/)                        |
+
+
+## Packages
+A copy of my `/etc/apk/world` is in the [world](./world) file.
diff --git a/alpine-river/build/emacs/.gitignore b/alpine-river/build/emacs/.gitignore
new file mode 100644
index 0000000..7ec083a
--- /dev/null
+++ b/alpine-river/build/emacs/.gitignore
@@ -0,0 +1,3 @@
+emacs-*/
+*.tar.xz
+*.zip
diff --git a/alpine-river/build/emacs/install-emacs.sh b/alpine-river/build/emacs/install-emacs.sh
new file mode 100755
index 0000000..bbb6fe3
--- /dev/null
+++ b/alpine-river/build/emacs/install-emacs.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+
+### WARNING STILL DEBIAN, NOT ALPINE, WAIT FOR UPDATE
+echo "------------------------------------------------------------------------"
+echo "WARNING! THIS SCRIPT IS FOR DEBIAN, PRESS ENTER TO CONTINUE, C-c TO EXIT"
+echo "------------------------------------------------------------------------"
+read -p ""
+
+# Basic Dependencies
+sudo apt install -y \
+  git \
+  build-essential \
+  libgtk-3-dev \
+  libgnutls28-dev \
+  libtiff5-dev \
+  libgif-dev \
+  libjpeg-dev \
+  libpng-dev \
+  libxpm-dev \
+  libncurses-dev \
+  texinfo
+# Native JSON
+sudo apt install -y libjansson4 libjansson-dev
+# Native Compilation
+sudo apt install -y \
+  libgccjit0 \
+  libgccjit-11-dev \
+  gcc-11 \
+  g++-11
+# Images
+sudo apt install -y libmagickcore-dev libmagick++-dev
+# TreeSitter
+sudo apt install -y libtree-sitter-dev
+# GTK3
+sudo apt install -y libgtk-3-dev libwebkit2gtk-4.1-dev
+# VTerm
+sudo apt install -y cmake libtool-bin
+
+# Download Font
+# Install Font
+FONT="FantasqueSansMono"
+FONT_ARCHIVE="${FONT}.zip"
+FONT_DIRECTORY="$HOME/.local/share/fonts/${FONT}"
+
+if [ ! -f "$FONT_ARCHIVE" ]; then
+    # Download the archive
+    wget "https://github.com/ryanoasis/nerd-fonts/releases/download/v3.2.1/$FONT_ARCHIVE"
+fi
+
+if [ -d "$FONT_DIRECTORY" ]; then
+    echo "Directory $FONT_DIRECTORY already exists. Deleting it."
+    rm -rf "$FONT_DIRECTORY"
+fi
+
+mkdir -p "$FONT_DIRECTORY"
+unzip -o "$FONT_ARCHIVE" -d "$FONT_DIRECTORY"
+fc-cache -fv
+
+# Download Emacs
+# Define the version variable
+VERSION="29.4"
+ARCHIVE="emacs-${VERSION}.tar.xz"
+DIRECTORY="emacs-${VERSION}"
+
+if [ -f "$ARCHIVE" ]; then
+    echo "Archive $ARCHIVE already exists. Skipping download."
+else
+    wget "https://mirror.lyrahosting.com/gnu/emacs/$ARCHIVE"
+fi
+
+if [ -d "$DIRECTORY" ]; then
+    echo "Directory $DIRECTORY already exists. Deleting it."
+    #TODO FIX THIS DANGEROUS LINE
+    sudo rm -rf "$DIRECTORY"
+fi
+
+tar -xf "$ARCHIVE"
+
+#Build Emacs
+tar xvf emacs-*.tar.xz
+cd $(find . -maxdepth 1 -type d -name 'emacs-*' | head -n 1)
+export CC=/usr/bin/gcc-11 CXX=/usr/bin/gcc-11
+./autogen.sh
+mkdir build
+cd build
+
+CONFIGURE_ARGS="--with-dbus --with-gif --with-jpeg --with-png --with-rsvg --with-tiff --with-xft --with-xpm --with-gpm=no --with-imagemagick --with-json --with-xwidgets --with-x-toolkit=gtk3 --with-cairo --with-modules --with-native-compilation --with-tree-sitter --without-pop --with-pgtk"
+
+../configure $CONFIGURE_ARGS CFLAGS="-O2 -pipe -march=native"
+make -j $(($(nproc) - 1)) CFLAGS="-O2 -pipe -march=native"
+read -p "Press Enter to install Emacs, C-c if compilation failed"
+sudo make clean install -j $(($(nproc) - 1))
diff --git a/alpine-river/config/btop/.gitignore b/alpine-river/config/btop/.gitignore
new file mode 100644
index 0000000..76fc0ad
--- /dev/null
+++ b/alpine-river/config/btop/.gitignore
@@ -0,0 +1 @@
+btop.log
diff --git a/alpine-river/config/btop/btop.conf b/alpine-river/config/btop/btop.conf
new file mode 100644
index 0000000..45225ef
--- /dev/null
+++ b/alpine-river/config/btop/btop.conf
@@ -0,0 +1,248 @@
+#? Config file for btop v. 1.4.0
+
+#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes.
+#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes"
+color_theme = "/home/venomade/.config/btop/themes/rose-pine.theme"
+
+#* If the theme set background should be shown, set to False if you want terminal background transparency.
+theme_background = False
+
+#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false.
+truecolor = True
+
+#* Set to true to force tty mode regardless if a real tty has been detected or not.
+#* Will force 16-color mode and TTY theme, set all graph symbols to "tty" and swap out other non tty friendly symbols.
+force_tty = False
+
+#* Define presets for the layout of the boxes. Preset 0 is always all boxes shown with default settings. Max 9 presets.
+#* Format: "box_name:P:G,box_name:P:G" P=(0 or 1) for alternate positions, G=graph symbol to use for box.
+#* Use whitespace " " as separator between different presets.
+#* Example: "cpu:0:default,mem:0:tty,proc:1:default cpu:0:braille,proc:0:tty"
+presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"
+
+#* Set to True to enable "h,j,k,l,g,G" keys for directional control in lists.
+#* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift.
+vim_keys = True
+
+#* Rounded corners on boxes, is ignored if TTY mode is ON.
+rounded_corners = False
+
+#* Default symbols to use for graph creation, "braille", "block" or "tty".
+#* "braille" offers the highest resolution but might not be included in all fonts.
+#* "block" has half the resolution of braille but uses more common characters.
+#* "tty" uses only 3 different symbols but will work with most fonts and should work in a real TTY.
+#* Note that "tty" only has half the horizontal resolution of the other two, so will show a shorter historical view.
+graph_symbol = "braille"
+
+# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
+graph_symbol_cpu = "default"
+
+# Graph symbol to use for graphs in gpu box, "default", "braille", "block" or "tty".
+graph_symbol_gpu = "default"
+
+# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
+graph_symbol_mem = "default"
+
+# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
+graph_symbol_net = "default"
+
+# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
+graph_symbol_proc = "braille"
+
+#* Manually set which boxes to show. Available values are "cpu mem net proc" and "gpu0" through "gpu5", separate values with whitespace.
+shown_boxes = "cpu mem net proc"
+
+#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs.
+update_ms = 500
+
+#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu direct",
+#* "cpu lazy" sorts top process over time (easier to follow), "cpu direct" updates top process directly.
+proc_sorting = "cpu lazy"
+
+#* Reverse sorting order, True or False.
+proc_reversed = False
+
+#* Show processes as a tree.
+proc_tree = False
+
+#* Use the cpu graph colors in the process list.
+proc_colors = True
+
+#* Use a darkening gradient in the process list.
+proc_gradient = False
+
+#* If process cpu usage should be of the core it's running on or usage of the total available cpu power.
+proc_per_core = False
+
+#* Show process memory as bytes instead of percent.
+proc_mem_bytes = True
+
+#* Show cpu graph for each process.
+proc_cpu_graphs = True
+
+#* Use /proc/[pid]/smaps for memory information in the process info box (very slow but more accurate)
+proc_info_smaps = False
+
+#* Show proc box on left side of screen instead of right.
+proc_left = False
+
+#* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop).
+proc_filter_kernel = True
+
+#* In tree-view, always accumulate child process resources in the parent process.
+proc_aggregate = False
+
+#* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available.
+#* Select from a list of detected attributes from the options menu.
+cpu_graph_upper = "Auto"
+
+#* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available.
+#* Select from a list of detected attributes from the options menu.
+cpu_graph_lower = "Auto"
+
+#* If gpu info should be shown in the cpu box. Available values = "Auto", "On" and "Off".
+show_gpu_info = "Auto"
+
+#* Toggles if the lower CPU graph should be inverted.
+cpu_invert_lower = True
+
+#* Set to True to completely disable the lower CPU graph.
+cpu_single_graph = False
+
+#* Show cpu box at bottom of screen instead of top.
+cpu_bottom = False
+
+#* Shows the system uptime in the CPU box.
+show_uptime = True
+
+#* Show cpu temperature.
+check_temp = True
+
+#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors.
+cpu_sensor = "Auto"
+
+#* Show temperatures for cpu cores also if check_temp is True and sensors has been found.
+show_coretemp = True
+
+#* Set a custom mapping between core and coretemp, can be needed on certain cpus to get correct temperature for correct core.
+#* Use lm-sensors or similar to see which cores are reporting temperatures on your machine.
+#* Format "x:y" x=core with wrong temp, y=core with correct temp, use space as separator between multiple entries.
+#* Example: "4:0 5:1 6:3"
+cpu_core_map = ""
+
+#* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine".
+temp_scale = "celsius"
+
+#* Use base 10 for bits/bytes sizes, KB = 1000 instead of KiB = 1024.
+base_10_sizes = False
+
+#* Show CPU frequency.
+show_cpu_freq = True
+
+#* Draw a clock at top of screen, formatting according to strftime, empty string to disable.
+#* Special formatting: /host = hostname | /user = username | /uptime = system uptime
+clock_format = "%X"
+
+#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort.
+background_update = True
+
+#* Custom cpu model name, empty string to disable.
+custom_cpu_name = ""
+
+#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with whitespace " ".
+#* Begin line with "exclude=" to change to exclude filter, otherwise defaults to "most include" filter. Example: disks_filter="exclude=/boot /home/user".
+disks_filter = ""
+
+#* Show graphs instead of meters for memory values.
+mem_graphs = True
+
+#* Show mem box below net box instead of above.
+mem_below_net = False
+
+#* Count ZFS ARC in cached and available memory.
+zfs_arc_cached = True
+
+#* If swap memory should be shown in memory box.
+show_swap = False
+
+#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk.
+swap_disk = False
+
+#* If mem box should be split to also show disks info.
+show_disks = False
+
+#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar.
+only_physical = True
+
+#* Read disks list from /etc/fstab. This also disables only_physical.
+use_fstab = True
+
+#* Setting this to True will hide all datasets, and only show ZFS pools. (IO stats will be calculated per-pool)
+zfs_hide_datasets = False
+
+#* Set to true to show available disk space for privileged users.
+disk_free_priv = False
+
+#* Toggles if io activity % (disk busy time) should be shown in regular disk usage view.
+show_io_stat = True
+
+#* Toggles io mode for disks, showing big graphs for disk read/write speeds.
+io_mode = True
+
+#* Set to True to show combined read/write io graphs in io mode.
+io_graph_combined = True
+
+#* Set the top speed for the io graphs in MiB/s (100 by default), use format "mountpoint:speed" separate disks with whitespace " ".
+#* Example: "/mnt/media:100 /:20 /boot:1".
+io_graph_speeds = ""
+
+#* Set fixed values for network graphs in Mebibits. Is only used if net_auto is also set to False.
+net_download = 100
+
+net_upload = 100
+
+#* Use network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest.
+net_auto = True
+
+#* Sync the auto scaling for download and upload to whichever currently has the highest scale.
+net_sync = True
+
+#* Starts with the Network Interface specified here.
+net_iface = ""
+
+#* Show battery stats in top right if battery is present.
+show_battery = True
+
+#* Which battery to use if multiple are present. "Auto" for auto detection.
+selected_battery = "Auto"
+
+#* Show power stats of battery next to charge indicator.
+show_battery_watts = True
+
+#* Set loglevel for "~/.config/btop/btop.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG".
+#* The level set includes all lower levels, i.e. "DEBUG" will show all logging info.
+log_level = "WARNING"
+
+#* Measure PCIe throughput on NVIDIA cards, may impact performance on certain cards.
+nvml_measure_pcie_speeds = True
+
+#* Horizontally mirror the GPU graph.
+gpu_mirror_graph = True
+
+#* Custom gpu0 model name, empty string to disable.
+custom_gpu_name0 = ""
+
+#* Custom gpu1 model name, empty string to disable.
+custom_gpu_name1 = ""
+
+#* Custom gpu2 model name, empty string to disable.
+custom_gpu_name2 = ""
+
+#* Custom gpu3 model name, empty string to disable.
+custom_gpu_name3 = ""
+
+#* Custom gpu4 model name, empty string to disable.
+custom_gpu_name4 = ""
+
+#* Custom gpu5 model name, empty string to disable.
+custom_gpu_name5 = ""
diff --git a/alpine-river/config/btop/themes/rose-pine.theme b/alpine-river/config/btop/themes/rose-pine.theme
new file mode 100644
index 0000000..b045441
--- /dev/null
+++ b/alpine-river/config/btop/themes/rose-pine.theme
@@ -0,0 +1,119 @@
+# Main background, empty for terminal default, need to be empty if you want transparent background
+theme[main_bg]="#191724"
+# Base
+
+# Main text color
+theme[main_fg]="#e0def4"
+# Text
+
+# Title color for boxes
+theme[title]="#908caa"
+# Subtle
+
+# Highlight color for keyboard shortcuts
+theme[hi_fg]="#e0def4"
+# Text
+
+# Background color of selected item in processes box
+theme[selected_bg]="#524f67"
+# HL High
+
+# Foreground color of selected item in processes box
+theme[selected_fg]="#f6c177"
+# Gold
+
+# Color of inactive/disabled text
+theme[inactive_fg]="#403d52"
+# HL Med
+
+# Color of text appearing on top of graphs, i.e uptime and current network graph scaling
+theme[graph_text]="#9ccfd8"
+# Foam
+
+# Background color of the percentage meters
+theme[meter_bg]="#9ccfd8"
+# Foam
+
+# Misc colors for processes box including mini cpu graphs, details memory graph and details status text
+theme[proc_misc]="#c4a7e7"
+# Iris
+
+# Cpu box outline color
+theme[cpu_box]="#ebbcba"
+# Rose
+
+# Memory/disks box outline color
+theme[mem_box]="#31748f"
+# Pine
+
+# Net up/down box outline color
+theme[net_box]="#c4a7e7"
+# Iris
+
+# Processes box outline color
+theme[proc_box]="#eb6f92"
+# Love
+
+# Box divider line and small boxes line color
+theme[div_line]="#6e6a86"
+# Muted
+
+# Temperature graph colors
+theme[temp_start]="#ebbcba"
+# Rose
+theme[temp_mid]="#f6c177"
+# Gold
+theme[temp_end]="#eb6f92"
+# Love
+
+# CPU graph colors
+theme[cpu_start]="#f6c177"
+# Gold
+theme[cpu_mid]="#ebbcba"
+# Rose
+theme[cpu_end]="#eb6f92"
+# Love
+
+# Mem/Disk free meter
+# all love
+theme[free_start]="#eb6f92"
+theme[free_mid]="#eb6f92"
+theme[free_end]="#eb6f92"
+
+# Mem/Disk cached meter
+# all iris
+theme[cached_start]="#c4a7e7"
+theme[cached_mid]="#c4a7e7"
+theme[cached_end]="#c4a7e7"
+
+# Mem/Disk available meter
+# all pine
+theme[available_start]="#31748f"
+theme[available_mid]="#31748f"
+theme[available_end]="#31748f"
+
+# Mem/Disk used meter
+# all rose
+theme[used_start]="#ebbcba"
+theme[used_mid]="#ebbcba"
+theme[used_end]="#ebbcba"
+
+# Download graph colors
+# Pine for start, foam for the rest
+theme[download_start]="#31748f"
+theme[download_mid]="#9ccfd8"
+theme[download_end]="#9ccfd8"
+
+# Upload graph colors
+theme[upload_start]="#ebbcba"
+# Rose for start
+theme[upload_mid]="#eb6f92"
+# Love for mid and end
+theme[upload_end]="#eb6f92"
+
+# Process box color gradient for threads, mem and cpu usage
+theme[process_start]="#31748f"
+# Pine
+theme[process_mid]="#9ccfd8"
+# Foam for mid and end
+theme[process_end]="#9ccfd8"
diff --git a/alpine-river/config/dunst/dunstrc b/alpine-river/config/dunst/dunstrc
new file mode 100644
index 0000000..225d5f8
--- /dev/null
+++ b/alpine-river/config/dunst/dunstrc
@@ -0,0 +1,42 @@
+[global]
+    width = (200,600)
+    offset = 0x24
+
+    progress_bar_min_width = 380
+    progress_bar_max_width = 380
+    progress_bar_corner_radius = 0
+
+    padding = 10
+    horizontal_padding = 10
+    frame_width = 2
+    gap_size = 3
+    origin = "top-center"
+    font = "FantasqueSansMono 12"
+
+    icon_theme = "rose-pine-icons"
+    enable_recursive_icon_lookup = true
+    corner_radius = 0
+
+    background = "#191724"
+    foreground = "#e0def4"
+
+[urgency_low]
+    background = "#26273d"
+    highlight = "#31748f"
+    frame_color = "#31748f"
+    default_icon = "dialog-information"
+    format = "<b><span foreground='#31748f'>%s</span></b>\n%b"
+
+[urgency_normal]
+    background = "#191724"
+    highlight = "#f6c177"
+    frame_color = "#ebbcba"
+    default_icon = "dialog-warning"
+    format = "<b><span foreground='#e0def4'>%s</span></b>\n%b"
+
+[urgency_critical]
+    background = "#eb6f92"
+    highlight = "#35263d"
+    frame_color = "#35263d"
+    default_icon = "dialog-error"
+    format = "<b><span foreground='#36263d'>%s</span></b>\n%b"
diff --git a/alpine-river/config/fastfetch/config.jsonc b/alpine-river/config/fastfetch/config.jsonc
new file mode 100644
index 0000000..746244c
--- /dev/null
+++ b/alpine-river/config/fastfetch/config.jsonc
@@ -0,0 +1,49 @@
+{
+    "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
+    "logo": {
+        "type": "small"
+    },
+    "display": {
+        "constants": [
+            //"██ "
+	    "> "
+        ]
+    },
+    "modules": [
+        {
+            "key": "{$1}Distro",
+            "keyColor": "38;5;210",
+            "type": "os"
+        },
+        {
+            "key": "{$1}Kernel",
+            "keyColor": "38;5;84",
+            "type": "kernel"
+        },
+        //{
+        //    "key": "{$1}Shell",
+        //    "keyColor": "38;5;147",
+        //    "type": "shell"
+        //},
+        {
+            "key": "{$1}Packages",
+            "keyColor": "38;5;200",
+            "type": "packages"
+        },
+        {
+            "key": "{$1}WM",
+            "keyColor": "38;5;44",
+            "type": "wm"
+        },
+        {
+            "key": "{$1}CPU",
+            "keyColor": "38;5;75",
+            "type": "cpu"
+        },
+        {
+            "key": "{$1}Memory",
+            "keyColor": "38;5;123",
+            "type": "memory"
+        }
+    ]
+}
diff --git a/alpine-river/config/fish/.gitignore b/alpine-river/config/fish/.gitignore
new file mode 100644
index 0000000..23efee9
--- /dev/null
+++ b/alpine-river/config/fish/.gitignore
@@ -0,0 +1 @@
+fish_variables
diff --git a/alpine-river/config/fish/completions/fisher.fish b/alpine-river/config/fish/completions/fisher.fish
new file mode 100644
index 0000000..6d23ce4
--- /dev/null
+++ b/alpine-river/config/fish/completions/fisher.fish
@@ -0,0 +1,7 @@
+complete --command fisher --exclusive --long help --description "Print help"
+complete --command fisher --exclusive --long version --description "Print version"
+complete --command fisher --exclusive --condition __fish_use_subcommand --arguments install --description "Install plugins"
+complete --command fisher --exclusive --condition __fish_use_subcommand --arguments update --description "Update installed plugins"
+complete --command fisher --exclusive --condition __fish_use_subcommand --arguments remove --description "Remove installed plugins"
+complete --command fisher --exclusive --condition __fish_use_subcommand --arguments list --description "List installed plugins matching regex"
+complete --command fisher --exclusive --condition "__fish_seen_subcommand_from update remove" --arguments "(fisher list)"
diff --git a/alpine-river/config/fish/completions/fzf_configure_bindings.fish b/alpine-river/config/fish/completions/fzf_configure_bindings.fish
new file mode 100644
index 0000000..b38ef92
--- /dev/null
+++ b/alpine-river/config/fish/completions/fzf_configure_bindings.fish
@@ -0,0 +1,8 @@
+complete fzf_configure_bindings --no-files
+complete fzf_configure_bindings --long help --short h --description "Print help" --condition "not __fish_seen_argument --help -h"
+complete fzf_configure_bindings --long directory --description "Change the key binding for Search Directory" --condition "not __fish_seen_argument --directory"
+complete fzf_configure_bindings --long git_log --description "Change the key binding for Search Git Log" --condition "not __fish_seen_argument --git_log"
+complete fzf_configure_bindings --long git_status --description "Change the key binding for Search Git Status" --condition "not __fish_seen_argument --git_status"
+complete fzf_configure_bindings --long history --description "Change the key binding for Search History" --condition "not __fish_seen_argument --history"
+complete fzf_configure_bindings --long processes --description "Change the key binding for Search Processes" --condition "not __fish_seen_argument --processes"
+complete fzf_configure_bindings --long variables --description "Change the key binding for Search Variables" --condition "not __fish_seen_argument --variables"
diff --git a/alpine-river/config/fish/completions/ya.fish b/alpine-river/config/fish/completions/ya.fish
new file mode 100644
index 0000000..2c869c5
--- /dev/null
+++ b/alpine-river/config/fish/completions/ya.fish
@@ -0,0 +1,52 @@
+# Print an optspec for argparse to handle cmd's options that are independent of any subcommand.
+function __fish_ya_global_optspecs
+	string join \n V/version h/help
+end
+
+function __fish_ya_needs_command
+	# Figure out if the current invocation already has a command.
+	set -l cmd (commandline -opc)
+	set -e cmd[1]
+	argparse -s (__fish_ya_global_optspecs) -- $cmd 2>/dev/null
+	or return
+	if set -q argv[1]
+		# Also print the command, so this can be used to figure out what it is.
+		echo $argv[1]
+		return 1
+	end
+	return 0
+end
+
+function __fish_ya_using_subcommand
+	set -l cmd (__fish_ya_needs_command)
+	test -z "$cmd"
+	and return 1
+	contains -- $cmd[1] $argv
+end
+
+complete -c ya -n "__fish_ya_needs_command" -s V -l version -d 'Print version'
+complete -c ya -n "__fish_ya_needs_command" -s h -l help -d 'Print help'
+complete -c ya -n "__fish_ya_needs_command" -f -a "pub" -d 'Publish a message to the current instance'
+complete -c ya -n "__fish_ya_needs_command" -f -a "pub-to" -d 'Publish a message to the specified instance'
+complete -c ya -n "__fish_ya_needs_command" -f -a "sub" -d 'Subscribe to messages from all remote instances'
+complete -c ya -n "__fish_ya_needs_command" -f -a "pack" -d 'Manage packages'
+complete -c ya -n "__fish_ya_needs_command" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
+complete -c ya -n "__fish_ya_using_subcommand pub" -l str -d 'Send the message with a string body' -r
+complete -c ya -n "__fish_ya_using_subcommand pub" -l json -d 'Send the message with a JSON body' -r
+complete -c ya -n "__fish_ya_using_subcommand pub" -l list -d 'Send the message as string of list' -r
+complete -c ya -n "__fish_ya_using_subcommand pub" -s h -l help -d 'Print help'
+complete -c ya -n "__fish_ya_using_subcommand pub-to" -l str -d 'Send the message with a string body' -r
+complete -c ya -n "__fish_ya_using_subcommand pub-to" -l json -d 'Send the message with a JSON body' -r
+complete -c ya -n "__fish_ya_using_subcommand pub-to" -l list -d 'Send the message as string of list' -r
+complete -c ya -n "__fish_ya_using_subcommand pub-to" -s h -l help -d 'Print help'
+complete -c ya -n "__fish_ya_using_subcommand sub" -s h -l help -d 'Print help'
+complete -c ya -n "__fish_ya_using_subcommand pack" -s a -l add -d 'Add a package' -r
+complete -c ya -n "__fish_ya_using_subcommand pack" -s i -l install -d 'Install all packages'
+complete -c ya -n "__fish_ya_using_subcommand pack" -s l -l list -d 'List all packages'
+complete -c ya -n "__fish_ya_using_subcommand pack" -s u -l upgrade -d 'Upgrade all packages'
+complete -c ya -n "__fish_ya_using_subcommand pack" -s h -l help -d 'Print help'
+complete -c ya -n "__fish_ya_using_subcommand help; and not __fish_seen_subcommand_from pub pub-to sub pack help" -f -a "pub" -d 'Publish a message to the current instance'
+complete -c ya -n "__fish_ya_using_subcommand help; and not __fish_seen_subcommand_from pub pub-to sub pack help" -f -a "pub-to" -d 'Publish a message to the specified instance'
+complete -c ya -n "__fish_ya_using_subcommand help; and not __fish_seen_subcommand_from pub pub-to sub pack help" -f -a "sub" -d 'Subscribe to messages from all remote instances'
+complete -c ya -n "__fish_ya_using_subcommand help; and not __fish_seen_subcommand_from pub pub-to sub pack help" -f -a "pack" -d 'Manage packages'
+complete -c ya -n "__fish_ya_using_subcommand help; and not __fish_seen_subcommand_from pub pub-to sub pack help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
diff --git a/alpine-river/config/fish/completions/yazi.fish b/alpine-river/config/fish/completions/yazi.fish
new file mode 100644
index 0000000..cd243b0
--- /dev/null
+++ b/alpine-river/config/fish/completions/yazi.fish
@@ -0,0 +1,9 @@
+complete -c yazi -l cwd-file -d 'Write the cwd on exit to this file' -r -F
+complete -c yazi -l chooser-file -d 'Write the selected files to this file on open fired' -r -F
+complete -c yazi -l client-id -d 'Use the specified client ID, must be a globally unique number' -r
+complete -c yazi -l local-events -d 'Report the specified local events to stdout' -r
+complete -c yazi -l remote-events -d 'Report the specified remote events to stdout' -r
+complete -c yazi -l clear-cache -d 'Clear the cache directory'
+complete -c yazi -l debug -d 'Print debug information'
+complete -c yazi -s V -l version -d 'Print version'
+complete -c yazi -s h -l help -d 'Print help'
diff --git a/alpine-river/config/fish/conf.d/fzf.fish b/alpine-river/config/fish/conf.d/fzf.fish
new file mode 100644
index 0000000..8156c11
--- /dev/null
+++ b/alpine-river/config/fish/conf.d/fzf.fish
@@ -0,0 +1,28 @@
+# fzf.fish is only meant to be used in interactive mode. If not in interactive mode and not in CI, skip the config to speed up shell startup
+if not status is-interactive && test "$CI" != true
+    exit
+end
+
+# Because of scoping rules, to capture the shell variables exactly as they are, we must read
+# them before even executing _fzf_search_variables. We use psub to store the
+# variables' info in temporary files and pass in the filenames as arguments.
+# This variable is global so that it can be referenced by fzf_configure_bindings and in tests
+set --global _fzf_search_vars_command '_fzf_search_variables (set --show | psub) (set --names | psub)'
+
+
+# Install the default bindings, which are mnemonic and minimally conflict with fish's preset bindings
+fzf_configure_bindings
+
+# Doesn't erase autoloaded _fzf_* functions because they are not easily accessible once key bindings are erased
+function _fzf_uninstall --on-event fzf_uninstall
+    _fzf_uninstall_bindings
+
+    set --erase _fzf_search_vars_command
+    functions --erase _fzf_uninstall _fzf_migration_message _fzf_uninstall_bindings fzf_configure_bindings
+    complete --erase fzf_configure_bindings
+
+    set_color cyan
+    echo "fzf.fish uninstalled."
+    echo "You may need to manually remove fzf_configure_bindings from your config.fish if you were using custom key bindings."
+    set_color normal
+end
diff --git a/alpine-river/config/fish/conf.d/rustup.fish b/alpine-river/config/fish/conf.d/rustup.fish
new file mode 100644
index 0000000..e4cb363
--- /dev/null
+++ b/alpine-river/config/fish/conf.d/rustup.fish
@@ -0,0 +1 @@
+source "$HOME/.cargo/env.fish"
diff --git a/alpine-river/config/fish/config.fish b/alpine-river/config/fish/config.fish
new file mode 100644
index 0000000..523724e
--- /dev/null
+++ b/alpine-river/config/fish/config.fish
@@ -0,0 +1,23 @@
+if status is-interactive
+    # Commands to run in interactive sessions can go here
+    fish_config theme choose "Rosé Pine"
+    fzf_configure_bindings --directory=\cf
+
+    # set fish_greeting $(fastfetch)
+    function fish_greeting
+       fastfetch
+    end
+    set BROWSER firefox-esr
+    set PATH "$PATH:$HOME/.local/bin"
+    set EDITOR nvim
+
+    function ls
+        command eza $argv
+    end
+
+    abbr y yazi
+    abbr v nvim
+    abbr ec emacsclient -t
+    abbr sudo doas
+
+end
diff --git a/alpine-river/config/fish/fish_plugins b/alpine-river/config/fish/fish_plugins
new file mode 100644
index 0000000..aa9becc
--- /dev/null
+++ b/alpine-river/config/fish/fish_plugins
@@ -0,0 +1,3 @@
+jorgebucaran/fisher
+rose-pine/fish
+patrickf1/fzf.fish
diff --git a/alpine-river/config/fish/functions/_fzf_configure_bindings_help.fish b/alpine-river/config/fish/functions/_fzf_configure_bindings_help.fish
new file mode 100644
index 0000000..ecfe68e
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_configure_bindings_help.fish
@@ -0,0 +1,43 @@
+function _fzf_configure_bindings_help --description "Prints the help message for fzf_configure_bindings."
+    echo "\
+USAGE:
+    fzf_configure_bindings [--COMMAND=[KEY_SEQUENCE]...]
+
+DESCRIPTION
+    fzf_configure_bindings installs key bindings for fzf.fish's commands and erases any bindings it
+    previously installed. It installs bindings for both default and insert modes. fzf.fish executes
+    it without options on fish startup to install the out-of-the-box key bindings.
+
+    By default, commands are bound to a mnemonic key sequence, shown below. Each command's binding
+    can be configured using a namesake corresponding option:
+        COMMAND            |  DEFAULT KEY SEQUENCE         |  CORRESPONDING OPTION
+        Search Directory   |  Ctrl+Alt+F (F for file)      |  --directory
+        Search Git Log     |  Ctrl+Alt+L (L for log)       |  --git_log
+        Search Git Status  |  Ctrl+Alt+S (S for status)    |  --git_status
+        Search History     |  Ctrl+R     (R for reverse)   |  --history
+        Search Processes   |  Ctrl+Alt+P (P for process)   |  --processes
+        Search Variables   |  Ctrl+V     (V for variable)  |  --variables
+    Override a command's binding by specifying its corresponding option with the desired key
+    sequence. Disable a command's binding by specifying its corresponding option with no value.
+
+    Because fzf_configure_bindings erases bindings it previously installed, it can be cleanly
+    executed multiple times. Once the desired fzf_configure_bindings command has been found, add it
+    to your config.fish in order to persist the customized bindings.
+
+    In terms of validation, fzf_configure_bindings fails if passed unknown options. It expects an
+    equals sign between an option's name and value. However, it does not validate key sequences.
+
+    Pass -h or --help to print this help message and exit.
+
+EXAMPLES
+    Default bindings but bind Search Directory to Ctrl+F and Search Variables to Ctrl+Alt+V
+        \$ fzf_configure_bindings --directory=\cf --variables=\e\cv
+    Default bindings but disable Search History
+        \$ fzf_configure_bindings --history=
+    An agglomeration of different options
+        \$ fzf_configure_bindings --git_status=\cg --history=\ch --variables= --processes=
+
+SEE Also
+    To learn more about fish key bindings, see bind(1) and fish_key_reader(1).
+"
+end
diff --git a/alpine-river/config/fish/functions/_fzf_extract_var_info.fish b/alpine-river/config/fish/functions/_fzf_extract_var_info.fish
new file mode 100644
index 0000000..dd4e952
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_extract_var_info.fish
@@ -0,0 +1,15 @@
+# helper function for _fzf_search_variables
+function _fzf_extract_var_info --argument-names variable_name set_show_output --description "Extract and reformat lines pertaining to \$variable_name from \$set_show_output."
+    # Extract only the lines about the variable, all of which begin with either
+    # $variable_name: ...or... $variable_name[
+    string match --regex "^\\\$$variable_name(?::|\[).*" <$set_show_output |
+
+        # Strip the variable name prefix, including ": " for scope info lines
+        string replace --regex "^\\\$$variable_name(?:: )?" '' |
+
+        # Distill the lines of values, replacing...
+        #   [1]: |value|
+        # ...with...
+        #   [1] value
+        string replace --regex ": \|(.*)\|" ' $1'
+end
diff --git a/alpine-river/config/fish/functions/_fzf_preview_changed_file.fish b/alpine-river/config/fish/functions/_fzf_preview_changed_file.fish
new file mode 100644
index 0000000..78dd561
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_preview_changed_file.fish
@@ -0,0 +1,49 @@
+# helper for _fzf_search_git_status
+# arg should be a line from git status --short, e.g.
+# MM functions/_fzf_preview_changed_file.fish
+#  D README.md
+# R  LICENSE -> "New License"
+function _fzf_preview_changed_file --argument-names path_status --description "Show the git diff of the given file."
+    # remove quotes because they'll be interpreted literally by git diff
+    # no need to requote when referencing $path because fish does not perform word splitting
+    # https://fishshell.com/docs/current/fish_for_bash_users.html
+    set -f path (string unescape (string sub --start 4 $path_status))
+    # first letter of short format shows index, second letter shows working tree
+    # https://git-scm.com/docs/git-status/2.35.0#_short_format
+    set -f index_status (string sub --length 1 $path_status)
+    set -f working_tree_status (string sub --start 2 --length 1 $path_status)
+
+    set -f diff_opts --color=always
+
+    if test $index_status = '?'
+        _fzf_report_diff_type Untracked
+        _fzf_preview_file $path
+    else if contains {$index_status}$working_tree_status DD AU UD UA DU AA UU
+        # Unmerged statuses taken directly from git status help's short format table
+        # Unmerged statuses are mutually exclusive with other statuses, so if we see
+        # these, then safe to assume the path is unmerged
+        _fzf_report_diff_type Unmerged
+        git diff $diff_opts -- $path
+    else
+        if test $index_status != ' '
+            _fzf_report_diff_type Staged
+
+            # renames are only detected in the index, never working tree, so only need to test for it here
+            # https://stackoverflow.com/questions/73954214
+            if test $index_status = R
+                # diff the post-rename path with the original path, otherwise the diff will show the entire file as being added
+                set -f orig_and_new_path (string split --max 1 -- ' -> ' $path)
+                git diff --staged $diff_opts -- $orig_and_new_path[1] $orig_and_new_path[2]
+                # path currently has the form of "original -> current", so we need to correct it before it's used below
+                set path $orig_and_new_path[2]
+            else
+                git diff --staged $diff_opts -- $path
+            end
+        end
+
+        if test $working_tree_status != ' '
+            _fzf_report_diff_type Unstaged
+            git diff $diff_opts -- $path
+        end
+    end
+end
diff --git a/alpine-river/config/fish/functions/_fzf_preview_file.fish b/alpine-river/config/fish/functions/_fzf_preview_file.fish
new file mode 100644
index 0000000..c926475
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_preview_file.fish
@@ -0,0 +1,43 @@
+# helper function for _fzf_search_directory and _fzf_search_git_status
+function _fzf_preview_file --description "Print a preview for the given file based on its file type."
+    # because there's no way to guarantee that _fzf_search_directory passes the path to _fzf_preview_file
+    # as one argument, we collect all the arguments into one single variable and treat that as the path
+    set -f file_path $argv
+
+    if test -L "$file_path" # symlink
+        # notify user and recurse on the target of the symlink, which can be any of these file types
+        set -l target_path (realpath "$file_path")
+
+        set_color yellow
+        echo "'$file_path' is a symlink to '$target_path'."
+        set_color normal
+
+        _fzf_preview_file "$target_path"
+    else if test -f "$file_path" # regular file
+        if set --query fzf_preview_file_cmd
+            # need to escape quotes to make sure eval receives file_path as a single arg
+            eval "$fzf_preview_file_cmd '$file_path'"
+        else
+            bat --style=numbers --color=always "$file_path"
+        end
+    else if test -d "$file_path" # directory
+        if set --query fzf_preview_dir_cmd
+            # see above
+            eval "$fzf_preview_dir_cmd '$file_path'"
+        else
+            # -A list hidden files as well, except for . and ..
+            # -F helps classify files by appending symbols after the file name
+            command ls -A -F "$file_path"
+        end
+    else if test -c "$file_path"
+        _fzf_report_file_type "$file_path" "character device file"
+    else if test -b "$file_path"
+        _fzf_report_file_type "$file_path" "block device file"
+    else if test -S "$file_path"
+        _fzf_report_file_type "$file_path" socket
+    else if test -p "$file_path"
+        _fzf_report_file_type "$file_path" "named pipe"
+    else
+        echo "$file_path doesn't exist." >&2
+    end
+end
diff --git a/alpine-river/config/fish/functions/_fzf_report_diff_type.fish b/alpine-river/config/fish/functions/_fzf_report_diff_type.fish
new file mode 100644
index 0000000..cc26fb3
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_report_diff_type.fish
@@ -0,0 +1,18 @@
+# helper for _fzf_preview_changed_file
+# prints out something like
+# ╭────────╮
+# │ Staged │
+# ╰────────╯
+function _fzf_report_diff_type --argument-names diff_type --description "Print a distinct colored header meant to preface a git patch."
+    # number of "-" to draw is the length of the string to box + 2 for padding
+    set -f repeat_count (math 2 + (string length $diff_type))
+    set -f line (string repeat --count $repeat_count ─)
+    set -f top_border ╭$line╮
+    set -f btm_border ╰$line╯
+
+    set_color yellow
+    echo $top_border
+    echo "│ $diff_type │"
+    echo $btm_border
+    set_color normal
+end
diff --git a/alpine-river/config/fish/functions/_fzf_report_file_type.fish b/alpine-river/config/fish/functions/_fzf_report_file_type.fish
new file mode 100644
index 0000000..49e02e1
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_report_file_type.fish
@@ -0,0 +1,6 @@
+# helper function for _fzf_preview_file
+function _fzf_report_file_type --argument-names file_path file_type --description "Explain the file type for a file."
+    set_color red
+    echo "Cannot preview '$file_path': it is a $file_type."
+    set_color normal
+end
diff --git a/alpine-river/config/fish/functions/_fzf_search_directory.fish b/alpine-river/config/fish/functions/_fzf_search_directory.fish
new file mode 100644
index 0000000..4541eec
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_search_directory.fish
@@ -0,0 +1,33 @@
+function _fzf_search_directory --description "Search the current directory. Replace the current token with the selected file paths."
+    # Directly use fd binary to avoid output buffering delay caused by a fd alias, if any.
+    # Debian-based distros install fd as fdfind and the fd package is something else, so
+    # check for fdfind first. Fall back to "fd" for a clear error message.
+    set -f fd_cmd (command -v fdfind || command -v fd  || echo "fd")
+    set -f --append fd_cmd --color=always $fzf_fd_opts
+
+    set -f fzf_arguments --multi --ansi $fzf_directory_opts
+    set -f token (commandline --current-token)
+    # expand any variables or leading tilde (~) in the token
+    set -f expanded_token (eval echo -- $token)
+    # unescape token because it's already quoted so backslashes will mess up the path
+    set -f unescaped_exp_token (string unescape -- $expanded_token)
+
+    # If the current token is a directory and has a trailing slash,
+    # then use it as fd's base directory.
+    if string match --quiet -- "*/" $unescaped_exp_token && test -d "$unescaped_exp_token"
+        set --append fd_cmd --base-directory=$unescaped_exp_token
+        # use the directory name as fzf's prompt to indicate the search is limited to that directory
+        set --prepend fzf_arguments --prompt="Directory $unescaped_exp_token> " --preview="_fzf_preview_file $expanded_token{}"
+        set -f file_paths_selected $unescaped_exp_token($fd_cmd 2>/dev/null | _fzf_wrapper $fzf_arguments)
+    else
+        set --prepend fzf_arguments --prompt="Directory> " --query="$unescaped_exp_token" --preview='_fzf_preview_file {}'
+        set -f file_paths_selected ($fd_cmd 2>/dev/null | _fzf_wrapper $fzf_arguments)
+    end
+
+
+    if test $status -eq 0
+        commandline --current-token --replace -- (string escape -- $file_paths_selected | string join ' ')
+    end
+
+    commandline --function repaint
+end
diff --git a/alpine-river/config/fish/functions/_fzf_search_git_log.fish b/alpine-river/config/fish/functions/_fzf_search_git_log.fish
new file mode 100644
index 0000000..aa54724
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_search_git_log.fish
@@ -0,0 +1,36 @@
+function _fzf_search_git_log --description "Search the output of git log and preview commits. Replace the current token with the selected commit hash."
+    if not git rev-parse --git-dir >/dev/null 2>&1
+        echo '_fzf_search_git_log: Not in a git repository.' >&2
+    else
+        if not set --query fzf_git_log_format
+            # %h gives you the abbreviated commit hash, which is useful for saving screen space, but we will have to expand it later below
+            set -f fzf_git_log_format '%C(bold blue)%h%C(reset) - %C(cyan)%ad%C(reset) %C(yellow)%d%C(reset) %C(normal)%s%C(reset)  %C(dim normal)[%an]%C(reset)'
+        end
+
+        set -f preview_cmd 'git show --color=always --stat --patch {1}'
+        if set --query fzf_diff_highlighter
+            set preview_cmd "$preview_cmd | $fzf_diff_highlighter"
+        end
+
+        set -f selected_log_lines (
+            git log --no-show-signature --color=always --format=format:$fzf_git_log_format --date=short | \
+            _fzf_wrapper --ansi \
+                --multi \
+                --scheme=history \
+                --prompt="Git Log> " \
+                --preview=$preview_cmd \
+                --query=(commandline --current-token) \
+                $fzf_git_log_opts
+        )
+        if test $status -eq 0
+            for line in $selected_log_lines
+                set -f abbreviated_commit_hash (string split --field 1 " " $line)
+                set -f full_commit_hash (git rev-parse $abbreviated_commit_hash)
+                set -f --append commit_hashes $full_commit_hash
+            end
+            commandline --current-token --replace (string join ' ' $commit_hashes)
+        end
+    end
+
+    commandline --function repaint
+end
diff --git a/alpine-river/config/fish/functions/_fzf_search_git_status.fish b/alpine-river/config/fish/functions/_fzf_search_git_status.fish
new file mode 100644
index 0000000..358f88c
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_search_git_status.fish
@@ -0,0 +1,41 @@
+function _fzf_search_git_status --description "Search the output of git status. Replace the current token with the selected file paths."
+    if not git rev-parse --git-dir >/dev/null 2>&1
+        echo '_fzf_search_git_status: Not in a git repository.' >&2
+    else
+        set -f preview_cmd '_fzf_preview_changed_file {}'
+        if set --query fzf_diff_highlighter
+            set preview_cmd "$preview_cmd | $fzf_diff_highlighter"
+        end
+
+        set -f selected_paths (
+            # Pass configuration color.status=always to force status to use colors even though output is sent to a pipe
+            git -c color.status=always status --short |
+            _fzf_wrapper --ansi \
+                --multi \
+                --prompt="Git Status> " \
+                --query=(commandline --current-token) \
+                --preview=$preview_cmd \
+                --nth="2.." \
+                $fzf_git_status_opts
+        )
+        if test $status -eq 0
+            # git status --short automatically escapes the paths of most files for us so not going to bother trying to handle
+            # the few edges cases of weird file names that should be extremely rare (e.g. "this;needs;escaping")
+            set -f cleaned_paths
+
+            for path in $selected_paths
+                if test (string sub --length 1 $path) = R
+                    # path has been renamed and looks like "R LICENSE -> LICENSE.md"
+                    # extract the path to use from after the arrow
+                    set --append cleaned_paths (string split -- "-> " $path)[-1]
+                else
+                    set --append cleaned_paths (string sub --start=4 $path)
+                end
+            end
+
+            commandline --current-token --replace -- (string join ' ' $cleaned_paths)
+        end
+    end
+
+    commandline --function repaint
+end
diff --git a/alpine-river/config/fish/functions/_fzf_search_history.fish b/alpine-river/config/fish/functions/_fzf_search_history.fish
new file mode 100644
index 0000000..cafbce9
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_search_history.fish
@@ -0,0 +1,39 @@
+function _fzf_search_history --description "Search command history. Replace the command line with the selected command."
+    # history merge incorporates history changes from other fish sessions
+    # it errors out if called in private mode
+    if test -z "$fish_private_mode"
+        builtin history merge
+    end
+
+    if not set --query fzf_history_time_format
+        # Reference https://devhints.io/strftime to understand strftime format symbols
+        set -f fzf_history_time_format "%m-%d %H:%M:%S"
+    end
+
+    # Delinate time from command in history entries using the vertical box drawing char (U+2502).
+    # Then, to get raw command from history entries, delete everything up to it. The ? on regex is
+    # necessary to make regex non-greedy so it won't match into commands containing the char.
+    set -f time_prefix_regex '^.*? │ '
+    # Delinate commands throughout pipeline using null rather than newlines because commands can be multi-line
+    set -f commands_selected (
+        builtin history --null --show-time="$fzf_history_time_format │ " |
+        _fzf_wrapper --read0 \
+            --print0 \
+            --multi \
+            --scheme=history \
+            --prompt="History> " \
+            --query=(commandline) \
+            --preview="string replace --regex '$time_prefix_regex' '' -- {} | fish_indent --ansi" \
+            --preview-window="bottom:3:wrap" \
+            $fzf_history_opts |
+        string split0 |
+        # remove timestamps from commands selected
+        string replace --regex $time_prefix_regex ''
+    )
+
+    if test $status -eq 0
+        commandline --replace -- $commands_selected
+    end
+
+    commandline --function repaint
+end
diff --git a/alpine-river/config/fish/functions/_fzf_search_processes.fish b/alpine-river/config/fish/functions/_fzf_search_processes.fish
new file mode 100644
index 0000000..133a880
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_search_processes.fish
@@ -0,0 +1,32 @@
+function _fzf_search_processes --description "Search all running processes. Replace the current token with the pid of the selected process."
+    # Directly use ps command because it is often aliased to a different command entirely
+    # or with options that dirty the search results and preview output
+    set -f ps_cmd (command -v ps || echo "ps")
+    # use all caps to be consistent with ps default format
+    # snake_case because ps doesn't seem to allow spaces in the field names
+    set -f ps_preview_fmt (string join ',' 'pid' 'ppid=PARENT' 'user' '%cpu' 'rss=RSS_IN_KB' 'start=START_TIME' 'command')
+    set -f processes_selected (
+        $ps_cmd -A -opid,command | \
+        _fzf_wrapper --multi \
+                    --prompt="Processes> " \
+                    --query (commandline --current-token) \
+                    --ansi \
+                    # first line outputted by ps is a header, so we need to mark it as so
+                    --header-lines=1 \
+                    # ps uses exit code 1 if the process was not found, in which case show an message explaining so
+                    --preview="$ps_cmd -o '$ps_preview_fmt' -p {1} || echo 'Cannot preview {1} because it exited.'" \
+                    --preview-window="bottom:4:wrap" \
+                    $fzf_processes_opts
+    )
+
+    if test $status -eq 0
+        for process in $processes_selected
+            set -f --append pids_selected (string split --no-empty --field=1 -- " " $process)
+        end
+
+        # string join to replace the newlines outputted by string split with spaces
+        commandline --current-token --replace -- (string join ' ' $pids_selected)
+    end
+
+    commandline --function repaint
+end
diff --git a/alpine-river/config/fish/functions/_fzf_search_variables.fish b/alpine-river/config/fish/functions/_fzf_search_variables.fish
new file mode 100644
index 0000000..52a7c70
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_search_variables.fish
@@ -0,0 +1,47 @@
+# This function expects the following two arguments:
+# argument 1 = output of (set --show | psub), i.e. a file with the scope info and values of all variables
+# argument 2 = output of (set --names | psub), i.e. a file with all variable names
+function _fzf_search_variables --argument-names set_show_output set_names_output --description "Search and preview shell variables. Replace the current token with the selected variable."
+    if test -z "$set_names_output"
+        printf '%s\n' '_fzf_search_variables requires 2 arguments.' >&2
+
+        commandline --function repaint
+        return 22 # 22 means invalid argument in POSIX
+    end
+
+    # Exclude the history variable from being piped into fzf because
+    # 1. it's not included in $set_names_output
+    # 2. it tends to be a very large value => increases computation time
+    # 3._fzf_search_history is a much better way to examine history anyway
+    set -f all_variable_names (string match --invert history <$set_names_output)
+
+    set -f current_token (commandline --current-token)
+    # Use the current token to pre-populate fzf's query. If the current token begins
+    # with a $, remove it from the query so that it will better match the variable names
+    set -f cleaned_curr_token (string replace -- '$' '' $current_token)
+
+    set -f variable_names_selected (
+        printf '%s\n' $all_variable_names |
+        _fzf_wrapper --preview "_fzf_extract_var_info {} $set_show_output" \
+            --prompt="Variables> " \
+            --preview-window="wrap" \
+            --multi \
+            --query=$cleaned_curr_token \
+            $fzf_variables_opts
+    )
+
+    if test $status -eq 0
+        # If the current token begins with a $, do not overwrite the $ when
+        # replacing the current token with the selected variable.
+        # Uses brace expansion to prepend $ to each variable name.
+        commandline --current-token --replace (
+            if string match --quiet -- '$*' $current_token
+                string join " " \${$variable_names_selected}
+            else
+                string join " " $variable_names_selected
+            end
+        )
+    end
+
+    commandline --function repaint
+end
diff --git a/alpine-river/config/fish/functions/_fzf_wrapper.fish b/alpine-river/config/fish/functions/_fzf_wrapper.fish
new file mode 100644
index 0000000..486e36c
--- /dev/null
+++ b/alpine-river/config/fish/functions/_fzf_wrapper.fish
@@ -0,0 +1,21 @@
+function _fzf_wrapper --description "Prepares some environment variables before executing fzf."
+    # Make sure fzf uses fish to execute preview commands, some of which
+    # are autoloaded fish functions so don't exist in other shells.
+    # Use --function so that it doesn't clobber SHELL outside this function.
+    set -f --export SHELL (command --search fish)
+
+    # If neither FZF_DEFAULT_OPTS nor FZF_DEFAULT_OPTS_FILE are set, then set some sane defaults.
+    # See https://github.com/junegunn/fzf#environment-variables
+    set --query FZF_DEFAULT_OPTS FZF_DEFAULT_OPTS_FILE
+    if test $status -eq 2
+        # cycle allows jumping between the first and last results, making scrolling faster
+        # layout=reverse lists results top to bottom, mimicking the familiar layouts of git log, history, and env
+        # border shows where the fzf window begins and ends
+        # height=90% leaves space to see the current command and some scrollback, maintaining context of work
+        # preview-window=wrap wraps long lines in the preview window, making reading easier
+        # marker=* makes the multi-select marker more distinguishable from the pointer (since both default to >)
+        set --export FZF_DEFAULT_OPTS '--cycle --layout=reverse --border --height=90% --preview-window=wrap --marker="*"'
+    end
+
+    fzf $argv
+end
diff --git a/alpine-river/config/fish/functions/fisher.fish b/alpine-river/config/fish/functions/fisher.fish
new file mode 100644
index 0000000..e915cb8
--- /dev/null
+++ b/alpine-river/config/fish/functions/fisher.fish
@@ -0,0 +1,240 @@
+function fisher --argument-names cmd --description "A plugin manager for Fish"
+    set --query fisher_path || set --local fisher_path $__fish_config_dir
+    set --local fisher_version 4.4.5
+    set --local fish_plugins $__fish_config_dir/fish_plugins
+
+    switch "$cmd"
+        case -v --version
+            echo "fisher, version $fisher_version"
+        case "" -h --help
+            echo "Usage: fisher install <plugins...>  Install plugins"
+            echo "       fisher remove  <plugins...>  Remove installed plugins"
+            echo "       fisher update  <plugins...>  Update installed plugins"
+            echo "       fisher update                Update all installed plugins"
+            echo "       fisher list    [<regex>]     List installed plugins matching regex"
+            echo "Options:"
+            echo "       -v, --version  Print version"
+            echo "       -h, --help     Print this help message"
+            echo "Variables:"
+            echo "       \$fisher_path  Plugin installation path. Default: $__fish_config_dir" | string replace --regex -- $HOME \~
+        case ls list
+            string match --entire --regex -- "$argv[2]" $_fisher_plugins
+        case install update remove
+            isatty || read --local --null --array stdin && set --append argv $stdin
+
+            set --local install_plugins
+            set --local update_plugins
+            set --local remove_plugins
+            set --local arg_plugins $argv[2..-1]
+            set --local old_plugins $_fisher_plugins
+            set --local new_plugins
+
+            test -e $fish_plugins && set --local file_plugins (string match --regex -- '^[^\s]+$' <$fish_plugins | string replace -- \~ ~)
+
+            if ! set --query argv[2]
+                if test "$cmd" != update
+                    echo "fisher: Not enough arguments for command: \"$cmd\"" >&2 && return 1
+                else if ! set --query file_plugins
+                    echo "fisher: \"$fish_plugins\" file not found: \"$cmd\"" >&2 && return 1
+                end
+                set arg_plugins $file_plugins
+            end
+
+            for plugin in $arg_plugins
+                set plugin (test -e "$plugin" && realpath $plugin || string lower -- $plugin)
+                contains -- "$plugin" $new_plugins || set --append new_plugins $plugin
+            end
+
+            if set --query argv[2]
+                for plugin in $new_plugins
+                    if contains -- "$plugin" $old_plugins
+                        test "$cmd" = remove &&
+                            set --append remove_plugins $plugin ||
+                            set --append update_plugins $plugin
+                    else if test "$cmd" = install
+                        set --append install_plugins $plugin
+                    else
+                        echo "fisher: Plugin not installed: \"$plugin\"" >&2 && return 1
+                    end
+                end
+            else
+                for plugin in $new_plugins
+                    contains -- "$plugin" $old_plugins &&
+                        set --append update_plugins $plugin ||
+                        set --append install_plugins $plugin
+                end
+
+                for plugin in $old_plugins
+                    contains -- "$plugin" $new_plugins || set --append remove_plugins $plugin
+                end
+            end
+
+            set --local pid_list
+            set --local source_plugins
+            set --local fetch_plugins $update_plugins $install_plugins
+            set --local fish_path (status fish-path)
+
+            echo (set_color --bold)fisher $cmd version $fisher_version(set_color normal)
+
+            for plugin in $fetch_plugins
+                set --local source (command mktemp -d)
+                set --append source_plugins $source
+
+                command mkdir -p $source/{completions,conf.d,themes,functions}
+
+                $fish_path --command "
+                    if test -e $plugin
+                        command cp -Rf $plugin/* $source
+                    else
+                        set temp (command mktemp -d)
+                        set repo (string split -- \@ $plugin) || set repo[2] HEAD
+
+                        if set path (string replace --regex -- '^(https://)?gitlab.com/' '' \$repo[1])
+                            set name (string split -- / \$path)[-1]
+                            set url https://gitlab.com/\$path/-/archive/\$repo[2]/\$name-\$repo[2].tar.gz
+                        else
+                            set url https://api.github.com/repos/\$repo[1]/tarball/\$repo[2]
+                        end
+
+                        echo Fetching (set_color --underline)\$url(set_color normal)
+
+                        if command curl -q --silent -L \$url | command tar -xzC \$temp -f - 2>/dev/null
+                            command cp -Rf \$temp/*/* $source
+                        else
+                            echo fisher: Invalid plugin name or host unavailable: \\\"$plugin\\\" >&2
+                            command rm -rf $source
+                        end
+
+                        command rm -rf \$temp
+                    end
+
+                    set files $source/* && string match --quiet --regex -- .+\.fish\\\$ \$files
+                " &
+
+                set --append pid_list (jobs --last --pid)
+            end
+
+            wait $pid_list 2>/dev/null
+
+            for plugin in $fetch_plugins
+                if set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)] && test ! -e $source
+                    if set --local index (contains --index -- "$plugin" $install_plugins)
+                        set --erase install_plugins[$index]
+                    else
+                        set --erase update_plugins[(contains --index -- "$plugin" $update_plugins)]
+                    end
+                end
+            end
+
+            for plugin in $update_plugins $remove_plugins
+                if set --local index (contains --index -- "$plugin" $_fisher_plugins)
+                    set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files
+
+                    if contains -- "$plugin" $remove_plugins
+                        for name in (string replace --filter --regex -- '.+/conf\.d/([^/]+)\.fish$' '$1' $$plugin_files_var)
+                            emit {$name}_uninstall
+                        end
+                        printf "%s\n" Removing\ (set_color red --bold)$plugin(set_color normal) "         "$$plugin_files_var | string replace -- \~ ~
+                        set --erase _fisher_plugins[$index]
+                    end
+
+                    command rm -rf (string replace -- \~ ~ $$plugin_files_var)
+
+                    functions --erase (string replace --filter --regex -- '.+/functions/([^/]+)\.fish$' '$1' $$plugin_files_var)
+
+                    for name in (string replace --filter --regex -- '.+/completions/([^/]+)\.fish$' '$1' $$plugin_files_var)
+                        complete --erase --command $name
+                    end
+
+                    set --erase $plugin_files_var
+                end
+            end
+
+            if set --query update_plugins[1] || set --query install_plugins[1]
+                command mkdir -p $fisher_path/{functions,themes,conf.d,completions}
+            end
+
+            for plugin in $update_plugins $install_plugins
+                set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)]
+                set --local files $source/{functions,themes,conf.d,completions}/*
+
+                if set --local index (contains --index -- $plugin $install_plugins)
+                    set --local user_files $fisher_path/{functions,themes,conf.d,completions}/*
+                    set --local conflict_files
+
+                    for file in (string replace -- $source/ $fisher_path/ $files)
+                        contains -- $file $user_files && set --append conflict_files $file
+                    end
+
+                    if set --query conflict_files[1] && set --erase install_plugins[$index]
+                        echo -s "fisher: Cannot install \"$plugin\": please remove or move conflicting files first:" \n"        "$conflict_files >&2
+                        continue
+                    end
+                end
+
+                for file in (string replace -- $source/ "" $files)
+                    command cp -RLf $source/$file $fisher_path/$file
+                end
+
+                set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files
+
+                set --query files[1] && set --universal $plugin_files_var (string replace -- $source $fisher_path $files | string replace -- ~ \~)
+
+                contains -- $plugin $_fisher_plugins || set --universal --append _fisher_plugins $plugin
+                contains -- $plugin $install_plugins && set --local event install || set --local event update
+
+                printf "%s\n" Installing\ (set_color --bold)$plugin(set_color normal) "           "$$plugin_files_var | string replace -- \~ ~
+
+                for file in (string match --regex -- '.+/[^/]+\.fish$' $$plugin_files_var | string replace -- \~ ~)
+                    source $file
+                    if set --local name (string replace --regex -- '.+conf\.d/([^/]+)\.fish$' '$1' $file)
+                        emit {$name}_$event
+                    end
+                end
+            end
+
+            command rm -rf $source_plugins
+
+            if set --query _fisher_plugins[1]
+                set --local commit_plugins
+
+                for plugin in $file_plugins
+                    contains -- (string lower -- $plugin) (string lower -- $_fisher_plugins) && set --append commit_plugins $plugin
+                end
+
+                for plugin in $_fisher_plugins
+                    contains -- (string lower -- $plugin) (string lower -- $commit_plugins) || set --append commit_plugins $plugin
+                end
+
+                string replace --regex -- $HOME \~ $commit_plugins >$fish_plugins
+            else
+                set --erase _fisher_plugins
+                command rm -f $fish_plugins
+            end
+
+            set --local total (count $install_plugins) (count $update_plugins) (count $remove_plugins)
+
+            test "$total" != "0 0 0" && echo (string join ", " (
+                test $total[1] = 0 || echo "Installed $total[1]") (
+                test $total[2] = 0 || echo "Updated $total[2]") (
+                test $total[3] = 0 || echo "Removed $total[3]")
+            ) plugin/s
+        case \*
+            echo "fisher: Unknown command: \"$cmd\"" >&2 && return 1
+    end
+end
+
+if ! set --query _fisher_upgraded_to_4_4
+    set --universal _fisher_upgraded_to_4_4
+    if functions --query _fisher_list
+        set --query XDG_DATA_HOME[1] || set --local XDG_DATA_HOME ~/.local/share
+        command rm -rf $XDG_DATA_HOME/fisher
+        functions --erase _fisher_{list,plugin_parse}
+        fisher update >/dev/null 2>/dev/null
+    else
+        for var in (set --names | string match --entire --regex '^_fisher_.+_files$')
+            set $var (string replace -- ~ \~ $$var)
+        end
+        functions --erase _fisher_fish_postexec
+    end
+end
diff --git a/alpine-river/config/fish/functions/fzf_configure_bindings.fish b/alpine-river/config/fish/functions/fzf_configure_bindings.fish
new file mode 100644
index 0000000..4b4e7a2
--- /dev/null
+++ b/alpine-river/config/fish/functions/fzf_configure_bindings.fish
@@ -0,0 +1,46 @@
+# Always installs bindings for insert and default mode for simplicity and b/c it has almost no side-effect
+# https://gitter.im/fish-shell/fish-shell?at=60a55915ee77a74d685fa6b1
+function fzf_configure_bindings --description "Installs the default key bindings for fzf.fish with user overrides passed as options."
+    # no need to install bindings if not in interactive mode or running tests
+    status is-interactive || test "$CI" = true; or return
+
+    set -f options_spec h/help 'directory=?' 'git_log=?' 'git_status=?' 'history=?' 'processes=?' 'variables=?'
+    argparse --max-args=0 --ignore-unknown $options_spec -- $argv 2>/dev/null
+    if test $status -ne 0
+        echo "Invalid option or a positional argument was provided." >&2
+        _fzf_configure_bindings_help
+        return 22
+    else if set --query _flag_help
+        _fzf_configure_bindings_help
+        return
+    else
+        # Initialize with default key sequences and then override or disable them based on flags
+        # index 1 = directory, 2 = git_log, 3 = git_status, 4 = history, 5 = processes, 6 = variables
+        set -f key_sequences \e\cf \e\cl \e\cs \cr \e\cp \cv # \c = control, \e = escape
+        set --query _flag_directory && set key_sequences[1] "$_flag_directory"
+        set --query _flag_git_log && set key_sequences[2] "$_flag_git_log"
+        set --query _flag_git_status && set key_sequences[3] "$_flag_git_status"
+        set --query _flag_history && set key_sequences[4] "$_flag_history"
+        set --query _flag_processes && set key_sequences[5] "$_flag_processes"
+        set --query _flag_variables && set key_sequences[6] "$_flag_variables"
+
+        # If fzf bindings already exists, uninstall it first for a clean slate
+        if functions --query _fzf_uninstall_bindings
+            _fzf_uninstall_bindings
+        end
+
+        for mode in default insert
+            test -n $key_sequences[1] && bind --mode $mode $key_sequences[1] _fzf_search_directory
+            test -n $key_sequences[2] && bind --mode $mode $key_sequences[2] _fzf_search_git_log
+            test -n $key_sequences[3] && bind --mode $mode $key_sequences[3] _fzf_search_git_status
+            test -n $key_sequences[4] && bind --mode $mode $key_sequences[4] _fzf_search_history
+            test -n $key_sequences[5] && bind --mode $mode $key_sequences[5] _fzf_search_processes
+            test -n $key_sequences[6] && bind --mode $mode $key_sequences[6] "$_fzf_search_vars_command"
+        end
+
+        function _fzf_uninstall_bindings --inherit-variable key_sequences
+            bind --erase -- $key_sequences
+            bind --erase --mode insert -- $key_sequences
+        end
+    end
+end
diff --git a/alpine-river/config/fish/themes/Rosé Pine.theme b/alpine-river/config/fish/themes/Rosé Pine.theme
new file mode 100644
index 0000000..446f6b5
--- /dev/null
+++ b/alpine-river/config/fish/themes/Rosé Pine.theme
@@ -0,0 +1,41 @@
+# syntax highlighting variables
+# https://fishshell.com/docs/current/interactive.html#syntax-highlighting-variables
+fish_color_normal e0def4
+fish_color_command c4a7e7
+fish_color_keyword 9ccfd8
+fish_color_quote f6c177
+fish_color_redirection 31748f
+fish_color_end 908caa
+fish_color_error eb6f92
+fish_color_param ebbcba
+fish_color_comment 908caa
+# fish_color_match --background=brblue
+fish_color_selection --reverse
+# fish_color_history_current --bold
+fish_color_operator e0def4
+fish_color_escape 31748f
+fish_color_autosuggestion 908caa
+fish_color_cwd ebbcba
+# fish_color_cwd_root red
+fish_color_user f6c177
+fish_color_host 9ccfd8
+fish_color_host_remote c4a7e7
+fish_color_cancel e0def4
+fish_color_search_match --background=191724
+fish_color_valid_path
+
+# pager color variables
+# https://fishshell.com/docs/current/interactive.html#pager-color-variables
+fish_pager_color_progress ebbcba
+fish_pager_color_background --background=1f1d2e
+fish_pager_color_prefix 9ccfd8
+fish_pager_color_completion 908caa
+fish_pager_color_description 908caa
+fish_pager_color_secondary_background
+fish_pager_color_secondary_prefix
+fish_pager_color_secondary_completion
+fish_pager_color_secondary_description
+fish_pager_color_selected_background --background=26233a
+fish_pager_color_selected_prefix 9ccfd8
+fish_pager_color_selected_completion e0def4
+fish_pager_color_selected_description e0def4
diff --git a/alpine-river/config/foot/foot.ini b/alpine-river/config/foot/foot.ini
new file mode 100644
index 0000000..af175a8
--- /dev/null
+++ b/alpine-river/config/foot/foot.ini
@@ -0,0 +1,34 @@
+shell=tmux
+font=FantasqueSansMono:size=14
+term=xterm-256color
+
+pad=0x0 center
+
+# -*- conf -*-
+# Rose-Piné
+
+[cursor]
+color=191724 e0def4
+style=beam
+
+[colors]
+background=191724
+foreground=e0def4
+regular0=26233a  # black (Overlay)
+regular1=eb6f92  # red (Love)
+regular2=31748f  # green (Pine)
+regular3=f6c177  # yellow (Gold)
+regular4=9ccfd8  # blue (Foam)
+regular5=c4a7e7  # magenta (Iris)
+regular6=ebbcba  # cyan (Rose)
+regular7=e0def4  # white (Text)
+
+bright0=6e6a86   # bright black (Muted)
+bright1=eb6f92   # bright red (Love)
+bright2=31748f   # bright green (Pine)
+bright3=f6c177   # bright yellow (Gold)
+bright4=9ccfd8   # bright blue (Foam)
+bright5=c4a7e7   # bright magenta (Iris)
+bright6=ebbcba   # bright cyan (Rose)
+bright7=e0def4   # bright white (Text)
+
diff --git a/alpine-river/config/fuzzel/fuzzel.ini b/alpine-river/config/fuzzel/fuzzel.ini
new file mode 100644
index 0000000..1f84146
--- /dev/null
+++ b/alpine-river/config/fuzzel/fuzzel.ini
@@ -0,0 +1,22 @@
+[main]
+font=FantasqueSansMono:size=14
+icons-enabled=false
+dpi-aware=no
+use-bold=true
+prompt="λ "
+width=35
+horizontal-pad=10
+vertical-pad=10
+
+[border]
+width=2
+radius=0
+
+[colors]
+border=ebbcbaff
+background=191724ff
+text=e0def4ff
+match=9ccfd8ff
+selection=1a1b26ff
+selection-match=9ccfd8ff
+selection-text=c4a7e7ff
diff --git a/alpine-river/config/gtk-3.0/gtk.css b/alpine-river/config/gtk-3.0/gtk.css
new file mode 100644
index 0000000..64c61fd
--- /dev/null
+++ b/alpine-river/config/gtk-3.0/gtk.css
@@ -0,0 +1,12 @@
+/* No (default) title bar on wayland */
+headerbar.default-decoration {
+  /* You may need to tweak these values depending on your GTK theme */
+  margin-bottom: 50px;
+  margin-top: -100px;
+}
+
+/* rm -rf window shadows */
+window.csd,             /* gtk4? */
+window.csd decoration { /* gtk3 */
+  box-shadow: none;
+}
diff --git a/alpine-river/config/gtk-3.0/settings.ini b/alpine-river/config/gtk-3.0/settings.ini
new file mode 100644
index 0000000..9f5e79d
--- /dev/null
+++ b/alpine-river/config/gtk-3.0/settings.ini
@@ -0,0 +1,5 @@
+[Settings]
+gtk-dialogs-use-header=false
+gtk-cursor-theme-name=BreezeX-RosePine-Linux
+gtk-cursor-theme-size=32
+gtk-font-name=Fantasque Sans Mono, 12
diff --git a/alpine-river/config/gtk-4.0/gtk.css b/alpine-river/config/gtk-4.0/gtk.css
new file mode 100644
index 0000000..64c61fd
--- /dev/null
+++ b/alpine-river/config/gtk-4.0/gtk.css
@@ -0,0 +1,12 @@
+/* No (default) title bar on wayland */
+headerbar.default-decoration {
+  /* You may need to tweak these values depending on your GTK theme */
+  margin-bottom: 50px;
+  margin-top: -100px;
+}
+
+/* rm -rf window shadows */
+window.csd,             /* gtk4? */
+window.csd decoration { /* gtk3 */
+  box-shadow: none;
+}
diff --git a/alpine-river/config/gtk-4.0/settings.ini b/alpine-river/config/gtk-4.0/settings.ini
new file mode 100644
index 0000000..8fea2b9
--- /dev/null
+++ b/alpine-river/config/gtk-4.0/settings.ini
@@ -0,0 +1,6 @@
+[Settings]
+gtk-dialogs-use-header=false
+gtk-cursor-theme-name=BreezeX-RosePine-Linux
+gtk-cursor-theme-size=32
+gtk-font-name=Fantasque Sans Mono, 12
+
diff --git a/alpine-river/config/kanata/config.kbd b/alpine-river/config/kanata/config.kbd
new file mode 100644
index 0000000..aeb84b0
--- /dev/null
+++ b/alpine-river/config/kanata/config.kbd
@@ -0,0 +1,52 @@
+#|
+This minimal config changes Caps Lock to act as Caps Lock on quick tap, but
+if held, it will act as Left Ctrl. It also changes the backtick/grave key to
+act as backtick/grave on quick tap, but change ijkl keys to arrow keys on hold.
+
+This text between the two pipe+octothorpe sequences is a multi-line comment.
+|#
+
+;; Text after double-semicolons are single-line comments.
+
+#|
+One defcfg entry may be added, which is used for configuration key-pairs. These
+configurations change kanata's behaviour at a more global level than the other
+configuration entries.
+|#
+
+(defcfg
+  #|
+  This configuration will process all keys pressed inside of kanata, even if
+  they are not mapped in defsrc. This is so that certain actions can activate
+  at the right time for certain input sequences. By default, unmapped keys are
+  not processed through kanata due to a Windows issue related to AltGr. If you
+  use AltGr in your keyboard, you will likely want to follow the simple.kbd
+  file while unmapping lctl and ralt from defsrc.
+  |#
+  process-unmapped-keys yes
+)
+
+(defsrc
+  esc                             del
+  caps                            pgup
+              h    j    k    l    pgdn
+  lsft rsft
+)
+
+(deflayer default
+  grv                             _
+  @cap                            _
+              _    _    _    _    _
+  _    _
+)
+
+(deflayer arrows
+  _                               home
+  _                               end
+              h    y    n    u    ins
+  _    _
+)
+
+(defalias
+  cap (tap-hold 200 200 esc lctl)
+)
diff --git a/alpine-river/config/mpv/mpv.conf b/alpine-river/config/mpv/mpv.conf
new file mode 100644
index 0000000..49b93d9
--- /dev/null
+++ b/alpine-river/config/mpv/mpv.conf
@@ -0,0 +1,3 @@
+background-color="#191724"
+sub-color="#e0def4"
+osd-color="#e0def4"
diff --git a/alpine-river/config/mpv/script-opts/uosc.conf b/alpine-river/config/mpv/script-opts/uosc.conf
new file mode 100644
index 0000000..de8e293
--- /dev/null
+++ b/alpine-river/config/mpv/script-opts/uosc.conf
@@ -0,0 +1,237 @@
+# Display style of current position. available: line, bar
+timeline_style=line
+# Line display style config
+timeline_line_width=2
+# Timeline size when fully expanded, in pixels, 0 to disable
+timeline_size=40
+# Comma separated states when element should always be fully visible.
+# Available: paused, audio, image, video, idle, windowed, fullscreen
+timeline_persistency=
+# Top border of background color to help visually separate timeline from video
+timeline_border=1
+# When scrolling above timeline, wheel will seek by this amount of seconds.
+# Default uses fast seeking. Add `!` suffix to enable exact seeks. Example: `5!`
+timeline_step=5
+# Render cache indicators for streaming content
+timeline_cache=yes
+
+# When to display an always visible progress bar (minimized timeline). Can be: windowed, fullscreen, always, never
+# Can also be toggled on demand with `toggle-progress` command.
+progress=windowed
+progress_size=2
+progress_line_width=20
+
+# A comma delimited list of controls above the timeline. Set to `never` to disable.
+# Parameter spec: enclosed in `{}` means value, enclosed in `[]` means optional
+# Full item syntax: `[<[!]{disposition1}[,[!]{dispositionN}]>]{element}[:{paramN}][#{badge}[>{limit}]][?{tooltip}]`
+# Common properties:
+#   `{icon}` - parameter used to specify an icon name (example: `face`)
+#            - pick here: https://fonts.google.com/icons?icon.platform=web&icon.set=Material+Icons&icon.style=Rounded
+# `{element}`s and their parameters:
+#   `{shorthand}` - preconfigured shorthands:
+#        `play-pause`, `menu`, `subtitles`, `audio`, `video`, `playlist`,
+#        `chapters`, `editions`, `stream-quality`, `open-file`, `items`,
+#        `next`, `prev`, `first`, `last`, `audio-device`, `fullscreen`,
+#        `loop-playlist`, `loop-file`, `shuffle`
+#   `speed[:{scale}]` - display speed slider, [{scale}] - factor of controls_size, default: 1.3
+#   `command:{icon}:{command}` - button that executes a {command} when pressed
+#   `toggle:{icon}:{prop}[@{owner}]` - button that toggles mpv property
+#   `cycle:{default_icon}:{prop}[@{owner}]:{value1}[={icon1}][!]/{valueN}[={iconN}][!]`
+#       - button that cycles mpv property between values, each optionally having different icon and active flag
+#       - presence of `!` at the end will style the button as active
+#       - `{owner}` is the name of a script that manages this property if any
+#   `gap[:{scale}]` - display an empty gap
+#       {scale} - factor of controls_size, default: 0.3
+#   `space` - fills all available space between previous and next item, useful to align items to the right
+#           - multiple spaces divide the available space among themselves, which can be used for centering
+#   `button:{name}` - button whose state, look, and click action are managed by external script
+# Item visibility control:
+#   `<[!]{disposition1}[,[!]{dispositionN}]>` - optional prefix to control element's visibility
+#   - `{disposition}` can be one of:
+#     - `idle` - true if mpv is in idle mode (no file loaded)
+#     - `image` - true if current file is a single image
+#     - `audio` - true for audio only files
+#     - `video` - true for files with a video track
+#     - `has_many_video` - true for files with more than one video track
+#     - `has_image` - true for files with a cover or other image track
+#     - `has_audio` - true for files with an audio track
+#     - `has_many_audio` - true for files with more than one audio track
+#     - `has_sub` - true for files with an subtitle track
+#     - `has_many_sub` - true for files with more than one subtitle track
+#     - `has_many_edition` - true for files with more than one edition
+#     - `has_chapter` - true for files with chapter list
+#     - `stream` - true if current file is read from a stream
+#     - `has_playlist` - true if current playlist has 2 or more items in it
+#   - prefix with `!` to negate the required disposition
+#   Examples:
+#     - `<stream>stream-quality` - show stream quality button only for streams
+#     - `<has_audio,!audio>audio` - show audio tracks button for all files that have
+#                                   an audio track, but are not exclusively audio only files
+# Place `#{badge}[>{limit}]` after the element params to give it a badge. Available badges:
+#   `sub`, `audio`, `video` - track type counters
+#   `{mpv_prop}` - any mpv prop that makes sense to you: https://mpv.io/manual/master/#property-list
+#                - if prop value is an array it'll display its size
+#   `>{limit}` will display the badge only if it's numerical value is above this threshold.
+#   Example: `#audio>1`
+# Place `?{tooltip}` after the element config to give it a tooltip.
+# Example implementations:
+#   menu = command:menu:script-binding uosc/menu-blurred?Menu
+#   subtitles = command:subtitles:script-binding uosc/subtitles#sub?Subtitles
+#   fullscreen = cycle:crop_free:fullscreen:no/yes=fullscreen_exit!?Fullscreen
+#   loop-playlist = cycle:repeat:loop-playlist:no/inf!?Loop playlist
+#   toggle:{icon}:{prop} = cycle:{icon}:{prop}:no/yes!
+controls=menu,gap,subtitles,<has_many_audio>audio,<has_many_video>video,<has_many_edition>editions,<stream>stream-quality,gap,space,speed,space,shuffle,loop-playlist,loop-file,gap,prev,items,next,gap,fullscreen
+controls_size=32
+controls_margin=8
+controls_spacing=2
+controls_persistency=
+
+# Where to display volume controls: none, left, right
+volume=right
+volume_size=40
+volume_border=1
+volume_step=1
+volume_persistency=
+
+# Playback speed widget: mouse drag or wheel to change, click to reset
+speed_step=0.1
+speed_step_is_factor=no
+speed_persistency=
+
+# Controls all menus, such as context menu, subtitle loader/selector, etc
+menu_item_height=36
+menu_min_width=260
+menu_padding=4
+# Determines if `/` or `ctrl+f` is required to activate the search, or if typing
+# any text is sufficient.
+# When enabled, you can no longer toggle a menu off with the same key that opened it, if the key is a unicode character.
+menu_type_to_search=yes
+
+# Top bar with window controls and media title
+# Can be: never, no-border, always
+top_bar=no-border
+top_bar_size=40
+# Can be: `no` (hide), left or right
+top_bar_controls=right
+# Can be: `no` (hide), `yes` (inherit title from mpv.conf), or a custom template string
+top_bar_title=yes
+# Template string to enable alternative top bar title. If alt title matches main title,
+# it'll be hidden. Tip: use `${media-title}` for main, and `${filename}` for alt title.
+top_bar_alt_title=
+# Can be:
+#   `below`  => display alt title below the main one
+#   `toggle` => toggle the top bar title text between main and alt by clicking
+#               the top bar, or calling `toggle-title` binding
+top_bar_alt_title_place=below
+# Flash top bar when any of these file types is loaded. Available: audio,video,image,chapter
+top_bar_flash_on=video,audio
+top_bar_persistency=
+
+# Window border drawn in no-border mode
+window_border_size=1
+
+# If there's no playlist and file ends, load next file in the directory
+# Requires `keep-open=yes` in `mpv.conf`.
+autoload=no
+# What types to accept as next item when autoloading or requesting to play next file
+# Can be: video, audio, image, subtitle
+autoload_types=video,audio,image
+# Enable uosc's playlist/directory shuffle mode
+# This simply makes the next selected playlist or directory item be random, just
+# like any other player in the world. It also has an easily togglable control button.
+shuffle=no
+
+# Scale the interface by this factor
+scale=1
+# Scale in fullscreen
+scale_fullscreen=1.3
+# Adjust the text scaling to fit your font
+font_scale=1
+# Border of text and icons when drawn directly on top of video
+text_border=1.2
+# Border radius of buttons, menus, and all other rectangles
+border_radius=4
+# A comma delimited list of color overrides in RGB HEX format. Defaults:
+# foreground=ffffff,foreground_text=000000,background=000000,background_text=ffffff,curtain=111111,success=a5e075,error=ff616e
+color=
+# A comma delimited list of opacity overrides for various UI element backgrounds and shapes.
+# This does not affect any text, which is always rendered fully opaque. Defaults:
+# timeline=0.9,position=1,chapters=0.8,slider=0.9,slider_gauge=1,controls=0,speed=0.6,menu=1,submenu=0.4,border=1,title=1,tooltip=1,thumbnail=1,curtain=0.8,idle_indicator=0.8,audio_indicator=0.5,buffering_indicator=0.3,playlist_position=0.8
+opacity=
+# A comma delimited list of features to refine at a cost of some performance impact.
+# text_width - Use a more accurate text width measurement that measures each text string individually
+#              instead of just measuring the width of known letters once and adding them up.
+# sorting    - Use filename sorting that handles non-english languages better, especially asian ones.
+#              At the moment, this is only available on windows, and has no effect on other platforms.
+refine=
+# Duration of animations in milliseconds
+animation_duration=100
+# Execute command for background clicks shorter than this number of milliseconds, 0 to disable
+# Execution always waits for `input-doubleclick-time` to filter out double-clicks
+click_threshold=0
+click_command=cycle pause; script-binding uosc/flash-pause-indicator
+# Flash duration in milliseconds used by `flash-{element}` commands
+flash_duration=1000
+# Distances in pixels below which elements are fully faded in/out
+proximity_in=40
+proximity_out=120
+# Use only bold font weight throughout the whole UI
+font_bold=no
+# One of `total`, `playtime-remaining` (scaled by the current speed), `time-remaining` (remaining length of file)
+destination_time=playtime-remaining
+# Display sub second fraction in timestamps up to this precision
+time_precision=0
+# Display stream's buffered time in timeline if it's lower than this amount of seconds, 0 to disable
+buffered_time_threshold=60
+# Hide UI when mpv autohides the cursor. Timing is controlled by `cursor-autohide` in `mpv.conf` (in milliseconds).
+autohide=no
+# Can be: flash, static, manual (controlled by flash-pause-indicator and decide-pause-indicator commands)
+pause_indicator=flash
+# Sizes to list in stream quality menu
+stream_quality_options=4320,2160,1440,1080,720,480,360,240,144
+# Types to identify media files
+video_types=3g2,3gp,asf,avi,f4v,flv,h264,h265,m2ts,m4v,mkv,mov,mp4,mp4v,mpeg,mpg,ogm,ogv,rm,rmvb,ts,vob,webm,wmv,y4m
+audio_types=aac,ac3,aiff,ape,au,cue,dsf,dts,flac,m4a,mid,midi,mka,mp3,mp4a,oga,ogg,opus,spx,tak,tta,wav,weba,wma,wv
+image_types=apng,avif,bmp,gif,j2k,jp2,jfif,jpeg,jpg,jxl,mj2,png,svg,tga,tif,tiff,webp
+subtitle_types=aqt,ass,gsub,idx,jss,lrc,mks,pgs,pjs,psb,rt,sbv,slt,smi,sub,sup,srt,ssa,ssf,ttxt,txt,usf,vt,vtt
+playlist_types=m3u,m3u8,pls,url,cue
+# Default open-file menu directory. Use `{drives}` to open drives menu on windows (defaults to `/` on unix).
+default_directory=~/
+# List hidden files when reading directories. Due to environment limitations, this currently only hides
+# files starting with a dot. Doesn't hide hidden files on windows (we have no way to tell they're hidden).
+show_hidden_files=no
+# Move files to trash (recycle bin) when deleting files. Dependencies:
+# - Linux: `sudo apt install trash-cli`
+# - MacOS: `brew install trash`
+use_trash=no
+# Adjusted osd margins based on the visibility of UI elements
+adjust_osd_margins=yes
+
+# Adds chapter range indicators to some common chapter types.
+# Additionally to displaying the start of the chapter as a diamond icon on top of the timeline,
+# the portion of the timeline of that chapter range is also colored based on the config below.
+#
+# The syntax is a comma-delimited list of `{type}:{color}` pairs, where:
+# `{type}` => range type. Currently supported ones are:
+#   - `openings`, `endings` => anime openings/endings
+#   - `intros`, `outros` => video intros/outros
+#   - `ads` => segments created by sponsor-block software like https://github.com/po5/mpv_sponsorblock
+# `{color}` => an RGB(A) HEX color code (`rrggbb`, or `rrggbbaa`)
+#
+# To exclude marking any of the range types, simply remove them from the list.
+chapter_ranges=openings:30abf964,endings:30abf964,ads:c54e4e80
+# Add alternative lua patterns to identify beginnings of simple chapter ranges (except for `ads`)
+# Syntax: `{type}:{pattern}[,{patternN}][;{type}:{pattern}[,{patternN}]]`
+chapter_range_patterns=openings:オープニング;endings:エンディング
+
+# Localization language priority from highest to lowest.
+# Also controls what languages are fetched by `download-subtitles` menu.
+# Built in languages can be found in `uosc/intl`.
+# `slang` is a keyword to inherit values from `--slang` mpv config.
+# Supports paths to custom json files: `languages=~~/custom.json,slang,en`
+languages=slang,en
+
+# A comma separated list of element IDs to disable. Available IDs:
+#   window_border, top_bar, timeline, controls, volume,
+#   idle_indicator, audio_indicator, buffering_indicator, pause_indicator
+disable_elements=
diff --git a/alpine-river/config/mpv/scripts/thumbfast.lua b/alpine-river/config/mpv/scripts/thumbfast.lua
new file mode 100644
index 0000000..58d1870
--- /dev/null
+++ b/alpine-river/config/mpv/scripts/thumbfast.lua
@@ -0,0 +1,951 @@
+-- thumbfast.lua
+--
+-- High-performance on-the-fly thumbnailer
+--
+-- Built for easy integration in third-party UIs.
+
+--[[
+This Source Code Form is subject to the terms of the Mozilla Public
+License, v. 2.0. If a copy of the MPL was not distributed with this
+file, You can obtain one at https://mozilla.org/MPL/2.0/.
+]]
+
+local options = {
+    -- Socket path (leave empty for auto)
+    socket = "",
+
+    -- Thumbnail path (leave empty for auto)
+    thumbnail = "",
+
+    -- Maximum thumbnail generation size in pixels (scaled down to fit)
+    -- Values are scaled when hidpi is enabled
+    max_height = 200,
+    max_width = 200,
+
+    -- Scale factor for thumbnail display size (requires mpv 0.38+)
+    -- Note that this is lower quality than increasing max_height and max_width
+    scale_factor = 1,
+
+    -- Apply tone-mapping, no to disable
+    tone_mapping = "auto",
+
+    -- Overlay id
+    overlay_id = 42,
+
+    -- Spawn thumbnailer on file load for faster initial thumbnails
+    spawn_first = false,
+
+    -- Close thumbnailer process after an inactivity period in seconds, 0 to disable
+    quit_after_inactivity = 0,
+
+    -- Enable on network playback
+    network = false,
+
+    -- Enable on audio playback
+    audio = false,
+
+    -- Enable hardware decoding
+    hwdec = false,
+
+    -- Windows only: use native Windows API to write to pipe (requires LuaJIT)
+    direct_io = false,
+
+    -- Custom path to the mpv executable
+    mpv_path = "mpv"
+}
+
+mp.utils = require "mp.utils"
+mp.options = require "mp.options"
+mp.options.read_options(options, "thumbfast")
+
+local properties = {}
+local pre_0_30_0 = mp.command_native_async == nil
+local pre_0_33_0 = true
+local support_media_control = mp.get_property_native("media-controls") ~= nil
+
+function subprocess(args, async, callback)
+    callback = callback or function() end
+
+    if not pre_0_30_0 then
+        if async then
+            return mp.command_native_async({name = "subprocess", playback_only = true, args = args}, callback)
+        else
+            return mp.command_native({name = "subprocess", playback_only = false, capture_stdout = true, args = args})
+        end
+    else
+        if async then
+            return mp.utils.subprocess_detached({args = args}, callback)
+        else
+            return mp.utils.subprocess({args = args})
+        end
+    end
+end
+
+local winapi = {}
+if options.direct_io then
+    local ffi_loaded, ffi = pcall(require, "ffi")
+    if ffi_loaded then
+        winapi = {
+            ffi = ffi,
+            C = ffi.C,
+            bit = require("bit"),
+            socket_wc = "",
+
+            -- WinAPI constants
+            CP_UTF8 = 65001,
+            GENERIC_WRITE = 0x40000000,
+            OPEN_EXISTING = 3,
+            FILE_FLAG_WRITE_THROUGH = 0x80000000,
+            FILE_FLAG_NO_BUFFERING = 0x20000000,
+            PIPE_NOWAIT = ffi.new("unsigned long[1]", 0x00000001),
+
+            INVALID_HANDLE_VALUE = ffi.cast("void*", -1),
+
+            -- don't care about how many bytes WriteFile wrote, so allocate something to store the result once
+            _lpNumberOfBytesWritten = ffi.new("unsigned long[1]"),
+        }
+        -- cache flags used in run() to avoid bor() call
+        winapi._createfile_pipe_flags = winapi.bit.bor(winapi.FILE_FLAG_WRITE_THROUGH, winapi.FILE_FLAG_NO_BUFFERING)
+
+        ffi.cdef[[
+            void* __stdcall CreateFileW(const wchar_t *lpFileName, unsigned long dwDesiredAccess, unsigned long dwShareMode, void *lpSecurityAttributes, unsigned long dwCreationDisposition, unsigned long dwFlagsAndAttributes, void *hTemplateFile);
+            bool __stdcall WriteFile(void *hFile, const void *lpBuffer, unsigned long nNumberOfBytesToWrite, unsigned long *lpNumberOfBytesWritten, void *lpOverlapped);
+            bool __stdcall CloseHandle(void *hObject);
+            bool __stdcall SetNamedPipeHandleState(void *hNamedPipe, unsigned long *lpMode, unsigned long *lpMaxCollectionCount, unsigned long *lpCollectDataTimeout);
+            int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
+        ]]
+
+        winapi.MultiByteToWideChar = function(MultiByteStr)
+            if MultiByteStr then
+                local utf16_len = winapi.C.MultiByteToWideChar(winapi.CP_UTF8, 0, MultiByteStr, -1, nil, 0)
+                if utf16_len > 0 then
+                    local utf16_str = winapi.ffi.new("wchar_t[?]", utf16_len)
+                    if winapi.C.MultiByteToWideChar(winapi.CP_UTF8, 0, MultiByteStr, -1, utf16_str, utf16_len) > 0 then
+                        return utf16_str
+                    end
+                end
+            end
+            return ""
+        end
+
+    else
+        options.direct_io = false
+    end
+end
+
+local file
+local file_bytes = 0
+local spawned = false
+local disabled = false
+local force_disabled = false
+local spawn_waiting = false
+local spawn_working = false
+local script_written = false
+
+local dirty = false
+
+local x, y
+local last_x, last_y
+
+local last_seek_time
+
+local effective_w, effective_h = options.max_width, options.max_height
+local real_w, real_h
+local last_real_w, last_real_h
+
+local script_name
+
+local show_thumbnail = false
+
+local filters_reset = {["lavfi-crop"]=true, ["crop"]=true}
+local filters_runtime = {["hflip"]=true, ["vflip"]=true}
+local filters_all = {["hflip"]=true, ["vflip"]=true, ["lavfi-crop"]=true, ["crop"]=true}
+
+local tone_mappings = {["none"]=true, ["clip"]=true, ["linear"]=true, ["gamma"]=true, ["reinhard"]=true, ["hable"]=true, ["mobius"]=true}
+local last_tone_mapping
+
+local last_vf_reset = ""
+local last_vf_runtime = ""
+
+local last_rotate = 0
+
+local par = ""
+local last_par = ""
+
+local last_crop = nil
+
+local last_has_vid = 0
+local has_vid = 0
+
+local file_timer
+local file_check_period = 1/60
+
+local allow_fast_seek = true
+
+local client_script = [=[
+#!/usr/bin/env bash
+MPV_IPC_FD=0; MPV_IPC_PATH="%s"
+trap "kill 0" EXIT
+while [[ $# -ne 0 ]]; do case $1 in --mpv-ipc-fd=*) MPV_IPC_FD=${1/--mpv-ipc-fd=/} ;; esac; shift; done
+if echo "print-text thumbfast" >&"$MPV_IPC_FD"; then echo -n > "$MPV_IPC_PATH"; tail -f "$MPV_IPC_PATH" >&"$MPV_IPC_FD" & while read -r -u "$MPV_IPC_FD" 2>/dev/null; do :; done; fi
+]=]
+
+local function get_os()
+    local raw_os_name = ""
+
+    if jit and jit.os and jit.arch then
+        raw_os_name = jit.os
+    else
+        if package.config:sub(1,1) == "\\" then
+            -- Windows
+            local env_OS = os.getenv("OS")
+            if env_OS then
+                raw_os_name = env_OS
+            end
+        else
+            raw_os_name = subprocess({"uname", "-s"}).stdout
+        end
+    end
+
+    raw_os_name = (raw_os_name):lower()
+
+    local os_patterns = {
+        ["windows"] = "windows",
+        ["linux"]   = "linux",
+
+        ["osx"]     = "darwin",
+        ["mac"]     = "darwin",
+        ["darwin"]  = "darwin",
+
+        ["^mingw"]  = "windows",
+        ["^cygwin"] = "windows",
+
+        ["bsd$"]    = "darwin",
+        ["sunos"]   = "darwin"
+    }
+
+    -- Default to linux
+    local str_os_name = "linux"
+
+    for pattern, name in pairs(os_patterns) do
+        if raw_os_name:match(pattern) then
+            str_os_name = name
+            break
+        end
+    end
+
+    return str_os_name
+end
+
+local os_name = mp.get_property("platform") or get_os()
+
+local path_separator = os_name == "windows" and "\\" or "/"
+
+if options.socket == "" then
+    if os_name == "windows" then
+        options.socket = "thumbfast"
+    else
+        options.socket = "/tmp/thumbfast"
+    end
+end
+
+if options.thumbnail == "" then
+    if os_name == "windows" then
+        options.thumbnail = os.getenv("TEMP").."\\thumbfast.out"
+    else
+        options.thumbnail = "/tmp/thumbfast.out"
+    end
+end
+
+local unique = mp.utils.getpid()
+
+options.socket = options.socket .. unique
+options.thumbnail = options.thumbnail .. unique
+
+if options.direct_io then
+    if os_name == "windows" then
+        winapi.socket_wc = winapi.MultiByteToWideChar("\\\\.\\pipe\\" .. options.socket)
+    end
+
+    if winapi.socket_wc == "" then
+        options.direct_io = false
+    end
+end
+
+options.scale_factor = math.floor(options.scale_factor)
+
+local mpv_path = options.mpv_path
+local frontend_path
+
+if mpv_path == "mpv" and os_name == "windows" then
+    frontend_path = mp.get_property_native("user-data/frontend/process-path")
+    mpv_path = frontend_path or mpv_path
+end
+
+if mpv_path == "mpv" and os_name == "darwin" and unique then
+    -- TODO: look into ~~osxbundle/
+    mpv_path = string.gsub(subprocess({"ps", "-o", "comm=", "-p", tostring(unique)}).stdout, "[\n\r]", "")
+    if mpv_path ~= "mpv" then
+        mpv_path = string.gsub(mpv_path, "/mpv%-bundle$", "/mpv")
+        local mpv_bin = mp.utils.file_info("/usr/local/mpv")
+        if mpv_bin and mpv_bin.is_file then
+            mpv_path = "/usr/local/mpv"
+        else
+            local mpv_app = mp.utils.file_info("/Applications/mpv.app/Contents/MacOS/mpv")
+            if mpv_app and mpv_app.is_file then
+                mp.msg.warn("symlink mpv to fix Dock icons: `sudo ln -s /Applications/mpv.app/Contents/MacOS/mpv /usr/local/mpv`")
+            else
+                mp.msg.warn("drag to your Applications folder and symlink mpv to fix Dock icons: `sudo ln -s /Applications/mpv.app/Contents/MacOS/mpv /usr/local/mpv`")
+            end
+        end
+    end
+end
+
+local function vo_tone_mapping()
+    local passes = mp.get_property_native("vo-passes")
+    if passes and passes["fresh"] then
+        for k, v in pairs(passes["fresh"]) do
+            for k2, v2 in pairs(v) do
+                if k2 == "desc" and v2 then
+                    local tone_mapping = string.match(v2, "([0-9a-z.-]+) tone map")
+                    if tone_mapping then
+                        return tone_mapping
+                    end
+                end
+            end
+        end
+    end
+end
+
+local function vf_string(filters, full)
+    local vf = ""
+    local vf_table = properties["vf"]
+
+    if (properties["video-crop"] or "") ~= "" then
+        vf = "lavfi-crop="..string.gsub(properties["video-crop"], "(%d*)x?(%d*)%+(%d+)%+(%d+)", "w=%1:h=%2:x=%3:y=%4")..","
+        local width = properties["video-out-params"] and properties["video-out-params"]["dw"]
+        local height = properties["video-out-params"] and properties["video-out-params"]["dh"]
+        if width and height then
+            vf = string.gsub(vf, "w=:h=:", "w="..width..":h="..height..":")
+        end
+    end
+
+    if vf_table and #vf_table > 0 then
+        for i = #vf_table, 1, -1 do
+            if filters[vf_table[i].name] then
+                local args = ""
+                for key, value in pairs(vf_table[i].params) do
+                    if args ~= "" then
+                        args = args .. ":"
+                    end
+                    args = args .. key .. "=" .. value
+                end
+                vf = vf .. vf_table[i].name .. "=" .. args .. ","
+            end
+        end
+    end
+
+    if (full and options.tone_mapping ~= "no") or options.tone_mapping == "auto" then
+        if properties["video-params"] and properties["video-params"]["primaries"] == "bt.2020" then
+            local tone_mapping = options.tone_mapping
+            if tone_mapping == "auto" then
+                tone_mapping = last_tone_mapping or properties["tone-mapping"]
+                if tone_mapping == "auto" and properties["current-vo"] == "gpu-next" then
+                    tone_mapping = vo_tone_mapping()
+                end
+            end
+            if not tone_mappings[tone_mapping] then
+                tone_mapping = "hable"
+            end
+            last_tone_mapping = tone_mapping
+            vf = vf .. "zscale=transfer=linear,format=gbrpf32le,tonemap="..tone_mapping..",zscale=transfer=bt709,"
+        end
+    end
+
+    if full then
+        vf = vf.."scale=w="..effective_w..":h="..effective_h..par..",pad=w="..effective_w..":h="..effective_h..":x=-1:y=-1,format=bgra"
+    end
+
+    return vf
+end
+
+local function calc_dimensions()
+    local width = properties["video-out-params"] and properties["video-out-params"]["dw"]
+    local height = properties["video-out-params"] and properties["video-out-params"]["dh"]
+    if not width or not height then return end
+
+    local scale = properties["display-hidpi-scale"] or 1
+
+    if width / height > options.max_width / options.max_height then
+        effective_w = math.floor(options.max_width * scale + 0.5)
+        effective_h = math.floor(height / width * effective_w + 0.5)
+    else
+        effective_h = math.floor(options.max_height * scale + 0.5)
+        effective_w = math.floor(width / height * effective_h + 0.5)
+    end
+
+    local v_par = properties["video-out-params"] and properties["video-out-params"]["par"] or 1
+    if v_par == 1 then
+        par = ":force_original_aspect_ratio=decrease"
+    else
+        par = ""
+    end
+end
+
+local info_timer = nil
+
+local function info(w, h)
+    local rotate = properties["video-params"] and properties["video-params"]["rotate"]
+    local image = properties["current-tracks/video"] and properties["current-tracks/video"]["image"]
+    local albumart = image and properties["current-tracks/video"]["albumart"]
+
+    disabled = (w or 0) == 0 or (h or 0) == 0 or
+        has_vid == 0 or
+        (properties["demuxer-via-network"] and not options.network) or
+        (albumart and not options.audio) or
+        (image and not albumart) or
+        force_disabled
+
+    if info_timer then
+        info_timer:kill()
+        info_timer = nil
+    elseif has_vid == 0 or (rotate == nil and not disabled) then
+        info_timer = mp.add_timeout(0.05, function() info(w, h) end)
+    end
+
+    local json, err = mp.utils.format_json({width=w * options.scale_factor, height=h * options.scale_factor, scale_factor=options.scale_factor, disabled=disabled, available=true, socket=options.socket, thumbnail=options.thumbnail, overlay_id=options.overlay_id})
+    if pre_0_30_0 then
+        mp.command_native({"script-message", "thumbfast-info", json})
+    else
+        mp.command_native_async({"script-message", "thumbfast-info", json}, function() end)
+    end
+end
+
+local function remove_thumbnail_files()
+    if file then
+        file:close()
+        file = nil
+        file_bytes = 0
+    end
+    os.remove(options.thumbnail)
+    os.remove(options.thumbnail..".bgra")
+end
+
+local activity_timer
+
+local function spawn(time)
+    if disabled then return end
+
+    local path = properties["path"]
+    if path == nil then return end
+
+    if options.quit_after_inactivity > 0 then
+        if show_thumbnail or activity_timer:is_enabled() then
+            activity_timer:kill()
+        end
+        activity_timer:resume()
+    end
+
+    local open_filename = properties["stream-open-filename"]
+    local ytdl = open_filename and properties["demuxer-via-network"] and path ~= open_filename
+    if ytdl then
+        path = open_filename
+    end
+
+    remove_thumbnail_files()
+
+    local vid = properties["vid"]
+    has_vid = vid or 0
+
+    local args = {
+        mpv_path, "--no-config", "--msg-level=all=no", "--idle", "--pause", "--keep-open=always", "--really-quiet", "--no-terminal",
+        "--load-scripts=no", "--osc=no", "--ytdl=no", "--load-stats-overlay=no", "--load-osd-console=no", "--load-auto-profiles=no",
+        "--edition="..(properties["edition"] or "auto"), "--vid="..(vid or "auto"), "--no-sub", "--no-audio",
+        "--start="..time, allow_fast_seek and "--hr-seek=no" or "--hr-seek=yes",
+        "--ytdl-format=worst", "--demuxer-readahead-secs=0", "--demuxer-max-bytes=128KiB",
+        "--vd-lavc-skiploopfilter=all", "--vd-lavc-software-fallback=1", "--vd-lavc-fast", "--vd-lavc-threads=2", "--hwdec="..(options.hwdec and "auto" or "no"),
+        "--vf="..vf_string(filters_all, true),
+        "--sws-scaler=fast-bilinear",
+        "--video-rotate="..last_rotate,
+        "--ovc=rawvideo", "--of=image2", "--ofopts=update=1", "--o="..options.thumbnail
+    }
+
+    if not pre_0_30_0 then
+        table.insert(args, "--sws-allow-zimg=no")
+    end
+
+    if support_media_control then
+        table.insert(args, "--media-controls=no")
+    end
+
+    if os_name == "darwin" and properties["macos-app-activation-policy"] then
+        table.insert(args, "--macos-app-activation-policy=accessory")
+    end
+
+    if os_name == "windows" or pre_0_33_0 then
+        table.insert(args, "--input-ipc-server="..options.socket)
+    elseif not script_written then
+        local client_script_path = options.socket..".run"
+        local script = io.open(client_script_path, "w+")
+        if script == nil then
+            mp.msg.error("client script write failed")
+            return
+        else
+            script_written = true
+            script:write(string.format(client_script, options.socket))
+            script:close()
+            subprocess({"chmod", "+x", client_script_path}, true)
+            table.insert(args, "--scripts="..client_script_path)
+        end
+    else
+        local client_script_path = options.socket..".run"
+        table.insert(args, "--scripts="..client_script_path)
+    end
+
+    table.insert(args, "--")
+    table.insert(args, path)
+
+    spawned = true
+    spawn_waiting = true
+
+    subprocess(args, true,
+        function(success, result)
+            if spawn_waiting and (success == false or (result.status ~= 0 and result.status ~= -2)) then
+                spawned = false
+                spawn_waiting = false
+                options.tone_mapping = "no"
+                mp.msg.error("mpv subprocess create failed")
+                if not spawn_working then -- notify users of required configuration
+                    if options.mpv_path == "mpv" then
+                        if properties["current-vo"] == "libmpv" then
+                            if options.mpv_path == mpv_path then -- attempt to locate ImPlay
+                                mpv_path = "ImPlay"
+                                spawn(time)
+                            else -- ImPlay not in path
+                                if os_name ~= "darwin" then
+                                    force_disabled = true
+                                    info(real_w or effective_w, real_h or effective_h)
+                                end
+                                mp.commandv("show-text", "thumbfast: ERROR! cannot create mpv subprocess", 5000)
+                                mp.commandv("script-message-to", "implay", "show-message", "thumbfast initial setup", "Set mpv_path=PATH_TO_ImPlay in thumbfast config:\n" .. string.gsub(mp.command_native({"expand-path", "~~/script-opts/thumbfast.conf"}), "[/\\]", path_separator).."\nand restart ImPlay")
+                            end
+                        else
+                            mp.commandv("show-text", "thumbfast: ERROR! cannot create mpv subprocess", 5000)
+                            if os_name == "windows" and frontend_path == nil then
+                                mp.commandv("script-message-to", "mpvnet", "show-text", "thumbfast: ERROR! install standalone mpv, see README", 5000, 20)
+                                mp.commandv("script-message", "mpv.net", "show-text", "thumbfast: ERROR! install standalone mpv, see README", 5000, 20)
+                            end
+                        end
+                    else
+                        mp.commandv("show-text", "thumbfast: ERROR! cannot create mpv subprocess", 5000)
+                        -- found ImPlay but not defined in config
+                        mp.commandv("script-message-to", "implay", "show-message", "thumbfast", "Set mpv_path=PATH_TO_ImPlay in thumbfast config:\n" .. string.gsub(mp.command_native({"expand-path", "~~/script-opts/thumbfast.conf"}), "[/\\]", path_separator).."\nand restart ImPlay")
+                    end
+                end
+            elseif success == true and (result.status == 0 or result.status == -2) then
+                if not spawn_working and properties["current-vo"] == "libmpv" and options.mpv_path ~= mpv_path then
+                    mp.commandv("script-message-to", "implay", "show-message", "thumbfast initial setup", "Set mpv_path=ImPlay in thumbfast config:\n" .. string.gsub(mp.command_native({"expand-path", "~~/script-opts/thumbfast.conf"}), "[/\\]", path_separator).."\nand restart ImPlay")
+                end
+                spawn_working = true
+                spawn_waiting = false
+            end
+        end
+    )
+end
+
+local function run(command)
+    if not spawned then return end
+
+    if options.direct_io then
+        local hPipe = winapi.C.CreateFileW(winapi.socket_wc, winapi.GENERIC_WRITE, 0, nil, winapi.OPEN_EXISTING, winapi._createfile_pipe_flags, nil)
+        if hPipe ~= winapi.INVALID_HANDLE_VALUE then
+            local buf = command .. "\n"
+            winapi.C.SetNamedPipeHandleState(hPipe, winapi.PIPE_NOWAIT, nil, nil)
+            winapi.C.WriteFile(hPipe, buf, #buf + 1, winapi._lpNumberOfBytesWritten, nil)
+            winapi.C.CloseHandle(hPipe)
+        end
+
+        return
+    end
+
+    local command_n = command.."\n"
+
+    if os_name == "windows" then
+        if file and file_bytes + #command_n >= 4096 then
+            file:close()
+            file = nil
+            file_bytes = 0
+        end
+        if not file then
+            file = io.open("\\\\.\\pipe\\"..options.socket, "r+b")
+        end
+    elseif pre_0_33_0 then
+        subprocess({"/usr/bin/env", "sh", "-c", "echo '" .. command .. "' | socat - " .. options.socket})
+        return
+    elseif not file then
+        file = io.open(options.socket, "r+")
+    end
+    if file then
+        file_bytes = file:seek("end")
+        file:write(command_n)
+        file:flush()
+    end
+end
+
+local function draw(w, h, script)
+    if not w or not show_thumbnail then return end
+    if x ~= nil then
+        local scale_w, scale_h = options.scale_factor ~= 1 and (w * options.scale_factor) or nil, options.scale_factor ~= 1 and (h * options.scale_factor) or nil
+        if pre_0_30_0 then
+            mp.command_native({"overlay-add", options.overlay_id, x, y, options.thumbnail..".bgra", 0, "bgra", w, h, (4*w), scale_w, scale_h})
+        else
+            mp.command_native_async({"overlay-add", options.overlay_id, x, y, options.thumbnail..".bgra", 0, "bgra", w, h, (4*w), scale_w, scale_h}, function() end)
+        end
+    elseif script then
+        local json, err = mp.utils.format_json({width=w, height=h, scale_factor=options.scale_factor, x=x, y=y, socket=options.socket, thumbnail=options.thumbnail, overlay_id=options.overlay_id})
+        mp.commandv("script-message-to", script, "thumbfast-render", json)
+    end
+end
+
+local function real_res(req_w, req_h, filesize)
+    local count = filesize / 4
+    local diff = (req_w * req_h) - count
+
+    if (properties["video-params"] and properties["video-params"]["rotate"] or 0) % 180 == 90 then
+        req_w, req_h = req_h, req_w
+    end
+
+    if diff == 0 then
+        return req_w, req_h
+    else
+        local threshold = 5 -- throw out results that change too much
+        local long_side, short_side = req_w, req_h
+        if req_h > req_w then
+            long_side, short_side = req_h, req_w
+        end
+        for a = short_side, short_side - threshold, -1 do
+            if count % a == 0 then
+                local b = count / a
+                if long_side - b < threshold then
+                    if req_h < req_w then return b, a else return a, b end
+                end
+            end
+        end
+        return nil
+    end
+end
+
+local function move_file(from, to)
+    if os_name == "windows" then
+        os.remove(to)
+    end
+    -- move the file because it can get overwritten while overlay-add is reading it, and crash the player
+    os.rename(from, to)
+end
+
+local function seek(fast)
+    if last_seek_time then
+        run("async seek " .. last_seek_time .. (fast and " absolute+keyframes" or " absolute+exact"))
+    end
+end
+
+local seek_period = 3/60
+local seek_period_counter = 0
+local seek_timer
+seek_timer = mp.add_periodic_timer(seek_period, function()
+    if seek_period_counter == 0 then
+        seek(allow_fast_seek)
+        seek_period_counter = 1
+    else
+        if seek_period_counter == 2 then
+            if allow_fast_seek then
+                seek_timer:kill()
+                seek()
+            end
+        else seek_period_counter = seek_period_counter + 1 end
+    end
+end)
+seek_timer:kill()
+
+local function request_seek()
+    if seek_timer:is_enabled() then
+        seek_period_counter = 0
+    else
+        seek_timer:resume()
+        seek(allow_fast_seek)
+        seek_period_counter = 1
+    end
+end
+
+local function check_new_thumb()
+    -- the slave might start writing to the file after checking existance and
+    -- validity but before actually moving the file, so move to a temporary
+    -- location before validity check to make sure everything stays consistant
+    -- and valid thumbnails don't get overwritten by invalid ones
+    local tmp = options.thumbnail..".tmp"
+    move_file(options.thumbnail, tmp)
+    local finfo = mp.utils.file_info(tmp)
+    if not finfo then return false end
+    spawn_waiting = false
+    local w, h = real_res(effective_w, effective_h, finfo.size)
+    if w then -- only accept valid thumbnails
+        move_file(tmp, options.thumbnail..".bgra")
+
+        real_w, real_h = w, h
+        if real_w and (real_w ~= last_real_w or real_h ~= last_real_h) then
+            last_real_w, last_real_h = real_w, real_h
+            info(real_w, real_h)
+        end
+        if not show_thumbnail then
+            file_timer:kill()
+        end
+        return true
+    end
+
+    return false
+end
+
+file_timer = mp.add_periodic_timer(file_check_period, function()
+    if check_new_thumb() then
+        draw(real_w, real_h, script_name)
+    end
+end)
+file_timer:kill()
+
+local function clear()
+    file_timer:kill()
+    seek_timer:kill()
+    if options.quit_after_inactivity > 0 then
+        if show_thumbnail or activity_timer:is_enabled() then
+            activity_timer:kill()
+        end
+        activity_timer:resume()
+    end
+    last_seek_time = nil
+    show_thumbnail = false
+    last_x = nil
+    last_y = nil
+    if script_name then return end
+    if pre_0_30_0 then
+        mp.command_native({"overlay-remove", options.overlay_id})
+    else
+        mp.command_native_async({"overlay-remove", options.overlay_id}, function() end)
+    end
+end
+
+local function quit()
+    activity_timer:kill()
+    if show_thumbnail then
+        activity_timer:resume()
+        return
+    end
+    run("quit")
+    spawned = false
+    real_w, real_h = nil, nil
+    clear()
+end
+
+activity_timer = mp.add_timeout(options.quit_after_inactivity, quit)
+activity_timer:kill()
+
+local function thumb(time, r_x, r_y, script)
+    if disabled then return end
+
+    time = tonumber(time)
+    if time == nil then return end
+
+    if r_x == "" or r_y == "" then
+        x, y = nil, nil
+    else
+        x, y = math.floor(r_x + 0.5), math.floor(r_y + 0.5)
+    end
+
+    script_name = script
+    if last_x ~= x or last_y ~= y or not show_thumbnail then
+        show_thumbnail = true
+        last_x, last_y = x, y
+        draw(real_w, real_h, script)
+    end
+
+    if options.quit_after_inactivity > 0 then
+        if show_thumbnail or activity_timer:is_enabled() then
+            activity_timer:kill()
+        end
+        activity_timer:resume()
+    end
+
+    if time == last_seek_time then return end
+    last_seek_time = time
+    if not spawned then spawn(time) end
+    request_seek()
+    if not file_timer:is_enabled() then file_timer:resume() end
+end
+
+local function watch_changes()
+    if not dirty or not properties["video-out-params"] then return end
+    dirty = false
+
+    local old_w = effective_w
+    local old_h = effective_h
+
+    calc_dimensions()
+
+    local vf_reset = vf_string(filters_reset)
+    local rotate = properties["video-rotate"] or 0
+
+    local resized = old_w ~= effective_w or
+        old_h ~= effective_h or
+        last_vf_reset ~= vf_reset or
+        (last_rotate % 180) ~= (rotate % 180) or
+        par ~= last_par or last_crop ~= properties["video-crop"]
+
+    if resized then
+        last_rotate = rotate
+        info(effective_w, effective_h)
+    elseif last_has_vid ~= has_vid and has_vid ~= 0 then
+        info(effective_w, effective_h)
+    end
+
+    if spawned then
+        if resized then
+            -- mpv doesn't allow us to change output size
+            local seek_time = last_seek_time
+            run("quit")
+            clear()
+            spawned = false
+            spawn(seek_time or mp.get_property_number("time-pos", 0))
+            file_timer:resume()
+        else
+            if rotate ~= last_rotate then
+                run("set video-rotate "..rotate)
+            end
+            local vf_runtime = vf_string(filters_runtime)
+            if vf_runtime ~= last_vf_runtime then
+                run("vf set "..vf_string(filters_all, true))
+                last_vf_runtime = vf_runtime
+            end
+        end
+    else
+        last_vf_runtime = vf_string(filters_runtime)
+    end
+
+    last_vf_reset = vf_reset
+    last_rotate = rotate
+    last_par = par
+    last_crop = properties["video-crop"]
+    last_has_vid = has_vid
+
+    if not spawned and not disabled and options.spawn_first and resized then
+        spawn(mp.get_property_number("time-pos", 0))
+        file_timer:resume()
+    end
+end
+
+local function update_property(name, value)
+    properties[name] = value
+end
+
+local function update_property_dirty(name, value)
+    properties[name] = value
+    dirty = true
+    if name == "tone-mapping" then
+        last_tone_mapping = nil
+    end
+end
+
+local function update_tracklist(name, value)
+    -- current-tracks shim
+    for _, track in ipairs(value) do
+        if track.type == "video" and track.selected then
+            properties["current-tracks/video"] = track
+            return
+        end
+    end
+end
+
+local function sync_changes(prop, val)
+    update_property(prop, val)
+    if val == nil then return end
+
+    if type(val) == "boolean" then
+        if prop == "vid" then
+            has_vid = 0
+            last_has_vid = 0
+            info(effective_w, effective_h)
+            clear()
+            return
+        end
+        val = val and "yes" or "no"
+    end
+
+    if prop == "vid" then
+        has_vid = 1
+    end
+
+    if not spawned then return end
+
+    run("set "..prop.." "..val)
+    dirty = true
+end
+
+local function file_load()
+    clear()
+    spawned = false
+    real_w, real_h = nil, nil
+    last_real_w, last_real_h = nil, nil
+    last_tone_mapping = nil
+    last_seek_time = nil
+    if info_timer then
+        info_timer:kill()
+        info_timer = nil
+    end
+
+    calc_dimensions()
+    info(effective_w, effective_h)
+end
+
+local function shutdown()
+    run("quit")
+    remove_thumbnail_files()
+    if os_name ~= "windows" then
+        os.remove(options.socket)
+        os.remove(options.socket..".run")
+    end
+end
+
+local function on_duration(prop, val)
+    allow_fast_seek = (val or 30) >= 30
+end
+
+mp.observe_property("current-tracks/video", "native", function(name, value)
+    if pre_0_33_0 then
+        mp.unobserve_property(update_tracklist)
+        pre_0_33_0 = false
+    end
+    update_property(name, value)
+end)
+
+mp.observe_property("track-list", "native", update_tracklist)
+mp.observe_property("display-hidpi-scale", "native", update_property_dirty)
+mp.observe_property("video-out-params", "native", update_property_dirty)
+mp.observe_property("video-params", "native", update_property_dirty)
+mp.observe_property("vf", "native", update_property_dirty)
+mp.observe_property("tone-mapping", "native", update_property_dirty)
+mp.observe_property("demuxer-via-network", "native", update_property)
+mp.observe_property("stream-open-filename", "native", update_property)
+mp.observe_property("macos-app-activation-policy", "native", update_property)
+mp.observe_property("current-vo", "native", update_property)
+mp.observe_property("video-rotate", "native", update_property)
+mp.observe_property("video-crop", "native", update_property)
+mp.observe_property("path", "native", update_property)
+mp.observe_property("vid", "native", sync_changes)
+mp.observe_property("edition", "native", sync_changes)
+mp.observe_property("duration", "native", on_duration)
+
+mp.register_script_message("thumb", thumb)
+mp.register_script_message("clear", clear)
+
+mp.register_event("file-loaded", file_load)
+mp.register_event("shutdown", shutdown)
+
+mp.register_idle(watch_changes)
diff --git a/alpine-river/config/nvim/.gitignore b/alpine-river/config/nvim/.gitignore
new file mode 100644
index 0000000..e033bc6
--- /dev/null
+++ b/alpine-river/config/nvim/.gitignore
@@ -0,0 +1 @@
+lazy-lock.json
diff --git a/alpine-river/config/nvim/init.lua b/alpine-river/config/nvim/init.lua
new file mode 100644
index 0000000..e1870d1
--- /dev/null
+++ b/alpine-river/config/nvim/init.lua
@@ -0,0 +1,134 @@
+-- Setup Lazy Plugin Manager
+require("config.lazy")
+
+-- Setup Config
+vim.cmd.colorscheme("rose-pine")
+vim.opt.termguicolors = true
+
+vim.opt.nu = true
+vim.opt.rnu = true
+
+vim.opt.tabstop = 2
+vim.opt.softtabstop = 2
+vim.opt.shiftwidth = 2
+vim.opt.expandtab = true
+vim.opt.autoindent = true
+
+vim.opt.smartindent = true
+
+vim.opt.wrap = false
+
+vim.opt.swapfile = false
+vim.opt.backup = false
+vim.opt.undodir = os.getenv("HOME") .. "/.nvim/undodir"
+vim.opt.undofile = true
+
+vim.opt.hlsearch = false
+vim.opt.incsearch = true
+
+vim.opt.termguicolors = true
+
+vim.opt.scrolloff = 12
+
+vim.opt.updatetime = 50
+
+vim.opt.splitbelow = true
+vim.opt.splitright = true
+
+vim.opt.encoding = "utf-8"
+
+vim.opt.shell = "fish"
+
+vim.opt.ignorecase = true
+vim.opt.smartcase = true
+vim.opt.incsearch = true
+
+vim.opt.cursorline = true
+
+vim.opt.title = true
+
+vim.opt.clipboard = "unnamedplus"
+
+vim.opt.colorcolumn = "80"
+
+vim.cmd "set showtabline=0 | set laststatus=0"
+
+vim.wo.fillchars='eob: '
+
+vim.g.codeium_enabled = false
+
+vim.g.mapleader = " "
+vim.keymap.set("n", "<leader>bk", vim.cmd.bdelete, 
+  { desc = "Kill Buffer" })
+vim.keymap.set("n", "<leader>bn", vim.cmd.bnext, 
+  { desc = "Next Buffer" })
+vim.keymap.set("n", "<leader>bp", vim.cmd.bprev, 
+  { desc = "Previous Buffer" })
+
+vim.keymap.set("n", "K", vim.lsp.buf.hover)
+vim.keymap.set("n", "gd", vim.lsp.buf.definition)
+vim.keymap.set("n", "gt", vim.lsp.buf.type_definition)
+vim.keymap.set("n", "gi", vim.lsp.buf.implementation)
+vim.keymap.set("n", "ge", vim.diagnostic.goto_next)
+
+vim.keymap.set("n", "<leader>wh", vim.cmd.split,
+  { desc = "Split Window Horizontally" })
+vim.keymap.set("n", "<leader>wv", vim.cmd.vsplit,
+  { desc = "Split Window Vertically" })
+vim.keymap.set("n", "<leader>wc", "<C-w>q", 
+  { desc = "Close Window" })
+vim.keymap.set("n", "<leader>ww", "<C-w>w", 
+  { desc = "Next Window" })
+
+
+local tscope = require('telescope.builtin')
+vim.keymap.set('n', '<leader>ff', tscope.find_files, 
+  { desc = "Find File" })
+vim.keymap.set('n', '<leader>fb', tscope.buffers, 
+  { desc = "Find Buffer" })
+vim.keymap.set('n', '<leader>fh', tscope.help_tags, 
+  { desc = "Find Help" })
+vim.keymap.set('n', '<leader>fg', function()
+  tscope.grep_string(
+    { search = vim.fn.input("Grep > "), 
+    desc = "Find by Grep" });
+end)
+
+-- Setup Plugins
+require("telescope").setup({})
+require("nvim-autopairs").setup({
+  disable_filetype = { "TelescopePrompt" , "vim" }
+})
+require("nvim-highlight-colors").setup({})
+require("statuscol").setup({relculright = true})
+require("lualine").setup({
+  options = {
+    icons_enabled = false,
+    component_separators = { left = '|', right = '|'},
+    section_separators = { left = '', right = ''},
+  },
+  sections = {
+    lualine_a = {"mode","filename"},
+    lualine_b = {},
+    lualine_c = {},
+    lualine_x = {"diagnostics"},
+    lualine_y = {},
+    lualine_z = {}
+  }
+})
+require('leap').create_default_mappings()
+require('leap').opts.equivalence_classes = {
+  ' \t\r\n', '([{', ')]}', '\'"`' }
+require("nvim-treesitter.configs").setup({
+  ensure_installed = {"c", "vimdoc", "markdown", "jsonc"},
+  sync_install = false,
+  highlight = { enable = true },
+  indent = { enable = true },
+})
+-- require("config.cmp")
+local capabilities = require('cmp_nvim_lsp').default_capabilities()
+require("lspconfig").clangd.setup({capabilities = capabilities})
+require("lspconfig").rust_analyzer.setup({})
+
+-- Use Colemak Bindings
+require("config.colemak")
diff --git a/alpine-river/config/nvim/lua/config/cmp.lua b/alpine-river/config/nvim/lua/config/cmp.lua
new file mode 100644
index 0000000..13ca020
--- /dev/null
+++ b/alpine-river/config/nvim/lua/config/cmp.lua
@@ -0,0 +1,30 @@
+vim.opt.completeopt={"menu", "menuone", "noselect"}
+
+local cmp = require'cmp'
+
+cmp.setup({
+  snippet = {
+    expand = function(args)
+      require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
+      -- vim.snippet.expand(args.body) -- For native neovim snippets (Neovim v0.10+)
+    end,
+  },
+  window = {
+    -- completion = cmp.config.window.bordered(),
+    -- documentation = cmp.config.window.bordered(),
+  },
+  mapping = cmp.mapping.preset.insert({
+    ['<C-b>'] = cmp.mapping.scroll_docs(-4),
+    ['<C-f>'] = cmp.mapping.scroll_docs(4),
+    ['<C-Space>'] = cmp.mapping.complete(),
+    ['<C-e>'] = cmp.mapping.abort(),
+    ['<CR>'] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
+  }),
+  sources = cmp.config.sources({
+    { name = 'nvim_lsp' },
+    { name = 'path' },
+    { name = 'luasnip' }, -- For luasnip users.
+  }, {
+    { name = 'buffer' },
+  })
+})
diff --git a/alpine-river/config/nvim/lua/config/colemak.lua b/alpine-river/config/nvim/lua/config/colemak.lua
new file mode 100644
index 0000000..a3a8d9a
--- /dev/null
+++ b/alpine-river/config/nvim/lua/config/colemak.lua
@@ -0,0 +1,29 @@
+local function map(mode, lhs, rhs, opts)
+  local options = { noremap = true, silent = true }
+  if opts then
+    options = vim.tbl_extend("force", options, opts)
+  end
+  vim.keymap.set(mode, lhs, rhs, options)
+end
+
+map("", "n", "j")
+map("", "e", "k")
+map("", "i", "l")
+map("", "j", "n")
+map("", "k", "e")
+map("", "l", "i")
+map("", "K", "E")
+map("", "N", "J")
+map("", "E", "K") -- As in 'Explore' documentation
+map("", "L", "I")
+map("", "I", "L")
+map("", "J", "N")
+
+map("n", "<c-w>h", "<c-w>h")
+map("n", "<c-w>n", "<c-w>j")
+map("n", "<c-w>e", "<c-w>k")
+map("n", "<C-w>i", "<c-w>l")
+
+-- Kakoune Holdover
+map ("n", "gh", "0")
+map ("n", "gi", "$")
diff --git a/alpine-river/config/nvim/lua/config/lazy.lua b/alpine-river/config/nvim/lua/config/lazy.lua
new file mode 100644
index 0000000..f5ee74c
--- /dev/null
+++ b/alpine-river/config/nvim/lua/config/lazy.lua
@@ -0,0 +1,35 @@
+-- Bootstrap lazy.nvim
+local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
+if not (vim.uv or vim.loop).fs_stat(lazypath) then
+  local lazyrepo = "https://github.com/folke/lazy.nvim.git"
+  local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
+  if vim.v.shell_error ~= 0 then
+    vim.api.nvim_echo({
+      { "Failed to clone lazy.nvim:\n", "ErrorMsg" },
+      { out, "WarningMsg" },
+      { "\nPress any key to exit..." },
+    }, true, {})
+    vim.fn.getchar()
+    os.exit(1)
+  end
+end
+vim.opt.rtp:prepend(lazypath)
+
+-- Make sure to setup `mapleader` and `maplocalleader` before
+-- loading lazy.nvim so that mappings are correct.
+-- This is also a good place to setup other settings (vim.opt)
+vim.g.mapleader = " "
+vim.g.maplocalleader = "\\"
+
+-- Setup lazy.nvim
+require("lazy").setup({
+  spec = {
+    -- import your plugins
+    { import = "plugins" },
+  },
+  -- Configure any other settings here. See the documentation for more details.
+  -- colorscheme that will be used when installing plugins.
+  install = { colorscheme = { "habamax" } },
+  -- automatically check for plugin updates
+  checker = { enabled = true },
+})
diff --git a/alpine-river/config/nvim/lua/plugins.lua b/alpine-river/config/nvim/lua/plugins.lua
new file mode 100644
index 0000000..7982b53
--- /dev/null
+++ b/alpine-river/config/nvim/lua/plugins.lua
@@ -0,0 +1,32 @@
+return {
+	{"rose-pine/neovim", as = "rose-pine"},
+	{"brenoprata10/nvim-highlight-colors"},
+  {"windwp/nvim-autopairs"},
+  {"nvim-treesitter/nvim-treesitter"},
+  {"nvim-telescope/telescope.nvim",
+  dependencies = {"nvim-lua/plenary.nvim"}},
+  {"hrsh7th/nvim-cmp"},
+  {"hrsh7th/cmp-buffer"},
+  {"hrsh7th/cmp-path"},
+  {"hrsh7th/cmp-nvim-lsp"},
+  {"L3MON4D3/LuaSnip"},
+  {"saadparwaiz1/cmp_luasnip"},
+  {"ggandor/leap.nvim",
+  dependencies = {"tpope/vim-repeat"}},
+  {"nvim-lualine/lualine.nvim"},
+  {"luukvbaal/statuscol.nvim"},
+  {"Exafunction/codeium.vim", event = 'BufEnter'},
+  {"neovim/nvim-lspconfig", lazy = false,
+  dependencies = {
+      { "ms-jpq/coq_nvim", branch = "coq" },
+      { "ms-jpq/coq.artifacts", branch = "artifacts" },
+      { 'ms-jpq/coq.thirdparty', branch = "3p" }
+    },
+    init = function()
+      vim.g.coq_settings = {
+          auto_start = true, -- if you want to start COQ at startup
+          -- Your COQ settings here
+      }
+    end,
+  }
+}
diff --git a/alpine-river/config/river/init b/alpine-river/config/river/init
new file mode 100755
index 0000000..4bd10d9
--- /dev/null
+++ b/alpine-river/config/river/init
@@ -0,0 +1,200 @@
+#!/bin/sh
+
+# This is the example configuration file for river.
+#
+# If you wish to edit this, you will probably want to copy it to
+# $XDG_CONFIG_HOME/river/init or $HOME/.config/river/init first.
+#
+# See the river(1), riverctl(1), and rivertile(1) man pages for complete
+# documentation.
+
+# Note: the "Super" modifier is also known as Logo, GUI, Windows, Mod4, etc.
+
+# Super+Shift+Return to start an instance of foot (https://codeberg.org/dnkl/foot)
+riverctl map normal Super+Shift Return spawn footclient
+
+# Super+Shift F to start a floating terminal seperate from the foot server
+riverctl map normal Super+Shift F spawn "foot --app-id=float-term -W 100x40 -e fish"
+
+# Super+D to open dmenu
+riverctl map normal Super D spawn fuzzel
+
+# Super+W to open firefox
+riverctl map normal Super W spawn firefox-esr
+
+# Super+L to lock
+riverctl map normal Super L spawn swaylock
+
+# Super+Shift+Q to close the focused view
+riverctl map normal Super+Shift Q close
+
+# Super+Shift+Control+C to exit river
+riverctl map normal Super+Shift+Control C exit
+
+# Super+N and Super+E to focus the next/previous view in the layout stack
+riverctl map normal Super N focus-view next
+riverctl map normal Super E focus-view previous
+
+# Super+Shift+N and Super+Shift+E to swap the focused view with the next/previous
+# view in the layout stack
+riverctl map normal Super+Shift N swap next
+riverctl map normal Super+Shift E swap previous
+
+# Super+Period and Super+Comma to focus the next/previous output
+riverctl map normal Super Period focus-output next
+riverctl map normal Super Comma focus-output previous
+
+# Super+Shift+{Period,Comma} to send the focused view to the next/previous output
+riverctl map normal Super+Shift Period send-to-output next
+riverctl map normal Super+Shift Comma send-to-output previous
+
+# Super+Return to bump the focused view to the top of the layout stack
+riverctl map normal Super Return zoom
+
+# Super+H and Super+I to decrease/increase the main ratio of rivertile(1)
+riverctl map normal Super H send-layout-cmd rivertile "main-ratio -0.05"
+riverctl map normal Super I send-layout-cmd rivertile "main-ratio +0.05"
+
+# Super+Shift+H and Super+Shift+I to increment/decrement the main count of rivertile(1)
+riverctl map normal Super+Shift H send-layout-cmd rivertile "main-count +1"
+riverctl map normal Super+Shift I send-layout-cmd rivertile "main-count -1"
+
+# Super+Alt+{H,N,E,I} to move views
+riverctl map normal Super+Alt H move left 100
+riverctl map normal Super+Alt N move down 100
+riverctl map normal Super+Alt E move up 100
+riverctl map normal Super+Alt I move right 100
+
+# Super+Alt+Control+{H,N,E,I} to snap views to screen edges
+riverctl map normal Super+Alt+Control H snap left
+riverctl map normal Super+Alt+Control N snap down
+riverctl map normal Super+Alt+Control E snap up
+riverctl map normal Super+Alt+Control I snap right
+
+# Super+Alt+Shift+{H,N,E,I} to resize views
+riverctl map normal Super+Alt+Shift H resize horizontal -100
+riverctl map normal Super+Alt+Shift N resize vertical 100
+riverctl map normal Super+Alt+Shift E resize vertical -100
+riverctl map normal Super+Alt+Shift I resize horizontal 100
+
+# Super + Left Mouse Button to move views
+riverctl map-pointer normal Super BTN_LEFT move-view
+
+# Super + Right Mouse Button to resize views
+riverctl map-pointer normal Super BTN_RIGHT resize-view
+
+# Super + Middle Mouse Button to toggle float
+riverctl map-pointer normal Super BTN_MIDDLE toggle-float
+
+for i in $(seq 1 9)
+do
+    tags=$((1 << ($i - 1)))
+
+    # Super+[1-9] to focus tag [0-8]
+    riverctl map normal Super $i set-focused-tags $tags
+
+    # Super+Shift+[1-9] to tag focused view with tag [0-8]
+    riverctl map normal Super+Shift $i set-view-tags $tags
+
+    # Super+Control+[1-9] to toggle focus of tag [0-8]
+    riverctl map normal Super+Control $i toggle-focused-tags $tags
+
+    # Super+Shift+Control+[1-9] to toggle tag [0-8] of focused view
+    riverctl map normal Super+Shift+Control $i toggle-view-tags $tags
+done
+
+# Super+0 to focus all tags
+# Super+Shift+0 to tag focused view with all tags
+all_tags=$(((1 << 32) - 1))
+riverctl map normal Super 0 set-focused-tags $all_tags
+riverctl map normal Super+Shift 0 set-view-tags $all_tags
+
+# Super+Space to toggle float
+riverctl map normal Super Space toggle-float
+
+# Super+F to toggle fullscreen
+riverctl map normal Super F toggle-fullscreen
+
+# Super+{Up,Right,Down,Left} to change layout orientation
+riverctl map normal Super Up    send-layout-cmd rivertile "main-location top"
+riverctl map normal Super Right send-layout-cmd rivertile "main-location right"
+riverctl map normal Super Down  send-layout-cmd rivertile "main-location bottom"
+riverctl map normal Super Left  send-layout-cmd rivertile "main-location left"
+
+# Declare a passthrough mode. This mode has only a single mapping to return to
+# normal mode. This makes it useful for testing a nested wayland compositor
+riverctl declare-mode passthrough
+
+# Super+F11 to enter passthrough mode
+riverctl map normal Super F11 enter-mode passthrough
+
+# Super+F11 to return to normal mode
+riverctl map passthrough Super F11 enter-mode normal
+
+# Various media key mapping examples for both normal and locked mode which do
+# not have a modifier
+for mode in normal locked
+do
+    # Eject the optical drive (well if you still have one that is)
+    riverctl map $mode None XF86Eject spawn 'eject -T'
+
+    # Control pulse audio volume with pamixer (https://github.com/cdemoulins/pamixer)
+    riverctl map $mode None XF86AudioRaiseVolume  spawn 'pamixer -i 5'
+    riverctl map $mode None XF86AudioLowerVolume  spawn 'pamixer -d 5'
+    riverctl map $mode None XF86AudioMute         spawn 'pamixer --toggle-mute'
+
+    # Control MPRIS aware media players with playerctl (https://github.com/altdesktop/playerctl)
+    riverctl map $mode None XF86AudioMedia spawn 'playerctl play-pause'
+    riverctl map $mode None XF86AudioPlay  spawn 'playerctl play-pause'
+    riverctl map $mode None XF86AudioPrev  spawn 'playerctl previous'
+    riverctl map $mode None XF86AudioNext  spawn 'playerctl next'
+
+    # Control screen backlight brightness with brightnessctl (https://github.com/Hummer12007/brightnessctl)
+    riverctl map $mode None XF86MonBrightnessUp   spawn 'brightnessctl set +5%'
+    riverctl map $mode None XF86MonBrightnessDown spawn 'brightnessctl set 5%-'
+done
+
+# Set keyboard layout
+riverctl keyboard-layout -variant "colemak" -options "ctrl:nocaps" "us"
+
+# Set keyboard repeat rate
+riverctl set-repeat 50 300
+
+# Make all windows use ssd by default
+riverctl rule-add ssd
+
+# Make all views with an app-id that starts with "float" and title "foo" start floating.
+riverctl rule-add -app-id 'float*' float
+
+# Make all views with app-id "bar" and any title use client-side decorations
+riverctl rule-add -app-id "bar" csd
+
+# Focus follows Cursor
+riverctl focus-follows-cursor normal
+
+# Hide Cursor when typing
+riverctl hide-cursor when-typing enabled
+
+# Set Cursor Theme
+riverctl xcursor-theme BreezeX-RosePine-Linux 32
+
+# Set River Theme
+source ~/.config/river/theme
+
+### TOUCHPAD
+riverctl input "pointer-1739-0-Synaptics_tm2964-001" tap enabled
+riverctl input "pointer-1739-0-Synaptics_tm2964-001" natural-scroll enabled
+riverctl input "pointer-1739-0-Synaptics_tm2964-001" disable-while-typing enabled
+
+### SPAWNS
+riverctl spawn "/usr/libexec/pipewire-launcher"
+riverctl spawn "foot --server"
+riverctl spawn "swaybg -i ~/Pictures/.wallpaper.jpg --mode fill"
+riverctl spawn "wlsunset -S 07:00 -s 22:00"
+riverctl spawn "waybar"
+riverctl spawn "dunst"
+
+# Set the default layout generator to be rivertile and start it.
+# River will send the process group of the init executable SIGTERM on exit.
+riverctl default-layout rivertile
+rivertile -view-padding 6 -outer-padding 6 &
diff --git a/alpine-river/config/river/theme b/alpine-river/config/river/theme
new file mode 100755
index 0000000..253e3f7
--- /dev/null
+++ b/alpine-river/config/river/theme
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# Rose Pine
+rp_base=191724
+rp_text=e0def4
+rp_overlay=26233a
+rp_love=eb6f92
+rp_pine=31748f
+rp_gold=f6c177
+rp_foam=9ccfd8
+rp_iris=c4a7e7
+rp_rose=ebbcba
+rp_text=e0def4
+rp_muted=6e6a86
+
+riverctl background-color       0x$rp_base
+riverctl border-color-focused   0x$rp_rose
+riverctl border-color-unfocused 0x$rp_muted
+riverctl border-color-urgent    0x$rp_love
diff --git a/alpine-river/config/swaylock/config b/alpine-river/config/swaylock/config
new file mode 100644
index 0000000..a1841a9
--- /dev/null
+++ b/alpine-river/config/swaylock/config
@@ -0,0 +1,48 @@
+# Font
+font=FantasqueSansMono
+font-size=18
+
+# Background color
+color=#191724
+
+# Layout text colors
+layout-bg-color=#00000000
+layout-border-color=#00000000
+layout-text-color=#e0def4
+
+# Text color
+text-color=#ebbcba
+text-clear-color=#9ccfd8
+text-caps-lock-color=#f6c177
+text-ver-color=#c4a7e7
+text-wrong-color=#eb6f92
+
+# Highlight segments
+bs-hl-color=#19172466
+key-hl-color=#ebbcba
+caps-lock-bs-hl-color=#19172466
+caps-lock-key-hl-color=#f6c177
+
+# Highlight segments separator
+separator-color=#00000000
+
+# Inside of the indicator
+inside-color=#ebbcba55
+inside-clear-color=#9ccfd855
+inside-caps-lock-color=#f6c17755
+inside-ver-color=#c4a7e755
+inside-wrong-color=#eb6f9255
+
+# Line between the inside and ring
+line-color=#ebbcba11
+line-clear-color=#9ccfd811
+line-caps-lock-color=#f6c17711
+line-ver-color=#c4a7e711
+line-wrong-color=#eb6f9211
+
+# Indicator ring
+ring-color=#ebbcbaaa
+ring-clear-color=#9ccfd8aa
+ring-caps-lock-color=#f6c177aa
+ring-ver-color=#c4a7e7aa
+ring-wrong-color=#eb6f92aa
diff --git a/alpine-river/config/waybar/config b/alpine-river/config/waybar/config
new file mode 100644
index 0000000..dd524e7
--- /dev/null
+++ b/alpine-river/config/waybar/config
@@ -0,0 +1,71 @@
+{
+  "modules-left": [
+    "river/tags"
+  ],
+  "modules-center": [
+    "mpris"
+  ],
+  "modules-right": [
+    "cpu",
+    "battery",
+    "memory",
+    "temperature",
+    "clock"
+  ],
+  "battery":{
+    "format": "bat {capacity:2}%",
+    "states": {
+      "warning": 20,
+      "critical": 10
+    },
+    "tooltip": false
+  },
+  "clock": {
+    "format": "{:%T}",
+    "format-alt": "{:%a %d-%m}",
+    "interval": 1,
+    "tooltip": false
+  },
+  "network": {
+    "format-wifi": "{essid} {signalStrength}%",
+    "format-ethernet": "{ifname}: {ipaddr}/{cidr}",
+    "format-linked": "{ifname} (No IP)",
+    "format-disconnected": "Disconnected",
+    "format-alt": "{ifname}: {ipaddr}/{cidr}",
+    "tooltip": false
+  },
+  "idle_inhibitor": {
+    "tooltip": false
+  },
+  "cpu": {
+    "format": "cpu{usage:3}%",
+    "interval": 1,
+    "states": {
+      "warning": 50,
+      "critical": 90
+    },
+    "tooltip": false
+  },
+  "memory": {
+    "format": "mem {}%",
+    "interval": 1,
+    "states": {
+      "warning": 50,
+      "critical": 90
+    },
+    "tooltip": false
+  },
+  "mpris":{
+    "player": "kew",
+    "format": "{artist} - {title}",
+    "tooltip": false,
+    "max-length": 75
+  },
+  "temperature": {
+    "format": "tmp {temperatureC}°",
+    "interval": 1,
+    "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
+    "critical-threshold": 80,
+    "tooltip": false
+  }
+}
diff --git a/alpine-river/config/waybar/rose-pine.css b/alpine-river/config/waybar/rose-pine.css
new file mode 100644
index 0000000..a3ae0e4
--- /dev/null
+++ b/alpine-river/config/waybar/rose-pine.css
@@ -0,0 +1,23 @@
+/*
+* Variant: Rosé Pine
+* Maintainer: DankChoir
+*/
+
+@define-color base            #191724;
+@define-color surface         #1f1d2e;
+@define-color overlay         #26233a;
+
+@define-color muted           #6e6a86;
+@define-color subtle          #908caa;
+@define-color text            #e0def4;
+
+@define-color love            #eb6f92;
+@define-color gold            #f6c177;
+@define-color rose            #ebbcba;
+@define-color pine            #31748f;
+@define-color foam            #9ccfd8;
+@define-color iris            #c4a7e7;
+
+@define-color highlightLow    #21202e;
+@define-color highlightMed    #403d52;
+@define-color highlightHigh   #524f67;
diff --git a/alpine-river/config/waybar/style.css b/alpine-river/config/waybar/style.css
new file mode 100644
index 0000000..484f6c4
--- /dev/null
+++ b/alpine-river/config/waybar/style.css
@@ -0,0 +1,98 @@
+@import "./rose-pine.css";
+
+* {
+    border-radius: 0;
+    font-family: FantasqueSansMono;
+    font-size: 14pt;
+    min-height: 0;
+}
+
+window#waybar {
+    background-color: rgba(0,0,0,0); /* transparent */
+}
+
+#tags {
+    margin-top: 12px;
+    margin-left: 12px;
+    padding: 1px;
+    background-color: @base; /*base02*/
+    border: 2px solid @rose; /*base1*/
+}
+
+#tags button {
+    margin: 1px;
+    padding: 1px;
+    color: @text; /*base1*/
+    border: 2px solid @base; /*base02*/
+
+    /* Disable animation on click, GTK has the stupidest defaults */
+    transition-property: none;
+}
+
+/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
+#tags button:hover {
+    box-shadow: inherit;
+    text-shadow: inherit;
+    background: @base; /*base02*/
+}
+
+#tags button.focused {
+    color: @base; /*base02*/
+    background-color: @rose; /*base1*/
+    border: 2px solid @base; /*base02*/
+}
+
+#tags button.occupied {
+    border: 2px solid @rose; /*base1*/
+}
+
+#tags button.urgent {
+    border: 2px solid @love; /*red*/
+}
+
+#tags button.occupied.urgent {
+    border: 2px solid @love; /*red*/
+}
+
+#tags button.focused.occupied {
+    color: @base; /*base02*/
+    background-color: @rose; /*base1*/
+    border: 2px solid @rose; /*base1*/
+}
+
+#battery,
+#clock,
+#mode,
+#cpu,
+#memory,
+#mpris,
+#network,
+#idle_inhibitor,
+#temperature {
+    padding: 1px 5px;
+    margin-top: 12px;
+    margin-left: 12px;
+    background-color: @base; /*base02*/
+    color: @text; /*base1*/
+    border: 2px solid @rose; /*base1*/
+}
+
+#clock {
+    margin-right: 12px;
+}
+
+#mprimpris {
+    margin-left: 0px;
+    margin-right: 0px;
+}
+
+#cpu.warning,
+#memory.warning {
+    border: 2px solid @gold; /*yellow*/
+}
+
+#cpu.critical,
+#memory.critical,
+#temperature.critical {
+    border: 2px solid @love; /*red*/
+}
diff --git a/alpine-river/config/yazi/keymap.toml b/alpine-river/config/yazi/keymap.toml
new file mode 100644
index 0000000..94ca258
--- /dev/null
+++ b/alpine-river/config/yazi/keymap.toml
@@ -0,0 +1,96 @@
+"$schema" = "https://yazi-rs.github.io/schemas/keymap.json"
+
+[manager]
+
+prepend_keymap = [
+	# { on = [ "w" ], exec = 'shell "$SHELL" --block --confirm', desc = "Open shell here" },
+	# { on = [ "W" ], exec = "tasks_show" },
+
+	# Navigation
+	{ on = [ "e" ], run = "arrow -1" },
+	{ on = [ "n" ], run = "arrow 1" },
+
+	{ on = [ "E" ], run = "arrow -5" },
+	{ on = [ "N" ], run = "arrow 5" },
+
+	{ on = [ "h" ], run = "leave" },
+	{ on = [ "i" ], run = "enter" },
+
+	{ on = [ "H" ], run = "back" },
+	{ on = [ "I" ], run = "forward" },
+
+	{ on = [ "<C-e>" ], run = "seek -5" },
+	{ on = [ "<C-n>" ], run = "seek 5" },
+
+	# Operation
+	{ on = [ "k" ], run = "link" },
+	{ on = [ "K" ], run = "link --relative" },
+
+	# Find
+	{ on = [ "j" ], run = "find_arrow" },
+	{ on = [ "J" ], run = "find_arrow --previous" },
+]
+
+[tasks]
+
+prepend_keymap = [
+	{ on = [ "W" ], run = "close" },
+
+	{ on = [ "e" ], run = "arrow -1" },
+	{ on = [ "n" ], run = "arrow 1" },
+]
+
+[select]
+
+prepend_keymap = [
+	{ on = [ "e" ], run = "arrow -1" },
+	{ on = [ "n" ], run = "arrow 1" },
+
+	{ on = [ "E" ], run = "arrow -5" },
+	{ on = [ "N" ], run = "arrow 5" },
+]
+
+[input]
+
+prepend_keymap = [
+	# Mode
+	{ on = [ "l" ],     run = "insert" },
+	{ on = [ "<C-h>" ], run = [ "move -999", "insert" ] },
+	{ on = [ "<C-i>" ], run = [ "move 999", "insert --append" ] },
+
+	# Character-wise movement
+	{ on = [ "h" ], run = "move -1" },
+	{ on = [ "i" ], run = "move 1" },
+
+	# Word-wise movement
+	{ on = [ "=" ], run = "forward --end-of-word" },
+
+	# Line-wise movement
+	{ on = [ "H" ], run = "move -999" },
+	{ on = [ "I" ], run = "move 999" },
+
+	# Cut/Yank/Paste
+	{ on = [ "x" ], run = [ "delete", "move 1 --in-operating" ] },
+
+	# Undo/Redo
+	{ on = [ "u" ], run = "undo" },
+	{ on = [ "U" ], run = "redo" },
+]
+
+[completion]
+
+prepend_keymap = [
+	{ on = [ "<C-e>" ], run = "arrow -1" },
+	{ on = [ "<C-n>" ], run = "arrow 1" },
+]
+
+[help]
+
+prepend_keymap = [
+	# Navigation
+	{ on = [ "e" ], run = "arrow -1" },
+	{ on = [ "n" ], run = "arrow 1" },
+
+	{ on = [ "E" ], run = "arrow -5" },
+	{ on = [ "N" ], run = "arrow 5" },
+]
diff --git a/alpine-river/config/yazi/rose-pine.tmTheme b/alpine-river/config/yazi/rose-pine.tmTheme
new file mode 100644
index 0000000..e90da85
--- /dev/null
+++ b/alpine-river/config/yazi/rose-pine.tmTheme
@@ -0,0 +1,959 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+    <key>name</key>
+    <string>Catppuccin</string>
+    <key>settings</key>
+    <array>
+      <dict>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#908caa</string>
+          <key>background</key>
+          <string>#191724</string>
+          <key>caret</key>
+          <string>#E0DEF4</string>
+          <key>invisibles</key>
+          <string>#e0def4</string>
+          <key>gutterForeground</key>
+          <string>#575279</string>
+          <key>gutterForegroundHighlight</key>
+          <string>#9ccfd8</string>
+          <key>lineHighlight</key>
+          <string>#26233A</string>
+          <key>selection</key>
+          <string>#393552</string>
+          <key>selectionBorder</key>
+          <string>#191724</string>
+          <key>activeGuide</key>
+          <string>#eb6f92</string>
+          <key>findHighlightForeground</key>
+          <string>#181825</string>
+          <key>findHighlight</key>
+          <string>#f6c177</string>
+          <key>bracketsForeground</key>
+          <string>#575279</string>
+          <key>bracketContentsForeground</key>
+          <string>#575279</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Comment</string>
+        <key>scope</key>
+        <string>comment</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#393552</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>String</string>
+        <key>scope</key>
+        <string>string</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#9ccfd8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>String regex</string>
+        <key>scope</key>
+        <string>string.regexp</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eb6f92</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Number</string>
+        <key>scope</key>
+        <string>constant.numeric</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eb6f92</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Boolean</string>
+        <key>scope</key>
+        <string>constant.language.boolean</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eb6f92</string>
+          <key>fontStyle</key>
+          <string>bold italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Built-in constant</string>
+        <key>scope</key>
+        <string>constant.language</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#E0DEF4</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Built-in function</string>
+        <key>scope</key>
+        <string>support.function.builtin</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eb6f92</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>User-defined constant</string>
+        <key>scope</key>
+        <string>variable.other.constant</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eb6f92</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Variable</string>
+        <key>scope</key>
+        <string>variable</string>
+        <key>settings</key>
+        <dict></dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Keyword</string>
+        <key>scope</key>
+        <string>keyword</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eb6f92</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Conditional/loop</string>
+        <key>scope</key>
+        <string>keyword.control.loop, keyword.control.conditional, keyword.control.c++</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#cba6f7</string>
+          <key>fontStyle</key>
+          <string>bold</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Return</string>
+        <key>scope</key>
+        <string>keyword.control.return, keyword.control.flow.return</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#B4637A</string>
+          <key>fontStyle</key>
+          <string>bold</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Exception</string>
+        <key>scope</key>
+        <string>support.type.exception</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eb6f92</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Operator</string>
+        <key>scope</key>
+        <string>keyword.operator, punctuation.accessor</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#89dceb</string>
+          <key>fontStyle</key>
+          <string>bold</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Punctuation separator</string>
+        <key>scope</key>
+        <string>punctuation.separator</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#9ccfd8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Punctuation terminator</string>
+        <key>scope</key>
+        <string>punctuation.terminator</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#9ccfd8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Punctuation bracket</string>
+        <key>scope</key>
+        <string>punctuation.section</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#575279</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Include</string>
+        <key>scope</key>
+        <string>keyword.control.import.include</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#9ccfd8</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Storage</string>
+        <key>scope</key>
+        <string>storage</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#f38ba8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Storage type</string>
+        <key>scope</key>
+        <string>storage.type</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#f6c177</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Storage modifier</string>
+        <key>scope</key>
+        <string>storage.modifier</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#f38ba8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Storage type namespace</string>
+        <key>scope</key>
+        <string>entity.name.namespace, meta.path</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#74658B</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Storage type class</string>
+        <key>scope</key>
+        <string>storage.type.class</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#74658B</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Label</string>
+        <key>scope</key>
+        <string>entity.name.label</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#31748F</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Keyword class</string>
+        <key>scope</key>
+        <string>keyword.declaration.class</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#f38ba8</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Class name</string>
+        <key>scope</key>
+        <string>entity.name.class, meta.toc-list.full-identifier</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#89dceb</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Inherited class</string>
+        <key>scope</key>
+        <string>entity.other.inherited-class</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#89dceb</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Function name</string>
+        <key>scope</key>
+        <string>entity.name.function, variable.function</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#31748F</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Function macro</string>
+        <key>scope</key>
+        <string>entity.name.function.preprocessor</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#f38ba8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Macro directive - ifdef</string>
+        <key>scope</key>
+        <string>keyword.control.import</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#f38ba8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Constructor</string>
+        <key>scope</key>
+        <string>entity.name.function.constructor, entity.name.function.destructor</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#E0DEF4</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Function argument</string>
+        <key>scope</key>
+        <string>variable.parameter.function</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#74658B</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Function declaration</string>
+        <key>scope</key>
+        <string>keyword.declaration.function</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eba0ac</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Library function</string>
+        <key>scope</key>
+        <string>support.function</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#89dceb</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Library constant</string>
+        <key>scope</key>
+        <string>support.constant</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#31748F</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Library class/type</string>
+        <key>scope</key>
+        <string>support.type, support.class</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#31748F</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Library variable</string>
+        <key>scope</key>
+        <string>support.other.variable</string>
+        <key>settings</key>
+        <dict>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Variable function</string>
+        <key>scope</key>
+        <string>variable.function</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#31748F</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Variable parameter</string>
+        <key>scope</key>
+        <string>variable.parameter</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#74658B</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Variable other</string>
+        <key>scope</key>
+        <string>variable.other</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#908caa</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Variable field</string>
+        <key>scope</key>
+        <string>variable.other.member</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#74658B</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Variable language</string>
+        <key>scope</key>
+        <string>variable.language</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#9ccfd8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Tag name</string>
+        <key>scope</key>
+        <string>entity.name.tag</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eb6f92</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Tag attribute</string>
+        <key>scope</key>
+        <string>entity.other.attribute-name</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#cba6f7</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Tag delimiter</string>
+        <key>scope</key>
+        <string>punctuation.definition.tag</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eba0ac</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Markdown URL</string>
+        <key>scope</key>
+        <string>markup.underline.link.markdown</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#74658B</string>
+          <key>fontStyle</key>
+          <string>italic underline</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Markdown reference</string>
+        <key>scope</key>
+        <string>meta.link.inline.description</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#74658B</string>
+          <key>fontStyle</key>
+          <string>bold</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Markdown literal</string>
+        <key>scope</key>
+        <string>comment.block.markdown, meta.code-fence, markup.raw.code-fence, markup.raw.inline</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#9ccfd8</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Markdown title</string>
+        <key>scope</key>
+        <string>punctuation.definition.heading, entity.name.section</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#31748F</string>
+          <key>fontStyle</key>
+          <string>bold</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Markdown emphasis</string>
+        <key>scope</key>
+        <string>markup.italic</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eba0ac</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Markdown strong</string>
+        <key>scope</key>
+        <string>markup.bold</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#eba0ac</string>
+          <key>fontStyle</key>
+          <string>bold</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Escape</string>
+        <key>scope</key>
+        <string>constant.character.escape</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#B4637A</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Bash built-in function</string>
+        <key>scope</key>
+        <string>source.shell.bash meta.function.shell meta.compound.shell meta.function-call.identifier.shell</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#B4637A</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Bash parameter</string>
+        <key>scope</key>
+        <string>variable.language.shell</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#f38ba8</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Lua field</string>
+        <key>scope</key>
+        <string>source.lua meta.function.lua meta.block.lua meta.mapping.value.lua meta.mapping.key.lua string.unquoted.key.lua</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#E0DEF4</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Lua constructor</string>
+        <key>scope</key>
+        <string>source.lua meta.function.lua meta.block.lua meta.mapping.key.lua string.unquoted.key.lua</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#E0DEF4</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Java constant</string>
+        <key>scope</key>
+        <string>entity.name.constant.java</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#9ccfd8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>CSS property</string>
+        <key>scope</key>
+        <string>support.type.property-name.css</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#E0DEF4</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>CSS constant</string>
+        <key>scope</key>
+        <string>support.constant.property-value.css</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#908caa</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>CSS suffix</string>
+        <key>scope</key>
+        <string>constant.numeric.suffix.css, keyword.other.unit.css</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#9ccfd8</string>
+          <key>fontStyle</key>
+          <string>italic</string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>CSS variable property</string>
+        <key>scope</key>
+        <string>variable.other.custom-property.name.css, support.type.custom-property.name.css, punctuation.definition.custom-property.css</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#9ccfd8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>SCSS tag</string>
+        <key>scope</key>
+        <string>entity.name.tag.css</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#E0DEF4</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>SASS variable</string>
+        <key>scope</key>
+        <string>variable.other.sass</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#9ccfd8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Invalid</string>
+        <key>scope</key>
+        <string>invalid</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#908caa</string>
+          <key>background</key>
+          <string>#f38ba8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Invalid deprecated</string>
+        <key>scope</key>
+        <string>invalid.deprecated</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#908caa</string>
+          <key>background</key>
+          <string>#cba6f7</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Diff header</string>
+        <key>scope</key>
+        <string>meta.diff, meta.diff.header</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#393552</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Diff deleted</string>
+        <key>scope</key>
+        <string>markup.deleted</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#f38ba8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Diff inserted</string>
+        <key>scope</key>
+        <string>markup.inserted</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#9ccfd8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Diff changed</string>
+        <key>scope</key>
+        <string>markup.changed</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#f6c177</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+      <dict>
+        <key>name</key>
+        <string>Message error</string>
+        <key>scope</key>
+        <string>message.error</string>
+        <key>settings</key>
+        <dict>
+          <key>foreground</key>
+          <string>#f38ba8</string>
+          <key>fontStyle</key>
+          <string></string>
+        </dict>
+      </dict>
+    </array>
+    <key>uuid</key>
+    <string>4d0379b5-ef82-467b-b8b8-365889420646</string>
+    <key>colorSpaceName</key>
+    <string>sRGB</string>
+    <key>semanticClass</key>
+    <string>theme.dark.Catppuccin</string>
+    <key>author</key>
+    <string>BrunDerSchwarzmagier</string>
+  </dict>
+</plist>
diff --git a/alpine-river/config/yazi/theme.toml b/alpine-river/config/yazi/theme.toml
new file mode 100644
index 0000000..2c92781
--- /dev/null
+++ b/alpine-river/config/yazi/theme.toml
@@ -0,0 +1,153 @@
+# vim:fileencoding=utf-8:foldmethod=marker
+
+# : Manager {{{
+
+[manager]
+cwd = { fg = "#9ccfd8" }
+
+# Hovered
+hovered = { fg = "#e0def4", bg = "#26233a" }
+preview_hovered = { underline = true }
+
+# Find
+find_keyword = { fg = "#f6c177", italic = true }
+find_position = { fg = "#eb6f92", bg = "reset", italic = true }
+
+# Marker
+marker_selected = { fg = "#9ccfd8", bg = "#9ccfd8" }
+marker_copied = { fg = "#f6c177", bg = "#f6c177" }
+marker_cut = { fg = "#B4637A", bg = "#B4637A" }
+
+# Tab
+tab_active = { fg = "#e0def4", bg = "#191724" }
+tab_inactive = { fg = "#e0def4", bg = "#2A273F" }
+tab_width = 1
+
+# Border
+border_symbol = "│"
+border_style = { fg = "#524f67" }
+
+# Highlighting
+syntect_theme = "~/.config/yazi/rose-pine.tmTheme"
+
+# : }}}
+
+
+# : Status {{{
+
+[status]
+separator_open = ""
+separator_close = ""
+separator_style = { fg = "#2A273F", bg = "#2A273F" }
+
+# Mode
+mode_normal = { fg = "#191724", bg = "#ebbcba", bold = true }
+mode_select = { fg = "#e0def4", bg = "#9ccfd8", bold = true }
+mode_unset = { fg = "#e0def4", bg = "#b4637a", bold = true }
+
+# Progress
+progress_label = { fg = "#e0def4", bold = true }
+progress_normal = { fg = "#191724", bg = "#2A273F" }
+progress_error = { fg = "#B4637A", bg = "#2A273F" }
+
+# Permissions
+permissions_t = { fg = "#31748f" }
+permissions_r = { fg = "#f6c177" }
+permissions_w = { fg = "#B4637A" }
+permissions_x = { fg = "#9ccfd8" }
+permissions_s = { fg = "#524f67" }
+
+# : }}}
+
+
+# : Input {{{
+
+[input]
+border = { fg = "#524f67" }
+title = {}
+value = {}
+selected = { reversed = true }
+
+# : }}}
+
+
+# : Select {{{
+
+[select]
+border = { fg = "#524f67" }
+active = { fg = "#eb6f92" }
+inactive = {}
+
+# : }}}
+
+
+# : Tasks {{{
+
+[tasks]
+border = { fg = "#524f67" }
+title = {}
+hovered = { underline = true }
+
+# : }}}
+
+
+# : Which {{{
+
+[which]
+mask = { bg = "#313244" }
+cand = { fg = "#9ccfd8" }
+rest = { fg = "#9399b2" }
+desc = { fg = "#eb6f92" }
+separator = "  "
+separator_style = { fg = "#585b70" }
+
+# : }}}
+
+
+# : Help {{{
+
+[help]
+on = { fg = "#eb6f92" }
+exec = { fg = "#9ccfd8" }
+desc = { fg = "#9399b2" }
+hovered = { bg = "#585b70", bold = true }
+footer = { fg = "#2A273F", bg = "#e0def4" }
+
+# : }}}
+
+
+# : File-specific styles {{{
+
+[filetype]
+
+rules = [
+    # Images
+    { mime = "image/*", fg = "#9ccfd8" },
+
+    # Videos
+    { mime = "video/*", fg = "#f6c177" },
+    { mime = "audio/*", fg = "#f6c177" },
+
+    # Archives
+    { mime = "application/zip", fg = "#eb6f92" },
+    { mime = "application/gzip", fg = "#eb6f92" },
+    { mime = "application/x-tar", fg = "#eb6f92" },
+    { mime = "application/x-bzip", fg = "#eb6f92" },
+    { mime = "application/x-bzip2", fg = "#eb6f92" },
+    { mime = "application/x-7z-compressed", fg = "#eb6f92" },
+    { mime = "application/x-rar", fg = "#eb6f92" },
+
+    # Fallback
+    { name = "*", fg = "#e0def4" },
+    { name = "*/", fg = "#524f67" },
+]
+
+# : }}}
+
+# Disable Nerds
+[icon]
+globs = []
+dirs  = []
+files = []
+exts  = []
+conds = []
diff --git a/alpine-river/config/yazi/yazi.toml b/alpine-river/config/yazi/yazi.toml
new file mode 100644
index 0000000..4e4a4e2
--- /dev/null
+++ b/alpine-river/config/yazi/yazi.toml
@@ -0,0 +1,6 @@
+[manager]
+# show_hidden = true
+sort_by = "modified"
+sort_reverse = true
+linemode = "size"
+scrolloff = 12
diff --git a/alpine-river/local/bin/dry b/alpine-river/local/bin/dry
new file mode 100755
index 0000000..0bca4a0
--- /dev/null
+++ b/alpine-river/local/bin/dry
Binary files differdiff --git a/alpine-river/local/bin/kanata b/alpine-river/local/bin/kanata
new file mode 100755
index 0000000..a88cf14
--- /dev/null
+++ b/alpine-river/local/bin/kanata
Binary files differdiff --git a/alpine-river/local/bin/kew b/alpine-river/local/bin/kew
new file mode 100755
index 0000000..7949cec
--- /dev/null
+++ b/alpine-river/local/bin/kew
Binary files differdiff --git a/alpine-river/local/bin/take-slurpshot b/alpine-river/local/bin/take-slurpshot
new file mode 100755
index 0000000..0edc9ec
--- /dev/null
+++ b/alpine-river/local/bin/take-slurpshot
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Generate base filename with timestamp
+base_filename=$(date +"%m-%d-%Y_%H-%M-%S")
+extension=".png"
+
+# Initialize full filename
+filename="${base_filename}${extension}"
+counter=1
+
+# Check if file exists and append incremental suffix if needed
+while [[ -e "$filename" ]]; do
+    filename="${base_filename}-${counter}${extension}"
+    ((counter++))
+done
+
+# Output the available filename
+wayshot -f "$HOME/Pictures/Screenshots/$filename" -s "$(slurp)"
diff --git a/alpine-river/local/bin/ya b/alpine-river/local/bin/ya
new file mode 100755
index 0000000..7a8ee1d
--- /dev/null
+++ b/alpine-river/local/bin/ya
Binary files differdiff --git a/alpine-river/local/bin/yazi b/alpine-river/local/bin/yazi
new file mode 100755
index 0000000..5ce96d0
--- /dev/null
+++ b/alpine-river/local/bin/yazi
Binary files differdiff --git a/alpine-river/profile b/alpine-river/profile
new file mode 100644
index 0000000..49fd884
--- /dev/null
+++ b/alpine-river/profile
@@ -0,0 +1,17 @@
+export XDG_SESSION_TYPE=wayland
+export XDG_CURRENT_DESKTOP=river
+export LIBSEAT_BACKEND=seatd
+
+# Setup XDG_RUNTIME_DIR
+if [ -z "$XDG_RUNTIME_DIR" ]; then
+  XDG_RUNTIME_DIR="/tmp/$(id -u)-runtime-dir"
+
+  mkdir -pm 0700 "$XDG_RUNTIME_DIR"
+  export XDG_RUNTIME_DIR
+fi
+
+# Start River
+if [ -z "$WAYLAND_DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ]; then
+  exec dbus-run-session river > ~/.river.log 2>&1
+fi
+. "$HOME/.cargo/env"
diff --git a/alpine-river/screenshot.png b/alpine-river/screenshot.png
new file mode 100644
index 0000000..310ae10
--- /dev/null
+++ b/alpine-river/screenshot.png
Binary files differdiff --git a/alpine-river/tmux.conf b/alpine-river/tmux.conf
new file mode 100644
index 0000000..8edbe2c
--- /dev/null
+++ b/alpine-river/tmux.conf
@@ -0,0 +1,76 @@
+# Set Shell to ZSH
+set-option -g default-shell /usr/bin/fish
+
+# Use C-t and C-n for the prefix
+set-option -g prefix C-space
+
+# Easy Config Reload
+bind-key r source-file ~/.tmux.conf \; display-message "Config reloaded"
+
+# Mouse Mode
+set -g mouse on
+
+# Fix Colors
+set -g default-terminal "screen-256color"
+set -ga terminal-overrides ",*col*:Tc"
+
+# Switch Pane Keys
+bind-key h select-pane -L
+bind-key i select-pane -R
+bind-key e select-pane -U
+bind-key n select-pane -D
+
+# Easier Splitting
+bind-key v split-window -h -c "#{pane_current_path}"
+bind-key s split-window -v -c "#{pane_current_path}"
+
+# Quick Create and tab through windows
+# bind-key -n C-Tab next-window
+# bind-key -n C-S-Tab previous-window
+bind-key Tab next-window
+bind-key k kill-window
+bind-key c new-window
+
+# Fix delay on vim escape
+set -s escape-time 0
+
+# Change background color of a tab when activity occurs
+setw -g monitor-activity on
+
+# Do NOT reset the color of the tab after activity stops occuring
+setw -g monitor-silence 0
+
+# Disable bell
+setw -g monitor-bell off
+
+# Disable visual text box when activity occurs
+set -g visual-activity off
+
+# Images in TMUX
+set -g allow-passthrough all
+set -ga update-environment TERM
+set -ga update-environment TERM_PROGRAM
+
+# mpris
+
+# tmux2k
+set -g @tmux2k-start-icon "λ"
+set -g @tmux2k-theme 'duo'
+set -g @tmux2k-duo-bg '#ebbcba'
+set -g @tmux2k-duo-fg '#191724'
+set -g @tmux2k-icons-only true
+set -g @tmux2k-left-plugins " "
+set -g @tmux2k-right-plugins " "
+set -g @tmux2k-refresh-rate 1
+set -g @tmux2k-window-list-alignment "left"
+set -g @tmux2k-compact-windows false #remove
+set -g @tmux2k-military-time true
+set -g @tmux2k-day-month true
+
+# TMUX Packages
+
+set -g @plugin 'tmux-plugins/tpm'
+set -g @plugin 'tmux-plugins/tmux-sensible'
+set -g @plugin 'venomade/tmux2k'
+
+run '~/.tmux/plugins/tpm/tpm'
diff --git a/alpine-river/world b/alpine-river/world
new file mode 100644
index 0000000..84c3419
--- /dev/null
+++ b/alpine-river/world
@@ -0,0 +1,93 @@
+alpine-base
+bash
+bat
+brightnessctl
+btop
+busybox-doc
+busybox-mdev-openrc
+chafa-libs
+clang19-extra-tools
+curl
+dbus
+doas
+docker
+docker-doc
+dosfstools
+dunst
+e2fsprogs
+emacs-doc
+emacs-pgtk-nativecomp
+eudev
+eza
+faad2-libs
+fastfetch
+fd
+fftw-single-libs
+file
+firefox-esr
+fish
+font-iosevka
+font-noto
+font-noto-cjk
+font-roboto
+foot
+fuse3
+fuzzel
+fzf
+gcompat
+git
+grep
+grub-efi
+iw
+lazygit
+libtag
+libva-intel-driver
+linux-firmware-i915
+linux-firmware-intel
+linux-firmware-mediatek
+linux-firmware-other
+linux-firmware-rtl_bt
+linux-lts
+maim
+make
+man-pages
+mandoc
+mesa-dri-gallium
+mesa-va-gallium
+mpv
+ncpamixer
+neovim
+neovim-doc
+openntpd
+openssh
+openssl
+opusfile
+pamixer
+pipewire
+pipewire-pulse
+playerctl
+rclone
+ripgrep
+river
+river-doc
+seatd
+slurp
+swaybg
+swayidle
+swayidle-doc
+swaylock
+tmux
+udev
+udev-init-scripts
+udev-init-scripts-openrc
+unzip
+waybar
+waybar-doc
+wayshot
+wf-recorder
+wireplumber
+wl-clipboard
+wlr-randr
+wlsunset
+wpa_supplicant
+xdg-utils