diff --git a/.config/ags/config.js b/.config/ags/config.js
deleted file mode 100644
index 9acba3e..0000000
--- a/.config/ags/config.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const systemtray = await Service.import('systemtray')
-
-/** @param {import('types/service/systemtray').TrayItem} item */
-const SysTrayItem = item => Widget.Button({
- child: Widget.Icon().bind('icon', item, 'icon'),
- tooltipMarkup: item.bind('tooltip_markup'),
- onPrimaryClick: (_, event) => item.activate(event),
- onSecondaryClick: (_, event) => item.openMenu(event),
-});
-
-function SysTray() {
- return Widget.Box({ children: systemtray.bind('items').transform(i => i.map(SysTrayItem)) });
-}
-
-function Bar(monitor = 0) {
- const lTime = Widget.Label({
- label: 'TIME',
- });
-
- Utils.interval(1000, () => {
- lTime.label = Utils.exec('date +%H:%M');
- //date +%d.%m.%Y
- });
-
- const bTimeDate = Widget.Box({
- children: [lTime]
- });
-
- const bInfo = Widget.Box({
- hpack: "end",
- children: [SysTray()]
- });
-
- return Widget.Window({
- monitor,
- exclusivity: 'exclusive',
- name: `bar ${monitor}`,
- anchor: ['top', 'left', 'right'],
- child: Widget.CenterBox({
- centerWidget: bTimeDate,
- endWidget: bInfo,
- }),
- });
-}
-
-export default {
- windows: [Bar(1), Bar(2)]
-};
diff --git a/.config/hypr/hyprshade.toml b/.config/hypr/hyprshade.toml
deleted file mode 100755
index a6f3246..0000000
--- a/.config/hypr/hyprshade.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-# [[shades]]
-# name = "vibrance"
-# default = true # shader to use during times when there is no other shader scheduled
-
-[[shades]]
-name = "blue-light-filter"
-start_time = 19:00:00
-end_time = 08:00:00 # optional if you have more than one shade with start_time
diff --git a/.config/hypr/scripts/bar.sh b/.config/hypr/scripts/bar.sh
deleted file mode 100755
index 3071e6c..0000000
--- a/.config/hypr/scripts/bar.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-eww open bar1
-eww open bar2
-eww open bar3
-
-## Waybar auto update (requires inotifytools)
-# CONFIG_FILES="$HOME/.config/waybar/config $HOME/.config/waybar/style.css"
-#
-# trap "killall waybar" EXIT
-#
-# while true; do
-# waybar &
-# inotifywait -e create,modify $CONFIG_FILES
-# killall waybar
-# done
diff --git a/.config/hypr/scripts/battery_check.sh b/.config/hypr/scripts/battery_check.sh
deleted file mode 100755
index edba4f3..0000000
--- a/.config/hypr/scripts/battery_check.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-
-bat=$(upower -e | grep BAT)
-
-if [ -z $bat ]; then
- echo "No battery available!"
- exit 1
-fi
-
-while true; do
- per=$(upower -i $bat | grep percentage | awk '{print $2}')
- per="${per%\%}"
-
- if "$per" -lt 15 #&& ! is_charging
- eww open battery_warning
- fi
-
- sleep 120
-done
diff --git a/.config/hypr/scripts/game_mode.sh b/.config/hypr/scripts/game_mode.sh
deleted file mode 100755
index 2626db2..0000000
--- a/.config/hypr/scripts/game_mode.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-
-eww close bar1 || eww open bar1 & disown
diff --git a/.config/hypr/theme/current_background.jpg b/.config/hypr/theme/current_background.jpg
deleted file mode 120000
index ea9845c..0000000
--- a/.config/hypr/theme/current_background.jpg
+++ /dev/null
@@ -1 +0,0 @@
-/home/keule/Data/Pictures/Backgrounds/Desktop/144565.jpg
\ No newline at end of file
diff --git a/.config/kdeglobals b/.config/kdeglobals
deleted file mode 100755
index 7d9707e..0000000
--- a/.config/kdeglobals
+++ /dev/null
@@ -1,14 +0,0 @@
-[$Version]
-update_info=filepicker.upd:filepicker-remove-old-previews-entry
-
-[General]
-TerminalApplication=alacritty
-
-[KDE]
-ShowDeleteCommand=true
-
-[KShortcutsDialog Settings]
-Dialog Size=600,480
-
-[PreviewSettings]
-MaximumRemoteSize=0
diff --git a/.config/rofi/app_launcher.rasi b/.config/rofi/app_launcher.rasi
deleted file mode 100755
index 8f87ad8..0000000
--- a/.config/rofi/app_launcher.rasi
+++ /dev/null
@@ -1,132 +0,0 @@
-// Config //
-configuration {
- modi: "drun,filebrowser,window,run";
- show-icons: true;
- display-drun: "";
- display-run: "";
- display-filebrowser: "";
- display-window: "";
- drun-display-format: "{name}";
- window-format: "{w}{t}";
- icon-theme: "Papirus";
-}
-
-// Theme //
-@theme "~/.config/rofi/themes/theme.rasi"
-
-
-// Main //
-window {
- height: 506px; // 16:9
- width: 900px; // 16:9
- transparency: "real";
- fullscreen: false;
- enabled: true;
- cursor: "default";
- spacing: 0px;
- padding: 0px;
- border: 2px;
- border-radius: 15px;
- border-color: @main-br;
- background-color: transparent;
-}
-mainbox {
- enabled: true;
- spacing: 0px;
- padding: 0px;
- orientation: vertical;
- children: [ "inputbar" , "listbox" ];
- background-color: transparent;
- background-image: url("~/.config/hypr/theme/current_background.jpg", width);
-}
-
-
-// Inputs //
-inputbar {
- enabled: true;
- spacing: 0px;
- padding: 40px;
- children: [ "entry" ];
- background-color: @main-bg;
-}
-entry {
- border-radius: 30px;
- enabled: true;
- spacing: 0px;
- padding: 20px;
- text-color: @main-fg;
- background-color: @main-bg;
-}
-
-
-// Lists //
-listbox {
- padding: 30px;
- spacing: 0px;
- orientation: horizontal;
- children: [ "listview" , "mode-switcher" ];
- background-color: @main-bg;
-}
-listview {
- padding: 0px;
- spacing: 10px;
- enabled: true;
- columns: 2;
- cycle: true;
- dynamic: true;
- scrollbar: false;
- layout: vertical;
- reverse: false;
- fixed-height: true;
- fixed-columns: true;
- cursor: "default";
- background-color: transparent;
- text-color: @main-fg;
-}
-mode-switcher {
- orientation: vertical;
- width: 95px;
- enabled: true;
- padding: 15px;
- spacing: 10px;
- background-color: transparent;
-}
-button {
- cursor: pointer;
- border-radius: 20px;
- background-color: @main-bg;
- text-color: @main-fg;
-}
-button selected {
- background-color: @main-fg;
- text-color: @main-bg;
-}
-
-
-// Elements //
-element {
- enabled: true;
- spacing: 20px;
- padding: 9px;
- border-radius: 25px;
- cursor: pointer;
- background-color: transparent;
- text-color: @main-fg;
-}
-element selected.normal {
- background-color: @select-bg;
- text-color: @select-fg;
-}
-element-icon {
- size: 47px;
- cursor: inherit;
- background-color: transparent;
- text-color: inherit;
-}
-element-text {
- vertical-align: 0.5;
- horizontal-align: 0.0;
- cursor: inherit;
- background-color: transparent;
- text-color: inherit;
-}
diff --git a/.config/rofi/clipboard.rasi b/.config/rofi/clipboard.rasi
deleted file mode 100755
index f036e90..0000000
--- a/.config/rofi/clipboard.rasi
+++ /dev/null
@@ -1,98 +0,0 @@
-// Config //
-configuration {
- modi: "drun";
- show-icons: false;
-}
-
-// Theme //
-@theme "~/.config/rofi/themes/theme.rasi"
-
-// Main //
-window {
- height: 50%;
- width: 20%;
- location: center;
- transparency: "real";
- fullscreen: false;
- enabled: true;
- cursor: "default";
- spacing: 0px;
- padding: 0px;
- border: 2px;
- border-radius: 15px;
- border-color: @main-br;
- background-color: transparent;
-}
-mainbox {
- enabled: true;
- spacing: 0px;
- orientation: vertical;
- children: [ "inputbar" , "listbox" ];
- background-color: transparent;
-}
-
-
-// Inputs //
-inputbar {
- enabled: true;
- padding: 7px;
- children: [ "entry" ];
- background-color: @main-bg;
-}
-entry {
- enabled: true;
- padding: 40px;
- text-color: @main-fg;
- background-color: @main-bg;
-}
-
-
-// Lists //
-listbox {
- spacing: 0px;
- padding: 6px;
- children: [ "listview" ];
- background-color: @main-bg;
-}
-listview {
- enabled: true;
- columns: 1;
- cycle: true;
- dynamic: true;
- scrollbar: false;
- layout: vertical;
- reverse: false;
- fixed-height: false;
- fixed-columns: true;
- cursor: "default";
- background-color: transparent;
- text-color: @main-fg;
-}
-
-
-// Elements //
-element {
- enabled: true;
- spacing: 0px;
- padding: 12px;
- border-radius: 10px;
- cursor: pointer;
- background-color: transparent;
- text-color: @main-fg;
-}
-@media(max-aspect-ratio: 1.8) {
- element {
- orientation: vertical;
- }
-}
-element selected.normal {
- background-color: @select-bg;
- text-color: @select-fg;
-}
-element-text {
- vertical-align: 0.0;
- horizontal-align: 0.0;
- cursor: inherit;
- background-color: transparent;
- text-color: inherit;
-}
diff --git a/.config/rofi/main.rasi b/.config/rofi/main.rasi
deleted file mode 100755
index fce3e6f..0000000
--- a/.config/rofi/main.rasi
+++ /dev/null
@@ -1,151 +0,0 @@
-// Config //
-configuration {
- modi: "emoji:rofimoji,calc,drun,filebrowser,run";
- show-icons: true;
- display-drun: "";
- display-run: "";
- display-filebrowser: "";
- display-window: "";
- drun-display-format: "{name}";
- window-format: "{w}{t}";
- icon-theme: "Papirus";
-}
-
-// Theme //
-@theme "~/.config/rofi/themes/theme.rasi"
-
-
-// Main //
-window {
- height: 506px; // 16:9
- width: 900px; // 16:9
- location: center;
- transparency: "real";
- fullscreen: false;
- enabled: true;
- cursor: "default";
- spacing: 0px;
- padding: 0px;
- border: 2px;
- border-radius: 15px;
- border-color: @main-br;
- background-color: transparent;
-}
-mainbox {
- enabled: true;
- spacing: 0px;
- padding: 0px;
- orientation: vertical;
- children: [ "inputbar", "listbox" ];
- background-color: transparent;
- background-image: url("~/.config/hypr/theme/current_background.jpg", width);
-}
-
-// Message //
-message {
- padding: 0px 55px;
- background-color: @main-bg;
-}
-
-textbox {
- enabled: true;
- border-radius: 15px;
- spacing: 0px;
- padding: 20px;
- text-color: @main-fg;
- background-color: @main-bg;
- border: 1px;
- border-color: @main-br;
-}
-
-// Inputs //
-inputbar {
- enabled: true;
- spacing: 0px;
- padding: 40px;
- children: [ "entry" ];
- background-color: @main-bg;
-}
-entry {
- enabled: true;
- border-radius: 15px;
- spacing: 0px;
- padding: 20px;
- text-color: @main-fg;
- background-color: @main-bg;
- border: 1px;
- border-color: @main-br;
-}
-
-
-// Lists //
-listbox {
- padding: 30px;
- spacing: 0px;
- orientation: horizontal;
- children: [ "listview" ];
- background-color: @main-bg;
-}
-listview {
- padding: 0px;
- spacing: 10px;
- enabled: true;
- columns: 2;
- cycle: true;
- dynamic: true;
- scrollbar: false;
- layout: vertical;
- reverse: false;
- fixed-height: true;
- fixed-columns: true;
- cursor: "default";
- background-color: transparent;
- text-color: @main-fg;
-}
-mode-switcher {
- orientation: vertical;
- width: 95px;
- enabled: true;
- padding: 15px;
- spacing: 10px;
- background-color: transparent;
-}
-button {
- cursor: pointer;
- border-radius: 20px;
- background-color: @main-bg;
- text-color: @main-fg;
-}
-button selected {
- background-color: @main-fg;
- text-color: @main-bg;
-}
-
-
-// Elements //
-element {
- enabled: true;
- spacing: 20px;
- padding: 9px;
- border-radius: 25px;
- cursor: pointer;
- background-color: transparent;
- text-color: @main-fg;
-}
-element selected.normal {
- background-color: @select-bg;
- text-color: @select-fg;
-}
-element-icon {
- size: 47px;
- cursor: inherit;
- background-color: transparent;
- text-color: inherit;
-}
-element-text {
- vertical-align: 0.5;
- horizontal-align: 0.0;
- cursor: inherit;
- background-color: transparent;
- text-color: inherit;
-}
diff --git a/.config/rofi/themes/theme.rasi b/.config/rofi/themes/theme.rasi
deleted file mode 100755
index db294b7..0000000
--- a/.config/rofi/themes/theme.rasi
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * https://github.com/catppuccin/rofi/
-*/
-
-* {
- main-bg: #11111bd6;
- main-fg: #cdd6f4ff;
- main-br: #7dc4e4ff; /*#cba6f7ff;*/
- main-ex: #f5e0dcff;
- select-bg: #b4befeff;
- select-fg: #11111bff;
- separatorcolor: transparent;
- border-color: transparent;
-}
diff --git a/.config/rofimoji.rc b/.config/rofimoji.rc
deleted file mode 100644
index 995ab53..0000000
--- a/.config/rofimoji.rc
+++ /dev/null
@@ -1,3 +0,0 @@
-action = copy
-files = [emojis, gitmoji, hebrew, fontawesome6, math]
-skin-tone=ask
diff --git a/.config/swaync/config.json b/.config/swaync/config.json
deleted file mode 100755
index b97ac90..0000000
--- a/.config/swaync/config.json
+++ /dev/null
@@ -1,91 +0,0 @@
-{
- "$schema": "/etc/xdg/swaync/configSchema.json",
- "positionX": "right",
- "positionY": "top",
- "layer": "overlay",
- "control-center-layer": "top",
- "layer-shell": true,
- "cssPriority": "application",
- "control-center-margin-top": 0,
- "control-center-margin-bottom": 0,
- "control-center-margin-right": 0,
- "control-center-margin-left": 0,
- "notification-2fa-action": true,
- "notification-inline-replies": true,
- "notification-icon-size": 64,
- "notification-body-image-height": 100,
- "notification-body-image-width": 200,
- "timeout": 10,
- "timeout-low": 5,
- "timeout-critical": 0,
- "fit-to-screen": true,
- "control-center-width": 500,
- "control-center-height": 600,
- "notification-window-width": 500,
- "keyboard-shortcuts": true,
- "image-visibility": "when-available",
- "transition-time": 200,
- "hide-on-clear": true,
- "hide-on-action": true,
- "script-fail-notify": true,
- "scripts-example": {
- "example-script": {
- "exec": "echo 'Custom config?'",
- "urgency": "Normal"
- }
- },
- "widgets": [
- "buttons-grid",
- "inhibitors",
- "title",
- "dnd",
- "notifications"
- ],
- "widget-config": {
- "inhibitors": {
- "text": "Inhibitors",
- "button-text": "Clear All",
- "clear-all-button": true
- },
- "title": {
- "text": "Notifications",
- "clear-all-button": true,
- "button-text": "Clear All"
- },
- "dnd": {
- "text": "Do Not Disturb"
- },
- "label": {
- "max-lines": 5,
- "text": "Label Text"
- },
- "mpris": {
- "image-size": 96,
- "image-radius": 12
- },
- "buttons-grid": {
- "actions": [
- {
- "label": "",
- "command": "systemctl poweroff"
- },
- {
- "label": "",
- "command": "systemctl reboot"
- },
- {
- "label": "",
- "command": "systemctl suspend"
- },
- {
- "label": "",
- "command": "~/.config/hypr/scripts/lock.sh"
- },
- {
- "label": "",
- "command": "hyprctl dispatch exit 0"
- }
- ]
- }
- }
-}
diff --git a/.config/swaync/style.css b/.config/swaync/style.css
deleted file mode 100755
index 4507843..0000000
--- a/.config/swaync/style.css
+++ /dev/null
@@ -1,294 +0,0 @@
-* {
- all: unset;
- font-size: 14px;
- font-family: "FiraCode Nerd Font";
- transition: 200ms;
-}
-
-.blank-window {
- background: alpha(black, 0.25);
-}
-
-.widget-buttons-grid {
- font-size: x-large;
- padding: 8px;
- margin: 20px 0px;
- border-radius: 12px;
- background: #363a4f;
-}
-
-.widget-buttons-grid>flowbox>flowboxchild>button {
- margin: 3px;
- background: #343b58;
- border-radius: 12px;
- color: #cad3f5;
-}
-
-.widget-buttons-grid>flowbox>flowboxchild>button:hover {
- /* background: @noti-bg-hover; */
- color: #8aadf4;
-}
-
-.floating-notifications.background .notification-row .notification-background {
- box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.8), inset 0 0 0 1px #363a4f;
- border-radius: 12.6px;
- margin: 18px;
- background-color: #24273a;
- color: #cad3f5;
- padding: 0;
-}
-
-.floating-notifications.background .notification-row .notification-background .notification {
- padding: 7px;
- border-radius: 12.6px;
-}
-
-.floating-notifications.background .notification-row .notification-background .notification.critical {
- box-shadow: inset 0 0 7px 0 #ed8796;
-}
-
-.floating-notifications.background .notification-row .notification-background .notification .notification-content {
- margin: 7px;
-}
-
-.floating-notifications.background .notification-row .notification-background .notification .notification-content .summary {
- color: #cad3f5;
-}
-
-.floating-notifications.background .notification-row .notification-background .notification .notification-content .time {
- color: #a5adcb;
-}
-
-.floating-notifications.background .notification-row .notification-background .notification .notification-content .body {
- color: #cad3f5;
-}
-
-.floating-notifications.background .notification-row .notification-background .notification > *:last-child > * {
- min-height: 3.4em;
-}
-
-.floating-notifications.background .notification-row .notification-background .notification > *:last-child > * .notification-action {
- border-radius: 7px;
- color: #cad3f5;
- background-color: #363a4f;
- box-shadow: inset 0 0 0 1px #494d64;
- margin: 7px;
-}
-
-.floating-notifications.background .notification-row .notification-background .notification > *:last-child > * .notification-action:hover {
- box-shadow: inset 0 0 0 1px #494d64;
- background-color: #363a4f;
- color: #cad3f5;
-}
-
-.floating-notifications.background .notification-row .notification-background .notification > *:last-child > * .notification-action:active {
- box-shadow: inset 0 0 0 1px #494d64;
- background-color: #7dc4e4;
- color: #cad3f5;
-}
-
-.floating-notifications.background .notification-row .notification-background .close-button {
- margin: 7px;
- padding: 2px;
- border-radius: 6.3px;
- color: #24273a;
- background-color: #ed8796;
-}
-
-.floating-notifications.background .notification-row .notification-background .close-button:hover {
- background-color: #ee99a0;
- color: #24273a;
-}
-
-.floating-notifications.background .notification-row .notification-background .close-button:active {
- background-color: #ed8796;
- color: #24273a;
-}
-
-.control-center {
- box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.8), inset 0 0 0 1px #363a4f;
- border-radius: 12.6px;
- margin: 18px;
- background-color: #24273a;
- color: #cad3f5;
- padding: 14px;
-}
-
-.control-center .widget-title {
- color: #cad3f5;
- font-size: 1.3em;
-}
-
-.control-center .widget-title button {
- border-radius: 7px;
- color: #cad3f5;
- background-color: #363a4f;
- box-shadow: inset 0 0 0 1px #494d64;
- padding: 8px;
-}
-
-.control-center .widget-title button:hover {
- box-shadow: inset 0 0 0 1px #494d64;
- background-color: #5b6078;
- color: #cad3f5;
-}
-
-.control-center .widget-title button:active {
- box-shadow: inset 0 0 0 1px #494d64;
- background-color: #7dc4e4;
- color: #24273a;
-}
-
-.control-center .notification-row .notification-background {
- border-radius: 7px;
- color: #cad3f5;
- background-color: #363a4f;
- box-shadow: inset 0 0 0 1px #494d64;
- margin-top: 14px;
-}
-
-.control-center .notification-row .notification-background .notification {
- padding: 7px;
- border-radius: 7px;
-}
-
-.control-center .notification-row .notification-background .notification.critical {
- box-shadow: inset 0 0 7px 0 #ed8796;
-}
-
-.control-center .notification-row .notification-background .notification .notification-content {
- margin: 7px;
-}
-
-.control-center .notification-row .notification-background .notification .notification-content .summary {
- color: #cad3f5;
-}
-
-.control-center .notification-row .notification-background .notification .notification-content .time {
- color: #a5adcb;
-}
-
-.control-center .notification-row .notification-background .notification .notification-content .body {
- color: #cad3f5;
-}
-
-.control-center .notification-row .notification-background .notification > *:last-child > * {
- min-height: 3.4em;
-}
-
-.control-center .notification-row .notification-background .notification > *:last-child > * .notification-action {
- border-radius: 7px;
- color: #cad3f5;
- background-color: #181926;
- box-shadow: inset 0 0 0 1px #494d64;
- margin: 7px;
-}
-
-.control-center .notification-row .notification-background .notification > *:last-child > * .notification-action:hover {
- box-shadow: inset 0 0 0 1px #494d64;
- background-color: #363a4f;
- color: #cad3f5;
-}
-
-.control-center .notification-row .notification-background .notification > *:last-child > * .notification-action:active {
- box-shadow: inset 0 0 0 1px #494d64;
- background-color: #7dc4e4;
- color: #cad3f5;
-}
-
-.control-center .notification-row .notification-background .close-button {
- margin: 7px;
- padding: 2px;
- border-radius: 6.3px;
- color: #24273a;
- background-color: #ee99a0;
-}
-
-.control-center .notification-row .notification-background .close-button:hover {
- background-color: #ed8796;
- color: #24273a;
-}
-
-.control-center .notification-row .notification-background .close-button:active {
- background-color: #ed8796;
- color: #24273a;
-}
-
-.control-center .notification-row .notification-background:hover {
- box-shadow: inset 0 0 0 1px #494d64;
- background-color: #8087a2;
- color: #cad3f5;
-}
-
-.control-center .notification-row .notification-background:active {
- box-shadow: inset 0 0 0 1px #494d64;
- background-color: #7dc4e4;
- color: #cad3f5;
-}
-
-progressbar,
-progress,
-trough {
- border-radius: 12.6px;
-}
-
-progressbar {
- box-shadow: inset 0 0 0 1px #494d64;
-}
-
-.notification.critical progress {
- background-color: #ed8796;
-}
-
-.notification.low progress,
-.notification.normal progress {
- background-color: #8aadf4;
-}
-
-trough {
- background-color: #363a4f;
-}
-
-.control-center trough {
- background-color: #494d64;
-}
-
-.control-center-dnd {
- margin-top: 5px;
- border-radius: 8px;
- background: #363a4f;
- border: 1px solid #494d64;
- box-shadow: none;
-}
-
-.control-center-dnd:checked {
- background: #363a4f;
-}
-
-.control-center-dnd slider {
- background: #494d64;
- border-radius: 8px;
-}
-
-.widget-dnd {
- margin: 0px;
- font-size: 1.1rem;
-}
-
-.widget-dnd > switch {
- font-size: initial;
- border-radius: 8px;
- background: #363a4f;
- border: 1px solid #494d64;
- box-shadow: none;
-}
-
-.widget-dnd > switch:checked {
- background: #363a4f;
-}
-
-.widget-dnd > switch slider {
- background: #494d64;
- border-radius: 8px;
- border: 1px solid #6e738d;
-}
diff --git a/.config/wlogout/imgs/lock-hover.png b/.config/wlogout/imgs/lock-hover.png
deleted file mode 100755
index 8fb86fe..0000000
Binary files a/.config/wlogout/imgs/lock-hover.png and /dev/null differ
diff --git a/.config/wlogout/imgs/lock.png b/.config/wlogout/imgs/lock.png
deleted file mode 100755
index 430451c..0000000
Binary files a/.config/wlogout/imgs/lock.png and /dev/null differ
diff --git a/.config/wlogout/imgs/logout-hover.png b/.config/wlogout/imgs/logout-hover.png
deleted file mode 100755
index 9e570a9..0000000
Binary files a/.config/wlogout/imgs/logout-hover.png and /dev/null differ
diff --git a/.config/wlogout/imgs/logout.png b/.config/wlogout/imgs/logout.png
deleted file mode 100755
index 128c995..0000000
Binary files a/.config/wlogout/imgs/logout.png and /dev/null differ
diff --git a/.config/wlogout/imgs/power-hover.png b/.config/wlogout/imgs/power-hover.png
deleted file mode 100755
index 122d331..0000000
Binary files a/.config/wlogout/imgs/power-hover.png and /dev/null differ
diff --git a/.config/wlogout/imgs/power.png b/.config/wlogout/imgs/power.png
deleted file mode 100755
index ce56166..0000000
Binary files a/.config/wlogout/imgs/power.png and /dev/null differ
diff --git a/.config/wlogout/imgs/restart-hover.png b/.config/wlogout/imgs/restart-hover.png
deleted file mode 100755
index 3e18536..0000000
Binary files a/.config/wlogout/imgs/restart-hover.png and /dev/null differ
diff --git a/.config/wlogout/imgs/restart.png b/.config/wlogout/imgs/restart.png
deleted file mode 100755
index 7855d40..0000000
Binary files a/.config/wlogout/imgs/restart.png and /dev/null differ
diff --git a/.config/wlogout/imgs/sleep-hover.png b/.config/wlogout/imgs/sleep-hover.png
deleted file mode 100755
index 0fd3bad..0000000
Binary files a/.config/wlogout/imgs/sleep-hover.png and /dev/null differ
diff --git a/.config/wlogout/imgs/sleep.png b/.config/wlogout/imgs/sleep.png
deleted file mode 100755
index 6a3d607..0000000
Binary files a/.config/wlogout/imgs/sleep.png and /dev/null differ
diff --git a/.config/wlogout/layout b/.config/wlogout/layout
deleted file mode 100755
index f3920b7..0000000
--- a/.config/wlogout/layout
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "label" : "lock",
- "action" : "~/.config/hypr/scripts/lock.sh",
- "text" : "Lock",
- "keybind" : "l"
-}
-{
- "label" : "reboot",
- "action" : "~/.config/hypr/scripts/close_apps.sh && systemctl reboot",
- "text" : "Reboot",
- "keybind" : "r"
-}
-{
- "label" : "shutdown",
- "action" : "~/.config/hypr/scripts/close_apps.sh && systemctl poweroff",
- "text" : "Shutdown",
- "keybind" : "s"
-}
-{
- "label" : "logout",
- "action" : "~/.config/hypr/scripts/close_apps.sh && hyprctl dispatch exit ",
- "text" : "Logout",
- "keybind" : "e"
-}
-{
- "label" : "suspend",
- "action" : "systemctl suspend",
- "text" : "Suspend",
- "keybind" : "u"
-}
-{
- "label" : "suspend",
- "action" : "systemctl hibernate",
- "text" : "Hibernate",
- "keybind" : "h"
-}
diff --git a/.config/wlogout/style.css b/.config/wlogout/style.css
deleted file mode 100755
index 784bb15..0000000
--- a/.config/wlogout/style.css
+++ /dev/null
@@ -1,61 +0,0 @@
-window {
- font-family: monospace;
- font-size: 14pt;
- color: #cdd6f4; /* text */
- background-color: rgba(30, 30, 46, 0.5);
-}
-
-button {
- background-repeat: no-repeat;
- background-position: center;
- background-size: 25%;
- border: none;
- background-color: rgba(30, 30, 46, 0);
- margin: 5px;
- transition: box-shadow 0.2s ease-in-out, background-color 0.2s ease-in-out;
-}
-
-button:hover {
- background-color: rgba(49, 50, 68, 0.1);
-}
-
-button:focus {
- background-color: #cba6f7;
- color: #1e1e2e;
- border: none;
-}
-
-#lock {
- background-image: image(url("./imgs/lock.png"));
-}
-#lock:focus {
- background-image: image(url("./imgs/lock-hover.png"));
-}
-
-#logout {
- background-image: image(url("./imgs/logout.png"));
-}
-#logout:focus {
- background-image: image(url("./imgs/logout-hover.png"));
-}
-
-#suspend {
- background-image: image(url("./imgs/sleep.png"));
-}
-#suspend:focus {
- background-image: image(url("./imgs/sleep-hover.png"));
-}
-
-#shutdown {
- background-image: image(url("./imgs/power.png"));
-}
-#shutdown:focus {
- background-image: image(url("./imgs/power-hover.png"));
-}
-
-#reboot {
- background-image: image(url("./imgs/restart.png"));
-}
-#reboot:focus {
- background-image: image(url("./imgs/restart-hover.png"));
-}
diff --git a/.config/yazi/keymap.toml b/.config/yazi/keymap.toml
deleted file mode 100644
index 0a47453..0000000
--- a/.config/yazi/keymap.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-# Bookmarks
-[[manager.prepend_keymap]]
-on = [ "b", "g" ]
-run = "cd ~/git/"
-desc = "GIT"
-
-[[manager.prepend_keymap]]
-on = [ "b", "d" ]
-run = "cd ~/Data/"
-desc = "DATA"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7f473d9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+roles/z
+roles/test
+error.log
+callback_plugins/__pycache__
diff --git a/README.md b/README.md
index 9fb7df7..2e5e390 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,40 @@
-# My Dotfiles
-- Simple install script
-- Arch
+# Installation
+Clone the repo and execute the `install.sh` script.
+Or use this command:
+```bash
+bash -c "$(curl -fsSL https://gitea.keuledrive.de/Keule2/Dotfiles/raw/branch/main/install.sh)"
+```
+Or this command to use arguments:
+```bash
+curl -fsSL "https://gitea.keuledrive.de/Keule2/Dotfiles/raw/branch/main/install.sh" | bash -s -- -e "system=server"
+```
+
+# Update
+Just execute the `install.sh` script again.
+
+# Usage
+All additional parameters are passed to the ansible playbook. This means that you can skip tags or only execute desired tags.
+Example: Skip alacritty
+```bash
+./install.sh --skip-tags alacritty
+```
+Example: Only execute alacritty and fish
+```bash
+./install.sh -t alacritty,fish
+```
+
+# Settings
+There are two ways to set settings.
+1. Create/Edit: `$HOME/.config/dotfiles/values.yml`
+2. Edit: `$HOME/.dotfiles/group_vars/all`
+
+## Install Option
+The variable `system` has three valid options.
+1. server: Minimal installation, only install and configure CMD tools
+2. desktop (default): Install WM and desktop applications
+3. desktop_full: Install additional packages for the desktop (wine)
# TODO
-...
+- AGS: Bar, AppLauncher, PowerMenu, Notifications, Calculator, Emoji-Picker, ...
+- Ubuntu/Debian Support
+- ...
diff --git a/ansible.cfg b/ansible.cfg
new file mode 100644
index 0000000..808ad9c
--- /dev/null
+++ b/ansible.cfg
@@ -0,0 +1,4 @@
+[defaults]
+stdout_callback = beautiful_output
+# Use the stdout_callback when running ad-hoc commands.
+bin_ansible_callbacks = True
diff --git a/applications.pkgs b/applications.pkgs
deleted file mode 100644
index f615c19..0000000
--- a/applications.pkgs
+++ /dev/null
@@ -1,32 +0,0 @@
-libreoffice-fresh
-nextcloud-client
-youtube-music
-waypaper-git
-pavucontrol
-hyprpicker
-brave-bin
-vscodium
-obsidian
-discord
-yt-dlp
-mpv
-
-#Device configuration
-#openrazer-daemon
-#openrgb
-#piper
-
-#AMD Stats
-#amdgpu_top
-
-#Explorer
-#qt5-imageformats
-#thunar
-#dolphin
-#ark
-
-#Character map
-#gucharmap
-
-#Calculator
-#galculator
diff --git a/callback_plugins/beautiful_output.py b/callback_plugins/beautiful_output.py
new file mode 100644
index 0000000..a2493cd
--- /dev/null
+++ b/callback_plugins/beautiful_output.py
@@ -0,0 +1,1466 @@
+# -*- coding: utf-8 -*-
+
+# MIT License
+#
+# Copyright (c) 2019 Thiago Alves
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""A clean and opinionated output callback plugin.
+
+The goal of this plugin is to consolidated Ansible's output in the style of
+LINUX/UNIX startup logs, and use unicode symbols to display task status.
+
+This Callback plugin is intended to be used on playbooks that you have
+to execute *"in-person"*, since it does always output to the screen.
+
+In order to use this Callback plugin, you should add this Role as a dependency
+in your project, and set the ``stdout_callback`` option on the
+:file:`ansible.cfg file::
+
+ stdout_callback = beautiful_output
+
+"""
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = """---
+ callback: beautiful_output
+ type: stdout
+ author: Thiago Alves
+ short_description: a clean, condensed, and beautiful Ansible output
+ version_added: 2.8
+ description:
+ - >-
+ Consolidated Ansible output in the style of LINUX/UNIX startup
+ logs, and use unicode symbols to organize tasks.
+ extends_documentation_fragment:
+ - default_callback
+ requirements:
+ - set as stdout in configuration
+"""
+
+import json
+import locale
+import os
+import re
+import textwrap
+import yaml
+
+from ansible import constants as C
+from ansible import context
+from ansible.executor.task_result import TaskResult
+from ansible.module_utils._text import to_text, to_bytes
+from ansible.module_utils.common._collections_compat import Mapping
+from ansible.parsing.utils.yaml import from_yaml
+from ansible.plugins.callback import CallbackBase
+from ansible.template import Templar
+from ansible.utils.color import colorize, hostcolor, stringc
+from ansible.vars.clean import strip_internal_keys, module_response_deepcopy
+from ansible.vars.hostvars import HostVarsVars
+from collections import OrderedDict
+try:
+ from collections.abc import Sequence
+except:
+ from collections import Sequence
+from numbers import Number
+from os.path import basename, isdir
+from watchdog.observers import Observer
+from watchdog.events import FileSystemEventHandler, EVENT_TYPE_CREATED
+
+_symbol = {
+ "success": to_text("✔"),
+ "warning": to_text("⚠"),
+ "failure": to_text("✘"),
+ "dead": to_text("✝"),
+ "yaml": to_text("🅨"),
+ "retry": to_text("️↻"),
+ "loop": to_text("∑"),
+ "arrow_right": to_text("➞"),
+ "skip": to_text("⤼"),
+ "flag": to_text("⚑"),
+} # type: Dict[str,str]
+""":obj:`dict` of :obj:`str` to :obj:`str`: A dictionary of symbols to be used
+when the Callback needs to display a symbol on the screen.
+"""
+
+_session_title = {
+ "msg": "Message",
+ "stdout": "Output",
+ "stderr": "Error output",
+ "module_stdout": "Module output",
+ "module_stderr": "Module error output",
+ "rc": "Return code",
+ "changed": "Environment changed",
+ "_ansible_no_log": "Omit logs",
+ "use_stderr": "Use STDERR to output",
+} # type: Dict[str,str]
+""":obj:`dict` of :obj:`str` to :obj:`str`: A dictionary of terms used as
+section title when displayin the output of a command.
+"""
+
+_session_order = OrderedDict(
+ [
+ ("_ansible_no_log", 3),
+ ("use_stderr", 4),
+ ("msg", 1),
+ ("stdout", 1),
+ ("module_stdout", 1),
+ ("stderr", 1),
+ ("module_stderr", 1),
+ ("rc", 3),
+ ("changed", 3),
+ ]
+)
+""":obj:`dict` of :obj:`str` to :obj:`str`: A dictionary representing the
+display an order in wich sections should be displayed to user.
+"""
+
+ansi_escape = re.compile(
+ r"""
+ \x1B # ESC
+ [@-_] # 7-bit C1 Fe
+ [0-?]* # Parameter bytes
+ [ -/]* # Intermediate bytes
+ [@-~] # Final byte
+""",
+ re.VERBOSE,
+)
+""":regexp:`Pattern`: A regular expression that can match any ANSI escape
+sequence in a string.
+"""
+
+
+def symbol(key, color=None): # type: (str, str) -> str
+ """Helper function that returns an Unicode character based on the given
+ ``key``. This function also colorize the returned string using the
+ :func:`~ansible.utils.color.stringc` function, depending on the value
+ passed to `color`.
+
+ Args:
+ key (:obj:`str`): One of the keys used to define the dictionary
+ :const:`~beautiful_output._symbol`.
+ color (:obj:`str`, optional): a string representing the color that
+ should be used to diplay the given symbol
+
+ Returns:
+ :obj:`str`: A unicode character representing a symbol for the given
+ ``key``.
+ """
+ output = _symbol.get(key, to_text(":{0}:").format(key))
+ if not color:
+ return output
+ return stringc(output, color)
+
+
+def iscollection(obj):
+ """Helper method to check if a given object is not only a Squence, but also
+ **not** any kind of string.
+
+ Args:
+ obj (object): The object used on the validation.
+
+ Returns:
+ bool: True if the object is a collection and False otherwise.
+ """
+ return isinstance(obj, Sequence) and not isinstance(obj, basestring)
+
+
+def stringtruncate(
+ value,
+ color="normal",
+ width=0,
+ justfn=None,
+ fillchar=" ",
+ truncate_placeholder="[...]",
+):
+ """Truncates a giving string using the configuration passed as arguments to
+ this function.
+
+ Args:
+ value (:obj:`str` or int): A value to be truncated if it has more
+ characters than is allowed.
+ color (:obj:`str`, optional): A string representing a color for Ansible.
+ If this color is ``None``, no color will be used. Defaults to None.
+ width (int, optional): The limits of characters allowed for the giving
+ ``value``. If 0 is given, no truncation happens. Defaults to 0.
+ justfn (:func:`Callable`, optional): A function to do the justification
+ of the text. Defaults to :func:`str.rjust` if the type of ``value``
+ is integer and :func:`str.ljust` otherwise.
+ fillchar (:obj:`str`, optional): The character used to fill the space up
+ to ``width`` after (or before) the ``value`` content. Defaults to
+ " ".
+ truncate_placeholder (:obj:`str`, optional): The text used to represents
+ the truncation. Defaults to "[...]".
+
+ Returns:
+ The original string truncated to ``width`` and aligned according to
+ ``justfn``.
+ """
+ if not value:
+ return fillchar * width
+
+ if not justfn:
+ justfn = str.rjust if isinstance(value, int) else str.ljust
+
+ if isinstance(value, int):
+ value = to_text("{:n}").format(value)
+
+ truncsize = len(truncate_placeholder)
+ do_not_trucate = len(value) <= width or width == 0
+ truncated_width = width - truncsize
+
+ return stringc(
+ to_text(justfn(str(value), width))
+ if do_not_trucate
+ else to_text("{0}{1}".format(
+ value[:truncated_width] if justfn == str.ljust else truncate_placeholder,
+ truncate_placeholder if justfn == str.ljust else value[truncated_width:],
+ )),
+ color,
+ )
+
+
+def dictsum(totals, values):
+ """Given two dictionaries of ``int`` values, this method will sum the
+ value in ``totals`` with values in ``values``.
+
+ If a key in ``values`` does not exist in ``totals``, that key will be
+ added to it, and its initial value will be the same as in ``values``.
+
+ Note:
+ The type of the keys in the dictionaries are irrelevant, and this
+ method will re-use anything that is used there.
+
+ Args:
+ totals (:obj:`dict` of :obj:`object` to int): The total cached
+ from previous calls of this functions.
+ values (:obj:`dict` of :obj:`object` to int): The dictionary of
+ values used to sum up the totals.
+
+ Exemple:
+ >>> dict1 = {"key1": 10, "key2": 20, "key3": 30}
+ >>> dict2 = {"key1": 5, "key2": 10, "key3": 15}
+ >>> dict3 = {"key1": 1, "key2": 2, "key3": 3}
+ >>> totals = {}
+ >>> dictsum(totals, dict1)
+ >>> totals
+ {"key1": 10, "key2": 20, "key3": 30}
+ >>> dictsum(totals, dict2)
+ >>> totals
+ {"key1": 15, "key2": 30, "key3": 45}
+ >>> dictsum(totals, dict3)
+ >>> totals
+ {"key1": 16, "key2": 32, "key3": 48}
+ """
+ for key, value in values.items():
+ if key not in totals:
+ totals[key] = value
+ else:
+ totals[key] += value
+
+
+class CallbackModule(CallbackBase, FileSystemEventHandler):
+ """The Callback plugin class to produce clean outputs.
+
+ This class handles all Ansible callbacks that generate text on the output.
+ It follows the new user configuration variables like
+ :data:`~ansible.constants.DISPLAY_ARGS_TO_STDOUT` and
+ :data:`~ansible.constants.DISPLAY_SKIPPED_HOSTS`, and it wraps lines at
+ column ``80`` to make it possible to read the output on any monitor.
+
+ In addition to that, the ``beautiful_output`` plugin implements a crud
+ version of a Bus to allow other plugins to flush the output when necessary.
+
+ Normally, in order to hide task not executed, the ``beautiful_output``
+ plugin will delay printing the task's title until it knows there is anything
+ to print. On certain conditions, an action plugin can output an information
+ to the user, and without the Bus mechanism, the action plugin output would
+ show up before the task title is printed, which would feel like the action
+ plugin output belongs to the previous task.
+
+ In order to flush the output on these scenarios, a plugin needs to write a
+ file to a location where the ``beautiful_output`` plugin is observing. At
+ this point, the Callback plugin will flush any outstanding text, and the
+ other plugin can proceed with its own task.
+
+ Args:
+ display (:obj:`ansible.utils.display.Display`, optional): Holds the
+ display to be used to print outputs with this callback.
+
+ Attributes:
+ CALLBACK_VERSION (:obj:`decimal`): A class attribute that holds the
+ last version of Ansible Callback API that can use this plugin.
+ CALLBACK_TYPE (:obj:`str`): The type of callback this plugin is
+ implementing.
+ CALLBACK_NAME (:obj:`str`): The name of this plugin.
+ BUS_DIR (:obj:`str`): The path where the ``beautiful_stdout`` plugin
+ will observe for files to trigger a flush.
+ delegated_vars (:obj:`dict` of :obj:`str` to :obj:`str`): This
+ dictionaire is used to store the variables used by a task when it
+ delegated to a different host. Mostly, we only need to know the
+ host name where our task was delegated to. Defaults to ``None``.
+ _item_processed (:obj:`bool`): A flag indicating if an item from a task
+ was already processed and printed. This is to allow us to print a
+ header before start printin all the items from a task. Defaults to
+ ``False``.
+ _current_play (:obj:`~ansible.playbook.play.Play`): This attribute holds
+ the current play being executed on this playbook. Defaults to
+ ``None``.
+ _current_host (:obj:`str`): The host where a task is being executed at
+ the moment we access this attribute. If this attribute is ``None``,
+ this means that at this moment there is no task being executed on
+ any host. Defaults to ``None``.
+ _task_name_buffer (:obj:`str`): This attribute holds the text that
+ should be printed when a task is being executed. Defaults to
+ ``None``.
+
+ See Also:
+ - :class:`ansible.plugins.callback.CallbackBase`
+ - :class:`watchdog.events.FileSystemEventHandler`
+ - `Ansible Callback documentation`_
+
+ References:
+ - `Ansible developping plugins documentation`_
+ - `Ansible Callback plugins from Ansible Core`_
+
+
+ .. _Ansible Callback documentation:
+ https://docs.ansible.com/ansible/latest/plugins/callback.html
+ .. _Ansible developping plugins documentation:
+ https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html#callback-plugins
+ .. _Ansible Callback plugins from Ansible Core:
+ https://github.com/ansible/ansible/tree/devel/lib/ansible/plugins/callback
+ """
+
+ CALLBACK_VERSION = 2.0
+ CALLBACK_TYPE = "stdout"
+ CALLBACK_NAME = "beautiful_output"
+ BUS_DIR = "%s/beautiful-output-bus" % C.DEFAULT_LOCAL_TMP
+
+ def __init__(self, display=None):
+ CallbackBase.__init__(self, display)
+ self.delegated_vars = None
+ self._item_processed = False
+ self._current_play = None
+ self._current_host = None
+ self._task_name_buffer = None
+
+ def display(self, msg, color=None, stderr=False):
+ """Helper method to display text on the screen.
+
+ This method is a thin wrapper aroung the real
+ :meth:`~ansible.utils.display.Display.display` method from the Ansible
+ :class:`~ansible.utils.display.Display` class.
+
+ Any ``msg`` that is displayed with this method, will be displayed
+ without any changes on the screen, and will have all the ANSI escape
+ sequences stripped before displaying it on the logs.
+
+ Args:
+ msg (:obj:`str`): The message to be displayed.
+ color (:obj:`str`, optional): A string representing a color on the
+ Ansible Display system. Defaults to None.
+ stderr (bool, optional): Flag indicating that the ``msg``should be
+ displayed on the :data:`stderr` stream. Defaults to False.
+ """
+ self._display.display(msg=msg, color=color, stderr=stderr, screen_only=True)
+ self._display.display(
+ msg=ansi_escape.sub("", msg), stderr=stderr, log_only=True
+ )
+
+ def v2_playbook_on_start(self, playbook):
+ """Displays the Playbook report Header when Ansible starst running it.
+
+ The content displayed will depend on the options used to run the
+ playbook, as well as the options configured in the :file:`ansible.cfg`
+ file.
+
+ It will always show which playbook it is running and if it is running
+ in check mode.
+
+ It will display all arguments used to run the given ``playbook` if it
+ is running in verbose mode (`-vvv`), the ``display_args_to_stdout``
+ option in the :file:`ansible.cfg` file, or if the
+ ``ANSIBLE_DISPLAY_ARGS_TO_STDOUT`` environment variable is set
+
+ It will display a tag line, only if the CLI arguments are **not**
+ displayed, since the tags used to filters which tasks to run are passed
+ in the command line as arguments
+
+ Args:
+ playbook (:obj:`~ansible.playbook.Playbook`): The running playbook.
+
+ See Also:
+ - :meth:`_display_cli_arguments`
+ - :meth:`_display_tag_strip`
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_playbook_on_start`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ playbook_name = to_text("{0} {1}").format(
+ symbol(to_text("yaml"), C.COLOR_HIGHLIGHT),
+ stringc(basename(playbook._file_name), C.COLOR_HIGHLIGHT),
+ )
+ if (
+ "check" in context.CLIARGS
+ and bool(context.CLIARGS["check"])
+ and not self._is_run_verbose(verbosity=3)
+ and not C.DISPLAY_ARGS_TO_STDOUT
+ ):
+ playbook_name = to_text("{0} (check mode)").format(playbook_name)
+
+ self.display(to_text("\nExecuting playbook {0}").format(playbook_name))
+
+ # show CLI arguments
+ if self._is_run_verbose(verbosity=3) or C.DISPLAY_ARGS_TO_STDOUT:
+ self._display_cli_arguments()
+ else:
+ self._display_tag_strip(playbook)
+ self.display(to_text("\n"))
+
+ def v2_playbook_on_no_hosts_matched(self):
+ """Display a warning when there is no hosts available.
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_playbook_on_no_hosts_matched`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ self.display(
+ " %s No hosts found!" % symbol("warning", "bright yellow"),
+ color=C.COLOR_DEBUG,
+ )
+
+ def v2_playbook_on_no_hosts_remaining(self):
+ """Display an error when one or more hosts that were alive when the
+ playbook start running are not reachable anymore.
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_playbook_on_no_hosts_remaining`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ self.display(
+ " %s Ran out of hosts!" % symbol("warning", "bright red"),
+ color=C.COLOR_ERROR,
+ )
+
+ def v2_playbook_on_play_start(self, play):
+ """Displays a banner with the play name and the hosts used in this
+ play.
+
+ This method might be called multimple times during the execution of a
+ playbook, and it will not always have the play changed. Due to this
+ fact, we short-circuit the method to not do anything if the play used
+ to display the banner is the same as the one used on the last time the
+ method was called.
+
+ Args:
+ play (:obj:`~ansible.playbook.play.Play`): the current play being
+ executed on this playbook.
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_playbook_on_play_start`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ if self._current_play:
+ self._current_play = play
+ return
+ self._current_play = play
+ name = play.get_name().strip()
+ if name:
+ self.display(
+ to_text("[PLAY: {0}]").format(stringc(name, C.COLOR_HIGHLIGHT)).center(91, "-")
+ )
+ else:
+ self.display("[PLAY]".center(80, "-"))
+
+ if play.hosts:
+ self.display("Hosts:")
+ for host in play.hosts:
+ self.display(to_text(" - {0}").format(stringc(host, C.COLOR_HIGHLIGHT)))
+ self.display(to_text("-") * 80)
+
+ def v2_playbook_on_task_start(self, task, is_conditional):
+ """Displays a title for the giving ``task`.
+
+ Args:
+ task (:obj:`~ansible.playbook.task.Task`): The task to have its
+ title printed in the console.
+ is_conditional: This attribute is ignored in this callback.
+
+ See Also:
+ :meth:`_display_task_name`
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_playbook_on_task_start`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ self._display_task_name(task)
+
+ def v2_playbook_on_handler_task_start(self, task):
+ """Displays a title for the giving ``task`, marking it as a handler
+ task.
+
+ Args:
+ task (:obj:`~ansible.playbook.task.Task`): The task to have its
+ title printed in the console.
+
+ See Also:
+ :meth:`_display_task_name`
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_playbook_on_handler_task_start`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ self._display_task_name(task, is_handler=True)
+
+ def v2_runner_retry(self, result):
+ """Displays the retrying steps Ansible is doing to make the task run
+ on the host.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the previous attempt to run the task.
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_runner_retry`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ msg = " ️%s Retrying... (%d of %d)" % (
+ symbol("retry"),
+ result._result["attempts"],
+ result._result["retries"],
+ )
+ if self._is_run_verbose(result, 2):
+ # All result keys stating with _ansible_ are internal, so remove them from the result before we output anything.
+ abridged_result = strip_internal_keys(
+ module_response_deepcopy(result._result)
+ )
+ abridged_result.pop("exception", None)
+
+ if not self._is_run_verbose(verbosity=3):
+ abridged_result.pop("invocation", None)
+ abridged_result.pop("diff", None)
+
+ msg += "Result was: %s" % CallbackModule.dump_value(abridged_result)
+ self.display(msg, color=C.COLOR_DEBUG)
+
+ def v2_runner_on_start(self, host, task):
+ """Caches the giving ``host`` object to be easily accessible during the
+ evaluation of a task display.
+
+ Args:
+ host (:obj:`~ansible.inventory.host.Host`): The host that will run
+ the giving ``task``.
+ task (:obj:`~ansible.playbook.task.Task`): The task that will be
+ ran on the giving ``host``.
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_runner_on_start`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ self._current_host = host
+
+ def v2_runner_on_ok(self, result):
+ """Displays the result of a task run.
+
+ This method will also be called every time an **item**, on a loop task,
+ is processed.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+
+ See Also:
+ - :meth:`_preprocess_result`
+ - :meth:`changed_artifacts`
+ - :meth:`_process_result_output`
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_runner_on_ok`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ if self._item_processed:
+ return
+
+ self._preprocess_result(result)
+ msg, display_color = CallbackModule.changed_artifacts(result, "ok", C.COLOR_OK)
+ task_result = self._process_result_output(result, msg, symbol("success"))
+ self.display(task_result, display_color)
+
+ def v2_runner_on_skipped(self, result):
+ """If the you configured Ansible to display skipped hosts, this method
+ will display the task and information that it was skipped.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+
+ See Also:
+ - :meth:`_preprocess_result`
+ - :meth:`_process_result_output`
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_runner_on_skipped`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ if C.DISPLAY_SKIPPED_HOSTS:
+ self._preprocess_result(result)
+ task_result = self._process_result_output(result, "skipped", symbol("skip"))
+ self.display(task_result, C.COLOR_SKIP)
+ pass
+ else:
+ self.outlines = []
+
+ def v2_runner_on_failed(self, result, ignore_errors=False):
+ """When a task fails, this method is called to display information
+ about the error.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+
+ See Also:
+ - :meth:`_preprocess_result`
+ - :meth:`_process_result_output`
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_runner_on_failed`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ if self._item_processed:
+ return
+
+ self._preprocess_result(result)
+ status = "ignored" if ignore_errors else "failed"
+ color = C.COLOR_SKIP if ignore_errors else C.COLOR_ERROR
+ task_result = self._process_result_output(result, status, symbol("failure"))
+ self.display(task_result, color)
+
+ def v2_runner_on_unreachable(self, result):
+ """When a host becames *unreachable* before the execution of its task,
+ this method will display information about the unreachability.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+
+ See Also:
+ - :meth:`_preprocess_result`
+ - :meth:`_process_result_output`
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_runner_on_unreachable`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ self._flush_display_buffer()
+ task_result = self._process_result_output(result, "unreachable", symbol("dead"))
+ self.display(task_result, C.COLOR_UNREACHABLE)
+
+ def v2_runner_item_on_ok(self, result):
+ """Displays the result of an item task run.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+
+ See Also:
+ - :meth:`_preprocess_result`
+ - :meth:`changed_artifacts`
+ - :meth:`_process_item_result_output`
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_runner_on_ok`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ self._preprocess_result(result)
+ status, display_color = CallbackModule.changed_artifacts(
+ result, "ok", C.COLOR_OK
+ )
+ task_result = self._process_item_result_output(
+ result, status, symbol("success")
+ )
+ self.display(task_result, display_color)
+
+ def v2_runner_item_on_skipped(self, result):
+ """If the you configured Ansible to display skipped hosts, this method
+ will display a task item and information that it was skipped.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+
+ See Also:
+ - :meth:`_preprocess_result`
+ - :meth:`_process_item_result_output`
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_runner_on_skipped`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ if C.DISPLAY_SKIPPED_HOSTS:
+ self._preprocess_result(result)
+ task_result = self._process_item_result_output(
+ result, "skipped", symbol("skip")
+ )
+ self.display(task_result, C.COLOR_SKIP)
+ else:
+ self.outlines = []
+
+ def v2_runner_item_on_failed(self, result):
+ """When an intem on a task fails, this method is called to display
+ information about the failure.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+
+ See Also:
+ - :meth:`_preprocess_result`
+ - :meth:`_process_item_result_output`
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_runner_item_on_failed`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ self._flush_display_buffer()
+ task_result = self._process_item_result_output(
+ result, "failed", symbol("failure")
+ )
+ self.display(task_result, C.COLOR_ERROR)
+
+ def v2_playbook_on_stats(self, stats):
+ """When the execution of a playbook finishes, this method is called to
+ display an execution summary.
+
+ It also displays an aggregate total for all executions.
+
+ Note:
+ Overrides the
+ :meth:`~ansible.plugins.callback.CallbackBase.v2_playbook_on_stats`
+ method from the :class:`~ansible.plugins.callback.CallbackBase`
+ class.
+ """
+ self.display(to_text("{0}\n\n").format("-" * 80))
+ totals = {
+ "ok": 0,
+ "changed": 0,
+ "unreachable": 0,
+ "failures": 0,
+ "rescued": 0,
+ "ignored": 0,
+ }
+
+ self._display_summary_table_row(
+ ("Hosts", C.COLOR_VERBOSE, 30),
+ ("Success", C.COLOR_VERBOSE, 7),
+ ("Changed", C.COLOR_VERBOSE, 7),
+ ("Dark", C.COLOR_VERBOSE, 7),
+ ("Failed", C.COLOR_VERBOSE, 7),
+ ("Rescued", C.COLOR_VERBOSE, 7),
+ ("Ignored", C.COLOR_VERBOSE, 7),
+ )
+ self._display_summary_table_separator("=")
+
+ hosts = sorted(stats.processed.keys())
+ for host_name in hosts:
+ host_summary = stats.summarize(host_name)
+ dictsum(totals, host_summary)
+ self._display_summary_table_row(
+ (host_name, C.COLOR_HIGHLIGHT, 30),
+ (host_summary["ok"], C.COLOR_OK, 7),
+ (host_summary["changed"], C.COLOR_CHANGED, 7),
+ (host_summary["unreachable"], C.COLOR_UNREACHABLE, 7),
+ (host_summary["failures"], C.COLOR_ERROR, 7),
+ (host_summary["rescued"], C.COLOR_OK, 7),
+ (host_summary["ignored"], C.COLOR_WARN, 7),
+ )
+
+ self._display_summary_table_separator("-")
+ self._display_summary_table_row(
+ ("Totals", C.COLOR_VERBOSE, 30),
+ (totals["ok"], C.COLOR_OK, 7),
+ (totals["changed"], C.COLOR_CHANGED, 7),
+ (totals["unreachable"], C.COLOR_UNREACHABLE, 7),
+ (totals["failures"], C.COLOR_ERROR, 7),
+ (totals["rescued"], C.COLOR_OK, 7),
+ (totals["ignored"], C.COLOR_WARN, 7),
+ )
+
+ def _handle_exception(self, result, use_stderr=False):
+ """When an exception happen during the execution of a playbook, this
+ method is called to display information about the crash.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+ use_stderr (bool, optional): Flag indicating if this exception
+ should be printed using the ``stderr`` stream. Defaults to
+ ``False``.
+ """
+ if "exception" in result:
+ result["use_stderr"] = use_stderr
+ msg = "An exception occurred during task execution. "
+ if not self._is_run_verbose(verbosity=3):
+ # extract just the actual error message from the exception text
+
+ error = result["exception"].strip().split("\n")[-1]
+ msg += "To see the full traceback, use -vvv. The error was: %s" % error
+ elif "module_stderr" in result:
+ if result["exception"] != result["module_stderr"]:
+ msg = "The full traceback is:\n" + result["exception"]
+ del result["exception"]
+ result["stderr"] = msg
+
+ def _is_run_verbose(self, result=None, verbosity=0):
+ """Verify if the current run is verbose (should display information)
+ respecting the given ``verbosity``.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult, optional):
+ The task result to be considered when checking verbosity.
+ Defaults to None.
+ verbosity (int, optional): The verbosity level that this method
+ will check against. Defaults to 0.
+
+ Returns:
+ bool: True if the display verbosity cresses the treshold defined by
+ the argument ``verbosity``, False otherwise.
+ """
+ result = {} if not result else result._result
+ return (
+ self._display.verbosity >= verbosity or "_ansible_verbose_always" in result
+ ) and "_ansible_verbose_override" not in result
+
+ def _display_cli_arguments(self, indent=2):
+ """Display all arguments passed to Ansible in the command line.
+
+ Args:
+ indent (int, optional): Number of spaces to indent the whole
+ arguments block. Defaults to 2.
+ """
+ if context.CLIARGS.get("args"):
+ self.display(
+ to_text("{0}Positional arguments: {1}").format(
+ " " * indent, ", ".join(context.CLIARGS["args"])
+ ),
+ color=C.COLOR_VERBOSE,
+ )
+
+ for arg, val in {
+ key: value
+ for key, value in context.CLIARGS.items()
+ if key != "args" and value
+ }.items():
+ if iscollection(val):
+ self.display(to_text("{0}{1}:").format(" " * indent, arg), color=C.COLOR_VERBOSE)
+ for v in val:
+ self.display(
+ to_text("{0}- {1}").format(" " * (indent + 2), v), color=C.COLOR_VERBOSE
+ )
+ else:
+ self.display(
+ to_text("{0}{1}: {2}").format(" " * indent, arg, val), color=C.COLOR_VERBOSE
+ )
+
+ def _get_tags(self, playbook):
+ """Returns a collection of tags that will be associated with all tasks
+ runnin during this session.
+
+ This means that it will collect all the tags available in the giving
+ ``playbook``, and filter against the tags passed to Ansible in the
+ command line.
+
+ Args:
+ playbook (:obj:`~ansible.playbook.Playbook`): The playbook where to
+ look for tags.
+
+ Returns:
+ :obj:`list` of :obj:`str`: A sorted list of all tags used in this
+ run.
+ """
+ tags = set()
+ for play in playbook.get_plays():
+ for block in play.compile():
+ blocks = block.filter_tagged_tasks({})
+ if blocks.has_tasks():
+ for task in blocks.block:
+ tags.update(task.tags)
+ if "tags" in context.CLIARGS:
+ requested_tags = set(context.CLIARGS["tags"])
+ else:
+ requested_tags = {"all"}
+ if len(requested_tags) > 1 or next(iter(requested_tags)) != "all":
+ tags = tags.intersection(requested_tags)
+ return sorted(tags)
+
+ def _display_tag_strip(self, playbook, width=80):
+ """Displays a line of tags present in the given ``playbook``
+ intersected with the tags given to Ansible in the command line.
+
+ If the line is bigger than ``width`` characters, it will wrap the tag
+ line before it cross the treshold.
+
+ To make the tag line be more aesthetic pleasant, it will be displayed
+ with a blank line before and after each line used.
+
+ Args:
+ playbook (:obj:`~ansible.playbook.Playbook`): The playbook where to
+ look for tags.
+ width (int): How many characters can be used in a single line.
+ Defaults to 80.
+ """
+ tags = self._get_tags(playbook)
+ tag_strings = ""
+ total_len = 0
+ first_item = True
+ for tag in sorted(tags):
+ if not first_item:
+ if total_len + len(tag) + 5 > width:
+ tag_strings += to_text("\n\n {0} {1} {2} {3}").format(
+ "\x1b[6;30;47m", symbol("flag"), tag, "\x1b[0m"
+ )
+ total_len = len(tag) + 6
+ first_item = True
+ else:
+ tag_strings += to_text(" {0} {1} {2} {3}").format(
+ "\x1b[6;30;47m", symbol("flag"), tag, "\x1b[0m"
+ )
+ total_len += len(tag) + 5
+ else:
+ first_item = False
+ tag_strings += to_text(" {0} {1} {2} {3}").format(
+ "\x1b[6;30;47m", symbol("flag"), tag, "\x1b[0m"
+ )
+ total_len = len(tag) + 6
+ self.display("\n")
+ self.display(tag_strings)
+
+ def _get_task_display_name(self, task):
+ """Caches the giving ``task`` name if it is not an include task.
+
+ Args:
+ task (:obj:`~ansible.playbook.task.Task`): The task object that
+ will be analyzed.
+ """
+ self.task_display_name = None
+ display_name = task.get_name().strip().split(" : ")
+
+ task_display_name = display_name[-1]
+ if task_display_name.startswith("include"):
+ return
+ else:
+ self.task_display_name = task_display_name
+
+ def _preprocess_result(self, result):
+ """Check the result object for errors or warning. It also make sure
+ that the task title buffer is flushed and displayed to the user.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+
+ See Also:
+ - :meth:`_flush_display_buffer`
+ - :meth:`_handle_exception`
+ - :meth:`_handle_warnings`
+ """
+ self.delegated_vars = result._result.get("_ansible_delegated_vars", None)
+ self._flush_display_buffer()
+ self._handle_exception(result._result)
+ self._handle_warnings(result._result)
+
+ def _get_host_string(self, result, prefix=""):
+ """Retrieve the host from the giving ``result``.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+ prefix (:obj:`str`, optional): A prefix added to the host name.
+ Defaults to "".
+
+ Returns:
+ A formatted version of the host that generated the ``result``.
+ """
+ task_host = to_text("{0}{1}").format(prefix, result._host.get_name())
+ if self.delegated_vars:
+ task_host += to_text(" {0} {1}{2}").format(
+ symbol("arrow_right"), prefix, self.delegated_vars["ansible_host"]
+ )
+ return task_host
+
+ def _process_result_output(self, result, status, symbol_char="", indent=2):
+ """Returns the result converted to string.
+
+ Each key in the ``result._result`` is considered a session for the
+ purpose of this method. All sessions have their content indented related
+ to the session title.
+
+ If a session verbosity (found on the :const:`_session_order` dictionary)
+ doesnot cross the treshold for this playbook, it will not be shown.
+
+ This method also converts all session titles that are present in the
+ :const:`` dictionary, to their string representation. The rest of the
+ titles are simply capitalized for aestetics purpose.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+ status (:obj:`str`): The status representing this ourput (e.g. "ok",
+ "changed", "failed").
+ symbol_char (:obj:`str`, optional): An UTF-8 character to be used as
+ a symbol_char in the beginning of the output. Defaults to "".
+ indent (int, optional): How many character the text generated from
+ the ``result`` should be indended to. Defaults to 2.
+
+ Returns:
+ :obj:`str`: A formated version of the giving ``result``.
+ """
+ task_host = self._get_host_string(result)
+
+ task_result = to_text("{0}{1}{2} [{3}]").format(
+ " " * indent,
+ symbol_char + " " if symbol_char else "",
+ task_host,
+ status.upper(),
+ )
+
+ for key, verbosity in _session_order.items():
+ if (
+ key in result._result
+ and result._result[key]
+ and self._is_run_verbose(result, verbosity)
+ ):
+ task_result += self.reindent_session(
+ _session_title.get(key, key), result._result[key], indent + 2
+ )
+
+ for title, text in result._result.items():
+ if title not in _session_title and text and self._is_run_verbose(result, 2):
+ task_result += self.reindent_session(
+ title.replace("_", " ").replace(".", " ").capitalize(),
+ text,
+ indent + 2,
+ )
+
+ return task_result
+
+ def _process_item_result_output(self, result, status, symbol_char="", indent=2):
+ """Displays the given ``result`` of an item task.
+
+ This method is a simplified version of the
+ :meth:`_process_result_output` method where no sessions are printed.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+ status (:obj:`str`): The status representing this ourput (e.g. "ok",
+ "changed", "failed").
+ symbol_char (:obj:`str`, optional): An UTF-8 character to be used as
+ a symbol_char in the beginning of the output. Defaults to "".
+ indent (int, optional): How many character the text generated from
+ the ``result`` should be indended to. Defaults to 2.
+
+ Returns:
+ :obj:`str`: A formated version of the giving ``result``.
+ """
+ if not self._item_processed:
+ self._item_processed = True
+ self.display(to_text("{0}{1} Items:").format(" " * indent, symbol("loop")))
+
+ item_name = self._get_item_label(result._result)
+ if isinstance(item_name, dict):
+ if "name" in item_name:
+ item_name = item_name.get("name")
+ elif "path" in item_name:
+ item_name = item_name.get("path")
+ else:
+ item_name = u'JSON: "{0}"'.format(
+ stringtruncate(
+ json.dumps(item_name, separators=(",", ":")), width=36
+ )
+ )
+ task_host = self._get_host_string(result, "@")
+ task_result = to_text("{0}{1} {2} ({3}) [{4}]").format(
+ " " * (indent + 2), symbol_char, item_name, task_host, status.upper()
+ )
+ return task_result
+
+ def _display_summary_table_separator(self, symbol_char):
+ """Displays a line separating header or footer from content on the
+ summary table.
+
+ Args:
+ symbol_char (:obj:`str`): The character to be used as the separator.
+ """
+ self.display(
+ to_text(" {0} {1} {2} {3} {4} {5} {6}").format(
+ symbol_char * 30,
+ symbol_char * 7,
+ symbol_char * 7,
+ symbol_char * 7,
+ symbol_char * 7,
+ symbol_char * 7,
+ symbol_char * 7,
+ )
+ )
+
+ def _display_summary_table_row(
+ self, host, success, changed, dark, failed, rescued, ignored
+ ):
+ """Displays a single line in the summary table, respecting the color and
+ size given in the arguments.
+
+ Each argument in this method is a tuple of three values:
+
+ - The text;
+ - The color;
+ - The width;
+
+ Args:
+ host (:obj:`tuple` of :obj:`str`, :obj:`str`, int): Which host this
+ row is representing.
+ success (:obj:`tuple` of :obj:`str`, :obj:`str`, int): How many
+ tasks were run successfully.
+ changed (:obj:`tuple` of :obj:`str`, :obj:`str`, int): How many
+ values were changed due to the execution of the task.
+ dark (:obj:`tuple` of :obj:`str`, :obj:`str`, int): How many hosts
+ were not reachable during the execution of this playbook.
+ failed (:obj:`tuple` of :obj:`str`, :obj:`str`, int): How many tasks
+ failed during their execution.
+ rescued (:obj:`tuple` of :obj:`str`, :obj:`str`, int): How manu
+ tasks where recover from a failure and were able to complete
+ successfully.
+ ignored (:obj:`tuple` of :obj:`str`, :obj:`str`, int): How many
+ tasks were ignored.
+ """
+ self.display(
+ to_text(" {0} {1} {2} {3} {4} {5} {6}").format(
+ stringtruncate(host[0], host[1], host[2]),
+ stringtruncate(success[0], success[1], success[2]),
+ stringtruncate(changed[0], changed[1], changed[2]),
+ stringtruncate(dark[0], dark[1], dark[2]),
+ stringtruncate(failed[0], failed[1], failed[2]),
+ stringtruncate(rescued[0], rescued[1], rescued[2]),
+ stringtruncate(ignored[0], ignored[1], ignored[2]),
+ )
+ )
+
+ def _display_task_decision_score(self, task):
+ """Calculate the probability for the giving ``task`` to be displayed
+ based on configurations and the task ``when`` clause.
+
+ Args:
+ task (:obj:`~ansible.playbook.task.Task`): The task object that
+ will be analyzed.
+
+ Returns:
+ :obj:`Number`: A number between 0 and 1 representing the
+ probability to show the giving ``task``. Currently this method
+ only return 3 possible values:
+
+ :0.0:
+ When we are sure that the task should **not** be displayed.
+ This means that we were able to process the ``when`` clause and
+ it returned ``False``, or this ``task`` is a debug task and its
+ verbosity does **not** cross the trashold for our playbook.
+ :1.0:
+ When we are sure the ``task`` should be displayed. This means
+ that we were able to process the ``when`` clause and it returned
+ ``True``, or this ``task`` is a debug task and its verbosity
+ does cross the trashold for our playbook.
+ :0.5:
+ When we don't know if this task should be displayed or not. By
+ default, we associate any ``task`` with this score, and change
+ it if one of the conditions for the other scores are met.
+ """
+ score = 0.5
+ var_manager = task.get_variable_manager()
+ task_args = task.args
+ if task.when and var_manager:
+ all_hosts = CallbackModule.get_chainned_value(
+ var_manager.get_vars(), "hostvars"
+ )
+ play_task_vars = var_manager.get_vars(
+ play=self._current_play, host=self._current_host, task=task
+ )
+ templar = Templar(task._loader, variables=play_task_vars)
+ exception = False
+ for hostname in all_hosts.keys():
+ host_vars = CallbackModule.get_chainned_value(all_hosts, hostname)
+ host_vars.update(play_task_vars)
+ try:
+ if not task.evaluate_conditional(templar, host_vars):
+ score = 0.0
+ break
+ except Exception as e:
+ exception = True
+ else:
+ if not exception:
+ score = 1.0
+ elif task.action == "debug" and task_args and "verbosity" in task_args:
+ score = (
+ 1.0
+ if self._is_run_verbose(verbosity=int(task_args["verbosity"]))
+ else 0.0
+ )
+ return score
+
+ def _display_task_name(self, task, is_handler=False):
+ """Displays the giving ``task`` title.
+
+ In reality, this method may or may not display the title based on some
+ factors:
+
+ If the :file:`ansible.cfg` has the ``display_skipped_hosts`` option set
+ to ``True``, or if either of the environment variables
+ (``ANSIBLE_DISPLAY_SKIPPED_HOSTS``, and ``DISPLAY_SKIPPED_HOSTS``) are
+ set, the ``task`` title is displayed as soon as this method is called.
+
+ Otherwise, this method will *cache* the ``task`` title until the
+ :meth:`_flush_display_buffer` is called.
+
+ Args:
+ task (:obj:`~ansible.playbook.task.Task`): The task object that
+ will be displayed in the console.
+ is_handler (bool, optional): Flag indicating if this task is being
+ handled by a different host. Defaults to False.
+
+ See Also:
+ - :meth:`_get_task_display_name`
+ - :meth:`_display_task_decision_score`
+ - :meth:`_flush_display_buffer`
+ """
+ self._item_processed = False
+ self._get_task_display_name(task)
+
+ if self.task_display_name:
+ self._task_name_buffer = (
+ self.task_display_name
+ if not is_handler
+ else "%s (via handler)..." % self.task_display_name
+ )
+
+ display_score = self._display_task_decision_score(task)
+ if display_score >= 1.0 or C.DISPLAY_SKIPPED_HOSTS:
+ self._flush_display_buffer()
+ elif display_score < 0.1:
+ self._task_name_buffer = None
+
+ def _flush_display_buffer(self):
+ """Display a task title if there is one to display.
+ """
+ if self._task_name_buffer:
+ self.display(self._task_name_buffer)
+ self._task_name_buffer = None
+
+ @staticmethod
+ def try_parse_string(text):
+ """This method will try to parse the giving ``text`` using a JSON and
+ a YAML parser in order to return a dictionary representing this parsed
+ structure.
+
+ Args:
+ text (:obj:`str`): A text that may or may not be a JSON or YAML
+ content.
+
+ Returns:
+ Returns the parser object from ``text``. If the giving ``text`` was
+ not a JSON or YAML content, ``None`` will be returned.
+ """
+ textobj = None
+
+ try:
+ textobj = json.loads(text)
+ except Exception as e:
+ try:
+ textobj = yaml.load(text, Loader=yaml.SafeLoader)
+ except Exception:
+ pass
+
+ return textobj
+
+ @staticmethod
+ def dump_value(value):
+ """Given a string, this method will parse the giving string and return
+ the parsed object converted to a YAML representation.
+
+ Args:
+ value (:obj:`str`): A string to be parsed.
+
+ Returns:
+ :obj:`str`: The YAML representation of the object parsed from the
+ giving ``value``.
+ """
+ text = None
+ obj = CallbackModule.try_parse_string(value)
+ if obj:
+ text = yaml.dump(obj, Dumper=yaml.SafeDumper, default_flow_style=False)
+ return text
+
+ @staticmethod
+ def reindent_session(title, text, indent=2, width=80):
+ """This method returns a text formatted with the giving ``indent`` and
+ wrapped at the giving ``width``.
+
+ Args:
+ title (:obj:`str`): The left most indented text.
+ text (:obj:`str`): The rest of the text that will be indented two
+ characters to the left of the ``title`` indentation.
+ indent (int): Number of spaces used to indent the whole block.
+ Defaults to 2.
+ width (int, optional): How many characters are allowed to be used
+ on a single line for this text block. Defaults to 80.
+
+ Returns:
+ :obj:`str`: The formatted text.
+ """
+ titleindent = " " * indent
+ textindent = " " * (indent + 2)
+ textwidth = width - (indent + len(title) + 2)
+ textstr = str(text).strip()
+ dumped = False
+ if textstr.startswith("---") or textstr.startswith("{"):
+ dumped = CallbackModule.dump_value(textstr)
+ textstr = dumped if dumped else textstr
+ output = to_text("\n{0}{1}:").format(titleindent, title)
+ lines = textstr.splitlines()
+
+ if (len(lines) == 1) and (len(textstr) <= textwidth) and (not dumped):
+ output += " %s" % textstr
+ else:
+ for line in lines:
+ output += "\n%s" % textwrap.fill(
+ text=line,
+ width=width,
+ initial_indent=textindent,
+ subsequent_indent=textindent,
+ )
+ return output
+
+ @staticmethod
+ def changed_artifacts(result, status, display_color):
+ """Detect if the given ``result`` did change anything during its
+ execution and return the proper status and display color for it.
+
+ Args:
+ result (:obj:`~ansible.executor.task_result.TaskResult`): The result
+ object representing the execution of a task.
+ status (:obj:`str`): A string representing the current status of
+ the giving ``result``.
+ display_color (:obj:`str`): A string representing the current status
+ color of the giving ``result``.
+
+ Returns:
+ :obj:`tuple` of :obj:`str`, :obj:`str`: The return value depends on
+ the giving ``result`` object. If this method detects the ``changed``
+ flag in the ``result`` object, it returns::
+
+ ("changed", "yellow")
+
+ Otherwise, the values passed in the ``status`` and ``display_color``
+ arguments will be used::
+
+ (status, display_color)
+ """
+ result_was_changed = "changed" in result._result and result._result["changed"]
+ if result_was_changed:
+ return "changed", C.COLOR_CHANGED
+ return status, display_color
+
+ @staticmethod
+ def get_chainned_value(mapping, *args):
+ """Returns a value from a dictionary.
+
+ It can return chainned values based on a list of keys giving by the
+ ``args`` argument.
+
+ Example:
+ >>> crazy_dict = {
+ ... "a_key": "a_value",
+ ... "dict_key": {
+ ... "other_key": "other_value",
+ ... "other_dict_key": {
+ ... "target_value": "Found It!"
+ ... }
+ ... }
+ ... }
+ >>> CallbackModule.get_chainned_value(crazy_dict, "dict_key", "other_dict_key", "target_value")
+ 'Found It!'
+
+ Args:
+ mapping (:obj:`dict`): The dictionary used to fetch a value using
+ chainned calls.
+ *args: A list of keys to use to retrieve the deep value in the
+ giving dictionary.
+
+ Returns:
+ Returns any value that matches the chain of keys passed in the
+ ``args`` argument. If this value is a dictionary of some sort, the
+ values of this dictionary will be shallowed copied to the returned
+ dictionary.
+ """
+ if args:
+ key = args[0]
+ others = args[1:]
+
+ if key in mapping:
+ value = mapping[key]
+ if others:
+ return CallbackModule.get_chainned_value(value, *others)
+ if isinstance(value, Mapping):
+ dict_value = {}
+ dict_value.update(value)
+ return dict_value
+ return value
+ return None
diff --git a/default.pkgs b/default.pkgs
deleted file mode 100644
index 6cddb2e..0000000
--- a/default.pkgs
+++ /dev/null
@@ -1,80 +0,0 @@
-# Core
-hyprland
-sddm
-hyprshade
-swaync
-rofi-lbonn-wayland
-rofi-calc
-rofimoji
-aylurs-gtk-shell
-swww
-swaylock-effects
-swayidle
-wlogout
-grimblast-git
-cliphist
-wl-clipboard
-polkit-kde-agent
-xdg-desktop-portal-hyprland
-gnome-keyring
-cifs-utils
-ntfs-3g
-openssh
-
-# Pipewire
-pipewire
-wireplumber
-pipewire-alsa
-pipewire-audio
-pipewire-jack
-pipewire-pulse
-gst-plugin-pipewire
-
-# Network
-networkmanager
-networkmanager-openvpn
-network-manager-applet
-
-# Bluetooth
-bluez
-bluez-utils
-blueman
-
-# Printing
-cups
-cups-pdf
-
-# CLI Tools
-inotify-tools
-brightnessctl
-playerctl
-upower
-socat
-unzip
-less
-curl
-wget
-awk
-zip
-tar
-jq
-
-# CLI nice too have
-#wlr-randr
-libnotify
-mediainfo
-eza
-bat
-
-# Terminal
-# ueberzugpp #Image preview
-alacritty
-fish
-fish-done
-imagemagick
-fastfetch
-starship
-neovim
-nvtop
-btop
-yazi
diff --git a/etc/locale.conf b/etc/locale.conf
deleted file mode 100644
index bb66eb1..0000000
--- a/etc/locale.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-LANG=en_US.UTF-8
-LC_ADDRESS=de_DE.UTF-8
-LC_IDENTIFICATION=de_DE.UTF-8
-LC_MEASUREMENT=de_DE.UTF-8
-LC_MONETARY=de_DE.UTF-8
-LC_NAME=de_DE.UTF-8
-LC_NUMERIC=de_DE.UTF-8
-LC_PAPER=de_DE.UTF-8
-LC_TELEPHONE=de_DE.UTF-8
-LC_TIME=de_DE.UTF-8
diff --git a/games.pkgs b/games.pkgs
deleted file mode 100644
index c041a7c..0000000
--- a/games.pkgs
+++ /dev/null
@@ -1,58 +0,0 @@
-steam
-lutris
-
-# Dependecies AMD
-lib32-mesa
-vulkan-radeon
-lib32-vulkan-radeon
-vulkan-icd-loader
-lib32-vulkan-icd-loader
-
-# Wine
-wine-staging
-giflib
-lib32-giflib
-libpng
-lib32-libpng
-libldap
-lib32-libldap
-gnutls
-lib32-gnutls
-mpg123
-lib32-mpg123
-openal
-lib32-openal
-v4l-utils
-lib32-v4l-utils
-libpulse
-lib32-libpulse
-libgpg-error
-lib32-libgpg-error
-alsa-plugins
-lib32-alsa-plugins
-alsa-lib
-lib32-alsa-lib
-libjpeg-turbo
-lib32-libjpeg-turbo
-sqlite
-lib32-sqlite
-libxcomposite
-lib32-libxcomposite
-libxinerama
-lib32-libgcrypt
-libgcrypt
-lib32-libxinerama
-ncurses
-lib32-ncurses
-ocl-icd
-lib32-ocl-icd
-libxslt
-lib32-libxslt
-libva
-lib32-libva
-gtk3
-lib32-gtk3
-gst-plugins-base-libs
-lib32-gst-plugins-base-libs
-vulkan-icd-loader
-lib32-vulkan-icd-loader
diff --git a/group_vars/all b/group_vars/all
new file mode 100644
index 0000000..b17615a
--- /dev/null
+++ b/group_vars/all
@@ -0,0 +1,19 @@
+default_roles:
+ - bash
+ - btop
+ - fish
+ - nvim
+ - starship
+ - yazi
+
+desktop_roles:
+ - ags
+ - alacritty
+ - discord
+ - hypr
+ - kvantum
+ - minegrub
+ - sddm
+ - swaylock
+
+system: desktop
diff --git a/install.sh b/install.sh
index fc9814f..77d6f0d 100755
--- a/install.sh
+++ b/install.sh
@@ -1,55 +1,89 @@
#!/bin/bash
-# Helpers
-get_aur_helper() {
- if is_installed paru; then
- echo "paru"
- elif is_installed yay; then
- echo "yay"
- fi
+# Vars
+DOTFILES_DIR="$HOME/.dotfiles"
+CONFIG_DIR="$HOME/.config/dotfiles"
+REPO="https://gitea.keuledrive.de/Keule2/Dotfiles.git"
+DIST=$(source /etc/os-release && echo $ID)
+
+# Colors
+COLOR_RESET='\033[0m'
+RED='\033[0;31m'
+LGREEN='\033[01;32m'
+
+# Helper Functions
+print_header() {
+ echo -e "${LGREEN}$1${COLOR_RESET}"
}
-is_installed() {
- if pacman -Qi $1 &> /dev/null; then
- return 0
- else
- return 1
- fi
+cmd() {
+ local DOTFILES_LOG="./error.log"
+
+ if ! [[ -f $DOTFILES_LOG ]]; then
+ touch $DOTFILES_LOG
+ fi
+
+ if eval "$1" 1> /dev/null 2> $DOTFILES_LOG; then
+ return 0
+ fi
+
+ echo -e "${RED}"
+ cat $DOTFILES_LOG
+ echo -e "${COLOR_RESET}"
+ exit 1
}
-is_pkg() {
- if "$1" -Si "$2" &>/dev/null; then
- return 0
- else
- return 1
- fi
+arch_install() {
+ # Install Ansible
+ if ! [ -x "$(command -v ansible)" ]; then
+ print_header "Installing ansible"
+ cmd "pacman -S ansible --noconfirm"
+ fi
+ # Install Git
+ if ! [ -x "$(command -v git)" ]; then
+ print_header "Installing git"
+ cmd "sudo pacman -S git --noconfirm"
+ fi
+ # Install PIP
+ if ! [ -x "$(command -v pip)" ]; then
+ print_header "Installing pip"
+ cmd "sudo pacman -S python-pip --noconfirm"
+ fi
+ # Install Watchdog
+ if [ -x "$(pip list | grep watchdog)" ]; then
+ print_header "Installing watchdog"
+ cmd "pip install --break-system-packages watchdog"
+ fi
}
-is_aur_pkg() {
- helper=$(get_aur_helper)
- if [ -z $helper ]; then
- return 1
- fi
-
- return $(is_pkg $helper $1)
+ubuntu_install() {
+ # Install Ansible
+ if ! dpkg -s ansible >/dev/null 2>&1; then
+ print_header "Installing ansible"
+ cmd "sudo apt-get update"
+ cmd "sudo apt-get install -y software-properties-common"
+ cmd "sudo apt-add-repository -y ppa:ansible/ansible"
+ cmd "sudo apt-get update"
+ cmd "sudo apt-get install -y ansible"
+ cmd "sudo apt-get install python3-argcomplete"
+ cmd "sudo activate-global-python-argcomplete3"
+ fi
+ # Install Git
+ if ! dpkg -s git >/dev/null 2>&1; then
+ print_header "Installing git"
+ cmd "sudo apt-get install -y git"
+ fi
+ # TODO pip, watchdog
}
-is_arch_pkg() {
- return $(is_pkg pacman $1)
-}
+update_galaxy() {
+ local OS=$1
-install() {
- if is_installed "$1"; then
- return 0
- fi
-
- if is_arch_pkg "$1"; then
- sudo pacman -S $1
- elif is_aur_pkg "$1"; then
- sudo $(get_aur_helper) -S $1
- else
- echo "error: unknown package [$1]"
- fi
+ print_header "Installing/Updating ansible-galaxy"
+ cmd "ansible-galaxy install -r $DOTFILES_DIR/requirements/default.yml"
+ if [ -f "$DOTFILES_DIR/requirements/$OS.yml" ]; then
+ cmd "ansible-galaxy install -r $DOTFILES_DIR/requirements/$OS.yml"
+ fi
}
# Banner
@@ -62,123 +96,44 @@ ________ __ .___ __ .__ .__
\/ \/ \/ \/ \/ \/
EOF
-# Vars
-script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
-clone_dir="$HOME/git/"
+# Setup
+case $DIST in
+ arch)
+ arch_install
+ ;;
+ ubuntu)
+ ubuntu_install
+ ;;
+ *)
+ echo "Unsupported OS"
+ exit 1
+ ;;
+esac
-# Change working directory
-cd $script_dir
-echo "Working directory: $(pwd)"
-
-# Dependencies
-echo ""
-echo "Installing dependencies..."
-install git
-install base-devel
-echo "Dependencies installed!"
-
-# AUR helper
-if ! (is_installed paru || is_installed yay); then
- echo ""
- echo "Installing AUR helper..."
- echo -e "AUR helper:\n1) paru\n2) yay"
- read -p "Enter your preference (default=1): " helper
-
- case $helper in
- 1) helper="paru" ;;
- 2) helper="yay" ;;
- *) helper="paru" ;;
- esac
-
- if [ -d $clone_dir ]; then
- rm -rf $clone_dir$helper
- else
- mkdir $clone_dir
- fi
-
- echo "Installing $helper..."
- cd $clone_dir
- git clone https://aur.archlinux.org/$helper.git
- cd $helper
- makepkg -si
- cd $script_dir
- echo "AUR helper installed!"
+# Clone repository
+if ! [[ -d "$DOTFILES_DIR" ]]; then
+ print_header "Cloning repo"
+ cmd "git clone $REPO $DOTFILES_DIR"
else
- helper=$(get_aur_helper)
+ print_header "Updating repo"
+ cmd "git -C $DOTFILES_DIR pull"
fi
-# Install packages
-echo ""
-echo "Installing packages..."
+# Change Working Dir
+cd "$DOTFILES_DIR"
-for pkg_file in *.pkgs; do
- [ -f "$pkg_file" ] || continue
- echo "Found package file: $pkg_file"
- read -p "Do you want to install the packages from this file(Y/n)?" inst
+# Update Galaxy
+update_galaxy $DIST
- if [ "$inst" == "n" ]; then
- continue
- fi
-
- while IFS= read -r pkg; do
- if [[ $pkg = \#* ]] || [ -z "$pkg" ]; then
- continue
- fi
-
- if is_installed $pkg; then
- echo "info: package already installed, ignoring [$pkg]"
- elif is_arch_pkg $pkg; then
- arch_pkgs="${arch_pkgs} $pkg"
- elif is_aur_pkg $pkg; then
- aur_pkgs="${aur_pkgs} $pkg"
- else
- echo "error: unknown package [$pkg]"
- fi
- done < $pkg_file
-done
-
-echo ""
-echo "Installing arch packages..."
-if [ ! -z "$arch_pkgs" ]; then
- sudo pacman -Sy $arch_pkgs
+# Run playbook
+if [[ -f "$CONFIG_DIR/vault-password.txt" ]]; then
+ if [[ -f "$CONFIG_DIR/values.yml" ]]; then
+ ansible-playbook --diff -v --ask-become-pass --extra-vars "@$CONFIG_DIR/values.yml" --vault-password-file "$CONFIG_DIR/vault-password.txt" "$DOTFILES_DIR/main.yml" "$@"
+ else
+ ansible-playbook --diff -v --ask-become-pass --vault-password-file "$CONFIG_DIR/vault-password.txt" "$DOTFILES_DIR/main.yml" "$@"
+ fi
+elif [[ -f "$CONFIG_DIR/values.yml" ]]; then
+ ansible-playbook --diff -v --ask-become-pass --extra-vars "@$CONFIG_DIR/values.yml" "$DOTFILES_DIR/main.yml" "$@"
+else
+ ansible-playbook --diff -v --ask-become-pass "$DOTFILES_DIR/main.yml" "$@"
fi
-
-echo ""
-echo "Installing AUR packages..."
-if [ ! -z "$aur_pkgs" ]; then
- $helper -Sy $aur_pkgs
-fi
-
-# Install minegrub
-read -p "Install grub theme 'minegrub'(Y/n)?" inst
-
-if [ "$inst" != "n" ]; then
- git clone https://github.com/Lxtharia/minegrub-theme.git
- cd ./minegrub-theme
- sudo cp -ruv ./minegrub /boot/grub/themes/
- sudo sed -i '/^\(#\)\?GRUB_THEME/ s~.*~GRUB_THEME=/boot/grub/themes/minegrub/theme.txt~' /etc/default/grub
- sudo grub-mkconfig -o /boot/grub/grub.cfg
- cd ..
-fi
-
-# TODO mic-indicator, nerd font
-echo "Packages installed!"
-
-# Apply default configs
-if [ "$1" != "nc" ]; then
- echo ""
- echo "Copying configs..."
- cp -r -f .config/. ~/.config/
- cp -r -f home/. ~/
- sudo cp -r -f etc/. /etc/
- echo "Configs copied!"
-fi
-
-#TODO Set theme
-
-#TODO Enable services
-# cups (is_isnstalled $pkg -> ask? -> enable)
-# bluetooth
-# sddm
-
-echo "Finished!"
diff --git a/main.yml b/main.yml
new file mode 100644
index 0000000..9bf962a
--- /dev/null
+++ b/main.yml
@@ -0,0 +1,40 @@
+---
+- name: Dotfiles
+ hosts: localhost
+ connection: local
+ tasks:
+ - name: Set default roles
+ set_fact:
+ roles: "{{ ansible_run_tags != ['all'] and ansible_run_tags or default_roles | difference(ansible_skip_tags | default([])) }}"
+ tags:
+ - always
+
+ - name: Set desktop roles
+ set_fact:
+ roles: "{{ (desktop_roles + roles) | difference(ansible_skip_tags | default([])) }}"
+ tags:
+ - always
+ when: system != 'server' and desktop_roles is defined and ansible_run_tags == ['all']
+
+ - name: Prepend system role
+ set_fact:
+ roles: "{{ ['system'] | difference(roles) + roles }}"
+ tags:
+ - always
+
+ - name: Display roles
+ debug: "var=roles"
+ tags:
+ - always
+
+ - name: Run roles
+ include_role:
+ apply:
+ tags:
+ - "{{ roles_item }}"
+ name: "{{ roles_item }}"
+ loop_control:
+ loop_var: roles_item
+ with_items: "{{ roles }}"
+ tags:
+ - always
diff --git a/programming.pkgs b/programming.pkgs
deleted file mode 100644
index 9565f12..0000000
--- a/programming.pkgs
+++ /dev/null
@@ -1,5 +0,0 @@
-# Programming languages
-jdk-openjdk
-maven
-rustup
-npm
diff --git a/requirements/arch.yml b/requirements/arch.yml
new file mode 100644
index 0000000..052506b
--- /dev/null
+++ b/requirements/arch.yml
@@ -0,0 +1,2 @@
+collections:
+ - name: kewlfft.aur
diff --git a/requirements/default.yml b/requirements/default.yml
new file mode 100644
index 0000000..72fe72d
--- /dev/null
+++ b/requirements/default.yml
@@ -0,0 +1,2 @@
+collections:
+ - name: community.general
diff --git a/roles/ags/files/config.js b/roles/ags/files/config.js
new file mode 100644
index 0000000..b1b4434
--- /dev/null
+++ b/roles/ags/files/config.js
@@ -0,0 +1,48 @@
+const systemtray = await Service.import('systemtray')
+
+/** @param {import('types/service/systemtray').TrayItem} item */
+const SysTrayItem = item => Widget.Button({
+ child: Widget.Icon().bind('icon', item, 'icon'),
+ tooltipMarkup: item.bind('tooltip_markup'),
+ onPrimaryClick: (_, event) => item.activate(event),
+ onSecondaryClick: (_, event) => item.openMenu(event),
+});
+
+function SysTray() {
+ return Widget.Box({ children: systemtray.bind('items').transform(i => i.map(SysTrayItem)) });
+}
+
+function Bar(monitor = 0) {
+ const lTime = Widget.Label({
+ label: 'TIME',
+ });
+
+ Utils.interval(1000, () => {
+ lTime.label = Utils.exec('date +%H:%M');
+ //date +%d.%m.%Y
+ });
+
+ const bTimeDate = Widget.Box({
+ children: [lTime]
+ });
+
+ const bInfo = Widget.Box({
+ hpack: "end",
+ children: [SysTray()]
+ });
+
+ return Widget.Window({
+ monitor,
+ exclusivity: 'exclusive',
+ name: `bar ${monitor}`,
+ anchor: ['top', 'left', 'right'],
+ child: Widget.CenterBox({
+ centerWidget: bTimeDate,
+ endWidget: bInfo,
+ }),
+ });
+}
+
+export default {
+ windows: [Bar(1), Bar(2)]
+};
diff --git a/roles/ags/tasks/main.yml b/roles/ags/tasks/main.yml
new file mode 100644
index 0000000..6b89d9a
--- /dev/null
+++ b/roles/ags/tasks/main.yml
@@ -0,0 +1,19 @@
+---
+- name: "[AGS] Install"
+ kewlfft.aur.aur:
+ name:
+ - aylurs-gtk-shell-git
+ use: paru
+ state: present
+ become: true
+
+- name: "[AGS] Create config folder"
+ ansible.builtin.file:
+ mode: "0755"
+ path: "{{ ansible_user_dir }}/.config/ags"
+ state: directory
+
+- name: "[AGS] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/.config/ags"
diff --git a/.config/alacritty/alacritty.toml b/roles/alacritty/files/alacritty.toml
similarity index 100%
rename from .config/alacritty/alacritty.toml
rename to roles/alacritty/files/alacritty.toml
diff --git a/.config/alacritty/catppuccin-macchiato.toml b/roles/alacritty/files/catppuccin-macchiato.toml
similarity index 100%
rename from .config/alacritty/catppuccin-macchiato.toml
rename to roles/alacritty/files/catppuccin-macchiato.toml
diff --git a/roles/alacritty/tasks/main.yml b/roles/alacritty/tasks/main.yml
new file mode 100644
index 0000000..4f9496b
--- /dev/null
+++ b/roles/alacritty/tasks/main.yml
@@ -0,0 +1,20 @@
+---
+- name: "[Alacritty] Install"
+ kewlfft.aur.aur:
+ name:
+ - alacritty
+ - ueberzugpp
+ use: paru
+ state: present
+ become: true
+
+- name: "[Alacritty] Create config folder"
+ ansible.builtin.file:
+ mode: "0755"
+ path: "{{ ansible_user_dir }}/.config/alacritty"
+ state: directory
+
+- name: "[Alacritty] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/.config/alacritty"
diff --git a/home/.bashrc b/roles/bash/files/.bashrc
old mode 100755
new mode 100644
similarity index 61%
rename from home/.bashrc
rename to roles/bash/files/.bashrc
index f2bae8e..8d415c2
--- a/home/.bashrc
+++ b/roles/bash/files/.bashrc
@@ -2,28 +2,15 @@
[[ $- != *i* ]] && return
# Load starship prompt if starship is installed
-if [ -x /usr/bin/starship ]; then
- __main() {
- local major="${BASH_VERSINFO[0]}"
- local minor="${BASH_VERSINFO[1]}"
-
- if ((major > 4)) || { ((major == 4)) && ((minor >= 1)); }; then
- source <("/usr/bin/starship" init bash --print-full-init)
- else
- source /dev/stdin <<<"$("/usr/bin/starship" init bash --print-full-init)"
- fi
- }
- __main
- unset -f __main
-fi
+eval "$(starship init bash)"
## Aliases
-# Replace ls with exa
-alias ls='exa -al --color=always --group-directories-first' # preferred listing
-alias la='exa -a --color=always --group-directories-first' # all files and dirs
-alias ll='exa -l --color=always --group-directories-first' # long format
-alias lt='exa -aT --color=always --group-directories-first' # tree listing
-alias l.='exa -ald --color=always --group-directories-first .*' # show only dotfiles
+# Replace ls with eza
+alias ls='eza -al --color=always --group-directories-first' # preferred listing
+alias la='eza -a --color=always --group-directories-first' # all files and dirs
+alias ll='eza -l --color=always --group-directories-first' # long format
+alias lt='eza -aT --color=always --group-directories-first' # tree listing
+alias l.='eza -ald --color=always --group-directories-first .*' # show only dotfiles
# Replace cat with bat
alias cat='bat --style header --style snip --style changes --style header'
diff --git a/roles/bash/tasks/main.yml b/roles/bash/tasks/main.yml
new file mode 100644
index 0000000..98b810f
--- /dev/null
+++ b/roles/bash/tasks/main.yml
@@ -0,0 +1,12 @@
+---
+- name: "[Bash] Install"
+ ansible.builtin.package:
+ name:
+ - bash
+ state: latest
+ become: yes
+
+- name: "[Bash] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/"
diff --git a/.config/btop/btop.conf b/roles/btop/files/btop.conf
similarity index 100%
rename from .config/btop/btop.conf
rename to roles/btop/files/btop.conf
diff --git a/roles/btop/tasks/main.yml b/roles/btop/tasks/main.yml
new file mode 100644
index 0000000..7b20963
--- /dev/null
+++ b/roles/btop/tasks/main.yml
@@ -0,0 +1,18 @@
+---
+- name: "[Btop] Install"
+ ansible.builtin.package:
+ name:
+ - btop
+ state: latest
+ become: true
+
+- name: "[Btop] Create config folder"
+ ansible.builtin.file:
+ mode: "0755"
+ path: "{{ ansible_user_dir }}/.config/btop"
+ state: directory
+
+- name: "[Btop] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/.config/btop"
diff --git a/roles/discord/files/Preferences b/roles/discord/files/Preferences
new file mode 100644
index 0000000..364bb10
--- /dev/null
+++ b/roles/discord/files/Preferences
@@ -0,0 +1 @@
+{"spellcheck":{"dictionaries":["en-GB", "de-DE"],"dictionary":""}}
diff --git a/roles/discord/files/storage/lang.json b/roles/discord/files/storage/lang.json
new file mode 100644
index 0000000..8b4cb6e
--- /dev/null
+++ b/roles/discord/files/storage/lang.json
@@ -0,0 +1,3 @@
+{
+ "lang": "en-US"
+}
diff --git a/roles/discord/files/storage/settings.json b/roles/discord/files/storage/settings.json
new file mode 100644
index 0000000..1e10803
--- /dev/null
+++ b/roles/discord/files/storage/settings.json
@@ -0,0 +1,26 @@
+{
+ "windowStyle": "native",
+ "channel": "stable",
+ "armcordCSP": true,
+ "minimizeToTray": true,
+ "keybinds": [],
+ "alternativePaste": false,
+ "multiInstance": false,
+ "mods": "none",
+ "spellcheck": true,
+ "performanceMode": "none",
+ "skipSplash": false,
+ "inviteWebsocket": true,
+ "startMinimized": false,
+ "dynamicIcon": false,
+ "tray": true,
+ "customJsBundle": "https://armcord.app/placeholder.js",
+ "customCssBundle": "https://armcord.app/placeholder.css",
+ "disableAutogain": false,
+ "useLegacyCapturer": false,
+ "mobileMode": false,
+ "trayIcon": "default",
+ "doneSetup": true,
+ "clientName": "ArmCord",
+ "customIcon": "/usr/lib/armcord/app.asar/assets/desktop.png"
+}
\ No newline at end of file
diff --git a/roles/discord/files/themes/Catppuccin-Macchiato-BD/LICENSE b/roles/discord/files/themes/Catppuccin-Macchiato-BD/LICENSE
new file mode 100644
index 0000000..5602ca7
--- /dev/null
+++ b/roles/discord/files/themes/Catppuccin-Macchiato-BD/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Catppuccin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/roles/discord/files/themes/Catppuccin-Macchiato-BD/manifest.json b/roles/discord/files/themes/Catppuccin-Macchiato-BD/manifest.json
new file mode 100644
index 0000000..b90d116
--- /dev/null
+++ b/roles/discord/files/themes/Catppuccin-Macchiato-BD/manifest.json
@@ -0,0 +1 @@
+{"theme":"src.css","name":"Catppuccin Macchiato","author":"winston#0001","authorId":"505490445468696576","version":"0.2.0","description":"🎮 Soothing pastel theme for Discord","website":"https://github.com/catppuccin/discord","invite":"r6Mdz5dpFc","updateSrc":"https://raw.githubusercontent.com/catppuccin/discord/main/themes/macchiato.theme.css","supportsArmCordTitlebar":false}
\ No newline at end of file
diff --git a/roles/discord/files/themes/Catppuccin-Macchiato-BD/src.css b/roles/discord/files/themes/Catppuccin-Macchiato-BD/src.css
new file mode 100644
index 0000000..3127eba
--- /dev/null
+++ b/roles/discord/files/themes/Catppuccin-Macchiato-BD/src.css
@@ -0,0 +1,11 @@
+/**
+ * @name Catppuccin Macchiato
+ * @author winston#0001
+ * @authorId 505490445468696576
+ * @version 0.2.0
+ * @description 🎮 Soothing pastel theme for Discord
+ * @website https://github.com/catppuccin/discord
+ * @invite r6Mdz5dpFc
+ * **/
+
+@import url("https://catppuccin.github.io/discord/dist/catppuccin-macchiato.theme.css");
diff --git a/roles/discord/tasks/main.yml b/roles/discord/tasks/main.yml
new file mode 100644
index 0000000..381d992
--- /dev/null
+++ b/roles/discord/tasks/main.yml
@@ -0,0 +1,19 @@
+---
+- name: "[Discord] Install"
+ kewlfft.aur.aur:
+ name:
+ - armcord
+ use: paru
+ state: present
+
+- name: "[Discord] Create config folder"
+ ansible.builtin.file:
+ mode: "0755"
+ path: "{{ ansible_user_dir }}/.config/ArmCord"
+ state: directory
+ force: false
+
+- name: "[Discord] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/.config/ArmCord"
diff --git a/.config/fish/config.fish b/roles/fish/files/config.fish
similarity index 100%
rename from .config/fish/config.fish
rename to roles/fish/files/config.fish
index 93c0d54..4272cc0 100755
--- a/.config/fish/config.fish
+++ b/roles/fish/files/config.fish
@@ -10,6 +10,10 @@ if test -f ~/.fish_profile
source ~/.fish_profile
end
+# Other env vars
+export EDITOR=nvim
+export VISUAL=nvim
+
# Add ~/.local/bin to PATH
if test -d ~/.local/bin
if not contains -- ~/.local/bin $PATH
@@ -17,10 +21,6 @@ if test -d ~/.local/bin
end
end
-# Other env vars
-export EDITOR=nvim
-export VISUAL=nvim
-
# Plugin configuration
# Set settings for https://github.com/franciscolourenco/done
set -U __done_min_cmd_duration 10000
diff --git a/roles/fish/tasks/main.yml b/roles/fish/tasks/main.yml
new file mode 100644
index 0000000..b4c4865
--- /dev/null
+++ b/roles/fish/tasks/main.yml
@@ -0,0 +1,20 @@
+---
+- name: "[Fish] Install"
+ kewlfft.aur.aur:
+ name:
+ - fish
+ - fish-done
+ - fastfetch
+ use: paru
+ state: present
+
+- name: "[Fish] Create config folder"
+ ansible.builtin.file:
+ mode: "0755"
+ path: "{{ ansible_user_dir }}/.config/fish"
+ state: directory
+
+- name: "[Fish] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/.config/fish"
diff --git a/.config/hypr/devices.conf b/roles/hypr/files/devices.conf
similarity index 100%
rename from .config/hypr/devices.conf
rename to roles/hypr/files/devices.conf
diff --git a/.config/hypr/env.conf b/roles/hypr/files/env.conf
similarity index 77%
rename from .config/hypr/env.conf
rename to roles/hypr/files/env.conf
index be4b4cb..cae8116 100755
--- a/.config/hypr/env.conf
+++ b/roles/hypr/files/env.conf
@@ -1,6 +1,7 @@
# Environment
env = XCURSOR_SIZE,24
-env = HYPRCURSOR_THEME,breeze_cursor
+env = HYPRCURSOR_SIZE,24
+env = HYPRCURSOR_THEME,rose-pine-hyprcursor
env = XDG_SESSION_TYPE,wayland
env = WLR_NO_HARDWARE_CURSORS,1
env = QT_QPA_PLATFORMTHEME,qt5ct
diff --git a/.config/hypr/hyprland.conf b/roles/hypr/files/hyprland.conf
similarity index 100%
rename from .config/hypr/hyprland.conf
rename to roles/hypr/files/hyprland.conf
diff --git a/.config/hypr/keybinds.conf b/roles/hypr/files/keybinds.conf
similarity index 98%
rename from .config/hypr/keybinds.conf
rename to roles/hypr/files/keybinds.conf
index 32e8411..e045114 100755
--- a/.config/hypr/keybinds.conf
+++ b/roles/hypr/files/keybinds.conf
@@ -34,7 +34,7 @@ binde = , XF86MonBrightnessUp, exec, brightnessctl set 5%+
# Applications
bind = $mainMod, T, exec, alacritty
-bind = $mainMod, E, exec, thunar || dolphin
+bind = $mainMod, E, exec, nemo
bind = $mainMod, G, exec, ~/.config/hypr/scripts/app_launcher.sh c
bind = CTRL SHIFT, ESCAPE, exec, gnome-system-monitor
diff --git a/.config/hypr/nvidia.conf b/roles/hypr/files/nvidia.conf
similarity index 100%
rename from .config/hypr/nvidia.conf
rename to roles/hypr/files/nvidia.conf
diff --git a/.config/hypr/scripts/app_launcher.sh b/roles/hypr/files/scripts/app_launcher.sh
similarity index 100%
rename from .config/hypr/scripts/app_launcher.sh
rename to roles/hypr/files/scripts/app_launcher.sh
diff --git a/.config/hypr/scripts/background.sh b/roles/hypr/files/scripts/background.sh
similarity index 95%
rename from .config/hypr/scripts/background.sh
rename to roles/hypr/files/scripts/background.sh
index 566238c..2c8df1b 100755
--- a/.config/hypr/scripts/background.sh
+++ b/roles/hypr/files/scripts/background.sh
@@ -47,7 +47,7 @@ while true; do
fi
swww img "$img" --transition-type wipe --resize=fit
- ln -sf "$img" ~/.config/hypr/theme/current_background.jpg
+ ln -sf "$img" ~/.config/background
sleep $INTERVAL
done
done
diff --git a/.config/hypr/scripts/clipboard.sh b/roles/hypr/files/scripts/clipboard.sh
similarity index 100%
rename from .config/hypr/scripts/clipboard.sh
rename to roles/hypr/files/scripts/clipboard.sh
diff --git a/.config/hypr/scripts/close_apps.sh b/roles/hypr/files/scripts/close_apps.sh
similarity index 100%
rename from .config/hypr/scripts/close_apps.sh
rename to roles/hypr/files/scripts/close_apps.sh
diff --git a/.config/hypr/scripts/idle.sh b/roles/hypr/files/scripts/idle.sh
similarity index 100%
rename from .config/hypr/scripts/idle.sh
rename to roles/hypr/files/scripts/idle.sh
diff --git a/.config/hypr/scripts/lock.sh b/roles/hypr/files/scripts/lock.sh
similarity index 100%
rename from .config/hypr/scripts/lock.sh
rename to roles/hypr/files/scripts/lock.sh
diff --git a/.config/hypr/scripts/logout.sh b/roles/hypr/files/scripts/logout.sh
similarity index 100%
rename from .config/hypr/scripts/logout.sh
rename to roles/hypr/files/scripts/logout.sh
diff --git a/.config/hypr/scripts/wait_for_tray.sh b/roles/hypr/files/scripts/wait_for_tray.sh
similarity index 88%
rename from .config/hypr/scripts/wait_for_tray.sh
rename to roles/hypr/files/scripts/wait_for_tray.sh
index e2d2069..bc194bc 100755
--- a/.config/hypr/scripts/wait_for_tray.sh
+++ b/roles/hypr/files/scripts/wait_for_tray.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-program_name="eww"
+program_name="ags"
check_program_running() {
pgrep -x "$program_name" > /dev/null
diff --git a/.config/hypr/startup.conf b/roles/hypr/files/startup.conf
similarity index 87%
rename from .config/hypr/startup.conf
rename to roles/hypr/files/startup.conf
index 9166c31..e2c469d 100755
--- a/.config/hypr/startup.conf
+++ b/roles/hypr/files/startup.conf
@@ -2,16 +2,13 @@
exec-once = ags -c /home/keule/test/config.js
# Programms
-exec-once = webcord
+exec-once = armcord
exec-once = nextcloud
exec-once = youtube-music
exec-once = element-desktop
-exec-once = swaync
exec-once = nm-applet
exec-once = blueman-applet
-exec-once = hyprshade auto
exec-once = playerctld daemon
-exec-once = indicator-mic-cam
exec-once = ~/.config/hypr/scripts/idle.sh
exec-once = ~/.config/hypr/scripts/battery_check.sh
diff --git a/.config/hypr/windowrule.conf b/roles/hypr/files/windowrule.conf
similarity index 92%
rename from .config/hypr/windowrule.conf
rename to roles/hypr/files/windowrule.conf
index 36c2b59..88b3417 100755
--- a/.config/hypr/windowrule.conf
+++ b/roles/hypr/files/windowrule.conf
@@ -14,7 +14,8 @@ windowrule = workspace 2,^(YouTube Music)$
windowrule = workspace 4,^(explorer.exe)$
windowrule = workspace 4,^(lutris)$
windowrule = workspace 5,^(discord)$
-windowrule = workspace 5,^(Webcord)$
+windowrule = workspace 5,^(WebCord)$
+windowrule = workspace 5,^(Element)$
windowrule = workspace 5,^(de.keule.client.ui.JavaFX)$
windowrule = float,^(lutris)$
diff --git a/roles/hypr/tasks/main.yml b/roles/hypr/tasks/main.yml
new file mode 100644
index 0000000..ced8261
--- /dev/null
+++ b/roles/hypr/tasks/main.yml
@@ -0,0 +1,18 @@
+---
+- name: "[Hyprland] Install"
+ ansible.builtin.package:
+ name:
+ - hyprland
+ state: latest
+ become: true
+
+- name: "[Hyprland] Create config folder"
+ ansible.builtin.file:
+ mode: "0755"
+ path: "{{ ansible_user_dir }}/.config/hypr"
+ state: directory
+
+- name: "[Hyprland] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/.config/hypr"
diff --git a/roles/kvantum/files/Catppuccin-Frappe-Rosewater/Catppuccin-Frappe-Rosewater.kvconfig b/roles/kvantum/files/Catppuccin-Frappe-Rosewater/Catppuccin-Frappe-Rosewater.kvconfig
new file mode 100644
index 0000000..91ab873
--- /dev/null
+++ b/roles/kvantum/files/Catppuccin-Frappe-Rosewater/Catppuccin-Frappe-Rosewater.kvconfig
@@ -0,0 +1,464 @@
+[%General]
+author=elkrien based on Arc Dark style
+comment=Catppuccin-Frappe-Rosewater
+spread_menuitems=true
+left_tabs=true
+mirror_doc_tabs=true
+scroll_width=8
+attach_active_tab=true
+composite=true
+menu_shadow_depth=7
+tooltip_shadow_depth=0
+splitter_width=7
+check_size=16
+slider_width=4
+slider_handle_width=18
+slider_handle_length=18
+textless_progressbar=false
+menubar_mouse_tracking=true
+slim_toolbars=false
+toolbutton_style=1
+x11drag=menubar_and_primary_toolbar
+double_click=false
+translucent_windows=false
+blurring=false
+popup_blurring=true
+opaque=kaffeine,kmplayer,subtitlecomposer,kdenlive,vlc,smplayer,smplayer2,avidemux,avidemux2_qt4,avidemux3_qt4,avidemux3_qt5,kamoso,QtCreator,VirtualBox,trojita,dragon,digikam,qmplay2
+group_toolbar_buttons=false
+vertical_spin_indicators=false
+fill_rubberband=false
+spread_progressbar=true
+merge_menubar_with_toolbar=true
+small_icon_size=16
+large_icon_size=32
+button_icon_size=16
+scroll_arrows=false
+iconless_pushbutton=true
+toolbar_icon_size=16
+combo_as_lineedit=true
+button_contents_shift=false
+groupbox_top_label=true
+inline_spin_indicators=true
+joined_inactive_tabs=false
+layout_spacing=2
+submenu_overlap=0
+tooltip_delay=-1
+animate_states=false
+transient_scrollbar=true
+alt_mnemonic=true
+combo_menu=true
+layout_margin=4
+no_window_pattern=false
+respect_DE=true
+scroll_min_extent=36
+scrollable_menu=false
+scrollbar_in_view=false
+spin_button_width=16
+submenu_delay=250
+tree_branch_line=true
+progressbar_thickness=8
+click_behavior=0
+contrast=1.00
+dialog_button_layout=0
+drag_from_buttons=false
+hide_combo_checkboxes=false
+intensity=1.00
+no_inactiveness=false
+reduce_menu_opacity=0
+reduce_window_opacity=10
+saturation=1.00
+shadowless_popup=false
+transient_groove=false
+
+[GeneralColors]
+window.color=#303446
+base.color=#292C3C
+alt.base.color=#292C3C
+button.color=#414559
+light.color=#51576D
+mid.light.color=#51576D
+dark.color=#292C3C
+mid.color=#292C3C
+highlight.color=#F2D5CF
+inactive.highlight.color=#F2D5CF
+text.color=#C6D0F5
+window.text.color=#C6D0F5
+button.text.color=#C6D0F5
+disabled.text.color=#626880
+tooltip.text.color=#C6D0F5
+highlight.text.color=#292C3C
+link.color=#F2D5CF
+link.visited.color=#8CAAEE
+
+[ItemView]
+inherits=PanelButtonCommand
+frame.element=itemview
+interior.element=itemview
+frame=true
+interior=true
+text.iconspacing=3
+text.toggle.color=#292C3C
+
+[RadioButton]
+inherits=PanelButtonCommand
+frame=false
+interior.element=radio
+
+[CheckBox]
+inherits=PanelButtonCommand
+frame=false
+interior.element=checkbox
+
+[TreeExpander]
+indicator.element=tree
+indicator.size=8
+
+[ToolTip]
+frame.top=4
+frame.right=4
+frame.bottom=4
+frame.left=4
+frame=true
+
+[PanelButtonCommand]
+inherits=PanelButtonCommand
+interior.element=button
+frame.element=button
+text.normal.color=#C6D0F5
+text.focus.color=#C6D0F5
+text.press.color=#292C3C
+text.toggle.color=#292C3C
+
+[PanelButtonTool]
+inherits=PanelButtonCommand
+
+[DockTitle]
+inherits=PanelButtonCommand
+interior=false
+frame=false
+text.margin.top=5
+text.margin.bottom=5
+text.margin.left=5
+text.margin.right=5
+indicator.size=0
+
+[Dock]
+interior.element=toolbar
+frame.element=toolbar
+frame=true
+interior=true
+
+[GroupBox]
+inherits=PanelButtonCommand
+interior.element=tabframe
+interior=true
+frame=false
+
+[Focus]
+inherits=PanelButtonCommand
+frame=true
+frame.element=focus
+frame.top=1
+frame.bottom=1
+frame.left=1
+frame.right=1
+frame.patternsize=20
+
+[GenericFrame]
+inherits=PanelButtonCommand
+frame.element=common
+frame.top=1
+frame.bottom=1
+frame.left=1
+frame.right=1
+
+[Slider]
+inherits=PanelButtonCommand
+interior=true
+frame.element=slider
+interior.element=slider
+frame.top=3
+frame.bottom=3
+frame.left=3
+frame.right=3
+focusFrame=true
+
+[SliderCursor]
+inherits=PanelButtonCommand
+interior=true
+interior.element=slidercursor
+frame=false
+
+[LineEdit]
+inherits=PanelButtonCommand
+frame.element=lineedit
+interior.element=lineedit
+
+[IndicatorSpinBox]
+inherits=LineEdit
+frame.element=lineedit
+interior.element=lineedit
+frame.top=0
+frame.bottom=2
+frame.left=2
+frame.right=2
+indicator.size=8
+
+[DropDownButton]
+inherits=PanelButtonCommand
+frame.top=2
+frame.bottom=2
+frame.left=0
+frame.right=1
+indicator.size=8
+
+[ToolboxTab]
+inherits=PanelButtonCommand
+frame.element=tabframe
+frame.top=1
+frame.bottom=1
+frame.left=1
+frame.right=1
+
+[Tab]
+inherits=PanelButtonCommand
+interior.element=tab
+frame.element=tab
+frame.top=2
+frame.bottom=3
+frame.left=3
+frame.right=3
+indicator.size=10
+text.normal.color=#626880
+text.focus.color=#C6D0F5
+text.press.color=#C6D0F5
+text.toggle.color=#C6D0F5
+focusFrame=true
+
+[TabBarFrame]
+inherits=GenericFrame
+frame=true
+frame.element=tabBarFrame
+interior=false
+frame.top=4
+frame.bottom=4
+frame.left=4
+frame.right=4
+
+[TabFrame]
+inherits=PanelButtonCommand
+frame.element=tabframe
+interior.element=tabframe
+
+[Dialog]
+inherits=TabBarFrame
+frame.element=tabframe
+interior=false
+frame=false
+frame.top=1
+frame.bottom=1
+frame.left=1
+frame.right=1
+
+[HeaderSection]
+inherits=PanelButtonCommand
+interior.element=header
+frame.element=header
+frame.top=0
+frame.bottom=1
+frame.left=1
+frame.right=1
+frame.expansion=0
+text.normal.color=#C6D0F5
+text.focus.color=#F2D5CF
+text.press.color=#C6D0F5
+text.toggle.color=#C6D0F5
+indicator.element=harrow
+
+[SizeGrip]
+inherits=PanelButtonCommand
+frame=false
+interior=false
+indicator.element=resize-grip
+indicator.size=0
+
+[Toolbar]
+inherits=PanelButtonCommand
+interior.element=menubar
+frame.element=menubar
+frame=true
+frame.bottom=4
+frame.left=4
+frame.right=4
+text.normal.color=#C6D0F5
+text.focus.color=#C6D0F5
+text.press.color=#F2D5CF
+text.toggle.color=#F2D5CF
+text.bold=false
+
+[MenuBar]
+inherits=PanelButtonCommand
+frame.element=menubar
+interior.element=menubar
+frame.bottom=0
+text.normal.color=#C6D0F5
+frame.expansion=0
+text.bold=false
+
+[ToolbarButton]
+frame.element=tbutton
+interior.element=tbutton
+indicator.element=arrow
+text.normal.color=#C6D0F5
+text.focus.color=#C6D0F5
+text.press.color=#292C3C
+text.toggle.color=#292C3C
+text.bold=false
+
+[Scrollbar]
+inherits=PanelButtonCommand
+indicator.size=0
+interior=false
+frame=false
+
+[ScrollbarGroove]
+inherits=PanelButtonCommand
+interior=false
+frame=false
+
+[ScrollbarSlider]
+inherits=PanelButtonCommand
+interior=false
+frame.element=scrollbarslider
+frame.top=4
+frame.bottom=4
+frame.left=4
+frame.right=4
+
+[ProgressbarContents]
+inherits=PanelButtonCommand
+frame=true
+frame.element=progress-pattern
+interior.element=progress-pattern
+frame.top=2
+frame.bottom=2
+frame.left=2
+frame.right=2
+
+[Progressbar]
+inherits=PanelButtonCommand
+frame.element=progress
+interior.element=progress
+frame.top=2
+frame.bottom=2
+frame.left=2
+frame.right=2
+text.margin=0
+text.normal.color=#C6D0F5
+text.focus.color=#C6D0F5
+text.press.color=#292C3C
+text.toggle.color=#292C3C
+text.bold=false
+frame.expansion=18
+
+[RadioButton]
+inherits=PanelButtonCommand
+
+[Menu]
+frame.element=menu
+interior.element=menu
+inherits=PanelButtonCommand
+text.press.color=#292C3C
+text.toggle.color=#292C3C
+text.bold=false
+frame.top=3
+frame.bottom=3
+frame.left=3
+frame.right=3
+
+[MenuItem]
+inherits=PanelButtonCommand
+interior.element=menuitem
+indicator.size=8
+text.focus.color=#C6D0F5
+text.press.color=#C6D0F5
+
+[MenuBarItem]
+inherits=PanelButtonCommand
+interior.element=menubaritem
+frame=false
+text.margin.top=3
+text.margin.bottom=3
+text.margin.left=5
+text.margin.right=5
+
+[StatusBar]
+inherits=Toolbar
+frame.element=toolbar
+font.bold=true
+text.normal.color=#C6D0F5
+frame=true
+frame.top=0
+frame.bottom=0
+
+[TitleBar]
+inherits=PanelButtonCommand
+frame=false
+interior=false
+text.margin.top=2
+text.margin.bottom=2
+text.margin.left=3
+text.margin.right=3
+
+[ComboBox]
+inherits=PanelButtonCommand
+indicator.size=8
+frame.top=3
+frame.bottom=3
+frame.left=3
+frame.right=3
+text.margin.top=1
+text.margin.bottom=1
+text.margin.left=3
+text.margin.right=3
+text.toggle.color=#C6D0F5
+
+[ToolboxTab]
+inherits=PanelButtonCommand
+text.normal.color=#C6D0F5
+text.press.color=#C6D0F5
+text.focus.color=#C6D0F5
+
+[Hacks]
+transparent_dolphin_view=false
+blur_konsole=true
+transparent_ktitle_label=true
+transparent_menutitle=true
+respect_darkness=true
+kcapacitybar_as_progressbar=true
+force_size_grip=false
+iconless_pushbutton=true
+iconless_menu=false
+disabled_icon_opacity=100
+lxqtmainmenu_iconsize=0
+normal_default_pushbutton=true
+single_top_toolbar=false
+tint_on_mouseover=0
+transparent_pcmanfm_sidepane=true
+transparent_pcmanfm_view=false
+blur_translucent=true
+centered_forms=false
+kinetic_scrolling=false
+middle_click_scroll=false
+no_selection_tint=false
+noninteger_translucency=false
+style_vertical_toolbars=false
+blur_only_active_window=false
+
+[Window]
+interior=true
+interior.element=window
+frame.top=0
+frame.bottom=0
+frame.left=0
+frame.right=0
diff --git a/roles/kvantum/files/Catppuccin-Frappe-Rosewater/Catppuccin-Frappe-Rosewater.svg b/roles/kvantum/files/Catppuccin-Frappe-Rosewater/Catppuccin-Frappe-Rosewater.svg
new file mode 100644
index 0000000..a029b1c
--- /dev/null
+++ b/roles/kvantum/files/Catppuccin-Frappe-Rosewater/Catppuccin-Frappe-Rosewater.svg
@@ -0,0 +1,1958 @@
+
diff --git a/roles/kvantum/files/Catppuccin-Frappe-Rosewater/LICENSE b/roles/kvantum/files/Catppuccin-Frappe-Rosewater/LICENSE
new file mode 100644
index 0000000..006383b
--- /dev/null
+++ b/roles/kvantum/files/Catppuccin-Frappe-Rosewater/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Catppuccin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/roles/kvantum/files/kvantum.kvconfig b/roles/kvantum/files/kvantum.kvconfig
new file mode 100644
index 0000000..14acad4
--- /dev/null
+++ b/roles/kvantum/files/kvantum.kvconfig
@@ -0,0 +1,2 @@
+[General]
+theme=Catppuccin-Macchiato-Rosewater
diff --git a/roles/kvantum/tasks/main.yml b/roles/kvantum/tasks/main.yml
new file mode 100644
index 0000000..d102364
--- /dev/null
+++ b/roles/kvantum/tasks/main.yml
@@ -0,0 +1,18 @@
+---
+- name: "[Kvantum] Install"
+ ansible.builtin.package:
+ name:
+ - kvantum
+ state: latest
+ become: true
+
+- name: "[Kvantum] Create config folder"
+ ansible.builtin.file:
+ mode: "0755"
+ path: "{{ ansible_user_dir }}/.config/kvantum"
+ state: directory
+
+- name: "[Kvantum] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/.config/kvantum"
diff --git a/roles/minegrub/files/minegrub/LICENSE b/roles/minegrub/files/minegrub/LICENSE
new file mode 100644
index 0000000..2c730c3
--- /dev/null
+++ b/roles/minegrub/files/minegrub/LICENSE
@@ -0,0 +1,23 @@
+MIT License
+
+Copyright (c) 2022 Lxtharia
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+https://github.com/Lxtharia/minegrub-theme
diff --git a/roles/minegrub/files/minegrub/Minecraft24.pf2 b/roles/minegrub/files/minegrub/Minecraft24.pf2
new file mode 100644
index 0000000..869b4d3
Binary files /dev/null and b/roles/minegrub/files/minegrub/Minecraft24.pf2 differ
diff --git a/roles/minegrub/files/minegrub/Minecraft30.pf2 b/roles/minegrub/files/minegrub/Minecraft30.pf2
new file mode 100644
index 0000000..fe6e2bc
Binary files /dev/null and b/roles/minegrub/files/minegrub/Minecraft30.pf2 differ
diff --git a/roles/minegrub/files/minegrub/Monocraft22.pf2 b/roles/minegrub/files/minegrub/Monocraft22.pf2
new file mode 100644
index 0000000..be68248
Binary files /dev/null and b/roles/minegrub/files/minegrub/Monocraft22.pf2 differ
diff --git a/roles/minegrub/files/minegrub/assets/MinecraftRegular-Bmg3.otf b/roles/minegrub/files/minegrub/assets/MinecraftRegular-Bmg3.otf
new file mode 100644
index 0000000..54f08ad
Binary files /dev/null and b/roles/minegrub/files/minegrub/assets/MinecraftRegular-Bmg3.otf differ
diff --git a/roles/minegrub/files/minegrub/assets/Monocraft.otf b/roles/minegrub/files/minegrub/assets/Monocraft.otf
new file mode 100644
index 0000000..631c97a
Binary files /dev/null and b/roles/minegrub/files/minegrub/assets/Monocraft.otf differ
diff --git a/roles/minegrub/files/minegrub/assets/logo_clear.png b/roles/minegrub/files/minegrub/assets/logo_clear.png
new file mode 100644
index 0000000..a450b2c
Binary files /dev/null and b/roles/minegrub/files/minegrub/assets/logo_clear.png differ
diff --git a/roles/minegrub/files/minegrub/assets/splashes.txt b/roles/minegrub/files/minegrub/assets/splashes.txt
new file mode 100644
index 0000000..f7254e2
--- /dev/null
+++ b/roles/minegrub/files/minegrub/assets/splashes.txt
@@ -0,0 +1,50 @@
+I use Arch BTW!
+Now with 100% more Linux!
+GNU's not UNIX!
+Praise Tux!
+Wine is not an Emulator!
+I am Root!
+Still stuck in Vim!
+Won't sell your data!
+Now with Rust!
+Full of Distros!
+Do redistribute!
+May contain penguins!
+Support FOSS devs!
+Bailing out!
+Everything is a file!
+May contain systemd...
+Open source!
+Made in Finland!
+It's not a bug, it's a feature!
+It's GNU/Linux!
+Sudo rm -rf!
+Yes, do as I say!
+90% bug free!
+Not water proof!
+Used by billions!
+12345 is a bad password!
+Turing complete!
+Woah.
+I have a suggestion.
+pls fix
+beep beep
+Boop!
+Splash!
+[Insert splash text here]
+Made by "real" people!
+Viruses have no power here!
+No place like ~
+Used in space!
+No reboots required!
+Case sensitive!
+.exe won't work here!
+No ads!
+May contain spaghetti...
+No registry needed!
+Forward slashes only!
+No DLLs needed!
+127.0.0.1 > localhost :)
+No caffeine!
+Zero calories!
+Do not eat!
diff --git a/roles/minegrub/files/minegrub/background.png b/roles/minegrub/files/minegrub/background.png
new file mode 100644
index 0000000..8e0f0a3
Binary files /dev/null and b/roles/minegrub/files/minegrub/background.png differ
diff --git a/roles/minegrub/files/minegrub/dirt.png b/roles/minegrub/files/minegrub/dirt.png
new file mode 100644
index 0000000..6e04f98
Binary files /dev/null and b/roles/minegrub/files/minegrub/dirt.png differ
diff --git a/roles/minegrub/files/minegrub/item_c.png b/roles/minegrub/files/minegrub/item_c.png
new file mode 100644
index 0000000..b8a9993
Binary files /dev/null and b/roles/minegrub/files/minegrub/item_c.png differ
diff --git a/roles/minegrub/files/minegrub/item_e.png b/roles/minegrub/files/minegrub/item_e.png
new file mode 100644
index 0000000..d9742eb
Binary files /dev/null and b/roles/minegrub/files/minegrub/item_e.png differ
diff --git a/roles/minegrub/files/minegrub/item_n.png b/roles/minegrub/files/minegrub/item_n.png
new file mode 100644
index 0000000..a50707d
Binary files /dev/null and b/roles/minegrub/files/minegrub/item_n.png differ
diff --git a/roles/minegrub/files/minegrub/item_ne.png b/roles/minegrub/files/minegrub/item_ne.png
new file mode 100644
index 0000000..b863a39
Binary files /dev/null and b/roles/minegrub/files/minegrub/item_ne.png differ
diff --git a/roles/minegrub/files/minegrub/item_nw.png b/roles/minegrub/files/minegrub/item_nw.png
new file mode 100644
index 0000000..447efb7
Binary files /dev/null and b/roles/minegrub/files/minegrub/item_nw.png differ
diff --git a/roles/minegrub/files/minegrub/item_s.png b/roles/minegrub/files/minegrub/item_s.png
new file mode 100644
index 0000000..32de032
Binary files /dev/null and b/roles/minegrub/files/minegrub/item_s.png differ
diff --git a/roles/minegrub/files/minegrub/item_se.png b/roles/minegrub/files/minegrub/item_se.png
new file mode 100644
index 0000000..e00df24
Binary files /dev/null and b/roles/minegrub/files/minegrub/item_se.png differ
diff --git a/roles/minegrub/files/minegrub/item_sw.png b/roles/minegrub/files/minegrub/item_sw.png
new file mode 100644
index 0000000..3b61033
Binary files /dev/null and b/roles/minegrub/files/minegrub/item_sw.png differ
diff --git a/roles/minegrub/files/minegrub/item_w.png b/roles/minegrub/files/minegrub/item_w.png
new file mode 100644
index 0000000..5a447fd
Binary files /dev/null and b/roles/minegrub/files/minegrub/item_w.png differ
diff --git a/roles/minegrub/files/minegrub/logo.png b/roles/minegrub/files/minegrub/logo.png
new file mode 100644
index 0000000..b560300
Binary files /dev/null and b/roles/minegrub/files/minegrub/logo.png differ
diff --git a/roles/minegrub/files/minegrub/selected_item_c.png b/roles/minegrub/files/minegrub/selected_item_c.png
new file mode 100644
index 0000000..612d8b1
Binary files /dev/null and b/roles/minegrub/files/minegrub/selected_item_c.png differ
diff --git a/roles/minegrub/files/minegrub/selected_item_e.png b/roles/minegrub/files/minegrub/selected_item_e.png
new file mode 100644
index 0000000..ae202e4
Binary files /dev/null and b/roles/minegrub/files/minegrub/selected_item_e.png differ
diff --git a/roles/minegrub/files/minegrub/selected_item_n.png b/roles/minegrub/files/minegrub/selected_item_n.png
new file mode 100644
index 0000000..6700703
Binary files /dev/null and b/roles/minegrub/files/minegrub/selected_item_n.png differ
diff --git a/roles/minegrub/files/minegrub/selected_item_ne.png b/roles/minegrub/files/minegrub/selected_item_ne.png
new file mode 100644
index 0000000..18e0db3
Binary files /dev/null and b/roles/minegrub/files/minegrub/selected_item_ne.png differ
diff --git a/roles/minegrub/files/minegrub/selected_item_nw.png b/roles/minegrub/files/minegrub/selected_item_nw.png
new file mode 100644
index 0000000..bbe69f8
Binary files /dev/null and b/roles/minegrub/files/minegrub/selected_item_nw.png differ
diff --git a/roles/minegrub/files/minegrub/selected_item_s.png b/roles/minegrub/files/minegrub/selected_item_s.png
new file mode 100644
index 0000000..30c00df
Binary files /dev/null and b/roles/minegrub/files/minegrub/selected_item_s.png differ
diff --git a/roles/minegrub/files/minegrub/selected_item_se.png b/roles/minegrub/files/minegrub/selected_item_se.png
new file mode 100644
index 0000000..6a2a3c3
Binary files /dev/null and b/roles/minegrub/files/minegrub/selected_item_se.png differ
diff --git a/roles/minegrub/files/minegrub/selected_item_sw.png b/roles/minegrub/files/minegrub/selected_item_sw.png
new file mode 100644
index 0000000..2fd4d11
Binary files /dev/null and b/roles/minegrub/files/minegrub/selected_item_sw.png differ
diff --git a/roles/minegrub/files/minegrub/selected_item_w.png b/roles/minegrub/files/minegrub/selected_item_w.png
new file mode 100644
index 0000000..2973406
Binary files /dev/null and b/roles/minegrub/files/minegrub/selected_item_w.png differ
diff --git a/roles/minegrub/files/minegrub/static_bar.png b/roles/minegrub/files/minegrub/static_bar.png
new file mode 100644
index 0000000..7baa25e
Binary files /dev/null and b/roles/minegrub/files/minegrub/static_bar.png differ
diff --git a/roles/minegrub/files/minegrub/term_e.png b/roles/minegrub/files/minegrub/term_e.png
new file mode 100644
index 0000000..e8f822b
Binary files /dev/null and b/roles/minegrub/files/minegrub/term_e.png differ
diff --git a/roles/minegrub/files/minegrub/term_n.png b/roles/minegrub/files/minegrub/term_n.png
new file mode 100644
index 0000000..2cf9905
Binary files /dev/null and b/roles/minegrub/files/minegrub/term_n.png differ
diff --git a/roles/minegrub/files/minegrub/term_ne.png b/roles/minegrub/files/minegrub/term_ne.png
new file mode 100644
index 0000000..d31d210
Binary files /dev/null and b/roles/minegrub/files/minegrub/term_ne.png differ
diff --git a/roles/minegrub/files/minegrub/term_nw.png b/roles/minegrub/files/minegrub/term_nw.png
new file mode 100644
index 0000000..0237a18
Binary files /dev/null and b/roles/minegrub/files/minegrub/term_nw.png differ
diff --git a/roles/minegrub/files/minegrub/term_s.png b/roles/minegrub/files/minegrub/term_s.png
new file mode 100644
index 0000000..bc004e4
Binary files /dev/null and b/roles/minegrub/files/minegrub/term_s.png differ
diff --git a/roles/minegrub/files/minegrub/term_se.png b/roles/minegrub/files/minegrub/term_se.png
new file mode 100644
index 0000000..4445547
Binary files /dev/null and b/roles/minegrub/files/minegrub/term_se.png differ
diff --git a/roles/minegrub/files/minegrub/term_sw.png b/roles/minegrub/files/minegrub/term_sw.png
new file mode 100644
index 0000000..986f1ca
Binary files /dev/null and b/roles/minegrub/files/minegrub/term_sw.png differ
diff --git a/roles/minegrub/files/minegrub/term_w.png b/roles/minegrub/files/minegrub/term_w.png
new file mode 100644
index 0000000..9f48977
Binary files /dev/null and b/roles/minegrub/files/minegrub/term_w.png differ
diff --git a/roles/minegrub/files/minegrub/theme.txt b/roles/minegrub/files/minegrub/theme.txt
new file mode 100644
index 0000000..9830e9b
--- /dev/null
+++ b/roles/minegrub/files/minegrub/theme.txt
@@ -0,0 +1,140 @@
+# Global
+
+title-text: ""
+desktop-image: "background.png"
+
+# Terminal for Console and Options
+terminal-border: "20"
+terminal-left: "10%"
+terminal-top: "10%+23"
+terminal-width: "80%"
+terminal-height: "80%"
+terminal-box: "term_*.png"
+terminal-font: "Monocraft Regular 22"
+
+# Text White
++ boot_menu {
+ # as we don't have any pixmaps here, it gets aligned strangely
+ # top pixmap is 17px in height
+ # left pixmap is 6px in width
+ # the text needs to be 3 pixels above and 3 pixels to the left
+ left = 50%-297
+ top = 40%+14
+ width = 600
+ height = 500
+
+ item_font = "Minecraft Regular 30"
+ item_color = "#ffffff"
+ selected_item_color = "#ffffa0"
+ item_height = 34
+ item_padding = 0
+ item_spacing = 38
+ scrollbar = false
+}
+
+
++ boot_menu {
+ left = 50%-300
+ top = 40%
+ width = 600
+ height = 500
+
+ item_font = "Minecraft Regular 30"
+ item_color = "#383838"
+ selected_item_color = "#3f3f28"
+ item_height = 34
+ item_padding = 0
+ item_spacing = 38
+ item_pixmap_style = "item_*.png"
+ selected_item_pixmap_style = "selected_item_*.png"
+ scrollbar = false
+}
+
+
+
++ image {
+ # width of the static bottom bar image is 744
+ left = 50%-372
+
+ # n is amount of boot options (each element is (42 height + 30 spacing) = 72px in height)
+ # top = 40%+( 72 * N + 26 )
+ #
+ ### +170 (for 2 boot options)
+ ### +242 (for 3 boot options)
+ ### +314 (for 4 boot options)
+ ### +386 (for 5 boot options)
+ ### +458 (for 6 boot options)
+ ### +530 (for 7 boot options)
+ ###
+ ############### CHANGE VALUE HERE ################
+
+ top = 40%+314
+
+ ### Don't leave spaces in between the value
+ ##################################################
+
+ file = "static_bar.png"
+}
+
++ image {
+ # width of the logo image is 1200, but the center of the logo is at x=400
+ left = 50%-400
+ top = 0
+ file = "logo.png"
+}
+
+# TEXT
++ label {
+ left = 6
+ top = 100%-31
+ height = 54
+ width = 200
+
+ text = "Minegrub 2.0.0"
+ font = "Minecraft Regular 30"
+ color = "white"
+}
+
+# SHADOW
++ label {
+ left = 9
+ top = 100%-28
+ height = 54
+ width = 200
+
+ text = "Minegrub 2.0.0"
+ font = "Minecraft Regular 30"
+ color = "#3f3f3f"
+}
+
+# TEXT
++ label {
+ id = "__timeout__"
+
+ left = 50%
+ top = 100%-31
+ height = 24
+ width = 50%-6
+
+ text = "Joining world in %d seconds"
+ align = "right"
+ font = "Minecraft Regular 30"
+ color = "white"
+}
+
+# SHADOW
++ label {
+ id = "__timeout__"
+
+ left = 50%+3
+ top = 100%-28
+ height = 24
+ width = 50%-6
+
+ text = "Joining world in %d seconds"
+ align = "right"
+ font = "Minecraft Regular 30"
+ color = "#3f3f3f"
+}
+
+
diff --git a/roles/minegrub/tasks/main.yml b/roles/minegrub/tasks/main.yml
new file mode 100644
index 0000000..59efed9
--- /dev/null
+++ b/roles/minegrub/tasks/main.yml
@@ -0,0 +1,17 @@
+---
+- name: "[Minegrub] Install"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "/boot/grub/themes/"
+ force: false
+ become: true
+
+- name: "[Minegrub] Configure"
+ shell: sed -i '/^\(#\)\?GRUB_THEME/ s~.*~GRUB_THEME=/boot/grub/themes/minegrub/theme.txt~' /etc/default/grub
+ ignore_errors: true
+ become: true
+
+- name: "[Minegrub] Updating grub"
+ shell: grub-mkconfig -o /boot/grub/grub.cfg
+ ignore_errors: true
+ become: true
diff --git a/.config/nvim/init.lua b/roles/nvim/files/init.lua
similarity index 99%
rename from .config/nvim/init.lua
rename to roles/nvim/files/init.lua
index 5b887e2..f624509 100755
--- a/.config/nvim/init.lua
+++ b/roles/nvim/files/init.lua
@@ -39,7 +39,7 @@ require("lazy").setup({
{ "numToStr/Comment.nvim", opts = {} },
-- Detect tabstop and shiftwidth automatically
- "tpope/vim-sleuth",
+ -- "tpope/vim-sleuth",
-- Add indentation guides even on blank lines ???
{
@@ -168,9 +168,9 @@ require("lazy").setup({
})
-- Tab
-vim.opt.tabstop = 4
-vim.opt.softtabstop = 4
-vim.opt.shiftwidth = 4
+vim.opt.tabstop = 2
+vim.opt.softtabstop = 2
+vim.opt.shiftwidth = 2
vim.opt.expandtab = true
--- Show line numbers
diff --git a/roles/nvim/tasks/main.yml b/roles/nvim/tasks/main.yml
new file mode 100644
index 0000000..2c9c828
--- /dev/null
+++ b/roles/nvim/tasks/main.yml
@@ -0,0 +1,18 @@
+---
+- name: "[Nvim] Install"
+ ansible.builtin.package:
+ name:
+ - neovim
+ state: latest
+ become: true
+
+- name: "[Nvim] Create config folder"
+ ansible.builtin.file:
+ mode: "0755"
+ path: "{{ ansible_user_dir }}/.config/nvim"
+ state: directory
+
+- name: "[Nvim] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/.config/nvim"
diff --git a/etc/sddm.conf.d/default.conf b/roles/sddm/files/sddm.conf.d/default.conf
similarity index 98%
rename from etc/sddm.conf.d/default.conf
rename to roles/sddm/files/sddm.conf.d/default.conf
index ec7121b..ba64598 100755
--- a/etc/sddm.conf.d/default.conf
+++ b/roles/sddm/files/sddm.conf.d/default.conf
@@ -58,7 +58,7 @@ EnableAvatars=true
FacesDir=/usr/share/sddm/faces
# Font used in the greeter
-Font=FiraCode Nerd Font Regular 12
+Font=CaskaydiaCove Nerd Font 12
# Theme directory path
ThemeDir=/usr/share/sddm/themes
diff --git a/roles/sddm/tasks/main.yml b/roles/sddm/tasks/main.yml
new file mode 100644
index 0000000..d25735c
--- /dev/null
+++ b/roles/sddm/tasks/main.yml
@@ -0,0 +1,14 @@
+---
+- name: "[SDDM] Install"
+ ansible.builtin.package:
+ name:
+ - sddm
+ state: latest
+ become: true
+
+- name: "[SDDM] Configure"
+ ansible.builtin.copy:
+ mode: 0755
+ src: "./"
+ dest: "/etc/"
+ become: true
diff --git a/.config/starship.toml b/roles/starship/files/starship.toml
similarity index 100%
rename from .config/starship.toml
rename to roles/starship/files/starship.toml
diff --git a/roles/starship/tasks/main.yml b/roles/starship/tasks/main.yml
new file mode 100644
index 0000000..d1bb099
--- /dev/null
+++ b/roles/starship/tasks/main.yml
@@ -0,0 +1,12 @@
+---
+- name: "[Starship] Install"
+ ansible.builtin.package:
+ name:
+ - starship
+ state: latest
+ become: true
+
+- name: "[Starship] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/.config"
diff --git a/.config/swaylock/swaylock.conf b/roles/swaylock/files/swaylock.conf
similarity index 71%
rename from .config/swaylock/swaylock.conf
rename to roles/swaylock/files/swaylock.conf
index 6bbea2f..8142fce 100755
--- a/.config/swaylock/swaylock.conf
+++ b/roles/swaylock/files/swaylock.conf
@@ -7,4 +7,4 @@ datestr=%a %e.%m.%Y
effect-blur=4x2
effect-scale=0.4
effect-vignette=0.2:0.5
-image=~/.config/hypr/theme/current_background.jpg
+image=~/.config/background
diff --git a/roles/swaylock/tasks/main.yml b/roles/swaylock/tasks/main.yml
new file mode 100644
index 0000000..893b3fc
--- /dev/null
+++ b/roles/swaylock/tasks/main.yml
@@ -0,0 +1,19 @@
+---
+- name: "[Swaylock] Install"
+ kewlfft.aur.aur:
+ name:
+ - swaylock-effects-git
+ use: paru
+ state: present
+ become: true
+
+- name: "[Swaylock] Create config folder"
+ ansible.builtin.file:
+ mode: "0755"
+ path: "{{ ansible_user_dir }}/.config/swaylock"
+ state: directory
+
+- name: "[Swaylock] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/.config/swaylock"
diff --git a/roles/system/files/pacman.conf b/roles/system/files/pacman.conf
new file mode 100644
index 0000000..e01c0f8
--- /dev/null
+++ b/roles/system/files/pacman.conf
@@ -0,0 +1,98 @@
+#
+# /etc/pacman.conf
+#
+# See the pacman.conf(5) manpage for option and repository directives
+
+#
+# GENERAL OPTIONS
+#
+[options]
+# The following paths are commented out with their default values listed.
+# If you wish to use different paths, uncomment and update the paths.
+#RootDir = /
+#DBPath = /var/lib/pacman/
+#CacheDir = /var/cache/pacman/pkg/
+#LogFile = /var/log/pacman.log
+#GPGDir = /etc/pacman.d/gnupg/
+#HookDir = /etc/pacman.d/hooks/
+HoldPkg = pacman glibc
+#XferCommand = /usr/bin/curl -L -C - -f -o %o %u
+#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
+#CleanMethod = KeepInstalled
+Architecture = auto
+
+# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup
+#IgnorePkg =
+#IgnoreGroup =
+
+#NoUpgrade =
+#NoExtract =
+
+# Misc options
+#UseSyslog
+Color
+ILoveCandy
+#NoProgressBar
+CheckSpace
+#VerbosePkgLists
+ParallelDownloads = 5
+
+# By default, pacman accepts packages signed by keys that its local keyring
+# trusts (see pacman-key and its man page), as well as unsigned packages.
+SigLevel = Required DatabaseOptional
+LocalFileSigLevel = Optional
+#RemoteFileSigLevel = Required
+
+# NOTE: You must run `pacman-key --init` before first using pacman; the local
+# keyring can then be populated with the keys of all official Arch Linux
+# packagers with `pacman-key --populate archlinux`.
+
+#
+# REPOSITORIES
+# - can be defined here or included from another file
+# - pacman will search repositories in the order defined here
+# - local/custom mirrors can be added here or in separate files
+# - repositories listed first will take precedence when packages
+# have identical names, regardless of version number
+# - URLs will have $repo replaced by the name of the current repo
+# - URLs will have $arch replaced by the name of the architecture
+#
+# Repository entries are of the format:
+# [repo-name]
+# Server = ServerName
+# Include = IncludePath
+#
+# The header [repo-name] is crucial - it must be present and
+# uncommented to enable the repo.
+#
+
+# The testing repositories are disabled by default. To enable, uncomment the
+# repo name header and Include lines. You can add preferred servers immediately
+# after the header, and they will be used before the default mirrors.
+
+#[core-testing]
+#Include = /etc/pacman.d/mirrorlist
+
+[core]
+Include = /etc/pacman.d/mirrorlist
+
+#[extra-testing]
+#Include = /etc/pacman.d/mirrorlist
+
+[extra]
+Include = /etc/pacman.d/mirrorlist
+
+# If you want to run 32 bit applications on your x86_64 system,
+# enable the multilib repositories as required here.
+
+#[multilib-testing]
+#Include = /etc/pacman.d/mirrorlist
+
+[multilib]
+Include = /etc/pacman.d/mirrorlist
+
+# An example of a custom package repository. See the pacman manpage for
+# tips on creating your own repositories.
+#[custom]
+#SigLevel = Optional TrustAll
+#Server = file:///home/custompkgs
diff --git a/roles/system/tasks/Archlinux.yml b/roles/system/tasks/Archlinux.yml
new file mode 100644
index 0000000..f916244
--- /dev/null
+++ b/roles/system/tasks/Archlinux.yml
@@ -0,0 +1,269 @@
+---
+- name: "[Arch] Configure pacman"
+ ansible.builtin.copy:
+ mode: 0644
+ src: "pacman.conf"
+ dest: "/etc/"
+ become: true
+ tags:
+ - pacman
+
+- name: "[Arch] Update packages"
+ community.general.pacman:
+ update_cache: true
+ upgrade: true
+ state: latest
+ become: true
+ tags:
+ - pacman
+
+- name: "[Arch] Install default packages"
+ kewlfft.aur.aur:
+ name:
+ - networkmanager
+ - networkmanager-openvpn
+ - network-manager-applet
+ - inotify-tools
+ - cifs-utils
+ - ntfs-3g
+ - openssh
+ - upower
+ - unzip
+ - less
+ - curl
+ - wget
+ - awk
+ - zip
+ - tar
+ - eza
+ - bat
+ - jq
+ use: paru
+ state: present
+ tags:
+ - default_pkgs
+
+- name: "[Arch] Install programming packages"
+ kewlfft.aur.aur:
+ name:
+ - jdk-openjdk
+ - maven
+ - rustup
+ - npm
+ use: paru
+ state: present
+ tags:
+ - programming_pkgs
+ when: system != 'server'
+
+- name: "[Arch] Configure rustup"
+ command: rustup default stable
+ tags:
+ - programming_pkgs
+ when: system != 'server'
+
+- name: "[Arch] Install desktop packages"
+ kewlfft.aur.aur:
+ name:
+ # Fonts
+ - noto-fonts
+ - noto-fonts-cjk
+ - noto-fonts-emoji
+ - ttf-font-awesome
+ - ttf-firacode-nerd
+ # Pipewire
+ - pipewire
+ - wireplumber
+ - pipewire-alsa
+ - pipewire-audio
+ - pipewire-jack
+ - pipewire-pulse
+ - gst-plugin-pipewire
+ # Bluetooth
+ - bluez
+ - bluez-utils
+ - blueman
+ # Printing
+ - cups
+ - cups-pdf
+ # Theming
+ #- qt5ct
+ - nwg-look
+ # Icon Themes
+ - papirus-icon-theme
+ # Cursor Themes
+ - rose-pine-hyprcursor
+ - xcursor-breeze
+ # Themes
+ - catppuccin-gtk-theme-frappe
+ - catppuccin-gtk-theme-latte
+ - catppuccin-gtk-theme-macchiato
+ - catppuccin-gtk-theme-mocha
+ # Misc
+ - brightnessctl
+ #- wlr-randr
+ - playerctl
+ - libnotify
+ - mediainfo
+ - hyprpicker
+ - swww
+ - swayidle
+ - grimblast-git
+ - cliphist
+ - wl-clipboard
+ - polkit-kde-agent
+ - xdg-desktop-portal-hyprland
+ - gnome-keyring
+ use: paru
+ state: present
+ tags:
+ - desktop_pkgs
+ when: system != 'server'
+
+- name: "[Arch] Install desktop applications"
+ kewlfft.aur.aur:
+ name:
+ - youtube-music
+ - libreoffice-fresh
+ - nextcloud-client
+ - youtube-music
+ - waypaper-git
+ - vscodium-bin
+ - pavucontrol
+ - hyprpicker
+ - brave-bin
+ - obsidian
+ - discord
+ - yt-dlp
+ - nvtop
+ - nemo
+ - mpv
+ # Device configuration
+ #- openrazer-daemon
+ #- openrgb
+ #- piper
+ # AMD Stats
+ #- amdgpu_top
+ # Character map
+ #- gucharmap
+ # Calculator
+ #- galculator
+ use: paru
+ state: present
+ tags:
+ - desktop_apps
+ when: system != 'server'
+
+- name: "[Arch] Install additional desktop packages"
+ kewlfft.aur.aur:
+ name:
+ - steam
+ - lutris
+ # Wine
+ - wine-staging
+ - giflib
+ - lib32-giflib
+ - libpng
+ - lib32-libpng
+ - libldap
+ - lib32-libldap
+ - gnutls
+ - lib32-gnutls
+ - mpg123
+ - lib32-mpg123
+ - openal
+ - lib32-openal
+ - v4l-utils
+ - lib32-v4l-utils
+ - libpulse
+ - lib32-libpulse
+ - libgpg-error
+ - lib32-libgpg-error
+ - alsa-plugins
+ - lib32-alsa-plugins
+ - alsa-lib
+ - lib32-alsa-lib
+ - libjpeg-turbo
+ - lib32-libjpeg-turbo
+ - sqlite
+ - lib32-sqlite
+ - libxcomposite
+ - lib32-libxcomposite
+ - libxinerama
+ - lib32-libgcrypt
+ - libgcrypt
+ - lib32-libxinerama
+ - ncurses
+ - lib32-ncurses
+ - ocl-icd
+ - lib32-ocl-icd
+ - libxslt
+ - lib32-libxslt
+ - libva
+ - lib32-libva
+ - gtk3
+ - lib32-gtk3
+ - gst-plugins-base-libs
+ - lib32-gst-plugins-base-libs
+ - vulkan-icd-loader
+ - lib32-vulkan-icd-loader
+ use: paru
+ state: present
+ tags:
+ - desktop_pkgs
+ when: system == 'desktop_full'
+
+- name: Gather GPU info
+ shell: "lspci | grep -i vga"
+ register: gpu_info
+ tags:
+ - desktop_pkgs
+ when: system == 'desktop_full'
+
+- name: "[Arch] Install AMD packages"
+ kewlfft.aur.aur:
+ name:
+ - lib32-mesa
+ - vulkan-radeon
+ - lib32-vulkan-radeon
+ use: paru
+ state: present
+ when: "system == 'desktop_full' and 'Advanced Micro Devices' in gpu_info.stdout"
+
+- name: "[Arch] Install Intel packages"
+ kewlfft.aur.aur:
+ name:
+ - lib32-mesa
+ - vulkan-intel
+ - lib32-vulkan-intel
+ use: paru
+ state: present
+ tags:
+ - desktop_pkgs
+ when: "system == 'desktop_full' and 'Intel Corporation' in gpu_info.stdout"
+
+- name: "[Arch] Install Nvidia packages"
+ kewlfft.aur.aur:
+ name:
+ - nvidia-dkms
+ - nvidia-utils
+ - lib32-nvidia-utils
+ - nvidia-settings
+ use: paru
+ state: present
+ tags:
+ - desktop_pkgs
+ when: "system == 'desktop_full' and 'NVIDIA' in gpu_info.stdout"
+
+- name: "[Arch] Enable services"
+ ansible.builtin.service:
+ name: "{{ item }}"
+ enabled: true
+ with_items:
+ - bluetooth
+ - cups
+ - sddm
+ tags:
+ - desktop_services
+ when: "system == 'desktop'"
+ become: true
diff --git a/roles/system/tasks/main.yml b/roles/system/tasks/main.yml
new file mode 100644
index 0000000..968dd62
--- /dev/null
+++ b/roles/system/tasks/main.yml
@@ -0,0 +1,11 @@
+---
+- name: "[System] Checking for Distribution Config: {{ ansible_distribution }}"
+ ansible.builtin.stat:
+ path: "{{ role_path }}/tasks/{{ ansible_distribution }}.yml"
+ register: system_distribution_config
+ tags:
+ - system
+
+- name: "[System] Run Tasks: {{ ansible_distribution }}"
+ ansible.builtin.include_tasks: "{{ ansible_distribution }}.yml"
+ when: system_distribution_config.stat.exists
diff --git a/roles/yazi/files/keymap.toml b/roles/yazi/files/keymap.toml
new file mode 100644
index 0000000..6010eb8
--- /dev/null
+++ b/roles/yazi/files/keymap.toml
@@ -0,0 +1,20 @@
+# Bookmarks
+[[manager.prepend_keymap]]
+on = [ "b", "g" ]
+run = "cd ~/git/"
+desc = "GIT"
+
+[[manager.prepend_keymap]]
+on = [ "b", "d" ]
+run = "cd ~/Data/"
+desc = "DATA"
+
+[[manager.prepend_keymap]]
+on = [ "b", "s" ]
+run = "plugin bookmark --args=save"
+desc = "Save Bookmark"
+
+[[manager.prepend_keymap]]
+on = [ "b", "j" ]
+run = "plugin bookmark --args=jump"
+desc = "Jump Bookmark"
diff --git a/roles/yazi/files/plugins/bookmark.yazi/init.lua b/roles/yazi/files/plugins/bookmark.yazi/init.lua
new file mode 100644
index 0000000..2151b3b
--- /dev/null
+++ b/roles/yazi/files/plugins/bookmark.yazi/init.lua
@@ -0,0 +1,39 @@
+local temp_dir = os.getenv("TEMP") or os.getenv("TMP") or "/tmp"
+local file_name = temp_dir .. "/bookmark.yazi"
+
+local save_bookmark = ya.sync(function(state, idx)
+ local folder = Folder:by_kind(Folder.CURRENT)
+ local file = io.open(file_name, "w")
+
+ if file then
+ file:write(tostring(folder.cwd))
+ file:close()
+ end
+end)
+
+local jump_bookmark = ya.sync(function(state, idx)
+ local io = require("io")
+ local file = io.open(file_name, "r")
+
+ if file then
+ local line = file:read("*line")
+ file:close()
+ ya.manager_emit("cd", { line })
+ ya.manager_emit("arrow", { -99999999 })
+ end
+end)
+
+return {
+ entry = function(_, args)
+ local action = args[1]
+ if not action then
+ return
+ end
+
+ if action == "save" then
+ save_bookmark()
+ elseif action == "jump" then
+ jump_bookmark()
+ end
+ end
+}
diff --git a/.config/yazi/yazi.toml b/roles/yazi/files/yazi.toml
similarity index 100%
rename from .config/yazi/yazi.toml
rename to roles/yazi/files/yazi.toml
diff --git a/roles/yazi/tasks/main.yml b/roles/yazi/tasks/main.yml
new file mode 100644
index 0000000..f241de1
--- /dev/null
+++ b/roles/yazi/tasks/main.yml
@@ -0,0 +1,18 @@
+---
+- name: "[Yazi] Install"
+ ansible.builtin.package:
+ name:
+ - yazi
+ state: latest
+ become: true
+
+- name: "[Yazi] Create config folder"
+ ansible.builtin.file:
+ mode: "0755"
+ path: "{{ ansible_user_dir }}/.config/yazi"
+ state: directory
+
+- name: "[Yazi] Configure"
+ ansible.builtin.copy:
+ src: "./"
+ dest: "{{ ansible_user_dir }}/.config/yazi"
diff --git a/theming.pkgs b/theming.pkgs
deleted file mode 100644
index 11ea522..0000000
--- a/theming.pkgs
+++ /dev/null
@@ -1,27 +0,0 @@
-# Theming
-nwg-look
-kvantum
-qt5ct
-
-# Fonts
-noto-fonts
-noto-fonts-cjk
-noto-fonts-emoji
-ttf-font-awesome
-ttf-firacode-nerd
-#nerd-fonts
-
-# Icon Themes
-papirus-icon-theme
-xcursor-breeze
-
-# Themes
-catppuccin-gtk-theme-frappe
-catppuccin-gtk-theme-latte
-catppuccin-gtk-theme-macchiato
-catppuccin-gtk-theme-mocha
-
-# Dependencies
-qt5-graphicaleffects
-qt5-quickcontrols2
-qt5-svg