Merge pull request #6 from SqrtMinusOne/arch
Some checks are pending
Update Site / trigger_update (push) Waiting to run

Arch
This commit is contained in:
Pavel Korytov 2025-11-23 21:58:11 +03:00 committed by GitHub
commit a622283422
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
69 changed files with 1798 additions and 1210 deletions

10
.bashrc
View file

@ -29,12 +29,8 @@ xhost +local:root > /dev/null 2>&1
# Startup & environment:5 ends here
# [[file:Console.org::*Startup & environment][Startup & environment:6]]
# export MANPAGER="sh -c 'sed -e s/.\\\\x08//g | bat -l man -p'"
# Startup & environment:6 ends here
# [[file:Console.org::*Startup & environment][Startup & environment:7]]
[ -n "$EAT_SHELL_INTEGRATION_DIR" ] && source "$EAT_SHELL_INTEGRATION_DIR/bash"
# Startup & environment:7 ends here
# Startup & environment:6 ends here
# [[file:Console.org::*Launch fish][Launch fish:1]]
use_fish=true
@ -133,9 +129,9 @@ fi
# [[file:Console.org::*Micromamba][Micromamba:1]]
init_mamba () {
export MAMBA_EXE="/home/pavel/.guix-extra-profiles/dev/dev/bin/micromamba";
export MAMBA_EXE="/usr/bin/micromamba";
export MAMBA_ROOT_PREFIX="/home/pavel/micromamba";
__mamba_setup="$("$MAMBA_EXE" shell hook --shell bash --prefix "$MAMBA_ROOT_PREFIX" 2> /dev/null)"
__mamba_setup="$("$MAMBA_EXE" shell hook --shell bash --root-prefix "$MAMBA_ROOT_PREFIX" 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__mamba_setup"
else

View file

@ -0,0 +1,152 @@
# [[file:../../Console.org::*Alacritty][Alacritty:1]]
[colors.bright]
black = "#484848"
red = "#d00000"
green = "#008900"
yellow = "#808000"
blue = "#0000ff"
magenta = "#dd22dd"
cyan = "#008899"
white = "#ffffff"
[colors.normal]
black = "#222222"
red = "#cc3333"
green = "#217a3c"
yellow = "#8a5d00"
blue = "#375cd8"
magenta = "#ba35af"
cyan = "#1f6fbf"
white = "#fff8f0"
[colors.primary]
background = "#fff8f0"
foreground = "#222222"
[env]
TERM = "xterm-256color"
[font]
size = 10
[font.normal]
family = "JetBrainsMono Nerd Font"
style = "Regular"
[[keyboard.bindings]]
action = "Paste"
key = "Paste"
[[keyboard.bindings]]
action = "Copy"
key = "Copy"
[[keyboard.bindings]]
action = "ClearLogNotice"
key = "L"
mods = "Control"
[[keyboard.bindings]]
chars = "\f"
key = "L"
mode = "~Vi|~Search"
mods = "Control"
[[keyboard.bindings]]
action = "ScrollPageUp"
key = "PageUp"
mode = "~Alt"
mods = "Shift"
[[keyboard.bindings]]
action = "ScrollPageDown"
key = "PageDown"
mode = "~Alt"
mods = "Shift"
[[keyboard.bindings]]
action = "ScrollToTop"
key = "Home"
mode = "~Alt"
mods = "Shift"
[[keyboard.bindings]]
action = "ScrollToBottom"
key = "End"
mode = "~Alt"
mods = "Shift"
[[keyboard.bindings]]
action = "ReceiveChar"
key = "Space"
mode = "~Search"
mods = "Shift|Control"
[[keyboard.bindings]]
action = "Paste"
key = "V"
mode = "~Vi"
mods = "Control|Shift"
[[keyboard.bindings]]
action = "Copy"
key = "C"
mods = "Control|Shift"
[[keyboard.bindings]]
action = "ReceiveChar"
key = "F"
mode = "~Search"
mods = "Control|Shift"
[[keyboard.bindings]]
action = "ReceiveChar"
key = "B"
mode = "~Search"
mods = "Control|Shift"
[[keyboard.bindings]]
action = "PasteSelection"
key = "Insert"
mods = "Shift"
[[keyboard.bindings]]
action = "ResetFontSize"
key = "Key0"
mods = "Control"
[[keyboard.bindings]]
action = "IncreaseFontSize"
key = "Equals"
mods = "Control"
[[keyboard.bindings]]
action = "IncreaseFontSize"
key = "Plus"
mods = "Control"
[[keyboard.bindings]]
action = "IncreaseFontSize"
key = "NumpadAdd"
mods = "Control"
[[keyboard.bindings]]
action = "DecreaseFontSize"
key = "Minus"
mods = "Control"
[[keyboard.bindings]]
action = "DecreaseFontSize"
key = "NumpadSubtract"
mods = "Control"
[window]
dynamic_padding = true
opacity = 1
[window.padding]
x = 0
y = 0
[keyboard]
# Alacritty:1 ends here

View file

@ -1,69 +0,0 @@
# [[file:../../Console.org::*Alacritty][Alacritty:1]]
decorations: none
font:
normal:
family: JetBrainsMono Nerd Font
style: Regular
size: 10
env:
TERM: xterm-256color
colors:
primary:
background: '#fff8f0'
foreground: '#222222'
normal:
black: '#222222'
red: '#cc3333'
green: '#217a3c'
yellow: '#8a5d00'
blue: '#375cd8'
magenta: '#ba35af'
cyan: '#1f6fbf'
white: '#fff8f0'
bright:
Black: '#484848'
Red: '#ff8f88'
Green: '#8adf80'
Yellow: '#fac200'
Blue: '#cbcfff'
Magenta: '#df8fff'
Cyan: '#88c8ff'
White: '#ffffff'
window:
padding:
x: 0
y: 0
dynamic_padding: true
opacity: 1
key_bindings:
- { key: Paste, action: Paste }
- { key: Copy, action: Copy }
- { key: L, mods: Control, action: ClearLogNotice }
- { key: L, mods: Control, mode: ~Vi|~Search, chars: "\x0c" }
- { key: PageUp, mods: Shift, mode: ~Alt, action: ScrollPageUp, }
- { key: PageDown, mods: Shift, mode: ~Alt, action: ScrollPageDown }
- { key: Home, mods: Shift, mode: ~Alt, action: ScrollToTop, }
- { key: End, mods: Shift, mode: ~Alt, action: ScrollToBottom }
# Turn off vi mode
- { key: Space, mods: Shift|Control, mode: ~Search, action: ReceiveChar }
# (Windows, Linux, and BSD only)
- { key: V, mods: Control|Shift, mode: ~Vi, action: Paste }
- { key: C, mods: Control|Shift, action: Copy }
- { key: F, mods: Control|Shift, mode: ~Search, action: ReceiveChar }
- { key: B, mods: Control|Shift, mode: ~Search, action: ReceiveChar }
- { key: Insert, mods: Shift, action: PasteSelection }
- { key: Key0, mods: Control, action: ResetFontSize }
- { key: Equals, mods: Control, action: IncreaseFontSize }
- { key: Plus, mods: Control, action: IncreaseFontSize }
- { key: NumpadAdd, mods: Control, action: IncreaseFontSize }
- { key: Minus, mods: Control, action: DecreaseFontSize }
- { key: NumpadSubtract, mods: Control, action: DecreaseFontSize }
# Alacritty:1 ends here

View file

@ -1,7 +1,9 @@
[flags]
hide_table_gap = true # Remove space in tables
color = "default-light"
process_command = true
[styles]
theme = "default-light"
[processes]
columns = ["PID", "State", "Name", "CPU%", "Mem%", "R/s", "W/s", "User"]

View file

@ -53,7 +53,7 @@
### Misc/Advanced ###
dmenu = /usr/bin/dmenu -p dunst:
browser = /home/pavel/.guix-extra-profiles/browsers/browsers/bin/firefox
browser = /user/bin/firefox
always_run_script = true
title = Dunst
class = Dunst
@ -69,15 +69,16 @@
mouse_middle_click = do_action
mouse_right_click = close_all
[experimental]
per_monitor_dpi = false
[shortcuts]
### Shortcuts
close = ctrl+space
close_all = ctrl+shift+space
history = ctrl+grave
context = ctrl+shift+period
[experimental]
per_monitor_dpi = false
[urgency_low]
background = "#f6ece8"
frame_color = "#baafba"

View file

@ -38,9 +38,9 @@ set fish_greeting
# [[file:../../Console.org::*Micromamba][Micromamba:1]]
function init_mamba
set -gx MAMBA_EXE "/home/pavel/.guix-extra-profiles/dev/dev/bin/micromamba"
set -gx MAMBA_EXE "/usr/bin/micromamba"
set -gx MAMBA_ROOT_PREFIX "/home/pavel/micromamba"
$MAMBA_EXE shell hook --shell fish --prefix $MAMBA_ROOT_PREFIX | source
$MAMBA_EXE shell hook --shell fish --root-prefix $MAMBA_ROOT_PREFIX | source
end
if test -n "$INIT_MAMBA";

View file

@ -0,0 +1,12 @@
hostname_enabled_backends_enabled = false
enabled_backends = ["arch"]
hostname_groups_enabled = true
[hostname_groups]
violet = ["system","office","nvidia","music","mail","latex","emacs","dev","desktop-rofi","desktop-polybar","desktop-misc","desktop","console","browsers"]
weiss = ["system","office","music","mail","latex","emacs","dev","desktop-rofi","desktop-polybar","desktop-misc","desktop","console","browsers"]
archlinux = ["system","office","music","mail","latex","emacs","dev","desktop-rofi","desktop-polybar","desktop-misc","desktop","console","browsers"]
[arch]
package_manager = "paru"

View file

@ -0,0 +1,4 @@
arch = [
"firefox-tridactyl",
"firefox",
"ungoogled-chromium-bin",]

View file

@ -0,0 +1,35 @@
arch = [
"pv",
"man-db",
"aria2",
"openssl",
"ncdu",
"megacmd",
"jless",
"direnv",
"git-lfs",
"sshfs",
"tokei",
"unrar",
"unzip",
"zip",
"pass",
"7zip",
"fzf",
"neofetch",
"nethogs",
"htop",
"eza",
"ncurses",
"bottom",
"alacritty",
"xclip",
"tmuxp",
"tmux",
"starship",
"nushell",
"atuin",
"shell-color-scripts-git",
"fish",
"xorg-xhost",
"xorg-xrdb",]

View file

@ -0,0 +1,27 @@
arch = [
"veracrypt",
"android-file-transfer",
"remmina",
"noto-fonts-emoji",
"telegram-desktop",
"bluez",
"xorg-xev",
"gparted",
"gnome-disk-utility",
"anydesk-bin",
"qbittorrent",
"gnome-font-viewer",
"xdg-utils",
"thunar",
"copyq",
"feh",
"polkit-gnome",
"fontconfig",
"xorg-xmodmap",
"network-manager-applet",
"pavucontrol",
"light",
"arandr",
"xorg-xprop",
"xss-lock",
"xorg-xinit",]

View file

@ -0,0 +1,8 @@
arch = [
"dateutils",
"sunwait",
"jq",
"curl",
"bind",
"noto-fonts-emoji",
"polybar",]

View file

@ -0,0 +1,5 @@
arch = [
"xorg-xset",
"rofi-pass",
"rofimoji",
"rofi",]

View file

@ -0,0 +1,18 @@
arch = [
"vnstat",
"activitywatch-bin",
"xdg-desktop-portal",
"flatpak",
"picom",
"libnotify",
"dunst",
"flameshot",
"i3lock",
"i3-wm",
"xorg-xinput",
"xorg-xgamma",
"xorg-xrandr",
"gnome-themes-extra",
"xsettingsd",
"papirus-icon-theme",
"gtk-engines",]

View file

@ -0,0 +1,32 @@
arch = [
"dbeaver",
"rust",
"git",
"wireshark-qt",
"socat",
"python-build",
"python-virtualenv",
"python-pip",
"python",
"php",
"gource",
"git-lfs",
"make",
"hugo",
"libfaketime",
"lua",
"cmake",
"gcc",
"pkgconf",
"gopls",
"go",
"jdk21-openjdk",
"nodejs",
"git-filter-repo",
"libvirt",
"virt-manager",
"postgresql",
"docker-compose",
"docker",
"pandoc-cli",
"micromamba-bin",]

View file

@ -0,0 +1,21 @@
arch = [
"texinfo",
"the_silver_searcher",
"ripgrep",
"hledger",
"rclone",
"gnu-free-fonts",
"ttf-unifont",
"telegram-tdlib",
"yt-dlp",
"mpv",
"python-youtube-transcript-api",
"rdrview",
"graphviz",
"python-isort",
"python-black",
"yapf",
"plantuml",
"difftastic",
"xkb-switch",
"emacs",]

View file

@ -0,0 +1,23 @@
arch = [
"ttf-dejavu",
"ttf-ms-fonts",
"python-pygments",
"biber",
"texlab",
"texlive-xetex",
"texlive-publishers",
"texlive-pstricks",
"texlive-plaingeneric",
"texlive-pictures",
"texlive-metapost",
"texlive-mathscience",
"texlive-latexrecommended",
"texlive-latexextra",
"texlive-latex",
"texlive-humanities",
"texlive-games",
"texlive-formatsextra",
"texlive-fontutils",
"texlive-binextra",
"texlive-bibtexextra",
"texlive-basic",]

View file

@ -0,0 +1,7 @@
arch = [
"notmuch",
"msmtp",
"parallel",
"notmuch",
"offlineimap",
"lieer-git",]

View file

@ -0,0 +1,8 @@
arch = [
"flac",
"cuetools",
"shntool",
"mpc",
"picard",
"ncmpcpp",
"mpd",]

View file

@ -0,0 +1,14 @@
arch = [
"rocketchat-desktop",
"obs-studio",
"okular",
"inkscape",
"kdenlive",
"ffmpeg",
"krita",
"gimp",
"libreoffice-fresh",
"zathura-djvu",
"zathura-pdf-mupdf",
"zathura-ps",
"zathura",]

View file

@ -0,0 +1,38 @@
arch = [
"xf86-video-ati",
"xf86-video-amdgpu",
"vulkan-radeon",
"vulkan-intel",
"intel-media-driver",
"libva-intel-driver",
"zram-generator",
"yadm",
"wireplumber",
"wireless_tools",
"wget",
"xterm",
"vim",
"smartmontools",
"sof-firmware",
"pipewire-jack",
"pipewire-pulse",
"pipewire-alsa",
"pipewire-audio",
"pipewire",
"paru",
"pacman-contrib",
"openssh",
"metapac",
"networkmanager",
"nano",
"inetutils",
"linux-firmware",
"linux",
"lightdm-gtk-greeter",
"lightdm",
"iwd",
"grub",
"decman",
"base-devel",
"base",
"amneziavpn-bin",]

View file

@ -180,16 +180,12 @@ radius = 0.0
; Global bar config:2 ends here
; [[file:../../Desktop.org::*Global bar config][Global bar config:3]]
; font-0 = ${env:FONT0:pango:monospace:size=10;1}
; font-1 = ${env:FONT1:NotoEmoji:scale=10:antialias=false;0}
; font-2 = ${env:FONT2:fontawesome:pixelsize=10;1}
; font-3 = ${env:FONT3:JetBrains Mono Nerd Font:monospace:size=10;1}
font-0 = pango:monospace:size=13;2
font-1 = NotoEmoji:scale=10:antialias=false;1
font-2 = fontawesome:pixelsize=13;3
font-3 = JetBrains Mono Nerd Font:monospace:size=13;4
font-4 = JetBrains Mono Nerd Font:monospace:size=17;4
font-3 = JetBrainsMono Nerd Font:style=Medium,Regular:size=13;4
font-4 = JetBrainsMono Nerd Font:style=Medium,Regular:size=17;4
font-5 = Adwaita Mono:style=Regular:size=13;3
; Global bar config:3 ends here
; [[file:../../Desktop.org::*Global bar config][Global bar config:4]]

View file

@ -39,13 +39,13 @@ palette = {
# 'background': '#282a36',
'background-alt': "#f6ece8",
# 'background-alt': '#282a36',
'background-attention': "#ff8f88",
'background-attention': "#d00000",
# 'background-attention': '#181920',
'border': "#baafba",
# 'border': '#282a36',
'current-line': "#5f5f5f",
'current-line': "#9da4b3",
# 'current-line': '#44475a',
'selection': "#5f5f5f",
'selection': "#9da4b3",
# 'selection': '#44475a',
'foreground': "#222222",
# 'foreground': '#f8f8f2',
@ -61,7 +61,7 @@ palette = {
# 'green': '#50fa7b',
'orange': "#8f5a3a",
# 'orange': '#ffb86c',
'pink': "#df8fff",
'pink': "#dd22dd",
# 'pink': '#ff79c6',
'purple': "#6052cf",
# 'purple': '#bd93f9',

View file

@ -0,0 +1,2 @@
- ~*
- .debris

View file

@ -9,12 +9,12 @@
cyan: #1f6fbf;
white: #fff8f0;
light-black: #484848;
light-red: #ff8f88;
light-green: #8adf80;
light-yellow: #fac200;
light-blue: #cbcfff;
light-magenta: #df8fff;
light-cyan: #88c8ff;
light-red: #d00000;
light-green: #008900;
light-yellow: #808000;
light-blue: #0000ff;
light-magenta: #dd22dd;
light-cyan: #008899;
light-white: #ffffff;
@ -25,8 +25,8 @@
border-color: #baafba;
selected-normal-background: #375cd8;
selected-normal-foreground: #fff8f0;
selected-active-background: #cbcfff;
selected-active-foreground: #222222;
selected-active-background: #0000ff;
selected-active-foreground: #fff8f0;
selected-urgent-background: #cc3333;
selected-urgent-foreground: #fff8f0;
normal-foreground: @foreground;
@ -37,8 +37,8 @@
urgent-background: @background;
alternate-normal-background: #f6ece8;
alternate-normal-foreground: @foreground;
alternate-active-background: #222222;
alternate-active-foreground: #cbcfff;
alternate-active-background: #fff8f0;
alternate-active-foreground: #0000ff;
alternate-urgent-background: #fff8f0;
alternate-urgent-foreground: #cc3333;
spacing: 2;

View file

@ -0,0 +1,8 @@
[Unit]
Description=ActivityWatch
[Service]
ExecStart=/usr/bin/aw-qt
[Install]
WantedBy=wm-session.target

View file

@ -0,0 +1,9 @@
[Unit]
Description=DETERRED MPD Watcher
ConditionPathExists=/home/pavel/10-19 Code/13 Other Projects/13.02 sqrt-data/13.02.R Repos/13.02.R.05 deterred/watchers/deterred-mpd.py
[Service]
ExecStart=/usr/bin/python "/home/pavel/10-19 Code/13 Other Projects/13.02 sqrt-data/13.02.R Repos/13.02.R.05 deterred/watchers/deterred-mpd.py" "--db" "/home/pavel/.deterred/database.db"
[Install]
WantedBy=wm-session.target

View file

@ -0,0 +1,8 @@
[Unit]
Description=Flameshot
[Service]
ExecStart=/usr/bin/flameshot
[Install]
WantedBy=wm-session.target

View file

@ -0,0 +1,8 @@
[Unit]
Description=Music Player Daemon
[Service]
ExecStart=/usr/bin/mpd --no-daemon
[Install]
WantedBy=graphical-session.target

View file

@ -0,0 +1,8 @@
[Unit]
Description=Network Manager Applet
[Service]
ExecStart=/usr/bin/nm-applet
[Install]
WantedBy=wm-session.target

View file

@ -0,0 +1,6 @@
[Unit]
Description=Update notmuch mail index
[Service]
Type=oneshot
ExecStart=/usr/bin/bash /home/pavel/bin/scripts/check-email

View file

@ -0,0 +1,9 @@
[Unit]
Description=Run notmuch sync script every 5 minutes
[Timer]
OnBootSec=1min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target

View file

@ -0,0 +1,8 @@
[Unit]
Description=vnStat network monitor
[Service]
ExecStart=/usr/bin/vnstatd
[Install]
WantedBy=wm-session.target

View file

@ -0,0 +1,8 @@
[Unit]
Description=X Settings Daemon
[Service]
ExecStart=/usr/bin/xsettingsd
[Install]
WantedBy=wm-session.target

View file

@ -8,7 +8,7 @@
;; Do not ask to confirm evaluations
(setq org-confirm-babel-evaluate nil)
(defun my/extract-guix-dependencies (&optional category)
(defun my/extract-arch-dependencies (&optional category)
(let ((dependencies '()))
(org-table-map-tables
(lambda ()
@ -21,7 +21,7 @@
nil
(mapcar #'substring-no-properties (nth 0 table))
:test (lambda (_ elem)
(string-match-p "[G|g]uix.*dep" elem))))
(string-match-p "[A|a]rch.*dep" elem))))
(category-name-index
(cl-position
nil
@ -33,7 +33,13 @@
nil
(mapcar #'substring-no-properties (nth 0 table))
:test (lambda (_ elem)
(string-match-p ".*[D|d]isabled.*" elem)))))
(string-match-p ".*[D|d]isabled.*" elem))))
(source-index
(cl-position
nil
(mapcar #'substring-no-properties (nth 0 table))
:test (lambda (_ elem)
(string-match-p ".*[S|s]ource.*" elem)))))
(when dep-name-index
(dolist (elem (cdr table))
(when
@ -53,15 +59,28 @@
(or
(not disabled-name-index)
(string-empty-p (nth disabled-name-index elem))))
(add-to-list
'dependencies
(substring-no-properties (nth dep-name-index elem)))))))))
(let ((source
(or
(when (and source-index
(not (string-empty-p (nth source-index elem))))
(substring-no-properties
(nth source-index elem)))
"arch")))
(push
(substring-no-properties (nth dep-name-index elem))
(alist-get source dependencies nil nil #'equal)))))))))
dependencies))
(defun my/format-guix-dependencies (&optional category)
(mapconcat
(lambda (e) (concat "\"" e "\""))
(my/extract-guix-dependencies category)
"\n"))
(defun my/format-arch-dependencies (&optional category)
(let ((data (my/extract-arch-dependencies category)))
(with-temp-buffer
(cl-loop for (backend . packages) in data
do (insert (format "%s = [\n" backend)
(mapconcat (lambda (package)
(format "\"%s\"," package))
packages
"\n")
"]"))
(buffer-string))))
;; A few dummy modes to avoid being prompted for comment systax
(define-derived-mode fish-mode prog-mode "Fish"

View file

@ -6,9 +6,13 @@
(call-process-shell-command "feh --bg-fill ~/Pictures/wallpaper.jpg"))
(defun my/exwm-run-shepherd ()
(when (string-empty-p (shell-command-to-string "pgrep -u pavel shepherd"))
(when (and (string-empty-p (shell-command-to-string "pgrep -u pavel shepherd"))
(executable-find "shepherd"))
(call-process "shepherd")))
(defun my/exwm-run-systemd ()
(call-process "systemctl" nil nil nil "--user" "start" "wm-session.target"))
(use-package pinentry
:straight t
:after (exwm)
@ -377,14 +381,14 @@ DIR is either 'left or 'right."
_t_: Terminal (Alacritty)
_b_: Browser (Firefox)
_s_: Rocket.Chat
_e_: Element
_d_: Discord
_d_: DBeaver
_c_: Chromium
"
("t" (lambda () (interactive) (my/run-in-background "alacritty")))
("b" (lambda () (interactive) (my/run-in-background "firefox")))
("s" (lambda () (interactive) (my/run-in-background "flatpak run chat.rocket.RocketChat")))
("e" (lambda () (interactive) (my/run-in-background "flatpak run im.riot.Riot")))
("d" (lambda () (interactive) (my/run-in-background "flatpak run com.discordapp.Discord"))))
("s" (lambda () (interactive) (my/run-in-background "rocketchat-desktop")))
("d" (lambda () (interactive) (my/run-in-background "dbeaver")))
("c" (lambda () (interactive) (my/run-in-background "chromium"))))
(defun my/exwm-lock ()
(interactive)
@ -588,10 +592,12 @@ _d_: Discord
(defun my/exwm-init ()
(exwm-workspace-switch 1)
(my/exwm-run-polybar)
(my/exwm-set-wallpaper)
(my/exwm-run-shepherd)
(my/run-in-background "gpgconf --reload gpg-agent")
(my/exwm-run-polybar)
(setenv "DBUS_SESSION_BUS_ADDRESS" "unix:path=/run/user/1000/bus")
(my/exwm-run-systemd)
(when (my/is-arch)
(my/run-in-background "set_layout")))
@ -696,11 +702,11 @@ _d_: Discord
(,(kbd "s-i") . ,(my/app-command "copyq menu"))
;; Basic controls
(,(kbd "<XF86AudioRaiseVolume>") . ,(my/app-command "ponymix increase 5 --max-volume 150"))
(,(kbd "<XF86AudioLowerVolume>") . ,(my/app-command "ponymix decrease 5 --max-volume 150"))
(,(kbd "<XF86AudioRaiseVolume>") . ,(my/app-command "wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"))
(,(kbd "<XF86AudioLowerVolume>") . ,(my/app-command "wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%-"))
(,(kbd "<XF86MonBrightnessUp>") . ,(my/app-command "light -A 5"))
(,(kbd "<XF86MonBrightnessDown>") . ,(my/app-command "light -U 5"))
(,(kbd "<XF86AudioMute>") . ,(my/app-command "ponymix toggle"))
(,(kbd "<XF86AudioMute>") . ,(my/app-command "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"))
(,(kbd "<XF86AudioPlay>") . ,(my/app-command "mpc toggle"))
(,(kbd "<XF86AudioPause>") . ,(my/app-command "mpc pause"))

View file

@ -28,7 +28,7 @@
:key (lambda () (my/password-store-get-field
"My_Online/Accounts/openrouter" "api-key"))
:stream t
:models '("anthropic/claude-sonnet-4"
:models '("anthropic/claude-sonnet-4.5"
"qwen/qwen3-coder"
"qwen/qwen3-coder:free"))
(setq gptel--known-backends

View file

@ -116,7 +116,8 @@
(string-match-p "/gnu/store" default-directory))
(nerd-icons-dired-mode))))
:config
(advice-add #'dired-create-empty-file :around #'nerd-icons-dired--refresh-advice))
;; (advice-add #'dired-create-empty-file :around #'nerd-icons-dired--refresh-advice)
)
(use-package dired-open
:straight t

View file

@ -82,6 +82,8 @@
;; I have everything I need in polybar
(emms-mode-line-mode -1)
(emms-playing-time-display-mode -1)
(delq 'emms-mark-mode evil-emacs-state-modes)
(delq 'emms-browser-mode evil-emacs-state-modes)
(defun emms-info-mpd-process (track info)
(dolist (data info)
(let ((name (car data))

View file

@ -245,7 +245,7 @@
"m" 'magit
"M" 'magit-file-dispatch)
:config
(require 'forge)
;; (require 'forge)
(setq magit-blame-styles
'((headings
(heading-format . "%-20a %C %s\n"))

View file

@ -355,7 +355,7 @@ With ARG, repeats or can move backward if negative."
name ".csv")
"orgtbl-to-csv")))))
(defun my/extract-guix-dependencies (&optional category)
(defun my/extract-arch-dependencies (&optional category)
(let ((dependencies '()))
(org-table-map-tables
(lambda ()
@ -368,7 +368,7 @@ With ARG, repeats or can move backward if negative."
nil
(mapcar #'substring-no-properties (nth 0 table))
:test (lambda (_ elem)
(string-match-p "[G|g]uix.*dep" elem))))
(string-match-p "[A|a]rch.*dep" elem))))
(category-name-index
(cl-position
nil
@ -380,7 +380,13 @@ With ARG, repeats or can move backward if negative."
nil
(mapcar #'substring-no-properties (nth 0 table))
:test (lambda (_ elem)
(string-match-p ".*[D|d]isabled.*" elem)))))
(string-match-p ".*[D|d]isabled.*" elem))))
(source-index
(cl-position
nil
(mapcar #'substring-no-properties (nth 0 table))
:test (lambda (_ elem)
(string-match-p ".*[S|s]ource.*" elem)))))
(when dep-name-index
(dolist (elem (cdr table))
(when
@ -400,16 +406,29 @@ With ARG, repeats or can move backward if negative."
(or
(not disabled-name-index)
(string-empty-p (nth disabled-name-index elem))))
(add-to-list
'dependencies
(substring-no-properties (nth dep-name-index elem)))))))))
(let ((source
(or
(when (and source-index
(not (string-empty-p (nth source-index elem))))
(substring-no-properties
(nth source-index elem)))
"arch")))
(push
(substring-no-properties (nth dep-name-index elem))
(alist-get source dependencies nil nil #'equal)))))))))
dependencies))
(defun my/format-guix-dependencies (&optional category)
(mapconcat
(lambda (e) (concat "\"" e "\""))
(my/extract-guix-dependencies category)
"\n"))
(defun my/format-arch-dependencies (&optional category)
(let ((data (my/extract-arch-dependencies category)))
(with-temp-buffer
(cl-loop for (backend . packages) in data
do (insert (format "%s = [\n" backend)
(mapconcat (lambda (package)
(format "\"%s\"," package))
packages
"\n")
"]"))
(buffer-string))))
(setq my/org-config-files
(mapcar
@ -417,6 +436,7 @@ With ARG, repeats or can move backward if negative."
'("~/Emacs.org"
"~/Desktop.org"
"~/Console.org"
"~/Arch.org"
"~/Guix.org"
"~/Mail.org")))

View file

@ -77,8 +77,8 @@
(setq doom-themes-treemacs-theme "doom-colors")
(doom-themes-treemacs-config))
(use-package modus-themes
:straight t)
;; (use-package modus-themes
;; :straight (:build (:not native-compile)))
(use-package ef-themes
:straight t
@ -137,9 +137,12 @@
(t (doom-color color)))))))
(defun my/modus-get-base (color)
(let ((base-value (string-to-number (substring (symbol-name color) 4 5)))
(base-start (cadr (assoc 'bg-main (modus-themes--current-theme-palette))))
(base-end (cadr (assoc 'fg-dim (modus-themes--current-theme-palette)))))
(let* ((base-value (string-to-number (substring (symbol-name color) 4 5)))
(palette (modus-themes-get-theme-palette
(or (my/modus-p) (my/ef-p))
:with-overrides :with-user-palette))
(base-start (cadr (assoc 'bg-main palette)))
(base-end (cadr (assoc 'fg-dim palette))))
(nth base-value (ct-gradient 9 base-start base-end t))))
(defun my/prot-color (color palette)
@ -179,10 +182,11 @@
(t (cadr (assoc color palette))))))
(defun my/modus-color (color)
(my/prot-color color (modus-themes--current-theme-palette)))
(my/prot-color color (modus-themes-get-theme-palette
(or (my/modus-p) (my/ef-p))
:with-overrides :with-user-palette)))
(defun my/ef-color (color)
(my/prot-color color (ef-themes--current-theme-palette)))
(defalias 'my/ef-color 'my/modus-color)
(defconst my/test-colors-list
'(black red green yellow blue magenta cyan white light-black
@ -250,9 +254,13 @@
collect (eval value)))))))
(enable-theme 'my-theme-1))
(defun my/advice-my-theme ()
(advice-add 'load-theme :after #'my/update-my-theme))
(unless my/is-termux
(advice-add 'load-theme :after #'my/update-my-theme)
(add-hook 'emacs-startup-hook #'my/update-my-theme))
(add-hook 'emacs-startup-hook #'my/update-my-theme)
;; (add-hook 'emacs-startup-hook #'my/advice-my-theme)
)
(my/use-colors
(tab-bar-tab :background (my/color-value 'bg)
@ -272,6 +280,7 @@
(eq enabled-theme theme)))
do (disable-theme enabled-theme))
(load-theme theme t)
(my/update-my-theme)
(when current-prefix-arg
(my/regenerate-desktop)))

View file

@ -1,6 +1,7 @@
;;; -*- lexical-binding: t -*-
(unless (or my/remote-server my/nested-emacs)
(add-hook 'after-init-hook #'server-start))
;; (add-hook 'after-init-hook #'server-start)
)
(defmacro i3-msg (&rest args)
`(start-process "emacs-i3-windmove" nil "i3-msg" ,@args))

View file

@ -375,8 +375,11 @@ REMOTE = '<rclone-remote>'
FOLDERS = json.loads('<rclone-folders-json>')
OPTIONS = json.loads('<rclone-options>')
for folder, i in zip(FOLDERS, range(len(FOLDERS))):
folder['id'] = i
def rclone_make_command(local_path, remote_path, remote):
def rclone_make_command(local_path, remote_path, remote, extra_args=[]):
return [
'rclone',
'bisync',
@ -390,7 +393,8 @@ def rclone_make_command(local_path, remote_path, remote):
'NEVER',
'--use-json-log',
'--stats',
'9999m'
'9999m',
*extra_args
]
@ -418,15 +422,26 @@ def process_output(output):
except Exception:
print(line)
def rclone_run(folder):
def process_command_for_print(command):
res = []
for c in command:
if ' ' in c:
res.append(f'\\'{c}\\'')
else:
res.append(c)
return ' '.join(res)
def rclone_run(folder, extra_args=[]):
command = rclone_make_command(
folder['local-path'], folder['remote-path'], folder['remote']
folder['local-path'], folder['remote-path'], folder['remote'], extra_args
)
try:
print(str(folder['id']) + '. ' + process_command_for_print(command))
result = subprocess.run(command, check=True, capture_output=True, text=True)
except subprocess.CalledProcessError as e:
print(f'=== Error syncing {folder['local-path']} ===')
print(f'Command: {' '.join(command)}')
print(f'Command: {process_command_for_print(command)}')
print(f'--- STDOUT ---')
process_output(e.stdout)
print(f'--- STDERR ---')
@ -434,7 +449,6 @@ def rclone_run(folder):
return {'success': False, 'stats': {}}
return {'success': True, 'stats': parse_rclone_stats(result.stderr)}
def notify(summary, body, level='normal', expire_time=5000):
subprocess.run(['notify-send', '-u', level, '-t', str(expire_time), summary, body])
@ -447,40 +461,65 @@ def sizeof_fmt(num, suffix='B'):
return f'{num:.1f}Yi{suffix}'
def rclone_run_all(folders):
def rclone_run_all(folders, extra_args=[]):
error_folders = []
total_bytes = 0
total_transfers = 0
total_deleted = 0
total_renamed = 0
for folder in folders:
print(f'Running rclone for {folder}')
res = rclone_run(folder)
res = rclone_run(folder, extra_args)
if not res['success']:
error_folders.append(folder['local-path'])
error_folders.append(folder)
else:
total_bytes += res.get('stats', {}).get('bytes', 0)
total_transfers += res.get('stats', {}).get('transfers', 0)
total_deleted += res.get('stats', {}).get('deletes', 0)
total_renamed += res.get('stats', {}).get('renames', 0)
if len(error_folders) > 0:
error_msg = f'Sync error for remote {REMOTE}!'
for folder in error_folders:
error_msg += '''\n- ''' + folder
notify(f'rclone sync {REMOTE}', error_msg, level='critical')
else:
msg = ''
level = 'normal'
if total_transfers > 0:
msg += f'''Transferred {total_transfers} files ({sizeof_fmt(total_bytes)})\n'''
if total_deleted > 0:
msg += f'''Deleted {total_transfers} files\n'''
msg += f'''Deleted {total_deleted} files\n'''
if total_renamed > 0:
msg += f'''Renamed {total_renamed} files\n'''
if len(error_folders) > 0:
msg += '''\nSync errors for the following folders:'''
for folder in error_folders:
msg += '''\n- ''' + str(folder['id']) + '. ' + folder['local-path']
level = 'critical'
if len(msg) > 0:
notify(f'rclone sync {REMOTE}', msg)
notify(f'rclone sync {REMOTE}', msg, level=level)
def parse_arguments():
if len(sys.argv) < 2:
return None, []
id_arg = sys.argv[1]
folder_ids = [int(x.strip()) for x in id_arg.split(',')]
extra_args = sys.argv[2:]
return folder_ids, extra_args
if __name__ == '__main__':
rclone_run_all(FOLDERS)
folder_ids, extra_args = parse_arguments()
if folder_ids is None:
selected_folders = FOLDERS
else:
selected_folders = [f for f in FOLDERS if f['id'] in folder_ids]
found_ids = {f['id'] for f in selected_folders}
missing_ids = set(folder_ids) - found_ids
if missing_ids:
print(f'Warning: folder IDs not found: {sorted(missing_ids)}')
rclone_run_all(selected_folders, extra_args)
"))
(setq script
(thread-last script
@ -559,6 +598,23 @@ The return value is a list of commands as defined by
commands))
(nreverse commands)))
(defun my/index-rclone-reset ()
"Delete all rclone test files."
(interactive)
(let* ((tree (my/index--tree-retrive))
(folders (my/index--rclone-get-folders tree))
files-to-delete)
(dolist (folder folders)
(let ((test-file-path
(concat
(alist-get :local-path folder)
(format ".rclone-test-%s" (alist-get :remote folder)))))
(when (file-exists-p test-file-path)
(push test-file-path files-to-delete))))
(when (y-or-n-p (format "Delete %d files" (seq-length files-to-delete)))
(dolist (file files-to-delete)
(delete-file file)))))
(defun my/index--git-commands (tree)
"Get commands to clone the yet uncloned git repos in TREE.
@ -583,7 +639,7 @@ The return value is a list of commands as defined by
E.g. 10.03.R.01 Project Name -> Project Name."
(replace-regexp-in-string
(rx bos (+ (| num alpha "." "-")) space) "" name))
(rx bos (+ num) (? "." (+ (| num alpha "." "-"))) space) "" name))
(defun my/index--wakatime-escape (string)
"Escape STRING for use in a WakaTime config file."

View file

@ -152,6 +152,8 @@
(org-element-property :end element))))
(with-temp-buffer
(insert s)
(let (org-mode-hook)
(org-mode))
(org-clock-sum)
org-clock-file-total-minutes)))

View file

@ -1,7 +1,5 @@
;;; -*- lexical-binding: t -*-
(use-package telega
;; :straight (:type built-in)
;; For now emacs-telega-server is compatible with the latest telega.el
:straight t
:commands (telega)
:init
@ -13,10 +11,8 @@
:background (my/color-value 'fg))
(telega-entity-type-spoiler :background (my/color-value 'base8)))
:config
(when (file-exists-p "~/.guix-extra-profiles/emacs/emacs/bin/telega-server")
(setq telega-server-command
(expand-file-name
"~/.guix-extra-profiles/emacs/emacs/bin/telega-server")))
(setq telega-server-libs-prefix "/usr")
(setq telega-emoji-use-images nil)
(setq telega-chat-fill-column 80)
(setq telega-completing-read-function #'completing-read)
@ -39,15 +35,6 @@
telega-image-mode 3 "telega"
telega-webpage-mode 3 "telega"))
(defun my/telega-server-build ()
(interactive)
(setq telega-server-libs-prefix
(if (executable-find "guix")
(string-trim
(shell-command-to-string "guix build tdlib"))
(expand-file-name "~/bin/td/build/res/usr/local")))
(telega-server-build "CC=gcc"))
(add-hook 'telega-load-hook #'telega-mode-line-mode)
(setq telega-mode-line-string-format
'("["

View file

@ -346,6 +346,7 @@
(use-package eshell-atuin
:straight (:host github :repo "SqrtMinusOne/eshell-atuin")
:when (executable-find "atuin")
:after eshell
:config
(eshell-atuin-mode)

View file

@ -92,6 +92,7 @@
(use-package combobulate
:straight (:host github :repo "mickeynp/combobulate")
:disabled
:commands (combobulate))
(provide 'sqrt-tree-sitter)

View file

@ -6,6 +6,7 @@
(advice-add 'wakatime-init :after
(lambda ()
(setq wakatime-cli-path (or
(executable-find "wakatime")
(executable-find "wakatime-cli")
(expand-file-name "~/bin/wakatime-cli")))))
(when (file-exists-p "~/.wakatime.cfg")

View file

@ -3,5 +3,5 @@ default-cache-ttl 3600
max-cache-ttl 3600
allow-emacs-pinentry
allow-loopback-pinentry
pinentry-program /home/pavel/.guix-profile/bin/pinentry
pinentry-program /usr/bin/pinentry
# Pinentry:3 ends here

View file

@ -1 +0,0 @@
https://nixos.org/channels/nixpkgs-unstable nixpkgs

103
.profile
View file

@ -22,14 +22,6 @@ fi
# TZ='Asia/Karachi'; export TZ
# Environment:5 ends here
#!/usr/bin/env bash
# [[file:Console.org::*Environment][Environment:6]]
if [ -f "/home/pavel/.no-guix" ]; then
export NO_GUIX=true
export PATH=$(echo $PATH | tr ":" "\n" | grep -vE "guix|nix|gnu" | tr "\n" ":")
fi
# Environment:6 ends here
# [[file:Console.org::*My paths][My paths:1]]
if [ -d "$HOME/bin" ] ; then
export PATH="$HOME/bin:$PATH"
@ -41,68 +33,22 @@ if [ -d "$HOME/.local/bin" ] ; then
fi
# My paths:1 ends here
# [[file:Console.org::*SSL Certs][SSL Certs:1]]
if [ -d "$HOME/.guix-extra-profiles" ] ; then
export SSL_CERT_DIR="$HOME/.guix-extra-profiles/system/system/etc/ssl/certs/"
export SSL_CERT_FILE="$HOME/.guix-extra-profiles/system/system/etc/ssl/certs/ca-certificates.crt"
export GIT_SSL_CAINFO="$SSL_CERT_FILE"
export CURL_CA_BUNDLE="$SSL_CERT_FILE"
fi
# SSL Certs:1 ends here
#!/usr/bin/env bash
# [[file:Console.org::*ssh-agent][ssh-agent:3]]
export SSH_AUTH_SOCK=$XDG_RUNTIME_DIR/ssh-agent.socket
# ssh-agent:3 ends here
# [[file:Console.org::*ssh-agent][ssh-agent:1]]
SSH_AGENT_DIR="/tmp"
if [ "$IS_ANDROID" == "true" ]; then
SSH_AGENT_DIR="/data/data/com.termux/files/tmp"
mkdir -p $SSH_AGENT_DIR
fi
if ! pgrep -u "$USER" ssh-agent > /dev/null; then
ssh-agent -t 1h > "$SSH_AGENT_DIR/ssh-agent.env"
fi
if [[ ! -f "$SSH_AUTH_SOCK" ]]; then
source "$SSH_AGENT_DIR/ssh-agent.env" >/dev/null
fi
# ssh-agent:1 ends here
# [[file:Console.org::*Guix settings][Guix settings:1]]
if [ -z "$IS_ANDROID" ] && [ -z "$NO_GUIX" ] ; then
GUIX_EXTRA_PROFILES=$HOME/.guix-extra-profiles
for i in $GUIX_EXTRA_PROFILES/*; do
profile=$i/$(basename "$i")
if [ -f "$profile"/etc/profile ]; then
GUIX_PROFILE="$profile"
. "$GUIX_PROFILE"/etc/profile
fi
if [ -d "$profile"/share/man ]; then
if command -v manpath >/dev/null 2>/dev/null; then
export MANPATH="${MANPATH:-$(manpath)}:$profile/share/man"
else
export MANPATH="${MANPATH}:$profile/share/man"
fi
fi
export XDG_DATA_DIRS="$XDG_DATA_DIRS:$profile/share"
unset profile
done
fi
# Guix settings:1 ends here
# [[file:Console.org::*Guix settings][Guix settings:2]]
# [[file:Console.org::*Misc settings][Misc settings:1]]
export JUPYTER_CONFIG_DIR=$HOME/.config/jupyter
# Guix settings:2 ends here
# Misc settings:1 ends here
# [[file:Console.org::*Guix settings][Guix settings:3]]
export GUIX_PACKAGE_PATH=~/guix-packages
# Guix settings:3 ends here
# [[file:Console.org::*Guix settings][Guix settings:4]]
export GUIX_LOCPATH=$HOME/.guix-extra-profiles/console/console/lib/locale
# Guix settings:4 ends here
# [[file:Console.org::*Guix settings][Guix settings:5]]
# [[file:Console.org::*Misc settings][Misc settings:2]]
export GIO_EXTRA_MODULES=""
# Guix settings:5 ends here
# Misc settings:2 ends here
# [[file:Console.org::*Misc settings][Misc settings:3]]
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
# Misc settings:3 ends here
# [[file:Console.org::*Other package managers][Other package managers:1]]
if [ -d "$HOME/.cask" ]; then
@ -125,33 +71,10 @@ if [ -e /home/pavel/.nix-profile/etc/profile.d/nix.sh ] && [ -z "$NO_GUIX" ] ; t
# Other package managers:3 ends here
# [[file:Console.org::*Other package managers][Other package managers:4]]
if [ -d "$HOME/.guix-extra-profiles/desktop-misc" ] && [ -z "$NO_GUIX" ] ; then
export FONTCONFIG_PATH="$HOME/.guix-extra-profiles/desktop-misc/desktop-misc/etc/fonts"
fi
# Other package managers:4 ends here
# [[file:Console.org::*Other package managers][Other package managers:5]]
if [ -d "$HOME/.nix-profile" ] && [ -z "$NO_GUIX" ]; then
export XDG_DATA_DIRS="$XDG_DATA_DIRS:$HOME/.nix-profile/share/applications"
fi
# Other package managers:5 ends here
# [[file:Console.org::*Other package managers][Other package managers:6]]
if [ -d "$HOME/bin/gradle/gradle-9.0.0" ]; then
export PATH="$HOME/bin/gradle/gradle-9.0.0/bin:$PATH"
fi
# Other package managers:6 ends here
# [[file:Console.org::*npm][npm:2]]
export NPM_CONFIG_USERCONFIG=$HOME/._npmrc
# npm:2 ends here
# [[file:Console.org::*npm][npm:3]]
NPM_PACKAGES="${HOME}/.npm-packages"
export PATH="$PATH:$NPM_PACKAGES/bin"
export MANPATH="${MANPATH:-$(manpath)}:$NPM_PACKAGES/share/man"
# npm:3 ends here
# Other package managers:4 ends here
# [[file:Console.org::*XResources][XResources:1]]
if [ -z "$IS_ANDROID" ]; then

View file

@ -13,8 +13,8 @@ set -g status-left-length "100"
setw -g window-status-activity-style "none,fg=#375cd8,bg=#f6ece8"
setw -g window-status-separator ""
setw -g window-status-style "none,fg=#222222,bg=#f6ece8"
set -g status-left "#[fg=#fff8f0,bg=#375cd8] #S #[fg=#375cd8,bg=#cbcfff,nobold,nounderscore,noitalics]#[fg=#222222,bg=#cbcfff] #W #[fg=#cbcfff,bg=#f6ece8,nobold,nounderscore,noitalics]"
set -g status-right "%-H:%M #[bg=#f6ece8,fg=#cbcfff,nobold,nounderscore,noitalics]#[fg=#222222,bg=#cbcfff] %a, %b %d #[bg=#cbcfff,fg=#375cd8,nobold,nounderscore,noitalics]#[fg=#fff8f0,bg=#375cd8] #H "
setw -g window-status-format "#[fg=#f6ece8,bg=#cbcfff,nobold,nounderscore,noitalics]#[fg=#222222,bg=#cbcfff] #I #W #[align=left] #[fg=#cbcfff,bg=#f6ece8,nobold,nounderscore,noitalics]"
set -g status-left "#[fg=#fff8f0,bg=#375cd8] #S #[fg=#375cd8,bg=#0000ff,nobold,nounderscore,noitalics]#[fg=#fff8f0,bg=#0000ff] #W #[fg=#0000ff,bg=#f6ece8,nobold,nounderscore,noitalics]"
set -g status-right "%-H:%M #[bg=#f6ece8,fg=#0000ff,nobold,nounderscore,noitalics]#[fg=#fff8f0,bg=#0000ff] %a, %b %d #[bg=#0000ff,fg=#375cd8,nobold,nounderscore,noitalics]#[fg=#fff8f0,bg=#375cd8] #H "
setw -g window-status-format "#[fg=#f6ece8,bg=#0000ff,nobold,nounderscore,noitalics]#[fg=#fff8f0,bg=#0000ff] #I #W #[align=left] #[fg=#0000ff,bg=#f6ece8,nobold,nounderscore,noitalics]"
setw -g window-status-current-format "#[fg=#f6ece8,bg=#375cd8,nobold,nounderscore,noitalics]#[fg=#fff8f0,bg=#375cd8] #I #W #[fg=#375cd8,bg=#f6ece8,nobold,nounderscore,noitalics]"
# UI:1 ends here

View file

@ -21,7 +21,7 @@ xss-lock -- i3lock -f -i /home/pavel/Pictures/lock-wallpaper.png &
# Some apps that have to be launched only once.
picom &
# nm-applet &
dunst &
# dunst &
copyq &
# Run the Emacs startup script as a session.

265
Arch.org Normal file
View file

@ -0,0 +1,265 @@
#+TITLE: Arch Linux
#+PROPERTY: header-args :mkdirp yes
I've decided to switch to [[https://archlinux.org/][Arch Linux]] and configure it declaratively with [[https://github.com/ripytide/metapac][metapac]].
* System installation
** Installation
On installation, see https://wiki.archlinux.org/title/Installation_guide and/or use =archinstall=.
** After installation
Update everything:
#+begin_src bash
sudo pacman -Syyu
#+end_src
Install git, python and yadm:
#+begin_src bash
sudo pacman -Syu python git pacman-contrib yadm
#+end_src
Select top-6 fastest mirrors to work with. Generate a mirrorlist file using this service: https://archlinux.org/mirrorlist/, then use =rankmirrors= from =pacman-contrib= (see [[https://wiki.archlinux.org/title/Mirrors][Mirrors]] on Arch Wiki).
#+begin_src bash
sudo -i
cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup
rankmirrors -n 6 /etc/pacman.d/mirrorlist.backup > /etc/pacman.d/mirrorlist
#+end_src
If there isn't enough RAM (e.g. running in a VM), turn off mounting =/tmp= as [[https://wiki.archlinux.org/title/Tmpfs#Disable_automatic_mount][tmpfs]]:
#+begin_src basd
sudo systemctl mask tmp.mount
#+end_src
Install [[https://github.com/Morganamilo/paru][paru]]:
#+begin_src bash
sudo pacman -S --needed base-devel
git clone https://aur.archlinux.org/paru.git
cd paru
makepkg -si
#+end_src
Install [[https://github.com/ripytide/metapac][metapac]]:
#+begin_src bash
paru -Syyu metapac
#+end_src
Then install Arch packages with =metapac=:
#+begin_src bash
mkdir ~/00-Scratch/
git clone https://github.com/SqrtMinusOne/dotfiles.git ~/00-Scratch/dotfiles/
cp -r ~/00-Scratch/dotfiles/.config/metapac ~/.config/
metapac s
#+end_src
Then, install the ssh and gpg keys (put them into the =~/.ssh= folder). To export gpg keys:
#+begin_src bash
gpg --output private.pgp --armor --export-secret-keys <keyname>
#+end_src
And to import:
#+begin_src bash
gpg --import private.pgp
gpg --edit-key <keyname>
trust
#+end_src
Also the following to =~/.ssh/config=:
#+begin_src conf-space
Host *
AddKeysToAgent yes
#+end_src
And run:
#+begin_src bash
systemctl enable --user --now ssh-agent
#+end_src
It looks like it is necessary to run at least once.
Then, clone the dotfiles repo with =yadm=:
#+begin_src bash
yadm clone git@github.com:SqrtMinusOne/dotfiles.git
#+end_src
Checkout the changed files.
Clone org-mode and passwords repos:
#+begin_src bash
git clone ssh://git@git.sqrtminusone.xyz:222/sqrtminusone/org-mode.git "/home/pavel/30-39 Life/32 org-mode"
git clone ssh://git@git.sqrtminusone.xyz:222/sqrtminusone/passwords.git "/home/pavel/.password-store"
#+end_src
And don't forget to configure git:
#+begin_src bash
git config --global user.email "thexcloud@gmail.com"
git config --global user.name "SqrtMinusOne"
#+end_src
#+begin_src bash
sudo systemctl enable --now NetworkManager
#+end_src
Install wakatime:
#+begin_src bash
cd ~/00-Scratch/
git clone https://github.com/wakatime/wakatime-cli.git
cd ./wakatime-cli
go build
mv wakatime-cli ~/bin
#+end_src
And create the =~/.wakatime.cfg= file with the following contents:
#+begin_src
[settings]
api_key = <api-key>
#+end_src
Then run =emacs= and make sure it starts. Run:
- =M-x nerd-icons-install-fonts=
- =M-x all-the-icons-install-fonts=
- =M-x treesit-install-language-grammar=
Run =rclone config=, configure the remotes. Then =M-x my/index-commands-sync=.
If everything works, login into EXWM.
Create some directories:
#+begin_src bash
mkdir -p /home/pavel/Pictures/screenshots/
mkdir -p /home/pavel/.mpd/
#+end_src
Also run:
#+begin_src bash
sudo chmod +s /usr/bin/light
#+end_src
For I've decided to use =NetworkManager=, but Arch Linux uses =iwd= by default, which causes issues. Disable it by:
#+begin_src bash
sudo systemctl disable --now iwd
sudo systemctl disable --now systemd-networkd
#+end_src
And reboot. After the reboot, =NetworkManager= should run using =wpa_supplicant= as backend for Wi-Fi.
Don't forget to sync mail and enable the sync timer.
* Metapac configuration
[[https://github.com/ripytide/metapac][metapac]] is a declarative wrapper around different package managers, including [[https://wiki.archlinux.org/title/Pacman][pacman]] and [[https://github.com/Morganamilo/paru][paru]]. This means the required packages can be listed in configuration files and checked into version control.
I've also tried [[https://github.com/kiviktnm/decman][decman]], but it turned out to be too unstable because it ships its own logic for building AUR packages, which doesn't always work. So wrapping =paru= seems like a saner approach. Also, sometimes AUR drops packets, and =decman= can't handle it gracefully.
In =metapac=, packages are listed in "groups", each group being a TOML file stating which package has to be installed by which package manager. I declare groups as Org tables, see the "System configuration" section in Emacs.org.
Below is the table enabling different groups on different hostnames:
#+NAME: metapac-groups
| Profile | archlinux | weiss | violet |
| browsers | + | + | + |
| console | + | + | + |
| desktop | + | + | + |
| desktop-misc | + | + | + |
| desktop-polybar | + | + | + |
| desktop-rofi | + | + | + |
| dev | + | + | + |
| emacs | + | + | + |
| latex | + | + | + |
| mail | + | + | + |
| music | + | + | + |
| nvidia | | | + |
| office | + | + | + |
| system | + | + | + |
And the code to format it as TOML:
#+NAME: metapac-groups-format
#+begin_src emacs-lisp :var groups=metapac-groups
(let* ((hostnames (cdr (nth 0 groups)))
groups-by-hostname)
(cl-loop for row in (cdr groups)
for group = (nth 0 row)
do (cl-loop for i from 0
for sign in (cdr row)
for hostname = (nth i hostnames)
if (not (string-empty-p sign))
do (push group (alist-get hostname groups-by-hostname
nil nil #'equal))))
(cl-loop for (hostname . groups) in groups-by-hostname
concat (format "%s = [%s]\n" hostname
(mapconcat (lambda (g) (format "\"%s\"" g)) groups ","))))
#+end_src
Which is used in the config:
#+begin_src toml :tangle .config/metapac/config.toml :noweb yes
hostname_enabled_backends_enabled = false
enabled_backends = ["arch"]
hostname_groups_enabled = true
[hostname_groups]
<<metapac-groups-format()>>
[arch]
package_manager = "paru"
#+end_src
* System packages
Some necessary Arch packages:
| Arch dependency |
|---------------------|
| amneziavpn-bin |
| base |
| base-devel |
| decman |
| grub |
| iwd |
| lightdm |
| lightdm-gtk-greeter |
| linux |
| linux-firmware |
| inetutils |
| nano |
| networkmanager |
| metapac |
| openssh |
| pacman-contrib |
| paru |
| pipewire |
| pipewire-audio |
| pipewire-alsa |
| pipewire-pulse |
| pipewire-jack |
| sof-firmware |
| smartmontools |
| vim |
| xterm |
| wget |
| wireless_tools |
| wireplumber |
| yadm |
| zram-generator |
Various drivers, I'm not sure which I actually need, so...
| Arch dependency |
|--------------------|
| libva-intel-driver |
| intel-media-driver |
| vulkan-intel |
| vulkan-radeon |
| xf86-video-amdgpu |
| xf86-video-ati |
NVIDIA drivers for violet
| Category | Arch dependency |
|----------+-----------------|
| nvidia | cuda |
| nvidia | nvidia-utils |
| nvidia | nvidia |
#+NAME: packages
#+begin_src emacs-lisp :tangle no :var category=""
(my/format-arch-dependencies category)
#+end_src
#+begin_src scheme :tangle .config/metapac/groups/nvidia.toml :noweb yes
<<packages("nvidia")>>
#+end_src
#+begin_src scheme :tangle .config/metapac/groups/system.toml :noweb yes
<<packages()>>
#+end_src

View file

@ -72,14 +72,6 @@ Timezone
# TZ='Asia/Karachi'; export TZ
#+end_src
Turn off Guix
#+begin_src bash
if [ -f "/home/pavel/.no-guix" ]; then
export NO_GUIX=true
export PATH=$(echo $PATH | tr ":" "\n" | grep -vE "guix|nix|gnu" | tr "\n" ":")
fi
#+end_src
** My paths
My script folders
#+begin_src sh
@ -92,23 +84,11 @@ if [ -d "$HOME/.local/bin" ] ; then
export PATH="$HOME/.local/bin:$PATH"
fi
#+end_src
** SSL Certs
This seems necessary when running Guix on a foreign distro.
#+begin_src bash
if [ -d "$HOME/.guix-extra-profiles" ] ; then
export SSL_CERT_DIR="$HOME/.guix-extra-profiles/system/system/etc/ssl/certs/"
export SSL_CERT_FILE="$HOME/.guix-extra-profiles/system/system/etc/ssl/certs/ca-certificates.crt"
export GIT_SSL_CAINFO="$SSL_CERT_FILE"
export CURL_CA_BUNDLE="$SSL_CERT_FILE"
fi
#+end_src
** ssh-agent
I'm paranoid so I encrypt my SSH keys.
Got the idea for below from [[https://wiki.archlinux.org/title/SSH_keys#SSH_agents][ArchWiki]]:
#+begin_src bash
I used to do the below, as instructed by [[https://wiki.archlinux.org/title/SSH_keys#SSH_agents][ArchWiki]]:
#+begin_src bash :tangle no
SSH_AGENT_DIR="/tmp"
if [ "$IS_ANDROID" == "true" ]; then
@ -123,52 +103,35 @@ if [[ ! -f "$SSH_AUTH_SOCK" ]]; then
source "$SSH_AGENT_DIR/ssh-agent.env" >/dev/null
fi
#+end_src
** Guix settings
Enable extra profiles
#+begin_src sh
if [ -z "$IS_ANDROID" ] && [ -z "$NO_GUIX" ] ; then
GUIX_EXTRA_PROFILES=$HOME/.guix-extra-profiles
for i in $GUIX_EXTRA_PROFILES/*; do
profile=$i/$(basename "$i")
if [ -f "$profile"/etc/profile ]; then
GUIX_PROFILE="$profile"
. "$GUIX_PROFILE"/etc/profile
fi
if [ -d "$profile"/share/man ]; then
if command -v manpath >/dev/null 2>/dev/null; then
export MANPATH="${MANPATH:-$(manpath)}:$profile/share/man"
else
export MANPATH="${MANPATH}:$profile/share/man"
fi
fi
export XDG_DATA_DIRS="$XDG_DATA_DIRS:$profile/share"
unset profile
done
fi
But for now switched to the [[https://wiki.archlinux.org/title/SSH_keys#Start_ssh-agent_with_systemd_user][systemd unit]], which requires:
#+begin_src bash :tangle no
systemctl --user enable --now ssh-agent.service
#+end_src
Set Jupyter config PATH. It defaults to readonly directory somewhere in Guix profile.
#+begin_src bash
export SSH_AUTH_SOCK=$XDG_RUNTIME_DIR/ssh-agent.socket
#+end_src
** Misc settings
Set Jupyter config PATH. I keep it from my Guix config where it defaulted to some readonly folder.
#+begin_src sh
export JUPYTER_CONFIG_DIR=$HOME/.config/jupyter
#+end_src
Set a folder for my packages.
#+begin_src sh
export GUIX_PACKAGE_PATH=~/guix-packages
#+end_src
Locale settings
#+begin_src sh
export GUIX_LOCPATH=$HOME/.guix-extra-profiles/console/console/lib/locale
#+end_src
Somehow LibreOffice doesn't work without the following:
#+begin_src sh
export GIO_EXTRA_MODULES=""
#+end_src
Not sure why this is necessary.
#+begin_src sh
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
#+end_src
** Other package managers
Using other package managers with Guix requires some extra work.
Using other package managers requires some extra work.
Cask
#+begin_src sh
@ -195,20 +158,6 @@ if [ -e /home/pavel/.nix-profile/etc/profile.d/nix.sh ] && [ -z "$NO_GUIX" ] ; t
#+RESULTS:
Use Guix fontconfig. Necessary for nix apps
#+begin_src sh
if [ -d "$HOME/.guix-extra-profiles/desktop-misc" ] && [ -z "$NO_GUIX" ] ; then
export FONTCONFIG_PATH="$HOME/.guix-extra-profiles/desktop-misc/desktop-misc/etc/fonts"
fi
#+end_src
Make nix apps visible to launchers:
#+begin_src sh
if [ -d "$HOME/.nix-profile" ] && [ -z "$NO_GUIX" ]; then
export XDG_DATA_DIRS="$XDG_DATA_DIRS:$HOME/.nix-profile/share/applications"
fi
#+end_src
Gradle:
#+begin_src sh
if [ -d "$HOME/bin/gradle/gradle-9.0.0" ]; then
@ -216,90 +165,16 @@ if [ -d "$HOME/bin/gradle/gradle-9.0.0" ]; then
fi
#+end_src
*** npm
npm is especially cumbersome, for instance because by default it tries to install packages to =/gnu/store/=.
In principle, one can set a prefix like this:
#+begin_src conf :tangle ~/._npmrc
prefix=/home/pavel/.npm-packages
#+end_src
But I also want to use node from conda occasionally, where prefix is already set correctly. So instead of tangling the above to the =~/.npmrc= directly, I set an environment variable in the profile:
#+begin_src sh
export NPM_CONFIG_USERCONFIG=$HOME/._npmrc
#+end_src
The variable is unset in a script in [[file:Guix.org::*micromamba][Guix.org]].
Set PATH & MANPATH
#+begin_src sh
NPM_PACKAGES="${HOME}/.npm-packages"
export PATH="$PATH:$NPM_PACKAGES/bin"
export MANPATH="${MANPATH:-$(manpath)}:$NPM_PACKAGES/share/man"
#+end_src
** XResources
| Guix dependency |
| Arch dependency |
|-----------------|
| xrdb |
| xorg-xrdb |
#+begin_src sh
if [ -z "$IS_ANDROID" ]; then
xrdb ~/.Xresources
fi
#+end_src
** OFF (OFF) Package manager paths
Turned off for now, because probably it won't be necessary in Guix.
LaTeX
#+begin_src sh :tangle no
if [ -d "/usr/local/texlive/2020" ]; then
export MANPATH="/usr/local/texlive/2020/texmf-dist/doc/man:$MANPATH"
export INFOPATH="/usr/local/texlive/2020/texmf-dist/doc/info:$INFOPATH"
export PATH="/usr/local/texlive/2020/bin/x86_64-linux:$PATH"
fi
#+end_src
Cargo (Rust)
#+begin_src sh :tangle no
if [ -d "$HOME/.cargo" ] ; then
export PATH="$HOME/.cargo/bin:$PATH"
fi
#+end_src
RVM (Ruby)
#+begin_src sh :tangle no
if [ -d "$HOME/.rvm" ] ; then
export PATH="$PATH:$HOME/.rvm/bin"
fi
# if [ -d "$HOME/.gem" ]; then
# export PATH="$HOME/.gem/ruby/2.7.0/bin:$PATH"
# fi
#+end_src
Go
#+begin_src sh :tangle no
if [ -d "$HOME/go" ] ; then
export PATH="$HOME/go/bin:$PATH"
fi
#+end_src
ghcup (Haskell)
#+begin_src sh :tangle no
[ -f "/home/pavel/.ghcup/env" ] && source "/home/pavel/.ghcup/env" # ghcup-env
#+end_src
Perl
#+begin_src sh :tangle no
if [ -d "$HOME/perl5" ] ; then
PATH="/home/pavel/perl5/bin${PATH:+:${PATH}}"
PERL5LIB="/home/pavel/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
PERL_LOCAL_LIB_ROOT="/home/pavel/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
PERL_MB_OPT="--install_base \"/home/pavel/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=/home/pavel/perl5"; export PERL_MM_OPT;
fi
#+end_src
* Bash
:PROPERTIES:
:header-args:bash: :shebang "" :comments link
@ -315,7 +190,7 @@ fi
:header-args+: :tangle ./.bashrc
:END:
My =.bashrc=, which has pieces from the default one in Guix & Manjaro, as well some mine settings.
My =.bashrc=, which has pieces from the default one in Guix & Manjaro.
*** Startup & environment
Export 'SHELL' to child processes. Programs such as 'screen' honor it and otherwise use /bin/sh.
@ -348,20 +223,15 @@ if [[ -f "/etc/bashrc" ]]; then
fi
#+end_src
| Guix dependency |
| Arch dependency |
|-----------------|
| xhost |
| xorg-xhost |
Allow other users to access X server. Necessary for stuff like aw-watcher-window.
#+begin_src bash
xhost +local:root > /dev/null 2>&1
#+end_src
Set manpager to bat
#+begin_src bash
# export MANPAGER="sh -c 'sed -e s/.\\\\x08//g | bat -l man -p'"
#+end_src
[[https://codeberg.org/akib/emacs-eat][eat]] integration
#+begin_src bash
[ -n "$EAT_SHELL_INTEGRATION_DIR" ] && source "$EAT_SHELL_INTEGRATION_DIR/bash"
@ -488,9 +358,9 @@ Yeah, tell this to yourself
#+begin_src bash
init_mamba () {
export MAMBA_EXE="/home/pavel/.guix-extra-profiles/dev/dev/bin/micromamba";
export MAMBA_EXE="/usr/bin/micromamba";
export MAMBA_ROOT_PREFIX="/home/pavel/micromamba";
__mamba_setup="$("$MAMBA_EXE" shell hook --shell bash --prefix "$MAMBA_ROOT_PREFIX" 2> /dev/null)"
__mamba_setup="$("$MAMBA_EXE" shell hook --shell bash --root-prefix "$MAMBA_ROOT_PREFIX" 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__mamba_setup"
else
@ -529,7 +399,7 @@ init_yc () {
:header-args+: :tangle ./.config/fish/config.fish :comments link
:END:
| Guix dependency | Description |
| Arch dependency | Description |
|-----------------+------------------------------------------|
| fish | An alternative non POSIX-compliant shell |
@ -566,9 +436,9 @@ end
#+end_src
| Guix dependency |
|-----------------|
| dt-colorscripts |
| Arch dependency |
|-------------------------|
| shell-color-scripts-git |
Launch a random [[https://gitlab.com/dwt1/shell-color-scripts][DT's colorscript]] unless ran inside tmux or Emacs.
#+begin_src fish
@ -585,9 +455,9 @@ set fish_greeting
First, a function to initialize micromamba.
#+begin_src fish
function init_mamba
set -gx MAMBA_EXE "/home/pavel/.guix-extra-profiles/dev/dev/bin/micromamba"
set -gx MAMBA_EXE "/usr/bin/micromamba"
set -gx MAMBA_ROOT_PREFIX "/home/pavel/micromamba"
$MAMBA_EXE shell hook --shell fish --prefix $MAMBA_ROOT_PREFIX | source
$MAMBA_EXE shell hook --shell fish --root-prefix $MAMBA_ROOT_PREFIX | source
end
if test -n "$INIT_MAMBA";
@ -641,6 +511,11 @@ if type -q direnv
end
#+end_src
** atuin
| Arch dependency |
|-----------------|
| atuin |
#+begin_src fish
if type -q atuin
set -gx ATUIN_NOBIND "true"
@ -653,16 +528,16 @@ end
:PROPERTIES:
:header-args+: :tangle ./.config/nu/config.toml :comments link
:END:
| Guix dependency |
| Arch dependency |
|-----------------|
| nushell-bin |
| nushell |
A structured shell. I don't use it as of now, but perhaps one day.
* Starship prompt
| Guix dependency | Description |
| Arch dependency | Description |
|-----------------+---------------------|
| starship-bin | my prompt of choice |
| starship | my prompt of choice |
[[https://starship.rs/][Starship]] is a nice cross-shell prompt, written in Rust.
@ -750,10 +625,10 @@ symbol = " "
:PROPERTIES:
:header-args+: :tangle ./.tmux.conf
:END:
| Guix dependency |
| Arch dependency |
|-----------------|
| tmux |
| python-tmuxp |
| tmuxp |
[[https://github.com/tmux/tmux][tmux]] is my terminal multiplexer of choice.
@ -805,7 +680,7 @@ Reload the config.
bind r source-file ~/.tmux.conf
#+end_src
** Copy to clipboard
| Guix dependency |
| Arch dependency |
|-----------------|
| xclip |
@ -846,10 +721,10 @@ source ~/.tmux.line.conf
#+end_src
* Alacritty
:PROPERTIES:
:header-args+: :tangle ./.config/alacritty/alacritty.yml :comments link
:header-args+: :tangle ./.config/alacritty/alacritty.toml :comments link
:END:
| Guix dependency |
| Arch dependency |
|-----------------|
| alacritty |
@ -858,79 +733,162 @@ source ~/.tmux.line.conf
References:
- [[https://github.com/alacritty/alacritty/blob/master/alacritty.yml][default config]]
#+begin_src yaml :noweb yes
decorations: none
#+begin_src toml :noweb yes
[colors.bright]
black = "<<get-color(name="light-black")>>"
red = "<<get-color(name="light-red")>>"
green = "<<get-color(name="light-green")>>"
yellow = "<<get-color(name="light-yellow")>>"
blue = "<<get-color(name="light-blue")>>"
magenta = "<<get-color(name="light-magenta")>>"
cyan = "<<get-color(name="light-cyan")>>"
white = "<<get-color(name="light-white")>>"
font:
normal:
family: JetBrainsMono Nerd Font
style: Regular
[colors.normal]
black = "<<get-color(name="black")>>"
red = "<<get-color(name="red")>>"
green = "<<get-color(name="green")>>"
yellow = "<<get-color(name="yellow")>>"
blue = "<<get-color(name="blue")>>"
magenta = "<<get-color(name="magenta")>>"
cyan = "<<get-color(name="cyan")>>"
white = "<<get-color(name="white")>>"
size: 10
[colors.primary]
background = "<<get-color(name="bg")>>"
foreground = "<<get-color(name="fg")>>"
env:
TERM: xterm-256color
[env]
TERM = "xterm-256color"
colors:
primary:
background: '<<get-color(name="bg")>>'
foreground: '<<get-color(name="fg")>>'
normal:
black: '<<get-color(name="black")>>'
red: '<<get-color(name="red")>>'
green: '<<get-color(name="green")>>'
yellow: '<<get-color(name="yellow")>>'
blue: '<<get-color(name="blue")>>'
magenta: '<<get-color(name="magenta")>>'
cyan: '<<get-color(name="cyan")>>'
white: '<<get-color(name="white")>>'
bright:
Black: '<<get-color(name="light-black")>>'
Red: '<<get-color(name="light-red")>>'
Green: '<<get-color(name="light-green")>>'
Yellow: '<<get-color(name="light-yellow")>>'
Blue: '<<get-color(name="light-blue")>>'
Magenta: '<<get-color(name="light-magenta")>>'
Cyan: '<<get-color(name="light-cyan")>>'
White: '<<get-color(name="light-white")>>'
[font]
size = 10
window:
padding:
x: 0
y: 0
dynamic_padding: true
opacity: 1
[font.normal]
family = "JetBrainsMono Nerd Font"
style = "Regular"
key_bindings:
- { key: Paste, action: Paste }
- { key: Copy, action: Copy }
- { key: L, mods: Control, action: ClearLogNotice }
- { key: L, mods: Control, mode: ~Vi|~Search, chars: "\x0c" }
- { key: PageUp, mods: Shift, mode: ~Alt, action: ScrollPageUp, }
- { key: PageDown, mods: Shift, mode: ~Alt, action: ScrollPageDown }
- { key: Home, mods: Shift, mode: ~Alt, action: ScrollToTop, }
- { key: End, mods: Shift, mode: ~Alt, action: ScrollToBottom }
[[keyboard.bindings]]
action = "Paste"
key = "Paste"
# Turn off vi mode
- { key: Space, mods: Shift|Control, mode: ~Search, action: ReceiveChar }
[[keyboard.bindings]]
action = "Copy"
key = "Copy"
# (Windows, Linux, and BSD only)
- { key: V, mods: Control|Shift, mode: ~Vi, action: Paste }
- { key: C, mods: Control|Shift, action: Copy }
- { key: F, mods: Control|Shift, mode: ~Search, action: ReceiveChar }
- { key: B, mods: Control|Shift, mode: ~Search, action: ReceiveChar }
- { key: Insert, mods: Shift, action: PasteSelection }
- { key: Key0, mods: Control, action: ResetFontSize }
- { key: Equals, mods: Control, action: IncreaseFontSize }
- { key: Plus, mods: Control, action: IncreaseFontSize }
- { key: NumpadAdd, mods: Control, action: IncreaseFontSize }
- { key: Minus, mods: Control, action: DecreaseFontSize }
- { key: NumpadSubtract, mods: Control, action: DecreaseFontSize }
[[keyboard.bindings]]
action = "ClearLogNotice"
key = "L"
mods = "Control"
[[keyboard.bindings]]
chars = "\f"
key = "L"
mode = "~Vi|~Search"
mods = "Control"
[[keyboard.bindings]]
action = "ScrollPageUp"
key = "PageUp"
mode = "~Alt"
mods = "Shift"
[[keyboard.bindings]]
action = "ScrollPageDown"
key = "PageDown"
mode = "~Alt"
mods = "Shift"
[[keyboard.bindings]]
action = "ScrollToTop"
key = "Home"
mode = "~Alt"
mods = "Shift"
[[keyboard.bindings]]
action = "ScrollToBottom"
key = "End"
mode = "~Alt"
mods = "Shift"
[[keyboard.bindings]]
action = "ReceiveChar"
key = "Space"
mode = "~Search"
mods = "Shift|Control"
[[keyboard.bindings]]
action = "Paste"
key = "V"
mode = "~Vi"
mods = "Control|Shift"
[[keyboard.bindings]]
action = "Copy"
key = "C"
mods = "Control|Shift"
[[keyboard.bindings]]
action = "ReceiveChar"
key = "F"
mode = "~Search"
mods = "Control|Shift"
[[keyboard.bindings]]
action = "ReceiveChar"
key = "B"
mode = "~Search"
mods = "Control|Shift"
[[keyboard.bindings]]
action = "PasteSelection"
key = "Insert"
mods = "Shift"
[[keyboard.bindings]]
action = "ResetFontSize"
key = "Key0"
mods = "Control"
[[keyboard.bindings]]
action = "IncreaseFontSize"
key = "Equals"
mods = "Control"
[[keyboard.bindings]]
action = "IncreaseFontSize"
key = "Plus"
mods = "Control"
[[keyboard.bindings]]
action = "IncreaseFontSize"
key = "NumpadAdd"
mods = "Control"
[[keyboard.bindings]]
action = "DecreaseFontSize"
key = "Minus"
mods = "Control"
[[keyboard.bindings]]
action = "DecreaseFontSize"
key = "NumpadSubtract"
mods = "Control"
[window]
dynamic_padding = true
opacity = 1
[window.padding]
x = 0
y = 0
[keyboard]
#+end_src
* Bottom
| Guix dependency | Description |
|-----------------------+---------------------------------------------|
| bottom-bin | resource monitor |
| Arch dependency | Description |
|-----------------+------------------|
| bottom | resource monitor |
[[https://github.com/ClementTsang/bottom][bottom]] is a TUI system monitor.
@ -941,12 +899,14 @@ See the [[https://github.com/ClementTsang/bottom/blob/master/sample_configs/defa
(if (my/light-p) "default-light" "default")
#+end_src
#+begin_src toml :tangle ~/.config/bottom/bottom.toml :noweb yes
#+begin_src toml :tangle .config/bottom/bottom.toml :noweb yes
[flags]
hide_table_gap = true # Remove space in tables
color = "<<bottom-theme()>>"
process_command = true
[styles]
theme = "<<bottom-theme()>>"
[processes]
columns = ["PID", "State", "Name", "CPU%", "Mem%", "R/s", "W/s", "User"]
#+end_src
@ -955,50 +915,47 @@ columns = ["PID", "State", "Name", "CPU%", "Mem%", "R/s", "W/s", "User"]
See [[https://docs.atuin.sh/configuration/config/][config reference]].
#+begin_src toml :tangle ~/.config/atuin/config.toml
#+begin_src toml :tangle .config/atuin/config.toml
update_check = false
enter_accept = true
keymap_mode = "vim-insert"
#+end_src
* Various console applications
| Guix dependency | Description |
|-----------------+---------------------------------------------|
| ncurses | Provides stuff like ~clear~ |
| exa | ~ls~ replacement, written in Rust |
| bat | ~cat~ clone with syntax highlighting |
| htop | Interactive process viewer |
| nethogs | A tool to group processed by used bandwidth |
| osync | rsync wrapper |
| neofetch | Fetch system info |
| fzf | fuzzy finder |
| p7zip | archiver |
| password-store | CLI password manager |
| zip | |
| unzip | |
| jmtpfs | A tool to mount MTP devices (e.g. Android) |
| tokei | Count lines of code |
| sshfs | Mount stuff over SSH |
| lftp | File transfer |
| git-lfs | |
| glibc-locales | |
| direnv | |
| jless-bin | JSON viewer |
| megacmd | mega.nz client |
| ncdu | disk usage analyzer |
| openssl | |
| aria2 | Download tool |
| man-db | |
| pv | |
| Arch dependency | Description | Disabled |
|-----------------+---------------------------------------------+----------|
| ncurses | Provides stuff like ~clear~ | |
| eza | ~ls~ replacement, written in Rust | |
| htop | Interactive process viewer | |
| nethogs | A tool to group processed by used bandwidth | |
| neofetch | Fetch system info | |
| fzf | fuzzy finder | |
| 7zip | archiver | |
| pass | CLI password manager | |
| zip | | |
| unzip | | |
| unrar | | |
| jmtpfs | A tool to mount MTP devices (e.g. Android) | t |
| tokei | Count lines of code | |
| sshfs | Mount stuff over SSH | |
| git-lfs | | |
| direnv | | |
| jless | JSON viewer | |
| megacmd | mega.nz client | |
| ncdu | disk usage analyzer | |
| openssl | | |
| aria2 | Download tool | |
| man-db | | |
| pv | | |
** ripgrep config
Occasionally I can't exclude certain files from ripgrep via the VCS settings, so here is a simple config to ignore certain files globally.
#+begin_src text :tangle ~/.config/ripgrep/ripgreprc
#+begin_src text :tangle .config/ripgrep/ripgreprc
--ignore-file=/home/pavel/.config/ripgrep/ripgrepignore
#+end_src
The ignore file:
#+begin_src text :tangle ~/.config/ripgrep/ripgrepignore
#+begin_src text :tangle .config/ripgrep/ripgrepignore
*.ts.snap
#+end_src
@ -1011,7 +968,7 @@ Usage:
nt <command>
#+end_example
#+begin_src sh :tangle ~/bin/scripts/nt
#+begin_src sh :tangle bin/scripts/nt
command="$@"
if [ ! -z "$command" ]; then
start_time="$(date -u +%s)"
@ -1045,7 +1002,7 @@ Here's roughly what the script is doing:
- Send a notification about the events above
- Send a separate notification if there is a merge conflict
#+begin_src bash :tangle ~/bin/scripts/autocommit
#+begin_src bash :tangle bin/scripts/autocommit
TIMEOUT_MIN=${TIMEOUT_MIN:-60}
export DISPLAY=:0
@ -1114,20 +1071,39 @@ fi
#+end_src
=mcron= job:
#+begin_src scheme :tangle ~/.config/cron/autocommit.guile
#+begin_src scheme :tangle .config/cron/autocommit.guile
(job "0 * * * *" "autocommit /home/pavel/30-39\\ Life/32\\ org-mode/")
(job "0,15,30,45 * * * *" "autocommit ~/.password-store")
#+end_src
* Guix settings
#+NAME: packages
#+begin_src emacs-lisp :tangle no :eval never-export
(my/format-guix-dependencies)
Systemd timers:
#+begin_src conf :tangle .config/systemd/user/autocommit-org-mode.service
[Unit]
Description=Autocommit org-mode
[Service]
Type=oneshot
ExecStart=/usr/bin/bash /home/pavel/bin/scripts/autocommit "/home/pavel/30-39 Life/32 org-mode"
#+end_src
#+begin_src scheme :tangle .config/guix/manifests/console.scm :noweb yes
(specifications->manifest
'(
<<packages()>>))
#+begin_src conf :tangle .config/systemd/user/autocommit-password-store.service
[Unit]
Description=Autocommit .password-store
[Service]
Type=oneshot
ExecStart=/usr/bin/bash /home/pavel/bin/scripts/autocommit "/home/pavel/.password-store"
#+end_src
* Arch settings
#+NAME: packages
#+begin_src emacs-lisp :tangle no
(when (fboundp #'my/format-arch-dependencies)
(my/format-arch-dependencies))
#+end_src
#+begin_src scheme :tangle .config/metapac/groups/console.toml :noweb yes
<<packages()>>
#+end_src
* Android notes
SSH instructions: https://wiki.termux.com/wiki/Remote_Access

File diff suppressed because it is too large Load diff

298
Emacs.org
View file

@ -85,6 +85,11 @@ First things first, lexical binding.
;;; -*- lexical-binding: t -*-
#+end_src
Adding =emacs= to the package list.
| Arch dependency |
|-----------------|
| emacs |
** straight.el
Straight.el is my Emacs package manager of choice. The following is its bootstrap script.
@ -237,6 +242,7 @@ So, first, specify how the modules are stored:
#+end_src
Then, scan =Emacs.org= for headings with the =MODULE_NAME= property and set the tangle property:
#+begin_src emacs-lisp
(defun my/modules--refresh-and-list ()
(let (modules-list
@ -1118,8 +1124,10 @@ This script is being run from the [[file:Desktop.org::*i3wm][i3 configuration]].
For this to work, we need to make sure that Emacs starts a server, so here is an expression to do just that:
#+BEGIN_SRC emacs-lisp
(unless (or my/remote-server my/nested-emacs)
(add-hook 'after-init-hook #'server-start))
;; (add-hook 'after-init-hook #'server-start)
)
#+END_SRC
Edit [2025-11-12 Wed]: This has stopped working with EXWM.
And here is a simple macro to do the Emacs -> i3 part:
#+begin_src emacs-lisp
@ -1371,7 +1379,7 @@ References:
I also want to call =xkb-switch= in EXWM buffers with the same keybindig.
| Guix dependency |
| Arch dependency |
|-----------------|
| xkb-switch |
@ -1604,7 +1612,7 @@ A few CLI alternatives:
"m" 'magit
"M" 'magit-file-dispatch)
:config
(require 'forge)
;; (require 'forge)
(setq magit-blame-styles
'((headings
(heading-format . "%-20a %C %s\n"))
@ -1630,9 +1638,9 @@ A few CLI alternatives:
:commands (git-timemachine))
#+end_src
| Guix dependency |
| Arch dependency |
|-----------------|
| difftastic-bin |
| difftastic |
[[https://github.com/pkryger/difftastic.el][difftastic.el]] is a wrapper package for [[https://difftastic.wilfred.me.uk/][difftastic]].
#+begin_src emacs-lisp
@ -2149,7 +2157,7 @@ References:
:MODULE_NAME: wakatime
:header-args:emacs-lisp: :tangle /home/pavel/.emacs.d/modules/sqrt-wakatime.el :comments links
:END:
Before I figure out how to package this for Guix:
Before I figure out how to package this for +Guix+ Arch:
- Clone [[https://github.com/wakatime/wakatime-cli][the repo]]
- Run ~go build~
- Copy the binary to the =~/bin= folder
@ -2162,6 +2170,7 @@ Before I figure out how to package this for Guix:
(advice-add 'wakatime-init :after
(lambda ()
(setq wakatime-cli-path (or
(executable-find "wakatime")
(executable-find "wakatime-cli")
(expand-file-name "~/bin/wakatime-cli")))))
(when (file-exists-p "~/.wakatime.cfg")
@ -2339,8 +2348,8 @@ My colorschemes of choice.
#+end_src
#+begin_src emacs-lisp
(use-package modus-themes
:straight t)
;; (use-package modus-themes
;; :straight (:build (:not native-compile)))
#+end_src
Let's see...
@ -2426,9 +2435,12 @@ Now, let's get the current color from =doom=. =doom-themes= provide =doom-color=
And the same for =modus-themes=. =my/modus-color= has to accept the same arguments as I use for =my/doom-color= for backward compatibility, which requires a bit more tuning.
#+begin_src emacs-lisp
(defun my/modus-get-base (color)
(let ((base-value (string-to-number (substring (symbol-name color) 4 5)))
(base-start (cadr (assoc 'bg-main (modus-themes--current-theme-palette))))
(base-end (cadr (assoc 'fg-dim (modus-themes--current-theme-palette)))))
(let* ((base-value (string-to-number (substring (symbol-name color) 4 5)))
(palette (modus-themes-get-theme-palette
(or (my/modus-p) (my/ef-p))
:with-overrides :with-user-palette))
(base-start (cadr (assoc 'bg-main palette)))
(base-end (cadr (assoc 'fg-dim palette))))
(nth base-value (ct-gradient 9 base-start base-end t))))
(defun my/prot-color (color palette)
@ -2468,10 +2480,11 @@ And the same for =modus-themes=. =my/modus-color= has to accept the same argumen
(t (cadr (assoc color palette))))))
(defun my/modus-color (color)
(my/prot-color color (modus-themes--current-theme-palette)))
(my/prot-color color (modus-themes-get-theme-palette
(or (my/modus-p) (my/ef-p))
:with-overrides :with-user-palette)))
(defun my/ef-color (color)
(my/prot-color color (ef-themes--current-theme-palette)))
(defalias 'my/ef-color 'my/modus-color)
#+end_src
Test the three functions.
@ -2556,9 +2569,13 @@ This macro puts lambdas to =my/my-theme-update-colors-hook= that updates faces i
collect (eval value)))))))
(enable-theme 'my-theme-1))
(defun my/advice-my-theme ()
(advice-add 'load-theme :after #'my/update-my-theme))
(unless my/is-termux
(advice-add 'load-theme :after #'my/update-my-theme)
(add-hook 'emacs-startup-hook #'my/update-my-theme))
(add-hook 'emacs-startup-hook #'my/update-my-theme)
;; (add-hook 'emacs-startup-hook #'my/advice-my-theme)
)
#+end_src
Defining colors for =tab-bar.el=:
@ -2585,6 +2602,7 @@ The built-in =load-theme= does not deactivate the previous theme, so here's a fu
(eq enabled-theme theme)))
do (disable-theme enabled-theme))
(load-theme theme t)
(my/update-my-theme)
(when current-prefix-arg
(my/regenerate-desktop)))
#+end_src
@ -3343,6 +3361,7 @@ I'm not actually using that, but its query editor is pretty useful to debug =tre
#+begin_src emacs-lisp
(use-package combobulate
:straight (:host github :repo "mickeynp/combobulate")
:disabled
:commands (combobulate))
#+end_src
*** DAP
@ -4220,7 +4239,7 @@ Section snippets. The code turned out to be more complicated than just writing t
:straight t)
#+end_src
*** PlantUML
| Guix dependency |
| Arch dependency |
|-----------------|
| plantuml |
@ -4530,9 +4549,9 @@ Automatically creates & manages virtualenvs and stores data in =Pipfile= and =Pi
*** OFF (OFF) yapf
[[https://github.com/google/yapf][yapf]] is a formatter for Python files.
| Guix dependency |
| Arch dependency |
|-----------------|
| python-yapf |
| yapf |
References:
- [[https://github.com/google/yapf][yapf repo]]
@ -4556,7 +4575,7 @@ column_limit = 80
*** black
[[https://github.com/psf/black][black]] is a formatter for Python files.
| Guix dependency |
| Arch dependency |
|-----------------|
| python-black |
@ -4571,7 +4590,7 @@ column_limit = 80
*** isort
[[https://github.com/PyCQA/isort][isort]] is a Python package to sort Python imports.
| Guix dependency |
| Arch dependency |
|-----------------|
| python-isort |
@ -4694,7 +4713,7 @@ To fix that, I've modified the following function in the =python-pytest= package
*** code-cells
Support for text with magic comments.
| Guix dependency | Disabled |
| Arch dependency | Disabled |
|-----------------+----------|
| python-jupytext | t |
@ -4967,7 +4986,7 @@ Emacs integration for [[http://gnuplot.info/][gnuplot]].
:header-args:emacs-lisp: :tangle /home/pavel/.emacs.d/modules/sqrt-misc-programming.el :comments links
:END:
*** C#
| Guix dependencies | Disabled |
| Arch dependencies | Disabled |
|-------------------+----------|
| omnisharp | t |
| dotnet | t |
@ -6146,6 +6165,8 @@ We can get the clocked value in minutes with =org-clock-sum=. This weird functio
(org-element-property :end element))))
(with-temp-buffer
(insert s)
(let (org-mode-hook)
(org-mode))
(org-clock-sum)
org-clock-file-total-minutes)))
#+end_src
@ -7191,9 +7212,8 @@ Some resources that helped me along the way (and still help):
- [[https://www.youtube.com/watch?v=-TpWahIzueg][System Crafters Live! - Can You Apply Zettelkasten in Emacs?]]
**** Basic package configuration
| Guix dependency | Disabled |
| Arch dependency | Disabled |
|-----------------------+----------|
| emacs-emacsql-sqlite3 | t |
| graphviz | |
About installing the package on Guix (*CREDIT*: thanks @Ashraz on the SystemCrafters discord)
@ -8104,10 +8124,10 @@ No idea why, but somehow the exported file uses english words if there isn't =:d
** System configuration
Functions related to literate configuration.
*** Tables for Guix Dependencies
This section deals with using [[https://guix.gnu.org/en/cookbook/en/html_node/Advanced-package-management.html#Advanced-package-management][using profiles in GNU Guix]].
*** Tables for Arch Dependencies
I used to use [[https://guix.gnu.org/en/cookbook/en/html_node/Advanced-package-management.html#Advanced-package-management][profiles in GNU Guix]]. Now that I've switched to [[https://github.com/ripytide/metapac][metapac]], I want to keep the same approach.
A "profile" in Guix is a way to group package installations. For instance, I have a "music" profile that has software like [[https://www.musicpd.org/][MPD]], [[https://github.com/ncmpcpp/ncmpcpp][ncmpcpp]] that I'm still occasionally using because of its tag editor, etc. Corresponding to that profile, there's a manifest named =music.scm= that looks like this:
A "profile" (metapac calls them "groups") is a way to group package installations. For instance, I have a "music" profile that has software like [[https://www.musicpd.org/][MPD]], [[https://github.com/ncmpcpp/ncmpcpp][ncmpcpp]] that I'm still occasionally using because of its tag editor, etc. In Guix, corresponding to that profile, there's a manifest named =music.scm= that looks like this:
#+begin_src scheme
(specifications->manifest
'(
@ -8121,12 +8141,12 @@ A "profile" in Guix is a way to group package installations. For instance, I hav
"mpd"))
#+end_src
I could generate this file with =org-babel= as any other, but that is often not so convenient. For example, I have a [[https://github.com/polybar/polybar][polybar]] module that uses [[https://github.com/risacher/sunwait][sunwait]] to show sunset and sunrise times, and ideally, I want to declare =sunwait= to be in the "desktop-polybar" profile in the same section that has the polybar module definition and the bash script.
Metapac stores the same info in TOML. I could generate this file with =org-babel= as any other, but that is often not so convenient. For example, I have a [[https://github.com/polybar/polybar][polybar]] module that uses [[https://github.com/risacher/sunwait][sunwait]] to show sunset and sunrise times, and ideally, I want to declare =sunwait= to be in the "desktop-polybar" profile in the same section that has the polybar module definition and the bash script.
So here's an approach I came up with. The relevant section of the config looks like this:
#+begin_example
,*** sun
| Category | Guix dependency |
| Category | Arch dependency |
|-----------------+-----------------|
| desktop-polybar | sunwait |
@ -8141,17 +8161,18 @@ Prints out the time of sunrise/sunset. Uses [[https://github.com/risacher/sunwai
,#+end_src
#+end_example
So =sunwait= is declared in an Org table with =Guix dependency= in the header. Such tables are spread through my configuration files.
So =sunwait= is declared in an Org table with =Arch dependency= in the header. Such tables are spread through my configuration files.
Thus I made a function that extracts packages from all such tables from the current Org buffer. The rules are as follows:
- If a column name matches =[G|g]uix.*dep=, its contents are added to the result.
- If a column name matches =[A|a]rch.*dep=, its contents are added to the result.
- If =CATEGORY= is passed, a column with name =[C|c]ategory= is used to filter results. That way, one Org file can be used to produce multiple manifests.
- If =CATEGORY= is not passed, entries with the non-empty category are filtered out
- If there is a =[D|d]isabled= column, entries that have a non-empty value in this column are filtered out.
- If there is a =[S|s]ource= column, it selects the backend for metapac, which is =arch= by default.
And here is the implementation:
#+begin_src emacs-lisp :noweb-ref guix-tables
(defun my/extract-guix-dependencies (&optional category)
(defun my/extract-arch-dependencies (&optional category)
(let ((dependencies '()))
(org-table-map-tables
(lambda ()
@ -8164,7 +8185,7 @@ And here is the implementation:
nil
(mapcar #'substring-no-properties (nth 0 table))
:test (lambda (_ elem)
(string-match-p "[G|g]uix.*dep" elem))))
(string-match-p "[A|a]rch.*dep" elem))))
(category-name-index
(cl-position
nil
@ -8176,7 +8197,13 @@ And here is the implementation:
nil
(mapcar #'substring-no-properties (nth 0 table))
:test (lambda (_ elem)
(string-match-p ".*[D|d]isabled.*" elem)))))
(string-match-p ".*[D|d]isabled.*" elem))))
(source-index
(cl-position
nil
(mapcar #'substring-no-properties (nth 0 table))
:test (lambda (_ elem)
(string-match-p ".*[S|s]ource.*" elem)))))
(when dep-name-index
(dolist (elem (cdr table))
(when
@ -8196,47 +8223,48 @@ And here is the implementation:
(or
(not disabled-name-index)
(string-empty-p (nth disabled-name-index elem))))
(add-to-list
'dependencies
(substring-no-properties (nth dep-name-index elem)))))))))
(let ((source
(or
(when (and source-index
(not (string-empty-p (nth source-index elem))))
(substring-no-properties
(nth source-index elem)))
"arch")))
(push
(substring-no-properties (nth dep-name-index elem))
(alist-get source dependencies nil nil #'equal)))))))))
dependencies))
#+end_src
To make it work in the configuration, it is necessary to format the list so that Scheme could read it:
To make it work in the configuration, it is necessary to format the list in the TOML format. Unfortunately, there doesn't seems to be a TOML generator for Elisp.
#+begin_src emacs-lisp :noweb-ref guix-tables
(defun my/format-guix-dependencies (&optional category)
(mapconcat
(lambda (e) (concat "\"" e "\""))
(my/extract-guix-dependencies category)
"\n"))
(defun my/format-arch-dependencies (&optional category)
(let ((data (my/extract-arch-dependencies category)))
(with-temp-buffer
(cl-loop for (backend . packages) in data
do (insert (format "%s = [\n" backend)
(mapconcat (lambda (package)
(format "\"%s\"," package))
packages
"\n")
"]"))
(buffer-string))))
#+end_src
And we need an Org snippet such as this:
#+begin_example
#+NAME: packages
#+begin_src emacs-lisp :tangle no :var category=""
(my/format-guix-dependencies category)
(my/format-arch-dependencies category)
#+end_src
#+end_example
Now, creating a manifest, for example, for the =desktop-polybar= profile is as simple as:
#+begin_example
#+begin_src scheme :tangle ~/.config/guix/manifests/desktop-polybar.scm :noweb yes
(specifications->manifest
'(
<<packages("desktop-polybar")>>))
#+begin_src scheme :tangle ~/.config/metapac/groups/desktop-polybar.toml :noweb yes
<<packages("desktop-polybar")>>
#+end_src
#+end_example
There's a newline symbol between "(" and =<<packages("desktop-polybar")>>= because whenever a noweb expression expands into multiple lines, for each new line noweb duplicates contents between the start of the line and the start of the expression.
One reason this is so is to support languages where indentation is a part of the syntax, for instance, Python:
#+begin_src python
class TestClass:
<<class-contents>>
#+end_src
So every line of =<<class-contents>>= will be indented appropriately. In our case though, it is a minor inconvenience to be aware of.
*** Noweb evaluations
One note is that by default running these commands will require the user to confirm evaluation of each code block. To avoid that, I set =org-confirm-babel-evaluate= to =nil=:
@ -8247,6 +8275,7 @@ One note is that by default running these commands will require the user to conf
'("~/Emacs.org"
"~/Desktop.org"
"~/Console.org"
"~/Arch.org"
"~/Guix.org"
"~/Mail.org")))
@ -8467,7 +8496,8 @@ Display icons for files.
(string-match-p "/gnu/store" default-directory))
(nerd-icons-dired-mode))))
:config
(advice-add #'dired-create-empty-file :around #'nerd-icons-dired--refresh-advice))
;; (advice-add #'dired-create-empty-file :around #'nerd-icons-dired--refresh-advice)
)
#+end_src
Provides stuff like =dired-open-xdg=
@ -9426,6 +9456,7 @@ Finally, a function that inserts the overlay in buffer if it's available and cal
#+begin_src emacs-lisp
(use-package eshell-atuin
:straight (:host github :repo "SqrtMinusOne/eshell-atuin")
:when (executable-find "atuin")
:after eshell
:config
(eshell-atuin-mode)
@ -9790,7 +9821,7 @@ Now, a function to add a YouTube link with metadata from elfeed to EMMS.
*** rdrview
[[https://github.com/eafer/rdrview][rdrview]] is a command-line tool to strip webpages from clutter, extracting only parts related to the actual content. It's a standalone port of the corresponding feature of Firefox, called [[https://support.mozilla.org/en-US/kb/firefox-reader-view-clutter-free-web-pages][Reader View]].
| Guix dependency |
| Arch dependency |
|-----------------|
| rdrview |
@ -10137,7 +10168,7 @@ However, sans the pictures issue, for certain sites like Wikipedia this is usabl
**** Getting subtitles
Finally, let's get to transcripts.
| Guix dependency |
| Arch dependency |
|-------------------------------|
| python-youtube-transcript-api |
@ -10402,6 +10433,8 @@ References:
;; I have everything I need in polybar
(emms-mode-line-mode -1)
(emms-playing-time-display-mode -1)
(delq 'emms-mark-mode evil-emacs-state-modes)
(delq 'emms-browser-mode evil-emacs-state-modes)
<<emms-fixes>>)
#+end_src
**** MPD
@ -10445,7 +10478,7 @@ After all this is done, run =M-x emms-cache-set-from-mpd-all= to set cache from
:PROPERTIES:
:header-args:emacs-lisp: :tangle no :noweb-ref emms-mpv-setup
:END:
| Guix dependency |
| Arch dependency |
|-----------------|
| mpv |
| yt-dlp |
@ -11390,16 +11423,15 @@ Or you can load up Element for a moment to see what the mention was, if that's e
:END:
[[https://github.com/zevlg/telega.el/][telega.el]] is a Telegam client for Emacs.
| Guix dependency |
|--------------------|
| emacs-telega-sever |
| font-gnu-unifont |
| font-gnu-freefont |
| Arch dependency | Disabled |
|--------------------+----------|
| emacs-telega-sever | t |
| telegram-tdlib | |
| ttf-unifont | |
| gnu-free-fonts | |
#+begin_src emacs-lisp
(use-package telega
;; :straight (:type built-in)
;; For now emacs-telega-server is compatible with the latest telega.el
:straight t
:commands (telega)
:init
@ -11411,10 +11443,8 @@ Or you can load up Element for a moment to see what the mention was, if that's e
:background (my/color-value 'fg))
(telega-entity-type-spoiler :background (my/color-value 'base8)))
:config
(when (file-exists-p "~/.guix-extra-profiles/emacs/emacs/bin/telega-server")
(setq telega-server-command
(expand-file-name
"~/.guix-extra-profiles/emacs/emacs/bin/telega-server")))
(setq telega-server-libs-prefix "/usr")
(setq telega-emoji-use-images nil)
(setq telega-chat-fill-column 80)
(setq telega-completing-read-function #'completing-read)
@ -11438,18 +11468,6 @@ Or you can load up Element for a moment to see what the mention was, if that's e
telega-webpage-mode 3 "telega"))
#+end_src
Building =telega-server= can create problems. On Guix I can use the Guix package definition, on termux just build manually.
#+begin_src emacs-lisp
(defun my/telega-server-build ()
(interactive)
(setq telega-server-libs-prefix
(if (executable-find "guix")
(string-trim
(shell-command-to-string "guix build tdlib"))
(expand-file-name "~/bin/td/build/res/usr/local")))
(telega-server-build "CC=gcc"))
#+end_src
Setting up the modeline. The default mode string doesn't look great with my other modeline modules, so I override that.
#+begin_src emacs-lisp
(add-hook 'telega-load-hook #'telega-mode-line-mode)
@ -11939,7 +11957,7 @@ I previously used [[https://github.com/ggerganov/whisper.cpp][whisper.cpp]] by G
One disadvantage is that it doesn't produce human-readable output by default, so I make my own.
| Guix dependency | Disabled |
| Arch dependency | Disabled |
|-----------------+----------|
| whisper-cpp | t |
@ -12770,6 +12788,10 @@ The return value is a list of commands as defined by
#+RESULTS:
: my/index--mega-commands
**** rclone
| Arch dependency |
|-----------------|
| rclone |
This section wraps the [[https://rclone.org/bisync/][bisync]] command for rclone, which implements two-way sync.
The general approach is:
@ -12791,7 +12813,6 @@ First, default options for =rclone bisync=:
A [[https://rclone.org/bisync/#filtering][filters file]] for rclone:
#+begin_src text :tangle ~/.config/rclone/filters-bisync
- .*
- ~*
- .debris
#+end_src
@ -12851,8 +12872,11 @@ REMOTE = '<rclone-remote>'
FOLDERS = json.loads('<rclone-folders-json>')
OPTIONS = json.loads('<rclone-options>')
for folder, i in zip(FOLDERS, range(len(FOLDERS))):
folder['id'] = i
def rclone_make_command(local_path, remote_path, remote):
def rclone_make_command(local_path, remote_path, remote, extra_args=[]):
return [
'rclone',
'bisync',
@ -12866,7 +12890,8 @@ def rclone_make_command(local_path, remote_path, remote):
'NEVER',
'--use-json-log',
'--stats',
'9999m'
'9999m',
,*extra_args
]
@ -12894,15 +12919,26 @@ def process_output(output):
except Exception:
print(line)
def rclone_run(folder):
def process_command_for_print(command):
res = []
for c in command:
if ' ' in c:
res.append(f'\\'{c}\\'')
else:
res.append(c)
return ' '.join(res)
def rclone_run(folder, extra_args=[]):
command = rclone_make_command(
folder['local-path'], folder['remote-path'], folder['remote']
folder['local-path'], folder['remote-path'], folder['remote'], extra_args
)
try:
print(str(folder['id']) + '. ' + process_command_for_print(command))
result = subprocess.run(command, check=True, capture_output=True, text=True)
except subprocess.CalledProcessError as e:
print(f'=== Error syncing {folder['local-path']} ===')
print(f'Command: {' '.join(command)}')
print(f'Command: {process_command_for_print(command)}')
print(f'--- STDOUT ---')
process_output(e.stdout)
print(f'--- STDERR ---')
@ -12910,7 +12946,6 @@ def rclone_run(folder):
return {'success': False, 'stats': {}}
return {'success': True, 'stats': parse_rclone_stats(result.stderr)}
def notify(summary, body, level='normal', expire_time=5000):
subprocess.run(['notify-send', '-u', level, '-t', str(expire_time), summary, body])
@ -12923,17 +12958,16 @@ def sizeof_fmt(num, suffix='B'):
return f'{num:.1f}Yi{suffix}'
def rclone_run_all(folders):
def rclone_run_all(folders, extra_args=[]):
error_folders = []
total_bytes = 0
total_transfers = 0
total_deleted = 0
total_renamed = 0
for folder in folders:
print(f'Running rclone for {folder}')
res = rclone_run(folder)
res = rclone_run(folder, extra_args)
if not res['success']:
error_folders.append(folder['local-path'])
error_folders.append(folder)
else:
total_bytes += res.get('stats', {}).get('bytes', 0)
total_transfers += res.get('stats', {}).get('transfers', 0)
@ -12945,21 +12979,44 @@ def rclone_run_all(folders):
if total_transfers > 0:
msg += f'''Transferred {total_transfers} files ({sizeof_fmt(total_bytes)})\n'''
if total_deleted > 0:
msg += f'''Deleted {total_transfers} files\n'''
msg += f'''Deleted {total_deleted} files\n'''
if total_renamed > 0:
msg += f'''Renamed {total_renamed} files\n'''
if len(error_folders) > 0:
msg += '''\nSync errors for the following folders:'''
for folder in error_folders:
msg += '''\n- ''' + folder
msg += '''\n- ''' + str(folder['id']) + '. ' + folder['local-path']
level = 'critical'
if len(msg) > 0:
notify(f'rclone sync {REMOTE}', msg, level=level)
def parse_arguments():
if len(sys.argv) < 2:
return None, []
id_arg = sys.argv[1]
folder_ids = [int(x.strip()) for x in id_arg.split(',')]
extra_args = sys.argv[2:]
return folder_ids, extra_args
if __name__ == '__main__':
rclone_run_all(FOLDERS)
folder_ids, extra_args = parse_arguments()
if folder_ids is None:
selected_folders = FOLDERS
else:
selected_folders = [f for f in FOLDERS if f['id'] in folder_ids]
found_ids = {f['id'] for f in selected_folders}
missing_ids = set(folder_ids) - found_ids
if missing_ids:
print(f'Warning: folder IDs not found: {sorted(missing_ids)}')
rclone_run_all(selected_folders, extra_args)
#+end_src
A function that templates the script above:
@ -13054,6 +13111,26 @@ The return value is a list of commands as defined by
(nreverse commands)))
#+end_src
Also, a command to remove all =.rclone-test-*= files. This is necessary, e.g. after a change in the filter file.
#+begin_src emacs-lisp
(defun my/index-rclone-reset ()
"Delete all rclone test files."
(interactive)
(let* ((tree (my/index--tree-retrive))
(folders (my/index--rclone-get-folders tree))
files-to-delete)
(dolist (folder folders)
(let ((test-file-path
(concat
(alist-get :local-path folder)
(format ".rclone-test-%s" (alist-get :remote folder)))))
(when (file-exists-p test-file-path)
(push test-file-path files-to-delete))))
(when (y-or-n-p (format "Delete %d files" (seq-length files-to-delete)))
(dolist (file files-to-delete)
(delete-file file)))))
#+end_src
**** Git repos
To sync git, we just need to clone the required git repos. Removing the repos is handled by the folder sync commands.
@ -13601,7 +13678,7 @@ My package for doing Pomodoro timer.
*** hledger
[[hledger.org/][hledger]] is a plain-text double-entry accounting software. I use it for managing my personal finances, and thus far it's great.
| Guix dependency |
| Arch dependency |
|-----------------|
| hledger |
@ -14140,22 +14217,19 @@ My text editor isn't old enough.
:straight (:host github :repo "ryanprior/ed-mode")
:commands (ed))
#+end_src
* Guix settings
| Guix dependency | Description |
* Arch settings
| Arch dependency | Description |
|---------------------+-------------------------------|
| emacs-vterm | The vterm package |
| ripgrep | A recursive search tool |
| the-silver-searcher | Another recursive search tool |
| the_silver_searcher | Another recursive search tool |
| texinfo | |
#+NAME: packages
#+begin_src emacs-lisp :tangle no
(when (fboundp #'my/format-guix-dependencies)
(my/format-guix-dependencies))
(when (fboundp #'my/format-arch-dependencies)
(my/format-arch-dependencies))
#+end_src
#+begin_src scheme :tangle .config/guix/manifests/emacs.scm :noweb yes
(specifications->manifest
'("emacs"
<<packages()>>))
#+begin_src scheme :tangle .config/metapac/groups/emacs.toml :noweb yes
<<packages()>>
#+end_src

View file

@ -19,9 +19,9 @@ References:
- [[https://sqrtminusone.xyz/posts/2021-02-27-gmail/][My post]] about email configuration. I wrote it some time ago, but the general idea remains.
* Lieer
| Guix dependency |
| Arch dependency |
|-----------------|
| python-lieer |
| lieer-git |
Lieer is a program to link up Gmail and notmuch. Basically, it downloads mail from Gmail via API, stores them in Maildir, and synchronizes labels with notmuch.
@ -40,7 +40,13 @@ gmi set --ignore-tags-local new
Running =gmi sync= in the required directory performs the synchronization. The first sync takes a while, the subsequent syncs are pretty fast.
* DavMail
[[davmail.sourceforge.net][DavMail]] is a gateway between MS Exchange and the rest of the world, which uses IMAP/SMTP/LDAP/etc. As I have one corporate MS Exchange address, this is just the program I need. As of yet, it isn't packaged for Guix, but it's easy enough to download.
[[davmail.sourceforge.net][DavMail]] is a gateway between MS Exchange and the rest of the world, which uses IMAP/SMTP/LDAP/etc. As I have one corporate MS Exchange address, this is just the program I need.
Edit [2025-11-11 Tue]: We've moved from MS Exhange, disabling this.
| Arch dependency | Disabled |
|-----------------+----------|
| davmail | t |
It has a GUI mode, but I prefer headless config.
#+begin_src conf-unix :tangle ~/bin/davmail-6.0.0-3375/davmail.properties
@ -68,7 +74,7 @@ cd $HOME/bin/davmail-6.0.0-3375
Shepherd service is defined in [[file:Desktop.org::*Davmail][Desktop.org]].
* OfflineIMAP
| Guix dependency |
| Arch dependency |
|-----------------|
| offlineimap |
@ -129,7 +135,7 @@ remoteport = 993
cert_fingerprint = 20bbfdcb617e4695c47a90af96e40d72a57adee4
#+end_src
* Notmuch
| Guix dependency |
| Arch dependency |
|-----------------|
| notmuch |
| parallel |
@ -292,7 +298,7 @@ echo "Running pre-new filters"
<<mail-tags(move="t",archive_root="Archive",root="pvkorytov_etu_mbox")>>
echo "Pre-new filters done"
parallel --link -j0 "(cd /home/pavel/Mail/{1}/ && {2} {3})" ::: thexcloud progin6304 pvkorytov_etu ::: "$GMI" "$GMI" "offlineimap" ::: sync sync ""
parallel --link -j0 "(cd /home/pavel/Mail/{1}/ && {2} {3})" ::: thexcloud progin6304 pvkorytov_etu ::: "$GMI" "$GMI" "offlineimap" ::: sync sync "-a pvkorytov-mbox"
#+end_src
*** =post_new=
@ -352,12 +358,35 @@ fi
echo "$(date +%s)" > $CHECK_FILE
#+end_src
The script is ran via GNU Mcron every 5 minutes.
#+begin_src scheme :tangle ~/.config/cron/mail.guile
(job "*/5 * * * * " "~/bin/scripts/check-email")
The script is ran via systemd every 5 minutes.
#+begin_src conf :tangle .config/systemd/user/notmuch.service
[Unit]
Description=Update notmuch mail index
[Service]
Type=oneshot
ExecStart=/usr/bin/bash /home/pavel/bin/scripts/check-email
#+end_src
#+begin_src conf :tangle .config/systemd/user/notmuch.timer
[Unit]
Description=Run notmuch sync script every 5 minutes
[Timer]
OnBootSec=1min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
#+end_src
Don't forget to run:
#+begin_src bash
systemctl --user enable --now notmuch.timer
#+end_src
* MSMTP
| Guix dependency |
| Arch dependency |
|-----------------|
| msmtp |
@ -405,9 +434,9 @@ msmtp --serverinfo --tls --tls-certcheck=off -a pvkorytov
:header-args+: :tangle ~/.emacs.d/mail.el
:END:
| Guix dependency |
| Arch dependency |
|-----------------|
| emacs-notmuch |
| notmuch |
Finally, Emacs configuration. Let's start with some variables:
#+begin_src emacs-lisp
@ -415,6 +444,8 @@ Finally, Emacs configuration. Let's start with some variables:
(setq user-full-name "Pavel Korytov")
#+end_src
TODO fix for Arch
Then, the problem with my Guix setup is that Emacs by default doesn't see the elisp files of notmuch, so here is a small workaround:
#+begin_src emacs-lisp
(let ((dir "/home/pavel/.guix-extra-profiles/mail/mail/share/emacs/site-lisp"))
@ -693,14 +724,12 @@ application/postscript ; zathura %s
text/html; firefox %s
#+end_src
* Guix settings
* Arch settings
#+NAME: packages
#+begin_src emacs-lisp :tangle no
(my/format-guix-dependencies)
(my/format-arch-dependencies)
#+end_src
#+begin_src scheme :tangle .config/guix/manifests/mail.scm :noweb yes
(specifications->manifest
'(
<<packages()>>))
#+begin_src scheme :tangle .config/metapac/groups/mail.toml :noweb yes
<<packages()>>
#+end_src

View file

@ -35,5 +35,5 @@ notmuch search --output=files "NOT path:pvkorytov_etu_mbox/Etu.Grad_School/cur/*
notmuch search --output=files "NOT path:pvkorytov_etu_mbox/Archive/cur/** AND path:pvkorytov_etu_mbox/** AND NOT tag:inbox AND NOT tag:sent AND NOT tag:spam AND NOT tag:trash AND NOT tag:job.digital AND NOT tag:job.digital.docs AND NOT tag:job.digital.support AND NOT tag:job.digital.superservice AND NOT tag:job.digital.applicants AND NOT tag:job.digital.testers AND NOT tag:job.moevm AND NOT tag:etu AND NOT tag:etu.grad-school AND tag:pvkorytov" | xargs -I ! mv ! ~/Mail/pvkorytov_etu_mbox/Archive/cur/
echo "Pre-new filters done"
parallel --link -j0 "(cd /home/pavel/Mail/{1}/ && {2} {3})" ::: thexcloud progin6304 pvkorytov_etu ::: "$GMI" "$GMI" "offlineimap" ::: sync sync ""
parallel --link -j0 "(cd /home/pavel/Mail/{1}/ && {2} {3})" ::: thexcloud progin6304 pvkorytov_etu ::: "$GMI" "$GMI" "offlineimap" ::: sync sync "-a pvkorytov-mbox"
# =pre_new=:2 ends here

View file

@ -9,7 +9,7 @@ I use the [[https://leanpub.com/lit-config/read][literate configuration]] strate
The files themselves are managed and deployed via [[https://yadm.io/][yadm]], although I use Org Mode for things like config templating.
My current GNU/Linux distribution is [[https://guix.gnu.org/][GNU Guix]]. I like Guix because, among other things, it allows [[https://guix.gnu.org/cookbook/en/html_node/Advanced-package-management.html#Advanced-package-management][to declare the required software]] in configuration files, so I can have the same set of programs across multiple machines (look for tables with "Guix dependency" in the header).
My current GNU/Linux distribution is [[https://guix.gnu.org/][Arch Linux]], managed declaratively with [[https://github.com/ripytide/metapac][metapac]] (look for tables with "Arch dependency" in the header). I used to use Guix for the same purpose for 4.5 years; I keep the config now for archival purposes.
The central program to all of that is, of course, [[https://www.gnu.org/software/emacs/][GNU Emacs]]. At the time of this writing, it takes ~50% of my screen time and has the largest share of configuration here.
@ -22,15 +22,14 @@ Table of contents and software:
- [[file:Console.org][Console.org]]
- /Active/: [[file:Console.org::*=.profile=][.profile]], [[file:Console.org::*Bash][Bash]], [[file:Console.org::*Fish][Fish]], [[file:Console.org::*Starship prompt][Starship]], [[file:Console.org::*Tmux][Tmux]], [[file:Console.org::*Alacritty][Alacritty]]
- /In Limbo/: [[file:Console.org::*Nushell][Nushell]]
- [[file:Guix.org][Guix.org]]
- [[file:Arch.org][Arch.org]]
- [[file:Mail.org][Mail.org]]
- /Active/: [[file:Mail.org::*Lieer][Lieer]], [[file:Mail.org::*DavMail][DavMail]], [[file:Mail.org::*OfflineIMAP][OfflineIMAP]], [[file:Mail.org::*Notmuch][Notmuch]]
- [[file:Guix.org][Guix.org]] (archive)
(/Apparently, links on the second level work only in Emacs 🙁/)
A few other repositories I may consider a part of my config:
- [[https://github.com/SqrtMinusOne/channel-q][channel-q]] is my Guix channel
- [[https://github.com/SqrtMinusOne/sqrt-data][sqrt-data]] is a home for my statistics gathering effort
- [[https://sqrtminusone.xyz/emacs-packages/][My Emacs Packages]], some of which originated in my Emacs config
See also [[https://sqrtminusone.xyz/posts/][my blog posts]].

View file

@ -1,16 +0,0 @@
# [[file:../../Mail.org::*DavMail][DavMail:1]]
davmail.server=true
davmail.mode=Auto
davmail.url=https://mail.etu.ru/owa/
davmail.server.certificate.hash=0C:9E:CF:D3:62:26:DB:FA:F1:EE:36:9D:60:E7:31:71:CF:1F:92:85
davmail.caldavPort=1080
davmail.imapPort=1143
davmail.ldapPort=1389
davmail.popPort=1110
davmail.smtpPort=1025
davmail.imapAutoExpunge=false
davmail.enableKeepalive=false
# DavMail:1 ends here

View file

@ -1,8 +0,0 @@
#!/usr/bin/env bash
# [[file:../../Guix.org::*Slack][Slack:2]]
echo "LSB Version: Hey. I spent an hour figuring out why Slack doesn't launch."
echo "Distributor ID: It seems like it requires an lsb_release."
echo "Description: But GNU Guix doesn't have one."
echo "Release: 42.2"
echo "Codename: n/a"
# Slack:2 ends here

View file

@ -12,6 +12,8 @@ elif [ "$hostname" = "eminence" ]; then
fi
elif [ "$hostname" = "iris" ]; then
TRAY_MONITOR="HDMI-1"
elif [ "$hostname" = "weiss" ]; then
TRAY_MONITOR="eDP-1"
else
TRAY_MONITOR="DP-1"
fi
@ -25,6 +27,7 @@ declare -A FONT_SIZES=(
["HDMI-1"]="13"
["HDMI-0"]="13"
["DP-1"]="13"
["Virtual-1"]="13"
)
declare -A EMOJI_SCALE=(
["eDP"]="9"
@ -34,6 +37,7 @@ declare -A EMOJI_SCALE=(
["HDMI-1"]="10"
["HDMI-0"]="10"
["DP-1"]="10"
["Virtual-1"]="13"
)
declare -A BAR_HEIGHT=(
["eDP"]="29"
@ -43,6 +47,7 @@ declare -A BAR_HEIGHT=(
["HDMI-1"]="29"
["HDMI-0"]="29"
["DP-1"]="29"
["Virtual-1"]="29"
)
declare -A BLOCKS=(
["eDP"]="glyph-background--light-magenta pulseaudio glyph-light-magenta--magenta mpd glyph-magenta--cyan cpu glyph-cyan--cyan temperature glyph-cyan--cyan battery glyph-cyan--light-green ram-memory glyph-light-green--green swap-memory glyph-green--light-red bandwidth openvpn glyph-light-red--red xkeyboard glyph-red--light-yellow weather glyph-light-yellow--yellow sun glyph-yellow--light-blue aw-afk glyph-light-blue--blue date glyph-blue--background "
@ -52,6 +57,7 @@ declare -A BLOCKS=(
["HDMI-1"]="glyph-background--light-magenta pulseaudio glyph-light-magenta--magenta mpd glyph-magenta--cyan cpu glyph-cyan--cyan temperature glyph-cyan--cyan battery glyph-cyan--light-green ram-memory glyph-light-green--green swap-memory glyph-green--light-red bandwidth openvpn glyph-light-red--red xkeyboard glyph-red--light-yellow weather glyph-light-yellow--yellow sun glyph-yellow--light-blue aw-afk glyph-light-blue--blue date glyph-blue--background "
["HDMI-0"]="glyph-background--light-magenta pulseaudio glyph-light-magenta--magenta mpd glyph-magenta--light-cyan nvidia glyph-light-cyan--cyan cpu glyph-cyan--cyan temperature glyph-cyan--light-green ram-memory glyph-light-green--green swap-memory glyph-green--light-red bandwidth openvpn glyph-light-red--red xkeyboard glyph-red--light-yellow weather glyph-light-yellow--yellow sun glyph-yellow--light-blue aw-afk glyph-light-blue--blue date glyph-blue--background "
["DP-1"]="glyph-background--light-magenta pulseaudio glyph-light-magenta--magenta mpd glyph-magenta--light-cyan nvidia glyph-light-cyan--cyan cpu glyph-cyan--cyan temperature glyph-cyan--light-green ram-memory glyph-light-green--green swap-memory glyph-green--light-red bandwidth openvpn glyph-light-red--red xkeyboard glyph-red--light-yellow weather glyph-light-yellow--yellow sun glyph-yellow--light-blue aw-afk glyph-light-blue--blue date glyph-blue--background "
["Virtual-1"]="glyph-background--light-magenta pulseaudio glyph-light-magenta--magenta mpd glyph-magenta--cyan cpu glyph-cyan--cyan temperature glyph-cyan--light-green ram-memory glyph-light-green--green swap-memory glyph-green--light-red bandwidth openvpn glyph-light-red--red xkeyboard glyph-red--light-yellow weather glyph-light-yellow--yellow sun glyph-yellow--light-blue aw-afk glyph-light-blue--blue date glyph-blue--background "
)
declare -A TEMP_HWMON_PATHS=(

View file

@ -4,7 +4,7 @@ afk_event=$(curl -s -X GET "http://localhost:5600/api/0/buckets/aw-watcher-afk_$
status=$(echo ${afk_event} | jq -r '.[0].data.status')
afk_time=$(echo "${afk_event}" | jq -r '.[0].duration' | xargs -I ! date -u -d @! +"%H:%M")
uptime=$(uptime | awk '{ print substr($3, 0, length($3) - 1) }' | xargs -I ! date -d ! +"%H:%M")
uptime=$(date -ud @$(uptime -r | awk '{print $2}') +%H:%M)
res="${afk_time} / ${uptime}"
if [[ $status == 'afk' ]]; then
# echo "%{u#cc3333}%{+u} [AFK] $res %{u-}"

31
bin/polybar/c-g.sh Executable file
View file

@ -0,0 +1,31 @@
#!/usr/bin/env bash
# [[file:../../Desktop.org::*C-g][C-g:1]]
EMACS_FLAG="-l /home/pavel/.emacs.d/desktop.el"
EXCLUDE_PATTERN="dbus-launch --exit-with-session emacs"
EMACS_PIDS=$(pgrep -f "emacs.*${EMACS_FLAG}")
SIGNAL_SENT=false
for PID in $EMACS_PIDS; d o
CMDLINE=$(ps -p "$PID" -o args=)
if [[ "$CMDLINE" == *"$EXCLUDE_PATTERN"* ]]; then
continue
fi
kill -SIGUSR2 "$PID" 2>/dev/null
if [ $? -eq 0 ]; then
echo "Sent SIGUSR2 to Emacs (PID: $PID)"
SIGNAL_SENT=true
else
echo "Failed to send SIGUSR2 to Emacs (PID: $PID)"
fi
done
if [ "$SIGNAL_SENT" = false ]; then
echo "Emacs process not found or already handled."
exit 1
fi
exit 0
# C-g:1 ends here

View file

@ -1,39 +0,0 @@
#!/usr/bin/env bash
# [[file:../../Guix.org::*Activate profiles][Activate profiles:1]]
GREEN='\033[1;32m'
RED='\033[1;30m'
NC='\033[0m'
GUIX_EXTRA_PROFILES=$HOME/.guix-extra-profiles
profiles=$*
if [[ $# -eq 0 ]]; then
profiles="$HOME/.config/guix/manifests/*.scm";
fi
for profile in $profiles; do
# Remove the path and file extension, if any
profileName=$(basename $profile)
profileName="${profileName%.*}"
profilePath="$GUIX_EXTRA_PROFILES/$profileName"
manifestPath=$HOME/.config/guix/manifests/$profileName.scm
if [ -f $manifestPath ]; then
echo
echo -e "${GREEN}Activating profile:" $manifestPath "${NC}"
echo
mkdir -p $profilePath
guix package --manifest=$manifestPath --profile="$profilePath/$profileName"
# Source the new profile
GUIX_PROFILE="$profilePath/$profileName"
if [ -f $GUIX_PROFILE/etc/profile ]; then
. "$GUIX_PROFILE"/etc/profile
else
echo -e "${RED}Couldn't find profile:" $GUIX_PROFILE/etc/profile "${NC}"
fi
else
echo "No profile found at path" $profilePath
fi
done
# Activate profiles:1 ends here

View file

@ -1,5 +0,0 @@
#!/usr/bin/env bash
# [[file:../../Desktop.org::*ActivityWatch][ActivityWatch:2]]
sleep 5
aw-watcher-afk
# ActivityWatch:2 ends here

View file

@ -1,4 +0,0 @@
#!/usr/bin/env bash
# [[file:../../Guix.org::*Turn off Guix profiles][Turn off Guix profiles:1]]
export PATH=$(echo $PATH | tr ":" "\n" | grep -vE "guix|nix|gnu" | tr "\n" ":")
# Turn off Guix profiles:1 ends here

View file

@ -2,11 +2,21 @@
{
"title": "OS/Distro",
"elements": [
{
"name": "Arch Linux",
"states": [
{
"startDate": "2025-11-23"
}
],
"color": "y"
},
{
"name": "GNU Guix",
"states": [
{
"startDate": "2021-06-11"
"startDate": "2021-06-11",
"endDate": "2025-11-23"
}
],
"color": "y"