*: move to arch v1

This commit is contained in:
Pavel Korytov 2025-11-12 16:19:11 +03:00
parent b0837527ef
commit 31db63c565
24 changed files with 774 additions and 554 deletions

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

View file

@ -0,0 +1,11 @@
hostname_enabled_backends_enabled = false
enabled_backends = ["arch"]
hostname_groups_enabled = true
[hostname_groups]
kek = ["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,3 @@
arch = [
"firefox",
"ungoogled-chromium-bin",]

View file

@ -0,0 +1,34 @@
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",
"shell-color-scripts-git",
"fish",
"xorg-xhost",
"xorg-xrdb",]

View file

@ -0,0 +1,26 @@
arch = [
"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 = [
"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",
"gtk-engine-murrine",]

View file

@ -0,0 +1,30 @@
arch = [
"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",
"pandoc-cli",
"micromamba-bin",]

View file

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

View file

@ -0,0 +1,22 @@
arch = [
"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,13 @@
arch = [
"obs-studio",
"okular",
"inkscape",
"kdenlive",
"ffmpeg",
"krita",
"gimp",
"libreoffice-fresh",
"zathura-djvu",
"zathura-pdf-mupdf",
"zathura-ps",
"zathura",]

View file

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

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
@ -402,14 +408,26 @@ With ARG, repeats or can move backward if negative."
(string-empty-p (nth disabled-name-index elem))))
(add-to-list
'dependencies
(substring-no-properties (nth dep-name-index elem)))))))))
(cons
(substring-no-properties (nth dep-name-index elem))
(when source-index
(let ((source (nth source-index elem)))
(unless (string-empty-p source)
source)))))))))))
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
(insert
(json-encode
(mapcar
(lambda (group)
(cons (car group)
(mapcar #'car (cdr group))))
(seq-group-by #'cdr data))))
(json-pretty-print-buffer)
(buffer-string))))
(setq my/org-config-files
(mapcar

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

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,15 +33,7 @@ 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:1]]
SSH_AGENT_DIR="/tmp"
@ -66,43 +50,13 @@ if [[ ! -f "$SSH_AUTH_SOCK" ]]; then
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::*Other package managers][Other package managers:1]]
if [ -d "$HOME/.cask" ]; then
@ -125,33 +79,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

184
Arch.org Normal file
View file

@ -0,0 +1,184 @@
#+PROPERTY: header-args :mkdirp yes
#+TITLE: Arch Linux
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
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 the org-mode repo:
#+begin_src bash
git clone git@github.com:SqrtMinusOne/dotfiles.git "/home/pavel/30-39 Life/32 org-mode"
#+end_src
Then run =emacs= and make sure it starts.
* 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 | kek |
| browsers | + | + |
| console | + | |
| desktop | + | |
| desktop-misc | + | |
| desktop-polybar | + | |
| desktop-rofi | + | |
| dev | + | |
| emacs | + | |
| latex | + | |
| mail | + | |
| music | + | |
| 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 |
|---------------------|
| base |
| base-devel |
| decman |
| grub |
| iwd |
| lightdm |
| lightdm-gtk-greeter |
| linux |
| linux-firmware |
| nano |
| metapac |
| openssh |
| pacman-contrib |
| paru |
| pipewire |
| pipewire-audio |
| pipewire-alsa |
| pipewire-pulse |
| pipewire-jack |
| smartmontools |
| vim |
| xterm |
| wget |
| wireless_tools |
| wpa_supplicant |
| yadm |
| zram-generator |
Various drivers, I'm not sure which I actually need, so...
| Arch dependency |
|--------------------|
| libva-intel-driver |
| intel-media-driver |
| vulkan-intel |
| nvidia-utils |
| vulkan-radeon |
| xf86-video-amdgpu |
| xf86-video-ati |
#+NAME: packages
#+begin_src emacs-lisp :tangle no :var category=""
(my/format-arch-dependencies category)
#+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,17 +84,6 @@ 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.
@ -123,52 +104,18 @@ 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
#+end_src
Set Jupyter config PATH. It defaults to readonly directory somewhere in Guix profile.
** 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
** 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 +142,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 +149,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 +174,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 +207,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"
@ -529,7 +383,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 +420,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
@ -653,16 +507,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 +604,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 +659,7 @@ Reload the config.
bind r source-file ~/.tmux.conf
#+end_src
** Copy to clipboard
| Guix dependency |
| Arch dependency |
|-----------------|
| xclip |
@ -849,7 +703,7 @@ source ~/.tmux.line.conf
:header-args+: :tangle ./.config/alacritty/alacritty.yml :comments link
:END:
| Guix dependency |
| Arch dependency |
|-----------------|
| alacritty |
@ -928,9 +782,9 @@ key_bindings:
- { key: NumpadSubtract, mods: Control, action: DecreaseFontSize }
#+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,7 +795,7 @@ 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()>>"
@ -955,50 +809,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 +862,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 +896,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 +965,19 @@ 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
* Arch settings
#+NAME: packages
#+begin_src emacs-lisp :tangle no :eval never-export
(my/format-guix-dependencies)
#+begin_src emacs-lisp :tangle no
(when (fboundp #'my/format-arch-dependencies)
(my/format-arch-dependencies))
#+end_src
#+begin_src scheme :tangle .config/guix/manifests/console.scm :noweb yes
(specifications->manifest
'(
<<packages()>>))
#+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

View file

@ -129,11 +129,11 @@ Xft.dpi: <<get-dpi()>>
** Themes
A few programs I use to customize the apperance are listed below.
| Guix dependency | Description |
|-----------------------+-------------------------|
| matcha-theme | My preferred GTK theme |
| Arch dependency | Description |
|--------------------+-------------------------|
| gtk-engine-murrine | My preferred GTK theme |
| gtk-engines | |
| papirus-icon-theme | My preferred Icon theme |
| gnome-themes-standard | |
| xsettingsd | X11 settings daemon |
| gnome-themes-extra | |
@ -182,11 +182,11 @@ x-scheme-handler/tg=userapp-Telegram Desktop-7PVWF1.desktop;
application/pdf=org.pwmt.zathura.desktop
#+end_src
** Device-specific settings
| Guix dependency | Description |
| Arch dependency | Description |
|-----------------+--------------------------------------------|
| xrandr | X11 CLI to RandR |
| xgamma | A tool to alter monitor's gamma correction |
| xinput | Configure input devices |
| xorg-xrandr | X11 CLI to RandR |
| xorg-xgamma | A tool to alter monitor's gamma correction |
| xorg-xinput | Configure input devices |
Set screen layout & other params depending on hostname
#+begin_src sh :tangle ~/bin/scripts/screen-layout
@ -214,9 +214,9 @@ References:
*** Xsession
First things first, Emacs has to be launched as a window manager. On a more conventional system I'd create a .desktop file in some system folder that can be seen by a login manager, but in the case of Guix it's a bit more complicated, because all such folders are not meant to be changed manually.
| Category | Guix dependency |
| Category | Arch dependency |
|--------------+-----------------|
| desktop-misc | xinit |
| desktop-misc | xorg-xinit |
| desktop-misc | xss-lock |
However, GDM, the login manager that seems to be the default on Guix, launches =~/.xsession= on the startup if it's present, which is just fine for my purposes.
@ -778,9 +778,9 @@ By default, it also shows paths from =/gnu/store=, so there is a custom formatte
Also, by default it tries to launch stuff with =gtk-launch=, which is in the =gtk+= package.
| Category | Guix dependency |
|--------------+-----------------|
| desktop-misc | gtk+:bin |
| Category | Arch dependency | Disabled |
|--------------+-----------------+----------|
| desktop-misc | gtk+:bin | t |
*** password-store-completion
[[https://github.com/SqrtMinusOne/password-store-completion][password-store-completion]] is another package of mine, inspired by [[https://github.com/carnager/rofi-pass][rofi-pass]].
@ -1262,12 +1262,10 @@ And the EXWM config itself.
:header-args+: :tangle ./.config/i3/config
:END:
| Guix dependency | Disabled |
| Arch dependency | Disabled |
|-----------------+----------|
| i3-gaps | |
| i3lock | true |
=i3lock= is disabled because the global one has to be used.
| i3-wm | |
| i3lock | |
[[https://i3wm.org/][i3wm]] is a manual tiling window manager, which is currently my window manager of choice. I've tried several alternatives, including [[https://xmonad.org/][xmonad]] & [[https://github.com/ch11ng/exwm][EXWM]], +but i3 seems to fit my workflow best+ and decided to switch to EXWM. This section is kept for a few cases when I need to be extra sure that my WM doesn't fail.
@ -1306,9 +1304,9 @@ bindsym $mod+Shift+r restart
bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
#+end_src
** Managing windows
| Guix dependency |
|---------------------|
| rust-i3-switch-tabs |
| Guix dependency | Disabled |
|-----------------+----------|
| i3-switch-tabs | t |
Some keybindings for managing windows.
@ -1552,9 +1550,9 @@ bindsym $mod+g mode "inner gaps"
bindsym $mod+Shift+g mode "outer gaps"
#+end_src
** Move & resize windows
| Guix dependency |
|-----------------------------|
| python-i3-balance-workspace |
| Arch dependency | Disabled |
|----------------------+----------|
| i3-balance-workspace | t |
A more or less standard set of keybindings to move & resize floating windows. Just be careful to always make a way to return from these new modes, otherwise you'd end up in a rather precarious situation.
@ -1825,9 +1823,10 @@ exec "xmodmap ~/.Xmodmap"
:header-args:conf-windows: :tangle ./.config/polybar/config :comments link
:END:
| Category | Guix dependency | Description |
|-----------------+-----------------+-------------|
| Category | Arch dependency | Description |
|-----------------+------------------+-------------|
| desktop-polybar | polybar | statusbar |
| desktop-polybar | noto-fonts-emoji | |
[[https://github.com/polybar/polybar][Polybar]] is a nice-looking, WM-agnostic statusbar program.
@ -2608,11 +2607,11 @@ BEGIN{old_received='"$init_received"';old_sent='"$init_sent"'}
#+end_src
*** ipstack-vpn
| Category | Guix dependency | Description |
|-----------------+-----------------+-------------------------|
| desktop-polybar | bind:utils | Provides dig |
| Category | Arch dependency | Description |
|-----------------+-----------------+----------------------------|
| desktop-polybar | bind | Provides dig |
| desktop-polybar | curl | |
| desktop-polybar | jq | util to work with JSONs |
| desktop-polybar | jq | An util to work with JSONs |
A module to get a country of the current IP and openvpn status. Uses [[https://ipstack.com/][ipstack]] API.
@ -2748,7 +2747,7 @@ format-foreground = ${colors.foreground}
interval = 1200
#+end_src
*** sun
| Category | Guix dependency |
| Category | Arch dependency |
|-----------------+-----------------|
| desktop-polybar | sunwait |
@ -2794,7 +2793,7 @@ interval = 60
*** aw-afk
Prints out a current uptime and non-AFK time from [[https://github.com/ActivityWatch][ActivityWatch]] server
| Category | Guix dependency |
| Category | Arch dependency |
|-----------------+-----------------|
| desktop-polybar | dateutils |
@ -2976,7 +2975,7 @@ label-urgent-padding = 1
#+end_src
* Rofi
| Category | Guix dependency |
| Category | Arch dependency |
|--------------+-----------------|
| desktop-rofi | rofi |
@ -3147,14 +3146,14 @@ if [[ ! -z $SELECTED ]]; then
fi
#+end_src
*** Emojis
| Category | Guix dependency |
| Category | Arch dependency |
|--------------+-----------------|
| desktop-rofi | python-rofimoji |
| desktop-rofi | rofimoji |
*** pass
| Category | Guix dependency |
| Category | Arch dependency |
|--------------+-----------------|
| desktop-rofi | rofi-pass |
| desktop-rofi | xset |
| desktop-rofi | xorg-xset |
A nice [[https://github.com/carnager/rofi-pass][pass frontend for Rofi]], which is even packaged for Guix.
@ -3165,7 +3164,7 @@ default_autotype='username :tab pass'
clip=both
#+end_src
* Flameshot
| Guix dependency |
| Arch dependency |
|-----------------|
| flameshot |
@ -3217,7 +3216,7 @@ TYPE_TOGGLE_PANEL=Space
TYPE_UNDO=Ctrl+Z
#+end_src
* dunst
| Guix dependency |
| Arch dependency |
|-----------------|
| dunst |
| libnotify |
@ -3618,9 +3617,9 @@ Which I then can use to create the URL.
: https://color.firefox.com/?theme=XQAAAAJFAQAAAAAAAABAqYhm849SCia3ftKEGccwS-xMDPsqcRvjh8JMhYPDf9_kNjVRdqrKsHr5AamG1FlOJ8DH_BqRXLhVF02YoR2FXVUIEYoXiV-3q19EVo-NqESyeWWEIwj-0QxR3X-JxWYJLJYc6tAeNGGDXNNrM0pNWpwesvR43yXL_fJfr9Q919y2QwP0cK7ZXO1lRou4HkpwWW4LWdO3V6ox_BN9yA
* keynav
| Guix dependency |
|-----------------|
| keynav |
| Arch dependency | Disabled |
|-----------------+----------|
| keynav | t |
| Type | Note |
|---------+--------------------------------|
@ -3697,7 +3696,7 @@ fade-exclude = [
:header-args+: :tangle ./.config/picom.conf
:END:
| Guix dependency |
| Arch dependency |
|-----------------|
| picom |
@ -3792,7 +3791,7 @@ wintypes:
};
#+end_src
* Zathura
| Category | Guix dependency |
| Category | Arch dependency |
|----------+-------------------|
| office | zathura |
| office | zathura-ps |
@ -4208,126 +4207,127 @@ c.tabs.favicons.scale = 1
This section generates manifests for various desktop software that I'm using.
** Browsers
| Category | Guix dependency |
|----------+--------------------|
| browsers | ungoogled-chromium |
| Category | Arch dependency |
|----------+------------------------|
| browsers | ungoogled-chromium-bin |
| browsers | firefox |
** Office & Multimedia
| Category | Guix dependency |
| Category | Arch dependency |
|----------+-----------------|
| office | libreoffice |
| office | libreoffice-fresh |
| office | gimp |
| office | krita |
| office | ffmpeg |
| office | kdenlive |
| office | inkscape |
| office | okular |
| office | obs |
| office | obs-studio |
** LaTeX
| Category | Guix dependency |
|----------+-------------------------------|
| latex | texlive |
| latex | texlab-bin |
| latex | biber |
| latex | python-pygments |
| latex | font-microsoft-web-core-fonts |
| Category | Arch dependency | Disabled |
|----------+--------------------------+----------|
| latex | texlive-basic | |
| latex | texlive-bibtexextra | |
| latex | texlive-binextra | |
| latex | texlive-fontsextra | t |
| latex | texlive-fontutils | |
| latex | texlive-formatsextra | |
| latex | texlive-games | |
| latex | texlive-humanities | |
| latex | texlive-latex | |
| latex | texlive-latexextra | |
| latex | texlive-latexrecommended | |
| latex | texlive-mathscience | |
| latex | texlive-metapost | |
| latex | texlive-pictures | |
| latex | texlive-plaingeneric | |
| latex | texlive-pstricks | |
| latex | texlive-publishers | |
| latex | texlive-xetex | |
| latex | texlab | |
| latex | biber | |
| latex | python-pygments | |
| latex | ttf-ms-fonts | |
** Dev
| Category | Guix dependency | Disabled |
| Category | Arch dependency | Disabled |
|----------+-------------------+----------|
| dev | micromamba-bin | |
| dev | pandoc | |
| dev | docker-compose | |
| dev | pandoc-cli | |
| dev | docker | |
| dev | postgresql | |
| dev | virt-manager | |
| dev | dnsmasq | |
| dev | libvirt | |
| dev | git-filter-repo | |
| dev | node | |
| dev | openjdk:jdk | |
| dev | nodejs | |
| dev | jdk21-openjdk | |
| dev | go | |
| dev | gopls | |
| dev | pkg-config | |
| dev | gcc-toolchain | |
| dev | pkgconf | |
| dev | gcc | |
| dev | cmake | |
| dev | lua | |
| dev | libfaketime | |
| dev | hugo-extended | |
| dev | hugo | |
| dev | make | |
| dev | sbcl | t |
| dev | git-lfs | |
| dev | mysql | t |
| dev | gource | |
| dev | php | |
| dev | python | |
| dev | python-pip | |
| dev | python-virtualenv | |
| dev | leiningen | |
| dev | python-build | |
| dev | socat | |
| dev | wireshark | |
| dev | python-chess | |
| dev | python-cairosvg | |
| dev | wireshark-qt | |
| dev | git | |
| dev | rust | |
** Manifests
#+NAME: packages
#+begin_src emacs-lisp :tangle no :var category=""
(my/format-guix-dependencies category)
(my/format-arch-dependencies category)
#+end_src
Dev
#+begin_src scheme :tangle .config/guix/manifests/dev.scm :noweb yes
(specifications->manifest
'(
<<packages("dev")>>))
#+begin_src scheme :tangle .config/metapac/groups/dev.toml :noweb yes
<<packages("dev")>>
#+end_src
Browsers
#+begin_src scheme :tangle .config/guix/manifests/browsers.scm :noweb yes
(specifications->manifest
'(
<<packages("browsers")>>))
#+begin_src scheme :tangle .config/metapac/groups/browsers.toml :noweb yes
<<packages("browsers")>>
#+end_src
Music
#+begin_src scheme :tangle .config/guix/manifests/music.scm :noweb yes
(specifications->manifest
'(
<<packages("music")>>))
#+begin_src scheme :tangle .config/metapac/groups/music.toml :noweb yes
<<packages("music")>>
#+end_src
Office
#+begin_src scheme :tangle .config/guix/manifests/office.scm :noweb yes
(specifications->manifest
'(
<<packages("office")>>))
#+begin_src scheme :tangle .config/metapac/groups/office.toml :noweb yes
<<packages("office")>>
#+end_src
LaTeX
#+begin_src scheme :tangle .config/guix/manifests/latex.scm :noweb yes
(specifications->manifest
'(
<<packages("latex")>>))
#+begin_src scheme :tangle .config/metapac/groups/latex.toml :noweb yes
<<packages("latex")>>
#+end_src
Desktop Misc
#+begin_src scheme :tangle .config/guix/manifests/desktop-misc.scm :noweb yes
(specifications->manifest
'(
<<packages("desktop-misc")>>))
#+begin_src scheme :tangle .config/metapac/groups/desktop-misc.toml :noweb yes
<<packages("desktop-misc")>>
#+end_src
Desktop polybar
#+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
Desktop rofi
#+begin_src scheme :tangle .config/guix/manifests/desktop-rofi.scm :noweb yes
(specifications->manifest
'(
<<packages("desktop-rofi")>>))
#+begin_src scheme :tangle .config/metapac/groups/desktop-rofi.toml :noweb yes
<<packages("desktop-rofi")>>
#+end_src
** Flatpak
A lot of proprietary desktop applications can be installed most easily with flatpak & flathub.
| Guix dependency |
| Arch dependency |
|--------------------|
| flatpak |
| xdg-desktop-portal |
@ -4348,8 +4348,6 @@ Packages to install:
| Flatpak dependency | Channel |
|------------------------------+---------|
| com.github.wwmm.pulseeffects | flathub |
| com.discordapp.Discord | flathub |
| com.jetbrains.DataGrip | flathub |
| chat.rocket.RocketChat | flathub |
#+begin_src emacs-lisp :var table=flatpak-deps :wrap example
@ -4362,50 +4360,21 @@ Packages to install:
#+RESULTS:
#+begin_example
flatpak install -y --user flathub com.github.wwmm.pulseeffects
flatpak install -y --user flathub com.discordapp.Discord
flatpak install -y --user flathub us.zoom.Zoom
flatpak install -y --user flathub com.slack.Slack
flatpak install -y --user flathub chat.rocket.RocketChat
#+end_example
** Nix
| Type | Description |
|------+--------------------|
| TODO | Make nix manifest? |
I probably should've used nix, as almost every program I packaged so far exists in the Nix repo.
But it's easy enough to use Nix on Guix.
#+begin_src conf :tangle ~/.nix-channels
https://nixos.org/channels/nixpkgs-unstable nixpkgs
#+end_src
Don't forget to run the following after the first installation:
#+begin_src sh
nix-channel --update
#+end_src
Installing packages:
#+begin_src
nix-env -i slack
#+end_src
* Services
:PROPERTIES:
:header-args+: :tangle ~/.config/shepherd/init.scm
:END:
[[https://www.gnu.org/software/shepherd/manual/html_node/index.html][GNU Shepherd]] is a service management system for GNU Guix.
I previously used supervisor, but shepherd also seems pretty capable.
| Guix dependency |
|-----------------|
| shepherd |
[[https://www.gnu.org/software/shepherd/manual/html_node/index.html][GNU Shepherd]] is a service management system for GNU Guix. I'll probably migrate to systemd since I'm not on Guix anymore.
** Music
| Category | Guix dependency |
| Category | Arch dependency |
|----------+-----------------|
| music | mpd |
| music | ncmpcpp |
| music | picard |
| music | mpd-mpc |
| music | mpc |
| music | shntool |
| music | cuetools |
| music | flac |
@ -4454,7 +4423,7 @@ MPD watcher
** ActivityWatch
[[https://activitywatch.net/][ActivityWatch]] is a FOSS time tracker. It tracks screen and application usage and has integrations with browsers, Emacs, etc.
| Guix dependency |
| Arch dependency |
|-------------------|
| activitywatch-bin |
@ -4543,7 +4512,7 @@ Launch an authentication agent. Necessary for stuff like =pkexec=. I suspect I'm
(make <service>
#:provides '(polkit-gnome)
#:respawn? #t
#:start (make-forkexec-constructor '("/home/pavel/.guix-extra-profiles/desktop-misc/desktop-misc/libexec/polkit-gnome-authentication-agent-1"))
#:start (make-forkexec-constructor '("/lib/polkit-gnome/polkit-gnome-authentication-agent-1"))
#:stop (make-kill-destructor)))
#+end_src
** Xmodmap
@ -4586,11 +4555,6 @@ Run my [[file:Guix.org::*OpenVPN][OpenVPN setup]]. Not lauching this automatiall
** opensnitch
[[https://github.com/evilsocket/opensnitch][opensnitch]] is a linux firewall.
Install it via nix:
#+begin_src bash :tangle no
nix-env -I opensnitchd opensnitch-ui
#+end_src
=sudoers= has to be modified this to work.
#+begin_src scheme
(define opensnitchd
@ -4670,45 +4634,40 @@ Run services
;; opensnitch-ui
))
#+end_src
* Guix settings
* Acch settings
Other desktop programs I use are listed below.
| Category | Guix dependency | Description |
| Category | Arch dependency | Description |
|--------------+------------------------+-------------------------------------------|
| desktop-misc | xprop | Tool to display properties of X windows |
| desktop-misc | xorg-xprop | Tool to display properties of X windows |
| desktop-misc | arandr | GUI to xrandr |
| desktop-misc | light | Control screen brightness |
| desktop-misc | ponymix | Control PulseAudio CLI |
| desktop-misc | pavucontrol | Control PulseAudio GUI |
| desktop-misc | network-manager-applet | Applet to manage network connections |
| desktop-misc | xmodmap | Program to modify keybindings on X server |
| desktop-misc | xorg-xmodmap | Program to modify keybindings on X server |
| desktop-misc | fontconfig | |
| desktop-misc | polkit-gnome | Polkit authentication agent |
| desktop-misc | feh | Image viewer. Used to set background |
| desktop-misc | geeqie | Image viewer |
| desktop-misc | copyq | Clipboard manager |
| desktop-misc | thunar | My preferred GUI file manager |
| desktop-misc | xdg-utils | gives xdg-open and stuff |
| desktop-misc | gnome-font-viewer | view fonts |
| desktop-misc | qbittorrent | torrent client |
| desktop-misc | anydesk | Remote desktop software |
| desktop-misc | anydesk-bin | Remote desktop software |
| desktop-misc | gnome-disk-utility | Manage disks |
| desktop-misc | gparted | Manage partitions |
| desktop-misc | xev | Test input |
| desktop-misc | xorg-xev | Test input |
| desktop-misc | bluez | Provides bluetoothctl |
| desktop-misc | telegram-desktop | |
| desktop-misc | font-google-noto-emoji | |
| desktop-misc | noto-fonts-emoji | |
| desktop-misc | remmina | |
| desktop-misc | android-file-transfer | |
| desktop-misc | mcron | |
#+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/desktop.scm :noweb yes
(specifications->manifest
'(
<<packages()>>))
#+begin_src scheme :tangle .config/metapac/groups/desktop.toml :noweb yes
<<packages()>>
#+end_src

146
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.
@ -1363,7 +1368,7 @@ References:
I also want to call =xkb-switch= in EXWM buffers with the same keybindig.
| Guix dependency |
| Arch dependency |
|-----------------|
| xkb-switch |
@ -1562,9 +1567,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
@ -2081,7 +2086,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
@ -4152,7 +4157,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 |
@ -4462,9 +4467,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]]
@ -4488,7 +4493,7 @@ column_limit = 80
*** black
[[https://github.com/psf/black][black]] is a formatter for Python files.
| Guix dependency |
| Arch dependency |
|-----------------|
| python-black |
@ -4503,7 +4508,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 |
@ -4626,7 +4631,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 |
@ -4899,7 +4904,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 |
@ -7143,9 +7148,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)
@ -8053,10 +8057,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
'(
@ -8070,12 +8074,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 |
@ -8090,17 +8094,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 ()
@ -8113,7 +8118,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
@ -8125,7 +8130,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
@ -8145,47 +8156,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=:
@ -8196,6 +8208,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")))
@ -9739,7 +9752,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 |
@ -10086,7 +10099,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 |
@ -10394,7 +10407,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 |
@ -11339,16 +11352,14 @@ 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 |
| 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
@ -11888,7 +11899,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 |
@ -13279,7 +13290,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 |
@ -13818,22 +13829,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 = 416b1f7f18d68a65f5e75bb1af5d65ea5e20739e
#+end_src
* Notmuch
| Guix dependency |
| Arch dependency |
|-----------------|
| notmuch |
| parallel |
@ -357,7 +363,7 @@ The script is ran via GNU Mcron every 5 minutes.
(job "*/5 * * * * " "~/bin/scripts/check-email")
#+end_src
* MSMTP
| Guix dependency |
| Arch dependency |
|-----------------|
| msmtp |
@ -405,9 +411,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 +421,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 +701,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

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