Compare commits
10 Commits
c568fce36a
...
92b9d417fb
| Author | SHA1 | Date | |
|---|---|---|---|
| 92b9d417fb | |||
| bab7526ac9 | |||
| 42f6cc3180 | |||
| 1e02be0a39 | |||
| cbe3ff94ac | |||
| d9bebb71ac | |||
| f20f7179ef | |||
| a9e5ace080 | |||
| f66b63354a | |||
| 15b50be80b |
1
.config/hypr/hypridle.conf
Symbolic link
1
.config/hypr/hypridle.conf
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/home/lousy/git/dotfiles/.config/hypr/includes/hypridle-desktop.conf
|
||||||
@ -1,9 +1,5 @@
|
|||||||
# Autostart applications
|
# Autostart applications
|
||||||
exec-once = waybar &
|
exec-once = waybar &
|
||||||
exec-once = mako &
|
|
||||||
exec-once = wl-clipboard-history -t &
|
|
||||||
exec-once = wlogout &
|
|
||||||
exec-once = rofi-wayland &
|
|
||||||
# exec-once = hyprpaper &
|
# exec-once = hyprpaper &
|
||||||
|
|
||||||
exec-once = hypridle &
|
exec-once = hypridle &
|
||||||
|
|||||||
@ -19,6 +19,7 @@ bind = $mainMod, P, pseudo, # dwindle
|
|||||||
bind = $mainMod, J, togglesplit, # dwindle
|
bind = $mainMod, J, togglesplit, # dwindle
|
||||||
bind = $mainMod SHIFT, P, exec, ~/.config/hypr/reway.sh
|
bind = $mainMod SHIFT, P, exec, ~/.config/hypr/reway.sh
|
||||||
bind = $mainMod, L, exec, hyprlock
|
bind = $mainMod, L, exec, hyprlock
|
||||||
|
bind = $mainMod, F12, exec, killall -SIGUSR2 waybar
|
||||||
|
|
||||||
# Move focus with mainMod + arrow keys
|
# Move focus with mainMod + arrow keys
|
||||||
bind = $mainMod, left, movefocus, l
|
bind = $mainMod, left, movefocus, l
|
||||||
|
|||||||
13
.config/hypr/includes/monitors-archlaptop.conf
Normal file
13
.config/hypr/includes/monitors-archlaptop.conf
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
monitor=eDP-1,preferred,auto,1
|
||||||
|
monitor=DP-1,preferred,auto,1
|
||||||
|
|
||||||
|
workspace=10,monitor:eDP-1
|
||||||
|
workspace=1,monitor:DP-1
|
||||||
|
workspace=2,monitor:DP-1
|
||||||
|
workspace=3,monitor:DP-1
|
||||||
|
workspace=4,monitor:DP-1
|
||||||
|
workspace=5,monitor:DP-1
|
||||||
|
workspace=6,monitor:DP-1
|
||||||
|
workspace=7,monitor:DP-1
|
||||||
|
workspace=8,monitor:DP-1
|
||||||
|
workspace=9,monitor:DP-1
|
||||||
@ -1 +0,0 @@
|
|||||||
/home/lousy/git/dotfiles/local.config/rofi/remmina_profiles.py
|
|
||||||
59
.config/rofi/remmina_profiles.py
Executable file
59
.config/rofi/remmina_profiles.py
Executable file
@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
remmina_cfg = "~/.config/remmina/remmina.pref"
|
||||||
|
remmina_bin = "/usr/bin/remmina"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Modules
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Main routine
|
||||||
|
def main():
|
||||||
|
|
||||||
|
# Get the Remmina data directory path
|
||||||
|
with open(os.path.abspath(os.path.expanduser(remmina_cfg)), "r") as f:
|
||||||
|
for l in f.readlines():
|
||||||
|
m = re.match(r"\s*datadir_path\s*=\s*(.*)$", l.rstrip())
|
||||||
|
if m:
|
||||||
|
datadir_path = os.path.abspath(os.path.expanduser(m[1]))
|
||||||
|
|
||||||
|
# Parse the Remmina profiles in the directory path, extract their names
|
||||||
|
profiles = {}
|
||||||
|
for fpath in os.listdir(datadir_path):
|
||||||
|
fpath = os.path.join(datadir_path, fpath)
|
||||||
|
if os.path.isfile(fpath) and fpath.endswith(".remmina"):
|
||||||
|
try:
|
||||||
|
with open(fpath, "r") as f:
|
||||||
|
for l in f.readlines():
|
||||||
|
m = re.match(r"\s*name\s*=\s*(.*)$", l.rstrip())
|
||||||
|
if m:
|
||||||
|
profiles[m[1]] = fpath
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# If rofi passed a profile name as argument, start the corresponding profile
|
||||||
|
if len(sys.argv) > 1 and sys.argv[1] in profiles:
|
||||||
|
subprocess.Popen([remmina_bin, profiles[sys.argv[1]]],
|
||||||
|
stdin=subprocess.DEVNULL,
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
|
# Otherwise send the list of profile names to rofi
|
||||||
|
else:
|
||||||
|
for p in sorted(profiles):
|
||||||
|
print(p)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Main program
|
||||||
|
if __name__ == "__main__":
|
||||||
|
exit(main())
|
||||||
@ -17,8 +17,8 @@
|
|||||||
"pulseaudio",
|
"pulseaudio",
|
||||||
"network",
|
"network",
|
||||||
"tray",
|
"tray",
|
||||||
],
|
"custom/wlogout"
|
||||||
"hyprland/workspaces": {
|
], "hyprland/workspaces": {
|
||||||
"format": "{icon}",
|
"format": "{icon}",
|
||||||
"on-click": "activate",
|
"on-click": "activate",
|
||||||
"on-scroll-up": "hyprctl dispatch workspace e-1",
|
"on-scroll-up": "hyprctl dispatch workspace e-1",
|
||||||
@ -102,5 +102,10 @@
|
|||||||
},
|
},
|
||||||
"tray": {
|
"tray": {
|
||||||
"icon-size": 20
|
"icon-size": 20
|
||||||
|
},
|
||||||
|
"custom/wlogout": {
|
||||||
|
"format": "⏻",
|
||||||
|
"tooltip": "Logout/Shutdown",
|
||||||
|
"on-click": "wlogout"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,9 +18,9 @@
|
|||||||
"pulseaudio",
|
"pulseaudio",
|
||||||
"network",
|
"network",
|
||||||
"battery",
|
"battery",
|
||||||
"tray"
|
"tray",
|
||||||
],
|
"custom/wlogout"
|
||||||
"hyprland/workspaces": {
|
], "hyprland/workspaces": {
|
||||||
"format": "{icon}",
|
"format": "{icon}",
|
||||||
"on-click": "activate",
|
"on-click": "activate",
|
||||||
"on-scroll-up": "hyprctl dispatch workspace e-1",
|
"on-scroll-up": "hyprctl dispatch workspace e-1",
|
||||||
@ -135,5 +135,10 @@
|
|||||||
},
|
},
|
||||||
"tray": {
|
"tray": {
|
||||||
"icon-size": 20
|
"icon-size": 20
|
||||||
|
},
|
||||||
|
"custom/wlogout": {
|
||||||
|
"format": "⏻",
|
||||||
|
"tooltip": "Logout/Shutdown",
|
||||||
|
"on-click": "wlogout"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,11 +1,16 @@
|
|||||||
* {
|
* {
|
||||||
font-family: JetBrainsMono, monospace;
|
font-family: JetBrainsMono, monospace;
|
||||||
font-size: 13px;
|
font-size: 17px;
|
||||||
border: none;
|
border: none;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon, .fa, .material-icons {
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
window#waybar {
|
window#waybar {
|
||||||
background: rgba(30, 30, 46, 0.95);
|
background: rgba(30, 30, 46, 0.95);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
@ -46,3 +51,21 @@ window#waybar {
|
|||||||
#pulseaudio.muted {
|
#pulseaudio.muted {
|
||||||
color: #f9e2af;
|
color: #f9e2af;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#custom-wlogout {
|
||||||
|
background: #f38ba8;
|
||||||
|
color: #1e1e2e;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0 8px;
|
||||||
|
margin: 0 4px;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: background 0.2s, color 0.2s;
|
||||||
|
}
|
||||||
|
#custom-wlogout .icon {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
#custom-wlogout:hover, #custom-wlogout:focus {
|
||||||
|
background: #cba6f7;
|
||||||
|
color: #1e1e2e;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.18);
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"label": "Logout",
|
|
||||||
"command": "loginctl terminate-user $USER"
|
|
||||||
}
|
|
||||||
2
.local/bin/wp-vol
Normal file → Executable file
2
.local/bin/wp-vol
Normal file → Executable file
@ -8,4 +8,4 @@ VOLUME=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{printf "%d", $2 * 100}')
|
|||||||
MUTED=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ | grep -q MUTED && echo " (muted)" || echo "")
|
MUTED=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ | grep -q MUTED && echo " (muted)" || echo "")
|
||||||
|
|
||||||
# Show notification
|
# Show notification
|
||||||
notify-send -a Volume -h string:x-canonical-private-synchronous:volume -u low "Volume: $VOLUME%$MUTED"
|
notify-send -a Volume -h string:x-canonical-private-synchronous:volume -h int:value:$VOLUME -u low "Volume: $VOLUME%$MUTED"
|
||||||
|
|||||||
99
.zshrc
99
.zshrc
@ -12,6 +12,15 @@
|
|||||||
# Environment settings
|
# Environment settings
|
||||||
# =====================
|
# =====================
|
||||||
|
|
||||||
|
# Ensure ~/.local/bin is in PATH (XDG standard)
|
||||||
|
if [ -d "$HOME/.local/bin" ] && [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
|
||||||
|
export PATH="$HOME/.local/bin:$PATH"
|
||||||
|
fi
|
||||||
|
# Optionally add XDG-compliant bin dir if present
|
||||||
|
if [ -d "${XDG_DATA_HOME:-$HOME/.local/share}/bin" ] && [[ ":$PATH:" != *":${XDG_DATA_HOME:-$HOME/.local/share}/bin:"* ]]; then
|
||||||
|
export PATH="${XDG_DATA_HOME:-$HOME/.local/share}/bin:$PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
# Do Not Track for CLI tools
|
# Do Not Track for CLI tools
|
||||||
export DO_NOT_TRACK=1
|
export DO_NOT_TRACK=1
|
||||||
|
|
||||||
@ -126,8 +135,88 @@ alias gcl="git clone"
|
|||||||
alias ..="cd .."
|
alias ..="cd .."
|
||||||
alias ...="cd ../.."
|
alias ...="cd ../.."
|
||||||
|
|
||||||
# Dotfiles management
|
# =====================
|
||||||
alias dotup="cd ~/git/dotfiles && git pull && ./setup.sh"
|
# Robust keybinds for navigation and editing (support most terminals)
|
||||||
|
# =====================
|
||||||
|
|
||||||
|
# Ensure Emacs keymap is set before custom bindings so later changes don't reset them
|
||||||
|
bindkey -e
|
||||||
|
|
||||||
|
# Load terminfo module for $terminfo[] and echoti
|
||||||
|
zmodload zsh/terminfo 2>/dev/null || true
|
||||||
|
|
||||||
|
# VSCode terminal compatibility detection
|
||||||
|
export IS_VSCODE_TERM=0
|
||||||
|
if [[ "$TERM_PROGRAM" == "vscode" ]] || [[ -n "$VSCODE_IPC_HOOK_CLI" ]]; then
|
||||||
|
export IS_VSCODE_TERM=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( IS_VSCODE_TERM )); then
|
||||||
|
# VSCode terminal: use standard escape sequences for keybinds
|
||||||
|
bindkey '^[[H' beginning-of-line
|
||||||
|
bindkey '^[[F' end-of-line
|
||||||
|
bindkey '^[[2~' overwrite-mode
|
||||||
|
bindkey '^[[3~' delete-char
|
||||||
|
bindkey '^[[5~' beginning-of-buffer-or-history
|
||||||
|
bindkey '^[[6~' end-of-buffer-or-history
|
||||||
|
bindkey '^[[A' up-line-or-history
|
||||||
|
bindkey '^[[B' down-line-or-history
|
||||||
|
bindkey '^[[C' forward-char
|
||||||
|
bindkey '^[[D' backward-char
|
||||||
|
bindkey '^[[1;5D' backward-word # Ctrl+Left
|
||||||
|
bindkey '^[[1;5C' forward-word # Ctrl+Right
|
||||||
|
bindkey '^[[1;3D' backward-word # Alt+Left
|
||||||
|
bindkey '^[[1;3C' forward-word # Alt+Right
|
||||||
|
else
|
||||||
|
# Use terminfo for portability
|
||||||
|
typeset -g -A key
|
||||||
|
key[Home]="${terminfo[khome]}"
|
||||||
|
key[End]="${terminfo[kend]}"
|
||||||
|
key[Insert]="${terminfo[kich1]}"
|
||||||
|
key[Delete]="${terminfo[kdch1]}"
|
||||||
|
key[Up]="${terminfo[kcuu1]}"
|
||||||
|
key[Down]="${terminfo[kcud1]}"
|
||||||
|
key[Left]="${terminfo[kcub1]}"
|
||||||
|
key[Right]="${terminfo[kcuf1]}"
|
||||||
|
key[PageUp]="${terminfo[kpp]}"
|
||||||
|
key[PageDown]="${terminfo[knp]}"
|
||||||
|
key[Shift-Tab]="${terminfo[kcbt]}"
|
||||||
|
|
||||||
|
[[ -n "${key[Home]}" ]] && bindkey -- "${key[Home]}" beginning-of-line
|
||||||
|
[[ -n "${key[End]}" ]] && bindkey -- "${key[End]}" end-of-line
|
||||||
|
[[ -n "${key[Insert]}" ]] && bindkey -- "${key[Insert]}" overwrite-mode
|
||||||
|
[[ -n "${key[Delete]}" ]] && bindkey -- "${key[Delete]}" delete-char
|
||||||
|
[[ -n "${key[Up]}" ]] && bindkey -- "${key[Up]}" up-line-or-history
|
||||||
|
[[ -n "${key[Down]}" ]] && bindkey -- "${key[Down]}" down-line-or-history
|
||||||
|
[[ -n "${key[Left]}" ]] && bindkey -- "${key[Left]}" backward-char
|
||||||
|
[[ -n "${key[Right]}" ]] && bindkey -- "${key[Right]}" forward-char
|
||||||
|
[[ -n "${key[PageUp]}" ]] && bindkey -- "${key[PageUp]}" beginning-of-buffer-or-history
|
||||||
|
[[ -n "${key[PageDown]}" ]] && bindkey -- "${key[PageDown]}" end-of-buffer-or-history
|
||||||
|
[[ -n "${key[Shift-Tab]}" ]] && bindkey -- "${key[Shift-Tab]}" reverse-menu-complete
|
||||||
|
|
||||||
|
# Common escape sequences for Ctrl/Alt + Arrow keys (Alacritty, xterm, etc.)
|
||||||
|
bindkey '^[[1;5D' backward-word # Ctrl+Left
|
||||||
|
bindkey '^[[1;5C' forward-word # Ctrl+Right
|
||||||
|
bindkey '^[Od' backward-word # Ctrl+Left (alternate)
|
||||||
|
bindkey '^[Oc' forward-word # Ctrl+Right (alternate)
|
||||||
|
bindkey '^[[1;3D' backward-word # Alt+Left
|
||||||
|
bindkey '^[[1;3C' forward-word # Alt+Right
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Already present: Alt+b/f for word movement
|
||||||
|
# bindkey '^[b' backward-word
|
||||||
|
# bindkey '^[f' forward-word
|
||||||
|
|
||||||
|
# Optionally, Alt+Up/Down for directory navigation (custom widgets can be added)
|
||||||
|
|
||||||
|
# Ensure terminal is in application mode for terminfo keycodes
|
||||||
|
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
|
||||||
|
|
||||||
# Quick edit .zshrc
|
# Quick edit .zshrc
|
||||||
alias ezrc="nvim ~/.zshrc"
|
alias ezrc="nvim ~/.zshrc"
|
||||||
@ -173,10 +262,8 @@ autoload -Uz compinit && compinit
|
|||||||
# Keybinds (Navigation, Editing, FZF, Completion)
|
# Keybinds (Navigation, Editing, FZF, Completion)
|
||||||
# =====================
|
# =====================
|
||||||
|
|
||||||
# Emacs mode by default (comment out for vi mode)
|
# Emacs/vi mode selection handled earlier to avoid resetting custom binds
|
||||||
bindkey -e
|
# bindkey -v # Uncomment to use vi mode instead
|
||||||
# Uncomment below for vi mode
|
|
||||||
# bindkey -v
|
|
||||||
|
|
||||||
# History search
|
# History search
|
||||||
bindkey '^R' fzf-history-widget # fzf history search (fzf-tab)
|
bindkey '^R' fzf-history-widget # fzf history search (fzf-tab)
|
||||||
|
|||||||
@ -1,5 +1,14 @@
|
|||||||
# AGENTS.md — Agentic Coding Guide for Dotfiles
|
# AGENTS.md — Agentic Coding Guide for Dotfiles
|
||||||
|
|
||||||
|
**🚨 ABSOLUTE AGENT SAFETY RULES — DO NOT IGNORE 🚨**
|
||||||
|
|
||||||
|
- Agents MUST NEVER run any scripts in this repo automatically.
|
||||||
|
- Agents MUST NEVER modify, symlink, or touch files outside of the repo root or its subdirectories.
|
||||||
|
- NO file operations or script executions unless the user gives direct, explicit permission for each action.
|
||||||
|
- All actions must be idempotent, explicit, and user-approved.
|
||||||
|
- Violating these rules risks breaking the user’s system and is strictly forbidden.
|
||||||
|
|
||||||
|
|
||||||
## Setup, Lint, and Test
|
## Setup, Lint, and Test
|
||||||
- Main entrypoint: `./setup.sh` (runs all `modules/*.sh` in order)
|
- Main entrypoint: `./setup.sh` (runs all `modules/*.sh` in order)
|
||||||
- To re-run a single module: `bash modules/XX-name.sh`
|
- To re-run a single module: `bash modules/XX-name.sh`
|
||||||
|
|||||||
52
README.md
52
README.md
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
This repository manages your personal dotfiles and a modular, Wayland-ready desktop environment for Arch Linux using `paru`.
|
This repository manages your personal dotfiles and a modular, Wayland-ready desktop environment for Arch Linux using `paru`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- Modular setup: each aspect (packages, symlinks, shell, Neovim, Hyprland, sound, browsers, devtools, etc.) is handled by its own script in `modules/`.
|
- Modular setup: each aspect (packages, symlinks, shell, Neovim, Hyprland, sound, browsers, devtools, etc.) is handled by its own script in `modules/`.
|
||||||
- All dotfiles and app configs are version-controlled and symlinked to your home directory.
|
- All dotfiles and app configs are version-controlled and symlinked to your home directory.
|
||||||
|
- Device-aware: uses `$DOTFILES_DEVICE` and `$HOSTNAME` to select device-specific config fragments (e.g., laptop/desktop, monitor layouts).
|
||||||
- Out-of-the-box integration for Hyprland, Waybar, Rofi, Mako, Alacritty, wlogout, and more.
|
- Out-of-the-box integration for Hyprland, Waybar, Rofi, Mako, Alacritty, wlogout, and more.
|
||||||
- Modern sound stack (PipeWire, WirePlumber, pavucontrol, etc.).
|
- Modern sound stack (PipeWire, WirePlumber, pavucontrol, etc.).
|
||||||
- Volume notifications: see current volume as a Mako popup at the bottom center when changed.
|
- Volume notifications: see current volume as a Mako popup at the bottom center when changed.
|
||||||
@ -13,7 +15,9 @@ This repository manages your personal dotfiles and a modular, Wayland-ready desk
|
|||||||
- Brave browser always launches on workspace 10 and autostarts with Hyprland.
|
- Brave browser always launches on workspace 10 and autostarts with Hyprland.
|
||||||
- TTY/console uses German nodeadkeys layout (`de-latin1-nodeadkeys`).
|
- TTY/console uses German nodeadkeys layout (`de-latin1-nodeadkeys`).
|
||||||
- Devtools module installs git, Python, Node.js, Docker, VS Code, opencode-bin, and more.
|
- Devtools module installs git, Python, Node.js, Docker, VS Code, opencode-bin, and more.
|
||||||
- Easily extensible: add new modules or configs as needed.
|
- Easily extensible: add new modules, fragments, or configs as needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
@ -27,30 +31,64 @@ This repository manages your personal dotfiles and a modular, Wayland-ready desk
|
|||||||
./setup.sh
|
./setup.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
When you run `setup.sh`, you will be prompted to select your device profile (`laptop` or `desktop`).
|
When you run `setup.sh`, your device profile is detected via `host-profiles.conf` (mapping `$HOSTNAME` to `$DOTFILES_DEVICE`, e.g., `laptop` or `desktop`).
|
||||||
This ensures that device-specific configs (e.g., battery, backlight, touchpad, monitor layout) are applied correctly for your hardware.
|
This ensures that device-specific configs (battery, backlight, touchpad, monitor layout, etc.) are applied correctly for your hardware.
|
||||||
You can also set the environment variable `DOTFILES_DEVICE` to skip the prompt:
|
You can also set the environment variable manually to override:
|
||||||
```sh
|
```sh
|
||||||
DOTFILES_DEVICE=desktop ./setup.sh
|
DOTFILES_DEVICE=desktop ./setup.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
The script will install all required packages and symlink dotfiles and configs (including everything in `.config/`) to your home directory, using the correct device-specific fragments for Hyprland and Waybar.
|
The script will install all required packages and symlink dotfiles and configs (including everything in `.config/`) to your home directory, using the correct device-specific fragments for Hyprland, Waybar, and more.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Customization
|
## Customization & Extending
|
||||||
- Add new dotfiles to the repo root (e.g., `.zshrc`, `.tmux.conf`).
|
- Add new dotfiles to the repo root (e.g., `.zshrc`, `.tmux.conf`).
|
||||||
- Place app configs in `.config/` (e.g., `.config/hypr/hyprland.conf`).
|
- Place app configs in `.config/` (e.g., `.config/hypr/hyprland.conf`).
|
||||||
- Add or edit modules in the `modules/` directory to automate more setup steps.
|
- Add or edit modules in the `modules/` directory to automate more setup steps.
|
||||||
- To add custom scripts, place them in `.local/bin/` in the repo; they will be symlinked to `~/.local/bin/`.
|
- To add custom scripts, place them in `.local/bin/` in the repo; they will be symlinked to `~/.local/bin/`.
|
||||||
- To add browsers, edit `modules/06-browsers.sh` (Chrome, Firefox, Brave supported out of the box).
|
- To add browsers, edit `modules/06-browsers.sh` (Chrome, Firefox, Brave supported out of the box).
|
||||||
- To add devtools, edit `modules/50-devtools.sh` (includes VS Code, opencode-bin, lazygit, etc.).
|
- To add devtools, edit `modules/50-devtools.sh` (includes VS Code, opencode-bin, lazygit, etc.).
|
||||||
|
- To add new device types (e.g., tablet, server), update `host-profiles.conf` and add corresponding config fragments (e.g., `hypridle-tablet.conf`).
|
||||||
|
- To add new fragment types, extend the `fragment_types` array in `modules/02-symlinks.sh`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
- Arch Linux
|
- Arch Linux
|
||||||
- [paru](https://github.com/Morganamilo/paru) (will be installed automatically if missing)
|
- [paru](https://github.com/Morganamilo/paru) (will be installed automatically if missing)
|
||||||
- For TTY keymap: `kbd` package (should be present on most systems)
|
- For TTY keymap: `kbd` package (should be present on most systems)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Reference: Main Modules
|
||||||
|
| Module | Purpose |
|
||||||
|
|-----------------------|-----------------------------------------|
|
||||||
|
| 01-packages.sh | Base packages (shell, tools, etc.) |
|
||||||
|
| 02-symlinks.sh | Symlinks dotfiles/configs, device-aware |
|
||||||
|
| 03-shell.sh | Shell setup (Zsh, keymap) |
|
||||||
|
| 04-nvim.sh | Neovim (AstroNvim) setup |
|
||||||
|
| 05-sound.sh | Sound stack (PipeWire, etc.) |
|
||||||
|
| 06-hyprland.sh | Hyprland, Waybar, Rofi, etc. |
|
||||||
|
| 07-browsers.sh | Browsers (Chrome, Firefox, Brave) |
|
||||||
|
| 50-devtools.sh | Devtools (git, VS Code, etc.) |
|
||||||
|
| 99-postinstall.sh | Post-install steps |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
- **Missing device-specific fragment:** If you see a warning about a missing fragment (e.g., `hypridle-laptop.conf`), create the file in `.config/hypr/includes/` or update your `host-profiles.conf` mapping.
|
||||||
|
- **Symlink warnings:** If a non-empty directory exists where a symlink should be, the script will warn and skip removal for safety. Manually back up and remove if needed.
|
||||||
|
- **Package install errors:** Ensure your Arch system is up to date and AUR is reachable. Rerun `setup.sh` after fixing network or package issues.
|
||||||
|
- **Updating dotfiles:** Pull the latest changes and re-run `./setup.sh` to sync configs and packages.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Safety & Idempotence
|
||||||
|
- All scripts are safe to re-run and will not overwrite user files unintentionally.
|
||||||
|
- Symlinking logic only removes symlinks or empty directories; non-empty directories are preserved with a warning.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Notable Integrations & Tips
|
## Notable Integrations & Tips
|
||||||
- **Browsers:** Chrome, Firefox, and Brave are installed via the browser module. Brave autostarts and is always on workspace 10.
|
- **Browsers:** Chrome, Firefox, and Brave are installed via the browser module. Brave autostarts and is always on workspace 10.
|
||||||
@ -61,5 +99,7 @@ The script will install all required packages and symlink dotfiles and configs (
|
|||||||
- **No official Teams/Outlook client:** Use the web app or AUR wrappers for best compatibility.
|
- **No official Teams/Outlook client:** Use the web app or AUR wrappers for best compatibility.
|
||||||
- **TortoiseGit alternative:** Use GitKraken, Sublime Merge, SmartGit, or lazygit for graphical Git workflows.
|
- **TortoiseGit alternative:** Use GitKraken, Sublime Merge, SmartGit, or lazygit for graphical Git workflows.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## License
|
## License
|
||||||
MIT
|
MIT
|
||||||
|
|||||||
3
host-profiles.conf
Normal file
3
host-profiles.conf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Map hostnames to device profiles
|
||||||
|
lousy-arch=desktop
|
||||||
|
archlaptop=laptop
|
||||||
@ -1,5 +1,13 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Ensure required directories exist
|
# =====================
|
||||||
|
# Dotfiles Symlinking Script
|
||||||
|
# =====================
|
||||||
|
# - Symlinks all dotfiles and app configs from the repo to $HOME and $HOME/.config
|
||||||
|
# - Handles device-specific fragments for Hyprland, Waybar, etc. using $DOTFILES_DEVICE and $HOSTNAME
|
||||||
|
# - Idempotent and safe to re-run
|
||||||
|
# - To extend, add new fragment types to the fragment_types array below
|
||||||
|
# =====================
|
||||||
|
|
||||||
mkdir -p "$HOME/.config"
|
mkdir -p "$HOME/.config"
|
||||||
|
|
||||||
echo "Symlinking dotfiles..."
|
echo "Symlinking dotfiles..."
|
||||||
@ -23,40 +31,76 @@ done
|
|||||||
# Symlink .config directory contents
|
# Symlink .config directory contents
|
||||||
CONFIG_DIR="$DOTFILES_DIR/.config"
|
CONFIG_DIR="$DOTFILES_DIR/.config"
|
||||||
if [ -d "$CONFIG_DIR" ]; then
|
if [ -d "$CONFIG_DIR" ]; then
|
||||||
echo "Symlinking .config contents..."
|
echo "Symlinking .config contents (files only, recursive)..."
|
||||||
for item in "$CONFIG_DIR"/*; do
|
find "$CONFIG_DIR" -type f | while read -r srcfile; do
|
||||||
[ -e "$item" ] || continue
|
# Get relative path from $CONFIG_DIR
|
||||||
baseitem="$(basename "$item")"
|
relpath="${srcfile#$CONFIG_DIR/}"
|
||||||
target_dir="$HOME/.config/$baseitem"
|
targetfile="$HOME/.config/$relpath"
|
||||||
|
targetdir="$(dirname "$targetfile")"
|
||||||
# Remove existing symlink or directory to avoid conflicts
|
# If targetdir is a symlink, remove it first
|
||||||
[ -L "$target_dir" ] && rm "$target_dir"
|
[ -L "$targetdir" ] && rm "$targetdir"
|
||||||
[ -d "$target_dir" ] && [ ! -L "$target_dir" ] && rm -rf "$target_dir"
|
mkdir -p "$targetdir"
|
||||||
|
# Remove existing file/symlink at target
|
||||||
ln -sf "$item" "$target_dir"
|
[ -L "$targetfile" ] && rm "$targetfile"
|
||||||
echo "Linked .config/$baseitem"
|
[ -f "$targetfile" ] && rm "$targetfile"
|
||||||
|
ln -sf "$srcfile" "$targetfile"
|
||||||
|
echo "Linked $srcfile -> $targetfile"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# =====================
|
||||||
# Device-specific symlinks for Hyprland and Waybar
|
# Device-specific symlinks for Hyprland and Waybar
|
||||||
if [ -n "$DOTFILES_DEVICE" ]; then
|
# =====================
|
||||||
# Hyprland monitors (hostname-based)
|
# This section handles device-specific config fragments for Hyprland, Waybar, etc.
|
||||||
|
# Uses $DOTFILES_DEVICE (set by setup.sh) and $HOSTNAME for profile-specific fragments.
|
||||||
|
# To add new device types (e.g., tablet, server), update host-profiles.conf and add fragments.
|
||||||
|
# To add new fragment types, extend the fragment_types array below.
|
||||||
|
# Format: "source_fragment_path:target_symlink_path"
|
||||||
|
# Example: fragment_types=(
|
||||||
|
# "hypr/includes/monitors-$HOSTNAME.conf:hypr/includes/monitors.conf"
|
||||||
|
# "hypr/includes/hypridle-$DOTFILES_DEVICE.conf:hypr/hypridle.conf"
|
||||||
|
# "waybar/config-$DOTFILES_DEVICE:waybar/config"
|
||||||
|
# )
|
||||||
|
|
||||||
|
if [ -z "$DOTFILES_DEVICE" ]; then
|
||||||
|
echo "ERROR: DOTFILES_DEVICE environment variable not set. Run setup.sh to detect device profile."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
HOSTNAME=$(hostname)
|
HOSTNAME=$(hostname)
|
||||||
if [ -f "$CONFIG_DIR/hypr/includes/monitors-$HOSTNAME.conf" ]; then
|
|
||||||
ln -sf "$CONFIG_DIR/hypr/includes/monitors-$HOSTNAME.conf" "$CONFIG_DIR/hypr/includes/monitors.conf"
|
# Device-specific fragments to symlink (source:target)
|
||||||
echo "Linked monitors-$HOSTNAME.conf as monitors.conf"
|
fragment_types=(
|
||||||
|
"hypr/includes/monitors-$HOSTNAME.conf:hypr/includes/monitors.conf" # Monitor layout per host
|
||||||
|
"hypr/includes/hypridle-$DOTFILES_DEVICE.conf:hypr/hypridle.conf" # Idle config per device type
|
||||||
|
"waybar/config-$DOTFILES_DEVICE:waybar/config" # Waybar config per device type
|
||||||
|
)
|
||||||
|
|
||||||
|
# Symlink each device-specific fragment
|
||||||
|
for fragment in "${fragment_types[@]}"; do
|
||||||
|
src="${CONFIG_DIR}/${fragment%%:*}"
|
||||||
|
tgt_rel="${fragment##*:}"
|
||||||
|
tgt="$HOME/.config/$tgt_rel"
|
||||||
|
tgt_dir="$(dirname "$tgt")"
|
||||||
|
mkdir -p "$tgt_dir"
|
||||||
|
if [ -f "$src" ]; then
|
||||||
|
# Remove existing file/symlink at target
|
||||||
|
[ -L "$tgt" ] && rm "$tgt"
|
||||||
|
[ -f "$tgt" ] && rm "$tgt"
|
||||||
|
ln -sf "$src" "$tgt"
|
||||||
|
echo "Linked $src -> $tgt"
|
||||||
else
|
else
|
||||||
echo "Warning: No monitors config for hostname $HOSTNAME"
|
echo "Warning: Device-specific fragment missing: $src"
|
||||||
fi
|
# To troubleshoot, ensure the fragment exists for your device/host
|
||||||
# Hyprland hypridle
|
|
||||||
ln -sf "$CONFIG_DIR/hypr/includes/hypridle-$DOTFILES_DEVICE.conf" "$CONFIG_DIR/hypr/hypridle.conf"
|
|
||||||
echo "Linked hypridle-$DOTFILES_DEVICE.conf as hypridle.conf"
|
|
||||||
# Waybar config
|
|
||||||
ln -sf "$CONFIG_DIR/waybar/config-$DOTFILES_DEVICE" "$CONFIG_DIR/waybar/config"
|
|
||||||
echo "Linked config-$DOTFILES_DEVICE as waybar config"
|
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
# =====================
|
||||||
|
# End device-specific symlinking
|
||||||
|
# =====================
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Dotfiles setup complete!"
|
echo "====================="
|
||||||
|
echo "Dotfiles symlinking complete!"
|
||||||
|
echo "====================="
|
||||||
|
|
||||||
# Symlink .local/bin scripts
|
# Symlink .local/bin scripts
|
||||||
LOCAL_BIN_REPO="$DOTFILES_DIR/.local/bin"
|
LOCAL_BIN_REPO="$DOTFILES_DIR/.local/bin"
|
||||||
|
|||||||
@ -11,11 +11,14 @@ HYPR_PACKAGES=(
|
|||||||
mako
|
mako
|
||||||
wl-clipboard
|
wl-clipboard
|
||||||
wlogout
|
wlogout
|
||||||
|
network-manager-applet
|
||||||
brightnessctl
|
brightnessctl
|
||||||
alacritty
|
alacritty
|
||||||
|
ttf-jetbrains-mono-nerd
|
||||||
ttf-jetbrains-mono
|
ttf-jetbrains-mono
|
||||||
ttf-nerd-fonts-symbols
|
ttf-nerd-fonts-symbols
|
||||||
noto-fonts
|
noto-fonts
|
||||||
|
noto-fonts-emoji
|
||||||
)
|
)
|
||||||
|
|
||||||
paru -S --needed --noconfirm "${HYPR_PACKAGES[@]}"
|
paru -S --needed --noconfirm "${HYPR_PACKAGES[@]}"
|
||||||
|
|||||||
@ -14,7 +14,7 @@ DEVTOOLS_PACKAGES=(
|
|||||||
htop
|
htop
|
||||||
lazygit
|
lazygit
|
||||||
visual-studio-code-bin
|
visual-studio-code-bin
|
||||||
opencode-bin
|
opencode
|
||||||
)
|
)
|
||||||
|
|
||||||
paru -S --needed --noconfirm "${DEVTOOLS_PACKAGES[@]}"
|
paru -S --needed --noconfirm "${DEVTOOLS_PACKAGES[@]}"
|
||||||
|
|||||||
23
setup.sh
23
setup.sh
@ -6,18 +6,19 @@ set -e
|
|||||||
# Dotfiles setup script for Arch Linux using paru
|
# Dotfiles setup script for Arch Linux using paru
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Device profile detection
|
# Device profile detection (unified via host-profiles.conf)
|
||||||
if [ -z "$DOTFILES_DEVICE" ]; then
|
HOSTNAME=$(hostname)
|
||||||
echo "Select device profile:"
|
DOTFILES_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
select profile in "laptop" "desktop"; do
|
DOTFILES_DEVICE=""
|
||||||
DOTFILES_DEVICE="$profile"
|
if [ -f "$DOTFILES_DIR/host-profiles.conf" ]; then
|
||||||
export DOTFILES_DEVICE
|
DOTFILES_DEVICE=$(awk -F= -v h="$HOSTNAME" '$1==h{print $2}' "$DOTFILES_DIR/host-profiles.conf")
|
||||||
echo "Using device profile: $DOTFILES_DEVICE"
|
|
||||||
break
|
|
||||||
done
|
|
||||||
else
|
|
||||||
echo "Using device profile from environment: $DOTFILES_DEVICE"
|
|
||||||
fi
|
fi
|
||||||
|
if [ -z "$DOTFILES_DEVICE" ]; then
|
||||||
|
echo "ERROR: No device profile mapping found for hostname '$HOSTNAME' in $DOTFILES_DIR/host-profiles.conf"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
export DOTFILES_DEVICE
|
||||||
|
echo "Using device profile: $DOTFILES_DEVICE"
|
||||||
|
|
||||||
# Find, sort, and run all modules in the modules directory
|
# Find, sort, and run all modules in the modules directory
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user