From 2bfe638719ff8d01a7eb7265b9c7169e78e6570b Mon Sep 17 00:00:00 2001 From: Haelnorr Date: Mon, 29 Dec 2025 20:35:16 +1100 Subject: [PATCH] updated config for wayland/hyprland --- .config/.gitignore | 16 + .config/alacritty/.gitignore | 1 + .config/bat/.gitignore | 1 + .config/btop/.gitignore | 1 + .config/hypr/.gitignore | 1 + .config/hypr/background | 1453 ++++++++++++++++++ .config/hypr/hyprland.conf | 337 ++++ .config/hypr/hyprlock.conf | 77 + .config/hypr/hyprpaper.conf | 9 + .config/hypr/mocha.conf | 78 + .config/hypr/restart_apps.sh | 8 + .config/i3/.gitignore | 1 + .config/neofetch/.gitignore | 1 + .config/picom/.gitignore | 1 + .config/polybar/.gitignore | 1 + .config/rofi/.gitignore | 1 + .config/starship/.gitignore | 1 + .config/tmux/.gitignore | 2 + .config/waybar/.gitignore | 1 + .config/waybar/audio_output_status.sh | 45 + .config/waybar/audio_output_switch.sh | 48 + .config/waybar/config.jsonc | 205 +++ .config/waybar/mediaplayer.py | 222 +++ .config/waybar/mocha.css | 26 + .config/waybar/power_menu.xml | 33 + .config/waybar/style.css | 11 + .config/wofi/.gitignore | 1 + .config/wofi/style.css | 42 + .config/zsh-vim-mode/.gitignore | 1 + .config/zsh-vim-mode/zsh-vim-mode.plugin.zsh | 677 ++++++++ .gitignore | 13 +- .local/.gitignore | 3 + .local/bin/.gitignore | 1 + .local/bin/movie | 10 - .zshrc | 2 +- 35 files changed, 3309 insertions(+), 22 deletions(-) create mode 100644 .config/.gitignore create mode 100644 .config/alacritty/.gitignore create mode 100644 .config/bat/.gitignore create mode 100644 .config/btop/.gitignore create mode 100644 .config/hypr/.gitignore create mode 100644 .config/hypr/background create mode 100644 .config/hypr/hyprland.conf create mode 100644 .config/hypr/hyprlock.conf create mode 100644 .config/hypr/hyprpaper.conf create mode 100644 .config/hypr/mocha.conf create mode 100755 .config/hypr/restart_apps.sh create mode 100644 .config/i3/.gitignore create mode 100644 .config/neofetch/.gitignore create mode 100644 .config/picom/.gitignore create mode 100644 .config/polybar/.gitignore create mode 100644 .config/rofi/.gitignore create mode 100644 .config/starship/.gitignore create mode 100644 .config/tmux/.gitignore create mode 100644 .config/waybar/.gitignore create mode 100755 .config/waybar/audio_output_status.sh create mode 100755 .config/waybar/audio_output_switch.sh create mode 100644 .config/waybar/config.jsonc create mode 100755 .config/waybar/mediaplayer.py create mode 100644 .config/waybar/mocha.css create mode 100644 .config/waybar/power_menu.xml create mode 100644 .config/waybar/style.css create mode 100644 .config/wofi/.gitignore create mode 100644 .config/wofi/style.css create mode 100644 .config/zsh-vim-mode/.gitignore create mode 100644 .config/zsh-vim-mode/zsh-vim-mode.plugin.zsh create mode 100644 .local/.gitignore create mode 100644 .local/bin/.gitignore delete mode 100755 .local/bin/movie diff --git a/.config/.gitignore b/.config/.gitignore new file mode 100644 index 0000000..f6c713b --- /dev/null +++ b/.config/.gitignore @@ -0,0 +1,16 @@ +* +!.gitignore +!alacritty/ +!bat/ +!btop/ +!i3/ +!neofetch/ +!picom/ +!polybar/ +!rofi/ +!starship/ +!tmux/ +!waybar/ +!wofi/ +!hypr/ +!zsh-vim-mode/ diff --git a/.config/alacritty/.gitignore b/.config/alacritty/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/alacritty/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/bat/.gitignore b/.config/bat/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/bat/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/btop/.gitignore b/.config/btop/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/btop/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/hypr/.gitignore b/.config/hypr/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/hypr/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/hypr/background b/.config/hypr/background new file mode 100644 index 0000000..d52dae7 --- /dev/null +++ b/.config/hypr/background @@ -0,0 +1,1453 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + hyprlock/assets/mocha.webp at main · catppuccin/hyprlock · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ Skip to content + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + +
+ + + + + + + + + +
+
+
+ + + + + + + + + + + + + +
+ +
+ +
+ +
+ + + + / + + hyprlock + + + Public +
+ + +
+ +
+ + +
+
+ +
+
+ + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+ +
+
+ +
+ +
+

Footer

+ + + + +
+
+ + + + + © 2025 GitHub, Inc. + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + +
+
+
+ + + diff --git a/.config/hypr/hyprland.conf b/.config/hypr/hyprland.conf new file mode 100644 index 0000000..a34e835 --- /dev/null +++ b/.config/hypr/hyprland.conf @@ -0,0 +1,337 @@ +source=~/.config/hypr/mocha.conf +# This is an example Hyprland config file. +# Refer to the wiki for more information. +# https://wiki.hypr.land/Configuring/ + +# Please note not all available settings / options are set here. +# For a full list, see the wiki + +# You can split this configuration into multiple files +# Create your files separately and then link them to this file like this: +# source = ~/.config/hypr/myColors.conf + + +################ +### MONITORS ### +################ + +# See https://wiki.hypr.land/Configuring/Monitors/ +monitor=DP-3,2560x1440@179.96,0x0,1.25 +monitor=HDMI-A-1,1920x1080@60,2048x0,1 +monitor=DP-2,1920x1080@60,-1080x-450,1,transform,1 + +################### +### MY PROGRAMS ### +################### + +# See https://wiki.hypr.land/Configuring/Keywords/ + +# Set programs that you use +$terminal = alacritty +$fileManager = thunar +$menu = wofi --show drun --insensitive --allow-images + + +################# +### AUTOSTART ### +################# + +# Autostart necessary processes (like notifications daemons, status bars, etc.) +# Or execute your favorite apps at launch like this: + +# exec-once = $terminal +# exec-once = nm-applet & +# exec-once = waybar & hyprpaper & firefox +$autostart = "waybar & hyprpaper" +exec-once = sh -c "$autostart" + + +############################# +### ENVIRONMENT VARIABLES ### +############################# + +# See https://wiki.hypr.land/Configuring/Environment-variables/ + +env = XCURSOR_SIZE,24 +env = HYPRCURSOR_SIZE,24 + + +################### +### 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 ### +##################### + +# Refer to https://wiki.hypr.land/Configuring/Variables/ + +# https://wiki.hypr.land/Configuring/Variables/#general +general { + gaps_in = 5 + gaps_out = 10 + + border_size = 2 + + # https://wiki.hypr.land/Configuring/Variables/#variable-types for info about colors + col.active_border = $blue $green 45deg + col.inactive_border = $surface0 + + # 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 +} + +# https://wiki.hypr.land/Configuring/Variables/#decoration +decoration { + rounding = 10 + rounding_power = 2 + + # Change transparency of focused and unfocused windows + active_opacity = 1.0 + inactive_opacity = 1.0 + + shadow { + enabled = true + range = 4 + render_power = 3 + color = $crust + } + + # https://wiki.hypr.land/Configuring/Variables/#blur + blur { + enabled = true + size = 3 + passes = 1 + + vibrancy = 0.1696 + } +} + +# https://wiki.hypr.land/Configuring/Variables/#animations +animations { + enabled = yes, please :) + + # Default curves, see https://wiki.hypr.land/Configuring/Animations/#curves + # NAME, X0, Y0, X1, Y1 + 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 + bezier = quick, 0.15, 0, 0.1, 1 + + # Default animations, see https://wiki.hypr.land/Configuring/Animations/ + # NAME, ONOFF, SPEED, CURVE, [STYLE] + 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 + animation = zoomFactor, 1, 7, quick +} + +# 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 = -1 # Set to 0 or 1 to disable the anime mascot wallpapers + disable_hyprland_logo = false # If true disables the random hyprland logo / anime girl background. :( +} + + +############# +### INPUT ### +############# + +# https://wiki.hypr.land/Configuring/Variables/#input +input { + kb_layout = us + kb_variant = + kb_model = + kb_options = + kb_rules = + + follow_mouse = 1 + + sensitivity = 0 # -1.0 - 1.0, 0 means no modification. + + touchpad { + natural_scroll = false + } +} + +# See https://wiki.hypr.land/Configuring/Gestures +gesture = 3, horizontal, workspace + +# Example per-device config +# See https://wiki.hypr.land/Configuring/Keywords/#per-device-input-configs for more +device { + name = epic-mouse-v1 + sensitivity = -0.5 +} + + +################### +### KEYBINDINGS ### +################### +num_lock_by_default = true + +# See https://wiki.hypr.land/Configuring/Keywords/ +$mainMod = SUPER # Sets "Windows" key as main modifier + +# Example binds, see https://wiki.hypr.land/Configuring/Binds/ for more +bind = $mainMod, Return, exec, $terminal +bind = $mainMod SHIFT, Q, killactive, +bind = $mainMod SHIFT, E, exit, +bind = $mainMod, E, exec, $fileManager +bind = $mainMod, V, togglefloating, +bind = $mainMod, D, exec, $menu +#bind = $mainMod, P, pseudo, # dwindle +#bind = $mainMod, J, togglesplit, # dwindle + +# Move focus with mainMod + vim bindings +bind = $mainMod, H, movefocus, l +bind = $mainMod, L, movefocus, r +bind = $mainMod, K, movefocus, u +bind = $mainMod, J, movefocus, d + +# Move focused window within the current workspace +bind = $mainMod SHIFT, H, movewindow, l +bind = $mainMod SHIFT, L, movewindow, r +bind = $mainMod SHIFT, K, movewindow, u +bind = $mainMod SHIFT, J, movewindow, d + +# Switch workspaces with mainMod + [0-9] +bind = $mainMod, 1, workspace, 1 +bind = $mainMod, 2, workspace, 2 +bind = $mainMod, 3, workspace, 3 +bind = $mainMod, 4, workspace, 4 +bind = $mainMod, 5, workspace, 5 +bind = $mainMod, 6, workspace, 6 +bind = $mainMod, 7, workspace, 7 +bind = $mainMod, 8, workspace, 8 +bind = $mainMod, 9, workspace, 9 +bind = $mainMod, 0, workspace, 10 + +# Move active window to a workspace with mainMod + SHIFT + [0-9] +bind = $mainMod SHIFT, 1, movetoworkspace, 1 +bind = $mainMod SHIFT, 2, movetoworkspace, 2 +bind = $mainMod SHIFT, 3, movetoworkspace, 3 +bind = $mainMod SHIFT, 4, movetoworkspace, 4 +bind = $mainMod SHIFT, 5, movetoworkspace, 5 +bind = $mainMod SHIFT, 6, movetoworkspace, 6 +bind = $mainMod SHIFT, 7, movetoworkspace, 7 +bind = $mainMod SHIFT, 8, movetoworkspace, 8 +bind = $mainMod SHIFT, 9, movetoworkspace, 9 +bind = $mainMod SHIFT, 0, movetoworkspace, 10 + +# 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 + +# Requires playerctl +bindl = , XF86AudioNext, exec, playerctl next +bindl = , XF86AudioPause, exec, playerctl play-pause +bindl = , XF86AudioPlay, exec, playerctl play-pause +bindl = , XF86AudioPrev, exec, playerctl previous + +# Lockscreen +bind = $mainMod SHIFT, X, exec, hyprlock + +# Sleep / Hibernate +bind = $mainMod SHIFT, Period, exec, systemctl suspend +bind = $mainMod SHIFT, Comma, exec, systemctl hibernate + +# Refresh autostart apps +bind = $mainMod SHIFT, R, exec, $HOME/.config/hypr/restart_apps.sh $autostart + +# Screenshots +bind = , PRINT, exec, hyprshot -m region --clipboard-only +bind = SHIFT, PRINT, exec, hyprshot -m output --clipboard-only + + +############################## +### WINDOWS AND WORKSPACES ### +############################## + +# See https://wiki.hypr.land/Configuring/Window-Rules/ for more +# See https://wiki.hypr.land/Configuring/Workspace-Rules/ for workspace rules + +# Example windowrule +# windowrule = float,class:^(kitty)$,title:^(kitty)$ + +# 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 + +# Monitor 1: DP-3 +workspace = 1, monitor:DP-3 +workspace = 4, monitor:DP-3 +workspace = 7, monitor:DP-3 + +# Monitor 2: HDMI-A-1 +workspace = 2, monitor:HDMI-A-1 +workspace = 5, monitor:HDMI-A-1 +workspace = 8, monitor:HDMI-A-1 + +# Monitor 3: DP-2 +workspace = 3, monitor:DP-2 +workspace = 6, monitor:DP-2 +workspace = 9, monitor:DP-2 diff --git a/.config/hypr/hyprlock.conf b/.config/hypr/hyprlock.conf new file mode 100644 index 0000000..19b75ae --- /dev/null +++ b/.config/hypr/hyprlock.conf @@ -0,0 +1,77 @@ +source = $HOME/.config/hypr/mocha.conf + +$accent = $mauve +$accentAlpha = $mauveAlpha +$font = JetBrainsMono Nerd Font + +# GENERAL +general { + hide_cursor = true +} + +# BACKGROUND +background { + monitor = + path = $HOME/.config/hypr/background + blur_passes = 0 + color = $base +} + +# LAYOUT +label { + monitor = DP-3 + text = Layout: $LAYOUT + color = $text + font_size = 25 + font_family = $font + position = 30, -30 + halign = left + valign = top +} + +# TIME +label { + monitor = DP-3 + text = $TIME + color = $text + font_size = 90 + font_family = $font + position = -30, 0 + halign = right + valign = top +} + +# DATE +label { + monitor = DP-3 + text = cmd[update:43200000] date +"%A, %d %B %Y" + color = $text + font_size = 25 + font_family = $font + position = -30, -150 + halign = right + valign = top +} + +# INPUT FIELD +input-field { + monitor = DP-3 + size = 300, 60 + outline_thickness = 4 + dots_size = 0.2 + dots_spacing = 0.2 + dots_center = true + outer_color = $accent + inner_color = $surface0 + font_color = $text + fade_on_empty = false + placeholder_text = 󰌾 Logged in as $USER + hide_input = false + check_color = $accent + fail_color = $red + fail_text = $FAIL ($ATTEMPTS) + capslock_color = $yellow + position = 0, -47 + halign = center + valign = center +} diff --git a/.config/hypr/hyprpaper.conf b/.config/hypr/hyprpaper.conf new file mode 100644 index 0000000..1fb985a --- /dev/null +++ b/.config/hypr/hyprpaper.conf @@ -0,0 +1,9 @@ +$wallpaper_1 = $HOME/.wallpapers/1.jpg +$wallpaper_2 = $HOME/.wallpapers/2.jpg +$wallpaper_3 = $HOME/.wallpapers/3.jpg +preload = $wallpaper_1 +preload = $wallpaper_2 +preload = $wallpaper_3 +wallpaper = DP-3,$wallpaper_1 +wallpaper = HDMI-A-1,$wallpaper_2 +wallpaper = DP-2,$wallpaper_3 diff --git a/.config/hypr/mocha.conf b/.config/hypr/mocha.conf new file mode 100644 index 0000000..8ccb56a --- /dev/null +++ b/.config/hypr/mocha.conf @@ -0,0 +1,78 @@ + +$rosewater = rgb(f5e0dc) +$rosewaterAlpha = f5e0dc + +$flamingo = rgb(f2cdcd) +$flamingoAlpha = f2cdcd + +$pink = rgb(f5c2e7) +$pinkAlpha = f5c2e7 + +$mauve = rgb(cba6f7) +$mauveAlpha = cba6f7 + +$red = rgb(f38ba8) +$redAlpha = f38ba8 + +$maroon = rgb(eba0ac) +$maroonAlpha = eba0ac + +$peach = rgb(fab387) +$peachAlpha = fab387 + +$yellow = rgb(f9e2af) +$yellowAlpha = f9e2af + +$green = rgb(a6e3a1) +$greenAlpha = a6e3a1 + +$teal = rgb(94e2d5) +$tealAlpha = 94e2d5 + +$sky = rgb(89dceb) +$skyAlpha = 89dceb + +$sapphire = rgb(74c7ec) +$sapphireAlpha = 74c7ec + +$blue = rgb(89b4fa) +$blueAlpha = 89b4fa + +$lavender = rgb(b4befe) +$lavenderAlpha = b4befe + +$text = rgb(cdd6f4) +$textAlpha = cdd6f4 + +$subtext1 = rgb(bac2de) +$subtext1Alpha = bac2de + +$subtext0 = rgb(a6adc8) +$subtext0Alpha = a6adc8 + +$overlay2 = rgb(9399b2) +$overlay2Alpha = 9399b2 + +$overlay1 = rgb(7f849c) +$overlay1Alpha = 7f849c + +$overlay0 = rgb(6c7086) +$overlay0Alpha = 6c7086 + +$surface2 = rgb(585b70) +$surface2Alpha = 585b70 + +$surface1 = rgb(45475a) +$surface1Alpha = 45475a + +$surface0 = rgb(313244) +$surface0Alpha = 313244 + +$base = rgb(1e1e2e) +$baseAlpha = 1e1e2e + +$mantle = rgb(181825) +$mantleAlpha = 181825 + +$crust = rgb(11111b) +$crustAlpha = 11111b diff --git a/.config/hypr/restart_apps.sh b/.config/hypr/restart_apps.sh new file mode 100755 index 0000000..b8b1e59 --- /dev/null +++ b/.config/hypr/restart_apps.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +LOG=$HOME/.config/hypr/temp.log +exec > $LOG 2>&1 + +RUN_STRING=$1 +KILL_STRING=${RUN_STRING//" & "/" "} +killall $KILL_STRING || true +exec sh -c "$RUN_STRING" diff --git a/.config/i3/.gitignore b/.config/i3/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/i3/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/neofetch/.gitignore b/.config/neofetch/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/neofetch/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/picom/.gitignore b/.config/picom/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/picom/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/polybar/.gitignore b/.config/polybar/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/polybar/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/rofi/.gitignore b/.config/rofi/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/rofi/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/starship/.gitignore b/.config/starship/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/starship/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/tmux/.gitignore b/.config/tmux/.gitignore new file mode 100644 index 0000000..5a23f60 --- /dev/null +++ b/.config/tmux/.gitignore @@ -0,0 +1,2 @@ +* +!tmux.conf diff --git a/.config/waybar/.gitignore b/.config/waybar/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/waybar/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/waybar/audio_output_status.sh b/.config/waybar/audio_output_status.sh new file mode 100755 index 0000000..3cdcafa --- /dev/null +++ b/.config/waybar/audio_output_status.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +get_default_sink_label() { + # Get the ID of the default sink (output device) + default_sink=$(wpctl status 2>/dev/null | awk '/Sinks:/,/Sources:/' | awk '/\*/ {print $3}' | tr -d '.') + + if [ -z "$default_sink" ]; then + echo "No default audio output device found" + exit 1 + fi + + # Get the description or fallback to node.name + device_name=$(wpctl inspect "$default_sink" 2>/dev/null | awk -F '"' '/node.description/ {print $2}') + + if [ -z "$device_name" ]; then + device_name=$(wpctl inspect "$default_sink" 2>/dev/null | awk -F '"' '/node.name/ {print $2}') + fi + + # Map known device names to labels + case "$device_name" in + "Starship/Matisse HD Audio Controller Analog Stereo") + label="Speakers" + ;; + "Yeti Stereo Microphone Analog Stereo") + label="Earphones" + ;; + *) + label="$device_name" + ;; + esac + + # Output the label + #echo "{\"text\":\"$label\",\"alt\":\"$device_name\"}" + printf '{"text":"%s","alt":"%s"}\n' "$label" "$device_name" +} + +get_default_sink_label + +pactl subscribe 2>/dev/null | while read -r line; do + # Filter for default sink or node changes + if echo "$line" | grep -qE "Event 'change' on sink #"; then + # Overwrite previous output + get_default_sink_label + fi +done diff --git a/.config/waybar/audio_output_switch.sh b/.config/waybar/audio_output_switch.sh new file mode 100755 index 0000000..7e49e19 --- /dev/null +++ b/.config/waybar/audio_output_switch.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Function to get the ID of the default sink +get_default_sink_id() { + wpctl status | awk '/Sinks:/,/Sources:/' | awk '/\*/ {print $3}' | tr -d '.' +} + +# Function to get the description of a sink by ID +get_sink_description() { + wpctl inspect "$1" | awk -F '"' '/node.description/ {print $2}' +} + +# Get current default sink ID +current_sink_id=$(get_default_sink_id) + +# If no sink found, exit +if [ -z "$current_sink_id" ]; then + echo "No default audio output device found" + exit 1 +fi + +# Get its description +current_description=$(get_sink_description "$current_sink_id") + +# Decide target device name based on current device +case "$current_description" in + "Starship/Matisse HD Audio Controller Analog Stereo") + target_description="Yeti Stereo Microphone Analog Stereo" + ;; + "Yeti Stereo Microphone Analog Stereo") + target_description="Starship/Matisse HD Audio Controller Analog Stereo" + ;; + *) + target_description="Yeti Stereo Microphone Analog Stereo" + ;; +esac + +# Find the sink ID of the target device +target_sink_id=$(wpctl status | awk '/Sinks:/,/Sources:/' | grep "$target_description" | awk '{print $2}' | tr -d '.') + +# If target sink found, switch to it +if [ -n "$target_sink_id" ]; then + wpctl set-default "$target_sink_id" + echo "Switched audio output to: $target_description" +else + echo "Target device '$target_description' not found." + exit 1 +fi diff --git a/.config/waybar/config.jsonc b/.config/waybar/config.jsonc new file mode 100644 index 0000000..dbdd834 --- /dev/null +++ b/.config/waybar/config.jsonc @@ -0,0 +1,205 @@ +// -*- mode: jsonc -*- +[ + { + "output": "!DP-2", + "height": 30, // Waybar height (to be removed for auto height) + "spacing": 4, // Gaps between modules (4px) + "modules-left": [ + "hyprland/workspaces", + "custom/sep", + "custom/media" + ], + "modules-center": [ + "hyprland/window" + ], + "modules-right": [ + "pulseaudio", + "custom/audio_device", + "custom/sep", + "network", + "custom/sep", + "cpu", + "custom/sep", + "memory", + "custom/sep", + "clock", + "custom/sep", + "custom/power" + ], + "custom/sep": { + "format": " | ", + "interval": 0, + "tooltip": false + }, + "hyprland/workspaces": { + "disable-scroll": true, + "all-outputs": false, + "warp-on-scroll": false, + "format": "{name}" + }, + "hyprland/window": { + "max-length": 40, + "separate-outputs": true + }, + "clock": { + "format": " {0:%H:%M:%S} {0:%a %d %b}", + //"format": " {time} {date}", + "tooltip-format": "{:%Y %B}\n{calendar}", + "format-alt": "{:%Y-%m-%d}" + }, + "cpu": { + "format": "{usage}%  ", + "tooltip": false + }, + "memory": { + "format": "{}% ({used}GiB)  " + }, + "network": { + "format-wifi": "{essid} ({signalStrength}%)  ", + "format-ethernet": "{ipaddr}/{cidr} 󱊪 ", + "tooltip-format": "{ifname} via {gwaddr}  ", + "format-disconnected": "Disconnected  " + }, + "pulseaudio": { + "scroll-step": 5, // %, can be a float + "format": "{volume}% {icon}", + "format-muted": "{volume}%  ", + "format-icons": { + "headphone": " ", + "default": [ + " ", + " ", + " " + ] + }, + "on-click": "pactl set-sink-mute @DEFAULT_SINK@ toggle" + }, + "custom/audio_device": { + "format": "{text}", + "tooltip": true, + "tooltip-format": "{alt}", + "return-type": "json", + "max-length": 40, + "escape": true, + "exec": "$HOME/.config/waybar/audio_output_status.sh 2>/dev/null", + "on-click": "$HOME/.config/waybar/audio_output_switch.sh 2>/dev/null" + }, + "custom/media": { + "format": "{icon} {text}", + "return-type": "json", + "max-length": 40, + "format-icons": { + "spotify": "", + "default": "🎜" + }, + "escape": true, + "exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder + //"exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name + }, + "custom/power": { + "format": "⏻ ", + "tooltip": false, + "menu": "on-click", + "menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder + "menu-actions": { + "lock": "hyprlock", + "shutdown": "shutdown", + "reboot": "reboot", + "suspend": "systemctl suspend", + "hibernate": "systemctl hibernate" + } + } + }, + { + "output": "DP-2", + "height": 30, // Waybar height (to be removed for auto height) + "spacing": 4, // Gaps between modules (4px) + "modules-left": [ + "hyprland/workspaces", + "custom/sep", + "custom/media" + ], + "modules-center": [ + "hyprland/window" + ], + "modules-right": [ + "pulseaudio", + "custom/sep", + "clock", + "custom/sep", + "custom/power" + ], + "custom/sep": { + "format": " | ", + "interval": 0, + "tooltip": false + }, + "hyprland/workspaces": { + "disable-scroll": true, + "all-outputs": false, + "warp-on-scroll": false, + "format": "{name}" + }, + "hyprland/window": { + "max-length": 40, + "separate-outputs": true + }, + "clock": { + "format": " {0:%H:%M:%S} {0:%a %d %b}", + //"format": " {time} {date}", + "tooltip-format": "{:%Y %B}\n{calendar}", + "format-alt": "{:%Y-%m-%d}" + }, + "cpu": { + "format": "{usage}%  ", + "tooltip": false + }, + "memory": { + "format": "{}% ({used}GiB)  " + }, + "network": { + "format-wifi": "{essid} ({signalStrength}%)  ", + "format-ethernet": "{ipaddr}/{cidr} 󱊪 ", + "tooltip-format": "{ifname} via {gwaddr}  ", + "format-disconnected": "Disconnected  " + }, + "pulseaudio": { + "scroll-step": 5, // %, can be a float + "format": "{volume}% {icon}", + "format-icons": { + "headphone": " ", + "default": [ + " ", + " ", + " " + ] + }, + "on-click": "pwvucontrol" + }, + "custom/media": { + "format": "{icon} {text}", + "return-type": "json", + "max-length": 40, + "format-icons": { + "spotify": "", + "default": "🎜" + }, + "escape": true, + //"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder + "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name + }, + "custom/power": { + "format": "⏻ ", + "tooltip": false, + "menu": "on-click", + "menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder + "menu-actions": { + "lock": "hyprlock", + "shutdown": "shutdown", + "reboot": "reboot", + "suspend": "systemctl suspend", + "hibernate": "systemctl hibernate" + } + } + } +] diff --git a/.config/waybar/mediaplayer.py b/.config/waybar/mediaplayer.py new file mode 100755 index 0000000..9c2dfc9 --- /dev/null +++ b/.config/waybar/mediaplayer.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python3 +import gi + +gi.require_version("Playerctl", "2.0") +import argparse +import json +import logging +import os +import signal +import sys +from typing import List + +import gi +from gi.repository import GLib, Playerctl +from gi.repository.Playerctl import Player + +logger = logging.getLogger(__name__) + + +def signal_handler(sig, frame): + logger.info("Received signal to stop, exiting") + sys.stdout.write("\n") + sys.stdout.flush() + # loop.quit() + sys.exit(0) + + +class PlayerManager: + def __init__(self, selected_player=None, excluded_player=[]): + self.manager = Playerctl.PlayerManager() + self.loop = GLib.MainLoop() + self.manager.connect( + "name-appeared", lambda *args: self.on_player_appeared(*args) + ) + self.manager.connect( + "player-vanished", lambda *args: self.on_player_vanished(*args) + ) + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + self.selected_player = selected_player + self.excluded_player = excluded_player.split(",") if excluded_player else [] + + self.init_players() + + def init_players(self): + for player in self.manager.props.player_names: + if player.name in self.excluded_player: + continue + if self.selected_player is not None and self.selected_player != player.name: + logger.debug(f"{player.name} is not the filtered player, skipping it") + continue + self.init_player(player) + + def run(self): + logger.info("Starting main loop") + self.loop.run() + + def init_player(self, player): + logger.info(f"Initialize new player: {player.name}") + player = Playerctl.Player.new_from_name(player) + player.connect("playback-status", self.on_playback_status_changed, None) + player.connect("metadata", self.on_metadata_changed, None) + self.manager.manage_player(player) + self.on_metadata_changed(player, player.props.metadata) + + def get_players(self) -> List[Player]: + return self.manager.props.players + + def write_output(self, text, player): + logger.debug(f"Writing output: {text}") + + output = { + "text": text, + "class": "custom-" + player.props.player_name, + "alt": player.props.player_name, + } + + sys.stdout.write(json.dumps(output) + "\n") + sys.stdout.flush() + + def clear_output(self): + sys.stdout.write("\n") + sys.stdout.flush() + + def on_playback_status_changed(self, player, status, _=None): + logger.debug( + f"Playback status changed for player {player.props.player_name}: {status}" + ) + self.on_metadata_changed(player, player.props.metadata) + + def get_first_playing_player(self): + players = self.get_players() + logger.debug(f"Getting first playing player from {len(players)} players") + if len(players) > 0: + # if any are playing, show the first one that is playing + # reverse order, so that the most recently added ones are preferred + for player in players[::-1]: + if player.props.status == "Playing": + return player + # if none are playing, show the first one + return players[0] + else: + logger.debug("No players found") + return None + + def show_most_important_player(self): + logger.debug("Showing most important player") + # show the currently playing player + # or else show the first paused player + # or else show nothing + current_player = self.get_first_playing_player() + if current_player is not None: + self.on_metadata_changed(current_player, current_player.props.metadata) + else: + self.clear_output() + + def on_metadata_changed(self, player, metadata, _=None): + logger.debug(f"Metadata changed for player {player.props.player_name}") + player_name = player.props.player_name + artist = player.get_artist() + artist = artist.replace("&", "&") + title = player.get_title() + title = title.replace("&", "&") + + track_info = "" + if ( + player_name == "spotify" + and "mpris:trackid" in metadata.keys() + and ":ad:" in player.props.metadata["mpris:trackid"] + ): + track_info = "Advertisement" + elif artist is not None and title is not None: + track_info = f"{artist} - {title}" + else: + track_info = title + + if track_info: + if player.props.status == "Playing": + track_info = " " + track_info + else: + track_info = " " + track_info + # only print output if no other player is playing + current_playing = self.get_first_playing_player() + if ( + current_playing is None + or current_playing.props.player_name == player.props.player_name + ): + self.write_output(track_info, player) + else: + logger.debug( + f"Other player {current_playing.props.player_name} is playing, skipping" + ) + + def on_player_appeared(self, _, player): + logger.info(f"Player has appeared: {player.name}") + if player.name in self.excluded_player: + logger.debug( + "New player appeared, but it's in exclude player list, skipping" + ) + return + if player is not None and ( + self.selected_player is None or player.name == self.selected_player + ): + self.init_player(player) + else: + logger.debug( + "New player appeared, but it's not the selected player, skipping" + ) + + def on_player_vanished(self, _, player): + logger.info(f"Player {player.props.player_name} has vanished") + self.show_most_important_player() + + +def parse_arguments(): + parser = argparse.ArgumentParser() + + # Increase verbosity with every occurrence of -v + parser.add_argument("-v", "--verbose", action="count", default=0) + + parser.add_argument("-x", "--exclude", "- Comma-separated list of excluded player") + + # Define for which player we"re listening + parser.add_argument("--player") + + parser.add_argument("--enable-logging", action="store_true") + + return parser.parse_args() + + +def main(): + arguments = parse_arguments() + + # Initialize logging + if arguments.enable_logging: + logfile = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "media-player.log" + ) + logging.basicConfig( + filename=logfile, + level=logging.DEBUG, + format="%(asctime)s %(name)s %(levelname)s:%(lineno)d %(message)s", + ) + + # Logging is set by default to WARN and higher. + # With every occurrence of -v it's lowered by one + logger.setLevel(max((3 - arguments.verbose) * 10, 0)) + + logger.info("Creating player manager") + if arguments.player: + logger.info(f"Filtering for player: {arguments.player}") + if arguments.exclude: + logger.info(f"Exclude player {arguments.exclude}") + + player = PlayerManager(arguments.player, arguments.exclude) + player.run() + + +if __name__ == "__main__": + main() diff --git a/.config/waybar/mocha.css b/.config/waybar/mocha.css new file mode 100644 index 0000000..0eb6a82 --- /dev/null +++ b/.config/waybar/mocha.css @@ -0,0 +1,26 @@ +@define-color rosewater #f5e0dc; +@define-color flamingo #f2cdcd; +@define-color pink #f5c2e7; +@define-color mauve #cba6f7; +@define-color red #f38ba8; +@define-color maroon #eba0ac; +@define-color peach #fab387; +@define-color yellow #f9e2af; +@define-color green #a6e3a1; +@define-color teal #94e2d5; +@define-color sky #89dceb; +@define-color sapphire #74c7ec; +@define-color blue #89b4fa; +@define-color lavender #b4befe; +@define-color text #cdd6f4; +@define-color subtext1 #bac2de; +@define-color subtext0 #a6adc8; +@define-color overlay2 #9399b2; +@define-color overlay1 #7f849c; +@define-color overlay0 #6c7086; +@define-color surface2 #585b70; +@define-color surface1 #45475a; +@define-color surface0 #313244; +@define-color base #1e1e2e; +@define-color mantle #181825; +@define-color crust #11111b; diff --git a/.config/waybar/power_menu.xml b/.config/waybar/power_menu.xml new file mode 100644 index 0000000..3704573 --- /dev/null +++ b/.config/waybar/power_menu.xml @@ -0,0 +1,33 @@ + + + + + + Lock + + + + + Suspend + + + + + Hibernate + + + + + Shutdown + + + + + + + + Reboot + + + + diff --git a/.config/waybar/style.css b/.config/waybar/style.css new file mode 100644 index 0000000..42070a1 --- /dev/null +++ b/.config/waybar/style.css @@ -0,0 +1,11 @@ +@import "mocha.css"; +* { + /* reference the color by using @color-name */ + color: @text; +} + +window#waybar { + /* you can also GTK3 CSS functions! */ + background-color: shade(@base, 0.9); + border: 2px solid alpha(@crust, 0.3); +} diff --git a/.config/wofi/.gitignore b/.config/wofi/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/wofi/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/wofi/style.css b/.config/wofi/style.css new file mode 100644 index 0000000..5eb4a00 --- /dev/null +++ b/.config/wofi/style.css @@ -0,0 +1,42 @@ +/* The name of the window itself */ +#window { + background-color: #313244; + box-shadow: + 0 10px 15px -3px rgba(0, 0, 0, 0.1), + 0 4px 6px -4px rgba(0, 0, 0, 0.1); + border-radius: 1rem; + font-size: 1.2rem; + /* The name of the box that contains everything */ +} +#window #outer-box #input { + background-color: #1e1e2e; + color: #f2f2f2; + border: none; + border-bottom: 1px solid #181825; + padding: 0.8rem 1rem; + font-size: 1.5rem; + border-radius: 1rem 1rem 0 0; +} +#window #outer-box #input:focus, +#window #outer-box #input:focus-visible, +#window #outer-box #input:active { + border: none; + outline: 2px solid transparent; + outline-offset: 2px; +} +#window #outer-box #scroll #inner-box #entry { + color: #cdd6f4; + background-color: none; + padding: 0.6rem 1rem; + /* The name of all images in entries displayed in image mode */ + /* The name of all the text in entries */ +} +#window #outer-box #scroll #inner-box #entry #img { + width: 1rem; + margin-right: 0.5rem; +} +#window #outer-box #scroll #inner-box #entry:selected { + color: #cdd6f4; + background-color: none; + outline: none; +} diff --git a/.config/zsh-vim-mode/.gitignore b/.config/zsh-vim-mode/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.config/zsh-vim-mode/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.config/zsh-vim-mode/zsh-vim-mode.plugin.zsh b/.config/zsh-vim-mode/zsh-vim-mode.plugin.zsh new file mode 100644 index 0000000..d2c9aae --- /dev/null +++ b/.config/zsh-vim-mode/zsh-vim-mode.plugin.zsh @@ -0,0 +1,677 @@ +# Global aliases can break things. Unset before using any non-builtins. +[[ -o aliases ]] && _vim_mode_shopt_aliases=1 +builtin set -o no_aliases + +bindkey -v + +#${(%):-%x}_debug () { print -r "$(date) $@" >> /tmp/zsh-debug-vim-mode.log 2>&1 } + + +# Special keys {{{1 + +# NB: The terminfo sequences are meant to be used with the terminal +# in *application mode*. This is properly initiated with `echoti smkx`, +# usually in a zle line-init hook widget. But it may cause problems: +# https://github.com/robbyrussell/oh-my-zsh/pull/5113 +# +# So for now, leave smkx untouched, and let the framework deal with it. +# Instead, read from terminfo but also hard-code values that various +# terminals use. +# +# Please open an issue if your special keys (Home, End, arrow keys, +# etc.) are not being recognized here! +# +# Extra info: +# http://invisible-island.net/xterm/xterm.faq.html#xterm_arrows +# https://stackoverflow.com/a/29408977/749778 + +zmodload zsh/terminfo + +typeset -A -H vim_mode_special_keys + +function vim-mode-define-special-key () { + local name="$1" tiname="$2" + local -a seqs + # Note that (V) uses the "^[" notation for , and "^X" for + [[ -n $tiname && -n $terminfo[$tiname] ]] && seqs+=${(V)terminfo[$tiname]} + for seq in ${@[3,-1]}; do + seqs+=$seq + done + vim_mode_special_keys[$name]=${${(uOqqq)seqs}} +} + +# Explicitly check for VT100 versions (both normal and application mode) +vim-mode-define-special-key Left kcub1 "^[[D" "^[OD" +vim-mode-define-special-key Right kcuf1 "^[[C" "^[OC" +vim-mode-define-special-key Up kcuu1 "^[[A" "^[OA" +vim-mode-define-special-key Down kcud1 "^[[B" "^[OB" +# These are XTerm and various others +vim-mode-define-special-key Home khome "^[[1~" "^[[H" +vim-mode-define-special-key End kend "^[[4~" "^[[F" +vim-mode-define-special-key PgUp kpp "^[[5~" +vim-mode-define-special-key PgDown knp "^[[6~" +vim-mode-define-special-key Insert kich1 "^[[2~" +vim-mode-define-special-key Delete kdch1 "^[[3~" +vim-mode-define-special-key Shift-Tab kcbt "^[[Z" +# These aren't in terminfo; these are for: XTerm & Rxvt +vim-mode-define-special-key Ctrl-Left '' "^[[1;5D" "^[Od" +vim-mode-define-special-key Ctrl-Right '' "^[[1;5C" "^[Oc" +vim-mode-define-special-key Ctrl-Up '' "^[[1;5A" "^[Oa" +vim-mode-define-special-key Ctrl-Down '' "^[[1;5B" "^[Ob" +vim-mode-define-special-key Alt-Left '' "^[[1;3D" "^[^[[D" +vim-mode-define-special-key Alt-Right '' "^[[1;3C" "^[^[[C" +vim-mode-define-special-key Alt-Up '' "^[[1;3A" "^[^[[A" +vim-mode-define-special-key Alt-Down '' "^[[1;3B" "^[^[[B" + +#for k in ${(k)vim_mode_special_keys}; do +# printf '%-12s' "$k:"; +# for x in ${(z)vim_mode_special_keys[$k]}; do printf "%8s" ${(Q)x}; done; +# printf "\n"; +#done + + +# + vim-mode-bindkey {{{1 +function vim-mode-bindkey () { + local -a maps + local command + + while (( $# )); do + [[ $1 = '--' ]] && break + maps+=$1 + shift + done + shift + + command=$1 + shift + + # A key combo can be made of more than one key press, so a binding for + # will map to '^[[1~^[[4~', for example. XXX Except this + # doesn't seem to work. ZLE just wants a single special key for viins + # & vicmd (multiples work in emacs). Oh, well, this accumulator + # doesn't hurt and may come in handy. Just only call vim-mode-bindkey + # with one special key. + + function vim-mode-accum-combo () { + typeset -g -a combos + local combo="$1"; shift + if (( $#@ )); then + local cur="$1"; shift + if (( ${+vim_mode_special_keys[$cur]} )); then + for seq in ${(z)vim_mode_special_keys[$cur]}; do + vim-mode-accum-combo "$combo${(Q)seq}" "$@" + done + else + vim-mode-accum-combo "$combo$cur" "$@" + fi + else + combos+="$combo" + fi + } + + local -a combos + vim-mode-accum-combo '' "$@" + for c in ${combos}; do + for m in ${maps}; do + bindkey -M $m "$c" $command + done + done +} + +if [[ -z $VIM_MODE_NO_DEFAULT_BINDINGS ]]; then + # Emacs-like bindings {{{1 + vim-mode-bindkey viins vicmd -- beginning-of-line '^A' + vim-mode-bindkey viins vicmd -- backward-char '^B' + vim-mode-bindkey viins vicmd -- end-of-line '^E' + vim-mode-bindkey viins vicmd -- forward-char '^F' + vim-mode-bindkey viins vicmd -- kill-line '^K' + vim-mode-bindkey viins vicmd -- history-incremental-search-backward '^R' + vim-mode-bindkey viins vicmd -- history-incremental-search-forward '^S' + vim-mode-bindkey viins vicmd -- backward-kill-line '^U' + vim-mode-bindkey viins vicmd -- backward-kill-word '^W' + vim-mode-bindkey viins vicmd -- yank '^Y' + vim-mode-bindkey viins vicmd -- undo '^_' + + # Avoid key bindings that conflict with entering NORMAL mode, like + # - common movement keys (hljk...) + # - common actions (dxcr...) + # But make this configurable: some people will never use ^[b and would + # rather be sure not to have a conflict, while others use it a lot and will + # rarely type 'b' as the first key in NORMAL mode. Which behavior shoudl win + # is very user-dependent. + vim-mode-maybe-bind() { + local k="$1"; shift + if (( $+VIM_MODE_VICMD_KEY )) \ + || [[ ${VIM_MODE_ESC_PREFIXED_WANTED-^?^Hbdf.g} = *${k}* ]]; + then + vim-mode-bindkey "$@" + fi + } + + vim-mode-maybe-bind '^?' viins vicmd -- backward-kill-word '^[^?' + vim-mode-maybe-bind '^H' viins vicmd -- backward-kill-word '^[^H' + vim-mode-maybe-bind b viins vicmd -- backward-word '^[b' + vim-mode-maybe-bind d viins vicmd -- kill-word '^[d' + vim-mode-maybe-bind f viins vicmd -- forward-word '^[f' + vim-mode-maybe-bind h viins -- run-help '^[h' + # u is not likely to cause conflict, but keep it here with l + vim-mode-maybe-bind u viins -- up-case-word '^[u' + vim-mode-maybe-bind l viins -- down-case-word '^[l' + + # Some -prefixed bindings that should rarely conflict with NORMAL mode, + # so always define them + # '.' usually comes after some other keystrokes + vim-mode-maybe-bind . viins vicmd -- insert-last-word '^[.' + # 'g...' bindings are not commonly-used; see `bindkey -pM vicmd g` + vim-mode-maybe-bind g viins -- get-line '^[g' + vim-mode-bindkey viins -- push-line '^Q' + + vim-mode-bindkey viins vicmd -- beginning-of-line Home + vim-mode-bindkey viins vicmd -- end-of-line End + vim-mode-bindkey viins vicmd -- backward-word Ctrl-Left + vim-mode-bindkey viins vicmd -- backward-word Alt-Left + vim-mode-bindkey viins vicmd -- forward-word Ctrl-Right + vim-mode-bindkey viins vicmd -- forward-word Alt-Right + vim-mode-bindkey viins vicmd -- up-line-or-history PgUp + vim-mode-bindkey viins vicmd -- down-line-or-history PgDown + + vim-mode-bindkey viins -- overwrite-mode Insert + vim-mode-bindkey viins -- delete-char Delete + vim-mode-bindkey viins -- reverse-menu-complete Shift-Tab + vim-mode-bindkey viins -- delete-char-or-list '^D' + vim-mode-bindkey viins -- backward-delete-char '^H' + vim-mode-bindkey viins -- backward-delete-char '^?' + vim-mode-bindkey viins -- redisplay '^X^R' + vim-mode-bindkey viins -- exchange-point-and-mark '^X^X' + + vim-mode-bindkey vicmd -- run-help 'H' + vim-mode-bindkey vicmd -- redo 'U' + vim-mode-bindkey vicmd -- vi-yank-eol 'Y' + + autoload -U edit-command-line + zle -N edit-command-line + vim-mode-bindkey viins vicmd -- edit-command-line '^X^E' + vim-mode-bindkey vicmd -- edit-command-line '^V' + + if [[ -n $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND ]]; then + vim-mode-bindkey viins vicmd -- history-substring-search-up '^P' + vim-mode-bindkey viins vicmd -- history-substring-search-down '^N' + vim-mode-bindkey viins vicmd -- history-substring-search-up Up + vim-mode-bindkey viins vicmd -- history-substring-search-down Down + else + autoload -Uz history-search-end + zle -N history-beginning-search-backward-end history-search-end + zle -N history-beginning-search-forward-end history-search-end + + vim-mode-bindkey viins vicmd -- history-beginning-search-backward-end '^P' + vim-mode-bindkey viins vicmd -- history-beginning-search-forward-end '^N' + vim-mode-bindkey viins vicmd -- history-beginning-search-backward-end Up + vim-mode-bindkey viins vicmd -- history-beginning-search-forward-end Down + fi + + # Compatibility with zsh-autosuggestions; see issue #25 + if zle -la up-line-or-beginning-search; then + vim-mode-bindkey vicmd -- down-line-or-beginning-search j + vim-mode-bindkey vicmd -- up-line-or-beginning-search k + fi + + exit-cmd () {exit;} + zle -N exit-cmd + vim-mode-bindkey vicmd -- exit-cmd Z Z + vim-mode-bindkey vicmd -- exit-cmd Z Q + + + # Enable surround text-objects (quotes, brackets) {{{1 + + autoload -U select-bracketed + zle -N select-bracketed + for m in visual viopp; do + for c in {a,i}${(s..)^:-'()[]{}<>bB'}; do + vim-mode-bindkey $m -- select-bracketed $c + done + done + + autoload -U select-quoted + zle -N select-quoted + for m in visual viopp; do + for c in {a,i}{\',\",\`}; do + vim-mode-bindkey $m -- select-quoted $c + done + done + + autoload -Uz surround + zle -N delete-surround surround + zle -N change-surround surround + zle -N add-surround surround + vim-mode-bindkey vicmd -- change-surround cs + vim-mode-bindkey vicmd -- delete-surround ds + vim-mode-bindkey vicmd -- add-surround ys + vim-mode-bindkey visual -- add-surround S + + + # Escape shortcut {{{1 + # From http://bewatermyfriend.org/posts/2010/08-08.21-16-02-computer.html + # > Copyright (c) 2010, Frank Terbeck + # > The same licensing terms as with zsh apply. + if (( $+VIM_MODE_VICMD_KEY )); then + vim-mode-bindkey viins -- vi-cmd-mode "$VIM_MODE_VICMD_KEY" + + case $VIM_MODE_VICMD_KEY in + ^[Dd] ) + builtin set -o ignore_eof + vim-mode-bindkey vicmd -- vim-mode-accept-or-eof "$VIM_MODE_VICMD_KEY" + + function vim-mode-accept-or-eof() { + if [[ $#BUFFER = 0 ]]; then + exit + else + zle accept-line + fi + } + zle -N vim-mode-accept-or-eof + ;; + esac + fi + + unfunction vim-mode-maybe-bind +fi + +# Identifying the editing mode {{{1 + +if [[ $VIM_MODE_TRACK_KEYMAP != no ]]; then + # Export the main variable so higher-level processes can view it; + # e.g., github:starship/starship uses this + export VIM_MODE_KEYMAP + + autoload -Uz add-zsh-hook + autoload -Uz add-zle-hook-widget + + # Compatibility with old variable names + (( $+MODE_INDICATOR_I )) && : ${MODE_INDICATOR_VIINS=MODE_INDICATOR_I} + (( $+MODE_INDICATOR_N )) && : ${MODE_INDICATOR_VICMD=MODE_INDICATOR_N} + (( $+MODE_INDICATOR_C )) && : ${MODE_INDICATOR_SEARCH=MODE_INDICATOR_C} + + typeset -g -a vim_mode_keymap_funcs=() + + vim-mode-precmd () { vim-mode-handle-event precmd "$KEYMAP" } + add-zsh-hook precmd vim-mode-precmd + + vim-mode-isearch-update () { vim-mode-handle-event isearch-update "$KEYMAP" } + vim-mode-isearch-exit () { vim-mode-handle-event isearch-exit "$KEYMAP" } + vim-mode-line-pre-redraw () { vim-mode-handle-event line-pre-redraw "$KEYMAP" } + vim-mode-line-init () { vim-mode-handle-event line-init "$KEYMAP" } + + () { + local w; for w in "$@"; do add-zle-hook-widget $w vim-mode-$w; done + } isearch-exit isearch-update line-pre-redraw line-init + + typeset -g vim_mode_keymap_state= + + vim-mode-handle-event () { + #${(%):-%x}_debug "handle-event [${(qq)@}][cur:${VIM_MODE_KEYMAP}]" + + local hook="$1" + local keymap="$2" + rc=0 # Assume we'll succeed + + case $hook in + line-init ) + [[ $VIM_MODE_KEYMAP = vicmd ]] && zle && zle vi-cmd-mode + ;; + line-pre-redraw ) + # This hook is called (maybe several times) on every action except + # for the initial prompt drawing + case $vim_mode_keymap_state in + '' ) + vim_mode_set_keymap "$keymap" + ;; + *-escape ) + vim_mode_set_keymap "${vim_mode_keymap_state%-escape}" + vim_mode_keymap_state= + ;; + *-update ) + # Normal update in isearch mode + vim_mode_keymap_state=${vim_mode_keymap_state%-update} + vim_mode_set_keymap isearch + ;; + * ) + # ^C was hit during isearch mode! + vim_mode_set_keymap "$vim_mode_keymap_state" + vim_mode_keymap_state= + ;; + esac + ;; + isearch-update ) + if [[ $keymap = vicmd ]]; then + # This is an abnormal exit from search (like ) + vim_mode_keymap_state+='-escape' + elif [[ $VIM_MODE_KEYMAP != isearch ]]; then + # Normal update, starting search mode + vim_mode_keymap_state=${VIM_MODE_KEYMAP}-update + else + # Normal update, staying in search mode + vim_mode_keymap_state+=-update + fi + ;; + isearch-exit ) + if [[ $VIM_MODE_KEYMAP = isearch ]]; then + # This could be a normal (movement key) exit, but it could also + # be ^G which behaves almost like . So don't trust $keymap. + vim_mode_keymap_state+='-escape' + fi + + # Otherwise, we already exited search via abnormal isearch-update, + # so there is nothing to do here. + ;; + precmd ) + # When the prompt is first shown line-pre-redraw does not get called + # so the state must be initialized here + vim_mode_keymap_state= + vim_mode_set_keymap $(vim-mode-initial-keymap) + ;; + * ) + # Should not happen + zle && zle -M "zsh-vim-mode internal error: bad hook $hook" + rc=1 # Oops + ;; + esac + + return $rc + } + + vim_mode_set_keymap () { + local keymap="$1" + + [[ $keymap = main || $keymap = '' ]] && keymap=viins + + if [[ $keymap = vicmd ]]; then + local active=${REGION_ACTIVE:-0} + if [[ $active = 1 ]]; then + keymap=visual + elif [[ $active = 2 ]]; then + keymap=vline + fi + elif [[ $keymap = viins ]]; then + [[ $ZLE_STATE = *overwrite* ]] && keymap=replace + fi + + #${(%):-%x}_debug " -> $keymap" + + [[ $VIM_MODE_KEYMAP = $keymap ]] && return + + # Can be used by prompt themes, etc. + VIM_MODE_KEYMAP=$keymap + + local func + for func in ${vim_mode_keymap_funcs[@]}; do + ${func} "$keymap" + done + } + + vim-mode-initial-keymap () { + case ${VIM_MODE_INITIAL_KEYMAP:-viins} in + last) + case $VIM_MODE_KEYMAP in + vicmd|visual|vline) print vicmd ;; + *) print viins ;; + esac + ;; + vicmd) + print vicmd ;; + *) + print viins ;; + esac + } + + # Editing mode indicator - Prompt string {{{1 + + # Unique prefix to tag the mode indicator text in the prompt. + # If ZLE_RPROMPT_INDENT is < 1, zle gets confused if $RPS1 isn't empty but + # printing it doesn't move the cursor. + (( ${ZLE_RPROMPT_INDENT:-1} > 0 )) \ + && vim_mode_indicator_pfx="%837(l,,)" \ + || vim_mode_indicator_pfx="%837(l,, )" + + # If mode indicator wasn't setup by theme, define default + vim-mode-set-up-indicators () { + local indicator=${MODE_INDICATOR_VICMD-${MODE_INDICATOR-DEFAULT}} + local set=$(( + $+MODE_INDICATOR_VIINS + + $+MODE_INDICATOR_REPLACE + + $+MODE_INDICATOR_VICMD + + $+MODE_INDICATOR_SEARCH + + $+MODE_INDICATOR_VISUAL + + $+MODE_INDICATOR_VLINE)) + + if [[ -n $indicator || $set > 0 ]]; then + if (( ! $set )); then + if [[ $indicator = DEFAULT ]]; then + MODE_INDICATOR_VICMD='%F{10}<%F{2}<<%f' + MODE_INDICATOR_REPLACE='%F{9}<%F{1}*<%f' + MODE_INDICATOR_SEARCH='%F{13}<%F{5}?<%f' + MODE_INDICATOR_VISUAL='%F{12}<%F{4}-<%f' + MODE_INDICATOR_VLINE='%F{12}<%F{4}=<%f' + else + MODE_INDICATOR_VICMD=$indicator + fi + + # Replace / Search indicator defaults to viins + (( $+MODE_INDICATOR_VIINS )) && \ + : ${MODE_INDICATOR_REPLACE=$MODE_INDICATOR_VIINS} + (( $+MODE_INDICATOR_VIINS )) && \ + : ${MODE_INDICATOR_SEARCH=$MODE_INDICATOR_VIINS} + + # Visual indicator defaults to vicmd + (( $+MODE_INDICATOR_VICMD )) && \ + : ${MODE_INDICATOR_VISUAL=$MODE_INDICATOR_VICMD} + (( $+MODE_INDICATOR_VISUAL )) && \ + : ${MODE_INDICATOR_VLINE=$MODE_INDICATOR_VISUAL} + + MODE_INDICATOR_PROMPT=${vim_mode_indicator_pfx}${MODE_INDICATOR_VIINS} + + if (( !$+RPS1 )); then + [[ -o promptsubst ]] \ + && RPS1='${MODE_INDICATOR_PROMPT}' \ + || RPS1="$MODE_INDICATOR_PROMPT" + fi + fi + else + unset MODE_INDICATOR_PROMPT + fi + } + + vim-mode-update-prompt () { + local keymap="$1" + + # See if user requested indicators since last time + (( $+MODE_INDICATOR_PROMPT )) || vim-mode-set-up-indicators + (( $+MODE_INDICATOR_PROMPT )) || return + + local -A modes=( + I ${vim_mode_indicator_pfx}${MODE_INDICATOR_VIINS} + C ${vim_mode_indicator_pfx}${MODE_INDICATOR_VICMD} + R ${vim_mode_indicator_pfx}${MODE_INDICATOR_REPLACE} + S ${vim_mode_indicator_pfx}${MODE_INDICATOR_SEARCH} + V ${vim_mode_indicator_pfx}${MODE_INDICATOR_VISUAL} + L ${vim_mode_indicator_pfx}${MODE_INDICATOR_VLINE} + # In case user has changed the mode string since last call, look + # for the previous value as well as set of current values + p ${MODE_INDICATOR_PROMPT} + ) + + # Pattern that will match any value from $modes. Reverse sort, so that + # if one pattern is a prefix of a longer one, it will be tried after. + local any_mode=${(j:|:)${(Obu)modes}} + + (( $+RPROMPT )) && : ${RPS1=$RPROMPT} + local prompts="$PS1 $RPS1" + + case $keymap in + vicmd) MODE_INDICATOR_PROMPT=$modes[C] ;; + replace) MODE_INDICATOR_PROMPT=$modes[R] ;; + isearch) MODE_INDICATOR_PROMPT=$modes[S] ;; + visual) MODE_INDICATOR_PROMPT=$modes[V] ;; + vline) MODE_INDICATOR_PROMPT=$modes[L] ;; + main|viins|*) MODE_INDICATOR_PROMPT=$modes[I] ;; + esac + + if [[ ${(SN)prompts#${~any_mode}} > 0 ]]; then + PS1=${PS1//${~any_mode}/$MODE_INDICATOR_PROMPT} + RPS1=${RPS1//${~any_mode}/$MODE_INDICATOR_PROMPT} + fi + + zle || return + zle reset-prompt + } + + # Compatibility with oh-my-zsh vi-mode + function vi_mode_prompt_info() { + print ${MODE_INDICATOR_PROMPT} + } + + vim-mode-set-up-indicators + vim_mode_keymap_funcs+=vim-mode-update-prompt + + + # Editing mode indicator - Cursor shape {{{1 + # + # Compatibility with old variable names + (( $+ZSH_VIM_MODE_CURSOR_VIINS )) \ + && : ${MODE_CURSOR_VIINS=ZSH_VIM_MODE_CURSOR_VIINS} + (( $+ZSH_VIM_MODE_CURSOR_REPLACE )) \ + && : ${MODE_CURSOR_REPLACE=ZSH_VIM_MODE_CURSOR_REPLACE} + (( $+ZSH_VIM_MODE_CURSOR_VICMD )) \ + && : ${MODE_CURSOR_VICMD=ZSH_VIM_MODE_CURSOR_VICMD} + (( $+ZSH_VIM_MODE_CURSOR_ISEARCH )) \ + && : ${MODE_CURSOR_SEARCH=ZSH_VIM_MODE_CURSOR_ISEARCH} + (( $+ZSH_VIM_MODE_CURSOR_VISUAL )) \ + && : ${MODE_CURSOR_VISUAL=ZSH_VIM_MODE_CURSOR_VISUAL} + (( $+ZSH_VIM_MODE_CURSOR_VLINE )) \ + && : ${MODE_CURSOR_VLINE=ZSH_VIM_MODE_CURSOR_VLINE} + (( $+ZSH_VIM_MODE_CURSOR_DEFAULT )) \ + && : ${MODE_CURSOR_DEFAULT=ZSH_VIM_MODE_CURSOR_DEFAULT} + + # You may want to set this to '', if your cursor stops blinking + # when you didn't ask it to. Some terminals, e.g., xterm, don't blink + # initially but do blink after the set-to-default sequence. So this + # forces it to steady, which should match most default setups. + : ${MODE_CURSOR_DEFAULT:=steady} + + send-terminal-sequence() { + local sequence="$1" + local is_tmux + + # Older TMUX (before 1.5) does not handle cursor styling and needs + # to be told to pass those escape sequences directly to the terminal + if [[ $TMUX_PASSTHROUGH = 1 ]]; then + # Double each escape (see zshbuiltins(1) echo for backslash escapes) + # And wrap it in the TMUX DCS passthrough + sequence=${sequence//\\(e|x27|033|[uU]00*1[bB])/\\e\\e} + sequence="\ePtmux;$sequence\e\\" + fi + print -n "$sequence" + } + + set-terminal-cursor-style() { + local steady= + local shape= + local color= + + for setting in ${=MODE_CURSOR_DEFAULT} "$@"; do + case $setting in + blinking) steady=0 ;; + steady) steady=1 ;; + block) shape=1 ;; + underline) shape=3 ;; + beam|bar) shape=5 ;; + *) color="$setting" ;; + esac + done + + # OSC Ps ; Pt BEL + # Ps = 1 2 -> Change text cursor color to Pt. + # Ps = 1 1 2 -> Reset text cursor color. + + if [[ -z $color ]]; then + # Reset cursor color + send-terminal-sequence "\e]112\a" + else + # Note: Color is "specified by name or RGB specification as per + # XParseColor", according to XTerm docs + send-terminal-sequence "\e]12;${color}\a" + fi + + # CSI Ps SP q + # Set cursor style (DECSCUSR), VT520. + # Ps = 0 -> blinking block. + # Ps = 1 -> blinking block (default). + # Ps = 2 -> steady block. + # Ps = 3 -> blinking underline. + # Ps = 4 -> steady underline. + # Ps = 5 -> blinking bar (xterm). + # Ps = 6 -> steady bar (xterm). + + if [[ -z $steady && -z $shape ]]; then + send-terminal-sequence "\e[0 q" + else + [[ -z $shape ]] && shape=1 + [[ -z $steady ]] && steady=1 + send-terminal-sequence "\e[$((shape + steady)) q" + fi + } + + vim-mode-set-cursor-style() { + local keymap="$1" + + if [[ -n $MODE_CURSOR_VIINS \ + || -n $MODE_CURSOR_REPLACE \ + || -n $MODE_CURSOR_VICMD \ + || -n $MODE_CURSOR_SEARCH \ + || -n $MODE_CURSOR_VISUAL \ + || -n $MODE_CURSOR_VLINE \ + ]] + then + case $keymap in + DEFAULT) set-terminal-cursor-style ;; + replace) set-terminal-cursor-style ${=MODE_CURSOR_REPLACE-$=MODE_CURSOR_VIINS} ;; + vicmd) set-terminal-cursor-style ${=MODE_CURSOR_VICMD} ;; + isearch) set-terminal-cursor-style ${=MODE_CURSOR_SEARCH-$=MODE_CURSOR_VIINS} ;; + visual) set-terminal-cursor-style ${=MODE_CURSOR_VISUAL-$=MODE_CURSOR_VIINS} ;; + vline) set-terminal-cursor-style ${=MODE_CURSOR_VLINE-${=MODE_CURSOR_VISUAL-$=MODE_CURSOR_VIINS}} ;; + + main|viins|*) + set-terminal-cursor-style ${=MODE_CURSOR_VIINS} ;; + esac + fi + + # Success + return 0 + } + + vim-mode-cursor-init-hook() { + vim-mode-set-cursor-style $(vim-mode-initial-keymap) + } + + vim-mode-cursor-finish-hook() { + vim-mode-set-cursor-style DEFAULT + } + + # See https://github.com/softmoth/zsh-vim-mode/issues/6#issuecomment-413606070 + if [[ $TERM = (dumb|linux|eterm-color) ]] || (( $+KONSOLE_PROFILE_NAME )); then + # Disable cursor styling on unsupported terminals + : + else + vim_mode_keymap_funcs+=vim-mode-set-cursor-style + + add-zsh-hook precmd vim-mode-cursor-init-hook + add-zle-hook-widget line-finish vim-mode-cursor-finish-hook + fi +fi + +# Restore shell option 'aliases'. This must be the last thing here. +if [[ $_vim_mode_shopt_aliases = 1 ]]; then + unset _vim_mode_shopt_aliases + set -o aliases +fi + +# vim:set ft=zsh sw=4 et fdm=marker: diff --git a/.gitignore b/.gitignore index 217f8a2..5de8ae7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,14 +3,5 @@ !.gitignore !.gitmodules !.zshrc -!.local/bin -!.config/alacritty -!.config/bat -!.config/btop -!.config/i3 -!.config/neofetch -!.config/picom -!.config/polybar -!.config/rofi -!.config/starship -!.config/tmux +!.config/ +!.local/ diff --git a/.local/.gitignore b/.local/.gitignore new file mode 100644 index 0000000..dc9c7bf --- /dev/null +++ b/.local/.gitignore @@ -0,0 +1,3 @@ +* +!bin/ +!.gitignore diff --git a/.local/bin/.gitignore b/.local/bin/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/.local/bin/.gitignore @@ -0,0 +1 @@ +!* diff --git a/.local/bin/movie b/.local/bin/movie deleted file mode 100755 index 4cb8390..0000000 --- a/.local/bin/movie +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -MOVIE_DIR=/media-storage/Movies -SELECTED=`fd . $MOVIE_DIR -e avi -e m4v -e mkv -e mp4 | fzf` -if [ -z "$SELECTED" ]; then - echo "No movie selected. Exiting." - exit 1 -fi -vlc "$SELECTED" & -exit 0 diff --git a/.zshrc b/.zshrc index c3b8557..0600454 100644 --- a/.zshrc +++ b/.zshrc @@ -25,7 +25,7 @@ alias vi=nvim alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles --work-tree=$HOME' alias top=btop alias movies="movie; exit" -alias ccp='xclip -selection clipboard <' +alias ccp='wl-copy<' eval "$(fzf --zsh)"