diff --git a/.gitignore b/.gitignore index e69de29..9f11b75 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/README.md b/README.md index cb91c5d..e5923c5 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ ## Installation -Run the `install.sh` script to install neovim, zsh (via oh-my-zsh) and all of the omz plugins. +```bash +pacman -S ansible-tools +ansible-galaxy install -r requirements.yml +ansible-playbook playbook.yml --ask-become-pass +``` -## nvim - --- TODO -- - -- Install nerdfont +- Install nerdfont -- TODO ## zsh diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..bf7b4a3 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,4 @@ +[default] +inventory = inventory +stdout_callback = yaml +host_key_checking = False diff --git a/group_vars/all.yml b/group_vars/all.yml new file mode 100644 index 0000000..951714d --- /dev/null +++ b/group_vars/all.yml @@ -0,0 +1,70 @@ +default_roles: + # === Core System Tools (Recommended) === + - system # Essential system configurations and tools + # - fonts # Developer-friendly fonts (Nerd Fonts) + + # === Development Core === + # - git # Version control system + - nvim # Modern text editor (or use 'vim') + # - tmux # Terminal multiplexer for session management + - zsh # Modern shell with oh-my-zsh + # - ssh + - hyprland + - ghostty + +temp: + - docker # Container platform + +system_packages: + # Network + - curl + - wget + - rsync + - nmap + + # archive/compression + - unzip + - tar + + # text processing + - jq + - ripgrep + - fd + + # utilities + - btop + - which + # - fzf + - bat + - eza + - tealdeer + - neofetch + + # dev + - nvm + - go + - discord # Team communication + + # Window manager + - hyprland + - waybar + - wofi + - hyprshot + - dunst + - hyprpaper + + # desktop + - thunar + - imv + + +# TODO +aur_packages: + - autojump + - spotify + - qownnotes + - stripe-cli + - pgformatter-git + # - jetbrains-toolbox + +config_dir: "{{ ansible_facts.env.HOME }}/.config" diff --git a/install.sh b/install.sh index 643332d..f48f7e2 100755 --- a/install.sh +++ b/install.sh @@ -1,48 +1,38 @@ #!/bin/bash -command_exists() { - command -v "$1" >/dev/null 2>&1 +set -e + +DOTFILES_DIR="$HOME/dotfiles" + + +function arch_setup() { + if ! [ -x "$(which ansible)" ]; then + echo "Installing ansible" + sudo pacman -S ansible + fi } -create_symlink() { - local source=$1 - local target=$2 - - if [ ! -e "$target" ]; then - ln -s "$source" "$target" - echo "Added symlink $source -> $target" - fi + +function detect_os() { + source /etc/os-release + echo "$ID" } -install_package() { - local package=$1 - if ! command_exists "$package"; then - # sudo dnf update && sudo dnf install "$package" - sudo pacman -S "$package" - fi -} +local_os=$(detect_os) -install_package "neovim" -create_symlink "$HOME/dotfiles/nvim" "$HOME/.config/nvim" +case $local_os in + cachyos|arch) + arch_setup + ;; + debian) + debian_setup + ;; + fedora) + fedora_setup + ;; + *) + echo "OS $local_os not supported" + exit 1 +esac -install_package "zsh" -create_symlink "$HOME/dotfiles/zsh/.zshrc" "$HOME/.zshrc" - -if [ ! -d "$HOME/.oh-my-zsh" ]; then - sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" -fi - -ZSH_CUSTOM=${ZSH_CUSTOM:-~/.oh-my-zsh/custom} - -# Install zsh-syntax-highlighting -if [ ! -d "${ZSH_CUSTOM}/plugins/zsh-syntax-highlighting" ]; then - git clone --depth 1 https://github.com/zsh-users/zsh-syntax-highlighting.git \ - ${ZSH_CUSTOM}/plugins/zsh-syntax-highlighting -fi - - -# Install zsh-syntax-highlighting -if [ ! -d "${ZSH_CUSTOM}/plugins/fzf-zsh-plugin" ]; then - git clone --depth 1 https://github.com/unixorn/fzf-zsh-plugin.git \ - ${ZSH_CUSTOM}/plugins/fzf-zsh-plugin -fi +ansible-playbook "$DOTFILES_DIR/playbook.yml" "$@" \ No newline at end of file diff --git a/inventory b/inventory new file mode 100644 index 0000000..fe31dc2 --- /dev/null +++ b/inventory @@ -0,0 +1,2 @@ +[local] +localhost ansible_connection=local ansible_user=johannes diff --git a/playbook.yml b/playbook.yml new file mode 100644 index 0000000..da49a69 --- /dev/null +++ b/playbook.yml @@ -0,0 +1,28 @@ +--- +- name: Setup dotfiles configuration + hosts: localhost + connection: local + become: false + vars: + dotfiles_dir: "{{ ansible_env.HOME }}/dotfiles" + # roles: + # - zsh + + pre_tasks: + - name: Create btrfs snapshot before changes + shell: | + sudo btrfs subvolume snapsho / /.snapshots/before-dotfiles-$(date +%Y%m%d-%H%M%S) + tags: [snapshot] + become: true + become_method: sudo + + tasks: + - name: Install enabled roles + ansible.builtin.include_role: + name: "{{ item }}" + apply: + tags: + - install + loop: + "{{ default_roles }}" + # when: default_roles is defined diff --git a/requirements.yml b/requirements.yml new file mode 100644 index 0000000..a937e53 --- /dev/null +++ b/requirements.yml @@ -0,0 +1,4 @@ +--- +collections: + - community.general + - kewlfft.aur diff --git a/roles/ghostty/files/config b/roles/ghostty/files/config new file mode 100644 index 0000000..c26140e --- /dev/null +++ b/roles/ghostty/files/config @@ -0,0 +1,29 @@ +shell-integration = zsh +shell-integration-features = cursor,sudo,title + +font-family = "RobotoMono Nerd Font Mono" + +# Monokai Pro +# Based on Monokai Pro color scheme, made by Monokai. https://monokai.pro/ +window-colorspace = srgb +palette = 0=2d2a2e +palette = 1=ff6188 +palette = 2=a9dc76 +palette = 3=ffd866 +palette = 4=fc9867 +palette = 5=ab9df2 +palette = 6=78dce8 +palette = 7=fcfcfa +palette = 8=727072 +palette = 9=ff6188 +palette = 10=a9dc76 +palette = 11=ffd866 +palette = 12=fc9867 +palette = 13=ab9df2 +palette = 14=78dce8 +palette = 15=fcfcfa +background = 2d2a2e +foreground = fcfcfa +cursor-color = c1c0c0 +selection-background = 5b595c +selection-foreground = fcfcfa diff --git a/roles/ghostty/tasks/main.yml b/roles/ghostty/tasks/main.yml new file mode 100644 index 0000000..1654e7e --- /dev/null +++ b/roles/ghostty/tasks/main.yml @@ -0,0 +1,7 @@ +--- +- name: Symlink ghostty config + file: + src: "{{ role_path }}/files" + dest: "{{ config_dir }}/ghostty" + state: link + force: true diff --git a/roles/hyprland/files/dunst/dunstrc b/roles/hyprland/files/dunst/dunstrc new file mode 100644 index 0000000..fcfb2f4 --- /dev/null +++ b/roles/hyprland/files/dunst/dunstrc @@ -0,0 +1,76 @@ +[global] + monitor = 0 + follow = mouse + width = 300 + height = 300 + origin = top-right + offset = 10x50 + scale = 0 + notification_limit = 0 + + progress_bar = true + progress_bar_height = 10 + progress_bar_frame_width = 1 + progress_bar_min_width = 150 + progress_bar_max_width = 300 + + indicate_hidden = yes + transparency = 0 + separator_height = 2 + padding = 8 + horizontal_padding = 8 + text_icon_padding = 0 + frame_width = 2 + frame_color = "#89b4fa" + separator_color = frame + sort = yes + + font = JetBrains Mono 10 + line_height = 0 + markup = full + format = "%s\n%b" + alignment = left + vertical_alignment = center + show_age_threshold = 60 + ellipsize = middle + ignore_newline = no + stack_duplicates = true + hide_duplicate_count = false + show_indicators = yes + + icon_position = left + min_icon_size = 0 + max_icon_size = 32 + + dmenu = /usr/bin/dmenu -p dunst: + browser = /usr/bin/xdg-open + always_run_script = true + title = Dunst + class = Dunst + corner_radius = 8 + ignore_dbusclose = false + force_xwayland = false + force_xinerama = false + mouse_left_click = close_current + mouse_middle_click = do_action, close_current + mouse_right_click = close_all + +[experimental] + per_monitor_dpi = false + +[urgency_low] + background = "#1e1e2e" + foreground = "#cdd6f4" + timeout = 10 + +[urgency_normal] + background = "#1e1e2e" + foreground = "#cdd6f4" + timeout = 10 + +[urgency_critical] + background = "#1e1e2e" + foreground = "#f38ba8" + frame_color = "#f38ba8" + timeout = 0 + diff --git a/roles/hyprland/files/hypr/hyprland.conf b/roles/hyprland/files/hypr/hyprland.conf new file mode 100644 index 0000000..92ab65e --- /dev/null +++ b/roles/hyprland/files/hypr/hyprland.conf @@ -0,0 +1,307 @@ +################ +### MONITORS ### +################ + +# See https://wiki.hypr.land/Configuring/Monitors/ +monitor=,preferred,auto,auto +source = ./monitors.conf +source = ./workspaces.conf + +################### +### MY PROGRAMS ### +################### + +# See https://wiki.hypr.land/Configuring/Keywords/ + +$terminal = ghostty +$fileManager = thunar +$menu = wofi --show drun + +################# +### AUTOSTART ### +################# + +# Autostart necessary processes (like notifications daemons, status bars, etc.) +# Or execute your favorite apps at launch like this: +exec-once = waybar +exec-once = dunst +exec-once = firefox +exec-once = hyprpaper +exec-once = spotify + +############################# +### ENVIRONMENT VARIABLES ### +############################# + +# See https://wiki.hypr.land/Configuring/Environment-variables/ +env = XCURSOR_SIZE,24 +env = HYPRCURSOR_SIZE,24 +env = QT_QPA_PLATFORM,waylandl;xcb +env = QT_QPA_PLATFORMTHEME,qt5ct + +env = XDG_CURRENT_DESKTOP,Hyprland +env = XDG_SESSION_TYPE,wayland +env = WLR_NO_HARDWARE_CURSORS,1 +env = CLUTTER_BACKEND,wayland +env = SDL_VIDEODRIVER,wayland,x11 +env = GDK_BACKEND,wayland,x11 + +# jetbrains +env = _JAVA_AWT_WM_NONREPARENTING, 1 +# env = AWT_TOOLKIT, MToolkit + +################### +### PERMISSIONS ### +################### + +# See https://wiki.hypr.land/Configuring/Permissions/ +# Please note permission changes here require a Hyprland restart and are not applied on-the-fly +# for security reasons + +# ecosystem { +# enforce_permissions = 1 +# } + +# permission = /usr/(bin|local/bin)/grim, screencopy, allow +# permission = /usr/(lib|libexec|lib64)/xdg-desktop-portal-hyprland, screencopy, allow +# permission = /usr/(bin|local/bin)/hyprpm, plugin, allow + + +##################### +### LOOK AND FEEL ### +##################### + +# https://wiki.hypr.land/Configuring/Variables/#general +general { + gaps_in = 5 + gaps_out = 20 + + border_size = 2 + + # https://wiki.hypr.land/Configuring/Variables/#variable-types for info about colors + col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg + col.inactive_border = rgba(595959aa) + # Active: cosmic purple -> neon cyan gradient + # col.active_border = rgba(7f5af0ee) rgba(00d1ffee) 45deg + # + # # Inactive: deep space slate + # col.inactive_border = rgba(0c0e14aa) + + # Set to true enable resizing windows by clicking and dragging on borders and gaps + resize_on_border = false + + # Please see https://wiki.hypr.land/Configuring/Tearing/ before you turn this on + allow_tearing = false + + layout = dwindle +} + + +# --- Decorations / cosmic glass --- +decoration { + rounding = 12 + active_opacity = 1.0 + inactive_opacity = 0.96 + fullscreen_opacity = 1.0 + + # Shadows (new nested syntax) + shadow { + enabled = true + range = 20 # size of the shadow + render_power = 3 # 1–4, higher = faster falloff + color = rgba(0, 0, 0, 0.35) + offset = 0 6 # optional: drop slightly downward + scale = 1.0 + } + + # Blur (nested) + blur { + enabled = true + size = 8 + passes = 3 + new_optimizations = true + noise = 0.02 + contrast = 1.00 + brightness = 1.00 + vibrancy = 0.18 + xray = true + } +} + +# wofi +layerrule = blur, wofi # apply compositor blur +layerrule = ignorezero, wofi # keep blur even on near-opaque colors +layerrule = dimaround, wofi # optional: dim background behind wofi +layerrule = ignorealpha 0.90, wofi # target overall opacity for the layer + +# waybar +layerrule = blur, waybar +layerrule = ignorealpha 0.15, waybar + +# https://wiki.hypr.land/Configuring/Variables/#animations +animations { + enabled = yes, please :) + + # Default animations, see https://wiki.hypr.land/Configuring/Animations/ for more + + bezier = easeOutQuint,0.23,1,0.32,1 + bezier = easeInOutCubic,0.65,0.05,0.36,1 + bezier = linear,0,0,1,1 + bezier = almostLinear,0.5,0.5,0.75,1.0 + bezier = quick,0.15,0,0.1,1 + + animation = global, 1, 10, default + animation = border, 1, 5.39, easeOutQuint + animation = windows, 1, 4.79, easeOutQuint + animation = windowsIn, 1, 4.1, easeOutQuint, popin 87% + animation = windowsOut, 1, 1.49, linear, popin 87% + animation = fadeIn, 1, 1.73, almostLinear + animation = fadeOut, 1, 1.46, almostLinear + animation = fade, 1, 3.03, quick + animation = layers, 1, 3.81, easeOutQuint + animation = layersIn, 1, 4, easeOutQuint, fade + animation = layersOut, 1, 1.5, linear, fade + animation = fadeLayersIn, 1, 1.79, almostLinear + animation = fadeLayersOut, 1, 1.39, almostLinear + animation = workspaces, 1, 1.94, almostLinear, fade + animation = workspacesIn, 1, 1.21, almostLinear, fade + animation = workspacesOut, 1, 1.94, almostLinear, fade +} + +# Ref https://wiki.hypr.land/Configuring/Workspace-Rules/ +# "Smart gaps" / "No gaps when only" +# uncomment all if you wish to use that. +# workspace = w[tv1], gapsout:0, gapsin:0 +# workspace = f[1], gapsout:0, gapsin:0 +# windowrule = bordersize 0, floating:0, onworkspace:w[tv1] +# windowrule = rounding 0, floating:0, onworkspace:w[tv1] +# windowrule = bordersize 0, floating:0, onworkspace:f[1] +# windowrule = rounding 0, floating:0, onworkspace:f[1] + +# See https://wiki.hypr.land/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 +} + +# See https://wiki.hypr.land/Configuring/Master-Layout/ for more +master { + new_status = master +} + +# https://wiki.hypr.land/Configuring/Variables/#misc +misc { + force_default_wallpaper = 0 # Set to 0 or 1 to disable the anime mascot wallpapers + disable_hyprland_logo = true # If true disables the random hyprland logo / anime girl background. :( + middle_click_paste = false +} + + +############# +### INPUT ### +############# + +# https://wiki.hypr.land/Configuring/Variables/#input +input { + kb_layout = us + kb_variant = altgr-intl + kb_model = + kb_options = + kb_rules = + + follow_mouse = 2 + + sensitivity = 0 # -1.0 - 1.0, 0 means no modification. + + scroll_method = on_button_down + scroll_button = 274 +} + +# Example per-device config +# See https://wiki.hypr.land/Configuring/Keywords/#per-device-input-configs for more +device { + name = benq-zowie-benq-zowie-gaming-mouse + sensitivity = 0 +} + + +################### +### KEYBINDINGS ### +################### + +# See https://wiki.hypr.land/Configuring/Keywords/ +$mainMod = SUPER # Sets "Super" key as main modifier +bind = $mainMod, T, exec, $terminal +bind = $mainMod, Q, killactive, +bind = $mainMod, N, exec, $fileManager +bind = $mainMod, V, togglefloating, +bind = $mainMod, Space, exec, $menu +bind = $mainMod, G, togglesplit, # dwindle +bind = $mainMod, F, fullscreen +bind = $mainMod, B, exec, firefox +bind = $mainMod, M, exec, thunderbird +bind = $mainMod, L, exec, hyprlock + +# Move focus with mainMod + arrow keys +bind = $mainMod, left, movefocus, l +bind = $mainMod, right, movefocus, r +bind = $mainMod, up, movefocus, u +bind = $mainMod, down, movefocus, d + +bind = $mainMod SHIFT, left, movewindow, l +bind = $mainMod SHIFT, right, movewindow, r +bind = $mainMod SHIFT, up, movewindow, u +bind = $mainMod SHIFT, down, movewindow, d + +# Example special workspace (scratchpad) +bind = $mainMod, S, togglespecialworkspace, magic +bind = $mainMod SHIFT, S, movetoworkspace, special:magic + +# Scroll through existing workspaces with mainMod + scroll +bind = $mainMod, mouse_down, workspace, e+1 +bind = $mainMod, mouse_up, workspace, e-1 + +# Move/resize windows with mainMod + LMB/RMB and dragging +bindm = $mainMod, mouse:272, movewindow +bindm = $mainMod, mouse:273, resizewindow + +# Laptop multimedia keys for volume and LCD brightness +bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ +bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- +bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle +bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle +bindel = ,XF86MonBrightnessUp, exec, brightnessctl -e4 -n2 set 5%+ +bindel = ,XF86MonBrightnessDown, exec, brightnessctl -e4 -n2 set 5%- + +# Requires playerctl +# Spotify controls +bind = CTRL ALT, K, exec, playerctl --player=spotify play-pause +bind = CTRL ALT, Left, exec, playerctl --player=spotify previous +bind = CTRL ALT, Right, exec, playerctl --player=spotify next +bind = CTRL ALT, Up, exec, playerctl --player=spotify volume 0.05+ +bind = CTRL ALT, Down, exec, playerctl --player=spotify volume 0.05- + +bind = ,F7,pass,class:^(discord)$ +bind = ,F8,pass,class:^(discord)$ + +# Printscreen +# Screenshot a selected region (interactive) +# bind = , Print, exec, hyprshot -m region +bind = , Print, exec, hyprshot -zm region + +############################## +### WINDOWRULES ### +############################## + +# See https://wiki.hypr.land/Configuring/Window-Rules/ for more +# See https://wiki.hypr.land/Configuring/Workspace-Rules/ for workspace rules + +# Ignore maximize requests from apps. You'll probably like this. +windowrule = suppressevent maximize, class:.* + +# Fix some dragging issues with XWayland +windowrule = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0 + +windowrulev2 = tag +jb, class:^jetbrains-.+$,floating:1 +windowrulev2 = stayfocused, tag:jb +windowrulev2 = noinitialfocus, tag:jb diff --git a/roles/hyprland/files/hypr/hyprlock.conf b/roles/hyprland/files/hypr/hyprlock.conf new file mode 100644 index 0000000..bd6a0a9 --- /dev/null +++ b/roles/hyprland/files/hypr/hyprlock.conf @@ -0,0 +1,37 @@ +general { + disable_loading_bar = true + grace = 2 + hide_cursor = true + no_fade_in = false +} + +background { + monitor = + path = screenshot + blur_passes = 3 + blur_size = 8 +} + +input-field { + monitor = + size = 300, 50 + position = 0, -80 + dots_center = true + fade_on_empty = false + font_color = rgb(202, 211, 245) + inner_color = rgb(91, 96, 120) + outer_color = rgb(24, 25, 38) + outline_thickness = 5 + placeholder_text = Password... + shadow_passes = 2 +} + +label { + monitor = + text = Hi there, $USER + font_size = 20 + font_family = RobotoMono Nerd Font Mono + position = 0, 160 + halign = center + valign = center +} diff --git a/roles/hyprland/files/hypr/hyprpaper.conf b/roles/hyprland/files/hypr/hyprpaper.conf new file mode 100644 index 0000000..0e236c6 --- /dev/null +++ b/roles/hyprland/files/hypr/hyprpaper.conf @@ -0,0 +1,7 @@ +preload = /home/johannes/Pictures/Wallpapers/wallhaven-5g22q5.png + +wallpaper = DP-1,/home/johannes/Pictures/Wallpapers/wallhaven-5g22q5.png +wallpaper = DP-2,/home/johannes/Pictures/Wallpapers/wallhaven-5g22q5.png +wallpaper = HDMI-A-2,/home/johannes/Pictures/Wallpapers/wallhaven-5g22q5.png + +splash = false diff --git a/roles/hyprland/files/hypr/monitors.conf b/roles/hyprland/files/hypr/monitors.conf new file mode 100644 index 0000000..d0957cb --- /dev/null +++ b/roles/hyprland/files/hypr/monitors.conf @@ -0,0 +1,8 @@ +# Generated by nwg-displays on 2025-09-09 at 19:00:43. Do not edit manually. + +monitor=DP-1,2560x1440@165.0,6626x876,1.0 +monitor=DP-2,2560x1440@165.0,4066x876,1.0 +monitor=HDMI-A-1,0x0@60.0,-1x-1,1.0 +monitor=HDMI-A-1,disable +monitor=HDMI-A-2,1920x1080@60.0,9186x396,1.0 +monitor=HDMI-A-2,transform,3 diff --git a/roles/hyprland/files/hypr/workspaces.conf b/roles/hyprland/files/hypr/workspaces.conf new file mode 100644 index 0000000..ba4b7c3 --- /dev/null +++ b/roles/hyprland/files/hypr/workspaces.conf @@ -0,0 +1,34 @@ +$mainMod = SUPER # Sets "Super" key as main modifier + +workspace = 1, monitor:DP-1, persistent:true, default:true +workspace = 2, monitor:DP-1, persistent:true +workspace = 3, monitor:DP-1, persistent:true +workspace = 4, monitor:DP-2, persistent:true, default:true +workspace = 5, monitor:DP-2, persistent:true +workspace = 6, monitor:DP-2, persistent:true +workspace = 7, monitor:HDMI-A-2, persistent:true, default:true +workspace = 8, monitor:HDMI-A-2, persistent:true +workspace = 9, monitor:HDMI-A-2, persistent:true +workspace = 10, monitor:HDMI-A-1, persistent:true, default:true + +bind = $mainMod, 1, exec, hyprctl --batch "dispatch focusmonitor DP-1; dispatch workspace 1;" +bind = $mainMod, 2, exec, hyprctl --batch "dispatch focusmonitor DP-1; dispatch workspace 2;" +bind = $mainMod, 3, exec, hyprctl --batch "dispatch focusmonitor DP-1; dispatch workspace 3;" +bind = $mainMod, 4, exec, hyprctl --batch "dispatch focusmonitor DP-2; dispatch workspace 4;" +bind = $mainMod, 5, exec, hyprctl --batch "dispatch focusmonitor DP-2; dispatch workspace 5;" +bind = $mainMod, 6, exec, hyprctl --batch "dispatch focusmonitor DP-2; dispatch workspace 6;" +bind = $mainMod, 7, exec, hyprctl --batch "dispatch focusmonitor HDMI-A-2; dispatch workspace 7;" +bind = $mainMod, 8, exec, hyprctl --batch "dispatch focusmonitor HDMI-A-2; dispatch workspace 8;" +bind = $mainMod, 9, exec, hyprctl --batch "dispatch focusmonitor HDMI-A-2; dispatch workspace 9;" +bind = $mainMod, 0, exec, hyprctl --batch "dispatch focusmonitor HDMI-A-1; dispatch workspace 10;" + +bind = $mainMod SHIFT, 1, movetoworkspacesilent, 1 +bind = $mainMod SHIFT, 2, movetoworkspacesilent, 2 +bind = $mainMod SHIFT, 3, movetoworkspacesilent, 3 +bind = $mainMod SHIFT, 4, movetoworkspacesilent, 4 +bind = $mainMod SHIFT, 5, movetoworkspacesilent, 5 +bind = $mainMod SHIFT, 6, movetoworkspacesilent, 6 +bind = $mainMod SHIFT, 7, movetoworkspacesilent, 7 +bind = $mainMod SHIFT, 8, movetoworkspacesilent, 8 +bind = $mainMod SHIFT, 9, movetoworkspacesilent, 9 +bind = $mainMod SHIFT, 0, movetoworkspacesilent, 10 diff --git a/roles/hyprland/files/waybar/config.jsonc b/roles/hyprland/files/waybar/config.jsonc new file mode 100644 index 0000000..34693fd --- /dev/null +++ b/roles/hyprland/files/waybar/config.jsonc @@ -0,0 +1,128 @@ +{ + "layer": "top", + "position": "top", + + "exclusive": true, // keep the gap reserved + "margin-top": 8, // gap from the top edge + "margin-left": 10, // gap from the left edge + "margin-right": 10, // gap from the right edge + "margin-bottom": 0, + + /* order: 1-2-3 | window-title | tray + clock */ + // "modules-left": [ "custom/group1", "custom/group2", "custom/group3", "custom/group4","custom/group5","custom/group6","custom/group7","custom/group8","custom/group9","custom/group10"], + "modules-left": ["hyprland/workspaces"], + "modules-center": [ "hyprland/window" ], + "modules-right": [ "tray", "custom/separator", "network", "bluetooth", "custom/separator", "disk", "cpu", "memory", "pulseaudio", "custom/separator", "clock"], + + + "hyprland/workspaces": { + "disable-scroll": true, + "all-outputs": true, + "warp-on-scroll": false, + "format": "{icon}", + "format-icons": { + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7", + "8": "8", + "9": "9", + "10": "0" + }, + "persistent-workspaces": { + "1": [], + "2": [], + "3": [], + "4": [], + "5": [], + "6": [], + "7": [], + "8": [], + "9": [], + "10": [] + } + }, + + + "hyprland/window": { "format": "{title}", "max-length": 60 }, + "tray": { "icon-size": 16, "spacing": 10 }, + + "pulseaudio": { + // ——— behaviour ——— + "scroll-step": 5, // ± 5 % per wheel-step + "max-volume": 150, // allow 0 – 150 % + "on-click": "pactl set-sink-mute @DEFAULT_SINK@ toggle", + "on-click-right": "pavucontrol", + + // ——— appearance ——— + "markup": "pango", // enable coloured markup + "format": "{icon} {volume}%", + "format-muted": " muted", + + // choose the glyphs you like (Nerd Font / Font Awesome) + "format-icons": { + "default": "", // speaker + "muted": "", // muted speaker + "headphones": "" + } + }, + + "custom/separator": { + // emit a JSON object with field "text" + "exec": "echo '{\"text\":\"|\"}'", + // treat stdout as JSON + "return-type": "json", + // wrap the text in a colored Pango span + "format": "{text}", + "markup": "pango", + // refresh only hourly + "interval": 3600 + }, + + "cpu": { + "interval": 1, // update every second + "markup": "pango", + "format": " {usage}%" + }, + + "memory": { + "interval": 2, // fast enough, still light + "markup": "pango", + "format": " {percentage}%" + }, + + "disk": { + "interval": 30, // disks change slowly + "path": "/", + "markup": "pango", + "format": "󰋊 {percentage_used}%" + }, + + /* ─── CLOCK (add date) ──────────────────────────────────── */ + + "clock": { + "interval": 1, + "format": "{:%Y-%m-%d %H:%M:%S}", + "format-alt": "{:%Y-%m-%d %H:%M}" + }, + +/* ─── NETWORK ─────────────────────────────────────────────── */ +"network": { + "interface": ["enp.*", "eth.*"], // wired NICs (regex—adjust if needed) + "interval": 3, + "markup": "pango", + + "format-ethernet": "󰈀 up", + "format-wifi": " {essid}", + // "format-linked": " link", + "format-unknown": "󰈂 up", + "format-disconnected":" down", + + "on-click": "nm-connection-editor" +}, + +} + diff --git a/roles/hyprland/files/waybar/scripts/groups.sh b/roles/hyprland/files/waybar/scripts/groups.sh new file mode 100755 index 0000000..50c8aa2 --- /dev/null +++ b/roles/hyprland/files/waybar/scripts/groups.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +current=$(hyprctl activeworkspace -j | jq -r '.id') + +if [ "$1" = "click" ]; then + group=$2 + start=$(( (group - 1) * 3 + 1 )) + + hyprctl --batch " \ + dispatch focusmonitor DP-1; dispatch workspace $start; \ + dispatch focusmonitor DP-2; dispatch workspace $((start+1)); \ + dispatch focusmonitor HDMI-A-2; dispatch workspace $((start+2)); \ + dispatch focusmonitor DP-1" + +else + # Display button state + group=$1 + start=$(( (group - 1) * 3 + 1 )) + end=$(( start + 2 )) + case $group in + 1) range="1-3"; icon="" ;; + 2) range="4-6"; icon="" ;; + 3) range="7-9"; icon="" ;; + 4) range="10-12"; icon="" ;; + 5) range="13-15"; icon="" ;; + 6) range="16-18"; icon="" ;; + 7) range="19-21"; icon="" ;; + 8) range="22-24"; icon="" ;; + 9) range="25-27"; icon="󰝚" ;; + 10) range="28-30"; icon="" ;; + esac + + if [ $current -ge $start ] && [ $current -le $end ]; then + # Active group - return with active class + echo "{\"text\": \"$icon\", \"class\": \"active\"}" + else + # Inactive group + echo "{\"text\": \"$icon\", \"class\": \"inactive\"}" + fi +fi diff --git a/roles/hyprland/files/waybar/style.css b/roles/hyprland/files/waybar/style.css new file mode 100644 index 0000000..eb9c920 --- /dev/null +++ b/roles/hyprland/files/waybar/style.css @@ -0,0 +1,100 @@ +/* Palette */ +@define-color glass rgba(12, 14, 20, 0.34); +@define-color glass_strong rgba(12, 14, 20, 0.46); +@define-color fg #DDE1EA; +@define-color fg_dim #B8BECC; +@define-color accent1 #7F5AF0; +@define-color accent2 #00D1FF; +@define-color occupied #a8557f; + +/* Whole bar: more vertical padding, no border, stronger shadow */ +window#waybar { + background: @glass; + color: @fg; + border-radius: 12px; + /* margin: 6px 8px; */ + border: none; /* ← removed border */ + box-shadow: 0 10px 34px rgba(0,0,0,0.34); + -gtk-outline-radius: 12px; +} + +* { + border: none; + padding: 2px 6px; + margin-top: 0; + font-family: "RobotoMono Nerd Font", "Roboto Mono Nerd Font", "RobotoMono NF", monospace; + font-size: 14px; + font-weight: 500; +} + +/* Keep groups transparent */ +#modules-left, #modules-center, #modules-right { background: transparent; } + +/* Common modules stay transparent; compact rounded hit area */ +#tray, #window, #clock, #cpu, #memory, #disk, #network, #bluetooth, #pulseaudio { + background: transparent; + border-radius: 8px; + color: @fg; +} + +/* Subtle separators */ +#custom-separator { + color: rgba(200,200,200,0.20); + padding: 0 4px; +} + +/* Tray tweaks */ +#tray { margin-right: 0px; } +#tray * { padding-left: 0px; padding-right: 0px; } + +/* Tray menu glass look (also lighter, no border) */ +#tray menu { + padding: 6px 0; + margin: 0; + background: @glass_strong; + border-radius: 10px; + border: none; + box-shadow: 0 10px 34px rgba(0,0,0,0.38); +} +#tray menu menuitem { padding: 6px 12px; } +#tray menu menuitem:hover { background: alpha(@accent1, 0.16); } + +#workspaces button { + padding: 0 8px; + background-color: transparent; + color: #6c7086; + border-radius: 3px; + margin: 2px; + transition: all 0.2s ease-in-out; +} + +/* Hover effect */ +#workspaces button:hover { + background-color: #74c7ec; + color: #1e1e2e; +} + +#workspaces button:not(.active):not(.empty) { + color: #cdd6f4; + background-color: #585b70; +} + +/* Active/focused workspace */ +#workspaces button.active { + color: #1e1e2e; + background-color: @occupied; + font-weight: bold; +} + +#workspaces button.visible { + color: #f9e2af; + /* background-color: #45475a; */ + border: 1px solid #f9e2af; +} + +/* Default state for persistent workspaces */ +#workspaces button { + color: #6c7086; + background-color: @glass; +} + diff --git a/roles/hyprland/files/wofi/config b/roles/hyprland/files/wofi/config new file mode 100644 index 0000000..334a4a8 --- /dev/null +++ b/roles/hyprland/files/wofi/config @@ -0,0 +1,13 @@ +[config] +allow_images=true +width=500 +show=drun +prompt=Search +height=400 +term=ghostty +hide_scroll=true +print_command=true +insensitive=true +columns=1 +pre_display_exec=true +no_actions=true diff --git a/roles/hyprland/files/wofi/style.css b/roles/hyprland/files/wofi/style.css new file mode 100644 index 0000000..b2d70fb --- /dev/null +++ b/roles/hyprland/files/wofi/style.css @@ -0,0 +1,91 @@ +* { + /* smoother corners everywhere */ + border-radius: 12px; + font-weight: 450; +} + +/* Window container */ +window { + margin: 0px; + padding: 6px; + border: 1px solid rgba(127, 90, 240, 0.35); /* accent tint */ + background-color: rgba(12, 14, 20, 0.55); /* translucent */ + color: #E6E7EB; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45); + backg +} + +/* Input field */ +#input { + margin: 8px; + padding: 10px 12px; + border: 1px solid rgba(127, 90, 240, 0.25); + background-color: rgba(34, 38, 48, 0.70); + color: #E6E7EB; + outline: none; +} + +/* Lists/boxes */ +#outer-box, #inner-box { + margin: 6px; + border: none; + background-color: rgba(24, 28, 36, 0.60); +} + +#scroll { + margin: 0px; + border: none; +} + +/* Entry text */ +#text, #entry > * { + margin: 6px 10px; + color: #E6E7EB; +} + +/* Rows (entries) */ +#entry { + margin: 4px 6px; + padding: 8px 6px; + border: 1px solid transparent; + background-color: transparent; + transition: background-color 120ms ease, border-color 120ms ease; +} + +/* Hover — soft highlight */ +#entry:hover { + background-color: rgba(127, 90, 240, 0.10); + border-color: rgba(127, 90, 240, 0.25); +} + +/* Selected row — stronger surface and bold text */ +#entry:selected { + background-color: rgba(127, 90, 240, 0.18); + border-color: rgba(127, 90, 240, 0.40); +} + +#entry:selected #text { + font-weight: 600; +} + +/* Activatable (e.g., currently typed match) — invert text for contrast */ +#entry.activatable #text { + color: rgba(12, 14, 20, 0.92); +} + +/* Muted secondary text, if present */ +#entry .secondary, #entry .desc { + color: #AAB0BC; +} + +/* Optional: focus ring for keyboard nav */ +#entry:focus { + border-color: rgba(127, 90, 240, 0.55); + background-color: rgba(127, 90, 240, 0.12); +} + +/* Optional: thin separators using subtle overlay lines */ +separator, .separator { + background-color: rgba(255, 255, 255, 0.06); + min-height: 1px; +} diff --git a/roles/hyprland/tasks/main.yml b/roles/hyprland/tasks/main.yml new file mode 100644 index 0000000..6d5d578 --- /dev/null +++ b/roles/hyprland/tasks/main.yml @@ -0,0 +1,29 @@ +--- +- name: Symlink hyprland + file: + src: "{{ role_path }}/files/hypr" + dest: "{{ config_dir }}/hypr" + state: link + force: true + +- name: Symlink dunst + file: + src: "{{ role_path }}/files/dunst" + dest: "{{ config_dir }}/dunst" + state: link + force: true + +- name: Symlink wofi + file: + src: "{{ role_path }}/files/wofi" + dest: "{{ config_dir }}/wofi" + state: link + force: true + +- name: Symlink waybar + file: + src: "{{ role_path }}/files/waybar" + dest: "{{ config_dir }}/waybar" + state: link + force: true + diff --git a/nvim/after/ftplugin/markdown.lua b/roles/nvim/files/after/ftplugin/markdown.lua similarity index 100% rename from nvim/after/ftplugin/markdown.lua rename to roles/nvim/files/after/ftplugin/markdown.lua diff --git a/nvim/after/ftplugin/scss.lua b/roles/nvim/files/after/ftplugin/scss.lua similarity index 100% rename from nvim/after/ftplugin/scss.lua rename to roles/nvim/files/after/ftplugin/scss.lua diff --git a/nvim/after/ftplugin/typescript.lua b/roles/nvim/files/after/ftplugin/typescript.lua similarity index 100% rename from nvim/after/ftplugin/typescript.lua rename to roles/nvim/files/after/ftplugin/typescript.lua diff --git a/nvim/after/ftplugin/vim.lua b/roles/nvim/files/after/ftplugin/vim.lua similarity index 100% rename from nvim/after/ftplugin/vim.lua rename to roles/nvim/files/after/ftplugin/vim.lua diff --git a/nvim/init.lua b/roles/nvim/files/init.lua similarity index 100% rename from nvim/init.lua rename to roles/nvim/files/init.lua diff --git a/nvim/lazy-lock.json b/roles/nvim/files/lazy-lock.json similarity index 100% rename from nvim/lazy-lock.json rename to roles/nvim/files/lazy-lock.json diff --git a/nvim/lua/config/core/init.lua b/roles/nvim/files/lua/config/core/init.lua similarity index 100% rename from nvim/lua/config/core/init.lua rename to roles/nvim/files/lua/config/core/init.lua diff --git a/nvim/lua/config/core/keymaps.lua b/roles/nvim/files/lua/config/core/keymaps.lua similarity index 93% rename from nvim/lua/config/core/keymaps.lua rename to roles/nvim/files/lua/config/core/keymaps.lua index f739e66..c2c5ba3 100644 --- a/nvim/lua/config/core/keymaps.lua +++ b/roles/nvim/files/lua/config/core/keymaps.lua @@ -6,7 +6,7 @@ local opts = { noremap = true, silent = true } -- INSERT MODE -- map `ctrl + backspace` to delete previous word in insert mode -keymap.set('i', '', '', opts) +keymap.set('i', '', '', opts) -- map `ctrl + delete` to delete next word in insert mode keymap.set('i', '', 'dw', opts) diff --git a/nvim/lua/config/core/options.lua b/roles/nvim/files/lua/config/core/options.lua similarity index 100% rename from nvim/lua/config/core/options.lua rename to roles/nvim/files/lua/config/core/options.lua diff --git a/nvim/lua/config/lazy.lua b/roles/nvim/files/lua/config/lazy.lua similarity index 100% rename from nvim/lua/config/lazy.lua rename to roles/nvim/files/lua/config/lazy.lua diff --git a/nvim/lua/config/plugins/airline.lua# b/roles/nvim/files/lua/config/plugins/airline.lua# similarity index 100% rename from nvim/lua/config/plugins/airline.lua# rename to roles/nvim/files/lua/config/plugins/airline.lua# diff --git a/nvim/lua/config/plugins/alpha.lua b/roles/nvim/files/lua/config/plugins/alpha.lua similarity index 100% rename from nvim/lua/config/plugins/alpha.lua rename to roles/nvim/files/lua/config/plugins/alpha.lua diff --git a/nvim/lua/config/plugins/auto-session.lua b/roles/nvim/files/lua/config/plugins/auto-session.lua similarity index 100% rename from nvim/lua/config/plugins/auto-session.lua rename to roles/nvim/files/lua/config/plugins/auto-session.lua diff --git a/nvim/lua/config/plugins/autopairs.lua b/roles/nvim/files/lua/config/plugins/autopairs.lua similarity index 100% rename from nvim/lua/config/plugins/autopairs.lua rename to roles/nvim/files/lua/config/plugins/autopairs.lua diff --git a/nvim/lua/config/plugins/bufdelete.lua b/roles/nvim/files/lua/config/plugins/bufdelete.lua similarity index 100% rename from nvim/lua/config/plugins/bufdelete.lua rename to roles/nvim/files/lua/config/plugins/bufdelete.lua diff --git a/nvim/lua/config/plugins/bufferline.lua b/roles/nvim/files/lua/config/plugins/bufferline.lua similarity index 100% rename from nvim/lua/config/plugins/bufferline.lua rename to roles/nvim/files/lua/config/plugins/bufferline.lua diff --git a/nvim/lua/config/plugins/cmp.lua b/roles/nvim/files/lua/config/plugins/cmp.lua similarity index 100% rename from nvim/lua/config/plugins/cmp.lua rename to roles/nvim/files/lua/config/plugins/cmp.lua diff --git a/nvim/lua/config/plugins/colorscheme.lua b/roles/nvim/files/lua/config/plugins/colorscheme.lua similarity index 100% rename from nvim/lua/config/plugins/colorscheme.lua rename to roles/nvim/files/lua/config/plugins/colorscheme.lua diff --git a/nvim/lua/config/plugins/diffview.lua b/roles/nvim/files/lua/config/plugins/diffview.lua similarity index 100% rename from nvim/lua/config/plugins/diffview.lua rename to roles/nvim/files/lua/config/plugins/diffview.lua diff --git a/nvim/lua/config/plugins/dressing.lua b/roles/nvim/files/lua/config/plugins/dressing.lua similarity index 100% rename from nvim/lua/config/plugins/dressing.lua rename to roles/nvim/files/lua/config/plugins/dressing.lua diff --git a/nvim/lua/config/plugins/floaterm.lua b/roles/nvim/files/lua/config/plugins/floaterm.lua similarity index 100% rename from nvim/lua/config/plugins/floaterm.lua rename to roles/nvim/files/lua/config/plugins/floaterm.lua diff --git a/nvim/lua/config/plugins/flutter.lua b/roles/nvim/files/lua/config/plugins/flutter.lua similarity index 100% rename from nvim/lua/config/plugins/flutter.lua rename to roles/nvim/files/lua/config/plugins/flutter.lua diff --git a/nvim/lua/config/plugins/init.lua b/roles/nvim/files/lua/config/plugins/init.lua similarity index 100% rename from nvim/lua/config/plugins/init.lua rename to roles/nvim/files/lua/config/plugins/init.lua diff --git a/nvim/lua/config/plugins/lazygit.lua b/roles/nvim/files/lua/config/plugins/lazygit.lua similarity index 100% rename from nvim/lua/config/plugins/lazygit.lua rename to roles/nvim/files/lua/config/plugins/lazygit.lua diff --git a/nvim/lua/config/plugins/lsp/lspconfig.lua b/roles/nvim/files/lua/config/plugins/lsp/lspconfig.lua similarity index 100% rename from nvim/lua/config/plugins/lsp/lspconfig.lua rename to roles/nvim/files/lua/config/plugins/lsp/lspconfig.lua diff --git a/nvim/lua/config/plugins/lsp/mason.lua b/roles/nvim/files/lua/config/plugins/lsp/mason.lua similarity index 100% rename from nvim/lua/config/plugins/lsp/mason.lua rename to roles/nvim/files/lua/config/plugins/lsp/mason.lua diff --git a/nvim/lua/config/plugins/lsp/null-ls.lua b/roles/nvim/files/lua/config/plugins/lsp/null-ls.lua similarity index 100% rename from nvim/lua/config/plugins/lsp/null-ls.lua rename to roles/nvim/files/lua/config/plugins/lsp/null-ls.lua diff --git a/nvim/lua/config/plugins/lsp/pyrightconfig.json b/roles/nvim/files/lua/config/plugins/lsp/pyrightconfig.json similarity index 100% rename from nvim/lua/config/plugins/lsp/pyrightconfig.json rename to roles/nvim/files/lua/config/plugins/lsp/pyrightconfig.json diff --git a/nvim/lua/config/plugins/lualine.lua b/roles/nvim/files/lua/config/plugins/lualine.lua similarity index 100% rename from nvim/lua/config/plugins/lualine.lua rename to roles/nvim/files/lua/config/plugins/lualine.lua diff --git a/nvim/lua/config/plugins/nvim-tree.lua b/roles/nvim/files/lua/config/plugins/nvim-tree.lua similarity index 100% rename from nvim/lua/config/plugins/nvim-tree.lua rename to roles/nvim/files/lua/config/plugins/nvim-tree.lua diff --git a/nvim/lua/config/plugins/surround.lua b/roles/nvim/files/lua/config/plugins/surround.lua similarity index 100% rename from nvim/lua/config/plugins/surround.lua rename to roles/nvim/files/lua/config/plugins/surround.lua diff --git a/nvim/lua/config/plugins/telescope.lua b/roles/nvim/files/lua/config/plugins/telescope.lua similarity index 100% rename from nvim/lua/config/plugins/telescope.lua rename to roles/nvim/files/lua/config/plugins/telescope.lua diff --git a/nvim/lua/config/plugins/todo-comments.lua b/roles/nvim/files/lua/config/plugins/todo-comments.lua similarity index 100% rename from nvim/lua/config/plugins/todo-comments.lua rename to roles/nvim/files/lua/config/plugins/todo-comments.lua diff --git a/nvim/lua/config/plugins/treesitter.lua b/roles/nvim/files/lua/config/plugins/treesitter.lua similarity index 100% rename from nvim/lua/config/plugins/treesitter.lua rename to roles/nvim/files/lua/config/plugins/treesitter.lua diff --git a/nvim/lua/config/plugins/venv-selector.lua b/roles/nvim/files/lua/config/plugins/venv-selector.lua similarity index 100% rename from nvim/lua/config/plugins/venv-selector.lua rename to roles/nvim/files/lua/config/plugins/venv-selector.lua diff --git a/nvim/lua/config/plugins/which-key.lua b/roles/nvim/files/lua/config/plugins/which-key.lua similarity index 100% rename from nvim/lua/config/plugins/which-key.lua rename to roles/nvim/files/lua/config/plugins/which-key.lua diff --git a/roles/nvim/tasks/main.yml b/roles/nvim/tasks/main.yml new file mode 100644 index 0000000..bad1f3b --- /dev/null +++ b/roles/nvim/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- name: Install neovim + package: + name: neovim + state: present + +- name: Symlink neovim + file: + src: "{{ role_path }}/files" + dest: "{{ config_dir }}/nvim" + state: link + force: true diff --git a/roles/system/tasks/main.yml b/roles/system/tasks/main.yml new file mode 100644 index 0000000..67fc787 --- /dev/null +++ b/roles/system/tasks/main.yml @@ -0,0 +1,20 @@ +--- +- name: Update package cache (Arch-based systems) + pacman: + update_cache: yes + when: ansible_os_family == "Archlinux" + become: yes + +- name: Install system packages + package: + name: "{{ system_packages }}" + state: present + become: yes + +- name: Ensure .config directory exists + file: + path: "{{ config_dir }}" + state: directory + mode: '0755' + owner: "{{ ansible_user }}" + group: "{{ ansible_user }}" diff --git a/roles/zsh/files/.zshrc b/roles/zsh/files/.zshrc new file mode 100644 index 0000000..2a70a1e --- /dev/null +++ b/roles/zsh/files/.zshrc @@ -0,0 +1,51 @@ +# If you come from bash you might have to change your $PATH. +# export PATH=$HOME/bin:$HOME/.local/bin:/usr/local/bin:$PATH + +# Path to your Oh My Zsh installation. +export ZSH="$HOME/.oh-my-zsh" + +ZSH_THEME="bira" +zstyle ':omz:update' mode reminder # just remind me to update when it's time +COMPLETION_WAITING_DOTS="true" + +plugins=( + git + zsh-syntax-highlighting + zsh-autosuggestions + fzf-zsh-plugin +) + +source $ZSH/oh-my-zsh.sh + + +# Preferred editor for local and remote sessions +if [[ -n $SSH_CONNECTION ]]; then + export EDITOR='vim' +else + export EDITOR='nvim' +fi + +export DOTFILES_ZSH_DIR="$HOME/dotfiles/roles/zsh/files" + +for zsh_file in "$DOTFILES_ZSH_DIR"/*.zsh; do + [[ -r "$zsh_file" ]] && source "$zsh_file" +done + + +# TODO source all files with .zsh suffix +# source ./aliases.zsh +# source ./dev_env.zsh +# source ./tools.zsh + +# TODO +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm +[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion + +if [[ -n "$MACHINE_TYPE" && -f "$HOME/dotfiles/zsh/hosts/$MACHINE_TYPE.zsh" ]]; then + source "$HOME/dotfiles/zsh/hosts/$MACHINE_TYPE.zsh" +fi + + +alias drun='docker run -it --network=host --device=/dev/kfd --device=/dev/dri --group-add=video --ipc=host --cap-add=SYS_PTRACE --security-opt seccomp=unconfined' + diff --git a/zsh/aliases.zsh b/roles/zsh/files/aliases.zsh similarity index 67% rename from zsh/aliases.zsh rename to roles/zsh/files/aliases.zsh index a4f838c..8d3de04 100644 --- a/zsh/aliases.zsh +++ b/roles/zsh/files/aliases.zsh @@ -4,8 +4,14 @@ alias tp='trash-put' alias tl='trash-list' alias szrc='source ~/.zshrc' +alias zrc="vim ~/.zshrc" alias dotf='vim ~/dotfiles/' +# TODO relative path +alias hyprconf='vim ~/dotfiles/roles/hyprland/files/hypr/hyprland.conf' + +alias ls='eza' + rm() { print "ℹ️ Consider using trash-put instead of rm" print "➡️ Running: trash-put $*" diff --git a/zsh/dev_env.zsh b/roles/zsh/files/dev_env.zsh similarity index 100% rename from zsh/dev_env.zsh rename to roles/zsh/files/dev_env.zsh diff --git a/zsh/hosts/personal.zsh b/roles/zsh/files/hosts/personal.zsh similarity index 100% rename from zsh/hosts/personal.zsh rename to roles/zsh/files/hosts/personal.zsh diff --git a/zsh/hosts/work.zsh b/roles/zsh/files/hosts/work.zsh similarity index 100% rename from zsh/hosts/work.zsh rename to roles/zsh/files/hosts/work.zsh diff --git a/zsh/tools.zsh b/roles/zsh/files/tools.zsh similarity index 100% rename from zsh/tools.zsh rename to roles/zsh/files/tools.zsh diff --git a/roles/zsh/tasks/main.yaml b/roles/zsh/tasks/main.yaml new file mode 100644 index 0000000..8cd5ac0 --- /dev/null +++ b/roles/zsh/tasks/main.yaml @@ -0,0 +1,24 @@ +--- +- name: Install zsh + package: + name: zsh + state: present + +- name: Install oh-my-zsh + shell: | + sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" --unattended + args: + creates: "{{ ansible_env.HOME }}/.oh-my-zsh" + +- name: Check for custom zshrc + stat: + path: "{{ role_path }}/files/.zshrc" + register: custom_zshrc + +- name: Symlink custom zshrc + file: + src: "{{ role_path }}/files/.zshrc" + dest: "{{ ansible_env.HOME }}/.zshrc" + state: link + force: yes + when: custom_zshrc.stat.exists diff --git a/todo_ansible.md b/todo_ansible.md new file mode 100644 index 0000000..ec1e301 --- /dev/null +++ b/todo_ansible.md @@ -0,0 +1,238 @@ +Here's how such a role-based Ansible dotfiles configuration would work: + +## Directory Structure +``` +dotfiles/ +├── playbook.yml # Main playbook +├── group_vars/ +│ └── all.yml # Your config with default_roles +├── roles/ +│ ├── system/ +│ │ ├── tasks/main.yml +│ │ ├── vars/main.yml +│ │ └── files/ +│ ├── git/ +│ │ ├── tasks/main.yml +│ │ ├── templates/ +│ │ │ └── .gitconfig.j2 +│ │ └── vars/main.yml +│ ├── neovim/ +│ │ ├── tasks/main.yml +│ │ └── files/ +│ └── zsh/ +│ ├── tasks/main.yml +│ ├── files/ +│ │ └── .zshrc +│ └── vars/main.yml +└── inventory +``` + +## Main Configuration (`group_vars/all.yml`) +```yaml +# Your system configuration +default_roles: + - system + - git + - neovim + - zsh + - docker + +# Global variables +dotfiles_dir: "{{ ansible_env.HOME }}/dotfiles" +config_dir: "{{ ansible_env.HOME }}/.config" + +# Git configuration +git_user_name: "Johannes" +git_user_email: "johannes@example.com" +git_editor: "nvim" + +# System packages to install +system_packages: + - curl + - wget + - unzip + - tree +``` + +## Main Playbook (`playbook.yml`) +```yaml +--- +- name: Setup development environment + hosts: localhost + connection: local + become: yes + become_method: sudo + + pre_tasks: + - name: Create btrfs snapshot before changes + shell: | + sudo btrfs subvolume snapshot / /.snapshots/before-dotfiles-$(date +%Y%m%d-%H%M%S) + ignore_errors: yes + tags: [snapshot] + + roles: "{{ default_roles }}" + + post_tasks: + - name: Summary of installed roles + debug: + msg: "Completed setup for: {{ default_roles | join(', ') }}" +``` + +## Example Roles + +### System Role (`roles/system/tasks/main.yml`) +```yaml +--- +- name: Install system packages + package: + name: "{{ system_packages }}" + state: present + +- name: Ensure .config directory exists + file: + path: "{{ config_dir }}" + state: directory + mode: '0755' + +- name: Set up shell as default + user: + name: "{{ ansible_env.USER }}" + shell: /usr/bin/zsh + when: "'zsh' in default_roles" +``` + +### Git Role (`roles/git/tasks/main.yml`) +```yaml +--- +- name: Install git + package: + name: git + state: present + +- name: Check if custom gitconfig exists + stat: + path: "{{ dotfiles_dir }}/git/.gitconfig" + register: custom_gitconfig + +- name: Use custom gitconfig if available + file: + src: "{{ dotfiles_dir }}/git/.gitconfig" + dest: "{{ ansible_env.HOME }}/.gitconfig" + state: link + force: yes + when: custom_gitconfig.stat.exists + +- name: Generate gitconfig from template if no custom config + template: + src: .gitconfig.j2 + dest: "{{ ansible_env.HOME }}/.gitconfig" + mode: '0644' + when: not custom_gitconfig.stat.exists +``` + +### Git Template (`roles/git/templates/.gitconfig.j2`) +```ini +[user] + name = {{ git_user_name }} + email = {{ git_user_email }} + +[core] + editor = {{ git_editor }} + autocrlf = input + +[init] + defaultBranch = main + +[push] + default = simple +``` + +### Neovim Role (`roles/neovim/tasks/main.yml`) +```yaml +--- +- name: Install neovim + package: + name: neovim + state: present + +- name: Check for custom neovim config + stat: + path: "{{ dotfiles_dir }}/nvim" + register: nvim_config + +- name: Symlink neovim config + file: + src: "{{ dotfiles_dir }}/nvim" + dest: "{{ config_dir }}/nvim" + state: link + force: yes + when: nvim_config.stat.exists + +- name: Create basic neovim config if none exists + copy: + content: | + -- Basic Neovim configuration + vim.opt.number = true + vim.opt.expandtab = true + vim.opt.tabstop = 2 + vim.opt.shiftwidth = 2 + dest: "{{ config_dir }}/nvim/init.lua" + mode: '0644' + when: not nvim_config.stat.exists +``` + +### ZSH Role (`roles/zsh/tasks/main.yml`) +```yaml +--- +- name: Install zsh + package: + name: zsh + state: present + +- name: Install oh-my-zsh + shell: | + sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" --unattended + args: + creates: "{{ ansible_env.HOME }}/.oh-my-zsh" + +- name: Check for custom zshrc + stat: + path: "{{ dotfiles_dir }}/zsh/.zshrc" + register: custom_zshrc + +- name: Symlink custom zshrc + file: + src: "{{ dotfiles_dir }}/zsh/.zshrc" + dest: "{{ ansible_env.HOME }}/.zshrc" + state: link + force: yes + when: custom_zshrc.stat.exists +``` + +## Usage + +**To install everything:** +```bash +ansible-playbook -i inventory playbook.yml --ask-become-pass +``` + +**To install only specific roles:** +```bash +ansible-playbook -i inventory playbook.yml --ask-become-pass --tags "git,neovim" +``` + +**To override roles temporarily:** +```bash +ansible-playbook -i inventory playbook.yml --ask-become-pass -e "default_roles=['system','git']" +``` + +## Benefits of This Approach + +1. **Modular**: Each tool is a separate role +2. **Configurable**: Easy to enable/disable tools in `all.yml` +3. **Reusable**: Roles can be shared across different machines +4. **Flexible**: Can override variables per host/group +5. **Fallback configs**: Generates basic configs when custom ones don't exist +6. **Scalable**: Easy to add new tools without touching existing code + +This approach lets you manage your entire development environment as code while keeping it organized and maintainable! diff --git a/zsh/.zshrc b/zsh/.zshrc deleted file mode 100644 index a620ac0..0000000 --- a/zsh/.zshrc +++ /dev/null @@ -1,126 +0,0 @@ -# If you come from bash you might have to change your $PATH. -# export PATH=$HOME/bin:$HOME/.local/bin:/usr/local/bin:$PATH - -# Path to your Oh My Zsh installation. -export ZSH="$HOME/.oh-my-zsh" - -# Set name of the theme to load --- if set to "random", it will -# load a random theme each time Oh My Zsh is loaded, in which case, -# to know which specific one was loaded, run: echo $RANDOM_THEME -# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes -ZSH_THEME="bira" - -# Set list of themes to pick from when loading at random -# Setting this variable when ZSH_THEME=random will cause zsh to load -# a theme from this variable instead of looking in $ZSH/themes/ -# If set to an empty array, this variable will have no effect. -# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) - -# Uncomment the following line to use case-sensitive completion. -# CASE_SENSITIVE="true" - -# Uncomment the following line to use hyphen-insensitive completion. -# Case-sensitive completion must be off. _ and - will be interchangeable. -# HYPHEN_INSENSITIVE="true" - -# Uncomment one of the following lines to change the auto-update behavior -# zstyle ':omz:update' mode disabled # disable automatic updates -# zstyle ':omz:update' mode auto # update automatically without asking -zstyle ':omz:update' mode reminder # just remind me to update when it's time - -# Uncomment the following line to change how often to auto-update (in days). -# zstyle ':omz:update' frequency 13 - -# Uncomment the following line if pasting URLs and other text is messed up. -# DISABLE_MAGIC_FUNCTIONS="true" - -# Uncomment the following line to disable colors in ls. -# DISABLE_LS_COLORS="true" - -# Uncomment the following line to disable auto-setting terminal title. -# DISABLE_AUTO_TITLE="true" - -# Uncomment the following line to enable command auto-correction. -# ENABLE_CORRECTION="true" - -# Uncomment the following line to display red dots whilst waiting for completion. -# You can also set it to another string to have that shown instead of the default red dots. -# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" -# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) -COMPLETION_WAITING_DOTS="true" - -# Uncomment the following line if you want to disable marking untracked files -# under VCS as dirty. This makes repository status check for large repositories -# much, much faster. -# DISABLE_UNTRACKED_FILES_DIRTY="true" - -# Uncomment the following line if you want to change the command execution time -# stamp shown in the history command output. -# You can set one of the optional three formats: -# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" -# or set a custom format using the strftime function format specifications, -# see 'man strftime' for details. -# HIST_STAMPS="mm/dd/yyyy" - -# Would you like to use another custom folder than $ZSH/custom? -# ZSH_CUSTOM=/path/to/new-custom-folder - -# Which plugins would you like to load? -# Standard plugins can be found in $ZSH/plugins/ -# Custom plugins may be added to $ZSH_CUSTOM/plugins/ -# Example format: plugins=(rails git textmate ruby lighthouse) -# Add wisely, as too many plugins slow down shell startup. -plugins=( - git - zsh-syntax-highlighting - zsh-autosuggestions - fzf-zsh-plugin -) - -source $ZSH/oh-my-zsh.sh - -# User configuration - -# export MANPATH="/usr/local/man:$MANPATH" - -# You may need to manually set your language environment -# export LANG=en_US.UTF-8 - -# Preferred editor for local and remote sessions -if [[ -n $SSH_CONNECTION ]]; then - export EDITOR='vim' -else - export EDITOR='nvim' -fi - -# Compilation flags -# export ARCHFLAGS="-arch $(uname -m)" - -# Set personal aliases, overriding those provided by Oh My Zsh libs, -# plugins, and themes. Aliases can be placed here, though Oh My Zsh -# users are encouraged to define aliases within a top-level file in -# the $ZSH_CUSTOM folder, with .zsh extension. Examples: -# - $ZSH_CUSTOM/aliases.zsh -# - $ZSH_CUSTOM/macos.zsh -# For a full list of active aliases, run `alias`. -# -# Example aliases -# alias zshconfig="mate ~/.zshrc" -# alias ohmyzsh="mate ~/.oh-my-zsh" -# bindkey '^R' history-incremental-search-backward - -# TODO source all files with .zsh suffix -source ~/dotfiles/zsh/aliases.zsh -source ~/dotfiles/zsh/dev_env.zsh -source ~/dotfiles/zsh/tools.zsh - - - - -export NVM_DIR="$HOME/.nvm" -[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm -[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion - -if [[ -n "$MACHINE_TYPE" && -f "$HOME/dotfiles/zsh/hosts/$MACHINE_TYPE.zsh" ]]; then - source "$HOME/dotfiles/zsh/hosts/$MACHINE_TYPE.zsh" -fi