#!/usr/bin/env bash revision='0.1f (feb 24/25)' set -a set -E # Exit function trap '[ "${?}" -ne 77 ] || exit 77' ERR function die { if [ ${@} ] then echo echo -e "\e[1;31mError encountered for the following reason:\e[0m \e[33m${@}\e[0m \e[1;31mScript aborted...\e[0m" echo else echo echo -e '\e[1;31mError encountered, script aborted...\e[0m' echo fi exit 77 } # Internet connection check if nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || nc -z -w 1 google.com 443 >/dev/null 2>&1 then sudo timedatectl set-ntp true else die 'No internet connectivity detected, plug in an ethernet cable or run \e[32miwd-connect\e[33m if using wifi and try again' fi totalde=21 cat <<- menu $(tput setaf 5 bold) Select a desktop$(tput sgr0) $(tput smul setaf 7 dim)# none$(tput sgr0) 0) none $(tput smul setaf 7 dim)# wayland$(tput sgr0) 1) sway 2) hyprland 3) qtile-wayland 4) river 5) plasma-wayland 6) gnome-wayland 7) cosmic $(tput smul setaf 7 dim)# x11$(tput sgr0) 8) qtile-x11 9) bspwm 10) awesome 11) i3 12) i3-plasma 13) plasma-x11 14) gnome-x11 15) xfce4 16) budgie 17) cinnamon 18) deepin 19) mate 20) pantheon 21) cutefish 22) lxde 23) lxqt menu if [ ${1} ] then desktop=${1} else desktop=-1 fi until [[ ${desktop} -ge 0 && ${desktop} -le ${totalde} ]] do read -p '> ' desktop [[ ${desktop} -ge 0 && ${desktop} -le ${totalde} ]] ||\ echo -e "\n\n\e[1;31mInvalid selection, type an option from 0 to ${totalde}\e[0m" done # Configure btrfs if findmnt / | grep -w -q btrfs then desktop_packages+=(btrfs-progs) if pacman -Q | grep -q "^grub" then desktop_packages+=(grub-btrfs inotify-tools) systemd_services+=(grub-btrfsd.service) fi # echo -e '\n\e[1;35mConfiguring snapper\e[0m' # sudo pacman --sync --ask 4 snapper snap-pac # echo # sudo umount /.snapshots /home/.snapshots # sudo rm -r /.snapshots /home/.snapshots # sudo snapper -c root create-config / # sudo snapper -c home create-config /home # sudo sed -i 's/TIMELINE_LIMIT_HOURLY="10"/TIMELINE_LIMIT_HOURLY="4"/' /etc/snapper/configs/root # sudo sed -i 's/TIMELINE_LIMIT_DAILY="10"/TIMELINE_LIMIT_DAILY="7"/' /etc/snapper/configs/root # sudo sed -i 's/TIMELINE_LIMIT_MONTHLY="10"/TIMELINE_LIMIT_MONTHLY="1"/' /etc/snapper/configs/root # sudo sed -i 's/TIMELINE_LIMIT_YEARLY="10"/TIMELINE_LIMIT_YEARLY="0"/' /etc/snapper/configs/root # sudo sed -i 's/TIMELINE_CREATE="yes"/TIMELINE_CREATE="no"/' /etc/snapper/configs/home # sudo btrfs subvolume delete /.snapshots # sudo btrfs subvolume delete /home/.snapshots # sudo mkdir -p --mode=750 /.snapshots /home/.snapshots # sudo mount -a # sudo systemctl --quiet enable --now snapper-cleanup.timer snapper-timeline.timer # # Create snapshots for fresh installation # sudo snapper -c root create --description "fresh install" # sudo snapper -c home create --description "fresh install" fi # Assign DE variables case ${desktop} in 0) # TTY only desktop_choice=none echo ;; *) systemd_user_services+=(wireplumber.service pipewire-pulse.service pipewire.service) desktop_packages+=(ttf-dejavu pipewire pipewire-audio pipewire-pulse pipewire-jack wireplumber) case ${desktop} in [1-7]) # Wayland desktop_packages+=(wayland) case ${desktop} in 1) desktop_choice=sway desktop_packages+=(sway seatd swaylock swayidle swaybg bemenu bemenu-wayland i3status foot kate dolphin konsole kompare kcalc breeze-icons kde-cli-tools brightnessctl gnome-keyring fakeroot qt5-wayland polkit-kde-agent) systemd_services+=(seatd.service) ;; 2) desktop_choice=hyprland desktop_packages+=(hyprland uwsm swaylock swayidle bemenu bemenu-wayland waybar foot kate dolphin konsole kompare kcalc breeze-icons kde-cli-tools ttf-font-awesome brightnessctl gnome-keyring fakeroot qt5-wayland polkit-kde-agent) systemd_user_services+=(foot-server.service) ;; 3) desktop_choice=qtile-wayland desktop_packages+=(qtile python-pywlroots xorg-xwayland foot) systemd_user_services+=(foot-server.service) ;; 4) desktop_choice=river desktop_packages+=(river foot) systemd_user_services+=(foot-server.service) ;; 5) desktop_choice=plasma-wayland desktop_packages+=($(pacman -Sgq plasma | grep -v 'discover\|oxygen\|plasma-nm') konsole foot kate dolphin kompare kcalc) systemd_services+=(sddm.service) systemd_user_services+=(foot-server.service) ;; 6) desktop_choice=gnome-wayland desktop_packages+=(gnome foot) systemd_services+=(gdm.service) systemd_user_services+=(foot-server.service) ;; 7) desktop_choice=cosmic desktop_packages+=(cosmic) systemd_services+=(cosmic-greeter.service) if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU' then desktop_packages+=(vulkan-virtio) elif lspci | grep VGA | grep -q NVIDIA then desktop_packages+=(nvidia-utils) elif lscpu | grep 'Model name:' | grep -q AMD then desktop_packages+=(amdvlk) elif lscpu | grep 'Model name:' | grep -q Intel then desktop_packages+=(vulkan-intel) fi ;; esac # Environment sudo tee -a /etc/environment >/dev/null <<- environment QT_QPA_PLATFORM=wayland environment ;; *) # Xorg desktop_packages+=(xorg) case ${desktop} in 8) desktop_choice=qtile-x11 desktop_packages+=(qtile xorg-xinit konsole) ;; 9) desktop_choice=bspwm desktop_packages+=(bspwm sxhkd xorg-xinit polybar konsole) ;; 10) desktop_choice=awesome desktop_packages+=(awesome xorg-xinit konsole) ;; 11) desktop_choice=i3 desktop_packages+=(i3-wm i3status i3lock dmenu lightdm lightdm-gtk-greeter pavucontrol konsole kate dolphin kompare breeze-icons) systemd_services+=(lightdm.service) ;; 12) desktop_choice=i3-plasma desktop_packages+=($(pacman -Sgq plasma | grep -v 'discover\|oxygen\|plasma-nm') konsole kate dolphin kompare kcalc i3-wm i3status dmenu wmctrl feh) systemd_services+=(sddm.service) ;; 13) desktop_choice=plasma-x11 desktop_packages+=($(pacman -Sgq plasma | grep -v 'discover\|oxygen\|plasma-nm') konsole kate dolphin kompare kcalc) systemd_services+=(sddm.service) ;; 14) desktop_choice=gnome-x11 desktop_packages+=(gnome) systemd_services+=(gdm.service) ;; 15) desktop_choice=xfce4 desktop_packages+=(xfce4 lightdm lightdm-gtk-greeter) systemd_services+=(lightdm.service) ;; 16) desktop_choice=budgie desktop_packages+=(budgie lightdm lightdm-gtk-greeter tilix) systemd_services+=(lightdm.service) ;; 17) desktop_choice=cinnamon desktop_packages+=(cinnamon lightdm lightdm-gtk-greeter gnome-console) systemd_services+=(lightdm.service) ;; 18) desktop_choice=deepin desktop_packages+=(deepin deepin-kwin $(pacman -Sgq deepin-extra | grep -v deepin-reader) lightdm lightdm-gtk-greeter gnome-keyring) systemd_services+=(lightdm.service) if uname -r | grep -q 'lts\|hardened\|zen' then desktop_packages+=(deepin-anything-dkms) else desktop_packages+=(deepin-anything-arch) fi ;; 19) desktop_choice=mate desktop_packages+=(mate mate-extra lightdm lightdm-gtk-greeter) systemd_services+=(lightdm.service) ;; 20) desktop_choice=pantheon desktop_packages+=(pantheon lightdm-pantheon-greeter lightdm) systemd_services+=(lightdm.service) ;; 21) desktop_choice=cutefish desktop_packages+=(cutefish sddm) systemd_services+=(sddm.service) ;; 22) desktop_choice=lxde desktop_packages+=(lxde lxdm) systemd_services+=(lxdm.service) ;; 23) desktop_choice=lxqt desktop_packages+=(lxqt sddm breeze-icons) systemd_services+=(sddm.service) ;; esac ;; esac echo echo -e "\t\e[1mYou have chosen \e[32m${desktop_choice}\e[0m\e[1m desktop\e[0m" echo echo -e '\e[1;35mInstalling base packages\e[0m' sudo pacman --sync --ask 4 ${desktop_packages[@]} || die 'Failed to install required packages' echo ;; esac case ${desktop_choice} in plasma-wayland) mkdir -p ~/.config/{autostart-scripts,foot}/ # install /dev/stdin ~/.config/autostart-scripts/foot.sh <<- foot # #!/bin/sh # foot --server # foot cat >>~/.config/kglobalshortcutsrc <<- shortcuts [services][footclient.desktop] _launch=Alt+Return [services][org.kde.konsole.desktop] _launch=none shortcuts ;; gnome-wayland) mkdir -p ~/.config/{autostart,foot}/ # cat > ~/.config/autostart/foot-server.desktop <<- foot # [Desktop Entry] # Type=Application # Name=Foot server # Exec=foot --server # foot gsettings set $(gsettings list-schemas | grep terminal) exec footclient ;; cosmic) mkdir -p ~/.config/foot/ ;; i3|i3-plasma) # i3-config mkdir -p ~/.config/i3/ curl --fail -s -L https://raw.githubusercontent.com/i3/i3/next/etc/config | sed 's/exec i3-config-wizard/# &/' > ~/.config/i3/config case ${desktop_choice} in i3-plasma) kwriteconfig6 --file startkderc --group General --key systemdBoot false sudo install /dev/stdin /opt/local/bin/plasma-i3.sh <<- EOF #!/usr/bin/env bash export KDEWM=/usr/bin/i3 /usr/bin/startplasma-x11 EOF sudo tee /usr/share/xsessions/plasma-i3.desktop >/dev/null <<- EOF [Desktop Entry] Type=XSession Exec=/opt/local/bin/plasma-i3.sh DesktopNames=KDE Name=Plasma (i3) Comment=KDE Plasma with i3 as the WM EOF ;; esac if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU' then cat >> ~/.config/i3/config <<- 'i3' exec xrandr --output $(xrandr -q | grep -w 'connected primary' | awk '{print $1}') --mode 1920x1080 exec xrandr --dpi 192 exec spice-vdagent exec VBoxClient-all i3 fi ;; qtile-x11) echo 'exec qtile start' >~/.xinitrc cat >> ~/.bash_profile <<- 'autostart' if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ] then exec startx fi autostart ;; qtile-wayland) mkdir -p ~/.config/foot/ cat >> ~/.bash_profile <<- 'autostart' # Start sway on login from tty if [ -z "${WAYLAND_DISPLAY}" ] && [ "${XDG_VTNR}" = 1 ] then exec qtile start -b wayland fi autostart ;; river) mkdir -p ~/.config/foot/ cat >> ~/.bash_profile <<- 'autostart' # Start sway on login from tty if [ -z "${WAYLAND_DISPLAY}" ] && [ "${XDG_VTNR}" = 1 ] then exec river fi autostart ;; bspwm) cat >> ~/.bash_profile <<- 'autostart' if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ] then exec startx /usr/bin/bspwm fi autostart mkdir -p ~/.config/{bspwm,sxhkd,polybar}/ install -Dm755 /usr/share/doc/bspwm/examples/bspwmrc ~/.config/bspwm/bspwmrc install -Dm644 /usr/share/doc/bspwm/examples/sxhkdrc ~/.config/sxhkd/sxhkdrc cp /etc/polybar/config.ini ~/.config/polybar/ ;; awesome) cat >> ~/.bash_profile <<- 'autostart' if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ] then exec startx /usr/bin/awesome fi autostart mkdir -p ~/.config/awesome/ sed -e '/^terminal =/c terminal = "konsole"' \ -e '/^modkey =/c modkey = "Mod1"' /etc/xdg/awesome/rc.lua > ~/.config/awesome/ ;; sway) # Sway sudo gpasswd -a ${USER} seat >/dev/null # Dolphin default apps mkdir -p ~/.config/menus/ curl --fail -s -L https://raw.githubusercontent.com/KDE/plasma-workspace/master/menu/desktop/plasma-applications.menu -o ~/.config/menus/applications.menu kbuildsycoca6 >/dev/null 2>&1 # Dolphin default terminal cat >> ~/.config/kdeglobals <<- foot [General] TerminalApplication=footclient foot # Create conf directories mkdir -p ~/.config/{sway/config.d,foot}/ # Identify conf locations cat > ~/.config/sway/config <<- 'config' include /etc/sway/config.d/* include ~/.config/sway/config.d/* config # Default sway config sed -e 's/mod Mod4/mod Mod1/' \ -e 's/term foot/&client/' \ -e '/set $menu/c set $menu bemenu-run -p "" --no-overlap --tb "#285577" --hb "#285577" --tf "#eeeeee" --hf "#eeeeee" --nf "#bbbbbb"' \ /etc/sway/config > ~/.config/sway/config.d/00-config sed -n "/^# Status Bar:$/q;p" -i ~/.config/sway/config.d/00-config # Sway config cat > ~/.config/sway/config.d/zz-sway <<- 'config' # Disable xwayland xwayland disable # Start foot terminal server exec foot --server # Use i3status bar { status_command i3status } # Floating windows for_window [window_role="About"] floating enable for_window [window_role="Organizer"] floating enable for_window [window_role="Preferences"] floating enable for_window [window_role="bubble"] floating enable for_window [window_role="page-info"] floating enable for_window [window_role="pop-up"] floating enable for_window [window_role="task_dialog"] floating enable for_window [window_role="toolbox"] floating enable for_window [window_role="webconsole"] floating enable for_window [window_type="dialog"] floating enable for_window [window_type="menu"] floating enable # Floating for KCalc for_window [title="KCalc"] floating enable # Bind keys for brightness bindsym XF86MonBrightnessDown exec brightnessctl set 5%- bindsym XF86MonBrightnessUp exec brightnessctl set 5%+ # Mouse and keyboard defaults input type:keyboard xkb_numlock enabled input type:touchpad { tap enabled natural_scroll enabled } config # Display config cat > ~/.config/sway/config.d/zz-display <<- 'display' # # Declare output # set $laptop eDP-1 (swaymsg -t get_outputs) # Swayidle exec swayidle -w \ timeout 300 'swaylock -e -f -c 000000' \ timeout 315 'swaymsg "output * power off"' \ resume 'swaymsg "output * power on"' \ timeout 600 'systemctl suspend' \ before-sleep 'swaylock -e -f -c 000000' # Laptop lid switches bindswitch --reload --locked lid:on output * disable bindswitch --reload --locked lid:off output * enable # Swaylock bindsym Mod4+l exec swaylock -e -f -c 000000 # Solid black background output * bg #000000 solid_color # Prevent swayidle when a window is in fullscreen for_window [class=".*"] inhibit_idle fullscreen for_window [app_id=".*"] inhibit_idle fullscreen display # Polkit cat > ~/.config/sway/config.d/zz-polkit <<- 'polkit' exec "/usr/lib/polkit-kde-authentication-agent-1" polkit # Monitor if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU' then cat > ~/.config/sway/config.d/zz-virtualmonitor <<- 'monitor' # Virtual monitor output Virtual-1 { pos 0,0 mode 1920x1080@60Hz scale 1.25 } monitor fi # TTY sway autostart cat >> ~/.bash_profile <<- 'sway' # Start sway on login from tty if [ -z "${WAYLAND_DISPLAY}" ] && [ "${XDG_VTNR}" = 1 ] then exec sway fi sway ;; hyprland) # Hyprland mkdir -p ~/.config/{menus,hypr/scripts,foot,waybar}/ # Dolphin default apps curl --fail -s -L https://raw.githubusercontent.com/KDE/plasma-workspace/master/menu/desktop/plasma-applications.menu -o ~/.config/menus/applications.menu kbuildsycoca6 >/dev/null 2>&1 # Dolphin default terminal cat >> ~/.config/kdeglobals <<- foot [General] TerminalApplication=footclient foot # Swayidle install /dev/stdin ~/.config/hypr/scripts/sleep.sh <<- 'swayidle' swayidle -w timeout 300 'swaylock -f -c 000000' \ timeout 600 'systemctl suspend' \ before-sleep 'swaylock -f -c 000000' & swayidle # Config curl --silent --fail https://raw.githubusercontent.com/hyprwm/Hyprland/refs/heads/main/example/hyprland.conf |\ sed -e '/Autostart/i exec-once = /usr/lib/polkit-kde-authentication-agent-1' \ -e '/Autostart/i exec-once = waybar -c ~/.config/waybar/waybar.conf' \ -e '/Autostart/i exec-once = ~/.config/hypr/scripts/sleep.sh' \ -e '/^$terminal =/c $terminal = footclient' \ -e '/gaps_in =/c gaps_in = 0' \ -e '/gaps_out =/c gaps_out = 0' \ -e '/^$menu =/c $menu = bemenu-run -p "" --no-overlap --tb "##285577" --hb "##285577" --tf "##eeeeee" --hf "##eeeeee" --nf "##bbbbbb"' \ -e 's/bind = $mainMod, R, exec, $menu/bind = $mainMod, D, exec, $menu/' \ -e 's/bind = $mainMod, Q, exec, $terminal/bind = $mainMod, RETURN, exec, $terminal/' \ -e 's/bind = $mainMod, C, killactive/bind = $mainMod SHIFT, Q, killactive/' \ -e '/$mainMod =/c $mainMod = ALT' \ -e '/RETURN/a bind = SUPER, L, exec, swaylock -e -f -c 000000' \ > ~/.config/hypr/hyprland.conf # -e '/Autostart/i exec-once = uwsm app -- foot --server' \ # QEMU monitor if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU' then sed -i "/^monitor/c monitor = $(hyprctl monitors all | grep "^Monitor" | awk '{print $2}'), 1920x1080@60, 0x0, 1.5" ~/.config/hypr/hyprland.conf fi # Waybar sed -e 's|sway/workspaces|sway/workspaces|g' \ -e 's|sway/mode|hyprland/submap|g' \ -e '/position/ s|//||' \ /etc/xdg/waybar/config.jsonc > ~/.config/waybar/waybar.conf # TTY sway autostart cat >> ~/.bash_profile <<- 'hyprland' # Start sway on login from tty if uwsm check may-start then exec uwsm start hyprland.desktop fi hyprland ;; esac # Foot terminal config (/etc/xdg/foot/foot.ini) if [ -d ~/.config/foot/ ] then cat > ~/.config/foot/foot.ini <<- 'foot' [main] include=/usr/share/foot/themes/kitty font=Source Code Pro:size=12 workers=32 [scrollback] # lines=1000 foot fi # Add user to shared folder group if in virtualbox guest if ls -l /dev/disk/* | grep -q VBOX then sudo gpasswd -a ${USER} vboxsf >/dev/null echo fi # iwd status function if pacman -Q | grep -w -q iwd then cat > ~/.local/functions/iwd-status <<- iwd #!/usr/bin/env bash # iwd connection status function iwd-status { iwctl station "$(iwctl station list | grep connected | awk '{print $(NF-1)}')" show } alias iwctl='iwctl station $(iwctl station list | grep connected | awk '{print $(NF-1)}')' iwd fi if [[ "${desktop_choice}" == "none" ]] then sudo rm -f ${0} echo -e '\e[1;34mSetup complete, press any key to continue\e[5m...\e[0m\n' read -n 1 -s -p '' elif ls /usr/share/*sessions | grep -q desktop then install /dev/stdin ~/.local/bin/startup <<- 'EOF' #!/usr/bin/env bash # Internet connection check if nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || nc -z -w 1 google.com 443 >/dev/null 2>&1 then vim ~/.local/bin/startupscript ~/.local/bin/startupscript rm -f ${0} exit 0 else echo -e '\n\e[31mNo internet connectivity detected' echo -e 'Connect to a network and try again' echo -e 'Aborting installer...\e[0m\n' exit 1 fi EOF install /dev/stdin ~/.local/bin/startupscript <<- EOF $(curl --fail --silent https://git.myvelabs.com/lab/archlinux/raw/branch/master/functions/startup) EOF sudo rm -f ${0} echo -e '\e[1;34mDesktop installed, press any key to load '${desktop_choice}'\e[5m...\e[0m' read -n 1 -s -p '' echo else die 'Something does not feel right' fi # Systemd services for service in ${systemd_user_services[@]} do systemctl --quiet --user enable --now ${service} done sudo systemctl --quiet enable --now ${systemd_services[@]}