Compare commits

...

65 Commits

Author SHA1 Message Date
39beb2cec4 feat(sway): update from vesktop to discord 2026-04-21 23:42:51 +02:00
36e0309bc9 feat(claude): add statusline 2026-04-17 09:46:17 +02:00
09609d6473 chore(claude): improve git work wording 2026-04-15 10:59:45 +02:00
4410db7880 feat(zsh): add --tags to gfa 2026-04-15 10:59:14 +02:00
cd5d707bda chore(sway): reposition fw16 screen setup 2026-04-15 10:58:37 +02:00
d5a9500be1 feat(sway): start ghostty with fastfetch 2026-04-15 00:21:53 +02:00
1efb93fc60 fix(sway): close satty after copy 2026-04-15 00:20:26 +02:00
1275a1ef4a feat(zsh): add ephvm global alias 2026-04-13 12:03:00 +02:00
1cfc8f1d37 chore(sway): bind rocketchat via app_id 2026-04-13 12:01:25 +02:00
6a4f00a9df feat(direnv): move direnv setup to nix repo 2026-04-01 22:05:40 +02:00
7408668b7f feat(direnv): migrate .dev to envrc use_dev 2026-03-27 15:09:42 +01:00
8d35c32782 feat(zsh): harden history setup 2026-03-20 14:42:38 +01:00
91d93955ab feat(claude): enable todo-mcp 2026-03-20 14:38:13 +01:00
f920a19118 chore(waybar): cleanup scripts 2026-03-18 00:50:23 +01:00
80d5f9c979 feat(tmux): allow passthrough 2026-03-18 00:39:21 +01:00
5a32bfeac5 feat(zsh): improve plugin load 2026-03-17 22:33:20 +01:00
5b2ecf82f7 fix(claude): global path in CLAUDE.md 2026-03-17 11:05:42 +01:00
4134296e7c feat(mako): add initial dotfiles 2026-03-15 11:16:49 +01:00
875cc8e8d1 feat(claude): add initial dotfiles 2026-03-15 11:15:28 +01:00
72ce9353fc feat(sway): add power-aware-effects script 2026-03-14 14:40:04 +01:00
07e5e31722 feat(waybar): drop eww and simplify components 2026-03-13 23:41:52 +01:00
dd9e8b5981 feat(zsh): set CLIPHIST_DB_PATH to /tmp 2026-03-13 15:36:46 +01:00
91191722ac fix(waybar): ssh-session false positive 2026-03-13 14:38:38 +01:00
5a9aec229e feat(sway): add fw16 specific config 2026-03-13 14:23:32 +01:00
e74a4390bb feat(sway): ws-to-current script 2026-03-13 14:21:39 +01:00
f64db7b9ce feat(fuzzel): change font size 2026-03-12 23:08:28 +01:00
e52005df82 feat(satty): replace flameshot 2026-03-12 18:28:31 +01:00
5b367986ee fix(waybar): ssh module false positive and resizing 2026-03-12 17:53:37 +01:00
af42a00659 merge: custom shell 2026-03-12 17:45:25 +01:00
4e765c57ff feat(sway): update for new components 2026-03-12 17:45:19 +01:00
8cf31772a5 feat(swaylock): update image and colors 2026-03-12 17:45:07 +01:00
d7cb42a64c feat(waybar): add config 2026-03-12 17:44:58 +01:00
f82afb4611 feat(swaync): add config 2026-03-12 17:44:51 +01:00
c6eaad94ef feat(eww): add config 2026-03-12 17:44:41 +01:00
adeb93bd24 feat(fuzzel): add config 2026-03-12 17:44:33 +01:00
5075adbeb3 chore: update .gitignore 2026-03-12 17:41:50 +01:00
f0aea1112a feat: simplify fzf scripts and extract FZF_DEFAULT_OPTS 2026-03-11 15:30:35 +01:00
574a190468 chore(alacritty): remove unused configuration 2026-03-11 14:45:35 +01:00
f4a94bb2c8 merge: sway improvements 2026-03-11 14:43:00 +01:00
7c5b9043c9 chore(sway): rename file with hostname change 2026-03-11 14:41:52 +01:00
807778fbb7 chore(sway): pkill wob on sway start 2026-03-11 14:38:29 +01:00
6ac6b70a3c feat(swaylock): polish ux options 2026-03-11 14:35:46 +01:00
0ba3a0d56f feat(swayidle): lock on loginctl lock-session 2026-03-11 14:35:21 +01:00
1edb0ebdf3 feat(sway): add inhibit idle for fullscreen 2026-03-11 14:35:01 +01:00
5c877bca5a chore(sway): always use pamixer instead of pactl 2026-03-11 14:32:42 +01:00
d4c4d21916 chore: blame ignore f148ab1559 2026-03-11 14:21:57 +01:00
f148ab1559 fix(sway): config typos 2026-03-11 14:20:56 +01:00
f63237e40e fix(tmux): copy selection with y 2026-03-11 14:16:21 +01:00
80444180d2 refactor: reorganize scripts to idiomatic locations 2026-03-11 14:14:24 +01:00
68302ad3d6 fix(zsh): return features that were removed with oh-my-zsh 2026-03-11 13:33:16 +01:00
2650b43ee3 feat(git): ignore full .claude 2026-03-10 09:24:11 +01:00
aaeacb8174 merge: cleanup tmux 2026-03-10 00:55:57 +01:00
a47d944286 chore(tmux): cleanup tmux scripts 2026-03-10 00:55:03 +01:00
42a1672fb0 chore(tmux): reorganize config 2026-03-10 00:50:12 +01:00
9b9b5b58a4 chore(tmux): normalize config 2026-03-10 00:47:51 +01:00
31950b6ae3 feat(tmux): remove os specific copy in favor of osc 2026-03-10 00:45:28 +01:00
74c3012139 feat(tmux): add sensible defaults 2026-03-10 00:44:39 +01:00
ef9bf9558f feat(tmux): add xterm-ghostty settings 2026-03-10 00:43:00 +01:00
30f82f848c feat(git): reorganize global gitignore and add ai 2026-03-09 22:23:45 +01:00
38d84331d1 feat(git): enable some sensible defaults 2026-03-09 22:20:58 +01:00
a9dc1bef9a chore(git): reorder and reformat config 2026-03-09 16:11:54 +01:00
9e33ba4640 merge: ghostty cleanup 2026-03-09 15:58:20 +01:00
6ed679170b fix(ghostty): add missing # to colorscheme 2026-03-09 15:58:13 +01:00
875f0cd0d1 feat(ghostty): dynamic light and dark colorscheme 2026-03-09 15:55:59 +01:00
e6e5244f3d chore(ghostty): remove unused macos and redundand config 2026-03-09 15:55:34 +01:00
43 changed files with 1084 additions and 465 deletions

2
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,2 @@
# typos
f148ab1559cbb4e0e46e05f8d151f74f64adb359

79
.gitignore vendored
View File

@@ -4,11 +4,9 @@
# allowed misc files
!.gitmodules
!.gitignore
!.git-blame-ignore-revs
!README.md
# allow some stuff to be pushed
!alacritty
# zsh
!zsh
zsh/*
@@ -17,7 +15,6 @@ zsh/*
!zsh/.zprofile
!zsh/scripts.zsh
!zsh/aliases.zsh
!zsh/ssh-menu
# starship
!starship
@@ -28,10 +25,7 @@ starship/*
!tmux
tmux/*
!tmux/tmux.conf
!tmux/tmux-new-project
!tmux/tmux-sessionizer
!tmux/tmux-ggclone
!tmux/tmux-ssher
!tmux/scripts
# git
!git
@@ -64,7 +58,68 @@ swaylock/*
swayidle/*
!swayidle/config
# flameshot
!flameshot
flameshot/*
!flameshot/flameshot.ini
# waybar
!waybar
waybar/*
!waybar/config.jsonc
!waybar/style.css
!waybar/scripts
waybar/scripts/*
!waybar/scripts/ssh-session.sh
!waybar/scripts/vpn-status.sh
!waybar/scripts/notification-status.sh
!waybar/scripts/mic-status.sh
!waybar/scripts/network-status.sh
# eww
!eww
eww/*
!eww/eww.yuck
!eww/eww.scss
!eww/scripts
eww/scripts/*
!eww/scripts/popup.sh
!eww/scripts/system.sh
!eww/scripts/battery.sh
!eww/scripts/volume.sh
!eww/scripts/bluetooth.sh
!eww/scripts/network.sh
!eww/scripts/vpn.sh
!eww/scripts/keyboard.sh
!eww/scripts/media.sh
# sway scripts
!sway/scripts
sway/scripts/*
!sway/scripts/power-menu.sh
!sway/scripts/screenshot.sh
!sway/scripts/ws-to-current.sh
!sway/scripts/power-aware-effects.sh
# bin
!bin
bin/*
!bin/ssh-menu
# swaync
!swaync
swaync/*
!swaync/config.json
!swaync/style.css
# fuzzel
!fuzzel
fuzzel/*
!fuzzel/fuzzel.ini
# mako
!mako
mako/*
!mako/config
# claude
!claude
claude/*
!claude/CLAUDE.md
!claude/settings.json
!claude/statusline-command.sh

View File

@@ -1,82 +0,0 @@
[colors]
draw_bold_text_with_bright_colors = true
[colors.bright]
black = "0x45403d"
blue = "0x7daea3"
cyan = "0x89b482"
green = "0xa9b665"
magenta = "0xd3869b"
red = "0xea6962"
white = "0xd4be98"
yellow = "0xd8a657"
[colors.normal]
black = "0x45403d"
blue = "0x7daea3"
cyan = "0x89b482"
green = "0xa9b665"
magenta = "0xd3869b"
red = "0xea6962"
white = "0xd4be98"
yellow = "0xd8a657"
[colors.primary]
background = "0x32302f"
foreground = "0xd4be98"
[cursor]
unfocused_hollow = true
[cursor.style]
blinking = "On"
shape = "Block"
[env]
TERM = "xterm-256color"
[font]
size = 15
[font.bold]
family = "JetBrainsMono Nerd Font"
style = "Bold"
[font.bold_italic]
family = "JetBrainsMono Nerd Font"
style = "Bold Italic"
[font.italic]
family = "JetBrainsMono Nerd Font"
style = "Italic"
[font.normal]
family = "JetBrainsMono Nerd Font"
style = "Regular"
[[keyboard.bindings]]
chars = "\f"
key = "R"
mode = "~Vi|~Search"
mods = "Command"
[[keyboard.bindings]]
action = "ScrollPageUp"
key = "PageUp"
mode = "~Alt"
[[keyboard.bindings]]
action = "ScrollPageDown"
key = "PageDown"
mode = "~Alt"
[scrolling]
history = 10000
[window]
dynamic_title = true
option_as_alt = "Both"
[window.dimensions]
columns = 150
lines = 36

53
bin/ssh-menu Executable file
View File

@@ -0,0 +1,53 @@
#!/usr/bin/env bash
function _ssh_menu_preview {
file=$1; shift
host=$1; shift
# show host block from ssh config
awk -v h="$host" '
$0 == "Host " h { found=1 }
found && /^[^ \t]/ && $0 != "Host " h { exit }
found
' "$file"
echo ""
# resolve hostname for reachability check
hostname=$(awk -v h="$host" '
$0 == "Host " h { found=1; next }
found && /^[^ \t]/ { exit }
found && /HostName/ { print $2 }
' "$file")
if command -v host &>/dev/null; then
host "${hostname:-$host}"
echo ""
fi
ping -c 1 -W 1 "${hostname:-$host}" &>/dev/null \
&& echo "reachable" \
|| echo "not reachable"
}
export -f _ssh_menu_preview
function _ssh_menu_select {
rg -N --no-heading '^Host .*' ~/.ssh \
| sed 's/Host \(.*\)/\1/' | sort \
| SHELL=$(which bash) fzf \
--delimiter ':' \
--with-nth 2 \
--preview "_ssh_menu_preview {1} {2}" \
--preview-label "ssh config info" \
--border-label "ssh-menu" \
| cut -d ":" -f2
}
case "${1:-}" in
-s) _ssh_menu_select ;;
*)
selected="$(_ssh_menu_select)"
[[ -n $selected ]] && ssh "$selected"
;;
esac

38
claude/CLAUDE.md Normal file
View File

@@ -0,0 +1,38 @@
# Global CLAUDE.md
## Comments
Comments must be one of two forms:
```
# descriptive but non-verbose comment
# KEYWORD:(@janezicmatej) descriptive but non-verbose comment
```
Rules:
- always lowercase
- no trailing punctuation
- keywords: WARN, FIX, NOTE, TODO, PERF, TEST, HACK
- keyword comments must include attribution `(@janezicmatej)`
## Git
- commit only when asked or when delegating to agents
- agents MUST commit with `--no-gpg-sign`
## Workflow
- implement changes directly; don't use sub-agents/Task for simple operations like renames, file moves, or single-file edits; only use Task for genuinely complex parallel exploration or research
- when redirected or interrupted, immediately stop the current approach and follow the new direction; don't explain or defend the previous approach
- focus on one goal per session; don't drift into unrelated improvements
- use Task agents for research and exploration, not for straightforward implementation
## Scope
- NEVER modify anything outside the scope of what was asked
- don't introduce unrelated changes, touch unrelated configs, or change defaults not mentioned
- if something related should change, ask first
## Config locations
- MCP server configs go in `.claude.json` (project) or `$CLAUDE_CONFIG_DIR/.claude.json` (global, defaults to `~/.claude.json`), not `settings.json`
- `settings.json` is for permissions, hooks, and behavior settings
## Code quality
- after making changes, check if the project has linters/formatters and run them

18
claude/settings.json Normal file
View File

@@ -0,0 +1,18 @@
{
"permissions": {
"allow": [
"mcp__todo-mcp__*",
"mcp__nixos__*",
"Bash(git remote get-url origin)"
]
},
"hooks": {},
"statusLine": {
"type": "command",
"command": "sh \"${CLAUDE_CONFIG_DIR:-$HOME/.claude}/statusline-command.sh\""
},
"effortLevel": "xhigh",
"skipDangerousModePermissionPrompt": true,
"voiceEnabled": true,
"mcpServers": {}
}

View File

@@ -0,0 +1,52 @@
#!/bin/sh
input=$(cat)
model=$(echo "$input" | jq -r '.model.display_name // empty')
total_in=$(echo "$input" | jq -r '.context_window.total_input_tokens // 0')
total_out=$(echo "$input" | jq -r '.context_window.total_output_tokens // 0')
ctx=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
five_hr=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
five_hr_reset=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')
seven_day=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')
seven_day_reset=$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty')
# format seconds until reset as human-readable
fmt_remaining() {
now=$(date +%s)
diff=$(( $1 - now ))
[ "$diff" -le 0 ] && return
h=$(( diff / 3600 ))
m=$(( (diff % 3600) / 60 ))
if [ "$h" -gt 0 ]; then
printf '%dh%dm' "$h" "$m"
else
printf '%dm' "$m"
fi
}
parts=""
[ -n "$model" ] && parts="$model"
if [ -n "$total_in" ] && [ "$total_in" != "0" ]; then
total=$((total_in + total_out))
parts="${parts:+$parts | }tokens:${total}"
fi
if [ -n "$ctx" ]; then
parts="${parts:+$parts | }ctx:$(printf '%.0f' "$ctx")%"
fi
if [ -n "$five_hr" ]; then
five_hr_ttl=""
[ -n "$five_hr_reset" ] && five_hr_ttl=$(fmt_remaining "$five_hr_reset")
parts="${parts:+$parts | }5h:$(printf '%.0f' "$five_hr")%${five_hr_ttl:+($five_hr_ttl)}"
fi
if [ -n "$seven_day" ]; then
seven_day_ttl=""
[ -n "$seven_day_reset" ] && seven_day_ttl=$(fmt_remaining "$seven_day_reset")
parts="${parts:+$parts | }7d:$(printf '%.0f' "$seven_day")%${seven_day_ttl:+($seven_day_ttl)}"
fi
[ -n "$parts" ] && printf '%s' "$parts"

View File

@@ -1,16 +0,0 @@
[General]
contrastOpacity=188
contrastUiColor=#000000
disabledGrimWarning=true
drawColor=#00ffff
saveAfterCopy=true
savePath=/home/matej/screens
showHelp=false
showMagnifier=true
showSelectionGeometryHideTime=3000
uiColor=#ffffff
useGrimAdapter=true
[Shortcuts]
TYPE_ACCEPT=
TYPE_COPY=Space

22
fuzzel/fuzzel.ini Normal file
View File

@@ -0,0 +1,22 @@
[main]
font=JetBrainsMono Nerd Font:size=10
prompt=" "
icons=no
terminal=ghostty -e
width=40
lines=12
layer=overlay
exit-on-keyboard-focus-loss=yes
[colors]
background=252423ff
text=d4be98ff
match=a9b665ff
selection=45403dff
selection-text=d4be98ff
selection-match=a9b665ff
border=45403dff
[border]
width=2
radius=8

View File

@@ -1,11 +1,8 @@
# theme
# theme = light:gruvbox-material-soft-light,dark:gruvbox-material-soft-dark
theme = gruvbox-material-soft-dark
theme = light:gruvbox-material-soft-light,dark:gruvbox-material-soft-dark
minimum-contrast = 1.1
# cursor
cursor-style = block
cursor-style-blink = true
# mouse
@@ -25,20 +22,10 @@ window-theme = dark
window-height = 36
window-width = 150
# macos send option as alt
macos-option-as-alt = true
# no warning full close
confirm-close-surface = false
# quit-after-last-window-closed = true
# keybinds
keybind = global:cmd+enter=new_window
# shell integrations for zsh
# https://ghostty.org/docs/features/shell-integration
shell-integration = zsh
# gtk
gtk-titlebar = false

View File

@@ -1,4 +1,4 @@
palette = 0=252423
palette = 0=#252423
palette = 1=#ea6962
palette = 2=#a9b665
palette = 3=#d8a657

View File

@@ -1,56 +1,71 @@
[user]
name = Matej Janežič
email = janezic.mj@gmail.com
signingkey = AF349EECC849D87B790E88FF6318FFB7DB374B7D
[commit]
gpgsign = true
verbose = true
; NOTE:(@janezicmatej) github/gitlab don't support these
; [push]
; gpgsign = true
[core]
autocrlf = input
editor = nvim
[user]
signingkey = AF349EECC849D87B790E88FF6318FFB7DB374B7D
[commit]
gpgsign = true
; NOTE:(@janezicmatej) github/gitlab don't support these
; [push]
; gpgsign = true
[init]
defaultBranch = main
[alias]
blame = "!f() { [ -f .git-blame-ignore-revs ] && git blame --ignore-revs-file .git-blame-ignore-revs \"$@\" || git blame \"$@\"; }; f"
[rebase]
updateRefs = true
[diff]
tool = "nvimdiff"
[difftool]
prompt = true
[difftool "nvimdiff"]
cmd = nvim -d "$LOCAL" "$REMOTE"
[maintenance]
auto = true
strategy = incremental
[rerere]
enabled = true
autoUpdate = true
[merge]
tool = "nvimdiff"
tool = nvimdiff
conflictStyle = zdiff3
[mergetool]
prompt = true
keepBackup = false
writeToTemp = true
[mergetool "nvimdiff"]
layout = "LOCAL,BASE,REMOTE / MERGED"
[includeIf "gitdir:~/git/git.aflabs.org/**"]
[diff]
tool = nvimdiff
algorithm = histogram
colorMoved = plain
mnemonicPrefix = true
[difftool "nvimdiff"]
cmd = nvim -d "$LOCAL" "$REMOTE"
[alias]
blame-ignore = "config blame.ignoreRevsFile .git-blame-ignore-revs"
[branch]
sort = -committerdate
[tag]
sort = version:refname
[help]
autoCorrect = prompt
[maintenance]
auto = true
strategy = incremental
[includeIf "gitdir:~/git/git.aflabs.org/"]
path = ~/.config/git/config.d/aflabs.conf
[includeIf "gitdir:~/git/gitlab.com/flarenetwork/**"]
[includeIf "gitdir:~/git/gitlab.com/flarenetwork/"]
path = ~/.config/git/config.d/flare.conf
[includeIf "gitdir:~/git/gitlab.com/flare-foundation/**"]
[includeIf "gitdir:~/git/gitlab.com/flare-foundation/"]
path = ~/.config/git/config.d/flare.conf

View File

@@ -1,22 +1,23 @@
# mac files
# os
.DS_Store
# i don't like pushing .vscode and .idea folders, i will force add if needed
# editors
.vscode
.idea
# pyenv
.python-version
# nix venv hook
.nix-venv
.dev
# i use .ignore for nvim
.ignore
# todo files
TODO.md
# ai
CLAUDE.local.md
.claude
# db dumps files
# languages
.python-version
# nix
.nix-venv
.envrc
.direnv/
# project-local
TODO.md
dumps

28
mako/config Normal file
View File

@@ -0,0 +1,28 @@
# gruvbox-material-soft-dark
font=JetBrainsMono Nerd Font 11
background-color=#252423
text-color=#d4be98
border-color=#45403d
border-size=2
border-radius=8
padding=12
width=450
height=300
margin=8
max-visible=3
default-timeout=10000
ignore-timeout=0
group-by=app-name
max-icon-size=32
icon-path=/usr/share/icons/Adwaita
layer=overlay
anchor=top-right
[urgency=low]
default-timeout=5000
[urgency=critical]
default-timeout=0
border-color=#ea6962

View File

@@ -8,7 +8,7 @@ set $right l
# programs
set $term ghostty
set $menu wofi --show drun -iIG -w 2
set $menu fuzzel
set $browser google-chrome-stable
set $lockscreen swaylock

View File

@@ -1,6 +1,6 @@
# sway
bindsym $mod+Shift+c reload
bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -B 'Yes, exit sway' 'swaymsg exit'
bindsym $mod+Shift+e exec ~/.config/sway/scripts/power-menu.sh
floating_modifier $mod normal
# programs
@@ -8,9 +8,16 @@ bindsym $mod+Return exec $term
bindsym $mod+d exec $menu
bindsym $mod+u exec $lockscreen
bindsym $mod+Shift+Ctrl+Alt+space exec 1password --quick-access
bindsym Print exec flameshot gui
bindsym Print exec ~/.config/sway/scripts/screenshot.sh
# programs'
# notifications
bindsym $mod+n exec makoctl dismiss
bindsym $mod+Shift+n exec makoctl dismiss --all
# clipboard
bindsym $mod+c exec cliphist list | fuzzel -d | cliphist decode | wl-copy
# window
bindsym $mod+Shift+q kill
# move focus
@@ -49,16 +56,16 @@ bindsym $mod+Shift+8 move container to workspace number 8
bindsym $mod+Shift+9 move container to workspace number 9
bindsym $mod+Shift+0 move container to workspace number 10
bindsym $mod+Ctrl+1 workspace number 1 output current
bindsym $mod+Ctrl+2 workspace number 2 output current
bindsym $mod+Ctrl+3 workspace number 3 output current
bindsym $mod+Ctrl+4 workspace number 4 output current
bindsym $mod+Ctrl+5 workspace number 5 output current
bindsym $mod+Ctrl+6 workspace number 6 output current
bindsym $mod+Ctrl+7 workspace number 7 output current
bindsym $mod+Ctrl+8 workspace number 8 output current
bindsym $mod+Ctrl+9 workspace number 9 output current
bindsym $mod+Ctrl+0 workspace number 10 output current
bindsym $mod+Ctrl+1 exec ~/.config/sway/scripts/ws-to-current.sh 1
bindsym $mod+Ctrl+2 exec ~/.config/sway/scripts/ws-to-current.sh 2
bindsym $mod+Ctrl+3 exec ~/.config/sway/scripts/ws-to-current.sh 3
bindsym $mod+Ctrl+4 exec ~/.config/sway/scripts/ws-to-current.sh 4
bindsym $mod+Ctrl+5 exec ~/.config/sway/scripts/ws-to-current.sh 5
bindsym $mod+Ctrl+6 exec ~/.config/sway/scripts/ws-to-current.sh 6
bindsym $mod+Ctrl+7 exec ~/.config/sway/scripts/ws-to-current.sh 7
bindsym $mod+Ctrl+8 exec ~/.config/sway/scripts/ws-to-current.sh 8
bindsym $mod+Ctrl+9 exec ~/.config/sway/scripts/ws-to-current.sh 9
bindsym $mod+Ctrl+0 exec ~/.config/sway/scripts/ws-to-current.sh 10
# layout
bindsym $mod+b splith
@@ -80,12 +87,12 @@ bindsym $mod+Shift+minus move scratchpad
bindsym $mod+minus scratchpad show
# xf86-volume
bindsym --locked XF86AudioMute exec pactl set-sink-mute \@DEFAULT_SINK@ toggle
bindsym --locked XF86AudioMute exec pamixer -t && ( pamixer --get-mute && echo 0 > $wobs || pamixer --get-volume > $wobs )
bindsym --locked XF86AudioLowerVolume exec pamixer -d 5 && pamixer --get-volume > $wobs
bindsym --locked XF86AudioRaiseVolume exec pamixer -i 5 && pamixer --get-volume > $wobs
bindsym --locked F16 exec pactl set-source-mute \@DEFAULT_SOURCE@ toggle
bindsym --locked F16 exec pamixer --default-source -t
# xf86-brightnes
# xf86-brightness
bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-
bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+
# xf86-audio

View File

@@ -2,17 +2,24 @@
for_window [floating] border pixel $border
for_window [tiling] border normal $border
for_window [app_id="com.mitchellh.ghostty" title="fastfetch"] floating enable, focus, move position 50 50
# workspace assignment
assign [app_id="google-chrome"] workspace 2
assign [app_id="thunderbird"] workspace 3
assign [app_id="Cider"] workspace 4
assign [app_id=".*BoltLauncher.*"] workspace 5
assign [class="net-runelite.*"] workspace 5
assign [app_id="vesktop"] workspace 8
assign [app_id="discord"] workspace 8
assign [app_id="Slack"] workspace 8
assign [app_id="org.telegram.desktop"] workspace 8
assign [class="Rocket.Chat"] workspace 8
assign [app_id="Rocket.Chat"] workspace 8
# rules
for_window [app_id="com.gabm.satty"] fullscreen enable
for_window [class="net-runelite.*"] floating enable
no_focus [class="net-runelite.*"]
# idle
for_window [app_id=".*"] inhibit_idle fullscreen
for_window [class=".*"] inhibit_idle fullscreen

View File

@@ -1,19 +1,19 @@
# deamon
# daemon
exec mako
exec swayidle -w
exec wlsunset -l 46.1 -L 14.5
exec rm -f $wobs \
&& mkfifo $wobs \
&& tail -f $wobs \
| wob
exec pkill -x wob; rm -f $wobs && mkfifo $wobs && tail -f $wobs | wob
exec wl-paste --watch cliphist store
exec ~/.config/sway/scripts/power-aware-effects.sh
exec protonmail-bridge -n
# traditional "start when os starts" programs
exec $term
exec ghostty --title=fastfetch --window-width=105 --window-height=27 -e bash -c 'nix run nixpkgs#fastfetch; read -rsn1' && ghostty
exec $browser
exec thunderbird
exec cider-2
exec bolt-launcher
exec vesktop
exec discord
exec slack
exec Telegram
exec rocketchat-desktop

2
sway/host.d/fw16.conf Normal file
View File

@@ -0,0 +1,2 @@
output DP-7 resolution 2560x1440 position 2560,-1200
output eDP-1 resolution 2560x1600@165Hz position 0,0 adaptive_sync on

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# toggle swayfx blur and shadows based on battery state
while true; do
status=$(cat /sys/class/power_supply/BAT1/status 2>/dev/null || cat /sys/class/power_supply/BAT0/status)
if [ "$status" = "Discharging" ]; then
swaymsg blur off
swaymsg shadows off
else
swaymsg blur on
swaymsg shadows on
fi
sleep 30
done

13
sway/scripts/power-menu.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# power menu via fuzzel
choice=$(printf "lock\nlogout\nsuspend\nreboot\nshutdown" | fuzzel -d -p "power: ")
case "$choice" in
lock) swaylock ;;
logout) swaymsg exit ;;
suspend) systemctl suspend ;;
reboot) systemctl reboot ;;
shutdown) systemctl poweroff ;;
esac

6
sway/scripts/screenshot.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
# screenshot focused monitor with satty
output=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused) | .name')
grim -o "$output" - | satty -f - --fullscreen --early-exit

4
sway/scripts/ws-to-current.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
# switch to workspace and move it to the currently focused output
output=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused) | .name')
swaymsg "workspace number $1, move workspace to output $output"

View File

@@ -1,3 +1,4 @@
lock 'swaylock -f'
timeout 300 'swaylock -f'
timeout 600 'swaymsg "output * power off"' resume 'swaymsg "output * power on"'
before-sleep 'swaylock -f'

View File

@@ -1,4 +1,7 @@
image=~/.assets/lockscreen.png
ignore-empty-password
show-failed-attempts
image=~/.assets/wallpaper.png
clock
datestr=%A, %d/%m/%y
@@ -9,23 +12,24 @@ indicator-idle-visible
indicator-y-position=300
indicator-x-position=1200
inside-color=000000
text-color=ffffff
ring-color=ffffff
# gruvbox-material-soft-dark
inside-color=#32302f
text-color=#d4be98
ring-color=#928374
inside-ver-color=000000
text-ver-color=000000
ring-ver-color=ffffff
inside-ver-color=#32302f
text-ver-color=#a9b665
ring-ver-color=#a9b665
inside-clear-color=000000
text-clear-color=ffffff
ring-clear-color=ffffff
inside-clear-color=#32302f
text-clear-color=#d8a657
ring-clear-color=#d8a657
inside-wrong-color=000000
text-wrong-color=ffffff
ring-wrong-color=ffffff
inside-wrong-color=#32302f
text-wrong-color=#ea6962
ring-wrong-color=#ea6962
key-hl-color=000000
bs-hl-color=000000
caps-lock-key-hl-color=000000
caps-lock-bs-hl-color=000000
key-hl-color=#7daea3
bs-hl-color=#ea6962
caps-lock-key-hl-color=#d8a657
caps-lock-bs-hl-color=#ea6962

View File

@@ -1,7 +1,5 @@
#!/usr/bin/env bash
source "$XDG_CONFIG_HOME/zsh/scripts.zsh"
if [[ $# -eq 1 ]]; then
selected=$1
else
@@ -12,7 +10,7 @@ if [[ -z $selected ]]; then
exit 0
fi
ggman clone $selected
ggman clone "$selected"
echo ""
read -p "press enter to continue..."

View File

@@ -6,8 +6,6 @@ if [[ -z ${NAME:+x} ]]; then
exit 1
fi
source "$XDG_CONFIG_HOME/zsh/scripts.zsh"
read -p "name: " project_name
if [[ -z $project_name ]]; then
@@ -19,16 +17,16 @@ if [[ -d "$GGROOT/no-remote/$project_name" ]]; then
fi
project="$GGROOT/no-remote/$project_name"
git init $project
git init "$project"
echo "# $project_name" >>"$project/README.md"
gitignore_template=$(
find "$GGROOT"/github.com/github/gitignore/*.gitignore -exec basename {} \; \
| sed 's/\(.*\)\.gitignore/\1/' \
| fzf --cycle --bind 'tab:toggle-up,btab:toggle-down'
| fzf
)
if ! [[ -z $gitignore_template ]]; then
if [[ -n $gitignore_template ]]; then
gitignore="$GGROOT/github.com/github/gitignore/$gitignore_template.gitignore"
echo "$gitignore"
echo "$project/.gitignore"
@@ -38,13 +36,11 @@ fi
license_template=$(
find "$GGROOT"/git.janezic.dev/janezicmatej/license/*.license -exec basename {} \; \
| sed 's/\(.*\)\.license/\1/' \
| fzf --cycle --bind 'tab:toggle-up,btab:toggle-down'
| fzf
)
if ! [[ -z $license_template ]]; then
if [[ -n $license_template ]]; then
license="$GGROOT/git.janezic.dev/janezicmatej/license/$license_template.license"
export YEAR="$(date '+%Y')"
envsubst <"$license" >"$project/LICENSE"
fi
ggcompile

27
tmux/scripts/tmux-sessionizer Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
if [[ $# -eq 1 ]]; then
selected=$1
else
selected=$(ggman ls \
| fzf \
--border-label "tmux-sessionizer" \
)
fi
if [[ -z $selected ]]; then
exit 0
fi
selected_name="$(echo "$selected" | shasum -a 256 | head -c 4)_$(basename "$selected" | tr . _ | head -c 10)"
if [[ -z $TMUX ]] && ! tmux list-sessions 2>/dev/null; then
tmux new-session -s "$selected_name" -c "$selected"
exit 0
fi
if ! tmux has-session -t="$selected_name" 2>/dev/null; then
tmux new-session -ds "$selected_name" -c "$selected"
fi
tmux switch-client -t "$selected_name"

24
tmux/scripts/tmux-ssher Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
if [[ $# -eq 1 ]]; then
selected=$1
else
selected="$(~/.config/bin/ssh-menu -s)"
fi
if [[ -z $selected ]]; then
exit 0
fi
selected_name="ssh_$selected"
if [[ -z $TMUX ]] && ! tmux list-sessions 2>/dev/null; then
tmux new-session -s "$selected_name" ssh "$selected"
exit 0
fi
if ! tmux has-session -t="$selected_name" 2>/dev/null; then
tmux new-session -ds "$selected_name" ssh "$selected"
fi
tmux switch-client -t "$selected_name"

View File

@@ -1,34 +0,0 @@
#!/usr/bin/env bash
if [[ $# -eq 1 ]]; then
selected=$1
else
selected=$(ggman ls \
| fzf --cycle \
--bind 'tab:toggle-up,btab:toggle-down' \
--header "Navigate with ARROW KEYS or TAB/S-TAB. Select with ENTER." \
--border "double" \
--border-label "tmux-sessionizer" \
--ansi \
--highlight-line \
)
fi
if [[ -z $selected ]]; then
exit 0
fi
selected_name="$(echo $selected | shasum -a 256 | head -c 4)_$(basename $selected | tr . _ | head -c 10)"
tmux_running=$(pgrep tmux)
if [[ -z $TMUX ]] && [[ -z $tmux_running ]]; then
tmux new-session -s $selected_name -c $selected
exit 0
fi
if ! tmux has-session -t=$selected_name 2> /dev/null; then
tmux new-session -ds $selected_name -c $selected
fi
tmux switch-client -t $selected_name

View File

@@ -1,77 +0,0 @@
#!/usr/bin/env bash
function _preview {
file=$1; shift
host=$1; shift
j=$(cat $file \
| jc --ssh-conf \
| jq -r ".[] \
| select(.host == \"$host\") \
| .jumps = (if (.proxyjump | type == \"array\" and length > 0) then (.proxyjump | join(\",\")) else \"null\" end)" \
)
user=$(jq -r '.user' <<<$j)
port=$(jq -r '.port' <<<$j)
hostname=$(jq -r '.hostname' <<<$j)
jumps=$(jq -r '.jumps' <<<$j)
echo "$(cat <<EOF
User $user
HostName $hostname\
$([[ $port != "null" ]] && echo -e "\nPort $port")\
$([[ $jumps != "null" ]] && echo -e "\nProxyJump $jumps")
command:
ssh $user@$hostname$([[ $port != "null" ]] && echo -n " -p $port")$([[ $jumps != "null" ]] && echo -n " -J $jumps")
EOF)"
echo ""
host $hostname
echo ""
ping -c 1 -W 1 $hostname &>/dev/null \
&& echo "Host is reachable!" \
|| echo "Host is not reachable!"
}
export -f _preview
function main() {
if [[ $# -eq 1 ]]; then
selected=$1
else
selected="$(rg -N --no-heading '^Host .*' ~/.ssh \
| sed 's/Host \(.*\)/\1/' \
| SHELL=$(which bash) fzf --cycle \
--bind 'tab:toggle-up,btab:toggle-down' \
--delimiter ':' \
--with-nth 2 \
--preview "_preview {1} {2}" \
| cut -d ":" -f2
)"
fi
if [[ -z $selected ]]; then
exit 0
fi
selected_name="ssh_$selected"
tmux_running=$(pgrep tmux)
if [[ -z $TMUX ]] && [[ -z $tmux_running ]]; then
tmux new-session -s $selected_name -c $selected ssh "$selected"
exit 0
fi
if ! tmux has-session -t=$selected_name 2> /dev/null; then
tmux new-session -ds $selected_name -c $selected ssh "$selected"
fi
tmux switch-client -t $selected_name
}
main "$@"

View File

@@ -1,53 +1,56 @@
set -g default-terminal "xterm-256color"
set -ga terminal-overrides ",xterm-256color:RGB"
set -ga terminal-features ",xterm-256color:clipboard"
set -g allow-passthrough on
set -g set-clipboard on
# server options
set -s escape-time 0
# terminal
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",xterm-ghostty:RGB,xterm-256color:RGB"
set -ga terminal-features ",xterm-ghostty:clipboard,xterm-256color:clipboard"
set -g set-clipboard on
set -g allow-passthrough on
# general
set -g prefix C-s
set -g base-index 1
set -g focus-events on
set -g update-environment "SSH_AUTH_SOCK SSH_CONNECTION SSH_TTY DISPLAY"
unbind C-b
set-option -g prefix C-s
bind r source-file "$XDG_CONFIG_HOME/tmux/tmux.conf"
set -g base-index 1
# status bar
set -g status-style 'bg=default fg=default'
set -g status-left-length 20
set-window-option -g mode-keys vi
# window options
set -wg mode-keys vi
set -g pane-base-index 1
set -g renumber-windows on
# prefix
unbind C-b
# copy mode
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-selection-and-cancel
# differentiate copy on linux and max
if-shell -b '[ "$(uname -s)" = "Linux" ]' {
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard'
}
if-shell -b '[ "$(uname -s)" = "Darwin" ]' {
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'pbcopy'
}
# vim-like pane switching
# navigation
bind ^ last-window
bind k select-pane -U
bind j select-pane -D
bind h select-pane -L
bind l select-pane -R
# reload
bind r source-file "$XDG_CONFIG_HOME/tmux/tmux.conf"
# sessionizer
bind-key f run-shell "tmux neww ~/.config/tmux/tmux-sessionizer"
bind-key R run-shell "tmux neww ~/.config/tmux/tmux-sessionizer ~"
bind-key g run-shell "tmux neww ~/.config/tmux/tmux-sessionizer ~/.config"
bind-key T run-shell "tmux neww ~/.config/tmux/tmux-sessionizer ~/temp"
bind f run-shell "tmux neww ~/.config/tmux/scripts/tmux-sessionizer"
bind R run-shell "tmux neww ~/.config/tmux/scripts/tmux-sessionizer ~"
bind g run-shell "tmux neww ~/.config/tmux/scripts/tmux-sessionizer ~/.config"
bind T run-shell "tmux neww ~/.config/tmux/scripts/tmux-sessionizer ~/temp"
# clone
bind-key G run-shell "tmux neww ~/.config/tmux/tmux-ggclone"
bind G run-shell "tmux neww ~/.config/tmux/scripts/tmux-ggclone"
# ssh
bind-key F run-shell "tmux neww ~/.config/tmux/tmux-ssher"
bind F run-shell "tmux neww ~/.config/tmux/scripts/tmux-ssher"
# project
bind-key N run-shell "tmux neww ~/.config/tmux/tmux-new-project"
bind N run-shell "tmux neww ~/.config/tmux/scripts/tmux-new-project"

142
waybar/config.jsonc Normal file
View File

@@ -0,0 +1,142 @@
[
{
"layer": "top",
"position": "top",
"height": 30,
"spacing": 1,
"margin": 0,
"modules-left": [
"sway/workspaces",
"sway/mode"
],
"modules-center": [
"custom/ssh",
"systemd-failed-units"
],
"modules-right": [
"mpris",
"cpu",
"memory",
"battery",
"wireplumber",
"custom/mic",
"backlight",
"sway/language",
"bluetooth",
"custom/network",
"clock"
],
"sway/workspaces": {
"disable-scroll": true,
"format": "{name}"
},
"sway/mode": {
"format": "{}"
},
"sway/language": {
"format": "{short}",
"on-click": "swaymsg input type:keyboard xkb_switch_layout next"
},
"custom/ssh": {
"format": "{}",
"return-type": "json",
"interval": 15,
"exec": "~/.config/waybar/scripts/ssh-session.sh",
"on-click": "~/.config/waybar/scripts/ssh-session.sh disconnect"
},
"systemd-failed-units": {
"hide-on-ok": true,
"format": "!{nr_failed}",
"format-ok": "",
"system": true,
"user": true,
"on-click": "ghostty -e sh -c 'systemctl --failed; systemctl --user --failed; read'"
},
"mpris": {
"format": "{artist} - {title}",
"format-paused": "{artist} - {title} [paused]",
"format-stopped": "",
"max-length": 35,
"tooltip-format": "{player}: {artist} - {title} ({album})",
"on-click": "playerctl play-pause",
"on-scroll-up": "playerctl next",
"on-scroll-down": "playerctl previous"
},
"custom/network": {
"format": "{}",
"return-type": "json",
"interval": 5,
"exec": "~/.config/waybar/scripts/network-status.sh"
},
"bluetooth": {
"format": "󰂯",
"format-connected": "󰂯 {num_connections}",
"format-connected-battery": "󰂯 {num_connections}",
"tooltip-format-connected": "{device_enumerate}"
},
"cpu": {
"format": "󰻠 {usage}%",
"tooltip": false
},
"memory": {
"interval": 10,
"format": "󰍛 {percentage}%",
"tooltip-format": "total: {total:0.2f}GiB\nused: {used:0.2f}GiB\navailable: {avail:0.2f}GiB\nswap: {swapUsed:0.2f}/{swapTotal:0.2f}GiB"
},
"battery": {
"states": {
"warning": 30,
"critical": 15
},
"format": "󰁹 {capacity}%",
"format-charging": "󰂄 {capacity}%",
"format-plugged": "󰚥 {capacity}%",
"format-full": "󰁹 full",
"format-alt": "{time}",
"tooltip-format": "{timeTo}\n{power}W",
"on-click": "p=$(powerprofilesctl get); case $p in power-saver) n=balanced;; balanced) n=performance;; *) n=power-saver;; esac; powerprofilesctl set $n"
},
"wireplumber": {
"format": "󰕾 {volume}%",
"format-muted": "󰖁 muted",
"on-click": "pamixer -t",
"on-scroll-up": "pamixer -i 5",
"on-scroll-down": "pamixer -d 5",
"tooltip-format": "{node_name}: {volume}%"
},
"custom/mic": {
"format": "{}",
"return-type": "json",
"interval": 2,
"exec": "~/.config/waybar/scripts/mic-status.sh",
"on-click": "pamixer --default-source -t",
"on-scroll-up": "pamixer --default-source -i 5",
"on-scroll-down": "pamixer --default-source -d 5"
},
"backlight": {
"format": "󰃟 {percent}%",
"tooltip": false
},
"clock": {
"interval": 1,
"format": "{:%d/%m %H:%M:%S}",
"tooltip-format": "<big><tt>{calendar}</tt></big>"
}
}
]

12
waybar/scripts/mic-status.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
# mic volume for waybar custom module
vol=$(pamixer --default-source --get-volume 2>/dev/null || echo 0)
muted=$(pamixer --default-source --get-mute 2>/dev/null || echo false)
if [[ "$muted" == "true" ]]; then
printf '{"text": "󰍭", "class": "muted", "tooltip": "mic muted"}\n'
else
printf '{"text": "󰍬 %d%%", "class": "", "tooltip": "mic %d%%"}\n' "$vol" "$vol"
fi

View File

@@ -0,0 +1,73 @@
#!/usr/bin/env bash
# combined network + vpn status for waybar
# format: icon ip/cidr [vpn-name ...]
iface=$(ip route show default 2>/dev/null | awk '/default/ {print $5; exit}')
icon="󰖪"
class="disconnected"
net_text=""
vpn_names=()
tooltip_parts=()
# network
if [[ -n "$iface" ]]; then
cidr=$(ip -4 addr show "$iface" 2>/dev/null | awk '/inet / {print $2; exit}')
gw=$(ip route show default 2>/dev/null | awk '/default/ {print $3; exit}')
if [[ "$iface" == wl* ]]; then
icon="󰖩"
class="wifi"
ssid=$(nmcli -t -f active,ssid dev wifi 2>/dev/null | awk -F: '/^yes:/ {print $2}')
signal=$(nmcli -t -f active,signal dev wifi 2>/dev/null | awk -F: '/^yes:/ {print $2}')
tooltip_parts+=("$iface: $cidr via $gw")
[[ -n "$ssid" ]] && tooltip_parts+=("ssid: $ssid (${signal}%)")
else
icon="󰈀"
class="wired"
tooltip_parts+=("$iface: $cidr via $gw")
fi
net_text="$cidr"
else
tooltip_parts+=("no connection")
fi
# wireguard — show config name (interface name, e.g. wg-office)
if command -v wg &>/dev/null; then
for wg_iface in $(wg show interfaces 2>/dev/null); do
wg_cidr=$(ip -4 addr show "$wg_iface" 2>/dev/null | awk '/inet / {print $2; exit}')
vpn_names+=("$wg_iface")
tooltip_parts+=("wg: $wg_iface $wg_cidr")
done
fi
# tailscale — show exit node name if routed, otherwise tailnet name
if command -v tailscale &>/dev/null; then
ts_json=$(tailscale status --json 2>/dev/null)
ts_state=$(jq -r '.BackendState // empty' <<<"$ts_json")
if [[ "$ts_state" == "Running" ]]; then
ts_ip=$(jq -r '.TailscaleIPs[0] // empty' <<<"$ts_json")
ts_self=$(jq -r '.Self.HostName // empty' <<<"$ts_json")
ts_exit_id=$(jq -r '.ExitNodeStatus.ID // empty' <<<"$ts_json")
if [[ -n "$ts_exit_id" ]]; then
exit_name=$(jq -r --arg id "$ts_exit_id" '[.Peer[] | select(.ID == $id) | .HostName][0] // "exit"' <<<"$ts_json")
vpn_names+=("$exit_name")
tooltip_parts+=("ts: $ts_self $ts_ip$exit_name")
else
tooltip_parts+=("ts: $ts_self $ts_ip")
fi
fi
fi
# build text
text="$icon"
[[ -n "$net_text" ]] && text+=" $net_text"
if [[ ${#vpn_names[@]} -gt 0 ]]; then
text+=" [$(IFS=,; echo "${vpn_names[*]}")]"
fi
tooltip=$(printf '%s\n' "${tooltip_parts[@]}")
jq -nc --arg text "$text" --arg class "$class" --arg tooltip "$tooltip" \
'{$text,$class,$tooltip}'

21
waybar/scripts/ssh-session.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
# detect remote ssh sessions and optionally disconnect them
# outputs waybar JSON; empty when no remote sessions
if [[ "$1" == "disconnect" ]]; then
pkill -HUP -f 'sshd-session:.*@' 2>/dev/null
exit 0
fi
count=$(pgrep -cf '[s]shd-session:.*@' 2>/dev/null)
count=${count:-0}
if [[ "$count" -gt 0 ]]; then
sessions=$(who 2>/dev/null | awk '$NF ~ /\([0-9]/ {gsub(/[()]/, "", $NF); print $1 "@" $NF}')
label="session"; [[ "$count" -gt 1 ]] && label="sessions"
tooltip=${sessions:-"$count remote $label"}
tooltip=${tooltip//$'\n'/\\n}
tooltip=${tooltip//\"/\\\"}
printf '{"text": "●", "class": "active", "tooltip": "%s"}\n' "$tooltip"
fi

231
waybar/style.css Normal file
View File

@@ -0,0 +1,231 @@
/* gruvbox-material-soft-dark palette
* mapped from ghostty/themes/gruvbox-material-soft-dark
* ansi 0=#252423 1=#ea6962 2=#a9b665 3=#d8a657
* 4=#7daea3 5=#d3869b 6=#89b482 7=#d4be98
* bg=#32302f fg=#d4be98 selection=#45403d */
@define-color bg #32302f;
@define-color bg_dim #252423;
@define-color bg_sel #45403d;
@define-color fg #d4be98;
@define-color red #ea6962;
@define-color green #a9b665;
@define-color yellow #d8a657;
@define-color blue #7daea3;
@define-color magenta #d3869b;
@define-color cyan #89b482;
@define-color gray #928374;
* {
font-family: "JetBrainsMono Nerd Font";
font-size: 14px;
font-weight: bold;
}
/* bar: dark background, modules float inside */
window#waybar {
background-color: @bg_dim;
color: @fg;
min-height: 30px;
}
window#waybar.hidden {
opacity: 0.2;
}
button {
box-shadow: none;
border: none;
border-radius: 0;
}
button:hover {
background: inherit;
box-shadow: none;
}
/* workspaces */
#workspaces {
background-color: @bg;
border-radius: 8px;
margin: 3px 2px;
padding: 0;
}
#workspaces button {
padding: 0 8px;
background-color: transparent;
color: @gray;
margin: 0;
border-radius: 8px;
}
#workspaces button:hover {
background-color: @bg_sel;
color: @fg;
box-shadow: none;
}
#workspaces button.focused {
background-color: @bg_sel;
color: @fg;
box-shadow: none;
}
#workspaces button.urgent {
background-color: @red;
color: @bg_dim;
}
/* floating pill style for all modules */
#mode,
#clock,
#battery,
#cpu,
#memory,
#backlight,
#wireplumber,
#mpris,
#bluetooth,
#language,
#custom-mic,
#custom-network,
#custom-ssh,
#custom-notification,
#systemd-failed-units {
background-color: @bg;
border-radius: 8px;
color: @fg;
padding: 0 10px;
margin: 3px 2px;
}
/* center: alert zone */
#custom-ssh.active {
color: @cyan;
font-size: 18px;
padding: 0 10px;
margin-top: -2px;
margin-bottom: -2px;
}
#custom-notification.notification {
color: @yellow;
}
#custom-notification.dnd-notification {
color: @red;
}
#custom-notification.dnd-none {
color: @gray;
}
#systemd-failed-units {
color: @red;
}
/* right: media (hidden by default, visible only when playing/paused) */
#mpris {
padding: 0;
margin: 0;
min-width: 0;
background-color: transparent;
color: @green;
}
#mpris.playing {
padding: 0 10px;
margin: 3px 2px;
background-color: @bg;
}
#mpris.paused {
padding: 0 10px;
margin: 3px 2px;
background-color: @bg;
color: @gray;
}
/* right: connectivity */
#custom-network.disconnected {
color: @red;
}
#bluetooth {
color: @blue;
}
/* right: system */
#cpu {
margin-right: 0;
border-radius: 8px 0 0 8px;
}
#memory {
margin-left: 0;
border-radius: 0 8px 8px 0;
}
/* right: battery */
#battery.charging,
#battery.plugged {
color: @green;
}
#battery.warning:not(.charging) {
color: @yellow;
}
@keyframes blink {
to {
background-color: @red;
color: @bg_dim;
}
}
#battery.critical:not(.charging) {
color: @red;
animation-name: blink;
animation-duration: 0.5s;
animation-timing-function: steps(12);
animation-iteration-count: infinite;
animation-direction: alternate;
}
/* right: audio */
#wireplumber.muted {
color: @red;
}
#custom-mic.muted {
color: @red;
}
/* right: audio group (volume + mic + brightness) */
#wireplumber {
margin-right: 0;
border-radius: 8px 0 0 8px;
}
#custom-mic {
margin-left: 0;
margin-right: 0;
border-radius: 0;
}
#backlight {
margin-left: 0;
border-radius: 0 8px 8px 0;
}
/* right: clock */
#clock {
color: @fg;
}
/* mode highlight */
#mode {
color: @bg_dim;
background-color: @yellow;
padding: 0 10px;
}

View File

@@ -22,3 +22,15 @@ export NAME="Matej Janežič"
# starship nest config into a folder, default is ~/.config/starship.toml
export STARSHIP_CONFIG="$XDG_CONFIG_HOME/starship/config.toml"
# claude
export CLAUDE_CONFIG_DIR="$XDG_CONFIG_HOME/claude"
# cliphist
export CLIPHIST_DB_PATH="/tmp/cliphist-db"
# fzf
export FZF_DEFAULT_OPTS="--cycle --bind 'tab:toggle-up,btab:toggle-down' --pointer '>' --color '16' --border 'double' --ansi --highlight-line --header 'Navigate with ARROW KEYS or TAB/S-TAB. Select with ENTER.'"
# ephvm
export EPHVM_FLAKE="/home/matej/git/git.janezic.dev/janezicmatej/matej.nix"

View File

@@ -1,4 +1,5 @@
# shell options
bindkey -e # emacs line editing
unsetopt autocd # don't cd into directories by name
setopt NO_BEEP # no terminal bell
setopt AUTO_PUSHD # cd pushes to directory stack
@@ -7,6 +8,7 @@ setopt EXTENDED_GLOB # enable extended glob operators (#, ~, ^)
# history
HISTFILE="$XDG_STATE_HOME/zsh/history"
mkdir -p "${HISTFILE:h}"
HISTSIZE=10000
SAVEHIST=10000
setopt HIST_IGNORE_DUPS # skip consecutive duplicates
@@ -14,33 +16,63 @@ setopt HIST_IGNORE_SPACE # skip commands starting with space
setopt SHARE_HISTORY # share history across sessions
setopt HIST_REDUCE_BLANKS # strip extra whitespace
# plugins
local _plugins="$XDG_DATA_HOME/zsh/plugins"
local _stamp="$XDG_CACHE_HOME/zsh/plugins-updated"
local _repos=(
"https://github.com/zsh-users/zsh-completions"
"https://github.com/zsh-users/zsh-autosuggestions"
)
local _needs_update=0
# -- plugins --
# auto-cloned on first launch, auto-updated weekly in background
PLUGIN_DIR="$XDG_DATA_HOME/zsh/plugins"
_plugin_stamp="$XDG_CACHE_HOME/zsh/plugins-updated"
_plugin_needs_update=0
if [[ ! -f "$_stamp" ]] || [[ -n $_stamp(#qN.mh+168) ]]; then
mkdir -p "${_stamp:h}"
touch "$_stamp"
_needs_update=1
# check if a week (168h) has passed since last update
if [[ ! -f "$_plugin_stamp" ]] || [[ -n $_plugin_stamp(#qN.mh+168) ]]; then
mkdir -p "${_plugin_stamp:h}"
touch "$_plugin_stamp"
_plugin_needs_update=1
fi
for _repo in $_repos; do
if [[ ! -d "$_plugins/${_repo:t}" ]]; then
git clone "$_repo" "$_plugins/${_repo:t}"
elif (( _needs_update )); then
git -C "$_plugins/${_repo:t}" pull --quiet &
function ensure_plugin() {
local repo=$1 dir="$PLUGIN_DIR/${1##*/}"
# clone if missing, pull if update is due
if [[ ! -d "$dir" ]]; then
git clone --depth=1 "https://github.com/$repo.git" "$dir"
elif (( _plugin_needs_update )); then
git -C "$dir" pull --quiet &
fi
done
(( _needs_update )) && wait
fpath=("$dir" $fpath)
source "$dir/${dir##*/}.plugin.zsh" 2>/dev/null
}
fpath=("$_plugins/zsh-completions/src" $fpath)
ensure_plugin zsh-users/zsh-completions
ensure_plugin zsh-users/zsh-autosuggestions
ensure_plugin romkatv/zsh-no-ps2
(( _plugin_needs_update )) && wait
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#ffffff,bg=cyan,bold,underline"
source "$_plugins/zsh-autosuggestions/zsh-autosuggestions.zsh"
# line editing widgets
autoload -Uz up-line-or-beginning-search down-line-or-beginning-search bracketed-paste-magic
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search
zle -N bracketed-paste bracketed-paste-magic
# only use builtin widgets during paste to avoid autosuggestions conflict
zstyle ':bracketed-paste-magic' active-widgets '.self-*'
# terminal application mode for correct terminfo sequences
if (( ${+terminfo[smkx]} && ${+terminfo[rmkx]} )); then
autoload -Uz add-zle-hook-widget
function zle_application_mode_start { echoti smkx }
function zle_application_mode_stop { echoti rmkx }
add-zle-hook-widget -Uz zle-line-init zle_application_mode_start
add-zle-hook-widget -Uz zle-line-finish zle_application_mode_stop
fi
# key bindings
[[ -n "${terminfo[kcuu1]}" ]] && bindkey -- "${terminfo[kcuu1]}" up-line-or-beginning-search
[[ -n "${terminfo[kcud1]}" ]] && bindkey -- "${terminfo[kcud1]}" down-line-or-beginning-search
[[ -n "${terminfo[khome]}" ]] && bindkey -- "${terminfo[khome]}" beginning-of-line
[[ -n "${terminfo[kend]}" ]] && bindkey -- "${terminfo[kend]}" end-of-line
[[ -n "${terminfo[kdch1]}" ]] && bindkey -- "${terminfo[kdch1]}" delete-char
[[ -n "${terminfo[kcbt]}" ]] && bindkey -- "${terminfo[kcbt]}" reverse-menu-complete
bindkey -- '^[[1;5C' forward-word # ctrl+right
bindkey -- '^[[1;5D' backward-word # ctrl+left
# aliases and functions
source "$ZDOTDIR/aliases.zsh"

View File

@@ -1,9 +1,10 @@
alias z="exec zsh"
alias t=tmux_attach
alias e="bash /home/matej/git/git.janezic.dev/janezicmatej/matej.nix/scripts/ephvm-run.sh"
alias n=nvim
alias s="ssh-menu"
alias s="~/.config/bin/ssh-menu"
# docker
alias dp="docker ps --format 'table {{.Names}}\t{{.Ports}}'"
@@ -36,7 +37,7 @@ alias gcm='git checkout $(git_main_branch)'
alias gsw="git switch"
# git fetch/pull/push
alias gfa="git fetch --all --prune"
alias gfa="git fetch --all --prune --tags"
alias gl="git pull"
alias gp="git push"
alias gpf="git push --force-with-lease"

View File

@@ -26,7 +26,7 @@ function tmux_attach {
fi
if [[ -z $tmux_running ]]; then
~/.config/tmux/tmux-sessionizer ~
~/.config/tmux/scripts/tmux-sessionizer ~
else
tmux a
fi

View File

@@ -1,75 +0,0 @@
#!/usr/bin/env bash
function _ssh_menu_preview {
file=$1; shift
host=$1; shift
j=$(cat $file \
| jc --ssh-conf \
| jq -r ".[] \
| select(.host == \"$host\") \
| .jumps = (\
if (.proxyjump | type == \"array\" and length > 0) then \
(.proxyjump | join(\",\")) \
else \
\"null\" \
end \
)" \
)
user=$(jq -r '.user' <<<$j)
port=$(jq -r '.port' <<<$j)
hostname=$(jq -r '.hostname' <<<$j)
jumps=$(jq -r '.jumps' <<<$j)
echo "$(cat <<EOF
User $user
HostName $hostname\
$([[ $port != "null" ]] && echo -e "\nPort $port")\
$([[ $jumps != "null" ]] && echo -e "\nProxyJump $jumps")
command:
ssh $user@$hostname$([[ $port != "null" ]] && echo -n " -p $port")$([[ $jumps != "null" ]] && echo -n " -J $jumps")
EOF
)"
echo ""
if command -v host 2>&1 >/dev/null; then
host $hostname
echo ""
fi
ping -c 1 -W 1 $hostname &>/dev/null \
&& echo "Host is reachable!" \
|| echo "Host is not reachable!"
}
export -f _ssh_menu_preview
function ssh-menu {
selected="$(rg -N --no-heading '^Host .*' ~/.ssh \
| sed 's/Host \(.*\)/\1/' | sort \
| SHELL=$(which bash) fzf --cycle \
--bind 'tab:toggle-up,btab:toggle-down' \
--delimiter ':' \
--with-nth 2 \
--preview "_ssh_menu_preview {1} {2}" \
--preview-label "ssh config info" \
--header "Navigate with ARROW KEYS or TAB/S-TAB. Select with ENTER." \
--border "double" \
--border-label "ssh-menu" \
--ansi \
--highlight-line \
| cut -d ":" -f2
)"
if [[ -z $selected ]]; then
return
fi
ssh "$selected"
}
ssh-menu