From f4c4550e327d9090c82a735d39d104d0bedb602d Mon Sep 17 00:00:00 2001
From: Benjamin Chausse <benjamin@chausse.xyz>
Date: Sun, 30 Mar 2025 01:00:51 -0400
Subject: Loads of laptop shit

---
 .config/aliasrc             |   2 +
 .config/foot/foot.ini       |   2 +-
 .config/git/config          |  21 +-
 .config/lf/clean            |   3 +
 .config/lf/cleaner          |   4 -
 .config/lf/kitty.sh         |  44 ++++
 .config/lf/lfrc             |  30 +--
 .config/lf/preview          |  68 +++++
 .config/lf/scope            |  29 +-
 .config/river/init          | 628 ++++++++++++++++++++++++++++++++++++++++++++
 .config/shortcutrc          |   8 +-
 .config/tofi/config         |  19 ++
 .config/waybar/config.json  |   9 +-
 .config/waybar/modules.json |  34 ++-
 .config/waybar/style.css    |  14 +-
 .config/zsh/.zshrc          |   8 +
 16 files changed, 864 insertions(+), 59 deletions(-)
 create mode 100755 .config/lf/clean
 delete mode 100755 .config/lf/cleaner
 create mode 100755 .config/lf/kitty.sh
 create mode 100755 .config/lf/preview
 create mode 100755 .config/river/init
 create mode 100644 .config/tofi/config

(limited to '.config')

diff --git a/.config/aliasrc b/.config/aliasrc
index f8ccd09..a1d34be 100644
--- a/.config/aliasrc
+++ b/.config/aliasrc
@@ -17,7 +17,9 @@
 :e,      $EDITOR
 :q,      exit
 cdd,     cd ..
+disks,   lsblk -o ID-LINK,MOUNTPOINT,FSTYPE,FSUSE%,SIZE
 e,       $EDITOR
+db,      maestral
 w,       $BROWSER
 g,       git
 ff,      fastfetch --raw $HOME/.cache/gentoo.six --logo-width 32 --logo-height 24 --logo-padding 2
diff --git a/.config/foot/foot.ini b/.config/foot/foot.ini
index 6331160..9750704 100644
--- a/.config/foot/foot.ini
+++ b/.config/foot/foot.ini
@@ -8,7 +8,7 @@ app-id=foot # globally set wayland app-id. Default values are "foot" and "footcl
 title=foot
 locked-title=no
 
-font=monospace:size=8
+font=monospace:size=13
 # font-bold=<bold variant of regular font>
 # font-italic=<italic variant of regular font>
 # font-bold-italic=<bold+italic variant of regular font>
diff --git a/.config/git/config b/.config/git/config
index 00ece71..9fa0732 100644
--- a/.config/git/config
+++ b/.config/git/config
@@ -1,6 +1,4 @@
-# This is Git's per-user configuration file.
 [user]
-# Please adapt and uncomment the following lines:
 name = Benjamin Chausse
 email = benjamin@chausse.xyz
 signingkey = ABC4A5A7430D6309ACBD219044F94DD6456590C3
@@ -12,8 +10,27 @@ signingkey = ABC4A5A7430D6309ACBD219044F94DD6456590C3
 	rebase = false
 [commit]
 	gpgsign = true
+[tag]
+	gpgsign = true
 [sendemail]
 	smtpserver = mail.chausse.xyz
 	smtpuser = benjamin
 	smtpserverport = 587
 	smtpencryption = tls
+[filter "lfs"]
+	clean = git-lfs clean -- %f
+	smudge = git-lfs smudge -- %f
+	process = git-lfs filter-process
+	required = true
+[safe]
+	directory = /home/master/.local/src/river
+[url "git@github.com:"]
+	insteadOf = https://github.com/
+[core]
+	pager = delta
+[interactive]
+	diffFilter = delta --color-only
+[delta]
+	navigate = true
+[merge]
+	conflictStyle = zdiff3
diff --git a/.config/lf/clean b/.config/lf/clean
new file mode 100755
index 0000000..4bbbaf1
--- /dev/null
+++ b/.config/lf/clean
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+$XDG_CONFIG_HOME/lf/kitty.sh delete_img $LF_KITTY_IMAGE_ID 0
diff --git a/.config/lf/cleaner b/.config/lf/cleaner
deleted file mode 100755
index a184d84..0000000
--- a/.config/lf/cleaner
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-if [ -n "$FIFO_UEBERZUG" ]; then
-	printf '{"action": "remove", "identifier": "PREVIEW"}\n' > "$FIFO_UEBERZUG"
-fi
diff --git a/.config/lf/kitty.sh b/.config/lf/kitty.sh
new file mode 100755
index 0000000..fa84b3f
--- /dev/null
+++ b/.config/lf/kitty.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+# Transmits an image in png format via file-mode transmission.
+#   $1 file path
+#   $2 image id
+transmit_file_png() {
+	abspath_b64="$(printf -- "$(realpath -- "$1")" | base64 -w0)"
+	printf "\e_Gt=f,i=$2,f=100,q=1;$abspath_b64\e\\" >/dev/tty
+}
+
+# Displays an already transferred image.
+#   $1 image id
+#   $2 placement id
+#   $3 x, $4 y, $5 w, $6 h
+display_img() {
+    printf "\e[s" >/dev/tty # save cursor position
+    tput cup $4 $3 >/dev/tty # move cursor
+    printf "\e_Ga=p,i=$1,p=$2,q=1\e\\" >/dev/tty
+    printf "\e[u" >/dev/tty # restore cursor position
+}
+
+# Deletes a displayed image.
+#   $1 image id
+#   $2 placement id
+delete_img() {
+	printf "\e_Ga=d,d=I,i=$1,p=$2,q=1\e\\" >/dev/tty
+}
+
+# Combines transmit_file_png and display_img.
+#   $1 file path
+#   $2 image id
+#   $3 placement id
+#   $4 x, $5 y, $6 w, $7 h
+show() {
+    local img_width img_height new_width new_height
+    img_width=$(identify -format "%w" "$1")
+    img_height=$(identify -format "%h" "$1")
+    new_width=$6
+    new_height=$7
+    transmit_file_png "$1" "$2"
+    display_img "$2" "$3" "$4" "$5" "$new_width" "$new_height"
+}
+
+"$@"
diff --git a/.config/lf/lfrc b/.config/lf/lfrc
index fe28549..48a5d0d 100755
--- a/.config/lf/lfrc
+++ b/.config/lf/lfrc
@@ -1,20 +1,3 @@
-# Luke's lf settings
-
-
-# Note on Image Previews
-# For those wanting image previews, like this system, there are four steps to
-# set it up. These are done automatically for LARBS users, but I will state
-# them here for others doing it manually.
-#
-# 1. ueberzug must be installed.
-# 2. The scope file (~/.config/lf/scope for me), must have a command similar to
-#    mine to generate ueberzug images.
-# 3. A `set cleaner` line as below is a cleaner script.
-# 4. lf should be started through a wrapper script (~/.local/bin/lfub for me)
-#    that creates the environment for ueberzug. This command can be be aliased
-#    in your shellrc (`alias lf="lfub") or if set to a binding, should be
-#    called directly instead of normal lf.
-
 # Basic vars
 set sixel true
 set shellopts '-eu'
@@ -23,10 +6,11 @@ set scrolloff 10
 set icons
 set period 1
 set hiddenfiles ".*:*.aux:*.log:*.bbl:*.bcf:*.blg:*.run.xml:tags:*.org_archive"
-set cleaner '~/.config/lf/cleaner'
-set previewer '~/.config/lf/scope'
 set autoquit true
 
+set previewer '~/.config/lf/preview'
+set cleaner '~/.config/lf/clean'
+
 # cmds/functions
 cmd open ${{
     case $(file --mime-type "$(readlink -f $f)" -b) in
@@ -75,7 +59,7 @@ cmd moveto ${{
 	clear; tput cup $(($(tput lines)/3)); tput bold
 	set -f
 	clear; echo "Move to where?"
-	dest="$(sed -e 's/\s*#.*//' -e '/^$/d' -e 's/^\S*\s*//' ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs | fzf | sed 's|~|$HOME|')" &&
+	dest="$(fzf-shortcuts)" &&
 	for x in $fx; do
 		eval mv -iv \"$x\" \"$dest\"
 	done &&
@@ -117,8 +101,6 @@ cmd bulkrename ${{
 }}
 
 # Bindings
-map <c-f> $lf -remote "send $id select \"$(fzf)\""
-map J $lf -remote "send $id cd $(sed -e 's/\s*#.*//' -e '/^$/d' -e 's/^\S*\s*//' ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs | fzf)"
 map D delete
 map <c-n> push :mkdir<space>
 map <c-r> reload
@@ -143,10 +125,10 @@ map V push :!nvim<space>
 map N push :!touch<space>
 
 map W $setsid -f $TERMINAL >/dev/null 2>&1
-map Y $printf "%s" "$fx" | xclip -selection clipboard
+map Y $printf "%s" "$fx" | wl-copy
 map E $dropbox-cli exclude add "$f" && notify-send -a " Dropbox" "Excluded $f from computer"
 map R $dropbox-restore "$f"
-map S $dropbox-cli sharelink "$f" | xsel -b && notify-send -a " Dropbox" "Link copied to clipboard."
+map S $dropbox-cli sharelink "$f" | wl-copy && notify-send -a " Dropbox" "Link copied to clipboard."
 
 # Source Bookmarks
 source "~/.config/lf/shortcuts"
diff --git a/.config/lf/preview b/.config/lf/preview
new file mode 100755
index 0000000..635edc9
--- /dev/null
+++ b/.config/lf/preview
@@ -0,0 +1,68 @@
+#!/bin/bash
+
+set -C -f
+IFS="$(printf '%b_' '\n')"
+IFS="${IFS%_}"
+
+# Called by lf to generate the preview.
+#   $1 file path
+#   $4 x offset in cell coordinates
+#   $5 y offset in cell coordinates
+#   $2 width of the display area in cell coordinates
+#   $3 height of the display area in cell coordinates
+THUMBNAIL_FPATH="$LF_KITTY_TEMPDIR/thumbnail.png"
+
+# case "$(basename -- "$1" | tr '[:upper:]' '[:lower:]')" in
+case "$(file --dereference --brief --mime-type -- "$1")" in
+text/html)
+  lynx -width="$4" -display_charset=utf-8 -dump "$1"
+  ;;
+text/troff)
+  w=`expr "$2" - 2`
+  MANWIDTH="$w" man ./ "$1"
+  ;;
+text/* | */xml)
+  [ "${1##*.}" = "md" ] && glow -s dark -w "$2" "$1" && exit 0
+  bat --terminal-width "$(($4 - 2))" -f "$1"
+  ;;
+application/json | application/x-ndjson)
+  jq -C < "$1" ;;
+audio/* | application/octet-stream)
+  mediainfo "$1" || exit 1
+  ;;
+image/png)
+	$XDG_CONFIG_HOME/lf/kitty.sh show "$1" $LF_KITTY_IMAGE_ID 1 $4 $5 $2 $3
+	;;
+image/gif)
+	magick convert "${1}[0]" "$THUMBNAIL_FPATH"
+	$XDG_CONFIG_HOME/lf/kitty.sh show "$THUMBNAIL_FPATH" $LF_KITTY_IMAGE_ID 1 $4 $5 $2 $3
+	;;
+image/*)
+	magick convert "$1" "$THUMBNAIL_FPATH"
+	$XDG_CONFIG_HOME/lf/kitty.sh show "$THUMBNAIL_FPATH" $LF_KITTY_IMAGE_ID 1 $4 $5 $2 $3
+	;;
+application/pdf)
+	gs -o "$THUMBNAIL_FPATH" -sDEVICE=pngalpha -dLastPage=1 "$1" >/dev/null
+	$XDG_CONFIG_HOME/lf/kitty.sh show "$THUMBNAIL_FPATH" $LF_KITTY_IMAGE_ID 1 $4 $5 $2 $3
+	;;
+font/* | application/vnd.ms-opentype)
+  FONT_NAME=$(fc-query --format "%{family}\n" "$1" | head -n 1)
+
+  PREVIEW_TEXT="${FONT_NAME}\nABCDEFGHIJKLMNOPQRSTUBWXYZ\n""\
+abcdefghijklmnopqrstuvwxyz\n""\
+1234567890\n""\
+!@#$\%(){}[]-+=_\`~"
+
+  magick convert -size "1920x1080" xc:'#ffffff' \
+    -gravity center -pointsize 76 \
+    -font "$1" \
+    -fill '#000000' \
+    -annotate +0+0 "$PREVIEW_TEXT" \
+    "$THUMBNAIL_FPATH"
+	$XDG_CONFIG_HOME/lf/kitty.sh show "$THUMBNAIL_FPATH" $LF_KITTY_IMAGE_ID 1 $4 $5 $2 $3
+  ;;
+*)
+	cat "$1"
+	;;
+esac
+exit 127
diff --git a/.config/lf/scope b/.config/lf/scope
index e2a77f7..d28177d 100755
--- a/.config/lf/scope
+++ b/.config/lf/scope
@@ -8,7 +8,7 @@ PREVIEW_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/lf"
 PREVIEW_WIDTH=600 # px
 
 chafafunc() {
-  chafa -f sixel -O 0 --polite on -c full --color-space din99d -w 9 -t 0.8 --size "$1"x
+  chafa -f sixel -O 0 --polite on -c full -w 9 -t 0.8 --view-size "$1"x"$2" --animate false --fg-only
 }
 
 # Prevent recursive thumbnails (if the file ends in .six)
@@ -19,16 +19,22 @@ text/html)
   lynx -width="$4" -display_charset=utf-8 -dump "$1"
   ;;
 text/troff)
-  man ./ "$1" | col -b
+  w=`expr "$2" - 2`
+  MANWIDTH="$w" man ./ "$1"
   ;;
-text/* | */xml | application/json | application/x-ndjson)
+text/* | */xml)
+  [ "${1##*.}" = "md" ] && glow -s dark -w "$2" "$1" && exit 0
   bat --terminal-width "$(($4 - 2))" -f "$1"
   ;;
+application/json | application/x-ndjson)
+  jq -C < "$1" ;;
 audio/* | application/octet-stream)
   mediainfo "$1" || exit 1
   ;;
 font/* | application/vnd.ms-opentype)
-  PREVIEW_TEXT="ABCDEFGHIJKLMNOPQRSTUBWXYZ\n""\
+  FONT_NAME=$(fc-query --format "%{family}\n" "$1" | head -n 1)
+
+  PREVIEW_TEXT="${FONT_NAME}\nABCDEFGHIJKLMNOPQRSTUBWXYZ\n""\
 abcdefghijklmnopqrstuvwxyz\n""\
 1234567890\n""\
 !@#$\%(){}[]-+=_\`~"
@@ -38,26 +44,27 @@ abcdefghijklmnopqrstuvwxyz\n""\
     -font "$1" \
     -fill '#000000' \
     -annotate +0+0 "$PREVIEW_TEXT" \
-    -flatten jpeg:- | chafafunc $2
+    -flatten jpeg:- | chafafunc $2 $3
   ;;
+
 image/vnd.djvu)
   djvused "$1" -e 'select 1; save-page-with /dev/stdout' |
-      convert djvu:- jpeg:- | chafafunc $2
+      convert djvu:- jpeg:- | chafafunc $2 $3
   ;;
 image/webp)
-  dwebp "$1" -tiff -o - | chafafunc $2
+  dwebp "$1" -tiff -o - | chafafunc $2 $3
   ;;
 image/heic)
-  convert "$1" jpeg:- | chafafunc $2
+  convert "$1" jpeg:- | chafafunc $2 $3
   ;;
 image/*)
-  cat "$1" | chafafunc $2
+  cat "$1" | chafafunc $2 $3
   ;;
 */pdf)
-  pdftocairo -singlefile -scale-to-x $PREVIEW_WIDTH -scale-to-y -1 -jpeg "$1" - | chafafunc $2
+  pdftocairo -singlefile -scale-to-x $PREVIEW_WIDTH -scale-to-y -1 -jpeg "$1" - | chafafunc $2 $3
   ;;
 video/*)
-  ffmpegthumbnailer -i "$1" -s 0 -c jpeg -f -o - | chafafunc $2
+  ffmpegthumbnailer -i "$1" -s 0 -c jpeg -f -o - | chafafunc $2 $3
   ;;
 application/*zip)
   atool --list -- "$1"
diff --git a/.config/river/init b/.config/river/init
new file mode 100755
index 0000000..676e7b8
--- /dev/null
+++ b/.config/river/init
@@ -0,0 +1,628 @@
+#!/usr/bin/lua
+
+--[[
+
+NOTE:
+- execp() needs 'lua-posix' package
+- bitwise operands for tag mappings need Lua version >= 5.3
+
+--]]
+
+-- Convenient functions ────────────────────────────────────────────────────────
+
+-- Wrapper around table.concat() to also handle other types
+local function concat(...)
+	local list, sep, i, j = ...
+
+	if type(list) == "table" then
+		return table.concat(list, sep, i, j)
+	else
+		return tostring(list)
+	end
+end
+
+-- All the setting tables ──────────────────────────────────────────────────────
+
+-- local wl_script_dir = os.getenv("HOME") .. "/.local/libexec/wayland"
+local drun_menu = "tofi-drun --drun-launch=true"
+local run_menu = "tofi-run --drun-launch=true"
+
+local startup_commands = {
+	-- Inform dbus about the environment variables
+	{
+		"dbus-update-activation-environment",
+		"DISPLAY",
+		"WAYLAND_DISPLAY",
+		"XDG_SESSION_TYPE",
+		"XDG_CURRENT_DESKTOP",
+	},
+	-- Startup programs
+	{ "gentoo-pipewire-launcher", "restart" },
+	{ "pidof", "waybar", "||", "waybar" },
+	{ "pidof", "kanshi", "||", "kanshi" },
+}
+
+local keyboard = {
+	layouts = { "us", "ca" },
+	model = "pc104",
+	options = "grp:ctrl_space_toggle",
+}
+
+local outputs = {
+	["DP-1"] = {
+		mode = "3840x2160",
+		pos = "0,0",
+		transform = "normal",
+		scale = "1.000000",
+		preferred = true,
+	},
+	["HDMI-A-1"] = {
+		mode = "2560x1080",
+		pos = "640,2160",
+		transform = "180",
+		scale = "1.000000",
+		preferred = true,
+	},
+}
+
+local inputs = {
+	["pointer-2-7-SynPS/2_Synaptics_TouchPad"] = {
+		["events"] = "disabled-on-external-mouse",
+		["click-method"] = "clickfinger",
+		["drag"] = "enabled",
+		["tap"] = "disabled",
+		["tap-button-map"] = "left-right-middle",
+		["disable-while-typing"] = "enabled",
+		["natural-scroll"] = "enabled",
+		["scroll-method"] = "two-finger",
+	},
+}
+
+local river_options = {
+	-- Theme options
+	["border-width"] = 2,
+	["border-color-focused"] = "0x447a6c",
+	["border-color-unfocused"] = "0x444444",
+	["border-color-urgent"] = "0x7d4b23",
+	["xcursor-theme"] = { "Posy_Cursor_Black", 28 },
+	["background-color"] = "0x222222",
+
+	-- Other options
+	["set-repeat"] = { 60, 150 }, -- Wait 150ms before repeating at 60/s
+	["focus-follows-cursor"] = "normal",
+	["set-cursor-warp"] = "on-output-change",
+	["attach-mode"] = "top",
+	["default-layout"] = "rivertile",
+}
+
+local gsettings = {
+	["org.gnome.desktop.interface"] = {
+		["gtk-theme"] = "Nordic",
+		["icon-theme"] = "Papirus-Dark",
+		["cursor-theme"] = river_options["xcursor-theme"][1],
+		["cursor-size"] = river_options["xcursor-theme"][2],
+	},
+}
+
+-- "Action" { "rule-type" { "selection" { "arguments" }}},
+local window_rules = {
+	["float"] = {
+		["app-id"] = {
+			["dropdown"] = "",
+		},
+		["title"] = {},
+	},
+	["no-float"] = {
+		["app-id"] = {},
+		["title"] = {},
+	},
+	["ssd"] = {
+		["app-id"] = {
+			["com.mitchellh.ghostty"] = "",
+			["firefox"] = "",
+			["imv"] = "",
+			["org.pwmt.zathura"] = "",
+		},
+		["title"] = {},
+	},
+	["csd"] = {
+		["app-id"] = {},
+		["title"] = {},
+	},
+	["tags"] = {
+		["app-id"] = {
+			["vesktop"] = "128", -- tag 8 = 1<<7
+			["cider"] = "256", -- tag 9 = 1<<8
+		},
+		["title"] = {},
+	},
+	["output"] = {
+		["app-id"] = {},
+		["title"] = {},
+	},
+	["position"] = {
+		["app-id"] = {},
+		["title"] = {},
+	},
+	["dimensions"] = {
+		["app-id"] = {},
+		["title"] = {},
+	},
+	["fullscreen"] = {
+		["app-id"] = {},
+		["title"] = {},
+	},
+	["no-fullscreen"] = {
+		["app-id"] = {},
+		["title"] = {},
+	},
+	["tearing"] = {
+		["app-id"] = {
+			-- ["factorio"] = "",
+		},
+		["title"] = {
+			["Balatro"] = "",
+		},
+	},
+	["no-tearing"] = {
+		["app-id"] = {
+			["factorio"] = "",
+		},
+		["title"] = {},
+	},
+}
+
+-- Window rules (float/csd filters)
+for action, patterns in pairs(window_rules) do
+	for pattern_type, entries in pairs(patterns) do
+		for pattern, args in pairs(entries) do
+			os.execute(string.format(
+				"riverctl rule-add -%s %s %s %s",
+				pattern_type, -- e.g., "app-id" or "title"
+				pattern, -- e.g., "dropdown" or "vesktop"
+				action, -- e.g., "float" or "tags"
+				args -- e.g., "" or "9"
+			))
+		end
+	end
+end
+
+-- Additional modes and their mappings to switch between them and 'normal' mode
+--
+-- name: string (the name of the additional mode)
+-- mod: string|list (modifiers for key binding, concanated by '+')
+-- key: string
+local modes = {
+	{
+		name = "passthrough",
+		mod = "Super",
+		key = "F11",
+	},
+}
+
+-- Each mapping contains 4 keys:
+--
+-- mod: string|list (modifiers, concanated by '+')
+-- key: string
+-- command: string|list (the command passed to riverctl)
+-- opt: string ('release' or 'repeat')
+local mappings = {
+	-- Key bindings
+	map = {
+		normal = {
+			{ -- Terminal emulators
+				mod = "Super",
+				key = "Return",
+				command = { "spawn", "ghostty" },
+				-- command = { "spawn", "foot" },
+			},
+			{ -- Application launcher
+				mod = "Super",
+				key = "D",
+				command = { "spawn", string.format([['%s']], drun_menu) },
+			},
+			{
+				mod = { "Super", "Shift" },
+				key = "D",
+				command = { "spawn", string.format([['%s']], run_menu) },
+			},
+			{ -- Web search
+				mod = "Super",
+				key = "W",
+				command = { "spawn", "$BROWSER" },
+			},
+			{ -- Super+Q to close the focused view
+				mod = "Super",
+				key = "Q",
+				command = "close",
+			},
+			{ -- Super+Shift+Q to exit river (requires 'swaynag' program from sway)
+				mod = { "Super", "Shift" },
+				key = "Q",
+				command = { "spawn", [['swaynag -t warning -m "Exit river?" -b "Yes" "riverctl exit"']] },
+			},
+			{ -- Super+Shift+X to lock the screen
+				mod = "Super",
+				key = "BackSpace",
+				command = { "spawn", [['swaylock -uc 000000']] },
+			},
+			{ -- Super+{J,K} to focus next/previous view in the layout stack
+				mod = "Super",
+				key = "J",
+				command = { "focus-view", "next" },
+			},
+			{
+				mod = "Super",
+				key = "K",
+				command = { "focus-view", "previous" },
+			},
+			{ -- Super+Shift+{J,K} to swap focused view with the next/previous view in the layout stack
+				mod = { "Super", "Shift" },
+				key = "K",
+				command = { "swap", "previous" },
+			},
+			{
+				mod = { "Super", "Shift" },
+				key = "J",
+				command = { "swap", "next" },
+			},
+			{ -- Super+S to S.nap the focused view to the top of the layout stack
+				mod = "Super",
+				key = "S",
+				command = "zoom",
+			},
+			{ -- Super+{H,L} to decrease/increase the main_factor value of rivertile by 0.02
+				mod = "Super",
+				key = "H",
+				command = { "send-layout-cmd", "rivertile", [['main-ratio -0.02']] },
+			},
+			{
+				mod = "Super",
+				key = "L",
+				command = { "send-layout-cmd", "rivertile", [['main-ratio +0.02']] },
+			},
+			{
+				mod = "Super",
+				key = "period",
+				command = { "focus-output", "next" },
+			},
+			{
+				mod = { "Super", "Shift" },
+				key = "period",
+				command = { "send-to-output", "next" },
+			},
+			{ -- Super+Shift+{H,L} to increment/decrement the main_count value of rivertile
+				mod = { "Super" },
+				key = "I",
+				command = { "send-layout-cmd", "rivertile", [['main-count +1']] },
+			},
+			{
+				mod = { "Super", "Shift" },
+				key = "I",
+				command = { "send-layout-cmd", "rivertile", [['main-count -1']] },
+			},
+			{ -- Super+Alt+{H,J,K,L} to move views (floating)
+				mod = { "Super", "Alt" },
+				key = "H",
+				command = { "move", "left", 100 },
+			},
+			{
+				mod = { "Super", "Alt" },
+				key = "J",
+				command = { "move", "down", 100 },
+			},
+			{
+				mod = { "Super", "Alt" },
+				key = "K",
+				command = { "move", "up", 100 },
+			},
+			{
+				mod = { "Super", "Alt" },
+				key = "L",
+				command = { "move", "right", 100 },
+			},
+			{ -- Super+Control+{H,J,K,L} to resize views
+				mod = { "Super", "Control" },
+				key = "H",
+				command = { "resize", "horizontal", -100 },
+			},
+			{
+				mod = { "Super", "Control" },
+				key = "J",
+				command = { "resize", "vertical", 100 },
+			},
+			{
+				mod = { "Super", "Control" },
+				key = "K",
+				command = { "resize", "vertical", -100 },
+			},
+			{
+				mod = { "Super", "Control" },
+				key = "L",
+				command = { "resize", "horizontal", 100 },
+			},
+			{ -- Super+Alt+Control+{H,J,K,L} to snap views to screen edges
+				mod = { "Super", "Alt", "Control" },
+				key = "H",
+				command = { "snap", "left" },
+			},
+			{
+				mod = { "Super", "Alt", "Control" },
+				key = "J",
+				command = { "snap", "down" },
+			},
+			{
+				mod = { "Super", "Alt", "Control" },
+				key = "K",
+				command = { "snap", "up" },
+			},
+			{
+				mod = { "Super", "Alt", "Control" },
+				key = "L",
+				command = { "snap", "right" },
+			},
+			{ -- Super+Space to toggle float
+				mod = "Super",
+				key = "Space",
+				command = "toggle-float",
+			},
+			{ -- Super+F to toggle fullscreen
+				mod = "Super",
+				key = "F",
+				command = "toggle-fullscreen",
+			},
+			{ -- Toggle keyboard layout
+				mod = "Alt",
+				key = "Return",
+				command = { "spawn", "layouttoggle" },
+			},
+			{ -- Dropdown Terminal
+				mod = "Super",
+				key = "A",
+				command = { "spawn", [['dropdowntoggle shell tmux-shell']] },
+			},
+			{ -- Dropdown Calculator
+				mod = { "Super", "Shift" },
+				key = "A",
+				command = { "spawn", [['dropdowntoggle calc tmux-py']] },
+			},
+			{ -- Dropdown Network Manager
+				mod = "None",
+				key = "XF86AudioMedia",
+				command = { "spawn", [['dropdowntoggle network nmtui']] },
+			},
+			{ -- Dropdown Bluetooth Manager
+				mod = "Shift",
+				key = "XF86AudioMedia",
+				command = { "spawn", [['dropdowntoggle bluetooth bluetuith']] },
+			},
+			{ -- Dropdown Audio Mixer
+				mod = "Shift",
+				key = "XF86AudioMute",
+				command = { "spawn", [['dropdowntoggle audio pulsemixer']] },
+			},
+			{ -- Print Screen
+				mod = "None",
+				key = "Print",
+				command = { "spawn", [['capture -f']] },
+			},
+			{ -- Print Selection
+				mod = "Super",
+				key = "Print",
+				command = { "spawn", [['capture -s']] },
+			},
+			{ -- Print Window
+				mod = "Shift",
+				key = "Print",
+				command = { "spawn", [['capture -w']] },
+			},
+		},
+		locked = {
+			{ -- Control screen backlight brightness
+				mod = "None",
+				key = "XF86MonBrightnessUp",
+				command = { "spawn", [['backlightctl -i 5']] },
+				opt = "repeat",
+			},
+			{
+				mod = "None",
+				key = "XF86MonBrightnessDown",
+				command = { "spawn", [['backlightctl -d 5']] },
+				opt = "repeat",
+			},
+			{
+				mod = "Shift",
+				key = "XF86MonBrightnessUp",
+				command = { "spawn", [['backlightctl -s 100']] },
+				opt = "repeat",
+			},
+			{
+				mod = "Shift",
+				key = "XF86MonBrightnessDown",
+				command = { "spawn", [['backlightctl -s 5']] },
+				opt = "repeat",
+			},
+			{
+				-- Control pulseaudio volume
+				mod = "None",
+				key = "XF86AudioRaiseVolume",
+				command = { "spawn", [['volumectl 5 +']] },
+				opt = "repeat",
+			},
+			{
+				mod = "None",
+				key = "XF86AudioLowerVolume",
+				command = { "spawn", [['volumectl 5 -']] },
+				opt = "repeat",
+			},
+			{
+				mod = "Shift",
+				key = "XF86AudioRaiseVolume",
+				command = { "spawn", [['volumectl 100']] },
+				opt = "repeat",
+			},
+			{
+				mod = "Shift",
+				key = "XF86AudioLowerVolume",
+				command = { "spawn", [['volumectl 5']] },
+				opt = "repeat",
+			},
+			{
+				mod = "None",
+				key = "XF86AudioMute",
+				command = { "spawn", [['volumectl mute']] },
+			},
+			{ -- Control MPRIS aware media players with 'playerctl'
+				mod = "None",
+				key = "XF86AudioPlay",
+				command = { "spawn", [['playerctl play-pause']] },
+			},
+			{
+				mod = "None",
+				key = "XF86AudioPrev",
+				command = { "spawn", [['playerctl previous']] },
+			},
+			{
+				mod = "None",
+				key = "XF86AudioNext",
+				command = { "spawn", [['playerctl next']] },
+			},
+		},
+	},
+	-- Mappings for pointer (mouse)
+	["map-pointer"] = {
+		normal = {
+			-- Super + Left Mouse Button to move views
+			{
+				mod = "Super",
+				key = "BTN_LEFT",
+				command = "move-view",
+			},
+			-- Super + Right Mouse Button to resize views
+			{
+				mod = "Super",
+				key = "BTN_RIGHT",
+				command = "resize-view",
+			},
+		},
+	},
+}
+
+-- -- These mappings are repeated, so they are separated from the mappings table
+local function tag_mappings()
+	for i = 1, 9 do
+		-- local tag_num = 1 << (i - 1)
+		local tag_num = math.pow(2, i - 1)
+		-- Super+[1-9] to focus tag [0-8]
+		os.execute(string.format("riverctl map normal Super %s set-focused-tags %s", i, tag_num))
+		-- Super+Shift+[1-9] to tag focused view with tag [0-8]
+		os.execute(string.format("riverctl map normal Super+Shift %s set-view-tags %s", i, tag_num))
+		-- Super+Control+[1-9] to toggle focus of tag [0-8]
+		os.execute(string.format("riverctl map normal Super+Control %s toggle-focused-tags %s", i, tag_num))
+		-- Super+Alt+[1-9] to toggle tag [0-8] of focused view
+		os.execute(string.format("riverctl map normal Super+Alt %s toggle-view-tags %s", i, tag_num))
+	end
+	-- river has a total of 32 tags
+	-- local all_tags = (1 << 32) - 1
+	local all_tags = math.pow(2, 32) - 1
+	os.execute(string.format("riverctl map normal Super 0 set-focused-tags %s", all_tags))
+	os.execute(string.format("riverctl map normal Super+Shift 0 set-view-tags %s", all_tags))
+end
+
+-- Apply settings ──────────────────────────────────────────────────────────────
+
+-- Run startup commands
+--
+-- 'riverctl spawn ...' always returns (even when the child process is a daemon)
+-- so we don't need to resort to posix.unistd.spawn()
+for _, cmd in ipairs(startup_commands) do
+	os.execute(string.format([[riverctl spawn '%s']], concat(cmd, " ")))
+end
+
+-- Configure outputs
+local randr_cmd = "wlr-randr"
+for output, options in pairs(outputs) do
+	randr_cmd = randr_cmd .. " --output " .. output
+
+	for opt, value in pairs(options) do
+		if opt ~= "preferred" then
+			randr_cmd = string.format(randr_cmd .. " --%s %s", opt, value)
+		end
+	end
+
+	-- Ensure '--preferred' is the last argument for each monitor
+	if options.preferred then
+		randr_cmd = randr_cmd .. " --preferred"
+	end
+end
+os.execute(randr_cmd)
+
+-- Configure input devices
+for device, options in pairs(inputs) do
+	for key, val in pairs(options) do
+		os.execute(string.format("riverctl input %s %s %s", device, key, val))
+	end
+end
+
+-- GNOME-related settings
+for group, tbl in pairs(gsettings) do
+	for key, value in pairs(tbl) do
+		os.execute(string.format("gsettings set %s %s %s", group, key, value))
+	end
+end
+
+-- Set river's options
+for key, value in pairs(river_options) do
+	os.execute(string.format("riverctl %s %s", key, concat(value, " ")))
+end
+
+-- Additional modes (beside 'normal' and 'locked')
+for _, mode in ipairs(modes) do
+	local mode_name = mode.name
+	local modifiers = concat(mode.mod, "+")
+
+	-- Declare the mode
+	os.execute("riverctl declare-mode " .. mode_name)
+
+	-- Setup key bindings to enter/exit the mode
+	os.execute(string.format("riverctl map normal %s %s enter-mode %s", modifiers, mode.key, mode_name))
+	os.execute(string.format("riverctl map %s %s %s enter-mode normal", mode_name, modifiers, mode.key))
+end
+
+-- Keyboard and mouse bindings
+for map_type, tbl in pairs(mappings) do
+	for mode, value in pairs(tbl) do
+		for _, binding in ipairs(value) do
+			local modifiers = concat(binding.mod, "+")
+			local cmd = concat(binding.command, " ")
+
+			-- Options -release and -repeat for 'map' and 'unmap' commands
+			local opt = binding.opt
+			if opt ~= "release" and opt ~= "repeat" then
+				opt = ""
+			else
+				opt = "-" .. opt
+			end
+
+			os.execute(string.format("riverctl %s %s %s %s %s %s", map_type, opt, mode, modifiers, binding.key, cmd))
+
+			-- Duplicate mappings of mode 'locked' for mode 'normal'
+			if mode == "locked" then
+				os.execute(string.format("riverctl %s %s normal %s %s %s", map_type, opt, modifiers, binding.key, cmd))
+			end
+		end
+	end
+end
+
+-- Mappings for tag management
+tag_mappings()
+
+-- Configure keyboard layouts
+os.execute(
+	string.format(
+		"riverctl keyboard-layout -model %s -options %s %s ",
+		keyboard.model,
+		keyboard.options,
+		concat(keyboard.layouts, ",")
+	)
+)
diff --git a/.config/shortcutrc b/.config/shortcutrc
index 099d2c8..feb6e89 100644
--- a/.config/shortcutrc
+++ b/.config/shortcutrc
@@ -25,18 +25,20 @@
 # - lowercase shortcuts prepended by 'y' copies selected files to these paths
 # - lowercase shortcuts prepended by 'm' moves selected files to these paths
 
+CV,            cv,  ~/Dropbox/A/work/Application/CV/current
 Compilation,   cp,  ~/.local/src
 Config,        cf,  ~/.config
-CV,            cv,  ~/Dropbox/A/work/Application/CV/current
 Downloads,     dl,  ~/Downloads
 Dropbox,       bx,  ~/Dropbox
 Hotkeys,       sx,  ~/.config/sxhkd
 Images,        img, ~/Dropbox/A/Personnal/Photos/unsorted
 Neovim,        vi,  ~/.config/nvim
+Obsidian,      oi,  ~/Documents/obsidian/main
 OrgMode,       om,  ~/Dropbox/org
-School,        sf,  ~/Dropbox/A/scholar/sherbrooke/24-05-T2
-Scripts,       sc,  ~/.local/bin
+Rafta,         rf,  ~/Workspace/rafta
+School,        sf,  ~/Dropbox/A/scholar/sherbrooke/24-09-reprise-automne
 Screenshots,   ss,  ~/Pictures/captures
+Scripts,       sc,  ~/.local/bin
 Wallpapers,    wp,  ~/Pictures/wallpapers
 Website,       ww,  ~/Workspace/chausse.xyz
 WindowManager, wm,  ~/.local/src/dwl
diff --git a/.config/tofi/config b/.config/tofi/config
new file mode 100644
index 0000000..8130030
--- /dev/null
+++ b/.config/tofi/config
@@ -0,0 +1,19 @@
+matching-algorithm = fuzzy
+anchor = center
+width = 30%
+height = 40%
+horizontal = false
+font-size = 8
+prompt-text = " run: "
+font = monospace
+outline-width = 0
+border-width = 0
+background-color = #1b1d1bcc
+text-color = #447a6cff
+selection-color = #7d4b23ff
+min-input-width = 120
+result-spacing = 0
+padding-top = 0
+padding-bottom = 0
+padding-left = 0
+padding-right = 0
diff --git a/.config/waybar/config.json b/.config/waybar/config.json
index f61d9bd..70606e5 100644
--- a/.config/waybar/config.json
+++ b/.config/waybar/config.json
@@ -1,4 +1,5 @@
 {
+  "reload_style_on_change": false,
   "position": "top",
    "layer": "top",
    "height": 12,
@@ -7,8 +8,9 @@
    "_Modules_": "Choose the order of the modules",
 
    "modules-left": [
-     "dwl/tags",
-     "dwl/window",
+     "river/tags",
+     "river/layout",
+     "river/window"
    ],
 
    "modules-center": [
@@ -18,9 +20,10 @@
      "custom/dotfiles",
      "custom/mail",
      "custom/eselect",
+     "custom/layout",
      "custom/date",
      "custom/time",
-     "custom/battery",
+     "custom/battery"
    ],
 
    "include": "~/.config/waybar/modules.json"
diff --git a/.config/waybar/modules.json b/.config/waybar/modules.json
index 6902c6b..618806b 100644
--- a/.config/waybar/modules.json
+++ b/.config/waybar/modules.json
@@ -1,17 +1,26 @@
 {
+  "river/layout": {
+    "format": " <tt>{}</tt> ",
+    "min-length": 4,
+    "align": "right"
+  },
+  "river/window": {
+    "format": "{}",
+  },
+  "river/tags": {
+    "num-tags": 9,
+    "set-tags": [
+      1, 2, 4, 8, 16, 32, 64, 128, 256
+    ],
+    "tag-labels": [
+      "1", "2", "3", "4", "5", "6", "7", "8", "9"
+    ],
+  },
   "dwl/tags": {
     "num-tags": 9,
     "disable-click": true,
     "tag-labels": [
-      "1",
-      "2",
-      "3",
-      "4",
-      "5",
-      "6",
-      "7",
-      "8",
-      "9"
+      "1", "2", "3", "4", "5", "6", "7", "8", "9"
     ],
   },
   "dwl/window": {
@@ -33,6 +42,13 @@
     "interval": 3600,
     "signal": 7,
   },
+  "custom/layout": {
+    "format": "<tt>{}</tt>",
+    "return-type": "json",
+    "exec": "/home/master/.local/bin/dwmbar/dwmb-layout",
+    "interval": 3600,
+    "signal": 4,
+  },
   "custom/mail": {
     "format": "<tt>{}</tt>",
     "return-type": "json",
diff --git a/.config/waybar/style.css b/.config/waybar/style.css
index a7e49ca..05791ab 100644
--- a/.config/waybar/style.css
+++ b/.config/waybar/style.css
@@ -1,6 +1,6 @@
 * {
   /* `otf-font-awesome` is required to be installed for icons */
-  font-size: 11px;
+  font-size: 20;
   padding: 0px;
   font-family: sans-serif;
   /* color: #1b1d1b; */
@@ -11,6 +11,16 @@ window#waybar {
   background-color: rgba(27, 29, 27, 0.78); /* #1b1d1b */
 }
 
+#layout {
+  padding-right: 5px;
+  margin-right: 5px;
+}
+
+#window {
+  padding-left: 5px;
+  margin-left: 5px;
+}
+
 #tags {
   font-family: sans-serif;
 }
@@ -32,7 +42,7 @@ window#waybar {
   color: rgba(68, 122, 108, 1);            /* #447a6c */
 }
 
-#tags button.focused, #window {
+#tags button.focused, #window, #layout {
   background-color: rgba(125,75,35,0.8);   /* #7d4b23 */
   color: rgba(27, 29, 27, 1);              /* #1b1d1b */
 }
diff --git a/.config/zsh/.zshrc b/.config/zsh/.zshrc
index b621cfd..9d115c6 100644
--- a/.config/zsh/.zshrc
+++ b/.config/zsh/.zshrc
@@ -76,6 +76,10 @@ RPROMPT="\$vcs_info_msg_0_ %B%F{magenta}(%B%F{cyan}%1/%B%F{magenta})"
 
 zstyle ':vcs_info:git:*' formats '%b'
 
+
+export LF_KITTY_TEMPDIR="$(mktemp -d -t lf-kitty-XXXXXX)"
+export LF_KITTY_IMAGE_ID=$(date +%s)
+# export LF_KITTY_IMAGE_ID=1234
 f() {
     tmp="$(mktemp -uq)"
     trap 'rm -f $tmp >/dev/null 2>&1 && trap - HUP INT QUIT TERM EXIT' HUP INT QUIT TERM EXIT
@@ -86,6 +90,10 @@ f() {
     fi
 }
 
+disks() {
+  lsblk -o NAME,MOUNTPOINT,FSTYPE,FSUSE%,SIZE
+}
+
 # Commonly used shortcuts
 [ -f "${XDG_CACHE_HOME:-$HOME/.cache}/zsh-aliases" ] && source "${XDG_CACHE_HOME:-$HOME/.cache}/zsh-aliases"
 [ -f "${XDG_CACHE_HOME:-$HOME/.cache}/zsh-shortcuts" ] && source "${XDG_CACHE_HOME:-$HOME/.cache}/zsh-shortcuts"
-- 
cgit v1.2.3