diff --git a/.config/kanshi/config b/.config/kanshi/config
new file mode 100644
index 0000000..baf9a3a
--- /dev/null
+++ b/.config/kanshi/config
@@ -0,0 +1,27 @@
+# Triple monitor setup (2 external + laptop)
+profile docked {
+ output "ASUSTek COMPUTER INC VY249HGR SALMRS003158" mode 1920x1080@60Hz position 2880,0
+ output "ASUSTek COMPUTER INC VY249HGR SALMRS003212" mode 1920x1080@60Hz position 4800,0
+ output "Samsung Display Corp. 0x419F" mode 2880x1800@120Hz position 3979,1080 scale 1.648438
+}
+
+# Laptop only
+profile laptop {
+ output "Samsung Display Corp. 0x419F" mode 2880x1800@120Hz position 0,0 scale 1.648438
+}
+
+# Left external only
+profile left-external {
+ output "ASUSTek COMPUTER INC VY249HGR SALMRS003158" mode 1920x1080@60Hz position 0,0
+}
+
+# Right external only
+profile right-external {
+ output "ASUSTek COMPUTER INC VY249HGR SALMRS003212" mode 1920x1080@60Hz position 0,0
+}
+
+# Both externals, no laptop
+profile dual-external {
+ output "ASUSTek COMPUTER INC VY249HGR SALMRS003158" mode 1920x1080@60Hz position 0,0
+ output "ASUSTek COMPUTER INC VY249HGR SALMRS003212" mode 1920x1080@60Hz position 1920,0
+}
diff --git a/.config/keyd/default.conf b/.config/keyd/default.conf
new file mode 100644
index 0000000..17468e7
--- /dev/null
+++ b/.config/keyd/default.conf
@@ -0,0 +1,7 @@
+[ids]
+*
+
+[main]
+# Swap capslock and escape by default
+capslock = esc
+esc = capslock
diff --git a/.config/keyd/normal.conf b/.config/keyd/normal.conf
new file mode 100644
index 0000000..fa20da6
--- /dev/null
+++ b/.config/keyd/normal.conf
@@ -0,0 +1,5 @@
+[ids]
+*
+
+[main]
+# Nothing remapped
diff --git a/.config/keyd/swapped.conf b/.config/keyd/swapped.conf
new file mode 100644
index 0000000..5a2b213
--- /dev/null
+++ b/.config/keyd/swapped.conf
@@ -0,0 +1,6 @@
+[ids]
+*
+
+[main]
+capslock = esc
+esc = capslock
diff --git a/.config/nvim/lua/core/autocmd.lua b/.config/nvim/lua/core/autocmd.lua
index 6e36ece..05d51bf 100644
--- a/.config/nvim/lua/core/autocmd.lua
+++ b/.config/nvim/lua/core/autocmd.lua
@@ -1,5 +1,16 @@
vim.api.nvim_set_hl(0, "YankColor", { fg = "#C8C093", bg = "#000000", ctermfg = 59, ctermbg = 41 })
+-- Use double backslashes
+vim.api.nvim_set_hl(0, 'InvisibleChar', { bg = '#ff0000', fg = '#ffffff' })
+
+vim.api.nvim_create_autocmd({'BufEnter', 'BufWritePost', 'TextChanged', 'InsertLeave'}, {
+ group = vim.api.nvim_create_augroup('InvisibleChars', { clear = true }),
+ callback = function()
+ vim.fn.clearmatches()
+ vim.fn.matchadd('InvisibleChar', '\\%u2028\\|\\%u200b\\|\\%u200c\\|\\%u200d\\|\\%u2029\\|\\%ufeff')
+ end
+})
+
local aucmd_dict = {
VimEnter = {
{
diff --git a/.config/nvim/lua/lsp/servers/tsserver.lua b/.config/nvim/lua/lsp/servers/tsserver.lua
index f36452f..16d4ad7 100644
--- a/.config/nvim/lua/lsp/servers/tsserver.lua
+++ b/.config/nvim/lua/lsp/servers/tsserver.lua
@@ -42,24 +42,12 @@ local function get_tsserver_cmd(root_dir)
return { tsserver, '--stdio' }
end
- -- Check for local typescript-language-server in node_modules
- tsserver = root_dir .. '/node_modules/.bin/tsserver'
- if vim.loop.fs_stat(tsserver) then
- return { tsserver, '--stdio' }
- end
-
-- Check frontend/node_modules
tsserver = root_dir .. '/frontend/node_modules/.bin/typescript-language-server'
if vim.loop.fs_stat(tsserver) then
return { tsserver, '--stdio' }
end
- -- Check frontend/node_modules
- tsserver = root_dir .. '/frontend/node_modules/.bin/tsserver'
- if vim.loop.fs_stat(tsserver) then
- return { tsserver, '--stdio' }
- end
-
-- Fallback to Mason
return { vim.fn.expand('~/.local/share/nvim/mason/bin/typescript-language-server'), '--stdio' }
end
diff --git a/.config/nvim/lua/plugins/diffview.lua b/.config/nvim/lua/plugins/diffview.lua
new file mode 100644
index 0000000..0aa847e
--- /dev/null
+++ b/.config/nvim/lua/plugins/diffview.lua
@@ -0,0 +1,4 @@
+return {
+ "sindrets/diffview.nvim",
+ opts = {},
+}
diff --git a/.config/river/init b/.config/river/init
new file mode 100755
index 0000000..8944483
--- /dev/null
+++ b/.config/river/init
@@ -0,0 +1,158 @@
+#!/bin/sh
+
+riverctl map normal Super+Shift Return spawn alacritty
+riverctl map normal Super P spawn "wofi --show drun"
+
+riverctl map normal Super T spawn ~/.config/river/scripts/toggle-caps-esc.sh
+
+# 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
+
+# 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)))
+
+ # Super+[1-9] to focus tag [0-8]
+ riverctl map normal Super $i set-focused-tags $tags
+
+ # Super+Shift+[1-9] to tag focused view with tag [0-8]
+ riverctl map normal Super+Shift $i set-view-tags $tags
+
+ # Super+Control+[1-9] to toggle focus of tag [0-8]
+ riverctl map normal Super+Control $i toggle-focused-tags $tags
+
+ # Super+Shift+Control+[1-9] to toggle tag [0-8] of focused view
+ riverctl map normal Super+Shift+Control $i toggle-view-tags $tags
+done
+
+# Super+0 to focus all tags
+# Super+Shift+0 to tag focused view with all tags
+all_tags=$(((1 << 32) - 1))
+riverctl map normal Super 0 set-focused-tags $all_tags
+riverctl map normal Super+Shift 0 set-view-tags $all_tags
+
+# Super+Space to toggle float
+riverctl map normal Super Space toggle-float
+
+# Super+F to toggle fullscreen
+riverctl map normal Super F toggle-fullscreen
+
+# Super+{Up,Right,Down,Left} to change layout orientation
+riverctl map normal Super Up send-layout-cmd rivertile "main-location top"
+riverctl map normal Super Right send-layout-cmd rivertile "main-location right"
+riverctl map normal Super Down send-layout-cmd rivertile "main-location bottom"
+riverctl map normal Super Left send-layout-cmd rivertile "main-location left"
+
+# Declare a passthrough mode. This mode has only a single mapping to return to
+# normal mode. This makes it useful for testing a nested wayland compositor
+riverctl declare-mode passthrough
+
+# Super+F11 to enter passthrough mode
+riverctl map normal Super F11 enter-mode passthrough
+
+# Super+F11 to return to normal mode
+riverctl map passthrough Super F11 enter-mode normal
+
+# Various media key mapping examples for both normal and locked mode which do
+# not have a modifier
+for mode in normal locked
+do
+ # Eject the optical drive (well if you still have one that is)
+ riverctl map $mode None XF86Eject spawn 'eject -T'
+
+ # Control pulse audio volume with pamixer (https://github.com/cdemoulins/pamixer)
+ riverctl map $mode None XF86AudioRaiseVolume spawn 'pamixer -i 5'
+ riverctl map $mode None XF86AudioLowerVolume spawn 'pamixer -d 5'
+ riverctl map $mode None XF86AudioMute spawn 'pamixer --toggle-mute'
+
+ # Control MPRIS aware media players with playerctl (https://github.com/altdesktop/playerctl)
+ riverctl map $mode None XF86AudioMedia spawn 'playerctl play-pause'
+ riverctl map $mode None XF86AudioPlay spawn 'playerctl play-pause'
+ riverctl map $mode None XF86AudioPrev spawn 'playerctl previous'
+ riverctl map $mode None XF86AudioNext spawn 'playerctl next'
+
+ # Control screen backlight brightness with brightnessctl (https://github.com/Hummer12007/brightnessctl)
+ riverctl map $mode None XF86MonBrightnessUp spawn 'brightnessctl set +5%'
+ riverctl map $mode None XF86MonBrightnessDown spawn 'brightnessctl set 5%-'
+done
+
+# Set background and border color
+riverctl background-color 0x000000
+riverctl border-color-focused 0x5ea1ff
+riverctl border-color-unfocused 0x3c4048
+
+# Set keyboard repeat rate
+riverctl set-repeat 50 300
+
+# Make all views with an app-id that starts with "float" and title "foo" start floating.
+riverctl rule-add -app-id 'float*' -title 'foo' float
+
+# Make all views with app-id "bar" and any title use client-side decorations
+riverctl rule-add -app-id "bar" 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
+rivertile -view-padding 6 -outer-padding 6 &
+
+waybar &
+
+kanshi &
diff --git a/.config/river/scripts/toggle-caps-esc.sh b/.config/river/scripts/toggle-caps-esc.sh
new file mode 100755
index 0000000..1c78e57
--- /dev/null
+++ b/.config/river/scripts/toggle-caps-esc.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+# Check if keyd is using the swapped config
+if pgrep -f "keyd.*default.conf" > /dev/null && keyd list | grep -q "capslock = esc"; then
+ # Currently swapped, switch to normal config
+ sudo cp ~/.config/keyd/normal.conf ~/.config/keyd/default.conf
+ sudo keyd reload
+ notify-send "Keyboard Layout" "Caps Lock and Escape returned to normal" -i input-keyboard
+else
+ # Not swapped, switch to swapped config
+ sudo cp ~/.config/keyd/swapped.conf ~/.config/keyd/default.conf
+ sudo keyd reload
+ notify-send "Keyboard Layout" "Caps Lock and Escape swapped" -i input-keyboard
+fi
diff --git a/.config/waybar/config.jsonc b/.config/waybar/config.jsonc
index 3601351..e220ede 100644
--- a/.config/waybar/config.jsonc
+++ b/.config/waybar/config.jsonc
@@ -1,144 +1,13 @@
-// -*- mode: jsonc -*-
{
"layer": "top",
- "mode": "dock",
- "position": "top", // (top|bottom|left|right)
- "height": 40, // (to be removed for auto height)
- "width": "auto",
- "spacing": 3, // Gaps between modules
- "margin": 0,
- "fixed-center": true,
- "reload_style_on_change": true,
- "modules-left": [
- "hyprland/workspaces",
- "hyprland/submap",
- ],
- "modules-center": [
- "clock"
- ],
- "modules-right": [
- "pulseaudio",
- "temperature",
- "network",
- "backlight",
- "battery",
- "tray"
- ],
- "keyboard-state": {
- "numlock": true,
- "capslock": true,
- "format": "{icon} {name}",
- "format-icons": {
- "locked": "",
- "unlocked": ""
- }
- },
- "tray": {
- "icon-size": 24,
- "show-passive-items": true,
- "spacing": 10
+ "modules-left": ["river/tags"],
+ "modules-center": ["clock"],
+ "modules-right": ["battery", "network", "pulseaudio"],
+
+ "river/tags": {
+ "num-tags": 9
},
"clock": {
- "interval": 1,
- "format": "{:%A %d. %b %T}",
- "tooltip-format": "{calendar}",
- "calendar": {
- "format": {
- "today": "{}"
- }
- }
- },
- "temperature": {
- "interval": 1000,
- "critical-threshold": 80,
- "format": "{temperatureC}°C"
- },
- "backlight": {
- "format": "{icon}",
- "tooltip-format": "{icon} {percent}",
- "format-icons": [
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- ""
- ]
- },
- "battery": {
- "states": {
- // "good": 95,
- "warning": 30,
- "critical": 15
- },
- "format": "{icon}",
- "format-full": "{icon}",
- "format-charging": "{icon} ",
- "format-plugged": "{icon} ",
- "format-alt": "{icon}",
- "format-icons": [
- "",
- "",
- "",
- "",
- ""
- ]
- },
- "power-profiles-daemon": {
- "format": "{icon}",
- "tooltip-format": "Power profile: {profile}\nDriver: {driver}",
- "tooltip": true,
- "format-icons": {
- "default": "",
- "performance": "",
- "balanced": "",
- "power-saver": ""
- }
- },
- "network": {
- "interval": 1000,
- "format-wifi": "{icon}",
- "format-ethernet": "{ipaddr}/{cidr} ",
- "tooltip-format": "{essid}\n{ifname} via {gwaddr}\n{ipaddr}/{cidr}",
- "format-linked": "{ifname} (No IP) ",
- "format-disconnected": "",
- "format-alt": "{essid}",
- "format-icons": [
- "",
- "",
- "",
- "",
- ""
- ]
- },
- "pulseaudio": {
- "format": "{icon} {format_source}",
- "format-muted": " {format_source}",
- "format-source": "",
- "format-source-muted": " ",
- "format-bluetooth": "{icon} {format_source}",
- "format-bluetooth-muted": "{icon} {format_source}",
- "format-icons": {
- "headphone": "",
- "hands-free": "",
- "headset": "",
- "phone": " ",
- "portable": " ",
- "car": "",
- "default": [
- "",
- "",
- ""
- ]
- },
- "tooltip-format": "{icon} {volume}%\n{format_source}",
- "ignored-sinks": [
- "Easy Effects Sink"
- ]
+ "format": "{:%a %d %b %H:%M}"
}
}
diff --git a/.config/waybar/style.css b/.config/waybar/style.css
index 4ccf423..5766f8e 100644
--- a/.config/waybar/style.css
+++ b/.config/waybar/style.css
@@ -1,130 +1,54 @@
* {
- border: none;
- border-radius: 0;
- font-family: JetBrainsMono NerdFont, Roboto, Helvetica, Arial, sans-serif;
- font-size: 14px;
- min-height: 0;
+ font-family: "JetBrainsMono NerdFont";
+ font-size: 13px;
+ border: none;
+ border-radius: 0;
}
window#waybar {
- background: rgba(0, 0, 0, 0.6);
- color: white;
+ background: #000000;
+ color: #ffffff;
}
-button {
- margin: 3px;
- padding: 3px;
+#tags button {
+ padding: 0 5px;
+ color: #ffffff;
+ background: transparent;
+ border-bottom: 2px solid transparent;
}
-tooltip {
- background: rgba(0, 0, 0, 0.202);/*rgba(43, 48, 59, 0.5);*/
- border: 4px solid white;
- border-radius: 10px;
+#tags button.occupied {
+ color: #8c9098;
+ border-bottom: 2px solid #8c9098;
}
-tooltip label {
- color: white;
+#tags button.focused {
+ color: #000000;
+ background: #5ea1ff;
}
-#workspaces button {
- margin: 0;
- padding: 0;
-
- background: transparent;
- color: #888888;
-}
-
-#workspaces button.active {
- color: white;
-}
-
-#mode,
-#clock,
-#battery,
-#pulseaudio,
-#temperature,
-#language,
-#backlight,
-#network,
-#tray,
-#custom-weather {
- padding: 0 10px;
-}
-
-#scratchpad,
-#window {
- margin-left: 6px;
- margin-right: 6px;
-}
-
-#custom-weather.sunny {
- color: rgb(215, 215, 0);
-}
-
-#custom-weather.lightrain {
- color: lightblue;
-}
-
-#custom-weather.rain,
-#custom-weather.heavyrain {
- color: blue;
-}
-
-#custom-weather.cloudy,
-#custom-weather.fog {
- color: gray;
-}
-
-#window {
- color: darkred;
-}
-
-#language {
- color: cadetblue;
-}
-
-#pulseaudio {
- color: darkcyan;
-}
-
-#network {
- color: coral;
-}
-
-#temperature {
- color: rgb(91, 191, 225);
-}
-
-#backlight {
- color: rgb(255, 255, 61);
+#tags button:hover {
+ background: #1a1a1a;
}
#clock {
- color: aqua;
+ padding: 0 10px;
+ color: #ffffff;
}
-#battery {
- color: rgb(147, 63, 225);
+#battery, #network, #pulseaudio {
+ padding: 0 10px;
+ color: #ffffff;
}
#battery.charging {
- color: #26A65B;
+ color: #5ea1ff;
}
-@keyframes blink {
- to {
- color: white;
- }
+#battery.warning {
+ color: #ffaa00;
}
-#battery.warning:not(.charging),
-#temperature.critical,
-#workspaces button.urgent,
-#mode {
- color: #ff0000;
- animation-name: blink;
- animation-duration: 0.5s;
- animation-timing-function: steps(2);
- animation-iteration-count: infinite;
- animation-direction: alternate;
+#battery.critical {
+ color: #ff5555;
}