Compare commits

...

12 Commits

13 changed files with 387 additions and 124 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.codex

View File

@@ -1,21 +1,22 @@
[font]
size = 12
size = 13
[font.offset]
y = 0
x = 0
[font.normal]
family = "JetBrainsMono Nerd Font"
family = "ComicShannsMono Nerd Font"
style = "Regular"
[font.bold]
family = "JetBrainsMono Nerd Font"
style = "Bold"
[font.italic]
family = "JetBrainsMono Nerd Font"
style = "Italic"
[font.bold_italic]
family = "JetBrainsMono Nerd Font"
style = "Bold Italic"
[window]

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
stow -t ~ bash zsh tmux nvim hypr waybar alacritty rider-palette walker
stow -t ~ bash zsh tmux nvim hypr waybar mako alacritty rider-palette walker

View File

@@ -4,7 +4,7 @@ set -euo pipefail
# ====== CONFIG ======
DOTFILES_DIR="${DOTFILES_DIR:-$HOME/repos/dotfiles}"
DOTFILES_GIT_URL="${DOTFILES_GIT_URL:-}" # ex: git@github.com:TON_USER/dotfiles.git
STOW_PACKAGES_DEFAULT=("zsh" "tmux" "nvim" "hypr" "hypridle" "waybar" "alacritty")
STOW_PACKAGES_DEFAULT=("zsh" "tmux" "nvim" "hypr" "waybar" "mako" "alacritty")
INSTALL_FONTS="${INSTALL_FONTS:-1}" # 1 = install nerd font, 0 = skip
SET_DEFAULT_SHELL="${SET_DEFAULT_SHELL:-1}" # 1 = chsh to zsh, 0 = skip
@@ -61,7 +61,7 @@ sudo_run apt install -y build-essential || true
# Hypr ecosystem (availability depends on distro/repo)
# We try, but do not fail if packages aren't found.
log "Trying to install Hyprland ecosystem packages (best effort)"
sudo_run apt install -y hyprland hypridle waybar alacritty 2>/dev/null || true
sudo_run apt install -y hyprland hyprpaper hypridle waybar mako-notifier alacritty 2>/dev/null || true
# ====== DOTFILES CLONE (OPTIONAL) ======
if [ ! -d "$DOTFILES_DIR/.git" ]; then

View File

@@ -25,7 +25,7 @@
# See https://wiki.hyprland.org/Configuring/Monitors/
monitor=DP-1,3440x1440@165, 0x0,1
monitor=DP-3,1920x1080@60, 3440x1200,1
###################
### MY PROGRAMS ###
###################
@@ -73,8 +73,8 @@ env = QT_QPA_PLATFORMTHEME,qt5ct
# https://wiki.hyprland.org/Configuring/Variables/#general
general {
gaps_in = 3
gaps_out = 6
gaps_in = 4
gaps_out = 8
border_size = 1
# https://wiki.hyprland.org/Configuring/Variables/#variable-types for info about colors
@@ -88,11 +88,18 @@ general {
allow_tearing = false
layout = dwindle
# layout = master
}
master {
new_status = inherit
mfact = 0.33
orientation = center
}
# https://wiki.hyprland.org/Configuring/Variables/#decoration
decoration {
rounding = 2
rounding = 0
inactive_opacity = 1.00
active_opacity = 1.00
fullscreen_opacity = 1.00
@@ -131,8 +138,8 @@ animations {
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
dwindle {
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = true # You probably want this
pseudotile = false # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = false # You probably want this
}
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
@@ -182,7 +189,7 @@ $mainMod = SUPER # Sets "Windows" key as main modifier
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
bind = $mainMod, Z, exec, $terminal
bind = $mainMod, C, killactive,
bind = $mainMod, M, exit,
# bind = $mainMod, M, exit,
bind = $mainMod, E, exec, $fileManager bind = $mainMod, N, exec, $navigator
bind = $mainMod, V, togglefloating
bind = $mainMod, F, fullscreen
@@ -192,16 +199,30 @@ bind = $mainMod, S, togglesplit, # dwindle
bind = $mainMod, Q, exec, hyprlock
bind = $mainMod, Y, exec, ~/scripts/screenshot-to-clipboard.sh
# Switch to layouts
bind = $mainMod, M, exec, ~/scripts/toggle_layout.sh
bind = $mainMod, Return, layoutmsg, swapwithmaster
bind = $mainMod, B, layoutmsg, mfact +0.05
bind = $mainMod, N, layoutmsg, mfact -0.05
# Move focus with mainMod + arrow keys
bind = $mainMod, H, movefocus, l
bind = $mainMod, J, movefocus, d
bind = $mainMod, K, movefocus, u
bind = $mainMod, L, movefocus, r
bind = $mainMod, left, movefocus, l
bind = $mainMod, down, movefocus, d
bind = $mainMod, up, movefocus, u
bind = $mainMod, right, movefocus, r
bind = $mainMod SHIFT, H, swapwindow, l
bind = $mainMod SHIFT, J, swapwindow, d
bind = $mainMod SHIFT, K, swapwindow, u
bind = $mainMod SHIFT, L, swapwindow, r
bind = $mainMod SHIFT, left, swapwindow, l
bind = $mainMod SHIFT, down, swapwindow, d
bind = $mainMod SHIFT, up, swapwindow, u
bind = $mainMod SHIFT, right, swapwindow, r
# Switch workspaces with mainMod + [0-9]
bind = $mainMod, 1, workspace, 1

30
mako/.config/mako/config Normal file
View File

@@ -0,0 +1,30 @@
font=JetBrainsMono Nerd Font 12
background-color=#191A1C
text-color=#BDBDBD
border-color=#39CC9B
progress-color=over #39CC9B
width=420
height=160
outer-margin=16
margin=12
padding=14
border-size=1
border-radius=7
icons=1
max-icon-size=48
markup=1
actions=1
max-visible=5
max-history=50
default-timeout=8000
ignore-timeout=0
anchor=bottom-right
layer=overlay
sort=-time
[urgency=high]
border-color=#FF5647
default-timeout=0
[mode=do-not-disturb]
invisible=1

View File

@@ -723,6 +723,10 @@ require('lazy').setup({
-- ts_ls = {},
--
marksman = {},
dockerls = {},
docker_compose_language_service = {},
lua_ls = {
-- cmd = { ... },
-- filetypes = { ... },
@@ -754,6 +758,8 @@ require('lazy').setup({
-- for you, so that they are available from within Neovim.
local ensure_installed = vim.tbl_keys(servers or {})
vim.list_extend(ensure_installed, {
'hadolint', -- Used to lint Dockerfiles
'markdownlint', -- Used to lint Markdown files
'stylua', -- Used to format Lua code
})
require('mason-tool-installer').setup { ensure_installed = ensure_installed }

View File

@@ -13,12 +13,21 @@ set -g pane-base-index 1
set -g renumber-windows on
set -g status-position top
unbind =
bind = select-layout -E
# using vim motions
bind-key h select-pane -L
bind-key j select-pane -D
bind-key k select-pane -U
bind-key l select-pane -R
# resize panes
bind -r H resize-pane -L
bind -r J resize-pane -D
bind -r K resize-pane -U
bind -r L resize-pane -R
# Split panes in the same directory
bind '"' split-window -v -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"

View File

@@ -1,6 +1,6 @@
{
"layer": "top",
"position": "top",
"layer": "bottom",
"position": "bottom",
"mod": "dock",
"margin-left": 0,
"margin-right": 0,
@@ -11,30 +11,21 @@
"gtk-layer-shell": true,
"reload_style_on_change": true,
"modules-left": [
"hyprland/workspaces",
"hyprland/window"
"hyprland/workspaces"
],
"modules-center": [
"clock"
],
"modules-right": [
"tray",
"custom/print-queue",
"network",
"bluetooth",
"pulseaudio",
"cpu",
"memory",
"battery",
"tray",
"custom/mako",
"custom/power"
],
"memory": {
"interval": 5,
"format": "󰍛 {}%"
},
"cpu": {
"interval": 5,
"format": "󰻠 {usage}%"
},
"battery": {
"states": {
"warning": 30,
@@ -57,8 +48,8 @@
"tooltip": true
},
"tray": {
"icon-size": 16,
"spacing": 6,
"icon-size": 22,
"spacing": 14,
"rotate": 0
},
"custom/power": {
@@ -75,25 +66,27 @@
"lock": "hyprlock"
}
},
"custom/print-queue": {
"exec": "$HOME/.config/waybar/scripts/print-queue.sh",
"return-type": "json",
"interval": 10,
"format": "{}",
"tooltip": true,
"on-click": "$HOME/.config/waybar/scripts/print-queue-view.sh"
},
"custom/mako": {
"exec": "$HOME/.config/waybar/scripts/mako-notifications.sh status",
"return-type": "json",
"interval": 5,
"signal": 8,
"format": "{}",
"tooltip": true,
"on-click": "$HOME/.config/waybar/scripts/mako-notifications.sh toggle",
"on-click-right": "$HOME/.config/waybar/scripts/mako-notifications.sh list"
},
"hyprland/workspaces": {
"all-outputs": false,
"sort-by-number": true,
"format": "{icon}",
"format-icons": {
"1": "󰎤",
"2": "󰎧",
"3": "󰎪",
"4": "󰎭",
"5": "󰎱",
"6": "󰎳",
"7": "󰎶",
"8": "󰎹",
"9": "󰎼",
"10": "󰽽",
"urgent": "",
"default": "",
"empty": ""
}
"sort-by-number": true
},
"hyprland/window": {
"separate-outputs": true,

View File

@@ -0,0 +1,135 @@
#!/usr/bin/env sh
set -eu
dnd_mode="do-not-disturb"
json_string() {
if command -v jq >/dev/null 2>&1; then
printf '%s' "$1" | jq -Rs .
return
fi
printf '%s' "$1" | awk '
BEGIN { ORS = "" }
{
gsub(/\\/, "\\\\")
gsub(/"/, "\\\"")
gsub(/\t/, "\\t")
if (NR > 1) {
printf "\\n"
}
printf "%s", $0
}
END { printf "\n" }
'
}
refresh_waybar() {
pkill -RTMIN+8 waybar >/dev/null 2>&1 || true
}
notification_count() {
if ! command -v jq >/dev/null 2>&1; then
printf '0'
return
fi
makoctl list -j 2>/dev/null \
| jq '[.. | objects | select(has("id"))] | length' 2>/dev/null \
|| printf '0'
}
is_dnd() {
makoctl mode 2>/dev/null | grep -qx "$dnd_mode"
}
status() {
if ! modes="$(makoctl mode 2>/dev/null)"; then
text="$(json_string " n/a")"
class="$(json_string "disabled")"
tooltip="$(json_string "Mako is unavailable")"
printf '{"text":%s,"class":%s,"tooltip":%s}\n' "$text" "$class" "$tooltip"
return
fi
count="$(notification_count)"
count="${count:-0}"
if printf '%s\n' "$modes" | grep -qx "$dnd_mode"; then
state="dnd"
icon=""
label="Do Not Disturb is on"
elif [ "$count" -gt 0 ] 2>/dev/null; then
state="active"
icon=""
label="Do Not Disturb is off"
else
state="normal"
icon=""
label="Do Not Disturb is off"
fi
text="$(json_string "$icon $count")"
class="$(json_string "$state")"
tooltip="$(json_string "$label
$count pending notifications
Left click toggles DND
Right click opens the notification list")"
printf '{"text":%s,"class":%s,"tooltip":%s}\n' "$text" "$class" "$tooltip"
}
toggle() {
makoctl mode -t "$dnd_mode" >/dev/null 2>&1 || true
refresh_waybar
}
list_notifications() {
title="Notifications"
if command -v jq >/dev/null 2>&1; then
list="$(
makoctl list -j 2>/dev/null \
| jq -r '
[.. | objects | select(has("id"))]
| if length == 0 then
"No pending notifications"
else
.[]
| [
(."app-name" // .app_name // "app"),
(.summary // ""),
(.body // "")
]
| map(select(. != ""))
| join(" - ")
end
' 2>/dev/null
)"
else
list="$(makoctl list 2>/dev/null || printf 'No pending notifications')"
fi
if [ -z "$list" ]; then
list="No pending notifications"
fi
if command -v wofi >/dev/null 2>&1; then
printf '%s\n' "$list" | wofi --dmenu --prompt "$title" >/dev/null 2>&1 || true
elif command -v alacritty >/dev/null 2>&1; then
tmp="${TMPDIR:-/tmp}/mako-notifications.$$"
printf '%s\n' "$list" > "$tmp"
alacritty -e sh -c 'printf "%s\n\n" "$1"; cat "$2"; printf "\nPress Enter to close."; read -r _' sh "$title" "$tmp"
rm -f "$tmp"
else
printf '%s\n' "$list"
fi
}
case "${1:-status}" in
status) status ;;
toggle) toggle ;;
list) list_notifications ;;
*) status ;;
esac

View File

@@ -0,0 +1,30 @@
#!/usr/bin/env sh
if command -v system-config-printer >/dev/null 2>&1; then
exec system-config-printer
fi
if command -v alacritty >/dev/null 2>&1; then
exec alacritty -e sh -lc '
while :; do
clear
printf "Print Queue\n"
printf "===========\n\n"
if ! lpstat -r >/dev/null 2>&1; then
printf "CUPS scheduler is not running.\n"
else
if ! lpstat -o 2>/dev/null | sed "/^[[:space:]]*$/d" | grep . >/dev/null 2>&1; then
printf "No print jobs queued.\n"
else
lpstat -o
fi
fi
printf "\nRefreshing every 3 seconds. Press Ctrl+C to close."
sleep 3
done
'
fi
exec xdg-open http://localhost:631/jobs/

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env sh
jobs_output="$(lpstat -o 2>/dev/null)"
status=$?
if [ "$status" -ne 0 ]; then
printf '%s\n' '{"text":"󰐪 n/a","class":"disabled","tooltip":"CUPS is unavailable"}'
exit 0
fi
if [ -z "$jobs_output" ]; then
printf '%s\n' '{"text":"","class":"idle","tooltip":"No print jobs queued"}'
exit 0
fi
job_count="$(printf '%s\n' "$jobs_output" | sed '/^[[:space:]]*$/d' | wc -l | tr -d ' ')"
if [ "$job_count" = "1" ]; then
tooltip="1 print job queued"
else
tooltip="$job_count print jobs queued"
fi
printf '{"text":"󰐪 %s","class":"active","tooltip":"%s"}\n' "$job_count" "$tooltip"

View File

@@ -15,25 +15,25 @@
* {
color: @foreground;
font-family: 'JetBrainsMono Nerd Font';
font-size: 15px;
font-weight: 300;
font-size: 17px;
}
window#waybar {
background: @background;
border-top: 1px solid alpha(@foreground, 0.28);
border-radius: 0px;
box-shadow: none;
color: @foreground;
}
window#waybar>box {
padding: 6px 3px;
padding: 4px 2px;
}
tooltip {
background: @background;
border: 1px solid @accent-alt;
border-radius: 12px;
border-radius: 14px;
}
.modules-left,
@@ -46,40 +46,69 @@ tooltip {
#workspaces,
#window,
#clock,
#custom-print-queue,
#network,
#bluetooth,
#pulseaudio,
#cpu,
#memory,
#battery,
#custom-mako,
#tray,
#custom-power {
background: alpha(@background, 0.56);
border: 1px solid alpha(@foreground, 0.14);
border-radius: 8px;
box-shadow: 0 8px 24px alpha(@background, 0.22);
margin: 0 3px;
padding: 0 10px;
min-height: 30px;
background: transparent;
border: none;
border-left: 1px solid alpha(@foreground, 0.18);
border-radius: 0;
box-shadow: none;
margin: 0;
padding: 0 12px;
}
#custom-launcher,
#workspaces,
#clock,
#custom-print-queue,
#tray {
border-left: none;
}
#bluetooth,
#pulseaudio {
border-left: none;
}
#custom-print-queue {
padding: 0 12px;
}
#network {
padding: 0 7px 0 12px;
}
#bluetooth {
padding: 0 7px;
}
#pulseaudio {
padding: 0 12px 0 7px;
}
#workspaces {
padding: 0 5px;
padding: 0 6px;
}
#workspaces button {
all: initial;
font-size: 18px;
min-width: 19px;
padding: 0 3px;
margin: 4px 2px;
border-radius: 6px;
color: @foreground-muted;
min-width: 29px;
padding: 0 5px;
margin: 2px 2px;
border-radius: 7px;
opacity: 0.9;
}
#workspaces button label {
font-size: 18px;
color: inherit;
margin: 0;
padding: 0;
}
#workspaces button.empty {
@@ -93,74 +122,58 @@ tooltip {
}
#workspaces button.active {
color: @background;
background: @accent;
opacity: 1;
color: @accent;
background: alpha(@accent, 0.16);
}
#workspaces button.active label {
color: @accent;
}
#workspaces button.urgent {
color: @foreground;
background: alpha(@danger, 0.26);
}
#workspaces button.urgent label {
color: @foreground;
}
#window {
color: @foreground-muted;
padding-right: 14px;
padding: 0 17px;
}
#clock {
color: @foreground;
padding: 0 15px;
padding: 0 18px;
box-shadow: none;
border: none;
}
#network {
color: @accent-soft;
}
#bluetooth {
color: @type;
}
#pulseaudio {
color: @accent;
}
#cpu,
#memory {
color: @warning;
}
#battery {
color: @accent-soft;
}
#battery.charging,
#battery.plugged {
color: @accent;
}
#battery.warning:not(.charging) {
color: @warning;
}
#battery.critical:not(.charging) {
color: @danger;
}
#tray {
padding: 0 12px;
padding: 0 14px;
}
#custom-power {
color: @danger;
padding: 0px 16px 0px 12px;
padding: 0px 19px 0px 14px;
}
#custom-mako {
min-width: 42px;
}
#custom-mako.active {
color: @accent;
}
#custom-launcher:hover,
#workspaces button:hover,
#network:hover,
#custom-print-queue:hover,
#bluetooth:hover,
#pulseaudio:hover,
#cpu:hover,
#memory:hover,
#battery:hover,
#custom-mako:hover,
#tray:hover,
#custom-power:hover,
#clock:hover {
@@ -170,7 +183,7 @@ tooltip {
#custom-launcher:hover,
#workspaces button.active:hover {
background: @accent;
background: alpha(@accent, 0.28);
}
.hidden {
@@ -180,14 +193,14 @@ tooltip {
menu#menu {
background: @background;
border: 1px solid alpha(@accent-alt, 0.24);
border-radius: 14px;
padding: 8px;
border-radius: 17px;
padding: 10px;
}
menu#menu menuitem {
border-radius: 10px;
margin: 10px;
padding: 8px 12px;
border-radius: 12px;
margin: 12px;
padding: 10px 14px;
}
menu#menu menuitem:hover {
@@ -196,9 +209,9 @@ menu#menu menuitem:hover {
menu#menu menuitem.section-header {
color: @foreground-muted;
font-size: 12px;
font-size: 17px;
margin-top: 4px;
padding: 4px 12px;
padding: 5px 14px;
}
menu#menu menuitem#lock {
@@ -225,5 +238,5 @@ menu#menu menuitem#shutdown {
menu#menu separator {
background: alpha(@accent-alt, 0.24);
margin: 6px 10px;
margin: 7px 12px;
}