Files
.dotfiles/config.org
T
2024-11-22 21:44:41 +01:00

143 KiB

PWL Arch Linux Config

Table of Contents   toc

Prerequisites

  • Completed Arch Linux Installation

    • partitioning
    • encryption
    • main user

Literate File Headers

This is used to initialize all files that are accessed from multiple places in the config

update.sh

#!/bin/sh
# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

packages.txt

contains all general Arch and AUR packages

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

pwl-desktop_pkg-list

contains all packages for the device pwl-desktop

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

paul-laptop_pkg-list

contains all packages for the device paul-laptop

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

alias.sh

#!/bin/sh
# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

path.sh

contains all modifications to the path variables

#!/bin/sh
# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

Doom Emacs

We start by simply defining the standard headers used by the three files. These headers come from the initial files generated by doom install, and contain either some Emacs-LISP relevant indicators like lexical-binding, or instructions about the contents of the file.

init.el

init.el
;;; init.el -*- lexical-binding: t; -*-

;; DO NOT EDIT THIS FILE DIRECTLY
;; This is a file generated from a literate programing source file
;; You should make any changes there and regenerate it from Emacs org-mode
;; using org-babel-tangle (C-c C-v t)

;; This file controls what Doom modules are enabled and what order they load
;; in. Remember to run 'doom sync' after modifying it!

;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
;;      documentation. There you'll find a "Module Index" link where you'll find
;;      a comprehensive list of Doom's modules and what flags they support.

;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
;;      'C-c c k' for non-vim users) to view its documentation. This works on
;;      flags as well (those symbols that start with a plus).
;;
;;      Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
;;      directory (for easy access to its source code).

packages.el

packages.el
;; -*- no-byte-compile: t; -*-
;;; $DOOMDIR/packages.el

;; DO NOT EDIT THIS FILE DIRECTLY
;; This is a file generated from a literate programing source file
;; You should make any changes there and regenerate it from Emacs org-mode
;; using org-babel-tangle (C-c C-v t)

;; To install a package with Doom you must declare them here and run 'doom sync'
;; on the command line, then restart Emacs for the changes to take effect -- or
;; use 'M-x doom/reload'.

;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
;;(package! some-package)

;; To install a package directly from a remote git repo, you must specify a
;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
;; https://github.com/raxod502/straight.el#the-recipe-format
;;(package! another-package
;;  :recipe (:host github :repo "username/repo"))

;; If the package you are trying to install does not contain a PACKAGENAME.el
;; file, or is located in a subdirectory of the repo, you'll need to specify
;; `:files' in the `:recipe':
;;(package! this-package
;;  :recipe (:host github :repo "username/repo"
;;           :files ("some-file.el" "src/lisp/*.el")))

;; If you'd like to disable a package included with Doom, you can do so here
;; with the `:disable' property:
;;(package! builtin-package :disable t)

;; You can override the recipe of a built in package without having to specify
;; all the properties for `:recipe'. These will inherit the rest of its recipe
;; from Doom or MELPA/ELPA/Emacsmirror:
;;(package! builtin-package :recipe (:nonrecursive t))
;;(package! builtin-package-2 :recipe (:repo "myfork/package"))

;; Specify a `:branch' to install a package from a particular branch or tag.
;; This is required for some packages whose default branch isn't 'master' (which
;; our package manager can't deal with; see raxod502/straight.el#279)
;;(package! builtin-package :recipe (:branch "develop"))

;; Use `:pin' to specify a particular commit to install.
;;(package! builtin-package :pin "1a2b3c4d5e")

;; Doom's packages are pinned to a specific commit and updated from release to
;; release. The `unpin!' macro allows you to unpin single packages...
;;(unpin! pinned-package)
;; ...or multiple packages
;;(unpin! pinned-package another-pinned-package)
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
;;(unpin! t)

config.el

config.el
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-

;; DO NOT EDIT THIS FILE DIRECTLY
;; This is a file generated from a literate programing source file
;; You should make any changes there and regenerate it from Emacs org-mode
;; using org-babel-tangle (C-c C-v t)

;; Place your private configuration here! Remember, you do not need to run 'doom
;; sync' after modifying this file!

;; Some functionality uses this to identify you, e.g. GPG configuration, email
;; clients, file templates and snippets.
;; (setq user-full-name "John Doe"
;;      user-mail-address "john@doe.com")

;; Doom exposes five (optional) variables for controlling fonts in Doom. Here
;; are the three important ones:
;;
;; + `doom-font'
;; + `doom-variable-pitch-font'
;; + `doom-big-font' -- used for `doom-big-font-mode'; use this for
;;   presentations or streaming.
;;
;; They all accept either a font-spec, font string ("Input Mono-12"), or xlfd
;; font string. You generally only need these two:
;; (setq doom-font (font-spec :family "monospace" :size 12 :weight 'semi-light)
;;       doom-variable-pitch-font (font-spec :family "sans" :size 13))

;; There are two ways to load a theme. Both assume the theme is installed and
;; available. You can either set `doom-theme' or manually load a theme with the
;; `load-theme' function. This is the default:
;; (setq doom-theme 'doom-one)

;; If you use `org' and don't want your org files in the default location below,
;; change `org-directory'. It must be set before org loads!
;; (setq org-directory "~/org/")

;; This determines the style of line numbers in effect. If set to `nil', line
;; numbers are disabled. For relative line numbers, set this to `relative'.
;; (setq display-line-numbers-type t)

;; Here are some additional functions/macros that could help you configure Doom:
;;
;; - `load!' for loading external *.el files relative to this one
;; - `use-package!' for configuring packages
;; - `after!' for running code after a package has loaded
;; - `add-load-path!' for adding directories to the `load-path', relative to
;;   this file. Emacs searches the `load-path' when you load packages with
;;   `require' or `use-package'.
;; - `map!' for binding new keys
;;
;; To get information about any of these functions/macros, move the cursor over
;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
;; This will open documentation for it, including demos of how they are used.
;;
;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
;; they are implemented.

.zshrc

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

.bashrc

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

autostart.sh

#!/bin/sh
# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

alacritty.toml

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

/etc/environment

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

#
# This file is parsed by pam_env module
#
# Syntax: simple "KEY=VAL" pairs on separate lines
#

Package Management

Yay

Prerequisites

git
base-devel

Installation

General Package Management is done via Yay. update.sh will install it if needed.

command_name="yay"

if ! command -v "$command_name" &> /dev/null; then
    echo "Installing $command_name ..."
    git clone https://aur.archlinux.org/yay.git /tmp/yay
    cd /tmp/yay
    makepkg -si
fi

after installation add yay to the packages list to ensure it doesn't delete itself

yay

Config

Literate File Header
# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)
Options
[options]
HoldPkg

Packages that should not be updated for compatibility reasons

HoldPkg     = pacman glibc
Automatic Archtiecture Detection
Architecture = auto
Check Space before Operation
CheckSpace
Colorful Output
Color
Enable Parallel Downloads

Increase the download speed by enabling parallel downloads

ParallelDownloads = 5
Accepted Packages
# 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
Core Packages
[core]
Include = /etc/pacman.d/mirrorlist
Extra Packages
[extra]
Include = /etc/pacman.d/mirrorlist
Multilib Packages
[multilib]
Include = /etc/pacman.d/mirrorlist

Update Package Repositories

yay -Sy

Package Installation

remove all packages not in pkg-list.txt or the specific device <device_name>_pkg-list.txt file

# Get list of installed packages
INSTALLED_PACKAGES=$(pacman -Qqe)

# Read the list of packages to keep from the file
KEEP_LIST=$(cat "pkg-list.txt")
KEEP_LIST+=$'\n'
KEEP_LIST+=$(cat "$(uname -n)_pkg-list.txt")

# Loop through installed packages
for PACKAGE in $INSTALLED_PACKAGES; do
    # Check if the package is not in the keep list
    if ! echo "$KEEP_LIST" | grep -q "^$PACKAGE$"; then
        echo "Removing package: $PACKAGE"
        # Uncomment the following line to actually remove the package
        yay -Rns --noconfirm "$PACKAGE"
    fi
done

remove orphaned packages and update the remaining packages to avoid version conflicts

yay -Qtdq | yay -Rns -
yay -Syu

and install the packages specified in pkg-list.txt or the specific device <device_name>_pkg-list.txt file

yay -S --needed `grep -v '^#' pkg-list.txt`
yay -S --needed `grep -v '^#' $(uname -n)_pkg-list.txt`

Base System

Arch Linux

the following packages are required for basic operation and should never be deleted

base
efibootmgr
grub
linux-zen
linux-zen-headers
linux-lts
linux-lts-headers
linux-firmware
linux-firmware-marvell
lvm2
sudo

Network Manager

Installation

This config uses the NetworkManager

networkmanager

after being installed it also needs to be enabled

systemd_service="NetworkManager"
if ! systemctl is-enabled --quiet "$systemd_service"; then
    echo "Enabling $systemd_service"
    sudo systemctl enable "$systemd_service"
    sudo systemctl start "$systemd_service"
fi

TODO Networks

Applet

network-manager-applet
nm-applet &

Man Pages and Texinfo

man-db
man-pages
texinfo

Build Tools

cmake
make

System Locale

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

LANG=en_US.UTF-8
LC_CTYPE=de_DE.UTF-8
LC_NUMERIC=de_DE.UTF-8
LC_TIME=de_DE.UTF-8
LC_COLLATE=en_US.UTF-8
LC_MONETARY=de_DE.UTF-8
LC_MESSAGES=en_US.UTF-8
LC_PAPER=de_DE.UTF-8
LC_NAME=en_US.UTF-8
LC_ADDRESS=de_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_MEASUREMENTS=de_DE.UTF-8
LC_IDENTIFICATION=en_US.UTF-8
LC_ALL=

Keyboard Layout

vconsole

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

KEYMAP=de-latin1

Xorg

if ! localectl status | grep -q "X11 Layout.*de"; then
    sudo localectl set-x11-keymap --no-convert de
fi

NTP

systemd_service="systemd-timesyncd"
if ! systemctl is-enabled --quiet "$systemd_service"; then
    echo "Enabling $systemd_service"
    sudo systemctl enable "$systemd_service"
fi

Audio

pulseaudio
pulseaudio-alsa
pulseaudio-bluetooth
pulseaudio-equalizer
pulseaudio-jack

Additional Firmware

pwl-desktop

amd-ucode
aic94xx-firmware
sof-firmware
wd719x-firmware
nvidia-dkms
# opencl-headers
# opencl-nvidia
mesa
#xf86-video-nouveau
cuda

paul-laptop

amd-ucode

NTFS Compatibility

ntfs-3g

Timeshift

timeshift

Desktop Environments and Window Manager

LightDM

install the required packages

lightdm
lightdm-gtk-greeter

and enable the systemd service

systemd_service="lightdm"
if ! systemctl is-enabled --quiet "$systemd_service"; then
    echo "Enabling $systemd_service"
    sudo systemctl enable "$systemd_service"
fi

Xfce

Installation

xfce4-appfinder
xfce4-panel
xfce4-power-manager
xfce4-session
xfce4-settings
xfce4-terminal
xfconf
xfdesktop
xfwm4
xfwm4-themes
exo
garcon
#file manager
thunar
#external media connection handling
gvfs
thunar-volman
#thumbnail generator
tumbler

Qtile

(Almost) all configuration is done via the config.py file

config.py Literate File Header

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

Installation

qtile

Import Qtile Dependencies

from libqtile import layout, bar, widget, hook
from libqtile.config import Key, Drag, Click, Group, Screen, ScratchPad, DropDown
from libqtile.lazy import lazy

Defines

Defines are stored in a separate defines.py file

defines.py Literate File Header
# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)
Terminal

Install Alacritty

alacritty

and set it as default

term = 'alacritty'
Main/Mod Key

This config uses the "Master" or "Windows" Key as Main/Mod Key

mod = 'mod4'

Visual

Colors

Colors are set in the Theming section of this config

Border Width
border_width = 2
Window Margin
window_margin = 5
Floats kept above

Keep floating windows above others

floats_kept_above = True
Automatic Full Screen
auto_fullscreen = True
Automaitc Minimization

If things like steam games want to auto-minimize themselves when losing focus, should we respect this or not?

auto_minimize = True
_NET_ACTIVATE_WINDOW Behavior

Behavior of the _NET_ACTIVATE_WINDOW message sent by applications

  • urgent: urgent flag is set for the window
  • focus: automatically focus the window
  • smart: automatically focus if the window is in the current group
  • never: never automatically focus any window that requests
focus_on_window_activation = 'smart'
Widget Defaults
from chassis_type import ChassisType, chassis_type
from defines import base_color
widget_defaults = dict(
    background=base_color,
    font='UbuntuMono Nerd Font',
    fontsize=18,
    padding=1 if chassis_type == ChassisType.LAPTOP else 5,
)
extension_defaults = widget_defaults.copy()
Bar Sizes and Heights
from chassis_type import ChassisType, chassis_type
main_bar_fontsize=22
main_bar_height=24 if chassis_type == ChassisType.LAPTOP else 28
secondary_bar_height=24
secondary_bar_fontsize=18

Compositor

picom is used to enable window composition, transparency, etc.

Installation
picom
Configuration
# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)
Shadows

disable shadow

shadow = false;
Rounded Corners

exclude Dock and Desktop from corner rounding

rounded-corners-exclude = [
  "window_type = 'dock'",
  "window_type = 'desktop'"
]
Add to Autostart
picom &

Chassis Type Detection

Needed to load correct settings for given hardware (laptop/desktop)

chassis_type.py Literate File Header
# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)
Enum
from enum import Enum
import subprocess

class ChassisType(Enum):
    DESKTOP = 0
    LAPTOP = 1
Detection Function
def detect_chassis_type() -> ChassisType:
    try:
        output = subprocess.check_output(["hostnamectl", "status"], universal_newlines=True)
    except subprocess.CalledProcessError as e:
        print("Error running hostnamectl:", e)
        exit(1)
    return ChassisType.LAPTOP if "Chassis: laptop" in output else ChassisType.DESKTOP

chassis_type = detect_chassis_type()

Mouse Settings

Follow Mouse Focus
follow_mouse_focus = True
Bring to Front with Click
bring_front_click = True
Warp Cursor

Cursor should not jump to the window selected via keyboard

cursor_warp = False

Autostart

import os

@hook.subscribe.startup_once
def autostart():
    home = os.path.expanduser('~/.autostart.sh')
    subprocess.call(['sh', home])

Custom Microphone Widgets

Based on the Volume widget. It requires some packages to be installed

python-psutil
alsa-utils
import subprocess
import psutil
import re

re_vol = re.compile(r'\[(\d?\d?\d?)%\]')
BUTTON_MUTE = 1
class Microphone(widget.base._TextBox):
    """
    Custom Microphone widget
    """
    orientations = widget.base.ORIENTATION_HORIZONTAL
    defaults = [
        ("cardid", None, "Card Id"),
        ("device", "default", "Device Name"),
        ("channel", "Capture", "Channel"),
        ("padding", 3, "Padding left and right. Calculated if None."),
        ("update_interval", 0.2, "Update time in seconds."),
        ("theme_path", None, "Path of the icons"),
        ("emoji", False, "Use emoji to display volume states, only if ``theme_path`` is not set."
                         "The specified font needs to contain the correct unicode characters."),
        ("mute_command", None, "Mute command"),
        ("volume_app", None, "App to control volume"),
        ("volume_up_command", None, "Volume up command"),
        ("volume_down_command", None, "Volume down command"),
        ("get_volume_command", None, "Command to get the current volume"),
        ("step", 2, "Volume change for up an down commands in percentage."
                    "Only used if ``volume_up_command`` and ``volume_down_command`` are not set.")
    ]

    def __init__(self, **config):
        widget.base._TextBox.__init__(self, '0', width=bar.CALCULATED, **config)
        self.add_defaults(Microphone.defaults)
        if self.theme_path:
            self.length_type = bar.STATIC
            self.length = 0
        self.surfaces = {}
        self.volume = None

    def timer_setup(self):
        self.timeout_add(self.update_interval, self.update)
        if self.theme_path:
            self.setup_images()

    def create_amixer_command(self, *args):
        cmd = ['amixer']
        cmd.extend([x for x in args])
        return cmd

    def button_press(self, x, y, button):
        if button == BUTTON_MUTE:
            if self.mute_command is not None:
                subprocess.call(self.mute_command, shell=True)
            else:
                subprocess.call(self.create_amixer_command('-q',
                                                           'sset',
                                                           self.channel,
                                                           'toggle'))
        self.draw()

    def update(self):
        vol = self.get_volume()
        if vol != self.volume:
            self.volume = vol
            # Update the underlying canvas size before actually attempting
            # to figure out how big it is and draw it.
            self._update_drawer()
            self.bar.draw()
        self.timeout_add(self.update_interval, self.update)

    def _update_drawer(self):
        if self.emoji:
            if self.volume > 0:
                self.text = ''
            elif self.volume <= 0:
                self.text = ''
        else:
            if self.volume == -1:
                self.text = 'M'
            else:
                self.text = '{}%'.format(self.volume)
    def get_volume(self):
        try:
            get_volume_cmd = self.create_amixer_command('sget',
                                                        self.channel)

            if self.get_volume_command:
                get_volume_cmd = self.get_volume_command

            mixer_out = self.call_process(get_volume_cmd)
        except subprocess.CalledProcessError:
            return -1

        if '[off]' in mixer_out:
            return -1

        volgroups = re_vol.search(mixer_out)
        if volgroups:
            return int(volgroups.groups()[0])
        else:
            # this shouldn't happen
            return -1

    def draw(self):
        if self.theme_path:
            self.drawer.draw(offsetx=self.offset, width=self.length)
        else:
            widget.base._TextBox.draw(self)

Widget Groups

To simplify the configuration of the Bars widgets are grouped

Imports
from libqtile import widget
from defines import term
from defines import focus_color, light_foreground_color, dark_foreground_color, background_color0, background_color8, base_color
from defines import red_color, light_red_color, green_color, light_green_color, orange_color, yellow_color, light_yellow_color, blue_color, purple_color, light_purple_color, magenta_color, cyan_color
Workspace Status
def workspace_status_widgets(size, fontsize):
    return [
        widget.CurrentLayoutIcon(
            scale = 0.9,
        ),
        widget.TextBox(
            text=' ',
            foreground=light_foreground_color,
            fontsize=fontsize,
            background=blue_color
        ),
        widget.GroupBox(
            fontsize=fontsize,
            rounded=False,
            disable_drag=True,
            active=light_foreground_color,
            inactive=dark_foreground_color,
            highlight_method='block',
            highlight_color=red_color,
            other_screen_border = light_purple_color,
            other_current_screen_border = purple_color,
            this_current_screen_border = blue_color,
            this_screen_border = blue_color,
            urgent_alert_method='block',
            urgent_border = red_color,
        ),
        widget.WindowName(fontsize=fontsize)
    ]
Audio Widgets
def audio_widgets(size, fontsize):
    return[
        widget.Volume(
            foreground=light_foreground_color,
            background=blue_color,
            emoji=True,
            fontsize=fontsize,
            ),
        widget.Volume(
            foreground=light_foreground_color,
            background=blue_color,
            fontsize=fontsize,
            padding=0
            ),
        Microphone(
            foreground=light_foreground_color,
            background=blue_color,
            emoji=True,
            fontsize=fontsize,
        ),
        Microphone(
            foreground=light_foreground_color,
            background=blue_color,
            fontsize=fontsize,
            padding=0
        )
    ]
System Widgets

These change depending on [[Chassis Type Detection][Chassis Type

def system_widgets(size,fontsize):
    sys_widgets = []
    # first widget is battery for laptop and cpu temp otherwise
    if chassis_type == ChassisType.LAPTOP:
        sys_widgets.append(
            widget.Battery(
                foreground=light_foreground_color,
                background=orange_color,
                fontsize=fontsize,
                update_interval=1,
                format="{char} {percent:2.0%}",
                low_percentage=0.2,
                notify_below=True,
                low_foreground=red_color,
                )
        )
    else:
        sys_widgets.extend([
            widget.TextBox(
                text='󰈸',
                foreground=light_foreground_color,
                background=orange_color,
                fontsize=fontsize+6
                ),
            widget.ThermalSensor(
                foreground=light_foreground_color,
                background=orange_color,
                fontsize=fontsize,
                tag_sensor='Tctl',
                )
        ])
    sys_widgets.extend([
        widget.TextBox(
            text=' ',
            foreground=light_foreground_color,
            background=green_color,
            fontsize=fontsize
            ),
        widget.CPU(
            foreground=light_foreground_color,
            background=green_color,
            fontsize=fontsize,
            format='{load_percent}%' if chassis_type == ChassisType.LAPTOP else'{load_percent}% @ {freq_current}GHz',
            ),
        widget.TextBox(
            text='',
            foreground=light_foreground_color,
            background=yellow_color,
            fontsize=fontsize
            ),
        widget.Memory(
            foreground=light_foreground_color,
            background=yellow_color,
            fontsize=fontsize,
            format='{MemUsed: 2.1f}GB|{SwapUsed: 2.1f}GB' if chassis_type == ChassisType.LAPTOP else'{MemUsed: 2.1f}GB({MemPercent: 2.0f}%) | {SwapUsed: 2.1f}GB({SwapPercent: 2.0f}%)',
            measure_mem = 'G',
            measure_swap = 'G',
            ),
        widget.TextBox(
            text='󰈀 ',
            foreground=light_foreground_color,
            background=blue_color,
            fontsize=fontsize
            ),
        widget.Net(
            background=blue_color,
            foreground=light_foreground_color,
            fontsize=fontsize,
            prefix='M',
            format='{down:6.2f}{down_suffix}{up:6.2f}{up_suffix}↑',
            )
        ]
    )
    return sys_widgets
Datetime

These require the DSEG Font

ttf-dseg
def datetime_widgets(size,fontsize):
    return [
        widget.TextBox(
            text='󰸗 ',
            foreground=light_foreground_color,
            background=purple_color,
            fontsize=fontsize
            ),
        widget.Clock(
            foreground=light_foreground_color,
            background=purple_color,
            fontsize=fontsize,
            format='%Y-%m-%d'
            ),
        widget.Clock(
            font='dseg7 classic bold',
            fontsize=16,
            format='%H:%M'
            ),
    ]

Bars

Imports
from libqtile import widget, bar
from defines import base_color, blue_color
from defines import main_bar_fontsize, main_bar_height, secondary_bar_height, secondary_bar_fontsize
Main Bar
main_bar = bar.Bar([
    *workspace_status_widgets(main_bar_height,main_bar_fontsize),
    widget.Systray(fontsize=main_bar_fontsize),
    *audio_widgets(main_bar_height,main_bar_fontsize),
    *system_widgets(main_bar_height,main_bar_fontsize),
    *datetime_widgets(main_bar_height,main_bar_fontsize),
],main_bar_height)
Left Screen Bars
left_bar = bar.Bar([
    *workspace_status_widgets(secondary_bar_height,secondary_bar_fontsize),
    *audio_widgets(secondary_bar_height,secondary_bar_fontsize),
    *datetime_widgets(secondary_bar_height,secondary_bar_fontsize)
],secondary_bar_height)
Secondary Bar
secondary_bar = bar.Bar([
    *workspace_status_widgets(secondary_bar_height,secondary_bar_fontsize),
    *audio_widgets(secondary_bar_height,secondary_bar_fontsize),
    *datetime_widgets(secondary_bar_height,secondary_bar_fontsize)
],secondary_bar_height)
Top Screen Bar
top_bar = bar.Bar([
    *workspace_status_widgets(secondary_bar_height,secondary_bar_fontsize),
    *audio_widgets(secondary_bar_height,secondary_bar_fontsize),
    *datetime_widgets(secondary_bar_height,secondary_bar_fontsize)
],secondary_bar_height)

Screens

Desktop Screen Detection

On my desktop setup I have to special screens that should be detected

main_screen_res = [3440,1440]
top_screen_res = [1440,900]
Getting Screen Information
Dependencies
xorg-xrandr
import subprocess
import re
import numpy as np
from libqtile.config import Screen
Reading the Information
cmd = ['xrandr','--listmonitors']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
resolution_string, junk = p.communicate()
p.stdout.close()
screen_resolutions = re.findall(r'(\d+)/\d+x(\d+)/', str(resolution_string))
max_width = max(screen_resolutions, key=lambda res: res[0])[0]
Setting the Screens
screens = []
defined_main_window = False
for width, height in screen_resolutions:
    if width == main_screen_res[0] and height == main_screen_res[1]:
        screens.append(Screen(top=main_bar, wallpaper= "~/Pictures/Wallpapers/gruvbox-like.jpg", wallpaper_mode="fill"))
        defined_main_window = True
    elif width == top_screen_res[0] and height == top_screen_res[1]:
        screens.append(Screen(bottom=top_bar, wallpaper="~/Pictures/Wallpapers/Xorg.jpg", wallpaper_mode="fill"))
    elif width < height:
        screens.append(Screen(top=left_bar, wallpaper="~/Pictures/Wallpapers/gruvbox-like-left.jpg", wallpaper_mode="fill"))
    elif width == max_width and not defined_main_window:
        screens.append(Screen(top=main_bar, wallpaper= "~/Pictures/Wallpapers/gruvbox-like.jpg", wallpaper_mode="fill"))
        defined_main_window = True
    else:
        screens.append(Screen(top=secondary_bar, wallpaper= "~/Pictures/Wallpapers/gruvbox-like.jpg", wallpaper_mode="fill"))
Automatically Reconfigure Screens

Controls whether or not to automatically reconfigure screens when there are changes in randr output configuration.

reconfigure_screens = True

Layouts

Basic Layouts
from libqtile import layout
from defines import focus_color, border_width, window_margin

layouts = [
    layout.MonadTall(
        align=1,
        border_focus = focus_color,
        border_width =  border_width,
        margin=window_margin,
        new_client_position = 'after_current',
          ),
    layout.Floating(
        border_focus = focus_color,
        border_width =  border_width,
        margin=window_margin,
    ),
    layout.Max(),
    layout.MonadWide(
        border_focus = focus_color,
        border_width =  border_width,
        new_client_position = 'after_current',
        margin=window_margin,
    ),
    layout.Columns(
        border_focus = focus_color,
        border_width = border_width,
        num_columns = 3,
        margin = window_margin,
        )
]
Floating Layout
from libqtile import layout
from libqtile.config import Match
from defines import focus_color, border_width

floating_layout = layout.Floating(
    border_focus = focus_color,
    border_width =  border_width,
    float_rules=[
    # Run the utility of `xprop` to see the wm class and name of an X client.
    ,*layout.Floating.default_float_rules,
    Match(wm_class='confirmreset'),  # gitk
    Match(wm_class='makebranch'),  # gitk
    Match(wm_class='maketag'),  # gitk
    Match(title='branchdialog'),  # gitk
    Match(title='pinentry'),  # GPG key password entry
    Match(wm_class='ssh-askpass'),  # ssh-askpass
    Match(wm_class='sun-awt-X11-XWindowPeer'), #matlab
    Match(wm_class='sun-awt-X11-XDialogPeer'), #matlab
])
Enable Dragging
from libqtile.config import Drag, Click
from libqtile.lazy import lazy
from defines import mod
mouse = [
    Drag([mod], "Button1", lazy.window.set_position_floating(),
         start=lazy.window.get_position()),
    Drag([mod], "Button3", lazy.window.set_size_floating(),
         start=lazy.window.get_size()),
    Click([mod], "Button2", lazy.window.bring_to_front())
]

Groups

Dependencies
from libqtile.config import Group, ScratchPad, DropDown, Key, Match
from libqtile.lazy import lazy

import re

from defines import mod,term
Main Groups
main_groups_info = [(" ","Org",'o',{'layout': 'monadtall'}),
               (" ","Home", 'h',{'layout': 'monadtall'}),
               (" ","Browser", 'f',{'layout': 'monadtall'}),
               ("  ","Mail", 'm',{'layout': 'monadtall', 'matches':[Match(wm_class="Mail")]}),
               (" ","Coding", 'c',{'layout': 'monadtall', 'matches' : [Match(wm_class="code")]}),
               (" ","Documents", 'l',{'layout': 'monadtall'}),
               ("󰝚 ","Music", 'u',{'layout': 'monadtall', 'matches' : [Match(wm_class="spotify")]}),
               (" ","Video", 'v',{'layout': 'monadtall', 'matches' : [Match(wm_class="vlc")]}),
               ("󰙯 ","VideoChat", 'z',{'layout': 'monadtall', 'matches':[Match(wm_class="discord")]}),
               ("一","etc1", '1', {'layout': 'monadtall'}),
               ("二","etc2", '2', {'layout': 'monadtall'}),
               ("三","etc3", '3', {'layout': 'monadtall'}),
               ("四","etc4", '4', {'layout': 'monadtall'})]

groups = [Group(icon, **kwargs) for icon, name, key, kwargs in main_groups_info]
DropDown Groups
dropdown_groups_info = []
ARandR
arandr
name = 'ARandR'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'arandr',
                                    height = 0.5,
                                    width = 0.8,
                                    x = 0.1, # (1-0.8)/2
                                    on_focus_lost_hide=True,
                                    opacity=1,
                                    match = Match(wm_class='arandr')
                                    ),
                           [mod],'p'))
DropDown Terminal
name = 'Terminal'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    term,
                                    height = 0.5,
                                    width = 0.8,
                                    x = .1
                                    ),
                           ['mod1','control'],'space'))
htop
htop
name = 'htop'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    term + ' -e htop'
                                    ),
                           ['control','shift'],'Escape'))
Audio Settings
pavucontrol
name = 'Audio Settings'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'pavucontrol'
                                    ),
                           ['mod1','control'],'a'))
DropDown PCManFM
pcmanfm-gtk3
name = 'filemanager'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'pcmanfm',
                                    on_focus_lost_hide=False,
                                    opacity=1
                                    ),
                           ['mod1','control'],'e'))
Bitwarden
bitwarden
name = 'Bitwarden'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'bitwarden-desktop',
                                    on_focus_lost_hide=False,
                                    match = Match(wm_class='bitwarden')
                                    ),
                           ['mod1','control'],'b'))
WhatsApp
whatsapp-for-linux
name = 'WhatsApp'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'wasistlos',
                                    height = 0.5,
                                    width = 0.8,
                                    x = .1,
                                    on_focus_lost_hide=False,
                                    opacity=1
                                    ),
                           ['mod1','control'],'w'))
Signal
signal-desktop
name = 'Signal'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'signal-desktop',
                                    height = 0.5,
                                    width = 0.8,
                                    x = .1,
                                    on_focus_lost_hide=False,
                                    opacity = 1,
                                    match = Match(wm_class='signal')
                                    ),
                           ['mod1','control'],'i'))
Qalculate!
qalculate-gtk
name = 'Qalculate!'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'qalculate-gtk',
                                    height = 0.5,
                                    width = 0.5,
                                    x = .25,
                                    on_focus_lost_hide=True,
                                    opacity = 1
                                    ),
                           ['mod1','control'],'q'))
Slack
slack-desktop
name = 'Slack'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'slack',
                                    height = 0.5,
                                    width = 0.8,
                                    x = 0.1,
                                    on_focus_lost_hide=False,
                                    opacity=1
                                    ),
                           ['mod1','control'],'s'))
DeepL

DeepL is being used inside a surf DropDown

surf
name = 'DeepL'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'surf deepl.com',
                                    height = 0.5,
                                    width = 0.8,
                                    x = 0.1,
                                    on_focus_lost_hide=True,
                                    opacity=1
                                    ),
                           ['mod1','control'],'d'))
Telegram
telegram-desktop
name = 'Telegram'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'telegram-desktop',
                                    height = 0.5,
                                    width = 0.8,
                                    x = 0.1,
                                    on_focus_lost_hide=False,
                                    opacity=1,
                                    match = Match(wm_class='telegram-desktop')
                                    ),
                           ['mod1','control'],'t'))
Rocket.Chat
name = 'Rocket.Chat'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'rocketchat-desktop',
                                    height = 0.5,
                                    width = 0.8,
                                    x = 0.1,
                                    on_focus_lost_hide=False,
                                    opacity=1,
                                    match = Match(wm_class='rocket.chat')
                                    ),
                           ['mod1','control'],'r'))
Org Agenda
name = 'Org Agenda'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'emacsclient -c -e \'(org-agenda-list)\'',
                                    height = 0.5,
                                    width = 0.8,
                                    x = 0.1,
                                    on_focus_lost_hide=True,
                                    opacity=1,
                                    match = Match(wm_class='emacs')
                                    ),
                           ['mod1','control'],'k'))
GTD Agenda
name = 'GTD Agenda'
dropdown_groups_info.append((name,
                           DropDown(name,
                                    'emacsclient -c -e \'(org-gtd-engage)\'',
                                    height = 0.5,
                                    width = 0.8,
                                    x = 0.1,
                                    on_focus_lost_hide=True,
                                    opacity=1,
                                    match = Match(wm_class='emacs')
                                    ),
                           ['mod1','control'],'g'))
Add ScratchPad to Groups
groups.append(ScratchPad("scratchpad",
   [dropdown for (name,dropdown,base_keys,key) in dropdown_groups_info]
        ))
Hotkeys
Main Group Hotkeys
try:
    _ = keys
except NameError:
    keys = []
for (icon,name,key, kwargs) in main_groups_info:
    keys.extend([
        Key(["mod1","control"], str(key), lazy.group[icon].toscreen(toggle=True),
            desc="Switch to group {}".format(name)),

        Key(['mod1','control', "shift"], str(key), lazy.window.togroup(icon),
            desc="move focused window to group {}".format(name)),
    ])
DropDown Group Hotkeys
try:
    _ = keys
except NameError:
    keys = []
for (name,dropdown,base_keys,key) in dropdown_groups_info:
    keys.extend([
Key(base_keys,key,lazy.group['scratchpad'].dropdown_toggle(name), desc=f'open the dropdown for {name}')
        ])

Keys

from libqtile.config import Key
from libqtile.lazy import lazy

from defines import mod, term
from chassis_type import ChassisType, chassis_type

try:
    _ = keys
except NameError:
    keys = []
Screen Lock
keys.extend([
    Key([mod], "End" , lazy.spawn('dm-tool lock'),desc="locks session"),
    Key([], "Pause" , lazy.spawn('dm-tool lock'),desc="locks session")
])
Moving Focus
keys.extend([
    Key([mod], "h", lazy.layout.left(),desc="move focus left"),
    Key([mod], "l", lazy.layout.right(),desc="move focus right"),
    Key([mod], "j", lazy.layout.down(),desc="move focus down"),
    Key([mod], "k", lazy.layout.up(),desc="move focus up"),
    Key([mod,"mod1"], "n", lazy.next_screen(),desc="move focus to next screen")
])
Moving Windows
keys.extend([
    Key([mod, "shift"], "h", lazy.layout.swap_left(),desc="move focused window left"),
    Key([mod, "shift"], "l", lazy.layout.swap_right(),desc="move focused window right"),
    Key([mod, "shift"], "j", lazy.layout.shuffle_down(),desc="move focused window down"),
    Key([mod, "shift"], "k", lazy.layout.shuffle_up(),desc="move focused window up"),
])
Resize Windows
keys.extend([
    Key([mod], "plus", lazy.layout.grow(),desc="increase window size"),
    Key([mod], "minus", lazy.layout.shrink(),desc="decrease window size"),
    Key([mod], "m", lazy.layout.maximize(),desc="maximize current window"),
    Key([mod], "space", lazy.window.toggle_fullscreen(),desc="toggle current window fullscreen"),
])
Toggle Layouts
keys.extend([
    Key([mod], "Tab", lazy.next_layout(), desc="Toggle between layouts"),
])
Close Current Window
keys.extend([
    Key([mod], "BackSpace", lazy.window.kill(), desc="Kill focused window"),
])
Qtile Meta Commands
keys.extend([
    Key([mod, "control"], "r", lazy.restart(), desc="Restart qtile"),
    Key([mod, "control"], "q", lazy.shutdown(), desc="Shutdown qtile"),
])
Audio
pamixer
keys.extend([
    Key([], 'XF86AudioRaiseVolume', lazy.spawn(f'pamixer -i {5 if chassis_type == ChassisType.LAPTOP else 1}'), desc="increase speaker volume"),
    Key([], 'XF86AudioLowerVolume', lazy.spawn(f'pamixer -d {5 if chassis_type == ChassisType.LAPTOP else 1}'), desc="decrease speaker volume"),
    Key([], 'XF86AudioMute', lazy.spawn('pamixer -t'), desc="toggle speaker mute"),
    Key(['control'], 'XF86AudioRaiseVolume', lazy.spawn(f'amixer set Capture {5 if chassis_type == ChassisType.LAPTOP else 1}%+'), desc="increase mic volume"),
    Key(['control'], 'XF86AudioLowerVolume', lazy.spawn(f'amixer set Capture {5 if chassis_type == ChassisType.LAPTOP else 1}%-'), desc="decrease mic volume"),
    Key(['control'], 'XF86AudioMute', lazy.spawn('amixer set Capture toggle'), desc="toggle mic mute"),
    Key([], 'XF86AudioMicMute', lazy.spawn('amixer set Capture toggle'), desc="toggle mic mute"),
])
Add User to Audio Group
groupname="audio"

# Add the current user to the group if not already a member
if ! groups "$USER" | grep -q "\b$groupname\b"; then
    echo "Adding user $USER to group $groupname"
    sudo usermod -aG "$groupname" "$USER"
    if [ $? -eq 0 ]; then
        echo "User $USER added to group $groupname successfully."
    else
        echo "Failed to add user $USER to group $groupname."
    fi
fi
Media Playback
playerctl
keys.extend([
    Key([], 'XF86AudioNext', lazy.spawn('playerctl next')),
    Key([], 'XF86AudioPrev', lazy.spawn('playerctl previous')),
    Key([], 'XF86AudioPlay', lazy.spawn('playerctl play-pause')),
    Key([mod], 'Right', lazy.spawn('playerctl next')),
    Key([mod], 'Left', lazy.spawn('playerctl previous')),
    Key([mod], 'Down', lazy.spawn('playerctl play-pause')),
])
Monitor Backlight
acpilight
keys.extend([
    Key([], 'XF86MonBrightnessUp', lazy.spawn('xbacklight -inc 5')),
    Key([], 'XF86MonBrightnessDown', lazy.spawn('xbacklight -dec 5')),
])
Add User to Video Group
groupname="video"

# Add the current user to the group if not already a member
if ! groups "$USER" | grep -q "\b$groupname\b"; then
    echo "Adding user $USER to group $groupname"
    sudo usermod -aG "$groupname" "$USER"
    if [ $? -eq 0 ]; then
        echo "User $USER added to group $groupname successfully."
    else
        echo "Failed to add user $USER to group $groupname."
    fi
fi
App Launch Hotkeys
Terminal
keys.extend([
    Key([mod],"t", lazy.spawn(term), desc="Launch terminal"),
])
Firefox
keys.extend([
    Key([mod],"f", lazy.spawn("firefox"),desc="Launch firefox"),
])
PCManFM
pcmanfm-gtk3
keys.extend([
    Key([mod],"e", lazy.spawn("pcmanfm"),desc="Launch pcmanfm"),
])
VSCode
keys.extend([
    Key([mod],"c", lazy.spawn("code"),desc="Launch visual studio code"),
])
NeoVim
keys.extend([
    Key([mod],"v", lazy.spawn(term + " -e nvim"),desc="Launch NeoVim"),
])
Screenshot Tool
gscreenshot
keys.extend([
    Key([mod, "shift"],"s", lazy.spawn('gscreenshot -s -o -f /tmp/screenshots'),desc="take a screenshot"),
])
Doom Emacs
keys.extend([
    Key([mod], "o", lazy.spawn("emacsclient -c -a 'emacs'"), desc="Launch Emacs (Client)"),
])
App Launcher
rofi
keys.extend([
    Key([mod],'Return',lazy.spawn("rofi -show drun -show-icons -modi drun"),desc="launch rofi (drun)"),
])

Misc

Miscelaneous settings from the default config

Deactivate dgroups

dynamic group keys are not needed, because they are assigned manually

dgroups_key_binder = None
dgroups_app_rules = []  # type: List
Setting WM Name

Nobody really uses or cares about this string besides java UI toolkits; you can see several discussions on the mailing lists, GitHub issues, and other WM documentation that suggest setting this string if your java app doesn't work correctly. We may as well just lie and say that we're a working one by default. We choose LG3D to maximize irony: it is a 3D non-reparenting WM written in java that happens to be on java's whitelist.

wmname = 'LG3D'

Dunst

Installation
dunst
Configuration
# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)
Global Configuration
[global]
    ### Display ###
Monitor

display dunst notifications on the main monitor

    monitor = 0
    # Display notification on focused monitor.  Possible modes are:
    #   mouse: follow mouse pointer
    #   keyboard: follow window with keyboard focus
    #   none: don't follow anything
    #
    # "keyboard" needs a window manager that exports the
    # _NET_ACTIVE_WINDOW property.
    # This should be the case for almost all modern window managers.
    #
    # If this option is set to mouse or keyboard, the monitor option
    # will be ignored.
    follow = none
Geometry
    # constant width
    width = 500

    # The height of a single notification, excluding the frame.
    # dynamic
    height = (0, 300)

    # Position the notification in the top right corner
    origin = top-right

    # Offset from the origin
    offset = (10, 50)

    # Scale factor. It is auto-detected if value is 0.
    scale = 0

    # Maximum number of notification (0 means no limit)
    notification_limit = 0

    # Show how many messages are currently hidden (because of
    # notification_limit).
    indicate_hidden = yes
Progress Bar
    # Turn on the progress bar. It appears when a progress hint is passed with
    # for example dunstify -h int:value:12
    progress_bar = true

    # Set the progress bar height. This includes the frame, so make sure
    # it's at least twice as big as the frame width.
    progress_bar_height = 10

    # Set the frame width of the progress bar
    progress_bar_frame_width = 1

    # Set the minimum width for the progress bar
    progress_bar_min_width = 150

    # Set the maximum width for the progress bar
    progress_bar_max_width = 500

    # Corner radius for the progress bar. 0 disables rounded corners.
    progress_bar_corner_radius = 0

    # Define which corners to round when drawing the progress bar. If progress_bar_corner_radius
    # is set to 0 this option will be ignored.
    progress_bar_corners = all

    # Draw a line of "separator_height" pixel height between two
    # notifications.
    # Set to 0 to disable.
    # If gap_size is greater than 0, this setting will be ignored.
    separator_height = 2

    # Padding between text and separator.
    padding = 8

    # Horizontal padding.
    horizontal_padding = 8

    # Padding between text and icon.
    text_icon_padding = 0

    # Defines width in pixels of frame around the notification window.
    # Set to 0 to disable.
    frame_width = 3

    # Size of gap to display between notifications - requires a compositor.
    # If value is greater than 0, separator_height will be ignored and a border
    # of size frame_width will be drawn around each notification instead.
    # Click events on gaps do not currently propagate to applications below.
    gap_size = 0
Icons
    # Corner radius for the icon image.
    icon_corner_radius = 0

    # Define which corners to round when drawing the icon image. If icon_corner_radius
    # is set to 0 this option will be ignored.
    icon_corners = all

    # Recursive icon lookup. You can set a single theme, instead of having to
    # define all lookup paths.
    enable_recursive_icon_lookup = true

    # Set icon theme (only used for recursive icon lookup)
    icon_theme = Adwaita
    # You can also set multiple icon themes, with the leftmost one being used first.
    # icon_theme = "Adwaita, breeze"

    # Align icons left/right/top/off
    icon_position = left

    # Scale small icons up to this size, set to 0 to disable. Helpful
    # for e.g. small files or high-dpi screens. In case of conflict,
    # max_icon_size takes precedence over this.
    min_icon_size = 32

    # Scale larger icons down to this size, set to 0 to disable
    max_icon_size = 128

    # Paths to default icons (only necessary when not using recursive icon lookup)
    icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
Transparency
    # The transparency of the window.  Range: [0; 100].
    # This option will only work if a compositing window manager is
    # present (e.g. xcompmgr, compiz, etc.). (X11 only)
    transparency = 0
Colors
    # Defines color of the frame around the notification window.
    frame_color = "#aaaaaa"

    # Define a color for the separator.
    # possible values are:
    #  * auto: dunst tries to find a color fitting to the background;
    #  * foreground: use the same color as the foreground;
    #  * frame: use the same color as the frame;
    #  * anything else will be interpreted as a X color.
    separator_color = frame
Sorting
    # Sort type.
    # possible values are:
    #  * id: sort by id
    #  * urgency_ascending: sort by urgency (low then normal then critical)
    #  * urgency_descending: sort by urgency (critical then normal then low)
    #  * update: sort by update (most recent always at the top)
    sort = yes
Text
    font = Monospace 8

    # The spacing between lines.  If the height is smaller than the
    # font height, it will get raised to the font height.
    line_height = 0

    # Possible values are:
    # full: Allow a small subset of html markup in notifications:
    #        <b>bold</b>
    #        <i>italic</i>
    #        <s>strikethrough</s>
    #        <u>underline</u>
    #
    #        For a complete reference see
    #        <https://docs.gtk.org/Pango/pango_markup.html>.
    #
    # strip: This setting is provided for compatibility with some broken
    #        clients that send markup even though it's not enabled on the
    #        server. Dunst will try to strip the markup but the parsing is
    #        simplistic so using this option outside of matching rules for
    #        specific applications *IS GREATLY DISCOURAGED*.
    #
    # no:    Disable markup parsing, incoming notifications will be treated as
    #        plain text. Dunst will not advertise that it has the body-markup
    #        capability if this is set as a global setting.
    #
    # It's important to note that markup inside the format option will be parsed
    # regardless of what this is set to.
    markup = full

    # The format of the message.  Possible variables are:
    #   %a  appname
    #   %s  summary
    #   %b  body
    #   %i  iconname (including its path)
    #   %I  iconname (without its path)
    #   %p  progress value if set ([  0%] to [100%]) or nothing
    #   %n  progress value if set without any extra characters
    #   %%  Literal %
    # Markup is allowed
    format = "<b>%s</b>\n%b"

    # Alignment of message text.
    # Possible values are "left", "center" and "right".
    alignment = left

    # Vertical alignment of message text and icon.
    # Possible values are "top", "center" and "bottom".
    vertical_alignment = center

    # Show age of message if message is older than show_age_threshold
    # seconds.
    # Set to -1 to disable.
    show_age_threshold = 60

    # Specify where to make an ellipsis in long lines.
    # Possible values are "start", "middle" and "end".
    ellipsize = middle

    # Ignore newlines '\n' in notifications.
    ignore_newline = no

    # Stack together notifications with the same content
    stack_duplicates = true

    # Hide the count of stacked notifications with the same content
    hide_duplicate_count = false

    # Display indicators for URLs (U) and actions (A).
    show_indicators = yes
History
    # Should a notification popped up from history be sticky or timeout
    # as if it would normally do.
    sticky_history = yes

    # Maximum amount of notifications kept in history
    history_length = 20
Misc/Advanced
    # dmenu path.
    dmenu = /usr/bin/dmenu -p dunst:

    # Browser for opening urls in context menu.
    browser = /usr/bin/xdg-open

    # Always run rule-defined scripts, even if the notification is suppressed
    always_run_script = true

    # Define the title of the windows spawned by dunst (X11 only)
    title = Dunst

    # Define the class of the windows spawned by dunst (X11 only)
    class = Dunst

    # Define the corner radius of the notification window
    # in pixel size. If the radius is 0, you have no rounded
    # corners.
    # The radius will be automatically lowered if it exceeds half of the
    # notification height to avoid clipping text and/or icons.
    corner_radius = 0

    # Define which corners to round when drawing the window. If the corner radius
    # is set to 0 this option will be ignored.
    #
    # Comma-separated list of the corners. The accepted corner values are bottom-right,
    # bottom-left, top-right, top-left, top, bottom, left, right or all.
    corners = all

    # Ignore the dbus closeNotification message.
    # Useful to enforce the timeout set by dunst configuration. Without this
    # parameter, an application may close the notification sent before the
    # user defined timeout.
    ignore_dbusclose = false
Wayland

These settings are Wayland-specific. They have no effect when using X11

    # Uncomment this if you want to let notifications appear under fullscreen
    # applications (default: overlay)
    # layer = top

    # Set this to true to use X11 output on Wayland.
    force_xwayland = false
Legacy
    # Use the Xinerama extension instead of RandR for multi-monitor support.
    # This setting is provided for compatibility with older nVidia drivers that
    # do not support RandR and using it on systems that support RandR is highly
    # discouraged.
    #
    # By enabling this setting dunst will not be able to detect when a monitor
    # is connected or disconnected which might break follow mode if the screen
    # layout changes.
    force_xinerama = false
Mouse Action
    # Defines list of actions for each mouse event
    # Possible values are:
    # * none: Don't do anything.
    # * do_action: Invoke the action determined by the action_name rule. If there is no
    #              such action, open the context menu.
    # * open_url: If the notification has exactly one url, open it. If there are multiple
    #             ones, open the context menu.
    # * close_current: Close current notification.
    # * close_all: Close all notifications.
    # * context: Open context menu for the notification.
    # * context_all: Open context menu for all notifications.
    # These values can be strung together for each mouse event, and
    # will be executed in sequence.
    mouse_left_click = do_action, close_current
    mouse_middle_click = close_current
    mouse_right_click = close_all
Experimental Configurations
# Calculate the dpi to use on a per-monitor basis.
    # If this setting is enabled the Xft.dpi value will be ignored and instead
    # dunst will attempt to calculate an appropriate dpi value for each monitor
    # using the resolution and physical size. This might be useful in setups
    # where there are multiple screens with very different dpi values.
    per_monitor_dpi = false

autorandr

Installation
autorandr
Configuration
Config File Header
#!/bin/sh
# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)
Restart Qtile after switching config
# Qtile restart
sleep 1
qtile cmd-obj -o cmd -f restart

make the postswitch file executable

FILE="$HOME/.config/autorandr/postswitch"

# Check if the file is already executable
if [ ! -x "$FILE" ]; then
  echo "Making $FILE script executable"
  chmod +x "$FILE"
fi

Doom Emacs

Installation

Prerequisites

git
emacs
ripgrep
findutils
fd

Doom Installation

update.sh will install Doom Emacs if needed

if [ ! -d "/home/paul/.config/doom" ]; then
    echo "Installing Doom Emacs ..."
    git clone --depth 1 https://github.com/doomemacs/doomemacs /home/paul/.config/emacs
    /home/paul/.config/emacs/bin/doom install-devel
fi

add to PATH

export PATH=$PATH:~/.config/emacs/bin

Doom Modules

(doom! :input
       ;;bidi              ; (tfel ot) thgir etirw uoy gnipleh
       ;;chinese
       ;;japanese
       ;;layout            ; auie,ctsrnm is the superior home row

       :completion
       (company +tng)          ; the ultimate code completion backend
       ;;helm              ; the *other* search engine for love and life
       ;;ido               ; the other *other* search engine...
       ;;ivy               ; a search engine for love and life
       vertico           ; the search engine of the future

       :ui
       ;;deft              ; notational velocity for Emacs
       doom              ; what makes DOOM look the way it does
       doom-dashboard    ; a nifty splash screen for Emacs
       doom-quit         ; DOOM quit-message prompts when you quit Emacs
       (emoji +unicode)  ; 🙂
       hl-todo           ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
       ;;hydra
       ;;indent-guides     ; highlighted indent columns
       ;;ligatures         ; ligatures and symbols to make your code pretty again
       ;;minimap           ; show a map of the code on the side
       modeline          ; snazzy, Atom-inspired modeline, plus API
       nav-flash         ; blink cursor line after big motions
       ;;neotree           ; a project drawer, like NERDTree for vim
       ophints           ; highlight the region an operation acts on
       (popup +defaults)   ; tame sudden yet inevitable temporary windows
       tabs              ; a tab bar for Emacs
       treemacs          ; a project drawer, like neotree but cooler
       unicode           ; extended unicode support for various languages
       (vc-gutter +pretty) ; vcs diff in the fringe
       vi-tilde-fringe   ; fringe tildes to mark beyond EOB
       ;;window-select     ; visually switch windows
       workspaces        ; tab emulation, persistence & separate workspaces
       ;;zen               ; distraction-free coding or writing

       :editor
       (evil +everywhere); come to the dark side, we have cookies
       file-templates    ; auto-snippets for empty files
       fold              ; (nigh) universal code folding
       ;;(format +onsave)  ; automated prettiness
       ;;god               ; run Emacs commands without modifier keys
       ;;lispy             ; vim for lisp, for people who don't like vim
       ;;multiple-cursors  ; editing in many places at once
       ;;objed             ; text object editing for the innocent
       ;;parinfer          ; turn lisp into python, sort of
       ;;rotate-text       ; cycle region at point between text candidates
       snippets          ; my elves. They type so I don't have to
       ;;word-wrap         ; soft wrapping with language-aware indent

       :emacs
       dired             ; making dired pretty [functional]
       electric          ; smarter, keyword-based electric-indent
       ;;ibuffer         ; interactive buffer management
       undo              ; persistent, smarter undo for your inevitable mistakes
       vc                ; version-control and Emacs, sitting in a tree

       :term
       ;;eshell            ; the elisp shell that works everywhere
       ;;shell             ; simple shell REPL for Emacs
       ;;term              ; basic terminal emulator for Emacs
       vterm             ; the best terminal emulation in Emacs

       :checkers
       syntax              ; tasing you for every semicolon you forget
       (spell +flyspell +everywhere) ; tasing you for misspelling mispelling
       grammar           ; tasing grammar mistake every you make

       :tools
       ;;ansible
       biblio           ; Writes a PhD for you (citation needed)
       ;;collab            ; buffers with friends
       (debugger +lsp)          ; FIXME stepping through code, to help you add bugs
       ;;direnv
       docker
       ;;editorconfig      ; let someone else argue about tabs vs spaces
       ;;ein               ; tame Jupyter notebooks with emacs
       (eval +overlay)     ; run code, run (also, repls)
       ;;gist              ; interacting with github gists
       lookup              ; navigate your code and its documentation
       lsp               ; M-x vscode
       magit             ; a git porcelain for Emacs
       ;;make              ; run make tasks from Emacs
       ;;pass              ; password manager for nerds
       pdf               ; pdf enhancements
       ;;prodigy           ; FIXME managing external services & code builders
       ;;rgb               ; creating color strings
       ;;taskrunner        ; taskrunner for all your projects
       ;;terraform         ; infrastructure as code
       ;;tmux              ; an API for interacting with tmux
       tree-sitter       ; syntax and parsing, sitting in a tree...
       ;;upload            ; map local to remote projects via ssh/ftp

       :os
       (:if IS-MAC macos)  ; improve compatibility with macOS
       ;;tty               ; improve the terminal Emacs experience

       :lang
       ;;agda              ; types of types of types of types...
       ;;beancount         ; mind the GAAP
       (cc +lsp +tree-sitter)         ; C > C++ == 1
       ;;clojure           ; java with a lisp
       ;;common-lisp       ; if you've seen one lisp, you've seen them all
       ;;coq               ; proofs-as-programs
       ;;crystal           ; ruby at the speed of c
       ;;csharp            ; unity, .NET, and mono shenanigans
       ;;data              ; config/data formats
       ;;(dart +flutter)   ; paint ui and not much else
       ;;dhall
       ;;elixir            ; erlang done right
       ;;elm               ; care for a cup of TEA?
       emacs-lisp        ; drown in parentheses
       ;;erlang            ; an elegant language for a more civilized age
       ;;ess               ; emacs speaks statistics
       ;;factor
       ;;faust             ; dsp, but you get to keep your soul
       ;;fortran           ; in FORTRAN, GOD is REAL (unless declared INTEGER)
       ;;fsharp            ; ML stands for Microsoft's Language
       ;;fstar             ; (dependent) types and (monadic) effects and Z3
       ;;gdscript          ; the language you waited for
       ;;(go +lsp)         ; the hipster dialect
       ;;(graphql +lsp)    ; Give queries a REST
       ;;(haskell +lsp)    ; a language that's lazier than I am
       ;;hy                ; readability of scheme w/ speed of python
       ;;idris             ; a language you can depend on
       json              ; At least it ain't XML
       ;;(java +lsp)       ; the poster child for carpal tunnel syndrome
       ;;javascript        ; all(hope(abandon(ye(who(enter(here))))))
       ;;julia             ; a better, faster MATLAB
       ;;kotlin            ; a better, slicker Java(Script)
       (latex +fold +latexmk +lsp)             ; writing papers in Emacs has never been so fun
       ;;lean              ; for folks with too much to prove
       ;;ledger            ; be audit you can be
       lua               ; one-based indices? one-based indices
       ;; markdown          ; writing docs for people to ignore
       ;;nim               ; python + lisp at the speed of c
       ;;nix               ; I hereby declare "nix geht mehr!"
       ;;ocaml             ; an objective camel
       (org +roam2 +dragndrop +pretty +present)               ; organize your plain life in plain text
       ;;php               ; perl's insecure younger brother
       ;;plantuml          ; diagrams for confusing people more
       ;;purescript        ; javascript, but functional
       (python +conda +lsp +pyright +pyenv +tree-sitter)            ; beautiful is better than ugly
       ;;qt                ; the 'cutest' gui framework ever
       ;;racket            ; a DSL for DSLs
       ;;raku              ; the artist formerly known as perl6
       ;;rest              ; Emacs as a REST client
       ;;rst               ; ReST in peace
       ;;(ruby +rails)     ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
       ;;(rust +lsp)       ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
       ;;scala             ; java, but good
       ;;(scheme +guile)   ; a fully conniving family of lisps
       sh                ; she sells {ba,z,fi}sh shells on the C xor
       ;;sml
       ;;solidity          ; do you need a blockchain? No.
       ;;swift             ; who asked for emoji variables?
       ;;terra             ; Earth and Moon in alignment for performance.
       ;;web               ; the tubes
       yaml              ; JSON, but readable
       ;;zig               ; C, but simpler

       :email
       (mu4e +org +gmail)
       ;;notmuch
       ;;(wanderlust +gmail)

       :app
       calendar
       ;;emms
       ;;everywhere        ; *leave* Emacs!? You must be joking
       ;;irc               ; how neckbeards socialize
       ;;(rss +org)        ; emacs as an RSS reader
       ;;twitter           ; twitter client https://twitter.com/vnought

       :config
       ;; literate
       (default +bindings +smartparens))

General Configuration

User Information

(setq user-full-name "Paul Lödige"
      user-mail-address "paul@gve-loedige.de")

Visual Settings

Font

install Ubuntu Mono

ttf-ubuntu-font-family
ttf-ubuntu-mono-nerd
ttf-ubuntu-nerd
adobe-source-han-sans-jp-fonts
adobe-source-han-serif-jp-fonts
noto-fonts-emoji

and activate it

(setq doom-font (font-spec :family "Ubuntu Mono" :size 16)
      doom-variable-pitch-font (font-spec :family "Ubuntu" :size 14))
Line Numbering

having used Neovim for quiet some time I got used to relative line numbering for navigation. Until I get used to the evil-snipe navigation I would like to keep them.

(setq display-line-numbers-type 'relative)

Authentication

Authentication information will be stored in a encrypted file that is part of my dotfiles

(setq auth-sources
    '((:source "~/.authinfo.gpg")))
:source ~/.authinfo.gpg

Start Daemon on Startup

emacs --daemon &

Misc

Set Start of Week to Monday
(setq calendar-week-start-day 1)

Multilanguage Spellcheck

Enables use of multiple dictionaries. In my case German and English install dependencies

hunspell
hunspell-de
hunspell-en_us

and configure it

(with-eval-after-load "ispell"
  (setq ispell-program-name "hunspell")
  (setq ispell-dictionary "en_US,de_DE")
  (ispell-set-spellchecker-params)
  (ispell-hunspell-add-multi-dic "en_US,de_DE"))

LaTeX

Set PDF Viewer

(setq +latex-viewers '(zathura))

Add shell-escape Toggle Command

(defun TeX-command-toggle-shell-escape ()
  (interactive)
  (setq TeX-command-extra-options
        (cond ((string-match-p "\\_<--shell-escape\\_>" TeX-command-extra-options )
               (replace-regexp-in-string "\\_<--shell-escape\\_>" "" TeX-command-extra-options))
              ((string-empty-p TeX-command-extra-options)"--shell-escape")
              (t(format "--shell-escape %s" TeX-command-extra-options))))
  (message "TeX-command-extra-options : `%s'" TeX-command-extra-options))

E-Mail

isync

Installation

isync git is needed to deal with a current bug

isync-git
mbsync Configuration
paul@ploedige.com
# Account Information
IMAPAccount ploedige
Host imap.mail.yahoo.com
User ploedige@yahoo.com
PassCmd "gpg --quiet --for-your-eyes-only --no-tty --decrypt ~/.dotfiles/.mbsync-pw-ploedige.gpg"
AuthMechs LOGIN
TLSType IMAPS

# Remote Storage
IMAPStore ploedige-remote
Account ploedige

# Local Storage
MaildirStore ploedige-local
Path ~/mail/ploedige/
Inbox ~/mail/ploedige/INBOX
SubFolders Verbatim

# Connections
Channel ploedige
Far :ploedige-remote:
Near :ploedige-local:
Patterns *
Create Both
Expunge Both
SyncState *
create mail directory if not yet exists
MAILDIR_PATH="$HOME/mail/ploedige"
if [ ! -d "$MAILDIR_PATH" ]; then
    mkdir -p "$MAILDIR_PATH"
fi

mu

Installation
mu
Initialize if needed
MAILDIR_PATH="$HOME/mail/ploedige"
if [ ! -d "$HOME/.cache/mu" ]; then
    echo "Initializing mu!"
    mu init --maildir="$MAILDIR_PATH" --my-address paul@ploedige.com --my-address ploedige@yahoo.com
    mu index
fi

Setup Emacs

(after! mu4e
  (set-email-account! "ploedige.com"
        '((mu4e-sent-folder     . "/Sent")
          (mu4e-drafts-folder   . "/Draft")
          (mu4e-trash-folder    . "/Trash")
          (mu4e-refile-folder   . "/Bulk")
          (smtpmail-smtp-user   . "ploedige@yahoo.com"))
        t))

msmtp Installation

msmtp
recommended config
(after! mu4e
  (setq sendmail-program (executable-find "msmtp")
	send-mail-function #'smtpmail-send-it
	message-sendmail-f-is-evil t
	message-sendmail-extra-arguments '("--read-envelope-from")
	message-send-mail-function #'message-send-mail-with-sendmail))

Org Mode

Dependencies

xclip
gnome-screenshot
graphviz

Default Location

(setq org-directory "~/org/")

Visual

Header Styling
Enable Header Numbering
(after! org
  (setq org-startup-numerated t))
Header Font Sizes
(after! org
  (custom-set-faces
   (set-face-attribute 'org-document-title nil :height 2.0)
   '(org-level-1 ((t(:inherit outline-1 :height 1.5))))
   '(org-level-2 ((t(:inherit outline-2 :height 1.3))))
   '(org-level-3 ((t(:inherit outline-3 :height 1.2))))
   '(org-level-4 ((t(:inherit outline-4 :height 1.1))))))
Misc Text Styling
Hide Emphasis Markers

bold italic strikethrough etc. should not have markers next to them

(after! org
  (setq org-hide-emphasis-markers t))
Image Display as Default

this stackexchange comment states that this has to be done before the adding the ~/org directory to Org Agenda

(after! org
  (setq org-startup-with-inline-images t)
  (setq org-image-actual-width '(600)))
Open Video in VLC

this requires the OpenWith minor mode and VLC

(package! openwith)
vlc

then the configuration from this reddit post can be used to achieve the desired behavior

(after! openwith
  (setq openwith-associations
        (cond
         ((string-equal system-type "darwin")
          '(("\\.\\(dmg\\|doc\\|docs\\|xls\\|xlsx\\)$"
             "open" (file))
            ("\\.\\(mp4\\|mp3\\|webm\\|avi\\|flv\\|mov\\)$"
             "open" ("-a" "VLC" file))))
         ((string-equal system-type "gnu/linux")
          '(("\\.\\(mp4\\|mp3\\|webm\\|avi\\|flv\\|mov\\)$"
             "xdg-open" (file))))))
  (openwith-mode +1))
Enable $\LaTeX$ preview on default
(after! org
  (setq org-startup-latex-with-latex-preview t))
Fix $\LaTeX$ block alignment in tables with valign

install valign

(package! valign)

and start it automatically in org mode

(after! org
  (add-hook 'org-mode-hook #'valign-mode))

CalDAV Sync

org-caldav provides a tool for syncing with a CalDAV server (in my case Nextcloud). A lot of the config is also taken from this reddit post.

org-caldav installation
(package! org-caldav)
Enable TODOs
(after! org-caldav
  (setq org-icalendar-include-todo 'all
    org-caldav-sync-todo t))
Configure Sync

add the calendars to the org-caldav config

(after! org-caldav
  (setq org-caldav-url "https://cloud.ploedige.com/remote.php/dav/calendars/paul-loedige")
  (setq org-caldav-sync-direction 'org->cal)
  (setq org-caldav-calendars
        '((:calendar-id "todo" :files ("~/org/todo.org")))))

Org Agenda Setup

Progress States

To get a more nuanced overview of my current TODOs I add more progress states.

INACTIVE TODO BLOCKED IN_PROGRESS REVIEW TESTING DONE DELEGATED CANCELED
Access Key i t b i r t d c
Log Type time time note time note note time note note
(after! org
  (setq org-todo-keywords
        '((sequence "INACTIVE(i!)" "TODO(t!)" "IN_PROGRESS(p!)" "BLOCKED(b@)" "REVIEW(r@)" "TESTING(e@)" "|" "DONE(d!)" "DELEGATED(x@)" "CANCELED(c@)"))))

Also set the percent states for CalDAV Sync

(after! org-caldav
  (setq org-caldav-todo-percent-states '((0 "INACTIVE") (1 "TODO") (2 "IN_PROGRESS") (3 "BLOCKED") (90 "REVIEW") (90 "TESTING") (100 "DONE") (100 "DELEGATED") (100 "CANCELED"))))
Add "~/org" to Agenda
(after! org
  (setq org-agenda-files (f-files "~/org"
                                  (lambda (f)
                                    (string= (f-ext f) "org"))
                                  'recursive)))
Styling
Priorities

using org-fancy-priorites the displayed priorities can be styled

(after! org-fancy-priorities
  (setq org-fancy-priorities-list '((?A . "HIGH")
                                    (?B . "MID")
                                    (?C . "LOW")
                                    (?D . "OPTIONAL"))))

Org Roam

set base directory

Both the org files themselves and the database should be located in the same directory to enable syncing via Nextcloud

(after! org
  (setq org-roam-directory (file-truename "~/org/org-roam"))
  (org-roam-db-autosync-mode))
Note Templates

This contains all the capture templates I am using. Adding the "#+category: " tag improves the Org Agenda View for tasks captured in Org Roam

(after! org-roam
  (setq org-roam-capture-templates
  '(("d" "default" plain
      "%?"
      :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+category: ${title}\n")
      :unnarrowed t)
    ("m" "Master Thesis Templates")
    ("md" "Default Master Thesis Template" plain
      "%?"
      :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+category: Master Thesis\n")
      :unnarrowed t)
    ("mm" "Master Thesis Meeting Template" plain
      "* Current Progress\n\n* Open Questions\n\n* TODOs\n"
      :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title} Master Thesis Meeting\n#+category: Master Thesis\n")
      :unnarrowed t)
    )))
Misc
Follow Links on RET

Because the normal shortcut for `org-open-at-point` is quite cumbersome I want it to just follow links when clicking the RET button

(after! org
  (setq return-follows-link t))

Org-GTD

Installation
(package! org-gtd)
Configuration
(setq org-gtd-update-ack "3.0.0")
(use-package! org-gtd
  :after org
  :config
  (setq org-gtd-directory "~/org/org-gtd/")
  (setq org-edna-use-inheritance t)
  (org-edna-mode)
  (map! :leader
        (:prefix ("d" . "org-gtd")
         :desc "Capture"        "c"  #'org-gtd-capture
         :desc "Engage"         "e"  #'org-gtd-engage
         :desc "Process inbox"  "p"  #'org-gtd-process-inbox
         :desc "Show all next"  "n"  #'org-gtd-show-all-next
         :desc "Stuck projects" "s"  #'org-gtd-review-stuck-projects))
  (map! :map org-gtd-clarify-map
        :desc "Organize this item" "C-c c" #'org-gtd-organize))

Org Transclusion

Installation
(package! org-transclusion)

Bibliography

Enabling Zotero Links
zotero

Following this guide we enable using zotero links with the following code

(after! org
  :custom
  (org-link-set-parameters "zotero" :follow
                           (lambda (zpath)
                             (browse-url
                              (format "zotero:%s" zpath)))))
Citar Config
Setting the Citar Bibliography

Following the Doom Emacs documentation we set the citar bibliography and notes paths

(after! oc
  (setq citar-bibliography '("~/org/biblio.bib"))
  (setq citar-notes-paths '("~/org/org-roam/")))
Citar Templates

Following the citar package documentation we modify the note template to contain the pdf link to Zotero NOTE: This requires the a specific Zotero Export Configuration

(after! oc
  (setq citar-templates
      '((main . "${author editor:30%sn}     ${date year issued:4}     ${title:48}")
        (suffix . "          ${=key= id:15}    ${=type=:12}    ${tags keywords:*}")
        (preview . "${author editor:%etal} (${year issued date}) ${title}, ${journal journaltitle publisher container-title collection-title}.\n")
        (note . "Notes on ${author editor:%etal}, ${title}\npdf: ${file}"))))
Enable Zotero Link Support

In this tutorial I found the config for enabling Zotero Link Support through Citar

(after! citar
  (defadvice! riccardo/citar-file-trust-zotero (oldfun &rest r)
    "Leave Zotero-generated file paths alone, especially zotero://..."
    :around '(citar-file-open citar-file--find-files-in-dirs)
    (cl-letf (((symbol-function 'file-exists-p) #'always)
              ((symbol-function 'expand-file-name) (lambda (first &rest _) first)))
      (apply oldfun r)))

  (add-to-list 'citar-file-open-functions '("pdf" . citar-file-open-external)))

Poly-Org

Polymode for Org

(package! poly-org)
;; (after! org
;;   (require 'poly-org))

Polymode

Polymode enables using multiple major modes inside a single buffer. This is especially useful for Org Mode as it allows for better code editing inside code blocks

(package! polymode)

Python

install dependencies

python-isort
python-pipenv
python-pytest
pyright

Set Debugger to debugpy

as per the Doom Emacs Documentation it is recommended to set the debugger used for python debugging to debugpy

(after! dap-mode
  (setq dap-python-debugger 'debugpy))

Text Editors

VSCode

Installation

visual-studio-code-bin

Add-On Configuration

Config File Header
# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)
Basic Look & Feel Extensions
Vim Key Bindings
vscodevim.vim
Useful Tools
Path Intellisense
christian-kohler.path-intellisense
Spellcheck
streetsidesoftware.code-spell-checker
Github Copilot
github.copilot
github.copilot-chat
Configure to use the gnome-keyring

As desribed in this Github issue it is sometimes necessary to modify VSCode's argv.json

// DO NOT EDIT THIS FILE DIRECTLY
// This is a file generated from a literate programing source file
// You should make any changes there and regenerate it from Emacs org-mode
// using org-babel-tangle (C-c C-v t)

{
	// Use software rendering instead of hardware accelerated rendering.
	// This can help in cases where you see rendering issues in VS Code.
	// "disable-hardware-acceleration": true,

	// Allows to disable crash reporting.
	// Should restart the app if the value is changed.
	"enable-crash-reporter": true,

	// Unique id used for correlating crash reports sent from this instance.
	// Do not edit this value.
	"crash-reporter-id": "bbaa03bf-7872-4c27-8488-3543d3064c9d",

    // enable gnome-keyring
    "password-store": "gnome-libsecret"
}
ROS Development
ms-vscode-remote.remote-containers
ms-vscode-remote.remote-ssh
ms-vscode.remote-server
ms-vscode.cpptools-extension-pack
ms-iot.vscode-ros
ms-vscode.cpptools
ms-vscode.cmake-tools
Languages
Python
ms-python.python
donjayamanne.python-environment-manager
ms-python.debugpy
ms-python.vscode-pylance
njpwerner.autodocstring

Jupyter is also considered here

ms-toolsai.jupyter
ms-toolsai.jupyter-keymap
ms-toolsai.jupyter-renderers
ms-toolsai.vscode-jupyter-cell-tags
ms-toolsai.vscode-jupyter-slideshow
Docker
ms-azuretools.vscode-docker

Add-On Sync

remove all packages not in vscode-extensions.txt and install otherwise

INSTALLED_EXTENSIONS=$(code --list-extensions)
KEEP_LIST=$(grep -v '^#' "vscode-extensions.txt")

for EXTENSION in $INSTALLED_EXTENSIONS; do
    if ! echo "$KEEP_LIST" | grep -q "^$EXTENSION$"; then
        echo "Removing VS Code Extension: $EXTENSION"
        code --uninstall-extension "$EXTENSION"
    fi
done
for EXTENSION in $KEEP_LIST; do
    if ! echo "$INSTALLED_EXTENSIONS" | grep -q "^$EXTENSION$"; then
        echo "Installing VS Code Extension: $EXTENSION"
        code --install-extension "$EXTENSION"
    fi
done

NeoVim

NeoVim Documentation

Installation

neovim
python-pynvim
tree-sitter-cli

additionally npm is needed for Conquer on Completion

npm

TODO Configuration

this is not the proper way to do it

if [ ! -L "$HOME/.config/nvim" ]; then
    echo "Installing Neovim Config..."
    ln -s ~/.dotfiles/neovim/.config/nvim ~/.config/nvim
    ln -s ~/.dotfiles/neovim/.config/coc ~/.config/coc
fi

Browser

Firefox

Installation

firefox

*

TODO Configuration

Chromium

It's always good to have a backup browser

Installation

chromium

TOR

torbrowser-launcher

Shells

ZSH is used as the default shell

Aliases

Shutdown and Reboot

alias sn='shutdown now'
alias rb='reboot'

Confirm before overwriting

alias cp="cp -i"
alias mv='mv -i'
alias rm='rm -i'

Git Aliases

git
alias add='git add'
alias addup='git add -u'
alias addall='git add .'
alias branch='git branch'
alias checkout='git checkout'
alias co='git checkout'
alias clone='git clone'
alias commit='git commit -m'
alias fetch='git fetch'
alias pull='git pull origin'
alias push='git push origin'
alias status='git status'
alias diff='git diff'
alias remote='git remote'
alias ftemplate='git fetch template'
alias mtemplate='git merge template/master --allow-unrelated-histories'
alias log='git log'

ls -> eza

eza
alias ls='eza --icons -lF --color=always --group-directories-first --git' # my preferred listing
alias la='eza --icons -aF --color=always --group-directories-first --git'  # all files and dirs
alias ll='eza --icons -alF --color=always --group-directories-first --git'  # long format
alias lt='eza --icons -aTF --color=always --group-directories-first --git' # tree listing
alias lx='eza --icons -lF --color=always --group-directories-first --git --extended' # extended info
alias l.='eza -a | egrep "^\."' # list dotfiles

ZSH

Installation

zsh
which

Set as default shell

if [ "$(basename $SHELL)" != "zsh" ]; then
    chsh -s $(which zsh)
fi

Oh-My-Zsh

Installation
curl

Install if needed Notes: Because the tangled .zshrc already would usually be overwritten it needs to be backed up and restored. Also, the $ZSH variable needs to be unset to avoid errors during installation

if [ ! -d "$HOME/.oh-my-zsh" ]; then
    echo "Backing up .zshrc..."
    mv ~/.zshrc ~/.zshrc-tmp
    echo "Installing Oh-My-Zsh..."
    unset ZSH
    sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
    if [ -e "$HOME/.zshrc.pre-oh-my-zsh" ]; then
        rm ~/.zshrc.pre-oh-my-zsh
    fi
    echo "Restoring .zshrc..."
    mv ~/.zshrc-tmp ~/.zshrc
fi
Basic Configuration
export ZSH="$HOME/.oh-my-zsh"

# Uncomment the following line to use case-sensitive completion.
CASE_SENSITIVE="false"

# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
HYPHEN_INSENSITIVE="true"

# Uncomment the following line to change how often to auto-update (in days).
export UPDATE_ZSH_DAYS=3

# Uncomment the following line to enable command auto-correction.
ENABLE_CORRECTION="true"

# Uncomment the following line to display red dots whilst waiting for completion.
# Caution: this setting can cause issues with multiline prompts (zsh 5.7.1 and newer seem to work)
# See https://github.com/ohmyzsh/ohmyzsh/issues/5765
COMPLETION_WAITING_DOTS="true"
Plugins
Dependencies

some of the following plugins require dependencies

#for bgnotify
libnotify
fd
fzf
github-cli
Symlink External Plugins
conda-zsh-completion
if [ ! -L "$HOME/.oh-my-zsh/custom/plugins/conda-zsh-completion" ]; then
    echo "Installing conda-zsh-completion..."
    if [ ! -d "$HOME/.oh-my-zsh/custom/plugins" ]; then
        mkdir -p ~/.oh-my-zsh/custom/plugins
    fi
    ln -s ~/.dotfiles/zsh/.oh-my-zsh/custom/plugins/conda-zsh-completion ~/.oh-my-zsh/custom/plugins/conda-zsh-completion
fi
zsh-autosuggestions
if [ ! -L "$HOME/.oh-my-zsh/custom/plugins/zsh-autosuggestions" ]; then
    echo "Installing conda-zsh-completion..."
    if [ ! -d "$HOME/.oh-my-zsh/custom/plugins" ]; then
        mkdir -p ~/.oh-my-zsh/custom/plugins
    fi
    ln -s ~/.dotfiles/zsh/.oh-my-zsh/custom/plugins/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions
fi
zsh-syntax-highlighting
if [ ! -L "$HOME/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting" ]; then
    echo "Installing conda-zsh-completion..."
    if [ ! -d "$HOME/.oh-my-zsh/custom/plugins" ]; then
        mkdir -p ~/.oh-my-zsh/custom/plugins
    fi
    ln -s ~/.dotfiles/zsh/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting
fi
Install Plugins
# Which plugins would you like to load?
# Standard plugins can be found in $ZSH/plugins/
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(
    adb
    aliases
    archlinux
    bgnotify
    colored-man-pages
    command-not-found
    docker
    docker-compose
    emacs
    extract
    fd
    gh
    git
    git-auto-fetch
    git-lfs
    isodate
    nmap
    pip
    pipenv
    python
    ripgrep
    rsync
    svn
    systemd
    themes
    vi-mode
    vscode
    # # non oh-my-zsh plugins
    zsh-autosuggestions
    zsh-syntax-highlighting
    conda-zsh-completion
)
Powerlevel10k

create symlink if needed

if [ ! -L "$HOME/.oh-my-zsh/custom/themes/powerlevel10k" ]; then
    echo "Installing Powerlevel10k..."
    if [ ! -d "$HOME/.oh-my-zsh/custom/themes" ]; then
        mkdir -p ~/.oh-my-zsh/custom/themes
    fi
    ln -s ~/.dotfiles/zsh/.oh-my-zsh/custom/themes/powerlevel10k ~/.oh-my-zsh/custom/themes/powerlevel10k
fi

init

ZSH_THEME="powerlevel10k/powerlevel10k"
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
Config

create symlink if needed. The config file was created via the p10k configure command

if [ ! -L "$HOME/.p10k.zsh" ]; then
    echo "Configuring Powerlevel10k..."
    ln -s ~/.dotfiles/zsh/.p10k.zsh ~/.p10k.zsh
fi
Source oh-my-zsh
source $ZSH/oh-my-zsh.sh

Configuration

Source Aliases
source ~/.alias.sh
Modify PATH
source ~/.path.sh
neofetch

install

neofetch

and start

neofetch

Bash

Installation

bash

Configuration

Source Aliases
source ~/.alias.sh
Modify PATH
source ~/.path.sh
neofetch

install

neofetch

and start

neofetch

Alacritty

Font

[font]
size = xx

[font.bold]
family = "UbuntuMonoNerdFont"
style = "Bold"

[font.bold_italic]
family = "UbuntuMonoNerdFont"
style = "Bold Italic"

[font.italic]
family = "UbuntuMonoNerdFont"
style = "Italic"

[font.normal]
family = "UbuntuMonoNerdFont"
style = "Regular"

The size is set via the autostart script depending on the system type (Laptop/Desktop)

# Use hostnamectl to get system information
chassis_type=$(hostnamectl status | grep "Chassis:" | awk '{print $2}')
# Check if the chassis type is "laptop"
if [ "$chassis_type" == "laptop" ]; then
    # set font size for alacritty
    sed -i 's/size = xx/size = 9/' ~/.config/alacritty/alacritty.toml
else
    # set font size for alacritty
    sed -i 's/size = xx/size = 14/' ~/.config/alacritty/alacritty.toml
fi

since update.sh will reset the font size value. This also needs to be set in there

# Use hostnamectl to get system information
chassis_type=$(hostnamectl status | grep "Chassis:" | awk '{print $2}')
# Check if the chassis type is "laptop"
if [ "$chassis_type" == "laptop" ]; then
    # set font size for alacritty
    sed -i 's/size = xx/size = 9/' ~/.config/alacritty/alacritty.toml
else
    # set font size for alacritty
    sed -i 's/size = xx/size = 14/' ~/.config/alacritty/alacritty.toml
fi

Theming

This Config applies the Gruvbox Theme to as many programs as possible

Doom Emacs

Install specific package

(package! gruvbox-theme)

and then set it

(setq doom-theme 'gruvbox-dark-hard)

VSCode

jdinhlife.gruvbox

Qtile

focus_color = '#076678'

light_foreground_color = ['#fbf1c7','#fbf1c7']
dark_foreground_color = ['#282828','#282828']
background_color0  = ['#1d2021','#1d2021']
background_color8  = ['#7c6f64','#7c6f64']
base_color = background_color0
# red
red_color = ['#cc241d','#cc241d']
light_red_color  = ['#fb4934','#fb4934']
# green
green_color = ['#98971a','#98971a']
light_green_color  = ['#b8bb26','#b8bb26']
#orange
orange_color = ['#d65d0e','#d65d0e']
# yellow
yellow_color  = ['#d79921','#d79921']
light_yellow_color = ['#fabd2f','#fabd2f']
#blue
blue_color = ['#076678','#076678']
# purple
purple_color  = ['#b16286','#b16286']
light_purple_color  = ['#d3869b','#d3869b']
# magenta
magenta_color  = ['#ff79c6','#ff79c6']
# cyan
cyan_color  = ['#8be9fd','#8be9fd']

Alacritty

[colors.bright]
black = "#928374"
blue = "#83a598"
cyan = "#8ec07c"
green = "#b8bb26"
magenta = "#d3869b"
red = "#fb4934"
white = "#ebdbb2"
yellow = "#fabd2f"

[colors.cursor]
cursor = "CellForeground"
text = "CellBackground"

[colors.dim]
black = "#32302f"
blue = "#076678"
cyan = "#427b58"
green = "#79740e"
magenta = "#8f3f71"
red = "#9d0006"
white = "#928374"
yellow = "#b57614"

[colors.normal]
black = "#282828"
blue = "#458588"
cyan = "#689d6a"
green = "#98971a"
magenta = "#b16286"
red = "#cc241d"
white = "#a89984"
yellow = "#d79921"

[colors.primary]
background = "#282828"
bright_foreground = "#f9f5d7"
dim_foreground = "#f2e5bc"
foreground = "#fbf1c7"

[colors.selection]
background = "CellForeground"
text = "CellBackground"

[colors.vi_mode_cursor]
cursor = "CellForeground"
text = "CellBackground"

Xorg

! DO NOT EDIT THIS FILE DIRECTLY
! This is a file generated from a literate programing source file
! You should make any changes there and regenerate it from Emacs org-mode
! using org-babel-tangle (C-c C-v t)

! -----------------------------------------------------------------------------
! File: gruvbox-dark.xresources
! Description: Retro groove colorscheme generalized
! Author: morhetz <morhetz@gmail.com>
! Source: https://github.com/morhetz/gruvbox-generalized
! Last Modified: 6 Sep 2014
! -----------------------------------------------------------------------------

! hard contrast: *background: #1d2021
*background: #282828
! soft contrast: *background: #32302f
*foreground: #ebdbb2
! Black + DarkGrey
*color0:  #282828
*color8:  #928374
! DarkRed + Red
*color1:  #cc241d
*color9:  #fb4934
! DarkGreen + Green
*color2:  #98971a
*color10: #b8bb26
! DarkYellow + Yellow
*color3:  #d79921
*color11: #fabd2f
! DarkBlue + Blue
*color4:  #458588
*color12: #83a598
! DarkMagenta + Magenta
*color5:  #b16286
*color13: #d3869b
! DarkCyan + Cyan
*color6:  #689d6a
*color14: #8ec07c
! LightGrey + White
*color7:  #a89984
*color15: #ebdbb2

GTK

gruvbox-dark-gtk
papirus-icon-theme

GTK 3

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

[Settings]
gtk-icon-theme-name = Papirus-Dark
gtk-theme-name = gruvbox-dark-gtk
gtk-font-name = UbuntuMono Nerd Font 11

GTK 4

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

[Settings]
gtk-icon-theme-name = Papirus-Dark
gtk-theme-name = gruvbox-dark-gtk
gtk-font-name = UbuntuMono Nerd Font 11

Rofi

/*
  DO NOT EDIT THIS FILE DIRECTLY
  This is a file generated from a literate programing source file
  You should make any changes there and regenerate it from Emacs org-mode
  using org-babel-tangle (C-c C-v t)
*/
/* ==========================================================================
   Rofi color theme

   Based on the Gruvbox color scheme for Vim by morhetz
   https://github.com/morhetz/gruvbox

   File: gruvbox-dark-hard.rasi
   Desc: Gruvbox dark (hard contrast) color theme for Rofi
   Author: bardisty <b@bah.im>
   Source: https://github.com/bardisty/gruvbox-rofi
   Modified: Mon Feb 12 2018 06:04:26 PST -0800
   ========================================================================== */

*{
    font: "Ubuntu Mono Nerd Font 16";
    /* Theme settings */
    highlight: bold italic;
    scrollbar: true;

    /* Gruvbox dark colors */
    gruvbox-dark-bg0-hard:     #1d2021;
    gruvbox-dark-bg0:          #282828;
    gruvbox-dark-bg2:          #504945;
    gruvbox-dark-fg0:          #fbf1c7;
    gruvbox-dark-fg1:          #ebdbb2;
    gruvbox-dark-red-dark:     #cc241d;
    gruvbox-dark-red-light:    #fb4934;
    gruvbox-dark-yellow-dark:  #d79921;
    gruvbox-dark-yellow-light: #fabd2f;
    gruvbox-dark-gray:         #a89984;

    /* Theme colors */
    background:                  @gruvbox-dark-bg0-hard;
    background-color:            @background;
    foreground:                  @gruvbox-dark-fg1;
    border-color:                @gruvbox-dark-gray;
    separatorcolor:              @border-color;
    scrollbar-handle:            @border-color;

    normal-background:           @background;
    normal-foreground:           @foreground;
    alternate-normal-background: @gruvbox-dark-bg0;
    alternate-normal-foreground: @foreground;
    selected-normal-background:  @gruvbox-dark-bg2;
    selected-normal-foreground:  @gruvbox-dark-fg0;

    active-background:           @gruvbox-dark-yellow-dark;
    active-foreground:           @background;
    alternate-active-background: @active-background;
    alternate-active-foreground: @active-foreground;
    selected-active-background:  @gruvbox-dark-yellow-light;
    selected-active-foreground:  @active-foreground;

    urgent-background:           @gruvbox-dark-red-dark;
    urgent-foreground:           @background;
    alternate-urgent-background: @urgent-background;
    alternate-urgent-foreground: @urgent-foreground;
    selected-urgent-background:  @gruvbox-dark-red-light;
    selected-urgent-foreground:  @urgent-foreground;
}

@import "gruvbox-common.rasi"

Dunst Urgency Levels

Low Urgency

[urgency_low]
    background = "#282828"
    foreground = "#928374"
    timeout = 10

Normal Urgency

[urgency_normal]
    background = "#076678"
    foreground = "#fbf1c7"
    timeout = 10
    override_pause_level = 30

Critical Urgency

[urgency_critical]
    background = "#9d0006"
    foreground = "#fbf1c7"
    frame_color = "#cc241d"
    timeout = 0
    override_pause_level = 60

Bluetooth

Installation

bluez
bluez-utils

Activate systemd Service

systemd_service="bluetooth"
if ! systemctl is-enabled --quiet "$systemd_service"; then
    echo "Enabling $systemd_service"
    sudo systemctl enable "$systemd_service"
    sudo systemctl start "$systemd_service"
fi

Blueman Applet

Installtion

blueman

Autostart

blueman-applet &

Space Mouse Support

spnavcfg

Daemon

systemd_service="spacenavd"
if ! systemctl is-enabled --quiet "$systemd_service"; then
    echo "Enabling $systemd_service"
    sudo systemctl enable "$systemd_service"
    sudo systemctl start "$systemd_service"
fi

Git

Installation

git

Configuration

Literate Header

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

User

[user]
    name = paul-loedige
    email = 59517210+ploedige@users.noreply.github.com

Default Branch

[init]
    defaultBranch = main

Git LFS

git-lfs

Meld

meld

Miniconda

Installation

miniconda3

universal link

if [ ! -e "/etc/profile.d/conda.sh" ]; then
    sudo ln -s /opt/miniconda3/etc/profile.d/conda.sh /etc/profile.d/conda.sh
fi

add to path

source /etc/profile.d/conda.sh
export PATH="$PATH:/opt/miniconda3/bin"

ZSH special settings

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/opt/miniconda3/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/opt/miniconda3/etc/profile.d/conda.sh" ]; then
        . "/opt/miniconda3/etc/profile.d/conda.sh"
    else
        export PATH="$PATH:/opt/miniconda3/bin"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<

Do not activate base environment on startup

auto_activate_base: false

Install Mamba for faster environment solve

install micromamba

micromamba-bin

and create a symlink so it can be called as mamba

if [ ! -L "/bin/mamba" ]; then
    sudo ln -s /bin/micromamba /bin/mamba
fi

and configure the MAMBA_ROOT_PREFIX to save environments to the conda's environment directory

export MAMBA_ROOT_PREFIX="$HOME/.conda"
export MAMBA_ROOT_PREFIX="$HOME/.conda"

Workaround: OpenSSL error

as per this comment in the AUR we need the current workaround

export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1

Zathura

Installation

zathura
zathura-pdf-poppler

enable synctex

set synctex true

Nextcloud

nextcloud-client

add to autostart

nextcloud &

add keyring

seahorse is used to manage the keyrings

gnome-keyring
seahorse

Bitwarden

Installation

bitwarden

TODO Configuration

PCManFM

Installation

pcmanfm-gtk3

Automount USB

udiskie
udiskie -t &

Trash Support

gvfs

SMB Support

gvfs-smb

MTP Support

gvfs-mtp

Redshift

Redshift is a blue light filter

Installation

redshift

Autostart

redshift-gtk -t 6500:3600 &

Automatic Location Configuration

Uses Geoclue to access the current location

geoclue

This requires a systemd service to allow access (see Arch Linux Wiki)

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

[Unit]
Description=redshift needs to get a (geo)clue

[Service]
ExecStart=/usr/lib/geoclue-2.0/demos/agent

[Install]
WantedBy=default.target

The service needs to be enabled

systemd_service="geoclue-agent"
if ! systemctl --user is-enabled --quiet "$systemd_service"; then
    echo "Enabling $systemd_service"
    systemctl --user enable "$systemd_service"
    systemctl --user start "$systemd_service"
fi

frpint

fprint enables authorization via fingerprint

Installation

fprintd

Enable systemd Service

systemd_service="fprintd"
if ! systemctl is-enabled --quiet "$systemd_service"; then
    echo "Enabling $systemd_service"
    sudo systemctl enable "$systemd_service"
    sudo systemctl start "$systemd_service"
fi

Add User to input Group

groupname="input"
# Add the current user to the group if not already a member
if ! groups "$USER" | grep -q "\b$groupname\b"; then
    echo "Adding user $USER to group $groupname"
    sudo usermod -aG "$groupname" "$USER"
    if [ $? -eq 0 ]; then
        echo "User $USER added to group $groupname successfully."
    else
        echo "Failed to add user $USER to group $groupname."
    fi
fi

Authentication Agent

lxsession-gtk3
lxpolkit &

enroll both hands if no fingers are enrolled

if fprintd-list $USER | grep -q "no fingers enrolled"; then
    echo "No fingerprints are enrolled. Enrolling all fingers..."
    for finger in {left,right}-{thumb,{index,middle,ring,little}-finger}; do
        fprintd-enroll -f "$finger" "$USER"
    done
fi

Add authentication to PAM

system-login

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

#%PAM-1.0

auth       sufficient pam_fprintd.so
auth       required   pam_shells.so
auth       requisite  pam_nologin.so
auth       include    system-auth

account    required   pam_access.so
account    required   pam_nologin.so
account    include    system-auth

password   include    system-auth

session    optional   pam_loginuid.so
session    optional   pam_keyinit.so       force revoke
session    include    system-auth
session    optional   pam_motd.so
session    optional   pam_mail.so          dir=/var/spool/mail standard quiet
session    optional   pam_umask.so
-session   optional   pam_systemd.so
session    required   pam_env.so

sudo

# DO NOT EDIT THIS FILE DIRECTLY
# This is a file generated from a literate programing source file
# You should make any changes there and regenerate it from Emacs org-mode
# using org-babel-tangle (C-c C-v t)

#%PAM-1.0
auth		sufficient		pam_fprintd.so
auth		include		system-auth
account		include		system-auth
session		include		system-auth

Communication

Thunderbird

Installation

thunderbird

Autostart

thunderbird &

TODO Config

WhatsApp

whatsapp-for-linux

Fix Webkit2GTK

for more information see this Github issue

WEBKIT_DISABLE_DMABUF_RENDERER=1

signal

signal-desktop

Slack

slack-desktop

Discord

discord

Telegram

telegram-desktop

Rocket.Chat

rocketchat-client-bin

Docker

docker
docker-compose

Activate systemd Service

systemd_service="docker"
if ! systemctl is-enabled --quiet "$systemd_service"; then
    echo "Enabling $systemd_service"
    sudo systemctl enable "$systemd_service"
    sudo systemctl start "$systemd_service"
fi

Add User to docker Group

groupname="docker"
# Add the current user to the group if not already a member
if ! groups "$USER" | grep -q "\b$groupname\b"; then
    echo "Adding user $USER to group $groupname"
    sudo usermod -aG "$groupname" "$USER"
    if [ $? -eq 0 ]; then
        echo "User $USER added to group $groupname successfully."
    else
        echo "Failed to add user $USER to group $groupname."
    fi
fi

LibreOffice

Installation

libreoffice-still

TexMaths Extension

Enables inserting $\LaTeX$ equations into LibreOffice

libreoffice-extension-texmaths

Writer2LaTeX Extension

Enables exporting LibreOffice Documents to $\LaTeX$

libreoffice-extension-writer2latex

Spell-Checking

hunspell
hunspell-en_us
hunspell-de

Hyphenation Rules

hyphen
hyphen-en
hyphen-de

Thesaurus

libmythes
mythes-en
mythes-de

Utils

Downgrade

downgrade

GNU Wget

wget

NCDU

ncdu

NMAP

nmap

PDFtk

pdftk

rpi-imager

rpi-imager

Rsync

rsync

Transmission

transmission-gtk

Tree

tree

WireGuard

wireguard-tools

xarchiver

xarchiver

Optional Dependencies

arj
binutils
bzip2
cpio
gzip
lhasa
lrzip
lz4
lzip
lzop
p7zip
tar
unarj
unrar
unzip
xdg-utils
xz
zip
zstd

XClip

xclip

yt-dlp

yt-dlp

zip

zip

Misc

LaTeX

TeX Live

biber
texlive-basic
texlive-bibtexextra
texlive-binextra
texlive-context
texlive-fontsextra
texlive-fontsrecommended
texlive-fontutils
texlive-formatsextra
texlive-games
texlive-humanities
texlive-langarabic
texlive-langchinese
texlive-langcjk
texlive-langcyrillic
texlive-langczechslovak
texlive-langenglish
texlive-langeuropean
texlive-langfrench
texlive-langgerman
texlive-langgreek
texlive-langitalian
texlive-langjapanese
texlive-langkorean
texlive-langother
texlive-langpolish
texlive-langportuguese
texlive-langspanish
texlive-latex
texlive-latexextra
texlive-latexrecommended
texlive-luatex
texlive-mathscience
texlive-metapost
texlive-music
texlive-pictures
texlive-plaingeneric
texlive-pstricks
texlive-publishers
texlive-xetex

Pympress

python-pympress
python-vlc

CUPS

cups
foomatic-db-gutenprint-ppds
gutenprint

TODO Configure Printers

Darktable

darktable

Evince Document Viewer

evince

Calibre E-Book Reader

calibre

Disks Utility

gnome-disk-utility

Font Viewer

gnome-font-viewer

GIMP

gimp

Inkscape

inkscape

kdenlive

kdenlive

Scribus

scribus

VLC

vlc

xclip

xclip

drawio

drawio-desktop

Spotify

spotify-launcher

Virtualbox

virtualbox
virtualbox-host-dkms
virtualbox-guest-iso

Teamviewer

teamviewer

Anki

anki-bin

FreeCAD

freecad

Gramps

gramps

OBS Studio

obs-studio

Portfolio Performance

portfolio-performance-bin

Steam

steam

Hugo

Hugo is a framework for building a static website from markup documents.

Installation

Install the basic requirements

hugo

Manual Tasks after tangling

  1. run update.sh
  2. log out and back in to update group permissions
  3. setup Nextcloud sync directories
  4. sign into Bitwarden
  5. add Firefox Account
  6. configure TST using these instructions

    • Note: Remove the -18px left-indent in the second config line for TST
  7. configure networks

  8. add message service accounts

    • WhatsApp
    • Slack
    • Signal
    • Telegram

Other TODOs

DONE dunst

  • State "DONE" from "TODO" [2024-05-21 Di 11:31]

TODO fcitx

TODO browser landing page

DONE go through https://wiki.archlinux.org/title/Laptop

  • State "DONE" from "TODO" [2024-05-21 Di 11:31]

DONE go through old pkglist

  • State "DONE" from "TODO" [2024-02-20 Di 23:49]

TODO add README

DONE CUDA

  • State "DONE" from "TODO" [2024-05-21 Di 11:31]