summaryrefslogtreecommitdiff
path: root/.config
diff options
context:
space:
mode:
Diffstat (limited to '.config')
-rw-r--r--.config/QtProject/qtcreator/styles/catppuccin-macchiato.xml70
-rw-r--r--.config/QtProject/qtcreator/themes/catppuccin-macchiato.creatortheme415
-rw-r--r--.config/aerc/accounts.conf10
-rw-r--r--.config/aerc/aerc.conf466
-rw-r--r--.config/aerc/binds.conf136
-rw-r--r--.config/aerc/stylesets/catppuccin-frappe47
-rw-r--r--.config/aerc/stylesets/catppuccin-latte47
-rw-r--r--.config/aerc/stylesets/catppuccin-macchiato47
-rw-r--r--.config/aerc/stylesets/catppuccin-mocha47
-rw-r--r--.config/aerc/templates/thanks3
-rw-r--r--.config/bottom/bottom.toml167
-rw-r--r--.config/foot/foot.ini65
-rw-r--r--.config/git/config24
-rw-r--r--.config/gitui/key_bindings.ron14
-rw-r--r--.config/gitui/theme.ron23
-rw-r--r--.config/gtk-3.0/settings.ini4
-rw-r--r--.config/himitsu/config.ini2
-rw-r--r--.config/hut/config3
-rw-r--r--.config/mako/config13
-rw-r--r--.config/nvim/.stylua.toml3
-rw-r--r--.config/nvim/README.md7
-rw-r--r--.config/nvim/init.lua18
-rw-r--r--.config/nvim/lazy-lock.json24
-rw-r--r--.config/nvim/lua/options.lua13
-rw-r--r--.config/nvim/lua/plugins/catppuccin.lua19
-rw-r--r--.config/nvim/lua/plugins/cmp.lua95
-rw-r--r--.config/nvim/lua/plugins/editor.lua4
-rw-r--r--.config/nvim/lua/plugins/git.lua27
-rw-r--r--.config/nvim/lua/plugins/lsp.lua64
-rw-r--r--.config/nvim/lua/plugins/telescope.lua17
-rw-r--r--.config/nvim/lua/plugins/treesitter.lua35
-rw-r--r--.config/nvim/lua/plugins/which-key.lua9
-rwxr-xr-x.config/river/init156
-rwxr-xr-x.config/river/rivertile2
-rw-r--r--.config/s6-rc/dbus-log/consumer-for1
-rw-r--r--.config/s6-rc/dbus-log/notification-fd1
-rw-r--r--.config/s6-rc/dbus-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/dbus-log/run4
-rw-r--r--.config/s6-rc/dbus-log/type1
-rwxr-xr-x.config/s6-rc/dbus/data/check3
-rwxr-xr-x.config/s6-rc/dbus/finish3
-rw-r--r--.config/s6-rc/dbus/notification-fd1
-rw-r--r--.config/s6-rc/dbus/producer-for1
-rwxr-xr-x.config/s6-rc/dbus/run5
-rw-r--r--.config/s6-rc/dbus/type1
-rw-r--r--.config/s6-rc/default/contents.d/dbus0
-rw-r--r--.config/s6-rc/default/contents.d/pipewire0
-rw-r--r--.config/s6-rc/default/contents.d/pipewire-pulse0
-rw-r--r--.config/s6-rc/default/contents.d/statusbar0
-rw-r--r--.config/s6-rc/default/contents.d/wayland0
-rw-r--r--.config/s6-rc/default/contents.d/wbg0
-rw-r--r--.config/s6-rc/default/contents.d/wireplumber0
-rw-r--r--.config/s6-rc/default/contents.d/wlsunset0
-rw-r--r--.config/s6-rc/default/contents.d/xdg-desktop-portal0
-rw-r--r--.config/s6-rc/default/type1
-rw-r--r--.config/s6-rc/eww-log/consumer-for1
-rw-r--r--.config/s6-rc/eww-log/notification-fd1
-rw-r--r--.config/s6-rc/eww-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/eww-log/run4
-rw-r--r--.config/s6-rc/eww-log/type1
-rwxr-xr-x.config/s6-rc/eww/data/check2
-rw-r--r--.config/s6-rc/eww/dependencies.d/wayland0
-rwxr-xr-x.config/s6-rc/eww/finish3
-rw-r--r--.config/s6-rc/eww/notification-fd1
-rw-r--r--.config/s6-rc/eww/producer-for1
-rwxr-xr-x.config/s6-rc/eww/run6
-rw-r--r--.config/s6-rc/eww/type1
-rw-r--r--.config/s6-rc/pipewire-log/consumer-for1
-rw-r--r--.config/s6-rc/pipewire-log/notification-fd1
-rw-r--r--.config/s6-rc/pipewire-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/pipewire-log/run4
-rw-r--r--.config/s6-rc/pipewire-log/type1
-rw-r--r--.config/s6-rc/pipewire-pulse-log/consumer-for1
-rw-r--r--.config/s6-rc/pipewire-pulse-log/notification-fd1
-rw-r--r--.config/s6-rc/pipewire-pulse-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/pipewire-pulse-log/run4
-rw-r--r--.config/s6-rc/pipewire-pulse-log/type1
-rw-r--r--.config/s6-rc/pipewire-pulse/dependencies.d/pipewire0
-rwxr-xr-x.config/s6-rc/pipewire-pulse/finish3
-rw-r--r--.config/s6-rc/pipewire-pulse/producer-for1
-rw-r--r--.config/s6-rc/pipewire-pulse/run3
-rw-r--r--.config/s6-rc/pipewire-pulse/type1
-rw-r--r--.config/s6-rc/pipewire/dependencies.d/dbus0
-rwxr-xr-x.config/s6-rc/pipewire/finish3
-rw-r--r--.config/s6-rc/pipewire/producer-for1
-rwxr-xr-x.config/s6-rc/pipewire/run3
-rw-r--r--.config/s6-rc/pipewire/type1
-rw-r--r--.config/s6-rc/river-log/consumer-for1
-rw-r--r--.config/s6-rc/river-log/notification-fd1
-rw-r--r--.config/s6-rc/river-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/river-log/run4
-rw-r--r--.config/s6-rc/river-log/type1
-rw-r--r--.config/s6-rc/river/dependencies.d/dbus0
-rwxr-xr-x.config/s6-rc/river/finish5
-rw-r--r--.config/s6-rc/river/notification-fd1
-rw-r--r--.config/s6-rc/river/producer-for1
-rwxr-xr-x.config/s6-rc/river/run28
-rw-r--r--.config/s6-rc/river/type1
-rw-r--r--.config/s6-rc/rivertile-log/consumer-for1
-rw-r--r--.config/s6-rc/rivertile-log/notification-fd1
-rw-r--r--.config/s6-rc/rivertile-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/rivertile-log/run4
-rw-r--r--.config/s6-rc/rivertile-log/type1
-rw-r--r--.config/s6-rc/rivertile/dependencies.d/river0
-rw-r--r--.config/s6-rc/rivertile/producer-for1
-rwxr-xr-x.config/s6-rc/rivertile/run8
-rw-r--r--.config/s6-rc/rivertile/type1
-rw-r--r--.config/s6-rc/sandbar-log/consumer-for1
-rw-r--r--.config/s6-rc/sandbar-log/notification-fd1
-rw-r--r--.config/s6-rc/sandbar-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/sandbar-log/run4
-rw-r--r--.config/s6-rc/sandbar-log/type1
-rw-r--r--.config/s6-rc/sandbar/consumer-for1
-rw-r--r--.config/s6-rc/sandbar/dependencies.d/wayland0
-rwxr-xr-x.config/s6-rc/sandbar/finish3
-rw-r--r--.config/s6-rc/sandbar/producer-for1
-rwxr-xr-x.config/s6-rc/sandbar/run5
-rw-r--r--.config/s6-rc/sandbar/type1
-rw-r--r--.config/s6-rc/statusbar/contents.d/sandbar-pipeline0
-rw-r--r--.config/s6-rc/statusbar/type1
-rwxr-xr-x.config/s6-rc/statusline/finish3
-rw-r--r--.config/s6-rc/statusline/producer-for1
-rwxr-xr-x.config/s6-rc/statusline/run2
-rw-r--r--.config/s6-rc/statusline/type1
-rw-r--r--.config/s6-rc/sway-log/consumer-for1
-rw-r--r--.config/s6-rc/sway-log/notification-fd1
-rw-r--r--.config/s6-rc/sway-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/sway-log/run4
-rw-r--r--.config/s6-rc/sway-log/type1
-rw-r--r--.config/s6-rc/sway/dependencies.d/dbus0
-rwxr-xr-x.config/s6-rc/sway/finish5
-rw-r--r--.config/s6-rc/sway/notification-fd1
-rw-r--r--.config/s6-rc/sway/producer-for1
-rwxr-xr-x.config/s6-rc/sway/run28
-rw-r--r--.config/s6-rc/sway/type1
-rw-r--r--.config/s6-rc/swayidle-log/consumer-for2
-rw-r--r--.config/s6-rc/swayidle-log/notification-fd1
-rw-r--r--.config/s6-rc/swayidle-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/swayidle-log/run4
-rw-r--r--.config/s6-rc/swayidle-log/type1
-rw-r--r--.config/s6-rc/swayidle-nosleep/dependencies.d/wayland0
-rwxr-xr-x.config/s6-rc/swayidle-nosleep/finish3
-rw-r--r--.config/s6-rc/swayidle-nosleep/producer-for1
-rwxr-xr-x.config/s6-rc/swayidle-nosleep/run8
-rw-r--r--.config/s6-rc/swayidle-nosleep/type1
-rw-r--r--.config/s6-rc/swayidle/dependencies.d/wayland0
-rwxr-xr-x.config/s6-rc/swayidle/finish3
-rw-r--r--.config/s6-rc/swayidle/producer-for1
-rwxr-xr-x.config/s6-rc/swayidle/run5
-rw-r--r--.config/s6-rc/swayidle/type1
-rw-r--r--.config/s6-rc/wayland/contents.d/river0
-rw-r--r--.config/s6-rc/wayland/contents.d/rivertile0
-rw-r--r--.config/s6-rc/wayland/type1
-rw-r--r--.config/s6-rc/wbg-log/consumer-for1
-rw-r--r--.config/s6-rc/wbg-log/notification-fd1
-rw-r--r--.config/s6-rc/wbg-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/wbg-log/run4
-rw-r--r--.config/s6-rc/wbg-log/type1
-rw-r--r--.config/s6-rc/wbg/dependencies.d/wayland0
-rwxr-xr-x.config/s6-rc/wbg/finish3
-rw-r--r--.config/s6-rc/wbg/producer-for1
-rwxr-xr-x.config/s6-rc/wbg/run8
-rw-r--r--.config/s6-rc/wbg/type1
-rw-r--r--.config/s6-rc/wireplumber-log/consumer-for1
-rw-r--r--.config/s6-rc/wireplumber-log/notification-fd1
-rw-r--r--.config/s6-rc/wireplumber-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/wireplumber-log/run4
-rw-r--r--.config/s6-rc/wireplumber-log/type1
-rw-r--r--.config/s6-rc/wireplumber/dependencies.d/pipewire0
-rw-r--r--.config/s6-rc/wireplumber/dependencies.d/xdg-desktop-portal0
-rwxr-xr-x.config/s6-rc/wireplumber/finish3
-rw-r--r--.config/s6-rc/wireplumber/producer-for1
-rwxr-xr-x.config/s6-rc/wireplumber/run3
-rw-r--r--.config/s6-rc/wireplumber/type1
-rw-r--r--.config/s6-rc/wlsunset-log/consumer-for1
-rw-r--r--.config/s6-rc/wlsunset-log/notification-fd1
-rw-r--r--.config/s6-rc/wlsunset-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/wlsunset-log/run4
-rw-r--r--.config/s6-rc/wlsunset-log/type1
-rw-r--r--.config/s6-rc/wlsunset/dependencies.d/wayland0
-rwxr-xr-x.config/s6-rc/wlsunset/finish3
-rw-r--r--.config/s6-rc/wlsunset/producer-for1
-rwxr-xr-x.config/s6-rc/wlsunset/run5
-rw-r--r--.config/s6-rc/wlsunset/type1
-rw-r--r--.config/s6-rc/xdg-desktop-portal-log/consumer-for1
-rw-r--r--.config/s6-rc/xdg-desktop-portal-log/notification-fd1
-rw-r--r--.config/s6-rc/xdg-desktop-portal-log/pipeline-name1
-rwxr-xr-x.config/s6-rc/xdg-desktop-portal-log/run4
-rw-r--r--.config/s6-rc/xdg-desktop-portal-log/type1
-rw-r--r--.config/s6-rc/xdg-desktop-portal/dependencies.d/dbus0
-rw-r--r--.config/s6-rc/xdg-desktop-portal/dependencies.d/pipewire0
-rw-r--r--.config/s6-rc/xdg-desktop-portal/dependencies.d/wayland0
-rwxr-xr-x.config/s6-rc/xdg-desktop-portal/finish3
-rw-r--r--.config/s6-rc/xdg-desktop-portal/notification-fd1
-rw-r--r--.config/s6-rc/xdg-desktop-portal/producer-for1
-rwxr-xr-x.config/s6-rc/xdg-desktop-portal/run6
-rw-r--r--.config/s6-rc/xdg-desktop-portal/type1
-rw-r--r--.config/sway/config186
-rw-r--r--.config/swayidle/config3
-rw-r--r--.config/user-dirs.dirs15
-rw-r--r--.config/user-dirs.locale1
-rw-r--r--.config/vis/lexers/execline.lua64
-rw-r--r--.config/vis/lexers/hare.lua82
-rw-r--r--.config/vis/lexers/roff.lua32
-rw-r--r--.config/vis/themes/flexoki.lua125
-rw-r--r--.config/vis/visrc.lua65
-rw-r--r--.config/waywall/flake.lock61
-rw-r--r--.config/waywall/flake.nix57
-rw-r--r--.config/waywall/init.lua224
-rw-r--r--.config/waywall/resources/bubble_pie.pngbin0 -> 2436 bytes
-rw-r--r--.config/waywall/resources/measuring_overlay.pngbin0 -> 11882 bytes
-rw-r--r--.config/waywall/resources/tall_bg.pngbin0 -> 41553 bytes
-rw-r--r--.config/waywall/resources/thin_bg.pngbin0 -> 75567 bytes
-rw-r--r--.config/waywall/resources/wide_bg.pngbin0 -> 68803 bytes
-rw-r--r--.config/waywall/waywork/LICENSE21
-rw-r--r--.config/waywall/waywork/README.md283
-rw-r--r--.config/waywall/waywork/core.lua61
-rw-r--r--.config/waywall/waywork/keys.lua12
-rw-r--r--.config/waywall/waywork/modes.lua103
-rw-r--r--.config/waywall/waywork/processes.lua110
-rw-r--r--.config/waywall/waywork/scene.lua115
-rw-r--r--.config/xdg-desktop-portal-wlr/config5
222 files changed, 4039 insertions, 0 deletions
diff --git a/.config/QtProject/qtcreator/styles/catppuccin-macchiato.xml b/.config/QtProject/qtcreator/styles/catppuccin-macchiato.xml
new file mode 100644
index 0000000..33f1f02
--- /dev/null
+++ b/.config/QtProject/qtcreator/styles/catppuccin-macchiato.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<style-scheme version="1.0" name="Catppuccin Macchiato">
+ <style name="Text" foreground="#CAD3F5" background="#24273A"/>
+ <style name="Link" foreground="#91D7E3" underlineStyle="SingleUnderline"/>
+ <style name="Selection" background="#5B6078"/>
+ <style name="LineNumber" foreground="#494D64"/>
+ <style name="SearchResult" foreground="#8BD5CA" bold="true"/>
+ <style name="SearchScope" foreground="#24273A" background="#CAD3F5"/>
+ <style name="Parentheses" foreground="#F5A97F" bold="true"/>
+ <style name="ParenthesesMismatch" foreground="#F5A97F"/>
+ <style name="AutoComplete" foreground="#CAD3F5"/>
+ <style name="CurrentLine" foreground="#24273A" background="#494D64"/>
+ <style name="CurrentLineNumber" foreground="#6E738D"/>
+ <style name="Occurrences" foreground="#24273A" background="#CAD3F5"/>
+ <style name="Occurrences.Unused" foreground="#CAD3F5"/>
+ <style name="Occurrences.Rename" foreground="#24273A" background="#CAD3F5"/>
+ <style name="Number" foreground="#F5A97F"/>
+ <style name="String" foreground="#A6DA95"/>
+ <style name="Type" foreground="#EED49F"/>
+ <style name="Local" foreground="#CAD3F5"/>
+ <style name="Parameter"/>
+ <style name="Global" foreground="#EE99A0"/>
+ <style name="Field" foreground="#F4DBD6"/>
+ <style name="Static" foreground="#8BD5CA"/>
+ <style name="VirtualMethod" foreground="#8AADF4" italic="true"/>
+ <style name="Function" foreground="#8AADF4"/>
+ <style name="Keyword" foreground="#C6A0F6"/>
+ <style name="PrimitiveType" foreground="#EED49F" italic="true"/>
+ <style name="Operator" foreground="#91D7E3"/>
+ <style name="Overloaded Operator" foreground="#91D7E3"/>
+ <style name="Punctuation"/>
+ <style name="Preprocessor" foreground="#91D7E3"/>
+ <style name="Label" foreground="#91D7E3"/>
+ <style name="Comment" foreground="#5B6078" italic="true"/>
+ <style name="Doxygen.Comment" foreground="#5B6078"/>
+ <style name="Doxygen.Tag" foreground="#5B6078" bold="true"/>
+ <style name="VisualWhitespace" foreground="#5B6078"/>
+ <style name="QmlLocalId" foreground="#A6DA95" italic="true"/>
+ <style name="QmlExternalId" foreground="#F5A97F" italic="true"/>
+ <style name="QmlTypeId" foreground="#91D7E3"/>
+ <style name="QmlRootObjectProperty" foreground="#A6DA95" italic="true"/>
+ <style name="QmlScopeObjectProperty" foreground="#A6DA95" italic="true"/>
+ <style name="QmlExternalObjectProperty" foreground="#F5A97F" italic="true"/>
+ <style name="JsScopeVar" foreground="#8AADF4" italic="true"/>
+ <style name="JsImportVar" foreground="#CAD3F5" italic="true"/>
+ <style name="JsGlobalVar" foreground="#ED8796" italic="true"/>
+ <style name="QmlStateName" foreground="#A6DA95" italic="true"/>
+ <style name="Binding" foreground="#F5BDE6"/>
+ <style name="DisabledCode" foreground="#6E738D"/>
+ <style name="AddedLine" foreground="#A6DA95"/>
+ <style name="RemovedLine" foreground="#ED8796"/>
+ <style name="DiffFile" foreground="#91D7E3"/>
+ <style name="DiffLocation" foreground="#F5A97F"/>
+ <style name="DiffFileLine" foreground="#24273A" background="#EED49F"/>
+ <style name="DiffContextLine" foreground="#24273A" background="#91D7E3"/>
+ <style name="DiffSourceLine" background="#754D5F"/>
+ <style name="DiffSourceChar" background="#4C3A4C"/>
+ <style name="DiffDestLine" background="#586E5F"/>
+ <style name="DiffDestChar" background="#3E4B4C"/>
+ <style name="LogChangeLine" foreground="#ED8796"/>
+ <style name="Warning" underlineColor="#F5A97F" underlineStyle="SingleUnderline"/>
+ <style name="WarningContext" underlineColor="#F5A97F" underlineStyle="DotLine"/>
+ <style name="Error" underlineColor="#ED8796" underlineStyle="SingleUnderline"/>
+ <style name="ErrorContext" underlineColor="#ED8796" underlineStyle="DotLine"/>
+ <style name="Declaration" bold="true"/>
+ <style name="FunctionDefinition"/>
+ <style name="OutputArgument" italic="true"/>
+ <style name="StaticMember" foreground="#F5A97F"/>
+</style-scheme>
+
diff --git a/.config/QtProject/qtcreator/themes/catppuccin-macchiato.creatortheme b/.config/QtProject/qtcreator/themes/catppuccin-macchiato.creatortheme
new file mode 100644
index 0000000..42672b8
--- /dev/null
+++ b/.config/QtProject/qtcreator/themes/catppuccin-macchiato.creatortheme
@@ -0,0 +1,415 @@
+[General]
+ThemeName=Catppuccin Macchiato
+PreferredStyles=Fusion
+DefaultTextEditorColorScheme=catppuccin-macchiato.xml
+
+[Palette]
+shadowBackground=ff181926
+text=ffCAD3F5
+textDisabled=99CAD3F5
+textHighlighted=ffCAD3F5
+toolBarItem=ffCAD3F5
+toolBarItemDisabled=99CAD3F5
+fancyBarsNormalTextColor=ffCAD3F5
+fancyBarsBoldTextColor=ffCAD3F5
+hoverBackground=ff494D64
+selectedBackground=ff494D64
+selectedBackgroundText=ffCAD3F5
+normalBackground=ff1E2030
+alternateBackground=ff24273A
+error=ffED8796
+warning=ffEED49F
+success=ffA6DA95
+message=ffC6A0F6
+splitter=ff494D64
+textColorLink=ffF4DBD6
+textColorLinkVisited=ffF4DBD6
+backgroundColorDisabled=ff494D64
+
+[Colors]
+;DS controls theme START
+DSpanelBackground=normalBackground
+
+DSwelcomeScreenBackground=normalBackground
+DSsubPanelBackground=shadowBackground
+DSthumbnailBackground=normalBackground
+DSthumbnailLabelBackground=shadowBackground
+
+DSgreenLight=success
+DSamberLight=message
+DSredLight=error
+
+DSinteraction=selectedBackground
+DSerrorColor=error
+DSwarningColor=warning
+DSdisabledColor=textDisabled
+
+DSinteractionHover=hoverBackground
+
+DScontrolBackground=shadowBackground
+DScontrolBackgroundInteraction=shadowBackground
+DScontrolBackgroundDisabled=backgroundColorDisabled
+DScontrolBackgroundGlobalHover=hoverBackground
+DScontrolBackgroundHover=hoverBackground
+
+DScontrolOutline=splitter
+DScontrolOutlineInteraction=message
+DScontrolOutlineDisabled=splitter
+
+DStextColor=text
+DStextColorDisabled=textDisabled
+DStextSelectionColor=selectedBackground
+DStextSelectedTextColor=selectedBackgroundText
+
+DSplaceholderTextColor=textDisabled
+DSplaceholderTextColorInteraction=textDisabled
+
+DSiconColor=text
+DSiconColorHover=textHighlighted
+DSiconColorInteraction=message
+DSiconColorDisabled=textDisabled
+DSiconColorSelected=message
+
+DSlinkIndicatorColor=text
+DSlinkIndicatorColorHover=textHighlighted
+DSlinkIndicatorColorInteraction=message
+DSlinkIndicatorColorDisabled=textDisabled
+
+DSpopupBackground=shadowBackground
+DSpopupOverlayColor=splitter
+
+DSsliderActiveTrack=message
+DSsliderActiveTrackHover=ff7f7f7f
+DSsliderActiveTrackFocus=ffaaaaaa
+DSsliderInactiveTrack=alternateBackground
+DSsliderInactiveTrackHover=ff505050
+DSsliderInactiveTrackFocus=ff7a7a7a
+DSsliderHandle=ff4b5362
+DSsliderHandleHover=ff7a7a7a
+DSsliderHandleFocus=ff1d545c
+DSsliderHandleInteraction=ff4b5362
+
+DSscrollBarTrack=normalBackground
+DSscrollBarHandle=ff4b5362
+
+DSsectionHeadBackground=alternateBackground
+
+DSstateDefaultHighlight=message
+DSstateSeparatorColor=splitter
+DSstateBackgroundColor=normalBackground
+DSstatePreviewOutline=splitter
+
+DSchangedStateText=message
+
+DS3DAxisXColor=error
+DS3DAxisYColor=success
+DS3DAxisZColor=message
+
+DSactionBinding=message
+DSactionAlias=error
+DSactionKeyframe=warning
+DSactionJIT=success
+
+DStableHeaderBackground=ff24273A
+DStableHeaderText=ffCAD3F5
+
+DSdockContainerBackground=shadowBackground
+DSdockContainerSplitter=splitter
+DSdockAreaBackground=normalBackground
+
+DSdockWidgetBackground=shadowBackground
+DSdockWidgetSplitter=splitter
+DSdockWidgetTitleBar=normalBackground
+
+DStitleBarText=text
+DStitleBarIcon=text
+DStitleBarButtonHover=30ffffff
+DStitleBarButtonPress=50ffffff
+
+DStabContainerBackground=shadowBackground
+DStabSplitter=splitter
+
+DStabInactiveBackground=backgroundColorDisabled
+DStabInactiveText=text
+DStabInactiveIcon=text
+DStabInactiveButtonHover=30ffffff
+DStabInactiveButtonPress=50ffffff
+
+DStabActiveBackground=normalBackground
+DStabActiveText=text
+DStabActiveIcon=text
+DStabActiveButtonHover=30ffffff
+DStabActiveButtonPress=50ffffff
+
+DStabFocusBackground=message
+DStabFocusText=shadowBackground
+DStabFocusIcon=shadowBackground
+DStabFocusButtonHover=30ffffff
+DStabFocusButtonPress=50ffffff
+
+DSnavigatorBranch=text
+DSnavigatorBranchIndicator=text
+DSnavigatorItemBackground=normalBackground
+DSnavigatorItemBackgroundHover=hoverBackground
+DSnavigatorItemBackgroundSelected=selectedBackground
+DSnavigatorText=text
+DSnavigatorTextHover=textHighlighted
+DSnavigatorTextSelected=message
+DSnavigatorIcon=text
+DSnavigatorIconHover=textHighlighted
+DSnavigatorIconSelected=text
+DSnavigatorAliasIconChecked=error
+DSnavigatorDropIndicatorBackground=message
+DSnavigatorDropIndicatorOutline=message
+
+DSheaderViewBackground=shadowBackground
+DStableViewAlternateBackground=alternateBackground
+
+DStoolTipBackground=normalBackground
+DStoolTipOutline=text
+DStoolTipText=text
+
+DSUnimportedModuleColor=success
+
+DSBackgroundColorAlternate=alternateBackground
+DSBackgroundColorNormal=normalBackground
+
+;DS controls theme END
+
+BackgroundColorAlternate=alternateBackground
+BackgroundColorDark=shadowBackground
+BackgroundColorHover=hoverBackground
+BackgroundColorNormal=normalBackground
+BackgroundColorDisabled=backgroundColorDisabled
+BackgroundColorSelected=selectedBackground
+BadgeLabelBackgroundColorChecked=text
+BadgeLabelBackgroundColorUnchecked=text
+BadgeLabelTextColorChecked=normalBackground
+BadgeLabelTextColorUnchecked=normalBackground
+CanceledSearchTextColor=error
+ComboBoxArrowColor=toolBarItem
+ComboBoxArrowColorDisabled=toolBarItemDisabled
+ComboBoxTextColor=fancyBarsNormalTextColor
+DetailsButtonBackgroundColorHover=hoverBackground
+DetailsWidgetBackgroundColor=shadowBackground
+DockWidgetResizeHandleColor=splitter
+DoubleTabWidget1stSeparatorColor=splitter
+DoubleTabWidget1stTabActiveTextColor=text
+DoubleTabWidget1stTabBackgroundColor=normalBackground
+DoubleTabWidget1stTabInactiveTextColor=text
+DoubleTabWidget2ndSeparatorColor=toolBarItemDisabled
+DoubleTabWidget2ndTabActiveTextColor=text
+DoubleTabWidget2ndTabBackgroundColor=selectedBackground
+DoubleTabWidget2ndTabInactiveTextColor=text
+EditorPlaceholderColor=shadowBackground
+FancyToolBarSeparatorColor=toolBarItemDisabled
+FancyTabBarBackgroundColor=shadowBackground
+FancyTabBarSelectedBackgroundColor=selectedBackground
+FancyTabWidgetDisabledSelectedTextColor=toolBarItemDisabled
+FancyTabWidgetDisabledUnselectedTextColor=toolBarItemDisabled
+FancyTabWidgetEnabledSelectedTextColor=fancyBarsBoldTextColor
+FancyTabWidgetEnabledUnselectedTextColor=fancyBarsBoldTextColor
+FancyToolButtonHoverColor=hoverBackground
+FancyToolButtonSelectedColor=selectedBackground
+FutureProgressBackgroundColor=shadowBackground
+IconsBaseColor=toolBarItem
+IconsDisabledColor=toolBarItemDisabled
+IconsInfoColor=message
+IconsInfoToolBarColor=message
+IconsWarningColor=warning
+IconsWarningToolBarColor=warning
+IconsErrorColor=error
+IconsErrorToolBarColor=error
+IconsRunColor=success
+IconsRunToolBarColor=success
+IconsStopColor=error
+IconsStopToolBarColor=error
+IconsInterruptColor=message
+IconsInterruptToolBarColor=message
+IconsDebugColor=toolBarItem
+IconsNavigationArrowsColor=warning
+IconsBuildHammerHandleColor=b06112
+IconsBuildHammerHeadColor=toolBarItem
+IconsModeWelcomeActiveColor=success
+IconsModeEditActiveColor=message
+IconsModeDesignActiveColor=warning
+IconsModeDebugActiveColor=message
+IconsModeProjectActiveColor=success
+IconsModeAnalyzeActiveColor=message
+IconsModeHelpActiveColor=warning
+IconsCodeModelKeywordColor=ff777777
+IconsCodeModelClassColor=ffc0b550
+IconsCodeModelStructColor=ff53b053
+IconsCodeModelFunctionColor=ffd34373
+IconsCodeModelVariableColor=ff2bbbcc
+IconsCodeModelEnumColor=ffc0b550
+IconsCodeModelMacroColor=ff476ba0
+IconsCodeModelAttributeColor=ff316511
+IconsCodeModelUniformColor=ff994899
+IconsCodeModelVaryingColor=ffa08833
+IconsCodeModelOverlayBackgroundColor=normalBackground
+IconsCodeModelOverlayForegroundColor=text
+InfoBarBackground=shadowBackground
+InfoBarText=text
+MenuBarEmptyAreaBackgroundColor=shadowBackground
+MenuBarItemBackgroundColor=shadowBackground
+MenuBarItemTextColorDisabled=textDisabled
+MenuBarItemTextColorNormal=text
+MenuItemTextColorDisabled=textDisabled
+MenuItemTextColorNormal=text
+MiniProjectTargetSelectorBackgroundColor=shadowBackground
+MiniProjectTargetSelectorBorderColor=shadowBackground
+MiniProjectTargetSelectorSummaryBackgroundColor=normalBackground
+MiniProjectTargetSelectorTextColor=fancyBarsNormalTextColor
+PanelStatusBarBackgroundColor=shadowBackground
+PanelsWidgetSeparatorLineColor=splitter
+PanelTextColorDark=text
+PanelTextColorMid=text
+PanelTextColorLight=textHighlighted
+ProgressBarColorError=error
+ProgressBarColorFinished=success
+ProgressBarColorNormal=message
+ProgressBarTitleColor=text
+ProgressBarBackgroundColor=alternateBackground
+SplitterColor=splitter
+TextColorDisabled=textDisabled
+TextColorError=error
+TextColorHighlight=textHighlighted
+TextColorHighlightBackground=hoverBackground
+TextColorLink=textColorLink
+TextColorLinkVisited=textColorLinkVisited
+TextColorNormal=text
+ToggleButtonBackgroundColor=shadowBackground
+ToolBarBackgroundColor=shadowBackground
+TreeViewArrowColorNormal=hoverBackground
+TreeViewArrowColorSelected=text
+
+OutputPanes_DebugTextColor=text
+OutputPanes_ErrorMessageTextColor=error
+OutputPanes_MessageOutput=message
+OutputPanes_NormalMessageTextColor=text
+OutputPanes_StdErrTextColor=error
+OutputPanes_StdOutTextColor=text
+OutputPanes_WarningMessageTextColor=warning
+OutputPanes_TestPassTextColor=success
+OutputPanes_TestFailTextColor=error
+OutputPanes_TestXFailTextColor=error
+OutputPanes_TestXPassTextColor=message
+OutputPanes_TestSkipTextColor=message
+OutputPanes_TestWarnTextColor=warning
+OutputPanes_TestFatalTextColor=error
+OutputPanes_TestDebugTextColor=text
+OutputPaneButtonFlashColor=error
+OutputPaneToggleButtonTextColorChecked=fancyBarsNormalTextColor
+OutputPaneToggleButtonTextColorUnchecked=fancyBarsNormalTextColor
+
+Debugger_LogWindow_LogInput=ff56b6c2
+Debugger_LogWindow_LogStatus=message
+Debugger_LogWindow_LogTime=error
+
+Debugger_WatchItem_ValueNormal=text
+Debugger_WatchItem_ValueInvalid=textDisabled
+Debugger_WatchItem_ValueChanged=error
+
+Debugger_Breakpoint_TextMarkColor=message
+
+Welcome_TextColor=text
+Welcome_ForegroundPrimaryColor=text
+Welcome_ForegroundSecondaryColor=text
+Welcome_BackgroundColor=normalBackground
+Welcome_BackgroundPrimaryColor=normalBackground
+Welcome_BackgroundSecondaryColor=normalBackground
+Welcome_ButtonBackgroundColor=normalBackground
+Welcome_DividerColor=splitter
+Welcome_HoverColor=hoverBackground
+Welcome_AccentColor=message
+Welcome_LinkColor=textColorLink
+Welcome_DisabledLinkColor=textDisabled
+
+Timeline_TextColor=text
+Timeline_BackgroundColor1=normalBackground
+Timeline_BackgroundColor2=shadowBackground
+Timeline_DividerColor=splitter
+Timeline_HighlightColor=selectedBackground
+Timeline_PanelBackgroundColor=alternateBackground
+Timeline_PanelHeaderColor=normalBackground
+Timeline_HandleColor=ff4b5362
+Timeline_RangeColor=selectedBackground
+
+VcsBase_FileStatusUnknown_TextColor=text
+VcsBase_FileAdded_TextColor=success
+VcsBase_FileModified_TextColor=warning
+VcsBase_FileDeleted_TextColor=error
+VcsBase_FileRenamed_TextColor=message
+VcsBase_FileUnmerged_TextColor=error
+
+Bookmarks_TextMarkColor=message
+
+TextEditor_SearchResult_ScrollBarColor=success
+TextEditor_CurrentLine_ScrollBarColor=message
+
+ProjectExplorer_TaskError_TextMarkColor=error
+ProjectExplorer_TaskWarn_TextMarkColor=warning
+
+CodeModel_Error_TextMarkColor=error
+CodeModel_Warning_TextMarkColor=warning
+
+QmlDesigner_BackgroundColor=normalBackground
+QmlDesigner_HighlightColor=selectedBackground
+QmlDesigner_FormEditorSelectionColor=message
+QmlDesigner_FormEditorForegroundColor=normalBackground
+QmlDesigner_BackgroundColorDarkAlternate=normalBackground
+QmlDesigner_BackgroundColorDarker=splitter
+QmlDesigner_BorderColor=splitter
+QmlDesigner_ButtonColor=normalBackground
+QmlDesigner_TabDark=shadowBackground
+QmlDesigner_TabLight=text
+QmlDesigner_FormeditorBackgroundColor=normalBackground
+QmlDesigner_AlternateBackgroundColor=alternateBackground
+QmlDesigner_ScrollBarHandleColor=ff4b5362
+
+PaletteWindow=shadowBackground
+PaletteWindowText=text
+PaletteBase=normalBackground
+PaletteAlternateBase=alternateBackground
+PaletteButton=shadowBackground
+PaletteBrightText=error
+PaletteText=text
+PaletteButtonText=text
+PaletteButtonTextDisabled=textDisabled
+PaletteToolTipBase=hoverBackground
+PaletteHighlight=selectedBackground
+PaletteDark=shadowBackground
+PaletteHighlightedText=selectedBackgroundText
+PaletteToolTipText=text
+PaletteLink=textColorLink
+PaletteLinkVisited=textColorLinkVisited
+PaletteWindowDisabled=backgroundColorDisabled
+PaletteWindowTextDisabled=textDisabled
+PaletteBaseDisabled=backgroundColorDisabled
+PaletteTextDisabled=textDisabled
+PaletteMid=text
+PalettePlaceholderText=textDisabled
+
+[Flags]
+ComboBoxDrawTextShadow=false
+DerivePaletteFromTheme=true
+DrawIndicatorBranch=true
+DrawSearchResultWidgetFrame=false
+DrawTargetSelectorBottom=false
+DrawToolBarHighlights=false
+DrawToolBarBorders=false
+ApplyThemePaletteGlobally=true
+FlatToolBars=true
+FlatSideBarIcons=true
+FlatProjectsMode=true
+FlatMenuBar=true
+ToolBarIconShadow=true
+WindowColorAsBase=true
+DarkUserInterface=true
+
+[Gradients]
+DetailsWidgetHeaderGradient\1\color=normalBackground
+DetailsWidgetHeaderGradient\1\pos=1
+DetailsWidgetHeaderGradient\size=1
+
diff --git a/.config/aerc/accounts.conf b/.config/aerc/accounts.conf
new file mode 100644
index 0000000..86170a3
--- /dev/null
+++ b/.config/aerc/accounts.conf
@@ -0,0 +1,10 @@
+[migadu]
+source = maildir://~/mail
+outgoing = smtps+plain://sam%40samnystrom.dev@smtp.migadu.com:465
+outgoing-cred-cmd = hiq -1d -F password proto=smtp user=sam@samnystrom.dev
+from = Sam Nystrom <sam@samnystrom.dev>
+default = INBOX
+copy-to = Sent
+check-mail = 1h
+check-mail-cmd = mbsync primary
+check-mail-timeout = 1m
diff --git a/.config/aerc/aerc.conf b/.config/aerc/aerc.conf
new file mode 100644
index 0000000..eb4f503
--- /dev/null
+++ b/.config/aerc/aerc.conf
@@ -0,0 +1,466 @@
+#
+# aerc main configuration
+
+[general]
+#
+# Used as a default path for save operations if no other path is specified.
+# ~ is expanded to the current user home dir.
+#
+#default-save-path=
+
+# If set to "gpg", aerc will use system gpg binary and keystore for all crypto
+# operations. If set to "internal", the internal openpgp keyring will be used.
+# If set to "auto", the system gpg will be preferred unless the internal
+# keyring already exists, in which case the latter will be used.
+#
+# Default: auto
+#pgp-provider=auto
+
+# By default, the file permissions of accounts.conf must be restrictive and
+# only allow reading by the file owner (0600). Set this option to true to
+# ignore this permission check. Use this with care as it may expose your
+# credentials.
+#
+# Default: false
+#unsafe-accounts-conf=false
+
+# Output log messages to specified file. A path starting with ~/ is expanded to
+# the user home dir. When redirecting aerc's output to a file using > shell
+# redirection, this setting is ignored and log messages are printed to stdout.
+#
+#log-file=
+
+# Only log messages above the specified level to log-file. Supported levels
+# are: trace, debug, info, warn and error. When redirecting aerc's output to
+# a file using > shell redirection, this setting is ignored and the log level
+# is forced to trace.
+#
+# Default: info
+#log-level=info
+
+[ui]
+#
+# Describes the format for each row in a mailbox view. This field is compatible
+# with mutt's printf-like syntax.
+#
+# Default: %-20.20D %-17.17n %Z %s
+#index-format=%-20.20D %-17.17n %Z %s
+
+#
+# See time.Time#Format at https://godoc.org/time#Time.Format
+#
+# Default: 2006-01-02 03:04 PM (ISO 8601 + 12 hour time)
+#timestamp-format=2006-01-02 03:04 PM
+
+#
+# Index-only time format for messages that were received/sent today.
+# If this is not specified, timestamp-format is used instead.
+#
+#this-day-time-format=
+
+#
+# Index-only time format for messages that were received/sent within the last
+# 7 days. If this is not specified, timestamp-format is used instead.
+#
+#this-week-time-format=
+
+#
+# Index-only time format for messages that were received/sent this year.
+# If this is not specified, timestamp-format is used instead.
+#
+#this-year-time-format=
+
+#
+# Width of the sidebar, including the border.
+#
+# Default: 20
+#sidebar-width=20
+
+#
+# Message to display when viewing an empty folder.
+#
+# Default: (no messages)
+#empty-message=(no messages)
+
+# Message to display when no folders exists or are all filtered
+#
+# Default: (no folders)
+#empty-dirlist=(no folders)
+
+# Enable mouse events in the ui, e.g. clicking and scrolling with the mousewheel
+#
+# Default: false
+#mouse-enabled=false
+
+#
+# Ring the bell when new messages are received
+#
+# Default: true
+#new-message-bell=true
+
+# Marker to show before a pinned tab's name.
+#
+# Default: `
+#pinned-tab-marker='`'
+
+# Describes the format string to use for the directory list
+#
+# Default: %n %>r
+#dirlist-format=%n %>r
+
+# Delay after which the messages are actually listed when entering a directory.
+# This avoids loading messages when skipping over folders and makes the UI more
+# responsive. If you do not want that, set it to 0s.
+#
+# Default: 200ms
+#dirlist-delay=200ms
+
+# Display the directory list as a foldable tree that allows to collapse and
+# expand the folders.
+#
+# Default: false
+#dirlist-tree=false
+
+# If dirlist-tree is enabled, set level at which folders are collapsed by
+# default. Set to 0 to disable.
+#
+# Default: 0
+#dirlist-collapse=0
+
+# List of space-separated criteria to sort the messages by, see *sort*
+# command in *aerc*(1) for reference. Prefixing a criterion with "-r "
+# reverses that criterion.
+#
+# Example: "from -r date"
+#
+#sort=
+
+# Moves to next message when the current message is deleted
+#
+# Default: true
+#next-message-on-delete=true
+
+# Automatically set the "seen" flag when a message is opened in the message
+# viewer.
+#
+# Default: true
+#auto-mark-read=true
+
+# The directories where the stylesets are stored. It takes a colon-separated
+# list of directories. If this is unset or if a styleset cannot be found, the
+# following paths will be used as a fallback in that order:
+#
+# ${XDG_CONFIG_HOME:-~/.config}/aerc/stylesets
+# ${XDG_DATA_HOME:-~/.local/share}/aerc/stylesets
+# /usr/local/share/aerc/stylesets
+# /usr/share/aerc/stylesets
+#
+#stylesets-dirs=
+
+# Uncomment to use box-drawing characters for vertical and horizontal borders.
+#
+# Default: " "
+border-char-vertical="│"
+border-char-horizontal="─"
+
+# Sets the styleset to use for the aerc ui elements.
+#
+# Default: default
+styleset-name=catppuccin-macchiato
+
+# Activates fuzzy search in commands and their arguments: the typed string is
+# searched in the command or option in any position, and need not be
+# consecutive characters in the command or option.
+#
+# Default: false
+#fuzzy-complete=false
+
+# How long to wait after the last input before auto-completion is triggered.
+#
+# Default: 250ms
+#completion-delay=250ms
+
+# The minimum required characters to allow auto-completion to be triggered after
+# completion-delay.
+#
+# Default: 1
+#completion-min-chars=1
+
+#
+# Global switch for completion popovers
+#
+# Default: true
+#completion-popovers=true
+
+# Uncomment to use UTF-8 symbols to indicate PGP status of messages
+#
+# Default: ASCII
+#icon-unencrypted=
+#icon-encrypted=✔
+#icon-signed=✔
+#icon-signed-encrypted=✔
+#icon-unknown=✘
+#icon-invalid=âš 
+
+# Reverses the order of the message list. By default, the message list is
+# ordered with the newest (highest UID) message on top. Reversing the order
+# will put the oldest (lowest UID) message on top. This can be useful in cases
+# where the backend does not support sorting.
+#
+# Default: false
+#reverse-msglist-order = false
+
+# Reverse display of the mesage threads. Default order is the the intial
+# message is on the top with all the replies being displayed below. The
+# reverse option will put the initial message at the bottom with the
+# replies on top.
+#
+# Default: false
+#reverse-thread-order=false
+
+# Sort the thread siblings according to the sort criteria for the messages. If
+# sort-thread-siblings is false, the thread siblings will be sorted based on
+# the message UID in ascending order. This option is only applicable for
+# client-side threading with a backend that enables sorting. Note that there's
+# a performance impact when sorting is activated.
+#
+# Default: false
+#sort-thread-siblings=false
+
+#[ui:account=foo]
+#
+# Enable a threaded view of messages. If this is not supported by the backend
+# (IMAP server or notmuch), threads will be built by the client.
+#
+# Default: false
+#threading-enabled=false
+
+# Force client-side thread building
+#
+# Default: false
+#force-client-threads=false
+
+# Debounce client-side thread building
+#
+# Default: 50ms
+#client-threads-delay=50ms
+
+[statusline]
+# Describes the format string for the statusline.
+#
+# Default: [%a] %S %>%T
+#render-format=[%a] %S %>%T
+
+# Specifies the separator between grouped statusline elements.
+#
+# Default: " | "
+#separator=" | "
+
+# Defines the mode for displaying the status elements.
+# Options: text, icon
+#
+# Default: text
+#display-mode=text
+
+[viewer]
+#
+# Specifies the pager to use when displaying emails. Note that some filters
+# may add ANSI codes to add color to rendered emails, so you may want to use a
+# pager which supports ANSI codes.
+#
+# Default: less -R
+#pager=less -R
+
+#
+# If an email offers several versions (multipart), you can configure which
+# mimetype to prefer. For example, this can be used to prefer plaintext over
+# html emails.
+#
+# Default: text/plain,text/html
+#alternatives=text/plain,text/html
+
+#
+# Default setting to determine whether to show full headers or only parsed
+# ones in message viewer.
+#
+# Default: false
+#show-headers=false
+
+#
+# Layout of headers when viewing a message. To display multiple headers in the
+# same row, separate them with a pipe, e.g. "From|To". Rows will be hidden if
+# none of their specified headers are present in the message.
+#
+# Default: From|To,Cc|Bcc,Date,Subject
+#header-layout=From|To,Cc|Bcc,Date,Subject
+
+# Whether to always show the mimetype of an email, even when it is just a single part
+#
+# Default: false
+#always-show-mime=false
+
+# Parses and extracts http links when viewing a message. Links can then be
+# accessed with the open-link command.
+#
+# Default: true
+#parse-http-links=true
+
+[compose]
+#
+# Specifies the command to run the editor with. It will be shown in an embedded
+# terminal, though it may also launch a graphical window if the environment
+# supports it. Defaults to $EDITOR, or vi.
+#editor=
+
+#
+# Default header fields to display when composing a message. To display
+# multiple headers in the same row, separate them with a pipe, e.g. "To|From".
+#
+# Default: To|From,Subject
+#header-layout=To|From,Subject
+
+#
+# Specifies the command to be used to tab-complete email addresses. Any
+# occurrence of "%s" in the address-book-cmd will be replaced with what the
+# user has typed so far.
+#
+# The command must output the completions to standard output, one completion
+# per line. Each line must be tab-delimited, with an email address occurring as
+# the first field. Only the email address field is required. The second field,
+# if present, will be treated as the contact name. Additional fields are
+# ignored.
+#
+# This parameter can also be set per account in accounts.conf.
+#address-book-cmd=
+
+# Specifies the command to be used to select attachments. Any occurence of '%s'
+# in the file-picker-cmd will be replaced the argument <arg> to :attach -m
+# <arg>.
+#
+# The command must output the selected files to standard output, one file per
+# line.
+#file-picker-cmd=
+
+#
+# Allow to address yourself when replying
+#
+# Default: true
+#reply-to-self=true
+
+#
+# Warn before sending an email that matches the specified regexp but does not
+# have any attachments. Leave empty to disable this feature.
+#
+# Uses Go's regexp syntax, documented at https://golang.org/s/re2syntax. The
+# "(?im)" flags are set by default (case-insensitive and multi-line).
+#
+# Example:
+# no-attachment-warning=^[^>]*attach(ed|ment)
+#
+#no-attachment-warning=
+
+[multipart-converters]
+#
+# Converters allow to generate multipart/alternative messages by converting the
+# main text/plain part into any other MIME type. Only exact MIME types are
+# accepted. The commands are invoked with sh -c and are expected to output
+# valid UTF-8 text.
+#
+# Example (obviously, this requires that you write your main text/plain body
+# using the markdown syntax):
+#text/html=pandoc -f markdown -t html --standalone
+
+[filters]
+#
+# Filters allow you to pipe an email body through a shell command to render
+# certain emails differently, e.g. highlighting them with ANSI escape codes.
+#
+# The commands are invoked with sh -c. The following folders are appended to
+# the system $PATH to allow referencing filters from their name only:
+#
+# ${XDG_CONFIG_HOME:-~/.config}/aerc/filters
+# ${XDG_DATA_HOME:-~/.local/share}/aerc/filters
+# $PREFIX/share/aerc/filters
+# /usr/share/aerc/filters
+#
+# The following variables are defined in the filter command environment:
+#
+# AERC_MIME_TYPE the part MIME type/subtype
+# AERC_FORMAT the part content type format= parameter
+# AERC_FILENAME the attachment filename (if any)
+# AERC_SUBJECT the message Subject header value
+# AERC_FROM the message From header value
+#
+# The first filter which matches the email's mimetype will be used, so order
+# them from most to least specific.
+#
+# You can also match on non-mimetypes, by prefixing with the header to match
+# against (non-case-sensitive) and a comma, e.g. subject,text will match a
+# subject which contains "text". Use header,~regex to match against a regex.
+#
+text/plain=colorize
+text/calendar=calendar
+message/delivery-status=colorize
+message/rfc822=colorize
+#text/html=pandoc -f html -t plain | colorize
+text/html=html | colorize
+#text/*=bat -fP --file-name="$AERC_FILENAME"
+#application/x-sh=bat -fP -l sh
+#image/*=catimg -w $(tput cols) -
+#subject,~Git(hub|lab)=lolcat -f
+#from,thatguywhodoesnothardwraphismessages=wrap -w 100 | colorize
+
+[openers]
+#
+# Openers allow you to specify the command to use for the :open action on a
+# per-MIME-type basis.
+#
+# {} is expanded as the temporary filename to be opened. If it is not
+# encountered in the command, the temporary filename will be appened to the end
+# of the command.
+#
+# Examples:
+# text/html=surf -dfgms
+# text/plain=gvim {} +125
+# message/rfc822=thunderbird
+
+[triggers]
+#
+# Triggers specify commands to execute when certain events occur.
+#
+# Example:
+# new-email=exec notify-send "New email from %n" "%s"
+
+#
+# Executed when a new email arrives in the selected folder
+#new-email=
+
+[templates]
+# Templates are used to populate email bodies automatically.
+#
+
+# The directories where the templates are stored. It takes a colon-separated
+# list of directories. If this is unset or if a template cannot be found, the
+# following paths will be used as a fallback in that order:
+#
+# ${XDG_CONFIG_HOME:-~/.config}/aerc/templates
+# ${XDG_DATA_HOME:-~/.local/share}/aerc/templates
+# /usr/local/share/aerc/templates
+# /usr/share/aerc/templates
+#
+#template-dirs=
+
+# The default template to be used for new messages.
+#
+# default: new_message
+#new-message=new_message
+
+# The default template to be used for quoted replies.
+#
+# default: quoted_reply
+#quoted-reply=quoted_reply
+
+# The default template to be used for forward as body.
+#
+# default: forward_as_body
+#forwards=forward_as_body
diff --git a/.config/aerc/binds.conf b/.config/aerc/binds.conf
new file mode 100644
index 0000000..29acaff
--- /dev/null
+++ b/.config/aerc/binds.conf
@@ -0,0 +1,136 @@
+# Binds are of the form <key sequence> = <command to run>
+# To use '=' in a key sequence, substitute it with "Eq": "<Ctrl+Eq>"
+# If you wish to bind #, you can wrap the key sequence in quotes: "#" = quit
+<C-p> = :prev-tab<Enter>
+<C-n> = :next-tab<Enter>
+<C-t> = :term<Enter>
+? = :help keys<Enter>
+
+[messages]
+q = :quit<Enter>
+
+j = :next<Enter>
+<Down> = :next<Enter>
+<C-d> = :next 50%<Enter>
+<C-f> = :next 100%<Enter>
+<PgDn> = :next 100%<Enter>
+
+k = :prev<Enter>
+<Up> = :prev<Enter>
+<C-u> = :prev 50%<Enter>
+<C-b> = :prev 100%<Enter>
+<PgUp> = :prev 100%<Enter>
+gg = :select 0<Enter>
+G = :select -1<Enter>
+
+J = :next-folder<Enter>
+K = :prev-folder<Enter>
+H = :collapse-folder<Enter>
+L = :expand-folder<Enter>
+
+v = :mark -t<Enter>
+V = :mark -v<Enter>
+
+T = :toggle-threads<Enter>
+
+<Enter> = :view<Enter>
+d = :prompt 'Really delete this message?' 'delete-message'<Enter>
+D = :delete<Enter>
+A = :archive flat<Enter>
+
+C = :compose<Enter>
+
+rr = :reply -a<Enter>
+rq = :reply -aq<Enter>
+Rr = :reply<Enter>
+Rq = :reply -q<Enter>
+rt = :reply -a -Tthanks<Enter>
+
+ga = :pipe -mb git am -3<Enter>
+
+c = :cf<space>
+$ = :term<space>
+! = :term<space>
+| = :pipe<space>
+
+/ = :search<space>
+\ = :filter<space>
+n = :next-result<Enter>
+N = :prev-result<Enter>
+<Esc> = :clear<Enter>
+
+[messages:folder=Drafts]
+<Enter> = :recall<Enter>
+
+[view]
+/ = :toggle-key-passthrough<Enter>/
+q = :close<Enter>
+O = :open<Enter>
+S = :save<space>
+| = :pipe<space>
+D = :delete<Enter>
+A = :archive flat<Enter>
+
+<C-l> = :open-link <space>
+
+f = :forward<Enter>
+rr = :reply -a<Enter>
+rq = :reply -aq<Enter>
+Rr = :reply<Enter>
+Rq = :reply -q<Enter>
+
+H = :toggle-headers<Enter>
+<C-k> = :prev-part<Enter>
+<C-j> = :next-part<Enter>
+J = :next<Enter>
+K = :prev<Enter>
+
+[view::passthrough]
+$noinherit = true
+$ex = <C-x>
+<Esc> = :toggle-key-passthrough<Enter>
+
+[compose]
+# Keybindings used when the embedded terminal is not selected in the compose
+# view
+$noinherit = true
+$ex = <C-x>
+<C-k> = :prev-field<Enter>
+<C-j> = :next-field<Enter>
+<A-p> = :switch-account -p<Enter>
+<A-n> = :switch-account -n<Enter>
+<tab> = :next-field<Enter>
+<backtab> = :prev-field<Enter>
+<C-p> = :prev-tab<Enter>
+<C-n> = :next-tab<Enter>
+
+[compose::editor]
+# Keybindings used when the embedded terminal is selected in the compose view
+$noinherit = true
+$ex = <C-x>
+<C-k> = :prev-field<Enter>
+<C-j> = :next-field<Enter>
+<C-p> = :prev-tab<Enter>
+<C-n> = :next-tab<Enter>
+
+[compose::review]
+# Keybindings used when reviewing a message to be sent
+y = :send<Enter>
+n = :abort<Enter>
+v = :preview<Enter>
+p = :postpone<Enter>
+q = :choose -o d discard abort -o p postpone postpone<Enter>
+e = :edit<Enter>
+a = :attach<space>
+d = :detach<space>
+
+V = :header -f X-Sourcehut-Patchset-Update NEEDS_REVISION<Enter>
+A = :header -f X-Sourcehut-Patchset-Update APPLIED<Enter>
+R = :header -f X-Sourcehut-Patchset-Update REJECTED<Enter>
+
+[terminal]
+$noinherit = true
+$ex = <C-x>
+
+<C-p> = :prev-tab<Enter>
+<C-n> = :next-tab<Enter>
diff --git a/.config/aerc/stylesets/catppuccin-frappe b/.config/aerc/stylesets/catppuccin-frappe
new file mode 100644
index 0000000..78e8e92
--- /dev/null
+++ b/.config/aerc/stylesets/catppuccin-frappe
@@ -0,0 +1,47 @@
+*.default=true
+*.normal=true
+
+default.fg=#c6d0f5
+
+error.fg=#e78284
+warning.fg=#ef9f76
+success.fg=#a6d189
+
+tab.fg=#737994
+tab.bg=#292c3c
+tab.selected.fg=#c6d0f5
+tab.selected.bg=#303446
+tab.selected.bold=true
+
+border.fg=#232634
+border.bold=true
+
+msglist_unread.bold=true
+msglist_flagged.fg=#e5c890
+msglist_flagged.bold=true
+msglist_result.fg=#8caaee
+msglist_result.bold=true
+msglist_*.selected.bold=true
+msglist_*.selected.bg=#414559
+
+dirlist_*.selected.bold=true
+dirlist_*.selected.bg=#414559
+
+statusline_default.fg=#949cbb
+statusline_default.bg=#414559
+statusline_error.bold=true
+statusline_success.bold=true
+
+[viewer]
+url.fg=#8caaee
+url.underline=true
+header.bold=true
+signature.dim=true
+diff_meta.bold=true
+diff_chunk.fg=#8caaee
+diff_chunk_func.fg=#8caaee
+diff_chunk_func.bold=true
+diff_add.fg=#a6d189
+diff_del.fg=#e78284
+quote_*.fg=#737994
+quote_1.fg=#949cbb
diff --git a/.config/aerc/stylesets/catppuccin-latte b/.config/aerc/stylesets/catppuccin-latte
new file mode 100644
index 0000000..1be8fe2
--- /dev/null
+++ b/.config/aerc/stylesets/catppuccin-latte
@@ -0,0 +1,47 @@
+*.default=true
+*.normal=true
+
+default.fg=#4c4f69
+
+error.fg=#d20f39
+warning.fg=#fe640b
+success.fg=#40a02b
+
+tab.fg=#9ca0b0
+tab.bg=#e6e9ef
+tab.selected.fg=#4c4f69
+tab.selected.bg=#eff1f5
+tab.selected.bold=true
+
+border.fg=#dce0e8
+border.bold=true
+
+msglist_unread.bold=true
+msglist_flagged.fg=#df8e1d
+msglist_flagged.bold=true
+msglist_result.fg=#1e66f5
+msglist_result.bold=true
+msglist_*.selected.bold=true
+msglist_*.selected.bg=#ccd0da
+
+dirlist_*.selected.bold=true
+dirlist_*.selected.bg=#ccd0da
+
+statusline_default.fg=#7c7f93
+statusline_default.bg=#ccd0da
+statusline_error.bold=true
+statusline_success.bold=true
+
+[viewer]
+url.fg=#1e66f5
+url.underline=true
+header.bold=true
+signature.dim=true
+diff_meta.bold=true
+diff_chunk.fg=#1e66f5
+diff_chunk_func.fg=#1e66f5
+diff_chunk_func.bold=true
+diff_add.fg=#40a02b
+diff_del.fg=#d20f39
+quote_*.fg=#9ca0b0
+quote_1.fg=#7c7f93
diff --git a/.config/aerc/stylesets/catppuccin-macchiato b/.config/aerc/stylesets/catppuccin-macchiato
new file mode 100644
index 0000000..34d8163
--- /dev/null
+++ b/.config/aerc/stylesets/catppuccin-macchiato
@@ -0,0 +1,47 @@
+*.default=true
+*.normal=true
+
+default.fg=#cad3f5
+
+error.fg=#ed8796
+warning.fg=#f5a97f
+success.fg=#a6da95
+
+tab.fg=#6e738d
+tab.bg=#1e2030
+tab.selected.fg=#cad3f5
+tab.selected.bg=#24273a
+tab.selected.bold=true
+
+border.fg=#181926
+border.bold=true
+
+msglist_unread.bold=true
+msglist_flagged.fg=#eed49f
+msglist_flagged.bold=true
+msglist_result.fg=#8aadf4
+msglist_result.bold=true
+msglist_*.selected.bold=true
+msglist_*.selected.bg=#363a4f
+
+dirlist_*.selected.bold=true
+dirlist_*.selected.bg=#363a4f
+
+statusline_default.fg=#939ab7
+statusline_default.bg=#363a4f
+statusline_error.bold=true
+statusline_success.bold=true
+
+[viewer]
+url.fg=#8aadf4
+url.underline=true
+header.bold=true
+signature.dim=true
+diff_meta.bold=true
+diff_chunk.fg=#8aadf4
+diff_chunk_func.fg=#8aadf4
+diff_chunk_func.bold=true
+diff_add.fg=#a6da95
+diff_del.fg=#ed8796
+quote_*.fg=#6e738d
+quote_1.fg=#939ab7
diff --git a/.config/aerc/stylesets/catppuccin-mocha b/.config/aerc/stylesets/catppuccin-mocha
new file mode 100644
index 0000000..4e90b99
--- /dev/null
+++ b/.config/aerc/stylesets/catppuccin-mocha
@@ -0,0 +1,47 @@
+*.default=true
+*.normal=true
+
+default.fg=#cdd6f4
+
+error.fg=#f38ba8
+warning.fg=#fab387
+success.fg=#a6e3a1
+
+tab.fg=#6c7086
+tab.bg=#181825
+tab.selected.fg=#cdd6f4
+tab.selected.bg=#1e1e2e
+tab.selected.bold=true
+
+border.fg=#11111b
+border.bold=true
+
+msglist_unread.bold=true
+msglist_flagged.fg=#f9e2af
+msglist_flagged.bold=true
+msglist_result.fg=#89b4fa
+msglist_result.bold=true
+msglist_*.selected.bold=true
+msglist_*.selected.bg=#313244
+
+dirlist_*.selected.bold=true
+dirlist_*.selected.bg=#313244
+
+statusline_default.fg=#9399b2
+statusline_default.bg=#313244
+statusline_error.bold=true
+statusline_success.bold=true
+
+[viewer]
+url.fg=#89b4fa
+url.underline=true
+header.bold=true
+signature.dim=true
+diff_meta.bold=true
+diff_chunk.fg=#89b4fa
+diff_chunk_func.fg=#89b4fa
+diff_chunk_func.bold=true
+diff_add.fg=#a6e3a1
+diff_del.fg=#f38ba8
+quote_*.fg=#6c7086
+quote_1.fg=#9399b2
diff --git a/.config/aerc/templates/thanks b/.config/aerc/templates/thanks
new file mode 100644
index 0000000..b77048e
--- /dev/null
+++ b/.config/aerc/templates/thanks
@@ -0,0 +1,3 @@
+X-Sourcehut-Patchset-Update: APPLIED
+
+Thanks!
diff --git a/.config/bottom/bottom.toml b/.config/bottom/bottom.toml
new file mode 100644
index 0000000..1000677
--- /dev/null
+++ b/.config/bottom/bottom.toml
@@ -0,0 +1,167 @@
+# This is a default config file for bottom. All of the settings are commented
+# out by default; if you wish to change them uncomment and modify as you see
+# fit.
+
+# This group of options represents a command-line flag/option. Flags explicitly
+# added when running (ie: btm -a) will override this config file if an option
+# is also set here.
+
+[flags]
+# Whether to hide the average cpu entry.
+#hide_avg_cpu = false
+# Whether to use dot markers rather than braille.
+#dot_marker = false
+# The update rate of the application.
+#rate = 1000
+# Whether to put the CPU legend to the left.
+#left_legend = false
+# Whether to set CPU% on a process to be based on the total CPU or just current usage.
+#current_usage = false
+# Whether to set CPU% on a process to be based on the total CPU or per-core CPU% (not divided by the number of cpus).
+#unnormalized_cpu = false
+# Whether to group processes with the same name together by default.
+#group_processes = false
+# Whether to make process searching case sensitive by default.
+#case_sensitive = false
+# Whether to make process searching look for matching the entire word by default.
+#whole_word = false
+# Whether to make process searching use regex by default.
+#regex = false
+# Defaults to Celsius. Temperature is one of:
+#temperature_type = "k"
+#temperature_type = "f"
+#temperature_type = "c"
+#temperature_type = "kelvin"
+#temperature_type = "fahrenheit"
+#temperature_type = "celsius"
+# The default time interval (in milliseconds).
+#default_time_value = 60000
+# The time delta on each zoom in/out action (in milliseconds).
+#time_delta = 15000
+# Hides the time scale.
+#hide_time = false
+# Override layout default widget
+#default_widget_type = "proc"
+#default_widget_count = 1
+# Expand selected widget upon starting the app
+#expanded_on_startup = true
+# Use basic mode
+#basic = false
+# Use the old network legend style
+#use_old_network_legend = false
+# Remove space in tables
+#hide_table_gap = false
+# Show the battery widgets
+#battery = false
+# Disable mouse clicks
+#disable_click = false
+# Built-in themes. Valid values are "default", "default-light", "gruvbox", "gruvbox-light", "nord", "nord-light"
+#color = "default"
+# Show memory values in the processes widget as values by default
+#mem_as_value = false
+# Show tree mode by default in the processes widget.
+#tree = false
+# Shows an indicator in table widgets tracking where in the list you are.
+#show_table_scroll_position = false
+# Show processes as their commands by default in the process widget.
+#process_command = false
+# Displays the network widget with binary prefixes.
+#network_use_binary_prefix = false
+# Displays the network widget using bytes.
+#network_use_bytes = false
+# Displays the network widget with a log scale.
+#network_use_log = false
+# Hides advanced options to stop a process on Unix-like systems.
+#disable_advanced_kill = false
+# Shows GPU(s) memory
+#enable_gpu_memory = false
+# How much data is stored at once in terms of time.
+#retention = "10m"
+
+# These are all the components that support custom theming. Note that colour support
+# will depend on terminal support.
+
+# Layout - layouts follow a pattern like this:
+# [[row]] represents a row in the application.
+# [[row.child]] represents either a widget or a column.
+# [[row.child.child]] represents a widget.
+#
+# All widgets must have the type value set to one of ["cpu", "mem", "proc", "net", "temp", "disk", "empty"].
+# All layout components have a ratio value - if this is not set, then it defaults to 1.
+# The default widget layout:
+#[[row]]
+# ratio=30
+# [[row.child]]
+# type="cpu"
+#[[row]]
+# ratio=40
+# [[row.child]]
+# ratio=4
+# type="mem"
+# [[row.child]]
+# ratio=3
+# [[row.child.child]]
+# type="temp"
+# [[row.child.child]]
+# type="disk"
+#[[row]]
+# ratio=30
+# [[row.child]]
+# type="net"
+# [[row.child]]
+# type="proc"
+# default=true
+
+
+# Filters - you can hide specific temperature sensors, network interfaces, and disks using filters. This is admittedly
+# a bit hard to use as of now, and there is a planned in-app interface for managing this in the future:
+#[disk_filter]
+#is_list_ignored = true
+#list = ["/dev/sda\\d+", "/dev/nvme0n1p2"]
+#regex = true
+#case_sensitive = false
+#whole_word = false
+
+#[mount_filter]
+#is_list_ignored = true
+#list = ["/mnt/.*", "/boot"]
+#regex = true
+#case_sensitive = false
+#whole_word = false
+
+#[temp_filter]
+#is_list_ignored = true
+#list = ["cpu", "wifi"]
+#regex = false
+#case_sensitive = false
+#whole_word = false
+
+#[net_filter]
+#is_list_ignored = true
+#list = ["virbr0.*"]
+#regex = true
+#case_sensitive = false
+#whole_word = false
+
+[colors]
+table_header_color = "#f4dbd6"
+all_cpu_color = "#f4dbd6"
+avg_cpu_color = "#ee99a0"
+cpu_core_colors = ["#ed8796","#f5a97f","#eed49f","#a6da95","#7dc4e4","#c6a0f6"]
+ram_color = "#a6da95"
+swap_color = "#f5a97f"
+rx_color = "#a6da95"
+tx_color = "#ed8796"
+widget_title_color = "#f0c6c6"
+border_color = "#5b6078"
+highlighted_border_color = "#f5bde6"
+text_color = "#cad3f5"
+graph_color = "#a5adcb"
+cursor_color = "#f5bde6"
+selected_text_color = "#181926"
+selected_bg_color = "#c6a0f6"
+high_battery_color = "#a6da95"
+medium_battery_color = "#eed49f"
+low_battery_color = "#ed8796"
+gpu_core_colors = ["#7dc4e4","#c6a0f6","#ed8796","#f5a97f","#eed49f","#a6da95"]
+arc_color = "#91d7e3"
diff --git a/.config/foot/foot.ini b/.config/foot/foot.ini
new file mode 100644
index 0000000..181caf8
--- /dev/null
+++ b/.config/foot/foot.ini
@@ -0,0 +1,65 @@
+font=Fira Code Nerd Font:size=11
+dpi-aware=off
+bold-text-in-bright=palette-based
+
+[colors]
+# Flexoki
+foreground=cecdc3
+background=100f0f
+regular0=100f0f
+regular1=af3029
+regular2=66800b
+regular3=ad8301
+regular4=205ea6
+regular5=a02f6f
+regular6=24837b
+regular7=f2f0e5
+bright0=1c1b1a
+bright1=d14d41
+bright2=879a39
+bright3=d0a215
+bright4=4385be
+bright5=ce5d97
+bright6=3aa99f
+bright7=fffcf0
+
+# Habamax
+#foreground=bcbcbc
+#background=1c1c1c
+#bright0=767676
+#bright1=d7875f
+#bright2=afd7af
+#bright3=d7d787
+#bright4=87afd7
+#bright5=d7afd7
+#bright6=87afaf
+#bright7=bcbcbc
+#regular0=1c1c1c
+#regular1=d75f5f
+#regular2=87af87
+#regular3=afaf87
+#regular4=5f87af
+#regular5=af87af
+#regular6=5f8787
+#regular7=9e9e9e
+
+
+# Catppuccin
+# foreground=cdd6f4 # Text
+# background=1e1e2e # Base
+# regular0=45475a # Surface 1
+# regular1=f38ba8 # red
+# regular2=a6e3a1 # green
+# regular3=f9e2af # yellow
+# regular4=89b4fa # blue
+# regular5=f5c2e7 # pink
+# regular6=94e2d5 # teal
+# regular7=bac2de # Subtext 1
+# bright0=585b70 # Surface 2
+# bright1=f38ba8 # red
+# bright2=a6e3a1 # green
+# bright3=f9e2af # yellow
+# bright4=89b4fa # blue
+# bright5=f5c2e7 # pink
+# bright6=94e2d5 # teal
+# bright7=a6adc8 # Subtext 0
diff --git a/.config/git/config b/.config/git/config
new file mode 100644
index 0000000..c21bb15
--- /dev/null
+++ b/.config/git/config
@@ -0,0 +1,24 @@
+[user]
+ email = sam@samnystrom.dev
+ name = Sam Nystrom
+
+[init]
+ defaultBranch = main
+
+[interactive]
+ singleKey = true
+
+[merge]
+ conflictstyle = diff3
+
+[diff]
+ colorMoved = default
+
+[sendemail]
+ annotate = yes
+ verify = off
+
+[commit]
+ verbose = true
+[push]
+ autoSetupRemote = true
diff --git a/.config/gitui/key_bindings.ron b/.config/gitui/key_bindings.ron
new file mode 100644
index 0000000..e575acc
--- /dev/null
+++ b/.config/gitui/key_bindings.ron
@@ -0,0 +1,14 @@
+(
+ focus_left: Some(( code: Char('h'), modifiers: ( bits: 0,),)),
+ focus_below: Some(( code: Char('j'), modifiers: ( bits: 0,),)),
+ focus_above: Some(( code: Char('k'), modifiers: ( bits: 0,),)),
+ focus_right: Some(( code: Char('l'), modifiers: ( bits: 0,),)),
+
+ move_left: Some(( code: Char('h'), modifiers: ( bits: 0,),)),
+ move_down: Some(( code: Char('j'), modifiers: ( bits: 0,),)),
+ move_up: Some(( code: Char('k'), modifiers: ( bits: 0,),)),
+ move_right: Some(( code: Char('l'), modifiers: ( bits: 0,),)),
+
+ stash_open: Some(( code: Char('l'), modifiers: ( bits: 0,),)),
+ open_help: Some(( code: F(1), modifiers: ( bits: 0,),)),
+)
diff --git a/.config/gitui/theme.ron b/.config/gitui/theme.ron
new file mode 100644
index 0000000..9818424
--- /dev/null
+++ b/.config/gitui/theme.ron
@@ -0,0 +1,23 @@
+(
+ selected_tab: Some(Reset),
+ command_fg: Some(Rgb(205, 214, 244)),
+ selection_bg: Some(Rgb(88, 91, 112)),
+ selection_fg: Some(Rgb(205, 214, 244)),
+ cmdbar_bg: Some(Rgb(24, 24, 37)),
+ cmdbar_extra_lines_bg: Some(Rgb(24, 24, 37)),
+ disabled_fg: Some(Rgb(127, 132, 156)),
+ diff_line_add: Some(Rgb(166, 227, 161)),
+ diff_line_delete: Some(Rgb(243, 139, 168)),
+ diff_file_added: Some(Rgb(249, 226, 175)),
+ diff_file_removed: Some(Rgb(235, 160, 172)),
+ diff_file_moved: Some(Rgb(203, 166, 247)),
+ diff_file_modified: Some(Rgb(250, 179, 135)),
+ commit_hash: Some(Rgb(180, 190, 254)),
+ commit_time: Some(Rgb(186, 194, 222)),
+ commit_author: Some(Rgb(116, 199, 236)),
+ danger_fg: Some(Rgb(243, 139, 168)),
+ push_gauge_bg: Some(Rgb(137, 180, 250)),
+ push_gauge_fg: Some(Rgb(30, 30, 46)),
+ tag_fg: Some(Rgb(245, 224, 220)),
+ branch_fg: Some(Rgb(148, 226, 213))
+)
diff --git a/.config/gtk-3.0/settings.ini b/.config/gtk-3.0/settings.ini
new file mode 100644
index 0000000..82feaed
--- /dev/null
+++ b/.config/gtk-3.0/settings.ini
@@ -0,0 +1,4 @@
+[Settings]
+gtk-theme-name=Catppuccin-Macchiato-Standard-Mauve-Dark
+gtk-cursor-theme-name=Catppuccin-Mocha-Dark-Cursors
+gtk-cursor-theme-size=24
diff --git a/.config/himitsu/config.ini b/.config/himitsu/config.ini
new file mode 100644
index 0000000..08d8d50
--- /dev/null
+++ b/.config/himitsu/config.ini
@@ -0,0 +1,2 @@
+[himitsud]
+prompter=hiprompt-wmenu
diff --git a/.config/hut/config b/.config/hut/config
new file mode 100644
index 0000000..ca0abc5
--- /dev/null
+++ b/.config/hut/config
@@ -0,0 +1,3 @@
+instance "sr.ht" {
+ access-token "APpCjmoAAAAAVHBhZ2VzLnNyLmh0L1BST0ZJTEU6UlcgcGFnZXMuc3IuaHQvU0lURVM6UlcgcGFnZXMuc3IuaHQvUEFHRVM6UlcgcGFnZXMuc3IuaHQvQUNMUzpSVwAKc3RvbmtzMzE0MQyt21pTWxymju2RhrNN54H0xv4Lqf5Lrd2ybjkPnSWZ"
+}
diff --git a/.config/mako/config b/.config/mako/config
new file mode 100644
index 0000000..6cc1f9c
--- /dev/null
+++ b/.config/mako/config
@@ -0,0 +1,13 @@
+font=FiraCode Nerd Font 10
+border-size=2
+border-radius=3
+margin=20
+
+background-color=#24273a
+text-color=#cad3f5
+border-color=#8aadf4
+progress-color=over #363a4f
+
+[urgency=high]
+border-color=#f5a97f
+
diff --git a/.config/nvim/.stylua.toml b/.config/nvim/.stylua.toml
new file mode 100644
index 0000000..6cb677e
--- /dev/null
+++ b/.config/nvim/.stylua.toml
@@ -0,0 +1,3 @@
+line_endings = "Unix"
+quote_style = "ForceSingle"
+call_parentheses = "Always"
diff --git a/.config/nvim/README.md b/.config/nvim/README.md
new file mode 100644
index 0000000..63f50b4
--- /dev/null
+++ b/.config/nvim/README.md
@@ -0,0 +1,7 @@
+# Neovim Config
+
+## Credits
+
+- [Winston](https://github.com/nekowinston) for his excellent [config](https://github.com/nekowinston/dotfiles/tree/main/home/apps/neovim)
+- [Lazyvim](https://lazyvim.org)
+
diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua
new file mode 100644
index 0000000..f6f4491
--- /dev/null
+++ b/.config/nvim/init.lua
@@ -0,0 +1,18 @@
+local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
+if not vim.loop.fs_stat(lazypath) then
+ vim.fn.system({
+ "git",
+ "clone",
+ "--filter=blob:none",
+ "https://github.com/folke/lazy.nvim.git",
+ "--branch=stable",
+ lazypath,
+ })
+end
+vim.opt.rtp:prepend(lazypath)
+
+require("options")
+
+require("lazy").setup("plugins", {
+ install = { colorscheme = { "catppuccin" } },
+})
diff --git a/.config/nvim/lazy-lock.json b/.config/nvim/lazy-lock.json
new file mode 100644
index 0000000..e72ad5d
--- /dev/null
+++ b/.config/nvim/lazy-lock.json
@@ -0,0 +1,24 @@
+{
+ "LuaSnip": { "branch": "master", "commit": "2c08f32a570c07b8130144813266e21393da80d3" },
+ "catppuccin": { "branch": "main", "commit": "65bf0b16f57a3db70d6a93ac68882dd9a31d0565" },
+ "cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" },
+ "cmp-cmdline": { "branch": "main", "commit": "d250c63aa13ead745e3a40f61fdd3470efde3923" },
+ "cmp-nvim-lsp": { "branch": "main", "commit": "39e2eda76828d88b773cc27a3f61d2ad782c922d" },
+ "cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" },
+ "cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" },
+ "diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" },
+ "export-colorscheme.nvim": { "branch": "master", "commit": "805bc285c9ba0e6da5c7c08fc89734f19d72e473" },
+ "flexoki": { "branch": "main", "commit": "975654bce67514114db89373539621cff42befb5" },
+ "friendly-snippets": { "branch": "main", "commit": "de8fce94985873666bd9712ea3e49ee17aadb1ed" },
+ "lazy.nvim": { "branch": "main", "commit": "cf8ecc2c5e4332760431a33534240b0cbc6680ab" },
+ "neogit": { "branch": "master", "commit": "001f43f50d9589d837cec59004fd92486ab06870" },
+ "nvim-cmp": { "branch": "main", "commit": "29fb4854573355792df9e156cb779f0d31308796" },
+ "nvim-lspconfig": { "branch": "master", "commit": "59a6766cbf32c7e4cf3ed685ccad7ffe1dde8c40" },
+ "nvim-surround": { "branch": "main", "commit": "dca2e998ff26681ee422b92c6ed39b3d2908d8a9" },
+ "nvim-treesitter": { "branch": "master", "commit": "39016abc99853c3e9d70f1bec7e2fa661b9a81bf" },
+ "nvim-web-devicons": { "branch": "master", "commit": "19d257cf889f79f4022163c3fbb5e08639077bd8" },
+ "plenary.nvim": { "branch": "master", "commit": "2d9b06177a975543726ce5c73fca176cedbffe9d" },
+ "telescope.nvim": { "branch": "master", "commit": "85922dde3767e01d42a08e750a773effbffaea3e" },
+ "vim-buftabline": { "branch": "master", "commit": "73b9ef5dcb6cdf6488bc88adb382f20bc3e3262a" },
+ "which-key.nvim": { "branch": "main", "commit": "8badb359f7ab8711e2575ef75dfe6fbbd87e4821" }
+}
diff --git a/.config/nvim/lua/options.lua b/.config/nvim/lua/options.lua
new file mode 100644
index 0000000..bd14907
--- /dev/null
+++ b/.config/nvim/lua/options.lua
@@ -0,0 +1,13 @@
+vim.o.number = true
+vim.o.relativenumber = true
+vim.o.timeout = true
+vim.o.timeoutlen = 300
+vim.o.softtabstop = 0
+
+vim.o.laststatus = 2
+vim.o.statusline = "%f %y%h%w%m%r%=%l:%c %P"
+
+vim.g.mapleader = " "
+vim.g.maplocalleader = " "
+
+vim.api.nvim_set_keymap('n', '\\', ':noh<cr>', {})
diff --git a/.config/nvim/lua/plugins/catppuccin.lua b/.config/nvim/lua/plugins/catppuccin.lua
new file mode 100644
index 0000000..155f929
--- /dev/null
+++ b/.config/nvim/lua/plugins/catppuccin.lua
@@ -0,0 +1,19 @@
+return {
+ { "jpe90/export-colorscheme.nvim", name = "export-colorscheme.nvim" },
+ { "kepano/flexoki-neovim", name = "flexoki" },
+ {
+ "catppuccin/nvim",
+ name = "catppuccin",
+ priority = 1000,
+ config = function()
+ require("catppuccin").setup({
+ flavour = "mocha",
+ integrations = {
+ neogit = true,
+ which_key = true,
+ },
+ })
+ vim.cmd.colorscheme("catppuccin")
+ end,
+ },
+}
diff --git a/.config/nvim/lua/plugins/cmp.lua b/.config/nvim/lua/plugins/cmp.lua
new file mode 100644
index 0000000..fc897eb
--- /dev/null
+++ b/.config/nvim/lua/plugins/cmp.lua
@@ -0,0 +1,95 @@
+return {
+ {
+ "hrsh7th/nvim-cmp",
+ dependencies = {
+ "hrsh7th/cmp-buffer",
+ "hrsh7th/cmp-path",
+ "nvim-lua/plenary.nvim",
+ "hrsh7th/cmp-nvim-lsp",
+ "saadparwaiz1/cmp_luasnip",
+ {
+ "L3MON4D3/LuaSnip",
+ dependencies = { "rafamadriz/friendly-snippets" },
+ config = function()
+ require("luasnip.loaders.from_vscode").lazy_load()
+ end,
+ },
+ },
+ event = "InsertEnter",
+ config = function()
+ local cmp = require("cmp")
+ local luasnip = require("luasnip")
+
+ cmp.setup({
+ 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 }),
+ ["<Tab>"] = cmp.mapping(function(fallback)
+ if cmp.visible() then
+ cmp.select_next_item()
+ elseif luasnip.expand_or_jumpable() then
+ luasnip.expand_or_jump()
+ else
+ fallback()
+ end
+ end, { "i", "s" }),
+ ["<S-Tab>"] = cmp.mapping(function(fallback)
+ if cmp.visible() then
+ cmp.select_prev_item()
+ elseif luasnip.jumpable(-1) then
+ luasnip.jump(-1)
+ else
+ fallback()
+ end
+ end, { "i", "s" }),
+ }),
+ snippet = {
+ expand = function(args)
+ luasnip.lsp_expand(args.body)
+ end
+ },
+ sources = cmp.config.sources({
+ { name = "luasnip" },
+ { name = "nvim_lsp" },
+ { name = "path" },
+ }, {
+ { name = "buffer" },
+ }),
+ })
+ end,
+ },
+ {
+ "hrsh7th/cmp-cmdline",
+ dependencies = {
+ "hrsh7th/nvim-cmp",
+ "hrsh7th/cmp-buffer",
+ "hrsh7th/cmp-path",
+ },
+ event = "CmdlineEnter",
+ config = function()
+ local cmp = require("cmp")
+ cmp.setup.cmdline({ "/", "?" }, {
+ mapping = cmp.mapping.preset.cmdline(),
+ sources = cmp.config.sources({
+ { name = "buffer" },
+ }),
+ })
+ cmp.setup.cmdline(":", {
+ mapping = cmp.mapping.preset.cmdline(),
+ sources = cmp.config.sources({
+ { name = "path" },
+ }, {
+ {
+ name = "cmdline",
+ option = {
+ ignore_cmds = { "Man", "!" },
+ },
+ },
+ })
+ })
+ end,
+ },
+}
diff --git a/.config/nvim/lua/plugins/editor.lua b/.config/nvim/lua/plugins/editor.lua
new file mode 100644
index 0000000..7004143
--- /dev/null
+++ b/.config/nvim/lua/plugins/editor.lua
@@ -0,0 +1,4 @@
+return {
+ { "ap/vim-buftabline", event = "VeryLazy" },
+ { "kylechui/nvim-surround", event = "VeryLazy", opts = {} },
+}
diff --git a/.config/nvim/lua/plugins/git.lua b/.config/nvim/lua/plugins/git.lua
new file mode 100644
index 0000000..a435df7
--- /dev/null
+++ b/.config/nvim/lua/plugins/git.lua
@@ -0,0 +1,27 @@
+return {
+ {
+ "sindrets/diffview.nvim",
+ cmd = {
+ "DiffviewLog",
+ "DiffviewOpen",
+ "DiffviewClose",
+ "DiffviewRefresh",
+ "DiffviewFocusFiles",
+ "DiffviewFileHistory",
+ "DiffviewToggleFiles",
+ },
+ },
+ {
+ "NeogitOrg/neogit",
+ dependencies = {
+ "nvim-lua/plenary.nvim",
+ "sindrets/diffview.nvim",
+ },
+ cmd = "Neogit",
+ opts = {
+ integrations = {
+ diffview = true,
+ },
+ },
+ },
+}
diff --git a/.config/nvim/lua/plugins/lsp.lua b/.config/nvim/lua/plugins/lsp.lua
new file mode 100644
index 0000000..7a67265
--- /dev/null
+++ b/.config/nvim/lua/plugins/lsp.lua
@@ -0,0 +1,64 @@
+return {
+ {
+ "neovim/nvim-lspconfig",
+ dependencies = {
+ "hrsh7th/cmp-nvim-lsp",
+ },
+ event = { "BufReadPre", "BufNewFile" },
+ config = function()
+ local lspconfig = require("lspconfig")
+ local capabilities = require("cmp_nvim_lsp").default_capabilities()
+ local common = {
+ capabilities = capabilities,
+ }
+
+ local lsps = {
+ "gopls",
+ "lua_ls",
+ "pylsp",
+ "ts_ls",
+ "cssls",
+ "html",
+ }
+
+ for _, lsp in ipairs(lsps) do
+ lspconfig[lsp].setup(common)
+ end
+
+ local wk = require("which-key")
+ wk.register({
+ { "[d", vim.diagnostic.goto_prev, desc = "Previous diagnostic" },
+ { "]d", vim.diagnostic.goto_next, desc = "Next diagnostic" },
+ })
+
+ vim.api.nvim_create_autocmd("LspAttach", {
+ group = vim.api.nvim_create_augroup("UserLspConfig", {}),
+ callback = function(ev)
+ wk.register({
+ { "gD", vim.lsp.buf.declaration, desc = "Go to declaration" },
+ { "gd", vim.lsp.buf.definition, desc = "Go to definition" },
+ { "gr", vim.lsp.buf.references, desc = "Go to references" },
+ { "gi", vim.lsp.buf.implementation, desc = "Go to implementation" },
+ { "K", vim.lsp.buf.hover, desc = "Show LSP hover info" },
+ { "<C-k>", vim.lsp.buf.signature_help, desc = "Show signature help" },
+ { "<leader>D", vim.lsp.buf.type_definition, desc = "Type definition" },
+ { "<leader>rn", vim.lsp.buf.rename, desc = "Rename" },
+ { "<leader>ca", vim.lsp.buf.code_action, desc = "Code action" },
+ { "<leader>F", function() vim.lsp.buf.format({ async = true }) end, desc = "Format buffer" },
+ ["<leader>w"] = {
+ name = "+LSP workspace",
+ a = { vim.lsp.buf.add_workspace_folder, "Add workspace folder" },
+ r = { vim.lsp.buf.remove_workspace_folder, "Remove workspace folder" },
+ l = {
+ function()
+ print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
+ end,
+ "List workspace folders",
+ },
+ },
+ }, {buffer=ev.buf})
+ end,
+ })
+ end,
+ },
+}
diff --git a/.config/nvim/lua/plugins/telescope.lua b/.config/nvim/lua/plugins/telescope.lua
new file mode 100644
index 0000000..8dfcce3
--- /dev/null
+++ b/.config/nvim/lua/plugins/telescope.lua
@@ -0,0 +1,17 @@
+return {
+ {
+ "nvim-telescope/telescope.nvim",
+ dependencies = {
+ "nvim-lua/plenary.nvim",
+ "nvim-tree/nvim-web-devicons",
+ },
+ keys = {
+ { "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Find files" },
+ { "<leader>fF", "<cmd>Telescope git_files<cr>", desc = "Find git files" },
+ { "<leader>fg", "<cmd>Telescope live_grep<cr>", desc = "Live grep" },
+ { "<leader>fb", "<cmd>Telescope buffers<cr>", desc = "Find buffers" },
+ { "<leader>fh", "<cmd>Telescope help_tags<cr>", desc = "Help tags" },
+ },
+ cmd = "Telescope",
+ },
+}
diff --git a/.config/nvim/lua/plugins/treesitter.lua b/.config/nvim/lua/plugins/treesitter.lua
new file mode 100644
index 0000000..fe48d9f
--- /dev/null
+++ b/.config/nvim/lua/plugins/treesitter.lua
@@ -0,0 +1,35 @@
+return {
+ {
+ "nvim-treesitter/nvim-treesitter",
+ event = { "BufReadPre", "BufNewFile" },
+ config = function()
+ require("nvim-treesitter.configs").setup({
+ auto_install = true,
+ ensure_installed = {
+ "bash",
+ "clojure",
+ "css",
+ "html",
+ "ini",
+ "javascript",
+ "json",
+ "kotlin",
+ "lua",
+ "markdown",
+ "perl",
+ "python",
+ "regex",
+ "rust",
+ "scss",
+ "sql",
+ "svelte",
+ "toml",
+ "tsx",
+ "typescript",
+ "yaml",
+ },
+ highlight = { enable = true },
+ })
+ end,
+ },
+}
diff --git a/.config/nvim/lua/plugins/which-key.lua b/.config/nvim/lua/plugins/which-key.lua
new file mode 100644
index 0000000..f636915
--- /dev/null
+++ b/.config/nvim/lua/plugins/which-key.lua
@@ -0,0 +1,9 @@
+return {
+ "folke/which-key.nvim",
+ event = "VeryLazy",
+ config = function()
+ require("which-key").register({
+ { "<leader>f", group = "Telescope" },
+ })
+ end,
+}
diff --git a/.config/river/init b/.config/river/init
new file mode 100755
index 0000000..9f1172a
--- /dev/null
+++ b/.config/river/init
@@ -0,0 +1,156 @@
+#!/bin/sh -e
+
+riverctl map normal Super+Shift Return spawn foot
+riverctl map normal Super P spawn wmenu-run
+
+# Super+Q to close the focused view
+riverctl map normal Super Q close
+
+# Super+Shift+E to exit river
+riverctl map normal Super+Shift E exit
+
+# Super+J and Super+K to focus the next/previous view in the layout stack
+riverctl map normal Super J focus-view next
+riverctl map normal Super K focus-view previous
+
+# Super+Shift+J and Super+Shift+K to swap the focused view with the next/previous
+# view in the layout stack
+riverctl map normal Super+Shift J swap next
+riverctl map normal Super+Shift K 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+L 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 L send-layout-cmd rivertile "main-ratio +0.05"
+
+# Super+Shift+H and Super+Shift+L 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 L send-layout-cmd rivertile "main-count -1"
+
+# Super+Alt+{H,J,K,L} to move views
+riverctl map normal Super+Alt H move left 100
+riverctl map normal Super+Alt J move down 100
+riverctl map normal Super+Alt K move up 100
+riverctl map normal Super+Alt L move right 100
+
+#riverctl map normal Super+Alt+Shift H move left 1
+#riverctl map normal Super+Alt+Shift J move down 1
+#riverctl map normal Super+Alt+Shift K move up 1
+#riverctl map normal Super+Alt+Shift L move right 1
+
+# Super+Alt+Control+{H,J,K,L} to snap views to screen edges
+riverctl map normal Super+Alt+Control H snap left
+riverctl map normal Super+Alt+Control J snap down
+riverctl map normal Super+Alt+Control K snap up
+riverctl map normal Super+Alt+Control L snap right
+
+# Super+Alt+Shift+{H,J,K,L} to resize views
+riverctl map normal Super+Alt+Shift H resize horizontal -100
+riverctl map normal Super+Alt+Shift J resize vertical 100
+riverctl map normal Super+Alt+Shift K resize vertical -100
+riverctl map normal Super+Alt+Shift L 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)))
+ riverctl map normal Super $i set-focused-tags $tags
+ riverctl map normal Super+Shift $i set-view-tags $tags
+ riverctl map normal Super+Control $i toggle-focused-tags $tags
+ 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
+ riverctl map $mode None XF86AudioRaiseVolume spawn 'wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+'
+ riverctl map $mode None XF86AudioLowerVolume spawn 'wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-'
+ riverctl map $mode None XF86AudioMute spawn 'wpctl set-mute toggle'
+
+ # 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'
+
+ riverctl map $mode None XF86MonBrightnessUp spawn 'brightctl +5'
+ riverctl map $mode None XF86MonBrightnessDown spawn 'brightctl -5'
+done
+
+riverctl keyboard-layout -variant colemak_dh us
+
+riverctl xcursor-theme Catppuccin-Mocha-Dark-Cursors 16
+
+# Set background and border color
+riverctl background-color 0x1e1e2e
+riverctl border-color-focused 0x9399b2
+riverctl border-color-unfocused 0x1e1e2e
+
+# Set keyboard repeat rate
+riverctl set-repeat 40 300
+
+for dev in $(riverctl list-inputs | grep '^pointer'); do
+ riverctl input "$dev" left-handed enabled
+ riverctl input "$dev" accel-profile flat
+done
+
+# Make certain views start floating
+# riverctl rule-add -app-id "float" float
+# riverctl rule-add -title "popup title with spaces" float
+
+# Set app-ids and titles of views which should use client side decorations
+# riverctl rule-add -app-id "gedit" csd
+
+# 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
+
+riverctl spawn 'printf %s\\n "$WAYLAND_DISPLAY" >"$XDG_RUNTIME_DIR"/wl_env/WAYLAND_DISPLAY'
+riverctl spawn 'printf %s\\n "$DISPLAY" >"$XDG_RUNTIME_DIR"/wl_env/DISPLAY'
+dbus-update-activation-environment WAYLAND_DISPLAY DISPLAY XDG_CURRENT_DESKTOP=wlroots
+printf \\n >"$XDG_RUNTIME_DIR"/service/river/data/ready
diff --git a/.config/river/rivertile b/.config/river/rivertile
new file mode 100755
index 0000000..3bc502a
--- /dev/null
+++ b/.config/river/rivertile
@@ -0,0 +1,2 @@
+#!/command/execlineb -s0
+rivertile -view-padding 4 -outer-padding 4 -main-ratio 0.5 ${@}
diff --git a/.config/s6-rc/dbus-log/consumer-for b/.config/s6-rc/dbus-log/consumer-for
new file mode 100644
index 0000000..e2182f1
--- /dev/null
+++ b/.config/s6-rc/dbus-log/consumer-for
@@ -0,0 +1 @@
+dbus
diff --git a/.config/s6-rc/dbus-log/notification-fd b/.config/s6-rc/dbus-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/dbus-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/dbus-log/pipeline-name b/.config/s6-rc/dbus-log/pipeline-name
new file mode 100644
index 0000000..0d56fa6
--- /dev/null
+++ b/.config/s6-rc/dbus-log/pipeline-name
@@ -0,0 +1 @@
+dbus-pipeline
diff --git a/.config/s6-rc/dbus-log/run b/.config/s6-rc/dbus-log/run
new file mode 100755
index 0000000..0b9b1ea
--- /dev/null
+++ b/.config/s6-rc/dbus-log/run
@@ -0,0 +1,4 @@
+#!/bin/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/dbus
diff --git a/.config/s6-rc/dbus-log/type b/.config/s6-rc/dbus-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/dbus-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/dbus/data/check b/.config/s6-rc/dbus/data/check
new file mode 100755
index 0000000..0444e0b
--- /dev/null
+++ b/.config/s6-rc/dbus/data/check
@@ -0,0 +1,3 @@
+#!/bin/execlineb -P
+importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+test -S ${XDG_RUNTIME_DIR}/bus
diff --git a/.config/s6-rc/dbus/finish b/.config/s6-rc/dbus/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/dbus/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/dbus/notification-fd b/.config/s6-rc/dbus/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/dbus/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/dbus/producer-for b/.config/s6-rc/dbus/producer-for
new file mode 100644
index 0000000..7be2401
--- /dev/null
+++ b/.config/s6-rc/dbus/producer-for
@@ -0,0 +1 @@
+dbus-log
diff --git a/.config/s6-rc/dbus/run b/.config/s6-rc/dbus/run
new file mode 100755
index 0000000..bbf8767
--- /dev/null
+++ b/.config/s6-rc/dbus/run
@@ -0,0 +1,5 @@
+#!/bin/execlineb -P
+fdmove -c 2 1
+importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+s6-notifyoncheck
+dbus-daemon --session --nofork --nopidfile --nosyslog --address unix:path=${XDG_RUNTIME_DIR}/bus
diff --git a/.config/s6-rc/dbus/type b/.config/s6-rc/dbus/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/dbus/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/default/contents.d/dbus b/.config/s6-rc/default/contents.d/dbus
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/default/contents.d/dbus
diff --git a/.config/s6-rc/default/contents.d/pipewire b/.config/s6-rc/default/contents.d/pipewire
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/default/contents.d/pipewire
diff --git a/.config/s6-rc/default/contents.d/pipewire-pulse b/.config/s6-rc/default/contents.d/pipewire-pulse
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/default/contents.d/pipewire-pulse
diff --git a/.config/s6-rc/default/contents.d/statusbar b/.config/s6-rc/default/contents.d/statusbar
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/default/contents.d/statusbar
diff --git a/.config/s6-rc/default/contents.d/wayland b/.config/s6-rc/default/contents.d/wayland
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/default/contents.d/wayland
diff --git a/.config/s6-rc/default/contents.d/wbg b/.config/s6-rc/default/contents.d/wbg
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/default/contents.d/wbg
diff --git a/.config/s6-rc/default/contents.d/wireplumber b/.config/s6-rc/default/contents.d/wireplumber
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/default/contents.d/wireplumber
diff --git a/.config/s6-rc/default/contents.d/wlsunset b/.config/s6-rc/default/contents.d/wlsunset
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/default/contents.d/wlsunset
diff --git a/.config/s6-rc/default/contents.d/xdg-desktop-portal b/.config/s6-rc/default/contents.d/xdg-desktop-portal
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/default/contents.d/xdg-desktop-portal
diff --git a/.config/s6-rc/default/type b/.config/s6-rc/default/type
new file mode 100644
index 0000000..757b422
--- /dev/null
+++ b/.config/s6-rc/default/type
@@ -0,0 +1 @@
+bundle
diff --git a/.config/s6-rc/eww-log/consumer-for b/.config/s6-rc/eww-log/consumer-for
new file mode 100644
index 0000000..3817e7a
--- /dev/null
+++ b/.config/s6-rc/eww-log/consumer-for
@@ -0,0 +1 @@
+eww
diff --git a/.config/s6-rc/eww-log/notification-fd b/.config/s6-rc/eww-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/eww-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/eww-log/pipeline-name b/.config/s6-rc/eww-log/pipeline-name
new file mode 100644
index 0000000..f2d8804
--- /dev/null
+++ b/.config/s6-rc/eww-log/pipeline-name
@@ -0,0 +1 @@
+eww-pipeline
diff --git a/.config/s6-rc/eww-log/run b/.config/s6-rc/eww-log/run
new file mode 100755
index 0000000..64b7783
--- /dev/null
+++ b/.config/s6-rc/eww-log/run
@@ -0,0 +1,4 @@
+#!/bin/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/eww
diff --git a/.config/s6-rc/eww-log/type b/.config/s6-rc/eww-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/eww-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/eww/data/check b/.config/s6-rc/eww/data/check
new file mode 100755
index 0000000..f460ac1
--- /dev/null
+++ b/.config/s6-rc/eww/data/check
@@ -0,0 +1,2 @@
+#!/command/execlineb -P
+redirfd -w 1 /dev/null fdmove -c 2 1 eww ping
diff --git a/.config/s6-rc/eww/dependencies.d/wayland b/.config/s6-rc/eww/dependencies.d/wayland
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/eww/dependencies.d/wayland
diff --git a/.config/s6-rc/eww/finish b/.config/s6-rc/eww/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/eww/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/eww/notification-fd b/.config/s6-rc/eww/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/eww/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/eww/producer-for b/.config/s6-rc/eww/producer-for
new file mode 100644
index 0000000..f49fd8d
--- /dev/null
+++ b/.config/s6-rc/eww/producer-for
@@ -0,0 +1 @@
+eww-log
diff --git a/.config/s6-rc/eww/run b/.config/s6-rc/eww/run
new file mode 100755
index 0000000..a0258fa
--- /dev/null
+++ b/.config/s6-rc/eww/run
@@ -0,0 +1,6 @@
+#!/bin/execlineb -P
+fdmove -c 2 1
+importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+s6-envdir ${XDG_RUNTIME_DIR}/wl_env
+s6-notifyoncheck
+eww daemon --no-daemonize
diff --git a/.config/s6-rc/eww/type b/.config/s6-rc/eww/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/eww/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/pipewire-log/consumer-for b/.config/s6-rc/pipewire-log/consumer-for
new file mode 100644
index 0000000..3b94baf
--- /dev/null
+++ b/.config/s6-rc/pipewire-log/consumer-for
@@ -0,0 +1 @@
+pipewire
diff --git a/.config/s6-rc/pipewire-log/notification-fd b/.config/s6-rc/pipewire-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/pipewire-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/pipewire-log/pipeline-name b/.config/s6-rc/pipewire-log/pipeline-name
new file mode 100644
index 0000000..b5dbcd0
--- /dev/null
+++ b/.config/s6-rc/pipewire-log/pipeline-name
@@ -0,0 +1 @@
+pipewire-pipeline
diff --git a/.config/s6-rc/pipewire-log/run b/.config/s6-rc/pipewire-log/run
new file mode 100755
index 0000000..8f71caf
--- /dev/null
+++ b/.config/s6-rc/pipewire-log/run
@@ -0,0 +1,4 @@
+#!/bin/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/pipewire
diff --git a/.config/s6-rc/pipewire-log/type b/.config/s6-rc/pipewire-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/pipewire-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/pipewire-pulse-log/consumer-for b/.config/s6-rc/pipewire-pulse-log/consumer-for
new file mode 100644
index 0000000..c6be362
--- /dev/null
+++ b/.config/s6-rc/pipewire-pulse-log/consumer-for
@@ -0,0 +1 @@
+pipewire-pulse
diff --git a/.config/s6-rc/pipewire-pulse-log/notification-fd b/.config/s6-rc/pipewire-pulse-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/pipewire-pulse-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/pipewire-pulse-log/pipeline-name b/.config/s6-rc/pipewire-pulse-log/pipeline-name
new file mode 100644
index 0000000..dc367a2
--- /dev/null
+++ b/.config/s6-rc/pipewire-pulse-log/pipeline-name
@@ -0,0 +1 @@
+pipewire-pulse-pipeline
diff --git a/.config/s6-rc/pipewire-pulse-log/run b/.config/s6-rc/pipewire-pulse-log/run
new file mode 100755
index 0000000..240b819
--- /dev/null
+++ b/.config/s6-rc/pipewire-pulse-log/run
@@ -0,0 +1,4 @@
+#!/bin/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/pipewire-pulse
diff --git a/.config/s6-rc/pipewire-pulse-log/type b/.config/s6-rc/pipewire-pulse-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/pipewire-pulse-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/pipewire-pulse/dependencies.d/pipewire b/.config/s6-rc/pipewire-pulse/dependencies.d/pipewire
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/pipewire-pulse/dependencies.d/pipewire
diff --git a/.config/s6-rc/pipewire-pulse/finish b/.config/s6-rc/pipewire-pulse/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/pipewire-pulse/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/pipewire-pulse/producer-for b/.config/s6-rc/pipewire-pulse/producer-for
new file mode 100644
index 0000000..d7dcdf1
--- /dev/null
+++ b/.config/s6-rc/pipewire-pulse/producer-for
@@ -0,0 +1 @@
+pipewire-pulse-log
diff --git a/.config/s6-rc/pipewire-pulse/run b/.config/s6-rc/pipewire-pulse/run
new file mode 100644
index 0000000..30cb174
--- /dev/null
+++ b/.config/s6-rc/pipewire-pulse/run
@@ -0,0 +1,3 @@
+#!/bin/execlineb -P
+fdmove -c 2 1
+pipewire-pulse
diff --git a/.config/s6-rc/pipewire-pulse/type b/.config/s6-rc/pipewire-pulse/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/pipewire-pulse/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/pipewire/dependencies.d/dbus b/.config/s6-rc/pipewire/dependencies.d/dbus
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/pipewire/dependencies.d/dbus
diff --git a/.config/s6-rc/pipewire/finish b/.config/s6-rc/pipewire/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/pipewire/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/pipewire/producer-for b/.config/s6-rc/pipewire/producer-for
new file mode 100644
index 0000000..ea63659
--- /dev/null
+++ b/.config/s6-rc/pipewire/producer-for
@@ -0,0 +1 @@
+pipewire-log
diff --git a/.config/s6-rc/pipewire/run b/.config/s6-rc/pipewire/run
new file mode 100755
index 0000000..e8fb02c
--- /dev/null
+++ b/.config/s6-rc/pipewire/run
@@ -0,0 +1,3 @@
+#!/bin/execlineb -P
+fdmove -c 2 1
+pipewire
diff --git a/.config/s6-rc/pipewire/type b/.config/s6-rc/pipewire/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/pipewire/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/river-log/consumer-for b/.config/s6-rc/river-log/consumer-for
new file mode 100644
index 0000000..5f58d4e
--- /dev/null
+++ b/.config/s6-rc/river-log/consumer-for
@@ -0,0 +1 @@
+river
diff --git a/.config/s6-rc/river-log/notification-fd b/.config/s6-rc/river-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/river-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/river-log/pipeline-name b/.config/s6-rc/river-log/pipeline-name
new file mode 100644
index 0000000..77c6e7a
--- /dev/null
+++ b/.config/s6-rc/river-log/pipeline-name
@@ -0,0 +1 @@
+river-pipeline
diff --git a/.config/s6-rc/river-log/run b/.config/s6-rc/river-log/run
new file mode 100755
index 0000000..ff52209
--- /dev/null
+++ b/.config/s6-rc/river-log/run
@@ -0,0 +1,4 @@
+#!/bin/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/river
diff --git a/.config/s6-rc/river-log/type b/.config/s6-rc/river-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/river-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/river/dependencies.d/dbus b/.config/s6-rc/river/dependencies.d/dbus
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/river/dependencies.d/dbus
diff --git a/.config/s6-rc/river/finish b/.config/s6-rc/river/finish
new file mode 100755
index 0000000..4c78186
--- /dev/null
+++ b/.config/s6-rc/river/finish
@@ -0,0 +1,5 @@
+#!/bin/execlineb -S2
+importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+foreground { s6-rc -l ${XDG_RUNTIME_DIR}/s6-rc -bDa change }
+s6-svscanctl -t ${XDG_RUNTIME_DIR}/service
+exit 125
diff --git a/.config/s6-rc/river/notification-fd b/.config/s6-rc/river/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/river/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/river/producer-for b/.config/s6-rc/river/producer-for
new file mode 100644
index 0000000..051e7e4
--- /dev/null
+++ b/.config/s6-rc/river/producer-for
@@ -0,0 +1 @@
+river-log
diff --git a/.config/s6-rc/river/run b/.config/s6-rc/river/run
new file mode 100755
index 0000000..de4fd8a
--- /dev/null
+++ b/.config/s6-rc/river/run
@@ -0,0 +1,28 @@
+#!/bin/execlineb -P
+fdmove -c 2 1
+multisubstitute {
+ importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+ importas -i HOME HOME
+}
+if { mkdir -p ${XDG_RUNTIME_DIR}/wl_env }
+if {
+ forx -E var {
+ XDG_SESSION_TYPE=wayland
+ XDG_SESSION_DESKTOP=wlroots
+ XDG_CURRENT_DESKTOP=wlroots
+ MOZ_ENABLE_WAYLAND=1
+ QT_QPA_PLATFORM=wayland
+ SDL_VIDEODRIVER=wayland
+ _JAVA_AWT_WM_NONREPARENTING=1
+ }
+ multidefine -d= ${var} { key val }
+ redirfd -w 1 ${XDG_RUNTIME_DIR}/wl_env/${key}
+ heredoc 0 ${val} cat
+}
+s6-envdir ${XDG_RUNTIME_DIR}/wl_env
+if { mkdir -p ./data }
+if { rm -f ./data/ready }
+if { mkfifo ./data/ready }
+background { redirfd -r 0 ./data/ready fdmove 1 3 cat }
+cd ${HOME}
+river
diff --git a/.config/s6-rc/river/type b/.config/s6-rc/river/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/river/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/rivertile-log/consumer-for b/.config/s6-rc/rivertile-log/consumer-for
new file mode 100644
index 0000000..d73f7d3
--- /dev/null
+++ b/.config/s6-rc/rivertile-log/consumer-for
@@ -0,0 +1 @@
+rivertile
diff --git a/.config/s6-rc/rivertile-log/notification-fd b/.config/s6-rc/rivertile-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/rivertile-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/rivertile-log/pipeline-name b/.config/s6-rc/rivertile-log/pipeline-name
new file mode 100644
index 0000000..0b1402c
--- /dev/null
+++ b/.config/s6-rc/rivertile-log/pipeline-name
@@ -0,0 +1 @@
+rivertile-pipeline
diff --git a/.config/s6-rc/rivertile-log/run b/.config/s6-rc/rivertile-log/run
new file mode 100755
index 0000000..9ae3251
--- /dev/null
+++ b/.config/s6-rc/rivertile-log/run
@@ -0,0 +1,4 @@
+#!/command/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/rivertile
diff --git a/.config/s6-rc/rivertile-log/type b/.config/s6-rc/rivertile-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/rivertile-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/rivertile/dependencies.d/river b/.config/s6-rc/rivertile/dependencies.d/river
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/rivertile/dependencies.d/river
diff --git a/.config/s6-rc/rivertile/producer-for b/.config/s6-rc/rivertile/producer-for
new file mode 100644
index 0000000..30d5062
--- /dev/null
+++ b/.config/s6-rc/rivertile/producer-for
@@ -0,0 +1 @@
+rivertile-log
diff --git a/.config/s6-rc/rivertile/run b/.config/s6-rc/rivertile/run
new file mode 100755
index 0000000..68b9075
--- /dev/null
+++ b/.config/s6-rc/rivertile/run
@@ -0,0 +1,8 @@
+#!/command/execlineb -P
+fdmove -c 2 1
+multisubstitute {
+ importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+ importas -i HOME HOME
+}
+s6-envdir ${XDG_RUNTIME_DIR}/wl_env
+${HOME}/.config/river/rivertile
diff --git a/.config/s6-rc/rivertile/type b/.config/s6-rc/rivertile/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/rivertile/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/sandbar-log/consumer-for b/.config/s6-rc/sandbar-log/consumer-for
new file mode 100644
index 0000000..a73c0ba
--- /dev/null
+++ b/.config/s6-rc/sandbar-log/consumer-for
@@ -0,0 +1 @@
+sandbar
diff --git a/.config/s6-rc/sandbar-log/notification-fd b/.config/s6-rc/sandbar-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/sandbar-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/sandbar-log/pipeline-name b/.config/s6-rc/sandbar-log/pipeline-name
new file mode 100644
index 0000000..fbbf07e
--- /dev/null
+++ b/.config/s6-rc/sandbar-log/pipeline-name
@@ -0,0 +1 @@
+sandbar-pipeline
diff --git a/.config/s6-rc/sandbar-log/run b/.config/s6-rc/sandbar-log/run
new file mode 100755
index 0000000..f269e87
--- /dev/null
+++ b/.config/s6-rc/sandbar-log/run
@@ -0,0 +1,4 @@
+#!/command/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/sandbar
diff --git a/.config/s6-rc/sandbar-log/type b/.config/s6-rc/sandbar-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/sandbar-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/sandbar/consumer-for b/.config/s6-rc/sandbar/consumer-for
new file mode 100644
index 0000000..9f6b34e
--- /dev/null
+++ b/.config/s6-rc/sandbar/consumer-for
@@ -0,0 +1 @@
+statusline
diff --git a/.config/s6-rc/sandbar/dependencies.d/wayland b/.config/s6-rc/sandbar/dependencies.d/wayland
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/sandbar/dependencies.d/wayland
diff --git a/.config/s6-rc/sandbar/finish b/.config/s6-rc/sandbar/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/sandbar/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/sandbar/producer-for b/.config/s6-rc/sandbar/producer-for
new file mode 100644
index 0000000..1b1bb42
--- /dev/null
+++ b/.config/s6-rc/sandbar/producer-for
@@ -0,0 +1 @@
+sandbar-log
diff --git a/.config/s6-rc/sandbar/run b/.config/s6-rc/sandbar/run
new file mode 100755
index 0000000..b9858fc
--- /dev/null
+++ b/.config/s6-rc/sandbar/run
@@ -0,0 +1,5 @@
+#!/command/execlineb -P
+fdmove -c 2 1
+importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+s6-envdir ${XDG_RUNTIME_DIR}/wl_env
+pipeline { loopwhilex cat } sandbar
diff --git a/.config/s6-rc/sandbar/type b/.config/s6-rc/sandbar/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/sandbar/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/statusbar/contents.d/sandbar-pipeline b/.config/s6-rc/statusbar/contents.d/sandbar-pipeline
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/statusbar/contents.d/sandbar-pipeline
diff --git a/.config/s6-rc/statusbar/type b/.config/s6-rc/statusbar/type
new file mode 100644
index 0000000..757b422
--- /dev/null
+++ b/.config/s6-rc/statusbar/type
@@ -0,0 +1 @@
+bundle
diff --git a/.config/s6-rc/statusline/finish b/.config/s6-rc/statusline/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/statusline/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/statusline/producer-for b/.config/s6-rc/statusline/producer-for
new file mode 100644
index 0000000..a73c0ba
--- /dev/null
+++ b/.config/s6-rc/statusline/producer-for
@@ -0,0 +1 @@
+sandbar
diff --git a/.config/s6-rc/statusline/run b/.config/s6-rc/statusline/run
new file mode 100755
index 0000000..35012fe
--- /dev/null
+++ b/.config/s6-rc/statusline/run
@@ -0,0 +1,2 @@
+#!/command/execlineb -P
+statusline
diff --git a/.config/s6-rc/statusline/type b/.config/s6-rc/statusline/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/statusline/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/sway-log/consumer-for b/.config/s6-rc/sway-log/consumer-for
new file mode 100644
index 0000000..e1fa762
--- /dev/null
+++ b/.config/s6-rc/sway-log/consumer-for
@@ -0,0 +1 @@
+sway
diff --git a/.config/s6-rc/sway-log/notification-fd b/.config/s6-rc/sway-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/sway-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/sway-log/pipeline-name b/.config/s6-rc/sway-log/pipeline-name
new file mode 100644
index 0000000..2ca2ab9
--- /dev/null
+++ b/.config/s6-rc/sway-log/pipeline-name
@@ -0,0 +1 @@
+sway-pipeline
diff --git a/.config/s6-rc/sway-log/run b/.config/s6-rc/sway-log/run
new file mode 100755
index 0000000..cc61312
--- /dev/null
+++ b/.config/s6-rc/sway-log/run
@@ -0,0 +1,4 @@
+#!/bin/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/sway
diff --git a/.config/s6-rc/sway-log/type b/.config/s6-rc/sway-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/sway-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/sway/dependencies.d/dbus b/.config/s6-rc/sway/dependencies.d/dbus
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/sway/dependencies.d/dbus
diff --git a/.config/s6-rc/sway/finish b/.config/s6-rc/sway/finish
new file mode 100755
index 0000000..4c78186
--- /dev/null
+++ b/.config/s6-rc/sway/finish
@@ -0,0 +1,5 @@
+#!/bin/execlineb -S2
+importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+foreground { s6-rc -l ${XDG_RUNTIME_DIR}/s6-rc -bDa change }
+s6-svscanctl -t ${XDG_RUNTIME_DIR}/service
+exit 125
diff --git a/.config/s6-rc/sway/notification-fd b/.config/s6-rc/sway/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/sway/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/sway/producer-for b/.config/s6-rc/sway/producer-for
new file mode 100644
index 0000000..1d76e06
--- /dev/null
+++ b/.config/s6-rc/sway/producer-for
@@ -0,0 +1 @@
+sway-log
diff --git a/.config/s6-rc/sway/run b/.config/s6-rc/sway/run
new file mode 100755
index 0000000..4a4e701
--- /dev/null
+++ b/.config/s6-rc/sway/run
@@ -0,0 +1,28 @@
+#!/bin/execlineb -P
+fdmove -c 2 1
+multisubstitute {
+ importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+ importas -i HOME HOME
+}
+if { mkdir -p ${XDG_RUNTIME_DIR}/wl_env }
+if {
+ forx -E var {
+ XDG_SESSION_TYPE=wayland
+ XDG_SESSION_DESKTOP=sway
+ XDG_CURRENT_DESKTOP=sway
+ MOZ_ENABLE_WAYLAND=1
+ QT_QPA_PLATFORM=wayland
+ SDL_VIDEODRIVER=wayland
+ _JAVA_AWT_WM_NONREPARENTING=1
+ }
+ multidefine -d= ${var} { key val }
+ redirfd -w 1 ${XDG_RUNTIME_DIR}/wl_env/${key}
+ heredoc 0 ${val} cat
+}
+s6-envdir ${XDG_RUNTIME_DIR}/wl_env
+if { mkdir -p ./data }
+if { rm -f ./data/ready }
+if { mkfifo ./data/ready }
+background { redirfd -r 0 ./data/ready fdmove 1 3 cat }
+cd ${HOME}
+sway
diff --git a/.config/s6-rc/sway/type b/.config/s6-rc/sway/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/sway/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/swayidle-log/consumer-for b/.config/s6-rc/swayidle-log/consumer-for
new file mode 100644
index 0000000..41abd49
--- /dev/null
+++ b/.config/s6-rc/swayidle-log/consumer-for
@@ -0,0 +1,2 @@
+swayidle
+swayidle-nosleep
diff --git a/.config/s6-rc/swayidle-log/notification-fd b/.config/s6-rc/swayidle-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/swayidle-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/swayidle-log/pipeline-name b/.config/s6-rc/swayidle-log/pipeline-name
new file mode 100644
index 0000000..37c41f5
--- /dev/null
+++ b/.config/s6-rc/swayidle-log/pipeline-name
@@ -0,0 +1 @@
+swayidle-pipeline
diff --git a/.config/s6-rc/swayidle-log/run b/.config/s6-rc/swayidle-log/run
new file mode 100755
index 0000000..98548eb
--- /dev/null
+++ b/.config/s6-rc/swayidle-log/run
@@ -0,0 +1,4 @@
+#!/bin/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/swayidle
diff --git a/.config/s6-rc/swayidle-log/type b/.config/s6-rc/swayidle-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/swayidle-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/swayidle-nosleep/dependencies.d/wayland b/.config/s6-rc/swayidle-nosleep/dependencies.d/wayland
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/swayidle-nosleep/dependencies.d/wayland
diff --git a/.config/s6-rc/swayidle-nosleep/finish b/.config/s6-rc/swayidle-nosleep/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/swayidle-nosleep/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/swayidle-nosleep/producer-for b/.config/s6-rc/swayidle-nosleep/producer-for
new file mode 100644
index 0000000..490cb3b
--- /dev/null
+++ b/.config/s6-rc/swayidle-nosleep/producer-for
@@ -0,0 +1 @@
+swayidle-log
diff --git a/.config/s6-rc/swayidle-nosleep/run b/.config/s6-rc/swayidle-nosleep/run
new file mode 100755
index 0000000..bc4fcd9
--- /dev/null
+++ b/.config/s6-rc/swayidle-nosleep/run
@@ -0,0 +1,8 @@
+#!/bin/execlineb -P
+fdmove -c 2 1
+multisubstitute {
+ importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+ importas -i HOME HOME
+}
+s6-envdir ${XDG_RUNTIME_DIR}/wl_env
+swayidle -C ${HOME}/.config/swayidle/config-nosleep
diff --git a/.config/s6-rc/swayidle-nosleep/type b/.config/s6-rc/swayidle-nosleep/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/swayidle-nosleep/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/swayidle/dependencies.d/wayland b/.config/s6-rc/swayidle/dependencies.d/wayland
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/swayidle/dependencies.d/wayland
diff --git a/.config/s6-rc/swayidle/finish b/.config/s6-rc/swayidle/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/swayidle/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/swayidle/producer-for b/.config/s6-rc/swayidle/producer-for
new file mode 100644
index 0000000..490cb3b
--- /dev/null
+++ b/.config/s6-rc/swayidle/producer-for
@@ -0,0 +1 @@
+swayidle-log
diff --git a/.config/s6-rc/swayidle/run b/.config/s6-rc/swayidle/run
new file mode 100755
index 0000000..bde027f
--- /dev/null
+++ b/.config/s6-rc/swayidle/run
@@ -0,0 +1,5 @@
+#!/bin/execlineb -P
+fdmove -c 2 1
+importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+s6-envdir ${XDG_RUNTIME_DIR}/wl_env
+swayidle
diff --git a/.config/s6-rc/swayidle/type b/.config/s6-rc/swayidle/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/swayidle/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/wayland/contents.d/river b/.config/s6-rc/wayland/contents.d/river
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/wayland/contents.d/river
diff --git a/.config/s6-rc/wayland/contents.d/rivertile b/.config/s6-rc/wayland/contents.d/rivertile
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/wayland/contents.d/rivertile
diff --git a/.config/s6-rc/wayland/type b/.config/s6-rc/wayland/type
new file mode 100644
index 0000000..757b422
--- /dev/null
+++ b/.config/s6-rc/wayland/type
@@ -0,0 +1 @@
+bundle
diff --git a/.config/s6-rc/wbg-log/consumer-for b/.config/s6-rc/wbg-log/consumer-for
new file mode 100644
index 0000000..bb4038a
--- /dev/null
+++ b/.config/s6-rc/wbg-log/consumer-for
@@ -0,0 +1 @@
+wbg
diff --git a/.config/s6-rc/wbg-log/notification-fd b/.config/s6-rc/wbg-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/wbg-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/wbg-log/pipeline-name b/.config/s6-rc/wbg-log/pipeline-name
new file mode 100644
index 0000000..b78a029
--- /dev/null
+++ b/.config/s6-rc/wbg-log/pipeline-name
@@ -0,0 +1 @@
+wbg-pipeline
diff --git a/.config/s6-rc/wbg-log/run b/.config/s6-rc/wbg-log/run
new file mode 100755
index 0000000..f2f9494
--- /dev/null
+++ b/.config/s6-rc/wbg-log/run
@@ -0,0 +1,4 @@
+#!/command/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/wbg
diff --git a/.config/s6-rc/wbg-log/type b/.config/s6-rc/wbg-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/wbg-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/wbg/dependencies.d/wayland b/.config/s6-rc/wbg/dependencies.d/wayland
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/wbg/dependencies.d/wayland
diff --git a/.config/s6-rc/wbg/finish b/.config/s6-rc/wbg/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/wbg/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/wbg/producer-for b/.config/s6-rc/wbg/producer-for
new file mode 100644
index 0000000..35b7757
--- /dev/null
+++ b/.config/s6-rc/wbg/producer-for
@@ -0,0 +1 @@
+wbg-log
diff --git a/.config/s6-rc/wbg/run b/.config/s6-rc/wbg/run
new file mode 100755
index 0000000..73da181
--- /dev/null
+++ b/.config/s6-rc/wbg/run
@@ -0,0 +1,8 @@
+#!/command/execlineb -P
+fdmove -c 2 1
+multisubstitute {
+ importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+ importas -i HOME HOME
+}
+s6-envdir ${XDG_RUNTIME_DIR}/wl_env
+wbg ${HOME}/wallpaper
diff --git a/.config/s6-rc/wbg/type b/.config/s6-rc/wbg/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/wbg/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/wireplumber-log/consumer-for b/.config/s6-rc/wireplumber-log/consumer-for
new file mode 100644
index 0000000..ec8e30f
--- /dev/null
+++ b/.config/s6-rc/wireplumber-log/consumer-for
@@ -0,0 +1 @@
+wireplumber
diff --git a/.config/s6-rc/wireplumber-log/notification-fd b/.config/s6-rc/wireplumber-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/wireplumber-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/wireplumber-log/pipeline-name b/.config/s6-rc/wireplumber-log/pipeline-name
new file mode 100644
index 0000000..e70298a
--- /dev/null
+++ b/.config/s6-rc/wireplumber-log/pipeline-name
@@ -0,0 +1 @@
+wireplumber-pipeline
diff --git a/.config/s6-rc/wireplumber-log/run b/.config/s6-rc/wireplumber-log/run
new file mode 100755
index 0000000..291099b
--- /dev/null
+++ b/.config/s6-rc/wireplumber-log/run
@@ -0,0 +1,4 @@
+#!/bin/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/wireplumber
diff --git a/.config/s6-rc/wireplumber-log/type b/.config/s6-rc/wireplumber-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/wireplumber-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/wireplumber/dependencies.d/pipewire b/.config/s6-rc/wireplumber/dependencies.d/pipewire
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/wireplumber/dependencies.d/pipewire
diff --git a/.config/s6-rc/wireplumber/dependencies.d/xdg-desktop-portal b/.config/s6-rc/wireplumber/dependencies.d/xdg-desktop-portal
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/wireplumber/dependencies.d/xdg-desktop-portal
diff --git a/.config/s6-rc/wireplumber/finish b/.config/s6-rc/wireplumber/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/wireplumber/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/wireplumber/producer-for b/.config/s6-rc/wireplumber/producer-for
new file mode 100644
index 0000000..e9cd359
--- /dev/null
+++ b/.config/s6-rc/wireplumber/producer-for
@@ -0,0 +1 @@
+wireplumber-log
diff --git a/.config/s6-rc/wireplumber/run b/.config/s6-rc/wireplumber/run
new file mode 100755
index 0000000..5780663
--- /dev/null
+++ b/.config/s6-rc/wireplumber/run
@@ -0,0 +1,3 @@
+#!/bin/execlineb -P
+fdmove -c 2 1
+wireplumber
diff --git a/.config/s6-rc/wireplumber/type b/.config/s6-rc/wireplumber/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/wireplumber/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/wlsunset-log/consumer-for b/.config/s6-rc/wlsunset-log/consumer-for
new file mode 100644
index 0000000..0c4949d
--- /dev/null
+++ b/.config/s6-rc/wlsunset-log/consumer-for
@@ -0,0 +1 @@
+wlsunset
diff --git a/.config/s6-rc/wlsunset-log/notification-fd b/.config/s6-rc/wlsunset-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/wlsunset-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/wlsunset-log/pipeline-name b/.config/s6-rc/wlsunset-log/pipeline-name
new file mode 100644
index 0000000..4f56ed0
--- /dev/null
+++ b/.config/s6-rc/wlsunset-log/pipeline-name
@@ -0,0 +1 @@
+wlsunset-pipeline
diff --git a/.config/s6-rc/wlsunset-log/run b/.config/s6-rc/wlsunset-log/run
new file mode 100755
index 0000000..668705a
--- /dev/null
+++ b/.config/s6-rc/wlsunset-log/run
@@ -0,0 +1,4 @@
+#!/bin/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/wlsunset
diff --git a/.config/s6-rc/wlsunset-log/type b/.config/s6-rc/wlsunset-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/wlsunset-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/wlsunset/dependencies.d/wayland b/.config/s6-rc/wlsunset/dependencies.d/wayland
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/wlsunset/dependencies.d/wayland
diff --git a/.config/s6-rc/wlsunset/finish b/.config/s6-rc/wlsunset/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/wlsunset/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/wlsunset/producer-for b/.config/s6-rc/wlsunset/producer-for
new file mode 100644
index 0000000..8e4f411
--- /dev/null
+++ b/.config/s6-rc/wlsunset/producer-for
@@ -0,0 +1 @@
+wlsunset-log
diff --git a/.config/s6-rc/wlsunset/run b/.config/s6-rc/wlsunset/run
new file mode 100755
index 0000000..933e919
--- /dev/null
+++ b/.config/s6-rc/wlsunset/run
@@ -0,0 +1,5 @@
+#!/bin/execlineb -P
+fdmove -c 2 1
+importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+s6-envdir ${XDG_RUNTIME_DIR}/wl_env
+wlsunset -l 36.2 -L 81.7
diff --git a/.config/s6-rc/wlsunset/type b/.config/s6-rc/wlsunset/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/wlsunset/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/xdg-desktop-portal-log/consumer-for b/.config/s6-rc/xdg-desktop-portal-log/consumer-for
new file mode 100644
index 0000000..8f7c009
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal-log/consumer-for
@@ -0,0 +1 @@
+xdg-desktop-portal
diff --git a/.config/s6-rc/xdg-desktop-portal-log/notification-fd b/.config/s6-rc/xdg-desktop-portal-log/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal-log/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/xdg-desktop-portal-log/pipeline-name b/.config/s6-rc/xdg-desktop-portal-log/pipeline-name
new file mode 100644
index 0000000..f31d587
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal-log/pipeline-name
@@ -0,0 +1 @@
+xdg-desktop-portal-pipeline
diff --git a/.config/s6-rc/xdg-desktop-portal-log/run b/.config/s6-rc/xdg-desktop-portal-log/run
new file mode 100755
index 0000000..0f16b96
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal-log/run
@@ -0,0 +1,4 @@
+#!/bin/execlineb -P
+importas -i HOME HOME
+exec -c
+s6-log -d3 -- t ${HOME}/.local/state/s6/logs/xdg-desktop-portal
diff --git a/.config/s6-rc/xdg-desktop-portal-log/type b/.config/s6-rc/xdg-desktop-portal-log/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal-log/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/s6-rc/xdg-desktop-portal/dependencies.d/dbus b/.config/s6-rc/xdg-desktop-portal/dependencies.d/dbus
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal/dependencies.d/dbus
diff --git a/.config/s6-rc/xdg-desktop-portal/dependencies.d/pipewire b/.config/s6-rc/xdg-desktop-portal/dependencies.d/pipewire
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal/dependencies.d/pipewire
diff --git a/.config/s6-rc/xdg-desktop-portal/dependencies.d/wayland b/.config/s6-rc/xdg-desktop-portal/dependencies.d/wayland
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal/dependencies.d/wayland
diff --git a/.config/s6-rc/xdg-desktop-portal/finish b/.config/s6-rc/xdg-desktop-portal/finish
new file mode 100755
index 0000000..b22f9dc
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal/finish
@@ -0,0 +1,3 @@
+#!/command/execlineb -P
+s6-permafailon 60 10 1-255
+exit
diff --git a/.config/s6-rc/xdg-desktop-portal/notification-fd b/.config/s6-rc/xdg-desktop-portal/notification-fd
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal/notification-fd
@@ -0,0 +1 @@
+3
diff --git a/.config/s6-rc/xdg-desktop-portal/producer-for b/.config/s6-rc/xdg-desktop-portal/producer-for
new file mode 100644
index 0000000..67fad61
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal/producer-for
@@ -0,0 +1 @@
+xdg-desktop-portal-log
diff --git a/.config/s6-rc/xdg-desktop-portal/run b/.config/s6-rc/xdg-desktop-portal/run
new file mode 100755
index 0000000..5c814c3
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal/run
@@ -0,0 +1,6 @@
+#!/bin/execlineb -P
+fdmove -c 2 1
+importas -i XDG_RUNTIME_DIR XDG_RUNTIME_DIR
+s6-envdir ${XDG_RUNTIME_DIR}/wl_env
+dbus-waiter -n3 -b org.freedesktop.portal.Desktop
+/usr/libexec/xdg-desktop-portal
diff --git a/.config/s6-rc/xdg-desktop-portal/type b/.config/s6-rc/xdg-desktop-portal/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/.config/s6-rc/xdg-desktop-portal/type
@@ -0,0 +1 @@
+longrun
diff --git a/.config/sway/config b/.config/sway/config
new file mode 100644
index 0000000..82d7345
--- /dev/null
+++ b/.config/sway/config
@@ -0,0 +1,186 @@
+include catppuccin-mocha
+
+set $mod Mod4
+set $left h
+set $down j
+set $up k
+set $right l
+set $term foot
+set $menu wmenu-run
+
+input type:pointer {
+ left_handed enabled
+}
+
+input type:keyboard {
+ repeat_delay 300
+ repeat_rate 40
+}
+
+ bindsym $mod+Return exec $term
+ bindsym $mod+p exec $menu
+ bindsym $mod+Shift+q kill
+ bindsym $mod+Shift+c reload
+ bindsym $mod+Shift+e exec wmenu-yesno 'Really exit?' swaymsg exit
+ floating_modifier $mod normal
+
+ bindsym $mod+$left focus left
+ bindsym $mod+$down focus down
+ bindsym $mod+$up focus up
+ bindsym $mod+$right focus right
+
+ bindsym $mod+Left focus left
+ bindsym $mod+Down focus down
+ bindsym $mod+Up focus up
+ bindsym $mod+Right focus right
+
+ bindsym $mod+Shift+$left move left 10px
+ bindsym $mod+Shift+$down move down 10px
+ bindsym $mod+Shift+$up move up 10px
+ bindsym $mod+Shift+$right move right 10px
+
+ bindsym $mod+Shift+Left move left 10px
+ bindsym $mod+Shift+Down move down 10px
+ bindsym $mod+Shift+Up move up 10px
+ bindsym $mod+Shift+Right move right 10px
+
+ bindsym $mod+Mod1+Shift+$left move left 1px
+ bindsym $mod+Mod1+Shift+$down move down 1px
+ bindsym $mod+Mod1+Shift+$up move up 1px
+ bindsym $mod+Mod1+Shift+$right move right 1px
+
+ bindsym $mod+Mod1+Shift+Left move left 1px
+ bindsym $mod+Mod1+Shift+Down move down 1px
+ bindsym $mod+Mod1+Shift+Up move up 1px
+ bindsym $mod+Mod1+Shift+Right move right 1px
+
+ bindsym $mod+1 workspace number 1
+ bindsym $mod+2 workspace number 2
+ bindsym $mod+3 workspace number 3
+ bindsym $mod+4 workspace number 4
+ bindsym $mod+5 workspace number 5
+ bindsym $mod+6 workspace number 6
+ bindsym $mod+7 workspace number 7
+ bindsym $mod+8 workspace number 8
+ bindsym $mod+9 workspace number 9
+
+ bindsym $mod+Shift+1 move container to workspace number 1
+ bindsym $mod+Shift+2 move container to workspace number 2
+ bindsym $mod+Shift+3 move container to workspace number 3
+ bindsym $mod+Shift+4 move container to workspace number 4
+ bindsym $mod+Shift+5 move container to workspace number 5
+ bindsym $mod+Shift+6 move container to workspace number 6
+ bindsym $mod+Shift+7 move container to workspace number 7
+ bindsym $mod+Shift+8 move container to workspace number 8
+ bindsym $mod+Shift+9 move container to workspace number 9
+
+ bindsym $mod+b splith
+ bindsym $mod+v splitv
+
+ bindsym $mod+s layout stacking
+ bindsym $mod+w layout tabbed
+ bindsym $mod+e layout toggle split
+
+ bindsym $mod+f fullscreen
+
+ bindsym $mod+Shift+space floating toggle
+ bindsym $mod+space focus mode_toggle
+
+ bindsym $mod+a focus parent
+
+ bindsym $mod+Shift+minus move scratchpad
+ bindsym $mod+minus scratchpad show
+
+mode "resize" {
+ bindsym $left resize shrink width 10px
+ bindsym $down resize grow height 10px
+ bindsym $up resize shrink height 10px
+ bindsym $right resize grow width 10px
+
+ bindsym Left resize shrink width 10px
+ bindsym Down resize grow height 10px
+ bindsym Up resize shrink height 10px
+ bindsym Right resize grow width 10px
+
+ bindsym Mod1+$left resize shrink width 1px
+ bindsym Mod1+$down resize grow height 1px
+ bindsym Mod1+$up resize shrink height 1px
+ bindsym Mod1+$right resize grow width 1px
+
+ bindsym Mod1+Left resize shrink width 1px
+ bindsym Mod1+Down resize grow height 1px
+ bindsym Mod1+Up resize shrink height 1px
+ bindsym Mod1+Right resize grow width 1px
+
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+}
+bindsym $mod+r mode "resize"
+
+bindsym XF86MonBrightnessUp exec brightctl +5
+bindsym XF86MonBrightnessDown exec brightctl -5
+bindsym XF86AudioRaiseVolume exec wpctl set-volume @DEFAULT_SINK@ 5%+
+bindsym XF86AudioLowerVolume exec wpctl set-volume @DEFAULT_SINK@ 5%-
+bindsym XF86AudioMute exec wpctl set-mute @DEFAULT_SINK@ toggle
+
+font 'FiraCode Nerd Font 11'
+
+set $gap 6
+
+gaps inner $gap
+
+titlebar_border_thickness 2
+
+# target border bg text indicator child_border
+client.focused $overlay0 $overlay0 $text $overlay0 $overlay0
+client.focused_inactive $surface0 $surface0 $text $overlay0 $surface0
+client.unfocused $mantle $mantle $text $overlay0 $mantle
+client.urgent $red $red $base $overlay0 $red
+client.background $base
+
+bar {
+ position top
+ output eDP-1
+
+ status_command statusbar
+ separator_symbol ''
+ pango_markup enabled
+ status_padding 6
+ status_edge_padding 0
+ workspace_min_width 32
+ gaps $gap
+
+ font 'FiraCode Nerd Font 11'
+
+ colors {
+ background $base
+ statusline $text
+ # separator
+ # focused_background
+ # focused_statusline
+ # focused_separator
+ focused_workspace $blue $blue $base
+ active_workspace $surface0 $surface0 $overlay2
+ inactive_workspace $base $base $overlay2
+ urgent_workspace $base $base $red
+ binding_mode $base $base $red
+ }
+}
+
+output HEADLESS-1 {
+ resolution 472x96
+ position 1920,0
+ bg '#000000' solid_color
+}
+workspace 10 output HEADLESS-1
+bindsym $mod+0 workspace number 10
+bindsym $mod+Shift+0 move container to workspace number 10
+
+exec printf %s\\n "$WAYLAND_DISPLAY" >"$XDG_RUNTIME_DIR"/wl_env/WAYLAND_DISPLAY
+exec printf %s\\n "$DISPLAY" >"$XDG_RUNTIME_DIR"/wl_env/DISPLAY
+exec printf %s\\n "$SWAYSOCK" >"$XDG_RUNTIME_DIR"/wl_env/SWAYSOCK
+exec printf %s\\n "$I3SOCK" >"$XDG_RUNTIME_DIR"/wl_env/I3SOCK
+exec dbus-update-activation-environment WAYLAND_DISPLAY DISPLAY XDG_CURRENT_DESKTOP=sway
+exec printf \\n >"$XDG_RUNTIME_DIR"/service/sway/data/ready
+
+include /etc/sway/config.d/*
diff --git a/.config/swayidle/config b/.config/swayidle/config
new file mode 100644
index 0000000..f95ca57
--- /dev/null
+++ b/.config/swayidle/config
@@ -0,0 +1,3 @@
+timeout 180 'brightctl -20' resume 'brightctl +20'
+timeout 285 'swaymsg output \* power off' resume 'swaymsg output \* power on'
+timeout 300 'powerctl mem & waylock'
diff --git a/.config/user-dirs.dirs b/.config/user-dirs.dirs
new file mode 100644
index 0000000..7f9a959
--- /dev/null
+++ b/.config/user-dirs.dirs
@@ -0,0 +1,15 @@
+# This file is written by xdg-user-dirs-update
+# If you want to change or add directories, just edit the line you're
+# interested in. All local changes will be retained on the next run.
+# Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
+# homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
+# absolute path. No other format is supported.
+#
+XDG_DESKTOP_DIR="$HOME/Desktop"
+XDG_DOWNLOAD_DIR="$HOME/Downloads"
+XDG_TEMPLATES_DIR="$HOME/Templates"
+XDG_PUBLICSHARE_DIR="$HOME/Public"
+XDG_DOCUMENTS_DIR="$HOME/Documents"
+XDG_MUSIC_DIR="$HOME/Music"
+XDG_PICTURES_DIR="$HOME/Pictures"
+XDG_VIDEOS_DIR="$HOME/Videos"
diff --git a/.config/user-dirs.locale b/.config/user-dirs.locale
new file mode 100644
index 0000000..96d80cd
--- /dev/null
+++ b/.config/user-dirs.locale
@@ -0,0 +1 @@
+C \ No newline at end of file
diff --git a/.config/vis/lexers/execline.lua b/.config/vis/lexers/execline.lua
new file mode 100644
index 0000000..cb79c8d
--- /dev/null
+++ b/.config/vis/lexers/execline.lua
@@ -0,0 +1,64 @@
+-- Copyright 2023 Sam Nystrom <sam@samnystrom.dev>
+-- Execline LPeg lexer.
+
+local l = require('lexer')
+local token, word_match = l.token, l.word_match
+local P, R, S = lpeg.P, lpeg.R, lpeg.S
+
+local M = {_NAME = 'execline'}
+
+-- Whitespace.
+local ws = token(l.WHITESPACE, l.space^1)
+
+-- Comments.
+local comment = token(l.COMMENT, l.starts_line(S('#')) * l.nonnewline^0)
+
+-- Strings.
+local sq_str = l.range("'")
+local dq_str = l.range('"')
+local string = token(l.STRING, sq_str + dq_str)
+
+-- Numbers.
+local dec = l.digit^1 * ('_' * l.digit^1)^0
+local oct_num = '0' * S('01234567_')^1
+local integer = S('+-')^-1 * (l.hex_num + oct_num + dec)
+local number = token(l.NUMBER, (l.float + integer))
+
+-- Keywords.
+local keyword = token(l.KEYWORD, word_match{
+ 'execlineb', 'execline-cd', 'posix-cd', 'execline-umask', 'posix-umask',
+ 'emptyenv', 'envfile', 'export', 'unexport', 'fdclose', 'fdblock', 'fdmove',
+ 'fdswap', 'fdreserve', 'redirfd', 'piperw', 'heredoc', 'wait', 'getcwd',
+ 'getpid', 'exec', 'tryexec', 'exit', 'trap', 'withstdinas',
+ 'foreground', 'background', 'case', 'if', 'ifelse', 'ifte', 'ifthenelse',
+ 'backtick', 'pipeline', 'runblock',
+ 'define', 'importas', 'elglob', 'elgetpositionals', 'multidefine',
+ 'multisubstitute',
+ 'forx', 'forstdin', 'forbacktickx', 'loopwhilex',
+ 'elgetopt', 'shift', 'dollarat',
+ 'eltest', 'homeof',
+ 'execline'
+})
+
+-- Identifiers.
+local identifier = token(l.IDENTIFIER, l.word)
+
+local variable = token(l.VARIABLE, '$' * (l.word + l.range('{}', true, true, true)))
+
+-- Operators.
+local operator = token(l.OPERATOR, S('{}'))
+
+M._rules = {
+ {'whitespace', ws},
+ {'keyword', keyword},
+ {'identifier', identifier},
+ {'string', string},
+ {'comment', comment},
+ {'number', number},
+ {'variable', variable},
+ {'operator', operator},
+}
+
+M._LEXBYLINE = true
+
+return M
diff --git a/.config/vis/lexers/hare.lua b/.config/vis/lexers/hare.lua
new file mode 100644
index 0000000..0aacad3
--- /dev/null
+++ b/.config/vis/lexers/hare.lua
@@ -0,0 +1,82 @@
+-- Copyright 2023 Sam Nystrom <sam@samnystrom.dev>
+-- Hare LPeg lexer
+
+local l = require('lexer')
+local C, Cmt, P, R, S = lpeg.C, lpeg.Cmt, lpeg.P, lpeg.R, lpeg.S
+
+local lex = l.new('hare')
+
+-- Whitespace
+lex:add_rule('whitespace', l.token(l.WHITESPACE, l.space^1))
+
+-- Comments
+lex:add_rule('comment', l.token(l.COMMENT, l.to_eol('//', true)))
+
+-- Keywords
+lex:add_rule('keyword', l.token(l.KEYWORD, l.word_match{
+ 'as', 'is',
+ 'if', 'else', 'match', 'switch',
+ 'break', 'continue', 'defer', 'return', 'yield',
+ 'const', 'def', 'let',
+ 'fn',
+ 'case',
+ 'for',
+ 'export', 'static',
+ 'enum', 'struct', 'union',
+ 'type',
+}))
+
+-- Builtins
+lex:add_rule('function', l.token(l.FUNCTION, l.word_match{
+ 'abort', 'assert',
+ 'align', 'len', 'offset',
+ 'alloc', 'free',
+ 'append', 'insert', 'delete',
+ -- C ABI
+ 'vastart', 'vaarg', 'vaend',
+}))
+
+-- Types
+lex:add_rule('type', l.token(l.TYPE, l.word_match{
+ 'bool',
+ 'f32', 'f64',
+ 'i8', 'i16', 'i32', 'i64', 'u8', 'u16', 'u32', 'u64',
+ 'size', 'int', 'uint', 'uintptr',
+ 'never',
+ 'nullable',
+ 'opaque',
+ 'rune', 'str',
+ 'void',
+ -- C ABI
+ 'valist',
+}))
+
+-- Constants
+lex:add_rule('constant', l.token(l.CONSTANT, l.word_match{'true', 'false', 'null'}))
+
+-- Numbers
+--[[local identifier = P('r#')^-1 * l.word
+local function opt_cap(patt) return C(patt^-1) end
+local float = l.digit *
+ (Cmt(opt_cap('.' * l.digit) * opt_cap(S('eE') * S('+-')^-1 * l.digit) *
+ opt_cap(P('f32') + 'f64'), function(input, index, decimals, exponent, type)
+ return decimals ~= "" or exponent ~= "" or type ~= ""
+ end) + '.' * -(S('._') + identifier))
+local bin = P('0b') * S('01')
+local oct = P('0o') * lpeg.R('07')
+local hex = P('0x') * l.xdigit
+local integer = (bin + oct + hex + decimal_literal) *
+ (S('iu') * (P('8') + '16' + '32' + '64' + '128' + 'size'))^-1
+--]]
+lex:add_rule('number', l.token(l.NUMBER, l.float + l.integer))
+
+-- Strings
+lex:add_rule('string', l.token(l.STRING, l.range('"') + l.range('\'')))
+
+-- Operators
+lex:add_rule('operator', l.token(l.OPERATOR, S('+-/*<>!=@~&|^?:;,.()[]{}')))
+
+lex:add_fold_point(l.OPERATOR, '{', '}')
+lex:add_fold_point(l.COMMENT, l.fold_consecutive_lines('//'))
+
+return lex
diff --git a/.config/vis/lexers/roff.lua b/.config/vis/lexers/roff.lua
new file mode 100644
index 0000000..59657a7
--- /dev/null
+++ b/.config/vis/lexers/roff.lua
@@ -0,0 +1,32 @@
+-- Copyright 2023 Sam Nystrom <sam@samnystrom.dev>
+-- Roff LPeg lexer.
+
+local l = require('lexer')
+local token, word_match = l.token, l.word_match
+local P, R, S = lpeg.P, lpeg.R, lpeg.S
+
+local M = {_NAME = 'roff'}
+
+-- Whitespace
+local ws = token(l.WHITESPACE, l.space^1)
+
+-- Comments
+local comment = token(l.COMMENT, '\\"' * l.nonnewline^0)
+
+-- Strings
+local string = token(l.STRING, l.delimited_range('"'))
+
+-- Keywords
+local word = (l.alpha + '_') * (l.alnum + S('_.'))^0
+local keyword = token(l.KEYWORD, l.starts_line('.') * l.word)
+
+M._rules = {
+ {'whitespace', ws},
+ {'keyword', keyword},
+ {'string', string},
+ {'comment', comment},
+}
+
+M._LEXBYLINE = true
+
+return M
diff --git a/.config/vis/themes/flexoki.lua b/.config/vis/themes/flexoki.lua
new file mode 100644
index 0000000..e540a00
--- /dev/null
+++ b/.config/vis/themes/flexoki.lua
@@ -0,0 +1,125 @@
+local mode = 'dark' -- one of 'dark' or 'light'
+
+local colors = {
+ black = '#100f0f',
+ base950 = '#1c1b1a',
+ base900 = '#282726',
+ base850 = '#343331',
+ base800 = '#403e3c',
+ base700 = '#575653',
+ base600 = '#6f6e69',
+ base500 = '#878580',
+ base300 = '#b7b5ac',
+ base200 = '#cecdc3',
+ base150 = '#dad8ce',
+ base100 = '#e6e4d9',
+ base50 = '#f2f0e5',
+ paper = '#fffcf0',
+ red600 = '#af3029',
+ orange600 = '#bc5215',
+ yellow600 = '#ad8301',
+ green600 = '#66800b',
+ cyan600 = '#24837b',
+ blue600 = '#205ea6',
+ purple600 = '#5e409d',
+ magenta600 = '#a02f6f',
+ red400 = '#d14d41',
+ orange400 = '#da702c',
+ yellow400 = '#d0a215',
+ green400 = '#879a39',
+ cyan400 = '#3aa99f',
+ blue400 = '#4385be',
+ purple400 = '#8b7ec8',
+ magenta400 = '#ce5d97',
+}
+
+if mode == 'light' then
+ colors.bg = colors.paper
+ colors.bg2 = colors.base50
+ colors.ui = colors.base100
+ colors.ui2 = colors.base150
+ colors.ui3 = colors.base200
+ colors.tx3 = colors.base300
+ colors.tx2 = colors.base600
+ colors.tx = colors.black
+
+ colors.re = colors.red600
+ colors.ng = colors.orange600
+ colors.ye = colors.yellow600
+ colors.gr = colors.green600
+ colors.cy = colors.cyan600
+ colors.bl = colors.blue600
+ colors.pu = colors.purple600
+ colors.ma = colors.magenta600
+
+ colors.re2 = colors.red400
+ colors.ng2 = colors.orange400
+ colors.ye2 = colors.yellow400
+ colors.gr2 = colors.green400
+ colors.cy2 = colors.cyan400
+ colors.bl2 = colors.blue400
+ colors.pu2 = colors.purple400
+ colors.ma2 = colors.magenta400
+else
+ colors.bg = colors.black
+ colors.bg2 = colors.base950
+ colors.ui = colors.base900
+ colors.ui2 = colors.base850
+ colors.ui3 = colors.base800
+ colors.tx3 = colors.base700
+ colors.tx2 = colors.base500
+ colors.tx = colors.base200
+
+ colors.re = colors.red400
+ colors.ng = colors.orange400
+ colors.ye = colors.yellow400
+ colors.gr = colors.green400
+ colors.cy = colors.cyan400
+ colors.bl = colors.blue400
+ colors.pu = colors.purple400
+ colors.ma = colors.magenta400
+
+ colors.re2 = colors.red600
+ colors.ng2 = colors.orange600
+ colors.ye2 = colors.yellow600
+ colors.gr2 = colors.green600
+ colors.cy2 = colors.cyan600
+ colors.bl2 = colors.blue600
+ colors.pu2 = colors.purple600
+ colors.ma2 = colors.magenta600
+end
+
+vis.lexers.STYLE_DEFAULT = 'fore:'..colors.tx..',back:'..colors.bg
+vis.lexers.STYLE_NOTHING = ''
+vis.lexers.STYLE_CLASS = 'fore:'..colors.ng
+vis.lexers.STYLE_COMMENT = 'fore:'..colors.tx3
+vis.lexers.STYLE_CONSTANT = 'fore:'..colors.ye
+vis.lexers.STYLE_DEFINITION = 'fore:'..colors.ng
+vis.lexers.STYLE_ERROR = 'fore:'..colors.re2..',bold'
+vis.lexers.STYLE_FUNCTION = 'fore:'..colors.ng
+vis.lexers.STYLE_KEYWORD = 'fore:'..colors.gr
+vis.lexers.STYLE_LABEL = 'fore:'..colors.gr
+vis.lexers.STYLE_NUMBER = 'fore:'..colors.pu
+vis.lexers.STYLE_OPERATOR = 'fore:'..colors.tx2
+vis.lexers.STYLE_REGEX = 'fore:'..colors.cy
+vis.lexers.STYLE_STRING = 'fore:'..colors.cy
+vis.lexers.STYLE_PREPROCESSOR = 'fore:'..colors.ma
+vis.lexers.STYLE_TAG = 'fore:'..colors.cy
+vis.lexers.STYLE_TYPE = 'fore:'..colors.gr
+vis.lexers.STYLE_VARIABLE = 'fore:'..colors.re..',bold'
+vis.lexers.STYLE_WHITESPACE = 'fore:'..colors.tx3
+vis.lexers.STYLE_EMBEDDED = 'fore:'..colors.re..',bold'
+vis.lexers.STYLE_IDENTIFIER = 'fore:'..colors.bl
+
+vis.lexers.STYLE_LINENUMBER = 'fore:'..colors.tx3
+vis.lexers.STYLE_LINENUMBER_CURSOR = 'fore:'..colors.tx
+vis.lexers.STYLE_CURSOR = 'fore:'..colors.bg..',back:'..colors.tx
+vis.lexers.STYLE_CURSOR_PRIMARY = 'fore:'..colors.bg..',back:'..colors.tx
+vis.lexers.STYLE_CURSOR_LINE = 'back:'..colors.bg2
+vis.lexers.STYLE_COLOR_COLUMN = 'back:'..colors.ui
+vis.lexers.STYLE_SELECTION = 'back:'..colors.ui
+vis.lexers.STYLE_STATUS = 'fore:'..colors.tx2..',back:'..colors.ui
+vis.lexers.STYLE_STATUS_FOCUSED = 'fore:'..colors.tx..',back:'..colors.ui2
+vis.lexers.STYLE_SEPARATOR = 'fore:'..colors.ui3
+vis.lexers.STYLE_INFO = 'fore:'..colors.ye..',bold'
+vis.lexers.STYLE_EOF = 'fore:'..colors.tx3 \ No newline at end of file
diff --git a/.config/vis/visrc.lua b/.config/vis/visrc.lua
new file mode 100644
index 0000000..982056e
--- /dev/null
+++ b/.config/vis/visrc.lua
@@ -0,0 +1,65 @@
+require('vis')
+
+require('plugins/vis-backspace')
+require('plugins/vis-ctags')
+require('plugins/vis-cursors')
+require('plugins/vis-editorconfig')
+require('plugins/vis-quickfix')
+
+for _, ext in ipairs({ "%.jsx$", "%.ts", "%.tsx$" }) do
+ table.insert(vis.ftdetect.filetypes.javascript.ext, ext)
+end
+
+for _, ext in ipairs({ "^Containerfile$", "%.Containerfile$" }) do
+ table.insert(vis.ftdetect.filetypes.dockerfile.ext, ext)
+end
+
+vis.ftdetect.filetypes.hare = {
+ ext = { "%.ha$" },
+}
+
+shebangs = {
+ awk = { "awk" },
+ bash = { "bash", "sh" },
+ execline = { "execlineb" },
+ perl = { "perl" },
+ python = { "python", "python3" },
+}
+
+vis.events.subscribe(vis.events.WIN_OPEN, function(win)
+ local shebang = vis.win.file.lines[1]
+ local cmd = shebang:match("^#!%g*/([^/%s]+)")
+ if cmd == "env" then
+ cmd = shebang:match("^#!%g*/env (%g+)")
+ end
+ for syntax, cmds in pairs(shebangs) do
+ for _, c in ipairs(cmds) do
+ if c == cmd then
+ vis:command("set syntax " .. syntax)
+ return
+ end
+ end
+ end
+end)
+
+vis.events.subscribe(vis.events.INIT, function()
+ vis:command('set escdelay 25')
+ vis:command('set autoindent')
+ vis:command('set theme flexoki')
+end)
+
+vis.events.subscribe(vis.events.WIN_OPEN, function(win)
+ vis:command('set relativenumbers')
+end)
+
+function automake_handler()
+ vis:command('make')
+end
+
+vis:option_register('automake', 'bool', function(value, toggle)
+ if toggle then
+ vis.events.subscribe(vis.events.FILE_SAVE_POST, automake_handler)
+ else
+ vis.events.unsubscribe(vis.events.FILE_SAVE_POST, automake_handler)
+ end
+end, 'Run :make automatically after saving')
diff --git a/.config/waywall/flake.lock b/.config/waywall/flake.lock
new file mode 100644
index 0000000..128df5b
--- /dev/null
+++ b/.config/waywall/flake.lock
@@ -0,0 +1,61 @@
+{
+ "nodes": {
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1731533236,
+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1763966396,
+ "narHash": "sha256-6eeL1YPcY1MV3DDStIDIdy/zZCDKgHdkCmsrLJFiZf0=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "5ae3b07d8d6527c42f17c876e404993199144b6a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "flake-utils": "flake-utils",
+ "nixpkgs": "nixpkgs"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/.config/waywall/flake.nix b/.config/waywall/flake.nix
new file mode 100644
index 0000000..a463acc
--- /dev/null
+++ b/.config/waywall/flake.nix
@@ -0,0 +1,57 @@
+{
+ description = "Ninjabrain Bot - Minecraft speedrunning utility";
+
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ flake-utils.url = "github:numtide/flake-utils";
+ };
+
+ outputs = { self, nixpkgs, flake-utils }:
+ flake-utils.lib.eachDefaultSystem (system:
+ let
+ pkgs = nixpkgs.legacyPackages.${system};
+
+ ninjabrain-bot = pkgs.stdenv.mkDerivation {
+ pname = "ninjabrain-bot";
+ version = "1.5.1";
+
+ src = pkgs.fetchurl {
+ url = "https://github.com/Ninjabrain1/Ninjabrain-Bot/releases/download/1.5.1/Ninjabrain-Bot-1.5.1.jar";
+ sha256 = "sha256-Rxu9A2EiTr69fLBUImRv+RLC2LmosawIDyDPIaRcrdw=";
+ };
+
+ dontUnpack = true;
+
+ nativeBuildInputs = [ pkgs.makeWrapper ];
+
+ installPhase = ''
+ mkdir -p $out/bin $out/share/ninjabrain-bot
+ cp $src $out/share/ninjabrain-bot/ninjabrain-bot.jar
+
+ makeWrapper ${pkgs.jre8}/bin/java $out/bin/ninjabrain-bot \
+ --add-flags "-Dawt.useSystemAAFontSettings=on" \
+ --add-flags "-jar $out/share/ninjabrain-bot/ninjabrain-bot.jar" \
+ --prefix LD_LIBRARY_PATH : ${pkgs.lib.makeLibraryPath [
+ pkgs.libxkbcommon
+ pkgs.xorg.libX11
+ pkgs.xorg.libXt
+ ]}
+ '';
+
+ meta = with pkgs.lib; {
+ description = "Stronghold calculator for Minecraft speedrunning";
+ homepage = "https://github.com/Ninjabrain1/Ninjabrain-Bot";
+ license = licenses.mit;
+ platforms = platforms.linux;
+ };
+ };
+ in
+ {
+ packages.default = ninjabrain-bot;
+ apps.default = {
+ type = "app";
+ program = "${ninjabrain-bot}/bin/ninjabrain-bot";
+ };
+ }
+ );
+}
diff --git a/.config/waywall/init.lua b/.config/waywall/init.lua
new file mode 100644
index 0000000..853ac64
--- /dev/null
+++ b/.config/waywall/init.lua
@@ -0,0 +1,224 @@
+local waywall = require("waywall")
+local helpers = require("waywall.helpers")
+
+local Scene = require("waywork.scene")
+local Modes = require("waywork.modes")
+local Keys = require("waywork.keys")
+local Processes = require("waywork.processes")
+
+local scene = Scene.SceneManager.new(waywall)
+local ModeManager = Modes.ModeManager.new(waywall)
+
+local waywall_config_path = os.getenv("HOME") .. "/.config/waywall"
+
+--[[
+celeste menu colors:
+
+light pink: ff92b1
+lavender: 9768e4
+med green: 419462
+pale yellow: ffff99
+gray blue: 759cb2
+dark gray blue: 36527c
+dark gray: 3b566b
+cyan: 53cfde
+brick red: ba5358
+med yellow: fff672
+royal purple: 8d24ed
+pale pink: eb82ff
+sky blue: 54b0ff
+cornflower blue: 606de7
+gold: ffea42
+med blue: 448ede
+deep red: 8a2939
+brightish red: f53c4c
+
+--]]
+
+local bg_color = "#ffffff"
+
+local pie_colors = {
+ entities = { pie = "#e446c4", text = "#e145c2", out = "#f225fc" },
+ unspecified = { pie = "#46ce66", text = "#45cc65", out = "#56f440" },
+ blockEntities = { pie = "#ec6e4e", text = "#e96d4d", out = "#f48769" },
+ destroyProgress = { pie = "#cc6c46", text = "#ca6b45", out = "#c78b56" },
+ mob_spawner = { pie = "#4ee4cc", text = "#4de1ca", out = "#63f9fb" },
+ chest = { pie = "#c66ee4", text = "#c46de1", out = "#e75dfc" },
+}
+
+local normal_sens = 12.800000599064097
+local tall_sens = 0.8634803836976988
+
+local pie_dst = { x = 1200, y = 400, w = 340, h = 340 }
+local percent_dst = { x = 1280, y = 800, w = 34 * 6, h = 25 * 6 }
+local eye_dst = { x = 30, y = 340, w = 700, h = 400 }
+
+local f3_root = { x = 1200, y = 150 }
+local f3_scale = 5
+local f3_text_color = "#48106e"
+
+function add_f3_scene(name, row, col, len, groups)
+ scene:register(name, {
+ kind = "mirror",
+ options = {
+ src = { x = col * 6 + 1, y = row * 9 + 1, w = len * 6, h = 9 },
+ dst = { x = f3_root.x, y = f3_root.y, w = len * 6 * f3_scale, h = 9 * f3_scale },
+ color_key = {
+ input = "#dddddd",
+ output = f3_text_color,
+ },
+ depth = 1,
+ },
+ groups = groups,
+ })
+ f3_root.y = f3_root.y + 9 * f3_scale
+end
+
+add_f3_scene("c_counter", 3, 0, 11, { "thin", "tall" })
+add_f3_scene("e_counter", 4, 0, 8, { "thin", "tall" })
+
+for _, name in ipairs({ "wide", "thin", "tall" }) do
+ scene:register(name .. "_bg", {
+ kind = "image",
+ path = waywall_config_path .. "/resources/" .. name .. "_bg.png",
+ options = {
+ dst = { x = 0, y = 0, w = 1920, h = 1080 },
+ },
+ groups = { name },
+ })
+end
+
+scene:register("bubble", {
+ kind = "image",
+ path = waywall_config_path .. "/resources/bubble_pie.png",
+ options = {
+ dst = pie_dst,
+ depth = -1
+ },
+ groups = { "thin", "tall" },
+})
+
+for name, colors in pairs(pie_colors) do
+ scene:register("thin_pie_" .. name, {
+ kind = "mirror",
+ options = {
+ src = { x = 9, y = 680, w = 321, h = 160 },
+ dst = pie_dst,
+ color_key = { input = colors.pie, output = colors.out },
+ },
+ groups = { "thin" },
+ })
+
+ scene:register("tall_pie_" .. name, {
+ kind = "mirror",
+ options = {
+ src = { x = 9, y = 15984, w = 321, h = 160 },
+ dst = pie_dst,
+ color_key = { input = colors.pie, output = colors.out },
+ },
+ groups = { "tall" },
+ })
+ scene:register("thin_percent_" .. name, {
+ kind = "mirror",
+ options = {
+ src = { x = 247, y = 859, w = 34, h = 25 },
+ dst = percent_dst,
+ color_key = { input = colors.text, output = colors.out },
+ depth = 1,
+ },
+ groups = { "thin" },
+ })
+ scene:register("tall_percent_" .. name, {
+ kind = "mirror",
+ options = {
+ src = { x = 247, y = 16163, w = 34, h = 25 },
+ dst = percent_dst,
+ color_key = { input = colors.text, output = colors.out },
+ depth = 1,
+ },
+ groups = { "tall" },
+ })
+end
+
+scene:register("eye_measure", {
+ kind = "mirror",
+ options = {
+ src = { x = 140, y = 7902, w = 60, h = 580 },
+ dst = eye_dst,
+ },
+ groups = { "tall" },
+})
+
+scene:register("eye_overlay", {
+ kind = "image",
+ path = waywall_config_path .. "/resources/measuring_overlay.png",
+ options = { dst = eye_dst },
+ groups = { "tall" },
+})
+
+ModeManager:define("thin", {
+ width = 340,
+ height = 1080,
+ on_enter = function() scene:enable_group("thin", true) end,
+ on_exit = function() scene:enable_group("thin", false) end,
+})
+
+ModeManager:define("tall", {
+ width = 340,
+ height = 16384,
+ on_enter = function()
+ scene:enable_group("tall", true)
+ waywall.set_sensitivity(tall_sens)
+ end,
+ on_exit = function()
+ scene:enable_group("tall", false)
+ waywall.set_sensitivity(normal_sens)
+ end,
+ toggle_guard = function() return not waywall.get_key("F3") end,
+})
+
+ModeManager:define("wide", {
+ width = 1920,
+ height = 300,
+ on_enter = function() scene:enable_group("wide", true) end,
+ on_exit = function() scene:enable_group("wide", false) end,
+})
+
+local ninbot_path = waywall_config_path .. "/result/bin/ninjabrain-bot"
+local ensure_ninbot = Processes.ensure_application(waywall, ninbot_path)("[Nn]injabrain.*\\.jar")
+
+return {
+ input = {
+ layout = "us",
+ variant = "colemak_dh",
+ repeat_rate = 40,
+ repeat_delay = 300,
+ sensitivity = normal_sens,
+ confine_pointer = false,
+ remaps = {
+ ["MB5"] = "F3",
+ ["Enter"] = "Esc",
+ },
+ },
+ theme = {
+ background = bg_color,
+ ninb_anchor = "bottomright",
+ ninb_opacity = 1.0,
+ },
+ experimental = {
+ debug = false,
+ jit = false,
+ tearing = false,
+ scene_add_text = true,
+ },
+ actions = Keys.actions({
+ ["*-F2"] = function() return ModeManager:toggle("thin") end,
+ ["*-F4"] = function() return ModeManager:toggle("tall") end,
+ ["*-apostrophe"] = function() return ModeManager:toggle("wide") end,
+ ["*-Alt_L"] = function()
+ ensure_ninbot()
+ helpers.toggle_floating()
+ end,
+ ["*-Shift-f"] = waywall.toggle_fullscreen,
+ }),
+}
diff --git a/.config/waywall/resources/bubble_pie.png b/.config/waywall/resources/bubble_pie.png
new file mode 100644
index 0000000..b721bbf
--- /dev/null
+++ b/.config/waywall/resources/bubble_pie.png
Binary files differ
diff --git a/.config/waywall/resources/measuring_overlay.png b/.config/waywall/resources/measuring_overlay.png
new file mode 100644
index 0000000..eb3a666
--- /dev/null
+++ b/.config/waywall/resources/measuring_overlay.png
Binary files differ
diff --git a/.config/waywall/resources/tall_bg.png b/.config/waywall/resources/tall_bg.png
new file mode 100644
index 0000000..873ad11
--- /dev/null
+++ b/.config/waywall/resources/tall_bg.png
Binary files differ
diff --git a/.config/waywall/resources/thin_bg.png b/.config/waywall/resources/thin_bg.png
new file mode 100644
index 0000000..8e8e617
--- /dev/null
+++ b/.config/waywall/resources/thin_bg.png
Binary files differ
diff --git a/.config/waywall/resources/wide_bg.png b/.config/waywall/resources/wide_bg.png
new file mode 100644
index 0000000..e353758
--- /dev/null
+++ b/.config/waywall/resources/wide_bg.png
Binary files differ
diff --git a/.config/waywall/waywork/LICENSE b/.config/waywall/waywork/LICENSE
new file mode 100644
index 0000000..c388b70
--- /dev/null
+++ b/.config/waywall/waywork/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Esensats
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/.config/waywall/waywork/README.md b/.config/waywall/waywork/README.md
new file mode 100644
index 0000000..5850eb0
--- /dev/null
+++ b/.config/waywall/waywork/README.md
@@ -0,0 +1,283 @@
+# Waywork
+
+A framework for building [waywall](https://github.com/tesselslate/waywall) configurations for Minecraft speedrunning setups on Linux/Wayland.
+
+## Overview
+
+Waywork provides a structured, modular approach to managing waywall configurations. It abstracts common patterns like resolution switching, scene management, and process orchestration into reusable components, making waywall configs more maintainable and easier to understand.
+
+## Example config
+
+For reference you can look at my config which uses waywork here: [Esensats/waywall-config](https://github.com/Esensats/waywall-config)
+
+## Table of Contents
+
+<!-- @import "[TOC]" {cmd="toc" depthFrom=2 depthTo=6 orderedList=false} -->
+
+<!-- code_chunk_output -->
+
+- [Overview](#overview)
+- [Example config](#example-config)
+- [Table of Contents](#table-of-contents)
+- [Components](#components)
+ - [Scene Manager (`scene.lua`)](#scene-manager-scenelua)
+ - [Mode Manager (`modes.lua`)](#mode-manager-modeslua)
+ - [Key Bindings (`keys.lua`)](#key-bindings-keyslua)
+ - [Core Utilities (`core.lua`)](#core-utilities-corelua)
+ - [Process Management (`processes.lua`)](#process-management-processeslua)
+- [Migration to Waywork](#migration-to-waywork)
+ - [Before](#before)
+ - [After (Waywork)](#after-waywork)
+- [Benefits](#benefits)
+
+<!-- /code_chunk_output -->
+
+## Components
+
+### Scene Manager (`scene.lua`)
+
+Manages visual elements (mirrors, images, text) uniformly with grouping and lifecycle management.
+
+**Features:**
+
+- **Unified Management**: Handle mirrors, images, and text objects through a single interface
+- **Grouping**: Organize scene objects into logical groups for batch operations
+- **Lazy Loading**: Objects are only created when enabled
+- **Dynamic Updates**: Modify object properties at runtime
+
+**Example:**
+
+```lua
+local Scene = require("waywork.scene")
+local scene = Scene.SceneManager.new(waywall)
+
+-- Register scene objects
+scene:register("e_counter", {
+ kind = "mirror",
+ options = {
+ src = { x = 1, y = 37, w = 49, h = 9 },
+ dst = { x = 1150, y = 300, w = 196, h = 36 }
+ },
+ groups = { "thin" },
+})
+
+scene:register("eye_overlay", {
+ kind = "image",
+ path = "/path/to/overlay.png",
+ options = { dst = { x = 30, y = 340, w = 700, h = 400 } },
+ groups = { "tall" },
+})
+
+-- Enable/disable by group
+scene:enable_group("thin", true) -- Enable all "thin" objects
+scene:enable_group("tall", false) -- Disable all "tall" objects
+
+-- Enable/disable individual objects
+scene:enable("e_counter", true)
+```
+
+### Mode Manager (`modes.lua`)
+
+Orchestrates resolution switching with enter/exit hooks and guard conditions.
+
+**Features:**
+
+- **Resolution Management**: Automatic resolution switching with cleanup
+- **Lifecycle Hooks**: `on_enter` and `on_exit` callbacks for mode transitions
+- **Toggle Guards**: Conditional guards to prevent accidental mode switches (e.g. pressing F3 + F4 to switch gamemode, but accidentally triggering mode transition instead)
+- **State Tracking**: Knows which mode is currently active
+
+**Example:**
+
+```lua
+local Modes = require("waywork.modes")
+local ModeManager = Modes.ModeManager.new(waywall)
+
+ModeManager:define("thin", {
+ width = 340,
+ height = 1080,
+ on_enter = function()
+ scene:enable_group("thin", true)
+ end,
+ on_exit = function()
+ scene:enable_group("thin", false)
+ end,
+})
+
+ModeManager:define("tall", {
+ width = 384,
+ height = 16384,
+ toggle_guard = function()
+ return not waywall.get_key("F3") -- Prevent toggle during F3 debug
+ end,
+ on_enter = function()
+ scene:enable_group("tall", true)
+ waywall.set_sensitivity(tall_sens)
+ end,
+ on_exit = function()
+ scene:enable_group("tall", false)
+ waywall.set_sensitivity(0)
+ end,
+})
+
+-- Toggle modes
+ModeManager:toggle("thin") -- Switch to thin mode
+ModeManager:toggle("thin") -- Switch back to default (0x0)
+```
+
+### Key Bindings (`keys.lua`)
+
+Simple utility for building action tables from key mappings.
+
+**Example:**
+
+```lua
+local Keys = require("waywork.keys")
+
+local actions = Keys.actions({
+ ["*-Alt_L"] = function()
+ return ModeManager:toggle("thin")
+ end,
+ ["*-F4"] = function()
+ return ModeManager:toggle("tall")
+ end,
+ ["Ctrl-E"] = function()
+ waywall.press_key("ESC")
+ end,
+})
+
+config.actions = actions
+```
+
+### Core Utilities (`core.lua`)
+
+Low-level utilities used throughout the framework.
+
+**Features:**
+
+- **Toggle**: Boolean state management with callbacks
+- **Resettable Timeout**: Timeout that cancels previous invocations
+- **Table Operations**: Copy and merge utilities
+
+### Process Management (`processes.lua`)
+
+Utilities for managing external processes with shell command handling.
+
+**Features:**
+
+- **Process Detection**: Check if processes are running using `pgrep`
+- **Java JAR Support**: Specialized utilities for launching Java applications
+- **Argument Handling**: Proper handling of command arguments as arrays
+
+**Example:**
+
+```lua
+local P = require("waywork.processes")
+
+-- Check if a process is running
+if P.is_running("firefox") then
+ print("Firefox is running")
+end
+
+-- Create Java JAR launchers with proper argument handling
+local ensure_paceman = P.ensure_java_jar(
+ waywall,
+ "/usr/lib/jvm/java-24-openjdk/bin/java",
+ "/home/user/apps/paceman-tracker.jar",
+ {"--nogui"} -- arguments as array
+)("paceman-tracker\\.jar*") -- process pattern to check
+
+local ensure_ninjabrain = P.ensure_java_jar(
+ waywall,
+ "/usr/lib/jvm/java-24-openjdk/bin/java",
+ "/home/user/apps/ninjabrain-bot.jar",
+ {"-Dawt.useSystemAAFontSettings=on"} -- JVM arguments
+)("ninjabrain-bot\\.jar") -- process pattern to check
+
+-- Use in key bindings
+["Ctrl-Shift-P"] = function()
+ ensure_ninjabrain() -- ensure Ninjabrain is running
+ ensure_paceman() -- ensure Paceman is running
+end,
+```
+
+## Migration to Waywork
+
+### Before
+
+```lua
+-- Scattered mirror management
+local make_mirror = function(options)
+ local this = nil
+ return function(enable)
+ if enable and not this then
+ this = waywall.mirror(options)
+ elseif this and not enable then
+ this:close()
+ this = nil
+ end
+ end
+end
+
+local mirrors = {
+ e_counter = make_mirror({ src = {...}, dst = {...} }),
+ thin_pie_all = make_mirror({ src = {...}, dst = {...} }),
+ -- ... dozens more
+}
+
+-- Manual resolution management
+local make_res = function(width, height, enable, disable)
+ return function()
+ local active_width, active_height = waywall.active_res()
+ if active_width == width and active_height == height then
+ waywall.set_resolution(0, 0)
+ disable()
+ else
+ waywall.set_resolution(width, height)
+ enable()
+ end
+ end
+end
+```
+
+### After (Waywork)
+
+```lua
+local waywall = require("waywall")
+
+local Scene = require("waywork.scene")
+local Modes = require("waywork.modes")
+local Keys = require("waywork.keys")
+
+local scene = Scene.SceneManager.new(waywall)
+local ModeManager = Modes.ModeManager.new(waywall)
+
+-- Clean object registration
+scene:register("e_counter", {
+ kind = "mirror",
+ options = { src = {...}, dst = {...} },
+ groups = { "thin" },
+})
+
+-- Declarative mode definitions
+ModeManager:define("thin", {
+ width = 340,
+ height = 1080,
+ on_enter = function() scene:enable_group("thin", true) end,
+ on_exit = function() scene:enable_group("thin", false) end,
+})
+
+-- Simple key mappings
+local actions = Keys.actions({
+ ["*-Alt_L"] = function() return ModeManager:toggle("thin") end,
+})
+```
+
+## Benefits
+
+1. **Reduced Boilerplate**: Framework handles object lifecycle, resolution management, and state tracking
+2. **Better Organization**: Logical grouping of related functionality
+3. **Maintainability**: Clear separation of concerns and declarative configuration
+4. **Reusability**: Common patterns abstracted into reusable components
+5. **Error Prevention**: Toggle guards and proper state management prevent common issues
+6. **Cleaner Code**: Focus on what you want to achieve, not how to implement it
diff --git a/.config/waywall/waywork/core.lua b/.config/waywall/waywork/core.lua
new file mode 100644
index 0000000..f8cd76b
--- /dev/null
+++ b/.config/waywall/waywork/core.lua
@@ -0,0 +1,61 @@
+local core = {}
+
+--- Create a boolean toggle with on/off callbacks.
+function core.toggle(on, off)
+ local state = false
+ return {
+ set = function(v)
+ if v == state then
+ return state
+ end
+ state = not not v
+ if state then
+ on()
+ else
+ off()
+ end
+ return state
+ end,
+ get = function()
+ return state
+ end,
+ toggle = function(self)
+ return self.set(not state)
+ end,
+ }
+end
+
+--- Create a resettable timeout using blocking sleep (matches waywall execution model).
+--- Calls `f()` only if this invocation is the last one.
+function core.resettable_timeout(sleep, f)
+ local gen = 0
+ return function(delay_ms)
+ gen = gen + 1
+ local my = gen
+ sleep(delay_ms)
+ if my == gen then
+ f()
+ end
+ end
+end
+
+--- Shallow table copy
+function core.copy(t)
+ local r = {}
+ for k, v in pairs(t) do
+ r[k] = v
+ end
+ return r
+end
+
+--- Merge (dst gets missing fields from src)
+function core.merge(dst, src)
+ for k, v in pairs(src or {}) do
+ if dst[k] == nil then
+ dst[k] = v
+ end
+ end
+ return dst
+end
+
+return core
diff --git a/.config/waywall/waywork/keys.lua b/.config/waywall/waywork/keys.lua
new file mode 100644
index 0000000..1bb18e1
--- /dev/null
+++ b/.config/waywall/waywork/keys.lua
@@ -0,0 +1,12 @@
+local K = {}
+
+--- Build actions table from simple mapping { [key] = fn, ... }
+function K.actions(map)
+ local t = {}
+ for k, fn in pairs(map) do
+ t[k] = fn
+ end
+ return t
+end
+
+return K
diff --git a/.config/waywall/waywork/modes.lua b/.config/waywall/waywork/modes.lua
new file mode 100644
index 0000000..3bf0047
--- /dev/null
+++ b/.config/waywall/waywork/modes.lua
@@ -0,0 +1,103 @@
+local modes = {}
+
+--- ModeManager orchestrates resolution toggles and on_enter/on_exit hooks.
+local ModeManager = {}
+ModeManager.__index = ModeManager
+
+function ModeManager.new(waywall)
+ return setmetatable({ ww = waywall, active = nil, defs = {} }, ModeManager)
+end
+
+--- def: { width, height, on_enter=function(), on_exit=function(), toggle_guard=function()->bool }
+function ModeManager:define(name, def)
+ self.defs[name] = def
+end
+
+local function active_res(ww)
+ local w, h = ww.active_res()
+ return tonumber(w), tonumber(h)
+end
+
+--- Get the mode definition by name, erroring if not found.
+--- @param name string
+function ModeManager:_get_def(name)
+ assert(self.defs[name], "No such mode: " .. tostring(name))
+ return self.defs[name]
+end
+
+--- Transition to a mode by name, turning off any previously active mode.
+--- If name is nil, turn off any active mode.
+--- This does not check toggle_guard.
+--- @param name string?
+function ModeManager:_transition_to(name)
+ local function exit_active()
+ if self.active then
+ local prev = self:_get_def(self.active)
+ self.ww.set_resolution(0, 0)
+ if prev.on_exit then
+ prev.on_exit()
+ end
+ self.active = nil
+ end
+ end
+
+ local function enter_mode(_name)
+ if _name then
+ local new = self:_get_def(_name)
+ self.ww.set_resolution(new.width, new.height)
+ if new.on_enter then
+ new.on_enter()
+ end
+ self.active = _name
+ end
+ end
+
+ if name == nil then
+ exit_active()
+ return
+ end
+ if name == self.active then
+ -- already active, do nothing
+ return
+ end
+ exit_active()
+ enter_mode(name)
+end
+
+--- Toggle a mode by name. If it's active, turn it off. If it's inactive, turn it on.
+--- If the mode has a toggle_guard and it returns false, do nothing and return false.
+--- @param name string
+--- @return boolean|nil
+function ModeManager:toggle(name)
+ local ww, def = self.ww, self.defs[name]
+ if not def then
+ return
+ end
+ if def.toggle_guard and def.toggle_guard() == false then
+ return false
+ end
+ -- local w, h = active_res(ww)
+ -- if w == def.width and h == def.height then
+ -- ww.set_resolution(0, 0)
+ -- if def.on_exit then
+ -- def.on_exit()
+ -- end
+ -- self.active = nil
+ -- else
+ -- ww.set_resolution(def.width, def.height)
+ -- if def.on_enter then
+ -- def.on_enter()
+ -- end
+ -- -- exit previous if different
+ -- self.active = name
+ -- end
+
+ if name == self.active then
+ self:_transition_to(nil)
+ else
+ self:_transition_to(name)
+ end
+end
+
+modes.ModeManager = ModeManager
+return modes
diff --git a/.config/waywall/waywork/processes.lua b/.config/waywall/waywork/processes.lua
new file mode 100644
index 0000000..4ba61e8
--- /dev/null
+++ b/.config/waywall/waywork/processes.lua
@@ -0,0 +1,110 @@
+local P = {}
+
+-- Shell-safe quoting: wraps in single quotes, escapes inner quotes
+local function shell_quote(str)
+ return "'" .. tostring(str):gsub("'", "'\"'\"'") .. "'"
+end
+
+-- Build a safe shell command from argv
+local function build_cmd(argv)
+ local quoted = {}
+ for i, arg in ipairs(argv) do
+ quoted[i] = shell_quote(arg)
+ end
+ return table.concat(quoted, " ")
+end
+
+--- Check if a process matching the given pattern is running.
+--- Uses `pgrep -f -- <pattern>`
+--- @param pattern string
+function P.is_running(pattern)
+ local cmd = build_cmd({ "pgrep", "-f", "--", pattern })
+ local h = io.popen(cmd)
+ if not h then
+ return false
+ end
+ local r = h:read("*l")
+ h:close()
+ return r ~= nil
+end
+
+--- @class waywall
+--- @field exec fun(cmd: string): nil
+
+--- wrapper around waywall.exec
+--- @param ww waywall
+--- @param argv table array-like table of args
+--- @return nil
+function P.ww_exec_argv(ww, argv)
+ -- No quoting needed; execvp-style expects raw argv
+ assert(type(argv) == "table", "argv must be an array-like table of strings")
+ for i, v in ipairs(argv) do
+ assert(type(v) == "string", "argv element must be a string")
+ end
+ local cmd = table.concat(argv, " ")
+ return ww.exec(cmd)
+end
+
+--- Return a function that starts an application when called.
+--- @param ww waywall waywall dependency
+--- @param app_path string path to the application executable
+--- @param args? string[] optional additional arguments to pass to the application
+--- @return fun(): nil
+function P.start_application(ww, app_path, args)
+ return function()
+ local argv = { app_path }
+ if args then
+ for _, a in ipairs(args) do
+ argv[#argv + 1] = a
+ end
+ end
+ P.ww_exec_argv(ww, argv)(ww, argv)
+ end
+end
+
+--- Ensure an application is running, start it if not.
+--- @param ww waywall waywall dependency
+--- @param app_path string path to the application executable
+--- @param args? string[] optional additional arguments to pass to the application
+--- @return fun(pattern: string): fun(): nil
+function P.ensure_application(ww, app_path, args)
+ return function(pattern)
+ return function()
+ if not P.is_running(pattern) then
+ local argv = { app_path }
+ if args then
+ for _, a in ipairs(args) do
+ argv[#argv + 1] = a
+ end
+ end
+ P.ww_exec_argv(ww, argv)
+ end
+ end
+ end
+end
+
+--- Ensure a Java JAR is running, start it if not.
+--- @param ww waywall
+--- @param java_path string path to java executable
+--- @param jar_path string path to the JAR file
+--- @param args? string[] optional additional arguments to pass to java
+--- @return fun(pattern: string): fun(): nil
+function P.ensure_java_jar(ww, java_path, jar_path, args)
+ return function(pattern)
+ return function()
+ if not P.is_running(pattern) then
+ local argv = { java_path }
+ if args then
+ for _, a in ipairs(args) do
+ argv[#argv + 1] = a
+ end
+ end
+ argv[#argv + 1] = "-jar"
+ argv[#argv + 1] = jar_path
+ P.ww_exec_argv(ww, argv)
+ end
+ end
+ end
+end
+
+return P
diff --git a/.config/waywall/waywork/scene.lua b/.config/waywall/waywork/scene.lua
new file mode 100644
index 0000000..bbb670a
--- /dev/null
+++ b/.config/waywall/waywork/scene.lua
@@ -0,0 +1,115 @@
+local core = require("waywork.core")
+
+--- SceneManager manages images, mirrors, and text objects uniformly.
+local SceneManager = {}
+SceneManager.__index = SceneManager
+
+function SceneManager.new(waywall)
+ return setmetatable({ ww = waywall, defs = {}, instances = {}, groups = {} }, SceneManager)
+end
+
+--- A scene object definition.
+--- @class SceneDef
+--- @field kind "mirror" | "image" | "text"
+--- @field options table
+--- @field path? string (for images)
+--- @field text? string (for text)
+--- @field groups string[]
+--- @field enabled_by_default? boolean
+
+--- Register a scene object by name.
+--- @param name string
+--- @param def SceneDef
+function SceneManager:register(name, def)
+ self.defs[name] = core.copy(def)
+ if def.groups then
+ for _, g in ipairs(def.groups) do
+ self.groups[g] = self.groups[g] or {}
+ table.insert(self.groups[g], name)
+ end
+ end
+ if def.enabled_by_default then
+ self:enable(name, true)
+ end
+end
+
+function SceneManager:_create(def)
+ if def.kind == "mirror" then
+ return self.ww.mirror(def.options)
+ elseif def.kind == "image" then
+ return self.ww.image(def.path, def.options)
+ elseif def.kind == "text" then
+ return self.ww.text(def.text, def.options)
+ end
+end
+
+function SceneManager:_ensure(name, enable)
+ local inst = self.instances[name]
+ if enable and not inst then
+ inst = self:_create(self.defs[name])
+ self.instances[name] = inst
+ elseif not enable and inst then
+ inst:close()
+ self.instances[name] = nil
+ end
+end
+
+--- Enable or disable a registered scene object by name.
+--- @param name string
+--- @param on boolean
+function SceneManager:enable(name, on)
+ if not self.defs[name] then
+ return
+ end
+ self:_ensure(name, on)
+end
+
+--- Disable a registered scene object by name.
+--- @param name string
+function SceneManager:disable(name)
+ self:enable(name, false)
+end
+
+--- Enable or disable all scene objects in a group.
+--- @param group string
+--- @param on boolean
+function SceneManager:enable_group(group, on)
+ for _, name in ipairs(self.groups[group] or {}) do
+ self:enable(name, on)
+ end
+end
+
+--- Apply a predicate function to all registered scene objects.
+---
+--- Example:
+--- ```lua
+--- scene:apply(function(name, def)
+--- return def.kind == "mirror" -- enable all mirrors
+--- end)
+--- ```
+--- @param predicate fun(name: string, def: table): boolean
+function SceneManager:apply(predicate)
+ for name, def in pairs(self.defs) do
+ self:enable(name, predicate(name, def))
+ end
+end
+
+--- Update the destination rectangle of a registered scene object.
+--- @param name string
+--- @param new_dst table { x=number, y=number, w=number, h=number }
+SceneManager.update_dst = function(self, name, new_dst)
+ local def = self.defs[name]
+ if not def then
+ return
+ end
+ if def.options then
+ def.options.dst = core.copy(new_dst)
+ end
+ local inst = self.instances[name]
+ if inst then
+ inst:close()
+ self.instances[name] = self:_create(def)
+ end
+end
+
+return { SceneManager = SceneManager }
diff --git a/.config/xdg-desktop-portal-wlr/config b/.config/xdg-desktop-portal-wlr/config
new file mode 100644
index 0000000..9a287cf
--- /dev/null
+++ b/.config/xdg-desktop-portal-wlr/config
@@ -0,0 +1,5 @@
+[screencast]
+max_fps=60
+chooser_type=simple
+chooser_cmd=swaymsg -t get_outputs | jq -r '.[] \| .name' | wmenu -p output:
+#slurp -f %o -or