summaryrefslogtreecommitdiff
path: root/home
diff options
context:
space:
mode:
authorMarc Coquand <marc@mccd.space>2024-10-22 11:07:59 +0300
committerMarc Coquand <marc@mccd.space>2024-10-22 11:07:59 +0300
commite24f418e3499afd1e9e529b8656a35376e69f52a (patch)
tree90e01f42d46dec91e3a6cace4de6d089152fad29 /home
downloadguix-e24f418e3499afd1e9e529b8656a35376e69f52a.tar.gz
guix-e24f418e3499afd1e9e529b8656a35376e69f52a.tar.bz2
guix-e24f418e3499afd1e9e529b8656a35376e69f52a.zip
initial commit
Diffstat (limited to '')
-rw-r--r--home/bashrc42
-rw-r--r--home/config.scm121
-rw-r--r--home/dots/.Xresources37
-rw-r--r--home/dots/.emacs863
-rw-r--r--home/dots/.emacs.d/elisp/almost-mono-themes.el205
-rw-r--r--home/dots/.emacs.d/elisp/exwm-mff.el191
-rw-r--r--home/dots/.emacs.d/elisp/org-link-minor-mode.el137
-rw-r--r--home/dots/.emacs.d/snippets/go-mode/errnotnil5
-rw-r--r--home/dots/.emacs.d/snippets/go-mode/error7
-rw-r--r--home/dots/.emacs.d/snippets/mhtml-mode/<div>..</div>~7
-rw-r--r--home/dots/.gitconfig49
-rwxr-xr-xhome/dots/.local/bin/capture16
-rwxr-xr-xhome/dots/.local/bin/convert-website5
-rwxr-xr-xhome/dots/.local/bin/logdate2
-rwxr-xr-xhome/dots/.local/bin/nextcloud-sync5
-rwxr-xr-xhome/dots/.local/bin/org-sync11
-rwxr-xr-xhome/dots/.local/bin/pfetch1956
-rwxr-xr-xhome/dots/.local/bin/todo14
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-Bold.ttfbin0 -> 1270864 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-BoldItalic.ttfbin0 -> 1331992 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-BoldOblique.ttfbin0 -> 1327108 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-Extended.ttfbin0 -> 1289280 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedBold.ttfbin0 -> 1285428 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedBoldItalic.ttfbin0 -> 1343788 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedBoldOblique.ttfbin0 -> 1338336 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBold.ttfbin0 -> 1284528 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBoldItalic.ttfbin0 -> 1342916 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBoldOblique.ttfbin0 -> 1337808 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLight.ttfbin0 -> 1296832 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLightItalic.ttfbin0 -> 1350264 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLightOblique.ttfbin0 -> 1345096 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavy.ttfbin0 -> 1287124 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavyItalic.ttfbin0 -> 1342492 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavyOblique.ttfbin0 -> 1337308 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedItalic.ttfbin0 -> 1348152 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedLight.ttfbin0 -> 1287748 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedLightItalic.ttfbin0 -> 1343544 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedLightOblique.ttfbin0 -> 1338064 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedMedium.ttfbin0 -> 1289884 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedMediumItalic.ttfbin0 -> 1348004 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedMediumOblique.ttfbin0 -> 1342708 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedOblique.ttfbin0 -> 1342648 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBold.ttfbin0 -> 1290220 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBoldItalic.ttfbin0 -> 1346084 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBoldOblique.ttfbin0 -> 1340864 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedThin.ttfbin0 -> 1301268 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedThinItalic.ttfbin0 -> 1356536 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtendedThinOblique.ttfbin0 -> 1351324 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtraBold.ttfbin0 -> 1273328 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtraBoldItalic.ttfbin0 -> 1333308 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtraBoldOblique.ttfbin0 -> 1328688 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtraLight.ttfbin0 -> 1277488 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtraLightItalic.ttfbin0 -> 1335216 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ExtraLightOblique.ttfbin0 -> 1329984 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-Heavy.ttfbin0 -> 1271444 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-HeavyItalic.ttfbin0 -> 1332568 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-HeavyOblique.ttfbin0 -> 1327684 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-Italic.ttfbin0 -> 1336272 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-Light.ttfbin0 -> 1272596 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-LightItalic.ttfbin0 -> 1330560 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-LightOblique.ttfbin0 -> 1325428 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-Medium.ttfbin0 -> 1271724 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-MediumItalic.ttfbin0 -> 1330412 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-MediumOblique.ttfbin0 -> 1325564 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-Oblique.ttfbin0 -> 1331344 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-Regular.ttfbin0 -> 1277388 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-SemiBold.ttfbin0 -> 1272304 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-SemiBoldItalic.ttfbin0 -> 1330020 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-SemiBoldOblique.ttfbin0 -> 1325424 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-Thin.ttfbin0 -> 1290164 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ThinItalic.ttfbin0 -> 1346888 bytes
-rw-r--r--home/dots/.local/share/fonts/IosevkaSS13-ThinOblique.ttfbin0 -> 1341348 bytes
-rw-r--r--home/dots/.mbsyncrc60
-rw-r--r--home/dots/.mozilla/firefox/p8ada7a1.default/chrome/userChrome.css10
-rw-r--r--home/dots/.msmtprc25
-rwxr-xr-xhome/dots/.xsession.bak18
-rw-r--r--home/profile18
77 files changed, 3804 insertions, 0 deletions
diff --git a/home/bashrc b/home/bashrc
new file mode 100644
index 0000000..9a3a2cf
--- /dev/null
+++ b/home/bashrc
@@ -0,0 +1,42 @@
+export SHELL
+
+if [[ $- != *i* ]]
+then
+ # We are being invoked from a non-interactive shell. If this
+ # is an SSH session (as in "ssh host command"), source
+ # /etc/profile so we get PATH and other essential variables.
+ [[ -n "$SSH_CLIENT" ]] && source /etc/profile
+
+ # Don't do anything else.
+ return
+fi
+
+# Source the system-wide file.
+[ -f /etc/bashrc ] && source /etc/bashrc
+
+alias rm='rm -i'
+alias grep="ugrep --exclude-dir=node-modules --exclude-dir=_build"
+alias e="$EDITOR"
+alias g="git"
+alias grep="ugrep"
+alias logdate='date +"%Y-%m-%d"'
+
+optimizeimg() {
+ magick -strip -quality 85% $1 $2
+}
+
+refs() {
+ recsel -q $1 ~/personal-db/refs.rec
+}
+
+cleartrail() {
+ cat $1 | tr -d '\n'
+}
+
+alias a='pwd'
+
+eval "$(zoxide init posix --hook prompt)"
+
+if [ "$(tty)" = "/dev/tty1" ]; then
+ exec startx
+fi
diff --git a/home/config.scm b/home/config.scm
new file mode 100644
index 0000000..4b2820a
--- /dev/null
+++ b/home/config.scm
@@ -0,0 +1,121 @@
+;; This is a sample Guix Home configuration which can help setup your
+;; home directory in the same declarative manner as Guix System.
+;; For more information, see the Home Configuration section of the manual.
+(define-module (guix-home-config)
+ #:use-module (gnu home)
+ #:use-module (gnu home services)
+ #:use-module (gnu home services shells)
+ #:use-module (gnu services)
+ #:use-module (gnu packages)
+ #:use-module (gnu packages admin)
+ #:use-module (gnu packages emacs)
+ #:use-module (gnu packages fonts)
+ #:use-module (gnu packages mail)
+ #:use-module (gnu packages rust-apps)
+ #:use-module (gnu packages search)
+ #:use-module (gnu packages imagemagick)
+ #:use-module (gnu packages password-utils)
+ #:use-module (gnu packages image-viewers)
+ #:use-module (gnu packages xfce)
+ #:use-module (gnu packages sync)
+ #:use-module (gnu packages xorg)
+ #:use-module (gnu packages xdisorg)
+ #:use-module (gnu packages gnome)
+ #:use-module (gnu packages librewolf)
+ #:use-module (gnu packages emacs-xyz)
+ #:use-module (gnu packages text-editors)
+ #:use-module (gnu packages golang)
+ #:use-module (gnu packages gnupg)
+ #:use-module (gnu packages aspell)
+ #:use-module (gnu packages sqlite)
+ #:use-module (gnu packages databases)
+ #:use-module (gnu packages compression)
+ #:use-module (gnu system shadow)
+ #:use-module (gnu home services fontutils)
+ #:use-module (gnu home services dotfiles)
+ #:use-module (gnu home services gnupg)
+ #:use-module (gnu packages ssh)
+ #:use-module (guix gexp)
+ #:use-module (guix packages)
+ #:use-module (guix download)
+ #:use-module (guix build-system go)
+ #:use-module (gnu home services pm))
+
+
+(define home-config
+ (home-environment
+ (packages (list
+ font-iosevka
+ font-iosevka-aile
+ font-iosevka-etoile
+
+ isync
+
+ zoxide
+ ugrep
+ imagemagick
+ password-store
+ fd
+ recutils
+ unzip
+
+ go
+ sqlite
+
+ mg
+
+ imv
+ thunar
+ thunar-volman
+
+ emacs-geiser
+ emacs-geiser-guile
+ emacs-pinentry
+ mu
+ msmtp
+ emacs
+
+ aspell
+ aspell-dict-en
+
+ gnupg
+ pinentry
+ openssh
+
+ librewolf
+
+ xsetroot
+ xset
+ xrdb
+ autocutsel
+ gsettings-desktop-schemas
+ setxkbmap))
+ (services
+ (list
+ (service home-bash-service-type
+ (home-bash-configuration
+ (guix-defaults? #f)
+ (bash-profile (list (local-file "./profile")))
+ (bashrc (list (local-file "./bashrc")))))
+ (service home-gpg-agent-service-type
+ (home-gpg-agent-configuration
+ (pinentry-program
+ (file-append pinentry-emacs "/bin/pinentry-emacs"))
+ (ssh-support? #t)))
+
+ (service home-files-service-type
+ `((".guile" ,%default-dotguile)
+ (".Xdefaults" ,%default-xdefaults)))
+
+ (service home-dotfiles-service-type
+ (home-dotfiles-configuration
+ (directories '("./dots"))))
+
+ (simple-service 'extend-home
+ home-environment-variables-service-type
+ `(("PATH" . "${PATH}:~/home/go/bin")))
+
+ (service home-xdg-configuration-files-service-type
+ `(("gdb/gdbinit" ,%default-gdbinit)))))))
+
+home-config
diff --git a/home/dots/.Xresources b/home/dots/.Xresources
new file mode 100644
index 0000000..5985b2c
--- /dev/null
+++ b/home/dots/.Xresources
@@ -0,0 +1,37 @@
+Xcursor*theme: Adwaita
+Xcursor*size: 32
+XTerm*faceSize: 6
+XTerm*selectToClipboard: true
+XTerm*faceName: Iosevka SS13 Extended:style=regular:antialias=true:hinting=false
+xterm*scrollBar: false
+xterm*rightScrollbar: false
+XTerm.termName: xterm-256color
+XTerm*Background: #FFFFFF
+XTerm*Foreground: #000000
+XTerm*HiBackColor: #FFFFFF
+XTerm*scaleHeight: 1.2
+
+urxvt*selectToClipboard: true
+urxvt*font: xft:Iosevka SS13 Extended:size=14:style=Regular:antialias=true:hinting=false
+urxvt*scrollBar: false
+urxvt*rightScrollbar: false
+urxvt.termName: xterm-256color
+urxvt*Background: #FFFFFF
+urxvt*Foreground: #000000
+urxvt*HiBackColor: #FFFFFF
+urxvt*internalBorder: 8
+urxvt*lineSpace: 4
+URxvt.perl-ext-common: default,matcher
+URxvt.url-launcher: /usr/bin/xdg-open
+URxvt.matcher.button: 1
+
+Emacs.font: Iosevka SS13 Extended-15
+
+! yellow
+*.color3: #ffb319
+*.color11: #ffb319
+
+! cyan
+*.color6: #0000FF
+*.color12: #0000FF
+*.color14: #0000FF
diff --git a/home/dots/.emacs b/home/dots/.emacs
new file mode 100644
index 0000000..9a931a1
--- /dev/null
+++ b/home/dots/.emacs
@@ -0,0 +1,863 @@
+;; -*- lexical-binding: t; -*-
+(add-to-list 'load-path "~/.emacs.d/elisp")
+(fset 'yes-or-no-p 'y-or-n-p)
+(setq
+ inhibit-startup-screen t
+ default-frame-alist '((font . "Iosevka SS13 Extended")
+ (height . 170)
+ (line-spacing . 0.5))
+ ;; undo
+ undo-limit 10000000
+ undo-outer-limit 20000000
+
+ ;; Package list
+ package-list '(
+ magit
+ nix-mode
+ go-mode
+ devdocs
+ rec-mode
+ almost-mono-themes
+ eldoc-box
+ markdown-mode
+ nov
+ yasnippet
+ yasnippet-snippets
+ pinentry
+ geiser
+ geiser-guile
+ guix
+ avy
+ tldr
+ elfeed
+ elfeed-protocol
+ exwm
+ emms
+ mastodon
+ pass
+ lem
+ expand-region)
+
+ package-archives '(("elpa" . "https://elpa.gnu.org")
+ ("gnu" . "http://elpa.gnu.org/packages/")
+ ("melpa" . "https://melpa.org/packages/")
+ ("non-gnu" . "https://elpa.nongnu.org/nongnu/")
+ ("melpa-stable" . "https://stable.melpa.org/packages/")))
+
+
+;; UI
+(menu-bar-mode -1)
+(tool-bar-mode -1)
+
+(setq-default fill-column 80
+ frame-title-format '("%b"))
+
+(package-initialize)
+
+
+(unless package-archive-contents
+ (package-refresh-contents))
+
+;; install the missing packages
+(dolist (package package-list)
+ (unless (package-installed-p package)
+ (package-install package)))
+
+(use-package tab-bar
+ :init
+ (tab-bar-mode))
+
+(use-package project
+ :ensure t
+ :init
+ (add-to-list 'project-switch-commands '(project-shell "Shell")))
+
+(use-package exwm
+ :init
+ (setq exwm-workspace-number 1
+ exwm-input-global-keys
+ `(([?\s-r] . exwm-reset) ;; s-r: Reset (to line-mode).
+ ;; s-N: Switch to certain workspace.
+ ,@(mapcar (lambda (i)
+ `(,(kbd (format "s-%d" i)) .
+ (lambda ()
+ (interactive)
+ (tab-bar-select-tab ,i))))
+ (number-sequence 0 9))))
+ (exwm-input-set-key (kbd "s-f")
+ (lambda () (interactive)
+ (shell-command "firefox")))
+ (exwm-input-set-key (kbd "<print>")
+ (lambda () (interactive)
+ (shell-command "scrot -F '/home/mccd/screenshots/%Y-%m-%d_$wx$h.png'")))
+ (exwm-input-set-key (kbd "C-<print>")
+ (lambda () (interactive)
+ (shell-command "scrot -s -F '/home/mccd/screenshots/%Y-%m-%d_$wx$h.png'")))
+ (exwm-input-set-key (kbd "s-<SPC>")
+ (lambda (cmd) ;; s-&: Launch application.
+ (interactive (list (read-shell-command "$ ")))
+ (start-process-shell-command cmd nil cmd)))
+ (exwm-enable)
+ (exwm-xim-mode)
+ (push ?\C-\\ exwm-input-prefix-keys)
+ :config
+ (setq
+ ring-bell-function 'ignore
+ default-directory "/home/mccd/"
+ focus-follows-mouse t
+ mouse-autoselect-window t)
+ :hook
+ (;; Make sure titles match X window
+ (server-after-make-frame . (lambda ()
+ (set-window-margins (selected-window) 2 2)))
+ (exwm-update-title . (lambda ()
+ (exwm-workspace-rename-buffer
+ (concat exwm-class-name ":"
+ (if (<= (length exwm-title) 50) exwm-title
+ (concat (substring exwm-title 0 49) "..."))))))
+ (exwm-update-class . (lambda ()
+ (exwm-workspace-rename-buffer
+ (concat exwm-class-name ":"
+ (if (<= (length exwm-title) 50) exwm-title
+ (concat (substring exwm-title 0 49) "..."))))))))
+
+(use-package time
+ :init
+ (display-time-mode)
+ :config
+ (setq display-time-format "%a, %d/%m/%Y %H:%M"))
+
+(use-package geiser
+ :ensure t)
+
+(use-package pixel-scroll
+ :init
+ (pixel-scroll-precision-mode))
+
+(use-package scroll-bar
+ :init
+ (scroll-bar-mode -1))
+
+(use-package frame
+ :init
+ (window-divider-mode))
+
+(use-package delsel
+ :init
+ (delete-selection-mode))
+
+(use-package files
+ :config
+ (setq delete-old-versions t
+ kept-new-versions 6
+ kept-old-versions 2
+ version-control t
+ auto-save-default nil))
+
+(use-package minibuffer
+ :defer t
+ :config
+ (setq completion-cycle-threshold 5
+ completion-ignore-case t))
+
+(use-package pass
+ :defer t
+ :ensure t)
+
+(use-package select
+ :config
+ (setq x-select-enable-clipboard t
+ x-select-enable-primary t))
+
+(use-package imenu
+ :defer t
+ :config
+ (setq imenu-auto-rescan t))
+
+(defun sudo-shell-command (command)
+ (interactive "MShell command (root): ")
+ (with-temp-buffer
+ (cd "/sudo::/")
+ (async-shell-command command)))
+
+
+(use-package guix
+ :ensure t
+ :bind
+ (("C-c C-g g" . guix)
+ ("C-c C-g o" . (lambda ()
+ (interactive)
+ (sudo-shell-command "guix system reconfigure /home/mccd/system/os/config.scm")))
+ ("C-c C-g h" . (lambda ()
+ (interactive)
+ (async-shell-command "guix home reconfigure ~/system/home/config.scm")))))
+
+
+(use-package nov
+ :defer t
+ :ensure t
+ :init
+ (add-to-list 'auto-mode-alist '("\\.epub'" . nov-mode)))
+
+(use-package battery
+ :init
+ (display-battery-mode t))
+
+(use-package comint
+ :bind
+ ((:repeat-map
+ repeat-hist-line-map
+ ("n" . comint-next-input)
+ ("p" . comint-previous-input))))
+
+(use-package repeat
+ :demand t
+ :bind
+ ((:repeat-map
+ repeat-normal-movement-map
+ ("n" . next-line)
+ ("b" . backward-char)
+ ("f" . forward-char)
+ ("e" . move-end-of-line)
+ ("F" . forward-word)
+ ("B" . backward-word)
+ ("v" . scroll-up-command)
+ ("V" . scroll-down-command)
+ ("o" . avy-goto-char-timer)
+ ("g" . goto-line)
+ ("a" . move-beginning-of-line)
+ ("k" . kill-line)
+ ("d" . delete-char)
+ ("D" . kill-word)
+ ("." . er/expand-region)
+ ("-" . er/contract-region)
+ ("p" . previous-line))
+ (:repeat-map
+ repeat-movement-map
+ ("e" . end-of-defun)
+ ("f" . forward-sexp)
+ ("n" . forward-list)
+ ("p" . backward-list)
+ ("d" . down-list)
+ ("u" . up-list)
+ ("b" . backward-sexp)
+ ("a" . beginning-of-defun)))
+ :config
+ (setq repeat-on-final-keystroke t
+ set-mark-command-repeat-pop t
+ repeat-exit-key (kbd "<TAB>"))
+ (repeat-mode 1))
+
+(use-package org-crypt
+ :ensure nil
+ :init
+ (setenv "GPG_AGENT_INFO" nil)
+ (setq auth-source-debug t
+ epg-gpg-program "gpg2")
+ (org-crypt-use-before-save-magic))
+
+(use-package grep
+ :config
+ (setq-default
+ grep-template (string-join
+ '("ugrep"
+ "--color=never"
+ "--ignore-binary"
+ "--ignore-case"
+ "--include=<F>"
+ "--line-number"
+ "--null"
+ "--recursive"
+ "--regexp=<R>")
+ " ")))
+
+(use-package pinentry
+ :ensure t
+ :init
+ (pinentry-start))
+
+
+(use-package epa-file
+ :init
+ (epa-file-enable)
+ (setq
+ epa-pinentry-mode 'loopback))
+
+(use-package exwm-mff
+ :demand t
+ :load-path "elisp"
+ :hook
+ ((server-after-make-frame . exwm-mff-mode)))
+
+(use-package avy
+ :ensure t
+ :config
+ (setq
+ avy-timeout-seconds 0.2)
+ (global-set-key (kbd "M-o") 'avy-goto-char-timer)
+ (set-face-attribute 'avy-lead-face nil :inherit 'fixed-pitch)
+ (set-face-attribute 'avy-lead-face-0 nil :inherit 'fixed-pitch)
+ (set-face-attribute 'avy-lead-face-1 nil :inherit 'fixed-pitch)
+ (set-face-attribute 'avy-lead-face-2 nil :inherit 'fixed-pitch)
+ (setf (alist-get ? avy-dispatch-alist) 'avy-action-mark-to-char)
+ (define-key isearch-mode-map (kbd "M-o") 'avy-isearch)
+ (defun avy-action-kill-whole-line (pt)
+ (save-excursion
+ (goto-char pt)
+ (kill-whole-line))
+ (select-window
+ (cdr
+ (ring-ref avy-ring 0)))
+ t)
+ (setf (alist-get ?k avy-dispatch-alist) 'avy-action-kill-stay
+ (alist-get ?K avy-dispatch-alist) 'avy-action-kill-whole-line)
+ (defun avy-action-copy-whole-line (pt)
+ (save-excursion
+ (goto-char pt)
+ (cl-destructuring-bind (start . end)
+ (bounds-of-thing-at-point 'line)
+ (copy-region-as-kill start end)))
+ (select-window
+ (cdr
+ (ring-ref avy-ring 0)))
+ t)
+ (defun avy-action-yank-whole-line (pt)
+ (avy-action-copy-whole-line pt)
+ (save-excursion (yank))
+ t)
+
+ (setf (alist-get ?y avy-dispatch-alist) 'avy-action-yank
+ (alist-get ?w avy-dispatch-alist) 'avy-action-copy
+ (alist-get ?W avy-dispatch-alist) 'avy-action-copy-whole-line
+ (alist-get ?Y avy-dispatch-alist) 'avy-action-yank-whole-line)
+ (defun avy-action-copy-whole-line (pt)
+ (save-excursion
+ (goto-char pt)
+ (cl-destructuring-bind (start . end)
+ (bounds-of-thing-at-point 'line)
+ (copy-region-as-kill start end)))
+ (select-window
+ (cdr
+ (ring-ref avy-ring 0)))
+ t)
+
+ (defun avy-action-yank-whole-line (pt)
+ (avy-action-copy-whole-line pt)
+ (save-excursion (yank))
+ t)
+
+ (setf (alist-get ?y avy-dispatch-alist) 'avy-action-yank
+ (alist-get ?w avy-dispatch-alist) 'avy-action-copy
+ (alist-get ?W avy-dispatch-alist) 'avy-action-copy-whole-line
+ (alist-get ?Y avy-dispatch-alist) 'avy-action-yank-whole-line)
+
+ (defun avy-action-teleport-whole-line (pt)
+ (avy-action-kill-whole-line pt)
+ (save-excursion (yank)) t)
+
+ (setf (alist-get ?t avy-dispatch-alist) 'avy-action-teleport
+ (alist-get ?T avy-dispatch-alist) 'avy-action-teleport-whole-line)
+
+ (defun avy-action-mark-to-char (pt)
+ (activate-mark)
+ (goto-char pt))
+
+ (setf (alist-get ? avy-dispatch-alist) 'avy-action-mark-to-char))
+
+(use-package flymake
+ :defer t
+ :bind
+ (:repeat-map flymake-repeat-map
+ ("]" . flymake-goto-next-error)
+ ("[" . flymake-goto-prev-error))
+ :hook
+ ((flymake-mode .
+ (lambda ()
+ (define-key flymake-mode-map (kbd "C-c ]") 'flymake-goto-next-error)
+ (define-key flymake-mode-map (kbd "C-c [") 'flymake-goto-prev-error)))))
+
+(use-package expand-region
+ :ensure t
+ :init
+ (global-set-key (kbd "C-c .") 'er/expand-region))
+
+(use-package devdocs
+ :ensure t
+ :init
+ (global-set-key (kbd "C-h D") 'devdocs-lookup))
+
+(use-package sgml-mode
+ :init
+ (add-to-list 'auto-mode-alist '("\\.njk\\'" . html-mode))
+ (add-to-list 'auto-mode-alist '("\\.tmpl\\'" . html-mode))
+ :hook
+ ;; TODO fix
+ ((html-mode . (lambda ()
+ (keymap-local-set (kbd "M-o") 'avy-goto-char-timer)))
+ (html-mode . (lambda ()
+ (setq sgml-basic-offset 8
+ indent-tabs-mode t)))))
+
+(use-package eldoc
+ :ensure t
+ :demand t
+ :diminish ""
+ :config
+ (setq eldoc-print-after-edit t
+ echo-area-display-truncation-message nil
+ eldoc-echo-area-prefer-doc-buffer 'maybe
+ eldoc-echo-area-use-multiline-p nil)
+ :hook (prog-mode . eldoc-mode))
+
+(use-package eldoc-box
+ :ensure t
+ :demand t
+ :hook
+ (eglot-managed-mode . #'eldoc-box-hover-mode)
+ :config
+ (global-set-key (kbd "C-h .") #'eldoc-box-help-at-point))
+
+(use-package markdown-mode
+ :ensure t
+ :config
+ (set-face-attribute 'markdown-code-face nil :inherit 'fixed-pitch)
+ :hook
+ ((markdown-mode . variable-pitch-mode)
+ (markdown-mode . markdown-toggle-url-hiding)
+ (markdown-mode . markdown-toggle-markup-hiding)
+ (markdown-mode . visual-line-mode)))
+
+(use-package elec-pair
+ :init
+ (electric-pair-mode 1)
+ :config
+ (global-set-key (kbd "M-{") 'insert-pair)
+ (global-set-key (kbd "M-\"") 'insert-pair)
+ (global-set-key (kbd "M-\'") 'insert-pair)
+ (global-set-key (kbd "M-<") 'insert-pair)
+ (global-set-key (kbd "M-[") 'insert-pair))
+
+(use-package ido
+ :init
+ (ido-mode t))
+
+(use-package org-link-minor-mode
+ :load-path "elisp"
+ :defer t)
+
+(use-package calendar
+ :defer t
+ :init
+ (add-to-list 'auto-mode-alist '("~/personal-db/log" . diary-mode))
+ :hook
+ ((diary-mode . variable-pitch-mode)
+ ; (diary-mode . org-link-minor-mode)
+ ; (diary-fancy-display-mode . org-link-minor-mode)
+ (diary-fancy-display-mode . variable-pitch-mode)
+ (diary-mode . (lambda ()
+ (add-hook 'after-save-hook 'sync-org nil t)))
+ (diary-mode . flyspell-mode))
+ :config
+ (global-set-key (kbd "C-c d") 'calendar)
+ (calendar-set-date-style 'european)
+ (set-face-attribute 'diary nil :inherit 'fixed-pitch)
+ (setq diary-file "~/personal-db/log"
+ calendar-mark-diary-entries-flag t
+ calendar-week-start-day 1))
+
+(use-package nix-mode
+ :ensure t
+ :defer t
+ :hook
+ ((nix-mode . (lambda ()
+ (add-hook 'before-save-hook #'nix-format-buffer nil t)))
+ (nix-mode . nix-prettify-mode)))
+
+(use-package eglot
+ :config
+ ;; Ensure `nil` is in your PATH.
+ (add-to-list 'eglot-server-programs '(nix-mode . ("nil")))
+ (define-key eglot-mode-map (kbd "C-c r") 'eglot-rename)
+ (define-key eglot-mode-map (kbd "C-c o") 'eglot-code-actions)
+ :hook
+ (nix-mode . eglot-ensure)
+ (go-mode . eglot-ensure))
+
+(use-package go-mode
+ :ensure t
+ :defer t
+ :hook
+ ((go-mode . (lambda ()
+ (add-hook
+ 'before-save-hook 'eglot-format-buffer nil t)))
+ (go-mode . (lambda ()
+ (setq-local compile-command "go build .")))))
+
+(use-package rec-mode
+ :ensure nil
+ :defer t
+ :mode "\\.rec\\'"
+ :hook
+ ((rec-mode . flymake-mode)
+ (rec-mode . eldoc-mode)))
+
+(use-package erc
+ :ensure t
+ :config
+ (setq erc-autojoin-channels-alist
+ '(("Libera.Chat"
+ "#emacs"
+ "#permacomputing"
+ "#oldcomputerchallenge"
+ "#go-nuts"
+ "#netbsd"
+ "#nonguix"
+ "#guix")))
+ :init
+ (global-set-key
+ "\C-cef"
+ (lambda ()
+ (interactive)
+ (erc
+ :server "irc.libera.chat"
+ :port "6667"
+ :nick "mccd"
+ :password (shell-command-to-string "pass show libera.chat")))))
+
+(use-package ob-rec
+ :ensure nil)
+
+(defun sync-org ()
+ (interactive)
+ (async-shell-command "org-sync"))
+
+(add-to-list 'display-buffer-alist '("*Async Shell Command*" display-buffer-no-window (nil)))
+
+;; Org
+(use-package org
+ :ensure t
+ :init
+ (add-to-list 'auto-mode-alist '("\\.org\\'" . org-mode))
+ (org-babel-do-load-languages
+ 'org-babel-load-languages
+ '((shell . t)
+ (rec .t)))
+
+ :config
+ (setq org-refile-targets
+ '((nil :maxlevel . 4)
+ (org-agenda-files :maxlevel . 4))
+ org-default-notes-file "~/personal-db/notes/todo.org"
+ org-hide-emphasis-markers t
+ org-agenda-include-diary t
+ org-agenda-remove-tags t
+ org-startup-folded 'content
+ org-agenda-inhibit-startup nil
+ ;; Add /New Heading at the end for use
+ org-refile-allow-creating-parent-nodes 'confirm
+ org-outline-path-complete-in-steps nil
+ org-refile-use-outline-path 'file
+ ;; Otherwise looks weird in variable-pitch-mode
+ org-log-done 'time
+ org-capture-templates
+ '(("t" "Todo"
+ entry (file "~/personal-db/notes/todo.org")
+ "* TODO %?\n%i\n%a\n "
+ :empty-lines 0)
+ ("l" "Log" plain (file "~/personal-db/log")
+ "%<%d %b %Y %H:%M> %?"
+ :prepend t)
+ ("n" "Inbox"
+ entry (file "~/personal-db/notes/inbox.org")
+ "** %?\n%T"
+ :empty-lines 0)))
+ (set-face-attribute 'org-block nil :inherit 'fixed-pitch)
+ (set-face-attribute 'org-code nil :inherit 'fixed-pitch)
+ (set-face-attribute 'org-table nil :inherit 'fixed-pitch)
+ (set-face-attribute 'org-date nil :inherit 'fixed-pitch)
+ (set-face-attribute 'org-tag nil :inherit 'fixed-pitch)
+ (global-set-key (kbd "C-c l") #'org-store-link)
+ (global-set-key (kbd "C-c a") #'org-agenda)
+ (global-set-key (kbd "C-c c") #'org-capture)
+ (global-set-key (kbd "C-c j") #'org-goto)
+ (global-set-key (kbd "C-c s") #'project-find-regexp)
+ (global-set-key (kbd "C-c C-o") #'org-open-at-point-global)
+ (global-set-key (kbd "C-c C-s") #'sync-org)
+ ;; Something errors out with capture logs and non-org files
+ (add-to-list 'warning-suppress-log-types '(org-element))
+ (add-to-list 'warning-suppress-types '(org-element))
+ :hook
+ ((org-mode . auto-save-visited-mode)
+ (org-mode . org-indent-mode)
+ (org-mode . flyspell-mode)
+ (org-mode . visual-line-mode)
+ (org-mode . (lambda ()
+ (add-hook 'after-save-hook 'sync-org nil t)))
+ (org-mode . variable-pitch-mode)))
+
+(use-package rec-mode
+ :ensure t)
+
+(use-package magit
+ :ensure t
+ :demand t)
+
+(use-package magit-extras
+ :ensure nil)
+
+(use-package yasnippet
+ :diminish t
+ :ensure t
+ :init
+ (yas-global-mode 1))
+
+(use-package register
+ :bind
+ (("C-z" . 'point-to-register)))
+
+(defun marc/set-msmtp-account ()
+ (if (message-mail-p)
+ (save-excursion
+ (let*
+ ((from (save-restriction
+ (message-narrow-to-headers)
+ (message-fetch-field "from")))
+ (account
+ (cond
+ ((string-match "marcc@fastmail.fr" from) "home")
+ ((string-match "marc.coquand@sustainably.app" from) "work")
+ ((string-match "marc@mccd.space" from) "home"))))
+ (setq message-sendmail-extra-arguments (list '"-a" account))))))
+
+;(use-package message
+; :defer t
+; :hook
+; ((message-send-mail . marc/set-msmtp-account)
+; (message-mode-hook flyspell-mode)))
+
+(add-hook 'message-send-mail-hook #'marc/set-msmtp-account)
+(add-hook 'message-mode-hook #'flyspell-mode)
+
+(use-package flyspell
+ :defer t)
+
+(use-package mu4e
+ :ensure nil
+ :config
+ ;; This is set to 't' to avoid mail syncing issues when using mbsync
+ (setq mu4e-change-filenames-when-moving t)
+
+ ;; don't keep message compose buffers around after sending:
+ (setq message-kill-buffer-on-exit t)
+
+ ;; send function:
+ (setq send-mail-function 'sendmail-send-it
+ message-send-mail-function 'sendmail-send-it)
+
+ ;; send program:
+ ;; this is exeranal. remember we installed it before.
+ (setq sendmail-program (executable-find "msmtp"))
+
+ ;; select the right sender email from the context.
+ (setq message-sendmail-envelope-from 'header)
+
+ ;; Refresh mail using isync every 10 minutes
+ (setq mu4e-update-interval (* 10 60)
+ mu4e-get-mail-command "mbsync -a"
+ mu4e-view-show-images t
+ mu4e-view-show-addresses t
+ mu4e-attachment-dir "~/Downloads"
+ mu4e-view-prefer-html t
+ mu4e-maildir "~/mail")
+
+ (setq mu4e-contexts
+ (list
+ ;; Home
+ (make-mu4e-context
+ :name "home"
+ :enter-func (lambda () (mu4e-message "Entering personal context"))
+ :leave-func (lambda () (mu4e-message "Leaving personal context"))
+ :match-func
+ (lambda (msg)
+ (when msg
+ (string-prefix-p "/home" (mu4e-message-field msg :maildir))))
+ :vars '((user-mail-address . "marc@mccd.space")
+ (user-full-name . "Marc Coquand")
+ (mu4e-drafts-folder . "/home/Drafts")
+ (mu4e-sent-folder . "/home/Sent")
+ (mu4e-refile-folder . "/home/Archive")
+ (mu4e-trash-folder . "/home/Trash")
+ (mu4e-sent-messages-behavior . sent)
+
+ (mu4e-maildir-shortcuts .
+ (("/home/INBOX" . ?i)
+ ("/home/Archive/Done" . ?d)
+ ("/home/Archive" . ?a)
+ ("/home/Archive/Todo" . ?t)))))
+ ;; Work account
+ (make-mu4e-context
+ :name "work"
+ :enter-func (lambda () (mu4e-message "Entering work context"))
+ :leave-func (lambda () (mu4e-message "Leaving work context"))
+ :match-func
+ (lambda (msg)
+ (when msg
+ (string-prefix-p "/work" (mu4e-message-field msg :maildir))))
+ :vars '((user-mail-address . "marc.coquand@sustainably.app")
+ (user-full-name . "Marc Coquand")
+ (mu4e-drafts-folder . "/work/[Gmail]/Drafts")
+ (mu4e-sent-folder . "/work/[Gmail]/Sent Mail")
+ (mu4e-refile-folder . "/work/[Gmail]/All Mail")
+ (mu4e-sent-messages-behavior . delete)
+ (mu4e-trash-folder . "/work/[Gmail]/Trash")
+ (mu4e-maildir-shortcuts .
+ (("/work/[Gmail]/All Mail" . ?a)
+ ("/work/INBOX" . ?i))))))))
+
+
+(use-package lem
+ :ensure t
+ :config
+ (setq lem-instance-url "https://lemmy.sdf.org"))
+
+(use-package elfeed-protocol
+ :ensure t
+ :init
+ (elfeed-protocol-enable))
+
+(use-package elfeed
+ :ensure t
+ :config
+ (setq elfeed-use-curl t
+ ;; setup feeds
+ elfeed-protocol-fever-update-unread-only t
+ elfeed-protocol-fever-fetch-category-as-tag t
+ elfeed-protocol-feeds '(("fever+https://freshrss@rss.mccd.space"
+ :api-url "https://rss.mccd.space/api/fever.php"
+ :password (shell-command-to-string "pass show mccd/freshrss")))
+ ;; enable elfeed-protocol
+ elfeed-protocol-enabled-protocols '(fever)
+ elfeed-curl-extra-arguments '("--insecure")) ;necessary for https without a trust certificate
+ (elfeed-set-timeout 36000)
+ (global-set-key (kbd "C-x w") 'elfeed))
+
+(use-package mastodon
+ :defer t
+ :config
+ (setq
+ mastodon-active-user "marcc"
+ mastodon-instance-url "https://fosstodon.org"))
+
+(use-package eww
+ :config
+ (setq
+ browse-url-browser-function 'eww-browse-url ; Use eww as the default browser
+ eww-search-prefix "https://lite.duckduckgo.com/lite/?q="
+ shr-max-image-proportion 0.3
+ shr-width 70))
+
+;; Can play youtube urls and music.
+;; Requires mpv
+(use-package emms
+ :ensure t
+ :init
+ (add-hook 'emms-player-started-hook 'emms-show)
+ :config
+ (setq emms-shop-format "on: %s")
+ (emms-all)
+ (emms-default-players))
+
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(default ((t (:inherit nil :extend nil :stipple nil :background "white" :foreground "black" :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight regular :height 150 :width expanded :foundry "UKWN" :family "Iosevka SS13 Extended"))))
+ '(avy-lead-face ((t (:inherit fixed-pitch :background "dark red" :foreground "white"))))
+ '(calendar-weekend-header ((t (:inherit nil))))
+ '(custom-group-subtitle ((t (:weight bold :family "Iosevka Aile"))))
+ '(diary ((t (:inherit fixed-pitch :foreground "red1"))))
+ '(eglot-highlight-symbol-face ((t (:weight bold))))
+ '(eglot-mode-line ((t (:weight regular))))
+ '(erc-timestamp-face ((t (:foreground "blue" :weight bold))))
+ '(eshell-prompt ((t (:weight bold))))
+ '(eww-valid-certificate ((t (:foreground "black" :weight bold))))
+ '(fixed-pitch ((t (:family "Iosevka SS13 Extended"))))
+ '(font-lock-builtin-face ((t (:weight regular))))
+ '(font-lock-comment-face ((t (:foreground "royalblue" :slant normal))))
+ '(font-lock-constant-face ((t (:slant italic :weight regular))))
+ '(font-lock-function-name-face ((t (:weight regular))))
+ '(font-lock-keyword-face ((t (:weight regular))))
+ '(font-lock-string-face ((t (:foreground "black" :slant italic))))
+ '(font-lock-type-face ((t (:foreground "black"))))
+ '(font-lock-variable-name-face ((t (:foreground "black"))))
+ '(fringe ((t (:background "white"))))
+ '(header-line ((t (:inherit default :foreground "grey20" :box (:line-width (8 . 8) :color "#FFFFFF") :underline (:color "#e0e0e0" :style line :position 0) :family "Iosevka Aile"))))
+ '(highlight ((t (:background "azure2"))))
+ '(info-header-xref ((t (:inherit info-xref :underline (:color "RoyalBlue3" :style line :position t)))))
+ '(info-node ((t (:foreground "brown" :box (:line-width (4 . 4) :color "white") :slant italic :weight bold))))
+ '(link ((t (:foreground "royalblue" :underline t))))
+ '(magit-branch-remote ((t (:foreground "royalblue"))))
+ '(markdown-inline-code-face ((t (:inherit markdown-code-face))))
+ '(markdown-pre-face ((t (:inherit markdown-code-face))))
+ '(mastodon-display-name-face ((t (:inherit nil :weight bold))))
+ '(mode-line ((t (:background "gray95" :foreground "black" :box (:line-width (8 . 8) :style flat-button) :overline "#e0e0e0" :underline (:color "#e0e0e0" :style line :position t) :family "Iosevka Aile"))))
+ '(mode-line-emphasis ((t (:weight regular))))
+ '(mode-line-inactive ((t (:inherit mode-line :background "#fbfbfb" :foreground "grey60" :overline "#f9f9f9" :underline (:color "#f9f9f9" :style line :position 0) :weight light))))
+ '(mu4e-header-highlight-face ((t (:inherit hl-line :extend t :weight bold))))
+ '(mu4e-highlight-face ((t (:inherit highlight))))
+ '(org-date ((t (:inherit fixed-pitch :foreground "gray40" :underline t))))
+ '(org-headline-done ((t (:foreground "gray40"))))
+ '(org-level-1 ((t (:inherit outline-1 :extend nil :weight regular))))
+ '(org-tag ((t (:inherit fixed-pitch :foreground "gray40" :weight regular))))
+ '(org-time-grid ((t (:foreground "gray"))))
+ '(outline-4 ((t (:inherit outline-2))))
+ '(tab-bar ((t (:box (:line-width (12 . 24) :style flat-button) :weight semi-light :family "Iosevka Aile"))))
+ '(tab-bar-tab ((t (:inherit tab-bar :foreground "black" :box (:line-width (20 . 1) :color "white") :weight semi-bold))))
+ '(tab-bar-tab-inactive ((t (:inherit tab-bar-tab :background "white" :foreground "#999999" :weight semi-light))))
+ '(tldr-code-block ((t (:background "cornsilk" :foreground "black"))))
+ '(tldr-command-argument ((t (:background "cornsilk" :foreground "black"))))
+ '(tldr-command-itself ((t (:background "khaki" :foreground "black" :weight bold))))
+ '(tldr-introduction ((t (:foreground "black" :slant italic))))
+ '(tldr-title ((t (:inherit variable-pitch :foreground "black" :weight bold :height 1.2))))
+ '(variable-pitch ((t (:family "Iosevka Aile"))))
+ '(window-divider ((t (:foreground "gray90")))))
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(custom-safe-themes
+ '("cbd85ab34afb47003fa7f814a462c24affb1de81ebf172b78cb4e65186ba59d2" default))
+ '(erc-mode-line-format "")
+ '(erc-modules
+ '(autojoin button completion fill irccontrols list match menu move-to-prompt netsplit networks noncommands notifications readonly ring services stamp spelling))
+ '(magit-section-visibility-indicator '("..." . t))
+ '(markdown-list-item-bullets '("-"))
+ '(mastodon-tl--enable-proportional-fonts t)
+ '(mastodon-use-emojify t)
+ '(mode-line-compact 'long)
+ '(mode-line-format
+ '("%e" mode-line-front-space
+ (:propertize
+ ("" mode-line-modified " "))
+ mode-line-buffer-identification " " mode-line-modes))
+ '(mode-line-percent-position nil)
+ '(mode-line-position-line-format '(" "))
+ '(mu4e-bookmarks
+ '((:name "Last 7 days" :query "date:7d..now" :hide-unread t :key 119)
+ (:name "Messages with images" :query "mime:image/*" :key 112)))
+ '(org-agenda-files
+ '("~/personal-db/notes/sustainable-software.org" "/home/mccd/personal-db/notes/thoughts.org" "/home/mccd/personal-db/notes/cal-ios.org" "/home/mccd/personal-db/notes/ethics-and-software.org" "/home/mccd/personal-db/notes/reminders.org" "/home/mccd/builds/sustainably/piva.org" "/home/mccd/personal-db/notes/programming.org" "/home/mccd/personal-db/notes/unix.org" "/home/mccd/personal-db/notes/agency-and-tech.org" "/home/mccd/personal-db/notes/emacs-teaches.org" "/home/mccd/personal-db/notes/emacs.org" "/home/mccd/personal-db/notes/inbox.org" "/home/mccd/personal-db/notes/todo.org"))
+ '(org-fold-core-style 'overlays)
+ '(package-selected-packages
+ '(nov eldoc-box hide-mode-line exwm-mff eat pinentry exwm emms company orglink web-mode flycheck nix-mode nix-ts-mode avy pdf-tools elfeed-protocol lem yasnippet-snippets elfeed yasnippet smartparens markdown-mode mastodon tldr almost-mono-themes rec-mode magit go-mode expand-region devdocs))
+ '(tab-bar-auto-width t)
+ '(tab-bar-close-button-show nil)
+ '(tab-bar-format
+ '(tab-bar-format-tabs tab-bar-format-align-right tab-bar-format-global))
+ '(tab-bar-position nil)
+ '(tab-bar-tab-hints t)
+ '(window-divider-default-right-width 2)
+ '(yank-from-kill-ring-rotate t))
+(put 'secrets-mode 'disabled nil)
diff --git a/home/dots/.emacs.d/elisp/almost-mono-themes.el b/home/dots/.emacs.d/elisp/almost-mono-themes.el
new file mode 100644
index 0000000..4b7769e
--- /dev/null
+++ b/home/dots/.emacs.d/elisp/almost-mono-themes.el
@@ -0,0 +1,205 @@
+;;; almost-mono-themes.el --- Almost monochromatic color themes -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 - 2022 John Olsson
+
+;; Author: John Olsson <john@cryon.se>
+;; Maintainer: John Olsson <john@cryon.se>
+;; URL: https://github.com/cryon/almost-mono-themes
+;; Created: 9th May 2019
+;; Version: 1.0.0
+;; Keywords: faces
+;; Package-Requires: ((emacs "24"))
+
+;; This file is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+
+;; This file is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this file. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A suite of almost monochrome Emacs themes
+
+;;; Code:
+
+(defconst almost-mono-themes-colors
+ '((white . ((background . "#ffffff")
+ (foreground . "#000000")
+ (weak . "#888888")
+ (weaker . "#dddddd")
+ (weakest . "#efefef")
+ (highlight . "#fda50f")
+ (warning . "#ff0000")
+ (success . "#00ff00")
+ (string . "#3c5e2b")))
+
+ (black . ((background . "#000000")
+ (foreground . "#ffffff")
+ (weak . "#aaaaaa")
+ (weaker . "#666666")
+ (weakest . "#222222")
+ (highlight . "#fda50f")
+ (warning . "#ff0000")
+ (success . "#00ff00")
+ (string . "#a7bca4")))
+
+ (gray . ((background . "#2b2b2b")
+ (foreground . "#ffffff")
+ (weak . "#aaaaaa")
+ (weaker . "#666666")
+ (weakest . "#222222")
+ (highlight . "#fda50f")
+ (warning . "#ff0000")
+ (success . "#00ff00")
+ (string . "#a7bca4")))
+
+ (cream . ((background . "#f0e5da")
+ (foreground . "#000000")
+ (weak . "#7d7165")
+ (weaker . "#c4baaf")
+ (weakest . "#dbd0c5")
+ (highlight . "#fda50f")
+ (warning . "#ff0000")
+ (success . "#00ff00")
+ (string . "#3c5e2b")))))
+
+(defmacro almost-mono-themes--variant-with-colors (variant &rest body)
+ "Execute BODY in a scope where the different colors for given VARIANT is bound."
+ `(let* ((colors (or (cdr (assoc ,variant almost-mono-themes-colors))
+ (error "No such theme variant")))
+ (background (cdr (assoc 'background colors)))
+ (foreground (cdr (assoc 'foreground colors)))
+ (weak (cdr (assoc 'weak colors)))
+ (weaker (cdr (assoc 'weaker colors)))
+ (weakest (cdr (assoc 'weakest colors)))
+ (highlight (cdr (assoc 'highlight colors)))
+ (warning (cdr (assoc 'warning colors)))
+ (success (cdr (assoc 'success colors)))
+ (string (cdr (assoc 'string colors))))
+ ,@body))
+
+(defmacro almost-mono-themes--faces-spec ()
+ "Provide the faces specification."
+ (quote
+ (mapcar
+ (lambda (entry) (list (car entry) `((t ,@(cdr entry)))))
+ `(
+
+ ;; default
+ (default (:background ,background :foreground ,foreground))
+ (fringe (:background ,background))
+ (region (:background ,highlight :foreground ,foreground))
+ (show-paren-match (:background ,background :foreground ,success :bold t))
+ (show-paren-mismatch (:background ,background :foreground ,warning :bold t))
+ (minibuffer-prompt (:weight bold :foreground ,foreground))
+ (isearch (:background ,weak :foreground ,foreground :bold t))
+ (lazy-highlight (:background ,weaker :foreground ,foreground))
+ (link (:underline t))
+
+ ;; mode line
+ (mode-line (:box (:line-width -1 :color ,weaker)
+ :background ,weakest :foreground ,foreground))
+
+ (mode-line-inactive (:box (:line-width -1 :color ,weaker)
+ :background ,background :foreground ,weaker))
+
+ ;; font lock
+ (font-lock-keyword-face (:bold t))
+ (font-lock-function-name-face (:bold t))
+ (font-lock-variable-name-face (:foreground ,foreground))
+ (font-lock-warning-face (:foreground ,foreground :underline (:color ,warning :style wave)))
+ (font-lock-builtin-face (:bold t))
+ (font-lock-variable-name-face (:foreground ,foreground :italic t))
+ (font-lock-constant-face (:bold t :italic t))
+ (font-lock-type-face (:italic t))
+ (font-lock-preprocessor-face (:italic t))
+ (font-lock-comment-face (:foreground ,weak :italic t))
+ (font-lock-string-face (:foreground ,string))
+ (font-lock-doc-face (:inherit font-lock-comment-face))
+ (line-number (:foreground ,weaker))
+ (linum (:inherit line-number))
+ (vertical-border (:foreground ,weaker))
+
+ ;; eshell
+ (eshell-prompt (:foreground ,foreground :bold t))
+ (eshell-ls-directory (:foreground ,foreground :bold t))
+ (eshell-ls-archive (:inherit eshell-ls-unreadable))
+ (eshell-ls-backup (:inherit eshell-ls-unreadable))
+ (eshell-ls-clutter (:inherit eshell-ls-unreadable))
+ (eshell-ls-executable (:inherit eshell-ls-unreadable))
+ (eshell-ls-missing (:inherit eshell-ls-unreadable))
+ (eshell-ls-product (:inherit eshell-ls-unreadable))
+ (eshell-ls-readonly (:inherit eshell-ls-unreadable))
+ (eshell-ls-special (:inherit eshell-ls-unreadable))
+ (eshell-ls-symlink (:inherit eshell-ls-unreadable))
+
+ ;; company mode
+ (company-tooltip (:background ,weakest :foreground ,foreground))
+ (company-tooltip-selection (:background ,weaker :foreground ,foreground))
+ ;;(company-tooltip-search (:background "#ff0000" :foreground "#00ff00"))
+ (company-tooltip-common (:bold t))
+ (company-tooltip-common-selection (:bold t))
+ (company-scrollbar-bg (:background ,weaker))
+ (company-scrollbar-fg (:background ,weak))
+ (company-tooltip-annotation-selection (:background ,weaker :foreground ,foreground :italic t))
+ (company-tooltip-annotation (:background ,weakest :foreground ,weak :italic t))
+
+ ;; git gutter
+ (git-gutter:modified (:background ,highlight :foreground ,highlight))
+ (git-gutter:added (:background ,success :foreground ,success))
+ (git-gutter:deleted (:background ,warning :foreground ,warning))
+
+ ;; diff hl
+ (diff-hl-change (:background ,highlight :foreground ,highlight))
+ (diff-hl-insert (:background ,success :foreground ,success))
+ (diff-hl-delete (:background ,warning :foreground ,warning))
+
+ ;; hl line
+ (hl-line (:background ,weakest))
+ (highlight-current-line-face (:inherit hl-line))
+
+ ;; ido
+ (ido-first-match (:bold t))
+ (ido-only-match (:bold t))
+ (ido-subdir (:italic t))
+ (ido-virtual (:foreground ,weak))
+ (ido-vertical-match-face (:bold t :italic nil))
+
+ ;; org mode
+ (org-table (:foreground ,weak))
+
+ ))))
+
+
+(defun almost-mono-themes--variant-name (variant)
+ "Create symbol for color theme variant VARIANT."
+ (intern (format "almost-mono-%s" (symbol-name variant))))
+
+(defmacro almost-mono-themes--define-theme (variant)
+ "Define a theme for the almost-mono variant VARIANT."
+ (let ((name (almost-mono-themes--variant-name variant))
+ (doc (format "almost mono theme (%s version)" variant)))
+ `(progn
+ (deftheme ,name ,doc)
+ (put ',name 'theme-immediate t)
+ (almost-mono-themes--variant-with-colors
+ ',variant
+ (apply 'custom-theme-set-faces ',name
+ (almost-mono-themes--faces-spec)))
+ (provide-theme ',name))))
+
+;;;###autoload
+(when (and (boundp 'custom-theme-load-path) load-file-name)
+ (add-to-list 'custom-theme-load-path
+ (file-name-as-directory (file-name-directory load-file-name))))
+
+(provide 'almost-mono-themes)
+
+;;; almost-mono-themes.el ends here
diff --git a/home/dots/.emacs.d/elisp/exwm-mff.el b/home/dots/.emacs.d/elisp/exwm-mff.el
new file mode 100644
index 0000000..6b1ef87
--- /dev/null
+++ b/home/dots/.emacs.d/elisp/exwm-mff.el
@@ -0,0 +1,191 @@
+;;; exwm-mff.el --- Mouse Follows Focus -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019, 2020, 2021 Ian Eure
+
+;; Author: Ian Eure <public@lowbar.fyi>
+;; URL: https://github.com/ieure/exwm-mff
+;; Version: 1.2.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: unix
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Mouse Follows Focus
+;; ===================
+;;
+;; Traditional window managers are mouse-centric: the window to receive
+;; input is usually selected with the pointing device.
+;;
+;; Emacs is keybord-centric: the window to receive key input is usually
+;; selected with the keyboard. When you use the keyboard to focus a
+;; window, the spatial relationship between pointer and active window is
+;; broken -- the pointer can be anywhere on the screen, instead of over
+;; the active window, which can make it hard to find.
+;;
+;; The same problem also exists in traditional windowing systems when
+;; you use the keyboard to switch windows, e.g. with Alt-Tab.
+;;
+;; Because Emacs’ model is inverted, this suggests that the correct
+;; behavior is also the inverse -- instead of using the mouse to
+;; select a window to receive keyboard input, the keyboard should be
+;; used to select the window to receive mouse input.
+;;
+;; `EXWM-MFF-MODE' is a global minor mode which does exactly this.
+;; When the selected window in Emacs changes, the mouse pointer is
+;; moved to its center, unless the pointer is already somewhere inside
+;; the window’s bounds. While it's especially helpful for for EXWM
+;; users, it works for any Emacs window in a graphical session.
+;;
+;; This package also offers the `EXWM-MFF-WARP-TO-SELECTED' command,
+;; which allows you to summon the pointer with a hotkey. Unlike the
+;; minor mode, summoning is unconditional, and will place the pointer in
+;; the center of the window even if it already resides within its bounds
+;; -- a handy feature if you’ve lost your pointer, even if you’re using
+;; the minor mode.
+;;
+;;
+;; Limitations
+;; ~~~~~~~~~~~
+;;
+;; None known at this time.
+
+;;; Code:
+
+(require 'subr-x)
+(require 'cl-macs)
+
+(defcustom exwm-mff-ignore-if nil
+ "List of predicate functions for windows to ignore.
+
+Predicates accept one argument, WINDOW, and return non-NIL if
+automatic pointer warping should be suppressed."
+ :type 'hook
+ :group 'exwm-mff)
+
+(defconst exwm-mff--debug-buffer " *exwm-mff-debug*"
+ "Name of the buffer exwm-mff will write debug messages into.")
+
+(defvar exwm-mff--debug 0
+ "Whether (and how) to debug exwm-mff.
+0 = don't debug.
+1 = log messages to *exwm-mff-debug*.
+2 = log messages to *exwm-mff-debug* and the echo area.")
+
+(defvar exwm-mff--last-window nil
+ "The last selected window.")
+
+(defun exwm-mff--guard ()
+ "Raise an error unless this is a graphic session with mouse support."
+ (unless (and (display-graphic-p) (display-mouse-p))
+ (error "EXWM-MFF-MODE doesn't work on non-graphic or non-mouse sessions")))
+
+(defun exwm-mff--contains-pointer? (window)
+ "Return non-NIL when the mouse pointer is within FRAME and WINDOW."
+ (cl-destructuring-bind ((mouse-x . mouse-y) (left top right bottom))
+ (list (mouse-absolute-pixel-position)
+ (window-absolute-pixel-edges window))
+ (and (<= left mouse-x right)
+ (<= top mouse-y bottom))))
+
+(defun exwm-mff--debug (string &rest objects)
+ "Log debug message STRING, using OBJECTS to format it."
+ (let ((debug-level (or exwm-mff--debug 0)))
+ (when (> debug-level 0)
+ (let ((str (apply #'format (concat "[%s] " string)
+ (cons (current-time-string) objects))))
+ (when (>= debug-level 1)
+ (with-current-buffer (get-buffer-create exwm-mff--debug-buffer)
+ (goto-char (point-max))
+ (insert (concat str "\n")))
+ (when (>= debug-level 2)
+ (message str)))))))
+
+(defun exwm-mff-show-debug ()
+ "Enable exwm-mff debugging, and show the buffer with debug logs."
+ (interactive)
+ (setq exwm-mff--debug 1)
+ (pop-to-buffer (get-buffer-create exwm-mff--debug-buffer)))
+
+(defun exwm-mff--window-center (window)
+ "Return a list of (x y) coordinates of the center of WINDOW in FRAME."
+ (cl-destructuring-bind (left top right bottom) (window-pixel-edges window)
+ (list (+ left (/ (- right left) 2))
+ (+ top (/ (- bottom top) 2)))))
+
+(defun exwm-mff-warp-to (frame window)
+ "Place the pointer in the center of WINDOW in FRAME."
+ (apply #'set-mouse-pixel-position frame
+ (exwm-mff--window-center window)))
+
+;;;###autoload
+(defun exwm-mff-warp-to-selected ()
+ "Place the pointer in the center of the selected window."
+ (interactive)
+ (exwm-mff--guard)
+ (exwm-mff-warp-to (selected-frame) (selected-window)))
+
+(defun exwm-mff--explain (selected-window same-window? contains-pointer? mini? ignored?)
+ "Use SELECTED-WINDOW, SAME-WINDOW?, CONTAINS-POINTER?, MINI?
+and IGNORED? to return an explanation of focusing behavior."
+ (cond
+ (same-window? "selected window hasn't changed")
+ (contains-pointer? "already contains pointer")
+ (mini? "is minibuffer")
+ (ignored? "one or more functions in `exwm-mff-ignore-if' matches")
+ (t (format "doesn't contain pointer (in %s)" selected-window))))
+
+(defun exwm-mff-hook (sw &optional norecord)
+ "EXWM-MFF-MODE hook.
+
+This is after-advice placed on SELECT-WINDOW. It moves the
+pointer to SW (the currently selected window), if NORECORD is
+nil, and if it's not already in it."
+ (unless norecord
+ (if-let ((same-window? (eq sw exwm-mff--last-window)))
+ ;; The selected window is unchanged, we don't need to check
+ ;; anything else.
+ (exwm-mff--debug
+ "nop-> %s" (exwm-mff--explain sw same-window? nil nil nil))
+
+ (let* ((sf (window-frame sw))
+ (contains-pointer? (exwm-mff--contains-pointer? sw))
+ (mini? (minibufferp (window-buffer sw)))
+ (ignore? (run-hook-with-args-until-success 'exwm-mff-ignore-if sw)))
+ (if (or same-window? contains-pointer? mini? ignore?)
+ (exwm-mff--debug
+ "nop-> %s::%s (%s)" sf sw (exwm-mff--explain sw nil contains-pointer? mini? ignore?))
+ (exwm-mff--debug
+ "warp-> %s::%s (%s)" sf sw (exwm-mff--explain sw nil contains-pointer? mini? ignore?))
+ (exwm-mff-warp-to sf (setq exwm-mff--last-window sw)))))))
+
+(defgroup exwm-mff nil
+ "Mouse-Follows-Focus mode for EXWM."
+ :group 'exwm)
+
+;;;###autoload
+(define-minor-mode exwm-mff-mode
+ "Mouse follows focus mode for EXWM."
+ :global t
+ :require 'exwm-mff
+ :group 'exwm-mff
+ (exwm-mff--guard)
+ (if exwm-mff-mode
+ (advice-add 'select-window :after #'exwm-mff-hook)
+ (advice-remove 'select-window #'exwm-mff-hook)))
+
+(provide 'exwm-mff)
+
+;;; exwm-mff.el ends here
diff --git a/home/dots/.emacs.d/elisp/org-link-minor-mode.el b/home/dots/.emacs.d/elisp/org-link-minor-mode.el
new file mode 100644
index 0000000..7f1faaa
--- /dev/null
+++ b/home/dots/.emacs.d/elisp/org-link-minor-mode.el
@@ -0,0 +1,137 @@
+;;; org-link-minor-mode.el --- Enable org-mode links in non-org modes -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2012-2020
+;;
+;; Author: Sean O'Halpin <sean.ohalpin@gmail.com>
+;; Maintainer: Sean O'Halpin <sean.ohalpin@gmail.com>
+;; Created: 20120825
+;; Modified: 20200129
+;; Version: 0.0.3
+;; Package-Requires: ((emacs "24.3"))
+;; Package-Version: 20200129.0141
+;; Keywords: hypermedia
+;; Url: https://github.com/seanohalpin/org-link-minor-mode
+;;
+;; Changes for org v9: Stefan-W. Hahn <stefan dot hahn at s-hahn dot de>
+;;
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+;;
+;;; Commentary:
+;;
+;; Enables org-mode links of the form:
+;;
+;; http://www.bbc.co.uk
+;; man:emacs
+;; info:emacs
+;; <http://www.bbc.co.uk>
+;; [[http://www.bbc.co.uk][BBC]]
+;; [[org-link-minor-mode]]
+;; [2012-08-18]
+;; <2012-08-18>
+;;
+;; Note that `org-toggle-link-display' will also work when this mode
+;; is enabled.
+;;
+;;; Code:
+
+(require 'org-element)
+
+;; Following declarations are necessary to make the byte compiler happy.
+
+;; For org v8 compatibility (if used with org v9)
+(declare-function org-activate-plain-links "org" (limit))
+(declare-function org-activate-angle-links "org" (limit))
+(declare-function org-activate-bracket-links "org" (limit))
+(declare-function org-decompose-region "org-compat" (beg end))
+
+;; For org v9 compatibility (if used with org v8)
+(declare-function org-activate-links "org" (limit))
+(declare-function org-activate-dates "org" (limit))
+
+(defun org-link-minor-mode--unfontify-region (beg end)
+ "Remove org-link fontification between BEG and END."
+ (font-lock-default-unfontify-region beg end)
+ (let* ((buffer-undo-list t)
+ (inhibit-read-only t) (inhibit-point-motion-hooks t)
+ (inhibit-modification-hooks t)
+ deactivate-mark buffer-file-name buffer-file-truename)
+ (if (fboundp 'org-decompose-region)
+ (org-decompose-region beg end)
+ (decompose-region beg end))
+ (remove-text-properties beg end
+ '(mouse-face t keymap t org-linked-text t
+ invisible t intangible t
+ help-echo t rear-nonsticky t
+ htmlize-link t
+ org-no-flyspell t org-emphasis t))
+ (org-remove-font-lock-display-properties beg end)))
+
+(defvar org-link-minor-mode-map (make-sparse-keymap)
+ "Local keymap.")
+(make-variable-buffer-local 'org-link-minor-mode-map)
+
+;;;###autoload
+(define-minor-mode org-link-minor-mode
+ "Toggle display of org-mode style links in non-org-mode buffers."
+ :lighter " org-link"
+ :keymap org-link-minor-mode-map
+ (let ((lk org-highlight-links)
+ org-link-minor-mode-keywords)
+ (if (fboundp 'org-activate-links)
+ ;; from Org v9.2
+ (setq org-link-minor-mode-keywords
+ (list
+ '(org-activate-links)
+ (when (memq 'tag lk) '(org-activate-tags (1 'org-tag prepend)))
+ (when (memq 'radio lk) '(org-activate-target-links (1 'org-link t)))
+ (when (memq 'date lk) '(org-activate-dates (0 'org-date t)))
+ (when (memq 'footnote lk) '(org-activate-footnote-links))))
+ (setq org-link-minor-mode-keywords
+ (list
+ (when (memq 'tag lk) '(org-activate-tags (1 'org-tag prepend)))
+ (when (memq 'angle lk) '(org-activate-angle-links (0 'org-link t)))
+ (when (memq 'plain lk) '(org-activate-plain-links (0 'org-link t)))
+ (when (memq 'bracket lk) '(org-activate-bracket-links (0 'org-link t)))
+ (when (memq 'radio lk) '(org-activate-target-links (0 'org-link t)))
+ (when (memq 'date lk) '(org-activate-dates (0 'org-date t)))
+ (when (memq 'footnote lk) '(org-activate-footnote-links)))))
+ (if org-link-minor-mode
+ (if (derived-mode-p 'org-mode)
+ (progn
+ (message "org-mode doesn't need org-link-minor-mode")
+ (org-link-minor-mode -1))
+ (font-lock-add-keywords nil org-link-minor-mode-keywords t)
+ (kill-local-variable 'org-mouse-map)
+ (setq-local org-mouse-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [return] 'org-open-at-point)
+ (define-key map [tab] 'org-next-link)
+ (define-key map [backtab] 'org-previous-link)
+ (define-key map [mouse-2] 'org-open-at-point)
+ (define-key map [follow-link] 'mouse-face)
+ map))
+ (setq-local font-lock-unfontify-region-function
+ 'org-link-minor-mode--unfontify-region)
+ (setq-local org-descriptive-links nil)
+ (org-toggle-link-display))
+ (unless (derived-mode-p 'org-mode)
+ (font-lock-remove-keywords nil org-link-minor-mode-keywords)
+ (setq org-descriptive-links t)
+ (org-toggle-link-display)
+ (kill-local-variable 'org-descriptive-links)
+ (kill-local-variable 'org-mouse-map)
+ (kill-local-variable 'font-lock-unfontify-region-function)))))
+
+(provide 'org-link-minor-mode)
+;;; org-link-minor-mode.el ends here
diff --git a/home/dots/.emacs.d/snippets/go-mode/errnotnil b/home/dots/.emacs.d/snippets/go-mode/errnotnil
new file mode 100644
index 0000000..0122e56
--- /dev/null
+++ b/home/dots/.emacs.d/snippets/go-mode/errnotnil
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: err not nil
+# key: ;
+# --
+; err != nil \ No newline at end of file
diff --git a/home/dots/.emacs.d/snippets/go-mode/error b/home/dots/.emacs.d/snippets/go-mode/error
new file mode 100644
index 0000000..799e9f8
--- /dev/null
+++ b/home/dots/.emacs.d/snippets/go-mode/error
@@ -0,0 +1,7 @@
+# -*- mode: snippet -*-
+# name: error
+# key: err@
+# --
+if err != nil {
+ $0
+}
diff --git a/home/dots/.emacs.d/snippets/mhtml-mode/<div>..</div>~ b/home/dots/.emacs.d/snippets/mhtml-mode/<div>..</div>~
new file mode 100644
index 0000000..028d782
--- /dev/null
+++ b/home/dots/.emacs.d/snippets/mhtml-mode/<div>..</div>~
@@ -0,0 +1,7 @@
+# -*- mode: snippet -*-
+# name: <div>..</div>
+# key: <div
+# --
+<div>
+ $1
+</div>
diff --git a/home/dots/.gitconfig b/home/dots/.gitconfig
new file mode 100644
index 0000000..99a675c
--- /dev/null
+++ b/home/dots/.gitconfig
@@ -0,0 +1,49 @@
+[alias]
+ pr = "!gh pr"
+ issue = "!gh issue"
+ bug = "!git-bug"
+[user]
+ email = marc@mccd.space
+ name = Marc Coquand
+[credential "https://github.com"]
+ helper = !gh auth git-credential
+[credential "https://gist.github.com"]
+ helper = !gh auth git-credential
+[credential "smtp://marcc%40fastmail.fr@smtp.fastmail.com%3a465"]
+ helper =
+ helper = !pass 'fastmail/git'
+[color]
+ ui = false
+[merge]
+ tool = meld
+[mergetool]
+ layout = LOCAL,MERGED,REMOTE
+[sendemail]
+ smtpserver = smtp.fastmail.com
+ smtpuser = marcc@fastmail.fr
+ smtpencryption = ssl
+ smtpserverport = 465
+[pull]
+ rebase = true
+[color "diff"]
+ meta = blue
+ old = red
+ new = green
+[log]
+ date = relative
+[format]
+ pretty = oneline
+ signoff = true
+[credential]
+ helper = store
+[push]
+ autoSetupRemote = true
+[commit]
+ gpgsign = true
+ verbose = true
+[init]
+ defaultBranch = main
+[grep]
+ lineNumber = true
+[help]
+ autocorrect = prompt
diff --git a/home/dots/.local/bin/capture b/home/dots/.local/bin/capture
new file mode 100755
index 0000000..c4cd844
--- /dev/null
+++ b/home/dots/.local/bin/capture
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+DATE=$(date +'%y-%m-%d.%H:%M.%S')
+CAPTURE_FILE="/tmp/capture-$DATE"
+echo $DATE
+JRNL="$STITCH_DIRECTORY/$DATE.org"
+echo '* ' > $CAPTURE_FILE
+$EDITOR $CAPTURE_FILE +1
+if grep -q '^\*\s*$' $CAPTURE_FILE
+then
+ echo "Empty capture; ignoring"
+else
+ echo "Storing capture in $JRNL"
+ cat $CAPTURE_FILE > $JRNL
+fi
+
diff --git a/home/dots/.local/bin/convert-website b/home/dots/.local/bin/convert-website
new file mode 100755
index 0000000..2b951d7
--- /dev/null
+++ b/home/dots/.local/bin/convert-website
@@ -0,0 +1,5 @@
+#!/bin/env sh
+for file in $*
+do
+ pandoc $file --from html --to markdown_strict | NO_COLOR=true lowdown -tterm -o "$file.md"
+done
diff --git a/home/dots/.local/bin/logdate b/home/dots/.local/bin/logdate
new file mode 100755
index 0000000..337552a
--- /dev/null
+++ b/home/dots/.local/bin/logdate
@@ -0,0 +1,2 @@
+#!/bin/env sh
+date +"%Y-%m-%d"
diff --git a/home/dots/.local/bin/nextcloud-sync b/home/dots/.local/bin/nextcloud-sync
new file mode 100755
index 0000000..cb7901a
--- /dev/null
+++ b/home/dots/.local/bin/nextcloud-sync
@@ -0,0 +1,5 @@
+#!/bin/env sh
+
+/usr/bin/rclone bisync storage.mccd.space:personal-db ~/personal-db
+/usr/bin/rclone bisync storage.mccd.space:Articles ~/docs
+/usr/bin/rclone bisync storage.mccd.space:Shared ~/shared
diff --git a/home/dots/.local/bin/org-sync b/home/dots/.local/bin/org-sync
new file mode 100755
index 0000000..47474e6
--- /dev/null
+++ b/home/dots/.local/bin/org-sync
@@ -0,0 +1,11 @@
+#!/usr/bin/env sh
+
+IS_CONNECTED=$(nmcli | grep -e ^wlp610s0)
+
+if $(echo $IS_CONNECTED | grep -q "disconnected")
+then
+ echo "System is not connected to Wifi. Will not sync";
+else
+ /usr/bin/env rclone bisync storage:personal-db ~/personal-db;
+ echo "Sync complete";
+fi
diff --git a/home/dots/.local/bin/pfetch b/home/dots/.local/bin/pfetch
new file mode 100755
index 0000000..bfc58b6
--- /dev/null
+++ b/home/dots/.local/bin/pfetch
@@ -0,0 +1,1956 @@
+#!/bin/sh
+#
+# pfetch - Simple POSIX sh fetch script.
+
+# Wrapper around all escape sequences used by pfetch to allow for
+# greater control over which sequences are used (if any at all).
+esc() {
+ case $1 in
+ CUU) e="${esc_c}[${2}A" ;; # cursor up
+ CUD) e="${esc_c}[${2}B" ;; # cursor down
+ CUF) e="${esc_c}[${2}C" ;; # cursor right
+ CUB) e="${esc_c}[${2}D" ;; # cursor left
+
+ # text formatting
+ SGR)
+ case ${PF_COLOR:=1} in
+ (1)
+ e="${esc_c}[${2}m"
+ ;;
+
+ (0)
+ # colors disabled
+ e=
+ ;;
+ esac
+ ;;
+
+ # line wrap
+ DECAWM)
+ case $TERM in
+ (dumb | minix | cons25)
+ # not supported
+ e=
+ ;;
+
+ (*)
+ e="${esc_c}[?7${2}"
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# Print a sequence to the terminal.
+esc_p() {
+ esc "$@"
+ printf '%s' "$e"
+}
+
+# This is just a simple wrapper around 'command -v' to avoid
+# spamming '>/dev/null' throughout this function. This also guards
+# against aliases and functions.
+has() {
+ _cmd=$(command -v "$1") 2>/dev/null || return 1
+ [ -x "$_cmd" ] || return 1
+}
+
+log() {
+ # The 'log()' function handles the printing of information.
+ # In 'pfetch' (and 'neofetch'!) the printing of the ascii art and info
+ # happen independently of each other.
+ #
+ # The size of the ascii art is stored and the ascii is printed first.
+ # Once the ascii is printed, the cursor is located right below the art
+ # (See marker $[1]).
+ #
+ # Using the stored ascii size, the cursor is then moved to marker $[2].
+ # This is simply a cursor up escape sequence using the "height" of the
+ # ascii art.
+ #
+ # 'log()' then moves the cursor to the right the "width" of the ascii art
+ # with an additional amount of padding to add a gap between the art and
+ # the information (See marker $[3]).
+ #
+ # When 'log()' has executed, the cursor is then located at marker $[4].
+ # When 'log()' is run a second time, the next line of information is
+ # printed, moving the cursor to marker $[5].
+ #
+ # Markers $[4] and $[5] repeat all the way down through the ascii art
+ # until there is no more information left to print.
+ #
+ # Every time 'log()' is called the script keeps track of how many lines
+ # were printed. When printing is complete the cursor is then manually
+ # placed below the information and the art according to the "heights"
+ # of both.
+ #
+ # The math is simple: move cursor down $((ascii_height - info_height)).
+ # If the aim is to move the cursor from marker $[5] to marker $[6],
+ # plus the ascii height is 8 while the info height is 2 it'd be a move
+ # of 6 lines downwards.
+ #
+ # However, if the information printed is "taller" (takes up more lines)
+ # than the ascii art, the cursor isn't moved at all!
+ #
+ # Once the cursor is at marker $[6], the script exits. This is the gist
+ # of how this "dynamic" printing and layout works.
+ #
+ # This method allows ascii art to be stored without markers for info
+ # and it allows for easy swapping of info order and amount.
+ #
+ # $[2] ___ $[3] goldie@KISS
+ # $[4](.· | $[5] os KISS Linux
+ # (<> |
+ # / __ \
+ # ( / \ /|
+ # _/\ __)/_)
+ # \/-____\/
+ # $[1]
+ #
+ # $[6] /home/goldie $
+
+ # End here if no data was found.
+ [ "$2" ] || return
+
+ # Store the values of '$1' and '$3' as we reset the argument list below.
+ name=$1
+ use_seperator=$3
+
+ # Use 'set --' as a means of stripping all leading and trailing
+ # white-space from the info string. This also normalizes all
+ # white-space inside of the string.
+ #
+ # Disable the shellcheck warning for word-splitting
+ # as it's safe and intended ('set -f' disables globbing).
+ # shellcheck disable=2046,2086
+ {
+ set -f
+ set +f -- $2
+ info=$*
+ }
+
+ # Move the cursor to the right, the width of the ascii art with an
+ # additional gap for text spacing.
+ esc_p CUF "$ascii_width"
+
+ # Print the info name and color the text.
+ esc_p SGR "3${PF_COL1-4}";
+ esc_p SGR 1
+ printf '%s' "$name"
+ esc_p SGR 0
+
+ # Print the info name and info data separator, if applicable.
+ [ "$use_seperator" ] || printf %s "$PF_SEP"
+
+ # Move the cursor backward the length of the *current* info name and
+ # then move it forwards the length of the *longest* info name. This
+ # aligns each info data line.
+ esc_p CUB "${#name}"
+ esc_p CUF "${PF_ALIGN:-$info_length}"
+
+ # Print the info data, color it and strip all leading whitespace
+ # from the string.
+ esc_p SGR "3${PF_COL2-9}"
+ printf '%s' "$info"
+ esc_p SGR 0
+ printf '\n'
+
+ # Keep track of the number of times 'log()' has been run.
+ info_height=$((${info_height:-0} + 1))
+}
+
+get_title() {
+ # Username is retrieved by first checking '$USER' with a fallback
+ # to the 'id -un' command.
+ user=${USER:-$(id -un)}
+
+ # Hostname is retrieved by first checking '$HOSTNAME' with a fallback
+ # to the 'hostname' command.
+ #
+ # Disable the warning about '$HOSTNAME' being undefined in POSIX sh as
+ # the intention for using it is allowing the user to overwrite the
+ # value on invocation.
+ # shellcheck disable=3028,2039
+ hostname=${HOSTNAME:-${hostname:-$(hostname)}}
+
+ # If the hostname is still not found, fallback to the contents of the
+ # /etc/hostname file.
+ [ "$hostname" ] || read -r hostname < /etc/hostname
+
+ # Add escape sequences for coloring to user and host name. As we embed
+ # them directly in the arguments passed to log(), we cannot use esc_p().
+ esc SGR 1
+ user=$e$user
+ esc SGR "3${PF_COL3:-1}"
+ user=$e$user
+ esc SGR 1
+ user=$user$e
+ esc SGR 1
+ hostname=$e$hostname
+ esc SGR "3${PF_COL3:-1}"
+ hostname=$e$hostname
+
+ log "${user}@${hostname}" " " " " >&6
+}
+
+get_os() {
+ # This function is called twice, once to detect the distribution name
+ # for the purposes of picking an ascii art early and secondly to display
+ # the distribution name in the info output (if enabled).
+ #
+ # On first run, this function displays _nothing_, only on the second
+ # invocation is 'log()' called.
+ [ "$distro" ] && {
+ log os "$distro" >&6
+ return
+ }
+
+ case $os in
+ (Linux*)
+ # Some Linux distributions (which are based on others)
+ # fail to identify as they **do not** change the upstream
+ # distribution's identification packages or files.
+ #
+ # It is senseless to add a special case in the code for
+ # each and every distribution (which _is_ technically no
+ # different from what it is based on) as they're either too
+ # lazy to modify upstream's identification files or they
+ # don't have the know-how (or means) to ship their own
+ # lsb-release package.
+ #
+ # This causes users to think there's a bug in system detection
+ # tools like neofetch or pfetch when they technically *do*
+ # function correctly.
+ #
+ # Exceptions are made for distributions which are independent,
+ # not based on another distribution or follow different
+ # standards.
+ #
+ # This applies only to distributions which follow the standard
+ # by shipping unmodified identification files and packages
+ # from their respective upstreams.
+ if has lsb_release; then
+ distro=$(lsb_release -sd)
+
+ # Android detection works by checking for the existence of
+ # the follow two directories. I don't think there's a simpler
+ # method than this.
+ elif [ -d /system/app ] && [ -d /system/priv-app ]; then
+ distro="Android $(getprop ro.build.version.release)"
+
+ elif [ -f /etc/os-release ]; then
+ # This used to be a simple '. /etc/os-release' but I believe
+ # this is insecure as we blindly executed whatever was in the
+ # file. This parser instead simply handles 'key=val', treating
+ # the file contents as plain-text.
+ while IFS='=' read -r key val; do
+ case $key in
+ (NAME)
+ distro="$(echo $val | tr '[:upper:]' '[:lower:]')"
+ ;;
+ esac
+ done < /etc/os-release
+
+ else
+ # Special cases for (independent) distributions which
+ # don't follow any os-release/lsb standards whatsoever.
+ has crux && distro=$(crux)
+ has guix && distro='Guix System'
+ fi
+
+ # 'os-release' and 'lsb_release' sometimes add quotes
+ # around the distribution name, strip them.
+ distro=${distro##[\"\']}
+ distro=${distro%%[\"\']}
+
+ # Check to see if we're running Bedrock Linux which is
+ # very unique. This simply checks to see if the user's
+ # PATH contains a Bedrock specific value.
+ case $PATH in
+ (*/bedrock/cross/*)
+ distro='Bedrock Linux'
+ ;;
+ esac
+
+ # Check to see if Linux is running in Windows 10 under
+ # WSL1 (Windows subsystem for Linux [version 1]) and
+ # append a string accordingly.
+ #
+ # If the kernel version string ends in "-Microsoft",
+ # we're very likely running under Windows 10 in WSL1.
+ if [ "$WSLENV" ]; then
+ distro="${distro}${WSLENV+ on Windows 10 [WSL2]}"
+
+ # Check to see if Linux is running in Windows 10 under
+ # WSL2 (Windows subsystem for Linux [version 2]) and
+ # append a string accordingly.
+ #
+ # This checks to see if '$WSLENV' is defined. This
+ # appends the Windows 10 string even if '$WSLENV' is
+ # empty. We only need to check that is has been _exported_.
+ elif [ -z "${kernel%%*-Microsoft}" ]; then
+ distro="$distro on Windows 10 [WSL1]"
+ fi
+ ;;
+
+ (Darwin*)
+ # Parse the SystemVersion.plist file to grab the macOS
+ # version. The file is in the following format:
+ #
+ # <key>ProductVersion</key>
+ # <string>10.14.6</string>
+ #
+ # 'IFS' is set to '<>' to enable splitting between the
+ # keys and a second 'read' is used to operate on the
+ # next line directly after a match.
+ #
+ # '_' is used to nullify a field. '_ _ line _' basically
+ # says "populate $line with the third field's contents".
+ while IFS='<>' read -r _ _ line _; do
+ case $line in
+ # Match 'ProductVersion' and read the next line
+ # directly as it contains the key's value.
+ ProductVersion)
+ IFS='<>' read -r _ _ mac_version _
+ continue
+ ;;
+
+ ProductName)
+ IFS='<>' read -r _ _ mac_product _
+ continue
+ ;;
+ esac
+ done < /System/Library/CoreServices/SystemVersion.plist
+
+ # Use the ProductVersion to determine which macOS/OS X codename
+ # the system has. As far as I'm aware there's no "dynamic" way
+ # of grabbing this information.
+ case $mac_version in
+ (10.4*) distro='Mac OS X Tiger' ;;
+ (10.5*) distro='Mac OS X Leopard' ;;
+ (10.6*) distro='Mac OS X Snow Leopard' ;;
+ (10.7*) distro='Mac OS X Lion' ;;
+ (10.8*) distro='OS X Mountain Lion' ;;
+ (10.9*) distro='OS X Mavericks' ;;
+ (10.10*) distro='OS X Yosemite' ;;
+ (10.11*) distro='OS X El Capitan' ;;
+ (10.12*) distro='macOS Sierra' ;;
+ (10.13*) distro='macOS High Sierra' ;;
+ (10.14*) distro='macOS Mojave' ;;
+ (10.15*) distro='macOS Catalina' ;;
+ (11*) distro='macOS Big Sur' ;;
+ (12*) distro='macOS Monterey' ;;
+ (*) distro='macOS' ;;
+ esac
+
+ # Use the ProductName to determine if we're running in iOS.
+ case $mac_product in
+ (iP*) distro='iOS' ;;
+ esac
+
+ distro="$distro $mac_version"
+ ;;
+
+ (Haiku)
+ # Haiku uses 'uname -v' for version information
+ # instead of 'uname -r' which only prints '1'.
+ distro=$(uname -sv)
+ ;;
+
+ (Minix|DragonFly)
+ distro="$os $kernel"
+
+ # Minix and DragonFly don't support the escape
+ # sequences used, clear the exit trap.
+ trap '' EXIT
+ ;;
+
+ (SunOS)
+ # Grab the first line of the '/etc/release' file
+ # discarding everything after '('.
+ IFS='(' read -r distro _ < /etc/release
+ ;;
+
+ (OpenBSD*)
+ # Show the OpenBSD version type (current if present).
+ # kern.version=OpenBSD 6.6-current (GENERIC.MP) ...
+ IFS=' =' read -r _ distro openbsd_ver _ <<-EOF
+ $(sysctl kern.version)
+ EOF
+
+ distro="$distro $openbsd_ver"
+ ;;
+
+ (FreeBSD)
+ distro="$(echo $os | tr '[:upper:]' '[:lower:]')"
+ ;;
+
+ (*)
+ # Catch all to ensure '$distro' is never blank.
+ # This also handles the BSDs.
+ distro="$os $kernel"
+ ;;
+ esac
+}
+
+get_kernel() {
+ case $os in
+ # Don't print kernel output on some systems as the
+ # OS name includes it.
+ (*BSD*|Haiku|Minix)
+ return
+ ;;
+ esac
+
+ # '$kernel' is the cached output of 'uname -r'.
+ log kernel "$kernel" >&6
+}
+
+get_host() {
+ case $os in
+ (Linux*)
+ # Despite what these files are called, version doesn't
+ # always contain the version nor does name always contain
+ # the name.
+ read -r name < /sys/devices/virtual/dmi/id/product_name
+ read -r version < /sys/devices/virtual/dmi/id/product_version
+ read -r model < /sys/firmware/devicetree/base/model
+
+ host="$name $version $model"
+ ;;
+
+ (Darwin* | FreeBSD* | DragonFly*)
+ host=$(sysctl -n hw.model)
+ ;;
+
+ (NetBSD*)
+ host=$(sysctl -n machdep.dmi.system-vendor \
+ machdep.dmi.system-product)
+ ;;
+
+ (OpenBSD*)
+ host=$(sysctl -n hw.version)
+ ;;
+
+ (*BSD* | Minix)
+ host=$(sysctl -n hw.vendor hw.product)
+ ;;
+ esac
+
+ # Turn the host string into an argument list so we can iterate
+ # over it and remove OEM strings and other information which
+ # shouldn't be displayed.
+ #
+ # Disable the shellcheck warning for word-splitting
+ # as it's safe and intended ('set -f' disables globbing).
+ # shellcheck disable=2046,2086
+ {
+ set -f
+ set +f -- $host
+ host=
+ }
+
+ # Iterate over the host string word by word as a means of stripping
+ # unwanted and OEM information from the string as a whole.
+ #
+ # This could have been implemented using a long 'sed' command with
+ # a list of word replacements, however I want to show that something
+ # like this is possible in pure sh.
+ #
+ # This string reconstruction is needed as some OEMs either leave the
+ # identification information as "To be filled by OEM", "Default",
+ # "undefined" etc and we shouldn't print this to the screen.
+ for word do
+ # This works by reconstructing the string by excluding words
+ # found in the "blacklist" below. Only non-matches are appended
+ # to the final host string.
+ case $word in
+ (To | [Bb]e | [Ff]illed | [Bb]y | O.E.M. | OEM |\
+ Not | Applicable | Specified | System | Product | Name |\
+ Version | Undefined | Default | string | INVALID | � | os |\
+ Type1ProductConfigId )
+ continue
+ ;;
+ esac
+
+ host="$host$word "
+ done
+
+ # '$arch' is the cached output from 'uname -m'.
+ log host "${host:-$arch}" >&6
+}
+
+get_uptime() {
+ # Uptime works by retrieving the data in total seconds and then
+ # converting that data into days, hours and minutes using simple
+ # math.
+ case $os in
+ (Linux* | Minix* | SerenityOS*)
+ IFS=. read -r s _ < /proc/uptime
+ ;;
+
+ (Darwin* | *BSD* | DragonFly*)
+ s=$(sysctl -n kern.boottime)
+
+ # Extract the uptime in seconds from the following output:
+ # [...] { sec = 1271934886, usec = 667779 } Thu Apr 22 12:14:46 2010
+ s=${s#*=}
+ s=${s%,*}
+
+ # The uptime format from 'sysctl' needs to be subtracted from
+ # the current time in seconds.
+ s=$(($(date +%s) - s))
+ ;;
+
+ (Haiku)
+ # The boot time is returned in microseconds, convert it to
+ # regular seconds.
+ s=$(($(system_time) / 1000000))
+ ;;
+
+ (SunOS)
+ # Split the output of 'kstat' on '.' and any white-space
+ # which exists in the command output.
+ #
+ # The output is as follows:
+ # unix:0:system_misc:snaptime 14809.906993005
+ #
+ # The parser extracts: ^^^^^
+ IFS=' .' read -r _ s _ <<-EOF
+ $(kstat -p unix:0:system_misc:snaptime)
+ EOF
+ ;;
+
+ (IRIX)
+ # Grab the uptime in a pretty format. Usually,
+ # 00:00:00 from the 'ps' command.
+ t=$(LC_ALL=POSIX ps -o etime= -p 1)
+
+ # Split the pretty output into days or hours
+ # based on the uptime.
+ case $t in
+ (*-*) d=${t%%-*} t=${t#*-} ;;
+ (*:*:*) h=${t%%:*} t=${t#*:} ;;
+ esac
+
+ h=${h#0} t=${t#0}
+
+ # Convert the split pretty fields back into
+ # seconds so we may re-convert them to our format.
+ s=$((${d:-0}*86400 + ${h:-0}*3600 + ${t%%:*}*60 + ${t#*:}))
+ ;;
+ esac
+
+ # Convert the uptime from seconds into days, hours and minutes.
+ d=$((s / 60 / 60 / 24))
+ h=$((s / 60 / 60 % 24))
+ m=$((s / 60 % 60))
+
+ # Only append days, hours and minutes if they're non-zero.
+ case "$d" in ([!0]*) uptime="${uptime}${d}d "; esac
+ case "$h" in ([!0]*) uptime="${uptime}${h}h "; esac
+ case "$m" in ([!0]*) uptime="${uptime}${m}m "; esac
+
+ log uptime "${uptime:-0m}" >&6
+}
+
+get_pkgs() {
+ # This works by first checking for which package managers are
+ # installed and finally by printing each package manager's
+ # package list with each package one per line.
+ #
+ # The output from this is then piped to 'wc -l' to count each
+ # line, giving us the total package count of whatever package
+ # managers are installed.
+ packages=$(
+ case $os in
+ (Linux*)
+ # Commands which print packages one per line.
+ has bonsai && bonsai list
+ has crux && pkginfo -i
+ has pacman-key && pacman -Qq
+ has dpkg && dpkg-query -f '.\n' -W
+ has rpm && rpm -qa
+ has xbps-query && xbps-query -l
+ has apk && apk info
+ has guix && guix package --list-installed
+ has opkg && opkg list-installed
+
+ # Directories containing packages.
+ has kiss && printf '%s\n' /var/db/kiss/installed/*/
+ has cpt-list && printf '%s\n' /var/db/cpt/installed/*/
+ has brew && printf '%s\n' "$(brew --cellar)/"*
+ has emerge && printf '%s\n' /var/db/pkg/*/*/
+ has pkgtool && printf '%s\n' /var/log/packages/*
+ has eopkg && printf '%s\n' /var/lib/eopkg/package/*
+
+ # 'nix' requires two commands.
+ has nix-store && {
+ nix-store -q --requisites /run/current-system/sw
+ nix-store -q --requisites ~/.nix-profile
+ }
+ ;;
+
+ (Darwin*)
+ # Commands which print packages one per line.
+ has pkgin && pkgin list
+ has dpkg && dpkg-query -f '.\n' -W
+
+ # Directories containing packages.
+ has brew && printf '%s\n' /usr/local/Cellar/*
+
+ # 'port' prints a single line of output to 'stdout'
+ # when no packages are installed and exits with
+ # success causing a false-positive of 1 package
+ # installed.
+ #
+ # 'port' should really exit with a non-zero code
+ # in this case to allow scripts to cleanly handle
+ # this behavior.
+ has port && {
+ pkg_list=$(port installed)
+
+ case "$pkg_list" in
+ ("No ports are installed.")
+ # do nothing
+ ;;
+
+ (*)
+ printf '%s\n' "$pkg_list"
+ ;;
+ esac
+ }
+ ;;
+
+ (FreeBSD*|DragonFly*)
+ pkg info
+ ;;
+
+ (OpenBSD*)
+ printf '%s\n' /var/db/pkg/*/
+ ;;
+
+ (NetBSD*)
+ pkg_info
+ ;;
+
+ (Haiku)
+ printf '%s\n' /boot/system/package-links/*
+ ;;
+
+ (Minix)
+ printf '%s\n' /usr/pkg/var/db/pkg/*/
+ ;;
+
+ (SunOS)
+ has pkginfo && pkginfo -i
+ has pkg && pkg list
+ ;;
+
+ (IRIX)
+ versions -b
+ ;;
+
+ (SerenityOS)
+ while IFS=" " read -r type _; do
+ [ "$type" != dependency ] &&
+ printf "\n"
+ done < /usr/Ports/packages.db
+ ;;
+ esac | wc -l
+ )
+
+ # 'wc -l' can have leading and/or trailing whitespace
+ # depending on the implementation, so strip them.
+ # Procedure explained at https://github.com/dylanaraps/pure-sh-bible
+ # (trim-leading-and-trailing-white-space-from-string)
+ packages=${packages#"${packages%%[![:space:]]*}"}
+ packages=${packages%"${packages##*[![:space:]]}"}
+
+ case $os in
+ # IRIX's package manager adds 3 lines of extra
+ # output which we must account for here.
+ (IRIX)
+ packages=$((packages - 3))
+ ;;
+
+ # OpenBSD's wc prints whitespace before the output
+ # which needs to be stripped.
+ (OpenBSD)
+ packages=$((packages))
+ ;;
+ esac
+
+ case $packages in
+ (1?*|[2-9]*)
+ log pkgs "$packages" >&6
+ ;;
+ esac
+}
+
+get_memory() {
+ case $os in
+ # Used memory is calculated using the following "formula":
+ # MemUsed = MemTotal + Shmem - MemFree - Buffers - Cached - SReclaimable
+ # Source: https://github.com/KittyKatt/screenFetch/issues/386
+ (Linux*)
+ # Parse the '/proc/meminfo' file splitting on ':' and 'k'.
+ # The format of the file is 'key: 000kB' and an additional
+ # split is used on 'k' to filter out 'kB'.
+ while IFS=':k ' read -r key val _; do
+ case $key in
+ (MemTotal)
+ mem_used=$((mem_used + val))
+ mem_full=$val
+ ;;
+
+ (Shmem)
+ mem_used=$((mem_used + val))
+ ;;
+
+ (MemFree | Buffers | Cached | SReclaimable)
+ mem_used=$((mem_used - val))
+ ;;
+
+ # If detected this will be used over the above calculation
+ # for mem_used. Available since Linux 3.14rc.
+ # See kernel commit 34e431b0ae398fc54ea69ff85ec700722c9da773
+ (MemAvailable)
+ mem_avail=$val
+ ;;
+ esac
+ done < /proc/meminfo
+
+ case $mem_avail in
+ (*[0-9]*)
+ mem_used=$(((mem_full - mem_avail) / 1024))
+ ;;
+
+ *)
+ mem_used=$((mem_used / 1024))
+ ;;
+ esac
+
+ mem_full=$((mem_full / 1024))
+ ;;
+
+ # Used memory is calculated using the following "formula":
+ # (wired + active + occupied) * 4 / 1024
+ (Darwin*)
+ mem_full=$(($(sysctl -n hw.memsize) / 1024 / 1024))
+
+ # Parse the 'vmstat' file splitting on ':' and '.'.
+ # The format of the file is 'key: 000.' and an additional
+ # split is used on '.' to filter it out.
+ while IFS=:. read -r key val; do
+ case $key in
+ (*' wired'*|*' active'*|*' occupied'*)
+ mem_used=$((mem_used + ${val:-0}))
+ ;;
+ esac
+
+ # Using '<<-EOF' is the only way to loop over a command's
+ # output without the use of a pipe ('|').
+ # This ensures that any variables defined in the while loop
+ # are still accessible in the script.
+ done <<-EOF
+ $(vm_stat)
+ EOF
+
+ mem_used=$((mem_used * 4 / 1024))
+ ;;
+
+ (OpenBSD*)
+ mem_full=$(($(sysctl -n hw.physmem) / 1024 / 1024))
+
+ # This is a really simpler parser for 'vmstat' which grabs
+ # the used memory amount in a lazy way. 'vmstat' prints 3
+ # lines of output with the needed value being stored in the
+ # final line.
+ #
+ # This loop simply grabs the 3rd element of each line until
+ # the EOF is reached. Each line overwrites the value of the
+ # previous one so we're left with what we wanted. This isn't
+ # slow as only 3 lines are parsed.
+ while read -r _ _ line _; do
+ mem_used=${line%%M}
+
+ # Using '<<-EOF' is the only way to loop over a command's
+ # output without the use of a pipe ('|').
+ # This ensures that any variables defined in the while loop
+ # are still accessible in the script.
+ done <<-EOF
+ $(vmstat)
+ EOF
+ ;;
+
+ # Used memory is calculated using the following "formula":
+ # mem_full - ((inactive + free + cache) * page_size / 1024)
+ (FreeBSD*|DragonFly*)
+ mem_full=$(($(sysctl -n hw.physmem) / 1024 / 1024))
+
+ # Use 'set --' to store the output of the command in the
+ # argument list. POSIX sh has no arrays but this is close enough.
+ #
+ # Disable the shellcheck warning for word-splitting
+ # as it's safe and intended ('set -f' disables globbing).
+ # shellcheck disable=2046
+ {
+ set -f
+ set +f -- $(sysctl -n hw.pagesize \
+ vm.stats.vm.v_inactive_count \
+ vm.stats.vm.v_free_count \
+ vm.stats.vm.v_cache_count)
+ }
+
+ # Calculate the amount of used memory.
+ # $1: hw.pagesize
+ # $2: vm.stats.vm.v_inactive_count
+ # $3: vm.stats.vm.v_free_count
+ # $4: vm.stats.vm.v_cache_count
+ mem_used=$((mem_full - (($2 + $3 + $4) * $1 / 1024 / 1024)))
+ ;;
+
+ (NetBSD*)
+ mem_full=$(($(sysctl -n hw.physmem64) / 1024 / 1024))
+
+ # NetBSD implements a lot of the Linux '/proc' filesystem,
+ # this uses the same parser as the Linux memory detection.
+ while IFS=':k ' read -r key val _; do
+ case $key in
+ (MemFree)
+ mem_free=$((val / 1024))
+ break
+ ;;
+ esac
+ done < /proc/meminfo
+
+ mem_used=$((mem_full - mem_free))
+ ;;
+
+ (Haiku)
+ # Read the first line of 'sysinfo -mem' splitting on
+ # '(', ' ', and ')'. The needed information is then
+ # stored in the 5th and 7th elements. Using '_' "consumes"
+ # an element allowing us to proceed to the next one.
+ #
+ # The parsed format is as follows:
+ # 3501142016 bytes free (used/max 792645632 / 4293787648)
+ IFS='( )' read -r _ _ _ _ mem_used _ mem_full <<-EOF
+ $(sysinfo -mem)
+ EOF
+
+ mem_used=$((mem_used / 1024 / 1024))
+ mem_full=$((mem_full / 1024 / 1024))
+ ;;
+
+ (Minix)
+ # Minix includes the '/proc' filesystem though the format
+ # differs from Linux. The '/proc/meminfo' file is only a
+ # single line with space separated elements and elements
+ # 2 and 3 contain the total and free memory numbers.
+ read -r _ mem_full mem_free _ < /proc/meminfo
+
+ mem_used=$(((mem_full - mem_free) / 1024))
+ mem_full=$(( mem_full / 1024))
+ ;;
+
+ (SunOS)
+ hw_pagesize=$(pagesize)
+
+ # 'kstat' outputs memory in the following format:
+ # unix:0:system_pages:pagestotal 1046397
+ # unix:0:system_pages:pagesfree 885018
+ #
+ # This simply uses the first "element" (white-space
+ # separated) as the key and the second element as the
+ # value.
+ #
+ # A variable is then assigned based on the key.
+ while read -r key val; do
+ case $key in
+ (*total)
+ pages_full=$val
+ ;;
+
+ (*free)
+ pages_free=$val
+ ;;
+ esac
+ done <<-EOF
+ $(kstat -p unix:0:system_pages:pagestotal \
+ unix:0:system_pages:pagesfree)
+ EOF
+
+ mem_full=$((pages_full * hw_pagesize / 1024 / 1024))
+ mem_free=$((pages_free * hw_pagesize / 1024 / 1024))
+ mem_used=$((mem_full - mem_free))
+ ;;
+
+ (IRIX)
+ # Read the memory information from the 'top' command. Parse
+ # and split each line until we reach the line starting with
+ # "Memory".
+ #
+ # Example output: Memory: 160M max, 147M avail, .....
+ while IFS=' :' read -r label mem_full _ mem_free _; do
+ case $label in
+ (Memory)
+ mem_full=${mem_full%M}
+ mem_free=${mem_free%M}
+ break
+ ;;
+ esac
+ done <<-EOF
+ $(top -n)
+ EOF
+
+ mem_used=$((mem_full - mem_free))
+ ;;
+
+ (SerenityOS)
+ IFS='{}' read -r _ memstat _ < /proc/memstat
+
+ set -f -- "$IFS"
+ IFS=,
+
+ for pair in $memstat; do
+ case $pair in
+ (*user_physical_allocated*)
+ mem_used=${pair##*:}
+ ;;
+
+ (*user_physical_available*)
+ mem_free=${pair##*:}
+ ;;
+ esac
+ done
+
+ IFS=$1
+ set +f --
+
+ mem_used=$((mem_used * 4096 / 1024 / 1024))
+ mem_free=$((mem_free * 4096 / 1024 / 1024))
+
+ mem_full=$((mem_used + mem_free))
+ ;;
+ esac
+
+ log memory "${mem_used:-?}M / ${mem_full:-?}M" >&6
+}
+
+get_wm() {
+ case $os in
+ (Darwin*)
+ # Don't display window manager on macOS.
+ ;;
+
+ (*)
+ # xprop can be used to grab the window manager's properties
+ # which contains the window manager's name under '_NET_WM_NAME'.
+ #
+ # The upside to using 'xprop' is that you don't need to hardcode
+ # a list of known window manager names. The downside is that
+ # not all window managers conform to setting the '_NET_WM_NAME'
+ # atom..
+ #
+ # List of window managers which fail to set the name atom:
+ # catwm, fvwm, dwm, 2bwm, monster, wmaker and sowm [mine! ;)].
+ #
+ # The final downside to this approach is that it does _not_
+ # support Wayland environments. The only solution which supports
+ # Wayland is the 'ps' parsing mentioned below.
+ #
+ # A more naive implementation is to parse the last line of
+ # '~/.xinitrc' to extract the second white-space separated
+ # element.
+ #
+ # The issue with an approach like this is that this line data
+ # does not always equate to the name of the window manager and
+ # could in theory be _anything_.
+ #
+ # This also fails when the user launches xorg through a display
+ # manager or other means.
+ #
+ #
+ # Another naive solution is to parse 'ps' with a hardcoded list
+ # of window managers to detect the current window manager (based
+ # on what is running).
+ #
+ # The issue with this approach is the need to hardcode and
+ # maintain a list of known window managers.
+ #
+ # Another issue is that process names do not always equate to
+ # the name of the window manager. False-positives can happen too.
+ #
+ # This is the only solution which supports Wayland based
+ # environments sadly. It'd be nice if some kind of standard were
+ # established to identify Wayland environments.
+ #
+ # pfetch's goal is to remain _simple_, if you'd like a "full"
+ # implementation of window manager detection use 'neofetch'.
+ #
+ # Neofetch use a combination of 'xprop' and 'ps' parsing to
+ # support all window managers (including non-conforming and
+ # Wayland) though it's a lot more complicated!
+
+ # Don't display window manager if X isn't running.
+ [ "$DISPLAY" ] || return
+
+ # This is a two pass call to xprop. One call to get the window
+ # manager's ID and another to print its properties.
+ has xprop && {
+ # The output of the ID command is as follows:
+ # _NET_SUPPORTING_WM_CHECK: window id # 0x400000
+ #
+ # To extract the ID, everything before the last space
+ # is removed.
+ id=$(xprop -root -notype _NET_SUPPORTING_WM_CHECK)
+ id=${id##* }
+
+ # The output of the property command is as follows:
+ # _NAME 8t
+ # _NET_WM_PID = 252
+ # _NET_WM_NAME = "bspwm"
+ # _NET_SUPPORTING_WM_CHECK: window id # 0x400000
+ # WM_CLASS = "wm", "Bspwm"
+ #
+ # To extract the name, everything before '_NET_WM_NAME = \"'
+ # is removed and everything after the next '"' is removed.
+ wm=$(xprop -id "$id" -notype -len 7 -f _NET_WM_NAME 8t)
+ }
+
+ # Handle cases of a window manager _not_ populating the
+ # '_NET_WM_NAME' atom. Display nothing in this case.
+ case $wm in
+ (*'_NET_WM_NAME = '*)
+ wm=${wm##*_NET_WM_NAME = \"}
+ wm=${wm%%\"*}
+ ;;
+
+ (*)
+ # Fallback to checking the process list
+ # for the select few window managers which
+ # don't set '_NET_WM_NAME'.
+ while read -r ps_line; do
+ case $ps_line in
+ (*catwm*) wm=catwm ;;
+ (*fvwm*) wm=fvwm ;;
+ (*dwm*) wm=dwm ;;
+ (*2bwm*) wm=2bwm ;;
+ (*monsterwm*) wm=monsterwm ;;
+ (*wmaker*) wm='Window Maker' ;;
+ (*sowm*) wm=sowm ;;
+ (*penrose*) wm=penrose ;;
+ esac
+ done <<-EOF
+ $(ps x)
+ EOF
+ ;;
+ esac
+ ;;
+ esac
+
+ log wm "cwm" >&6
+}
+
+
+get_de() {
+ # This only supports Xorg related desktop environments though
+ # this is fine as knowing the desktop environment on Windows,
+ # macOS etc is useless (they'll always report the same value).
+ #
+ # Display the value of '$XDG_CURRENT_DESKTOP', if it's empty,
+ # display the value of '$DESKTOP_SESSION'.
+ log de "${XDG_CURRENT_DESKTOP:-$DESKTOP_SESSION}" >&6
+}
+
+get_shell() {
+ # Display the basename of the '$SHELL' environment variable.
+ log sh "${SHELL##*/}" >&6
+}
+
+get_editor() {
+ # Display the value of '$VISUAL', if it's empty, display the
+ # value of '$EDITOR'.
+ editor=${VISUAL:-"$EDITOR"}
+
+ log ed "${editor##*/}" >&6
+}
+
+get_palette() {
+ # Print the first 8 terminal colors. This uses the existing
+ # sequences to change text color with a sequence prepended
+ # to reverse the foreground and background colors.
+ #
+ # This allows us to save hardcoding a second set of sequences
+ # for background colors.
+ #
+ # False positive.
+ # shellcheck disable=2154
+ {
+ esc SGR 7
+ palette="$e$c1 $c1 $c2 $c2 $c3 $c3 $c4 $c4 $c5 $c5 $c6 $c6 "
+ esc SGR 0
+ palette="$palette$e"
+ }
+
+ # Print the palette with a new-line before and afterwards but no seperator.
+ printf '\n' >&6
+ log "$palette
+ " " " " " >&6
+}
+
+get_ascii() {
+ # This is a simple function to read the contents of
+ # an ascii file from 'stdin'. It allows for the use
+ # of '<<-EOF' to prevent the break in indentation in
+ # this source code.
+ #
+ # This function also sets the text colors according
+ # to the ascii color.
+ read_ascii() {
+ # 'PF_COL1': Set the info name color according to ascii color.
+ # 'PF_COL3': Set the title color to some other color. ¯\_(ツ)_/¯
+ PF_COL1=${PF_COL1:-${1:-7}}
+ PF_COL3=${PF_COL3:-$((${1:-7}%8+1))}
+
+ # POSIX sh has no 'var+=' so 'var=${var}append' is used. What's
+ # interesting is that 'var+=' _is_ supported inside '$(())'
+ # (arithmetic) though there's no support for 'var++/var--'.
+ #
+ # There is also no $'\n' to add a "literal"(?) newline to the
+ # string. The simplest workaround being to break the line inside
+ # the string (though this has the caveat of breaking indentation).
+ while IFS= read -r line; do
+ ascii="$ascii$line
+"
+ done
+ }
+
+ # This checks for ascii art in the following order:
+ # '$1': Argument given to 'get_ascii()' directly.
+ # '$PF_ASCII': Environment variable set by user.
+ # '$distro': The detected distribution name.
+ # '$os': The name of the operating system/kernel.
+ #
+ # NOTE: Each ascii art below is indented using tabs, this
+ # allows indentation to continue naturally despite
+ # the use of '<<-EOF'.
+ #
+ # False positive.
+ # shellcheck disable=2154
+ case ${1:-${PF_ASCII:-${distro:-$os}}} in
+ ([Aa]lpine*)
+ read_ascii 4 <<-EOF
+ ${c4} /\\ /\\
+ /${c7}/ ${c4}\\ \\
+ /${c7}/ ${c4}\\ \\
+ /${c7}// ${c4}\\ \\
+ ${c7}// ${c4}\\ \\
+ ${c4}\\
+ EOF
+ ;;
+
+ ([Aa]ndroid*)
+ read_ascii 2 <<-EOF
+ ${c2} ;, ,;
+ ${c2} ';,.-----.,;'
+ ${c2} ,' ',
+ ${c2} / O O \\
+ ${c2}| |
+ ${c2}'-----------------'
+ EOF
+ ;;
+
+ ([Aa]rch*)
+ read_ascii 4 <<-EOF
+ ${c6} /\\
+ ${c6} / \\
+ ${c6} /\\ \\
+ ${c4} / \\
+ ${c4} / ,, \\
+ ${c4} / | | -\\
+ ${c4} /_-'' ''-_\\
+ EOF
+ ;;
+
+ ([Aa]rco*)
+ read_ascii 4 <<-EOF
+ ${c4} /\\
+ ${c4} / \\
+ ${c4} / /\\ \\
+ ${c4} / / \\ \\
+ ${c4} / / \\ \\
+ ${c4} / / _____\\ \\
+ ${c4}/_/ \`----.\\_\\
+ EOF
+ ;;
+
+ ([Aa]rtix*)
+ read_ascii 6 <<-EOF
+ ${c4} /\\
+ ${c4} / \\
+ ${c4} /\`'.,\\
+ ${c4} / ',
+ ${c4} / ,\`\\
+ ${c4} / ,.'\`. \\
+ ${c4}/.,'\` \`'.\\
+ EOF
+ ;;
+
+ ([Bb]edrock*)
+ read_ascii 4 <<-EOF
+ ${c7}__
+ ${c7}\\ \\___
+ ${c7} \\ _ \\
+ ${c7} \\___/
+ EOF
+ ;;
+
+ ([Bb]uildroot*)
+ read_ascii 3 <<-EOF
+ ${c3} ___
+ ${c3} / \` \\
+ ${c3}| : :|
+ ${c3}-. _:__.-
+ ${c3} \` ---- \`
+ EOF
+ ;;
+
+ ([Cc]el[Oo][Ss]*)
+ read_ascii 5 0 <<-EOF
+ ${c5} .////\\\\\//\\.
+ ${c5} //_ \\\\
+ ${c5} /_ ${c7}##############
+ ${c5} // *\\
+ ${c7}############### ${c5}|#
+ ${c5} \/ */
+ ${c5} \* ${c7}##############
+ ${c5} */, .//
+ ${c5} '_///\\\\\//_'
+ EOF
+ ;;
+
+ ([Cc]ent[Oo][Ss]*)
+ read_ascii 5 <<-EOF
+ ${c2} ____${c3}^${c5}____
+ ${c2} |\\ ${c3}|${c5} /|
+ ${c2} | \\ ${c3}|${c5} / |
+ ${c5}<---- ${c4}---->
+ ${c4} | / ${c2}|${c3} \\ |
+ ${c4} |/__${c2}|${c3}__\\|
+ ${c2} v
+ EOF
+ ;;
+
+ ([Cc]rystal*[Ll]inux)
+ read_ascii 5 5 <<-EOF
+ ${c5} -//.
+ ${c5} -//.
+ ${c5} -//. .
+ ${c5} -//. '//-
+ ${c5} /+: :+/
+ ${c5} .//' .//.
+ ${c5} . .//.
+ ${c5} .//.
+ ${c5} .//.
+ EOF
+ ;;
+
+ ([Dd]ahlia*)
+ read_ascii 1 <<-EOF
+ ${c1} _
+ ${c1} ___/ \\___
+ ${c1} | _-_ |
+ ${c1} | / \ |
+ ${c1}/ | | \\
+ ${c1}\\ | | /
+ ${c1} | \ _ _ / |
+ ${c1} |___ - ___|
+ ${c1} \\_/
+ EOF
+ ;;
+
+ ([Dd]ebian*)
+ read_ascii 1 <<-EOF
+ ${c1} _____
+ ${c1} / __ \\
+ ${c1}| / |
+ ${c1}| \\___-
+ ${c1}-_
+ ${c1} --_
+ EOF
+ ;;
+
+ ([Dd]evuan*)
+ read_ascii 6 <<-EOF
+ ${c4} ..:::.
+ ${c4} ..-==-
+ ${c4} .+#:
+ ${c4} =@@
+ ${c4} :+%@#:
+ ${c4}.:=+#@@%*:
+ ${c4}#@@@#=:
+ EOF
+ ;;
+
+ ([Dd]ragon[Ff]ly*)
+ read_ascii 1 <<-EOF
+ ,${c1}_${c7},
+ ('-_${c1}|${c7}_-')
+ >--${c1}|${c7}--<
+ (_-'${c1}|${c7}'-_)
+ ${c1}|
+ ${c1}|
+ ${c1}|
+ EOF
+ ;;
+
+ ([Ee]lementary*)
+ read_ascii <<-EOF
+ ${c7} _______
+ ${c7} / ____ \\
+ ${c7}/ | / /\\
+ ${c7}|__\\ / / |
+ ${c7}\\ /__/ /
+ ${c7}\\_______/
+ EOF
+ ;;
+
+ ([Ee]ndeavour*)
+ read_ascii 4 <<-EOF
+ ${c1}/${c4}\\
+ ${c1}/${c4}/ \\${c6}\\
+ ${c1}/${c4}/ \\ ${c6}\\
+ ${c1}/ ${c4}/ _) ${c6})
+ ${c1}/_${c4}/___-- ${c6}__-
+ ${c6}/____--
+ EOF
+ ;;
+
+ ([Ff]edora*)
+ read_ascii 4 <<-EOF
+ ${c4},'''''.
+ ${c4}| ,. |
+ ${c4}| | '_'
+ ${c4} ,....| |..
+ ${c4}.' ,_;| ..'
+ ${c4}| | | |
+ ${c4}| ',_,' |
+ ${c4} '. ,'
+ ${c4}'''''
+ EOF
+ ;;
+
+ ([Ff]ree[Bb][Ss][Dd]*)
+ read_ascii 1 <<-EOF
+ ${c1}/\\,-'''''-,/\\
+ ${c1}\\_) (_/
+ ${c1}| |
+ ${c1}| |
+ ${c1}; ;
+ ${c1}'-_____-'
+ EOF
+ ;;
+
+ ([Gg]aruda*)
+ read_ascii 4 <<-EOF
+ ${c3} _______
+ ${c3} __/ \\_
+ ${c3} _/ / \\_
+ ${c7} _/ /_________\\
+ ${c7}_/ |
+ ${c2}\\ ____________
+ ${c2} \\_ __/
+ ${c2} \\__________/
+ EOF
+ ;;
+
+ ([Gg]entoo*)
+ read_ascii 5 <<-EOF
+ ${c5} _-----_
+ ${c5}( \\
+ ${c5}\\ 0 \\
+ ${c7} \\ )
+ ${c7} / _/
+ ${c7}( _-
+ ${c7}\\____-
+ EOF
+ ;;
+
+ ([Gg][Nn][Uu]*)
+ read_ascii 3 <<-EOF
+ ${c2} _-\`\`-, ,-\`\`-_
+ ${c2} .' _-_| |_-_ '.
+ ${c2}./ /_._ _._\\ \\.
+ ${c2}: _/_._\`:'_._\\_ :
+ ${c2}\\:._/ ,\` \\ \\ \\_.:/
+ ${c2} ,-';'.@) \\ @) \\
+ ${c2} ,'/' ..- .\\,-.|
+ ${c2} /'/' \\(( \\\` ./ )
+ ${c2} '/'' \\_,----'
+ ${c2} '/'' ,;/''
+ ${c2} \`\`;'
+ EOF
+ ;;
+
+ ([Gg]uix[Ss][Dd]*|[Gg]uix*)
+ read_ascii 3 <<-EOF
+ ${c3}|.__ __.|
+ ${c3}|__ \\ / __|
+ ${c3}\\ \\ / /
+ ${c3}\\ \\ / /
+ ${c3}\\ \\ / /
+ ${c3}\\ \\/ /
+ ${c3}\\__/
+ EOF
+ ;;
+
+ ([Hh]aiku*)
+ read_ascii 3 <<-EOF
+ ${c3} ,^,
+ ${c3} / \\
+ ${c3}*--_ ; ; _--*
+ ${c3}\\ '" "' /
+ ${c3}'. .'
+ ${c3}.-'" "'-.
+ ${c3}'-.__. .__.-'
+ ${c3}|_|
+ EOF
+ ;;
+
+ ([Hh]ydroOS*)
+ read_ascii 4 <<-EOF
+ ${c1}╔╗╔╗──╔╗───╔═╦══╗
+ ${c1}║╚╝╠╦╦╝╠╦╦═╣║║══╣
+ ${c1}║╔╗║║║╬║╔╣╬║║╠══║
+ ${c1}╚╝╚╬╗╠═╩╝╚═╩═╩══╝
+ ${c1}───╚═╝
+ EOF
+ ;;
+
+ ([Hh]yperbola*)
+ read_ascii <<-EOF
+ ${c7} |\`__.\`/
+ ${c7} \____/
+ ${c7} .--.
+ ${c7} / \\
+ ${c7} / ___ \\
+ ${c7}/ .\` \`.\\
+ ${c7}/.\` \`.\\
+ EOF
+ ;;
+
+ ([Ii]glunix*)
+ read_ascii <<-EOF
+ ${c0} |
+ ${c0} | |
+ ${c0} |
+ ${c0} | ________
+ ${c0} | /\\ | \\
+ ${c0} / \\ | \\ |
+ ${c0} / \\ \\ |
+ ${c0} / \\________\\
+ ${c0} \\ / /
+ ${c0} \\ / /
+ ${c0} \\ / /
+ ${c0} \\/________/
+ EOF
+ ;;
+
+ ([Ii]nstant[Oo][Ss]*)
+ read_ascii <<-EOF
+ ${c0} ,-''-,
+ ${c0}: .''. :
+ ${c0}: ',,' :
+ ${c0} '-____:__
+ ${c0} : \`.
+ ${c0} \`._.'
+ EOF
+ ;;
+
+ ([Ii][Rr][Ii][Xx]*)
+ read_ascii 1 <<-EOF
+ ${c1} __
+ ${c1} \\ \\ __
+ ${c1} \\ \\ / /
+ ${c1} \\ v /
+ ${c1} / . \\
+ ${c1} /_/ \\ \\
+ ${c1} \\_\\
+ EOF
+ ;;
+
+ ([Kk][Dd][Ee]*[Nn]eon*)
+ read_ascii 6 <<-EOF
+ ${c7} .${c6}__${c7}.${c6}__${c7}.
+ ${c6} / _${c7}.${c6}_ \\
+ ${c6} / / \\ \\
+ ${c7} . ${c6}| ${c7}O${c6} | ${c7}.
+ ${c6} \\ \\_${c7}.${c6}_/ /
+ ${c6} \\${c7}.${c6}__${c7}.${c6}__${c7}.${c6}/
+ EOF
+ ;;
+
+ ([Ll]inux*[Ll]ite*|[Ll]ite*)
+ read_ascii 3 <<-EOF
+ ${c3} /\\
+ ${c3} / \\
+ ${c3} / ${c7}/ ${c3}/
+ ${c3}> ${c7}/ ${c3}/
+ ${c3}\\ ${c7}\\ ${c3}\\
+ ${c3}\\_${c7}\\${c3}_\\
+ ${c7} \\
+ EOF
+ ;;
+
+ ([Ll]inux*[Mm]int*|[Mm]int)
+ read_ascii 2 <<-EOF
+ ${c2} ___________
+ ${c2}|_ \\
+ ${c2}| ${c7}| _____ ${c2}|
+ ${c2}| ${c7}| | | | ${c2}|
+ ${c2}| ${c7}| | | | ${c2}|
+ ${c2}| ${c7}\\__${c7}___/ ${c2}|
+ ${c2}\\_________/
+ EOF
+ ;;
+
+
+ ([Ll]inux*)
+ read_ascii 4 <<-EOF
+ ${c4} ___
+ ${c4}(${c7}.. ${c4}|
+ ${c4}(${c5}<> ${c4}|
+ ${c4}/ ${c7}__ ${c4}\\
+ ${c4}( ${c7}/ \\ ${c4}/|
+ ${c5}_${c4}/\\ ${c7}__)${c4}/${c5}_${c4})
+ ${c5}\/${c4}-____${c5}\/
+ EOF
+ ;;
+
+ ([Mm]ac[Oo][Ss]*|[Dd]arwin*)
+ read_ascii 1 <<-EOF
+ ${c2} .:'
+ ${c2} _ :'_
+ ${c3} .'\`_\`-'_\`\`.
+ ${c1}:________.-'
+ ${c1}:_______:
+ ${c4} :_______\`-;
+ ${c5} \`._.-._.'
+ EOF
+ ;;
+
+ ([Mm]ageia*)
+ read_ascii 2 <<-EOF
+ ${c6} *
+ ${c6} *
+ ${c6} **
+ ${c7} /\\__/\\
+ ${c7}/ \\
+ ${c7}\\ /
+ ${c7} \\____/
+ EOF
+ ;;
+
+ ([Mm]anjaro*)
+ read_ascii 2 <<-EOF
+ ${c2}||||||||| ||||
+ ${c2}||||||||| ||||
+ ${c2}|||| ||||
+ ${c2}|||| |||| ||||
+ ${c2}|||| |||| ||||
+ ${c2}|||| |||| ||||
+ ${c2}|||| |||| ||||
+ EOF
+ ;;
+
+ ([Mm]inix*)
+ read_ascii 4 <<-EOF
+ ${c4} ,, ,,
+ ${c4};${c7},${c4} ', ,' ${c7},${c4};
+ ${c4}; ${c7}',${c4} ',,' ${c7},'${c4} ;
+ ${c4}; ${c7}',${c4} ${c7},'${c4} ;
+ ${c4}; ${c7};, '' ,;${c4} ;
+ ${c4}; ${c7};${c4};${c7}',,'${c4};${c7};${c4} ;
+ ${c4}', ${c7};${c4};; ;;${c7};${c4} ,'
+ ${c4} '${c7};${c4}' '${c7};${c4}'
+ EOF
+ ;;
+
+ ([Mm][Xx]*)
+ read_ascii <<-EOF
+ ${c7} \\\\ /
+ ${c7} \\\\/
+ ${c7} \\\\
+ ${c7} /\\/ \\\\
+ ${c7} / \\ /\\
+ ${c7} / \\/ \\
+ ${c7}/__________\\
+ EOF
+ ;;
+
+ ([Nn]et[Bb][Ss][Dd]*)
+ read_ascii 3 <<-EOF
+ ${c7}\\${c3}\`-__,----__
+ ${c7} \\ ${c3}__\`_
+ ${c7} \\${c3}-__,----\`-
+ ${c7} \\
+ ${c7} \\
+ EOF
+ ;;
+
+ ([Nn]ix[Oo][Ss]*)
+ read_ascii 4 <<-EOF
+ ${c4} \\\\ \\\\ //
+ ${c4} ==\\\\__\\\\/ //
+ ${c4} // \\\\//
+ ${c4}==// //==
+ ${c4} //\\\\___//
+ ${c4}// /\\\\ \\\\==
+ ${c4} // \\\\ \\\\
+ EOF
+ ;;
+
+ ([Oo]pen[Bb][Ss][Dd]*)
+ read_ascii 3 <<-EOF
+ ${c3} _____
+ ${c3} \\- -/
+ ${c3} \\_/ \\
+ ${c3} | ${c7}O O${c3} |
+ ${c3} |_ < ) 3 )
+ ${c3} / \\ /
+ ${c3} /-_____-\\
+ EOF
+ ;;
+
+ ([Oo]pen[Ss][Uu][Ss][Ee]*[Tt]umbleweed*)
+ read_ascii 2 <<-EOF
+ ${c2} _____ ______
+ ${c2} / ____\\ / ____ \\
+ ${c2}/ / \`/ / \\ \\
+ ${c2}\\ \\____/ /,____/ /
+ ${c2} \\______/ \\_____/
+ EOF
+ ;;
+
+ ([Oo]pen[Ss][Uu][Ss][Ee]*|[Oo]pen*SUSE*|SUSE*|suse*)
+ read_ascii 2 <<-EOF
+ ${c2} _______
+ ${c2}__| __ \\
+ ${c2} / .\\ \\
+ ${c2} \\__/ |
+ ${c2} _______|
+ ${c2} \\_______
+ ${c2}__________/
+ EOF
+ ;;
+
+ ([Oo]pen[Ww]rt*)
+ read_ascii 1 <<-EOF
+ ${c1} _______
+ ${c1}| |.-----.-----.-----.
+ ${c1}| - || _ | -__| |
+ ${c1}|_______|| __|_____|__|__|
+ ${c1} ________|__| __
+ ${c1}| | | |.----.| |_
+ ${c1}| | | || _|| _|
+ ${c1}|________||__| |____|
+ EOF
+ ;;
+
+ ([Pp]arabola*)
+ read_ascii 5 <<-EOF
+ ${c5} __ __ __ _
+ ${c5}.\`_//_//_/ / \`.
+ ${c5} / .\`
+ ${c5} / .\`
+ ${c5} /.\`
+ ${c5} /\`
+ EOF
+ ;;
+
+ ([Pp]op!_[Oo][Ss]*)
+ read_ascii 6 <<-EOF
+ ${c6}______
+ ${c6}\\ _ \\ __
+ ${c6}\\ \\ \\ \\ / /
+ ${c6}\\ \\_\\ \\ / /
+ ${c6}\\ ___\\ /_/
+ ${c6} \\ \\ _
+ ${c6} __\\_\\__(_)_
+ ${c6}(___________)
+ EOF
+ ;;
+
+ ([Pp]ure[Oo][Ss]*)
+ read_ascii <<-EOF
+ ${c7} _____________
+ ${c7}| _________ |
+ ${c7}| | | |
+ ${c7}| | | |
+ ${c7}| |_________| |
+ ${c7}|_____________|
+ EOF
+ ;;
+
+ ([Rr]aspbian*)
+ read_ascii 1 <<-EOF
+ ${c2} __ __
+ ${c2} (_\\)(/_)
+ ${c1} (_(__)_)
+ ${c1}(_(_)(_)_)
+ ${c1} (_(__)_)
+ ${c1} (__)
+ EOF
+ ;;
+
+ ([Ss]erenity[Oo][Ss]*)
+ read_ascii 4 <<-EOF
+ ${c7} _____
+ ${c1} ,-${c7} -,
+ ${c1} ;${c7} ( ;
+ ${c1}| ${c7}. \_${c1}.,${c7} |
+ ${c1}| ${c7}o _${c1} ',${c7} |
+ ${c1} ; ${c7}(_)${c1} )${c7} ;
+ ${c1} '-_____-${c7}'
+ EOF
+ ;;
+
+ ([Ss]lackware*)
+ read_ascii 4 <<-EOF
+ ${c4} ________
+ ${c4} / ______|
+ ${c4} | |______
+ ${c4} \\______ \\
+ ${c4} ______| |
+ ${c4}| |________/
+ ${c4}|____________
+ EOF
+ ;;
+
+ ([Ss]olus*)
+ read_ascii 4 <<-EOF
+ ${c6}
+ ${c6} /|
+ ${c6} / |\\
+ ${c6} / | \\ _
+ ${c6} /___|__\\_\\
+ ${c6} \\ /
+ ${c6} \`-------´
+ EOF
+ ;;
+
+ ([Ss]un[Oo][Ss]|[Ss]olaris*)
+ read_ascii 3 <<-EOF
+ ${c3} . .; .
+ ${c3} . :; :: ;: .
+ ${c3} .;. .. .. .;.
+ ${c3}.. .. .. ..
+ ${c3} .;, ,;.
+ EOF
+ ;;
+
+ ([Uu]buntu*)
+ read_ascii 3 <<-EOF
+ ${c3} _
+ ${c3} ---(_)
+ ${c3} _/ --- \\
+ ${c3}(_) | |
+ ${c3} \\ --- _/
+ ${c3} ---(_)
+ EOF
+ ;;
+
+ ([Vv]oid*)
+ read_ascii 2 <<-EOF
+ ${c2} _______
+ ${c2} _ \\______ -
+ ${c2}| \\ ___ \\ |
+ ${c2}| | / \ | |
+ ${c2}| | \___/ | |
+ ${c2}| \\______ \\_|
+ ${c2} -_______\\
+ EOF
+ ;;
+
+ ([Xx]eonix*)
+ read_ascii 2 <<-EOF
+ ${c2} ___ ___
+ ${c2}___ \ \/ / ___
+ ${c2}\ \ \ / / /
+ ${c2} \ \/ \/ /
+ ${c2} \ /\ /
+ ${c2} \__/ \__/
+ EOF
+ ;;
+
+ (*)
+ # On no match of a distribution ascii art, this function calls
+ # itself again, this time to look for a more generic OS related
+ # ascii art (KISS Linux -> Linux).
+ [ "$1" ] || {
+ get_ascii "$os"
+ return
+ }
+
+ printf 'error: %s is not currently supported.\n' "$os" >&6
+ printf 'error: Open an issue for support to be added.\n' >&6
+ exit 1
+ ;;
+ esac
+
+ # Store the "width" (longest line) and "height" (number of lines)
+ # of the ascii art for positioning. This script prints to the screen
+ # *almost* like a TUI does. It uses escape sequences to allow dynamic
+ # printing of the information through user configuration.
+ #
+ # Iterate over each line of the ascii art to retrieve the above
+ # information. The 'sed' is used to strip '\033[3Xm' color codes from
+ # the ascii art so they don't affect the width variable.
+ while read -r line; do
+ ascii_height=$((${ascii_height:-0} + 1))
+
+ # This was a ternary operation but they aren't supported in
+ # Minix's shell.
+ [ "${#line}" -gt "${ascii_width:-0}" ] &&
+ ascii_width=${#line}
+
+ # Using '<<-EOF' is the only way to loop over a command's
+ # output without the use of a pipe ('|').
+ # This ensures that any variables defined in the while loop
+ # are still accessible in the script.
+ done <<-EOF
+ $(printf %s "$ascii" | sed 's/\[3.m//g')
+ EOF
+
+ # Add a gap between the ascii art and the information.
+ ascii_width=$((ascii_width + 4))
+
+ # Print the ascii art and position the cursor back where we
+ # started prior to printing it.
+ {
+ esc_p SGR 1
+ printf '%s' "$ascii"
+ esc_p SGR 0
+ esc_p CUU "$ascii_height"
+ } >&6
+}
+
+main() {
+ case $* in
+ -v)
+ printf '%s 0.7.0\n' "${0##*/}"
+ return 0
+ ;;
+
+ -d)
+ # Below exec is not run, stderr is shown.
+ ;;
+
+ '')
+ exec 2>/dev/null
+ ;;
+
+ *)
+ cat <<EOF
+${0##*/} show system information
+${0##*/} -d show stderr (debug mode)
+${0##*/} -v show version information
+EOF
+ return 0
+ ;;
+ esac
+
+ # Hide 'stdout' and selectively print to it using '>&6'.
+ # This gives full control over what it displayed on the screen.
+ exec 6>&1 >/dev/null
+
+ # Store raw escape sequence character for later reuse.
+ esc_c=$(printf '\033')
+
+ # Allow the user to execute their own script and modify or
+ # extend pfetch's behavior.
+ # shellcheck source=/dev/null
+ ! [ -f "$PF_SOURCE" ] || . "$PF_SOURCE"
+
+ # Ensure that the 'TMPDIR' is writable as heredocs use it and
+ # fail without the write permission. This was found to be the
+ # case on Android where the temporary directory requires root.
+ [ -w "${TMPDIR:-/tmp}" ] || export TMPDIR=~
+
+ # Generic color list.
+ # Disable warning about unused variables.
+ # shellcheck disable=2034
+ for _c in c1 c2 c3 c4 c5 c6 c7 c8; do
+ esc SGR "3${_c#?}" 0
+ export "$_c=$e"
+ done
+
+ # Disable line wrapping and catch the EXIT signal to enable it again
+ # on exit. Ideally you'd somehow query the current value and retain
+ # it but I'm yet to see this irk anyone.
+ esc_p DECAWM l >&6
+ trap 'esc_p DECAWM h >&6' EXIT
+
+ # Store the output of 'uname' to avoid calling it multiple times
+ # throughout the script. 'read <<EOF' is the simplest way of reading
+ # a command into a list of variables.
+ read -r os kernel arch <<-EOF
+ $(uname -srm)
+ EOF
+
+ # Always run 'get_os' for the purposes of detecting which ascii
+ # art to display.
+ get_os
+
+ # Allow the user to specify the order and inclusion of information
+ # functions through the 'PF_INFO' environment variable.
+ # shellcheck disable=2086
+ {
+ # Disable globbing and set the positional parameters to the
+ # contents of 'PF_INFO'.
+ set -f
+ set +f -- ${PF_INFO-ascii title os host kernel uptime pkgs memory}
+
+ # Iterate over the info functions to determine the lengths of the
+ # "info names" for output alignment. The option names and subtitles
+ # match 1:1 so this is thankfully simple.
+ for info do
+ command -v "get_$info" >/dev/null || continue
+
+ # This was a ternary operation but they aren't supported in
+ # Minix's shell.
+ [ "${#info}" -gt "${info_length:-0}" ] &&
+ info_length=${#info}
+ done
+
+ # Add an additional space of length to act as a gap.
+ info_length=$((info_length + 1))
+
+ # Iterate over the above list and run any existing "get_" functions.
+ for info do
+ "get_$info"
+ done
+ }
+
+ # Position the cursor below both the ascii art and information lines
+ # according to the height of both. If the information exceeds the ascii
+ # art in height, don't touch the cursor (0/unset), else move it down
+ # N lines.
+ #
+ # This was a ternary operation but they aren't supported in Minix's shell.
+ [ "${info_height:-0}" -lt "${ascii_height:-0}" ] &&
+ cursor_pos=$((ascii_height - info_height))
+
+ # Print '$cursor_pos' amount of newlines to correctly position the
+ # cursor. This used to be a 'printf $(seq X X)' however 'seq' is only
+ # typically available (by default) on GNU based systems!
+ while [ "${i:=0}" -le "${cursor_pos:-0}" ]; do
+ printf '\n'
+ i=$((i + 1))
+ done >&6
+}
+
+main "$@"
diff --git a/home/dots/.local/bin/todo b/home/dots/.local/bin/todo
new file mode 100755
index 0000000..f0a02b8
--- /dev/null
+++ b/home/dots/.local/bin/todo
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+TODO_BASE='* TODO '
+JRNL="$STITCH_DIRECTORY/$(date +'%y-%m-%d.%H:%M.%S').org"
+echo '* TODO ' > /tmp/capture
+$EDITOR /tmp/capture +1
+if grep -q '^\* TODO\s*$' /tmp/capture
+then
+ echo "Empty capture"
+else
+ echo "Storing capture in $JRNL"
+ cat /tmp/capture > $JRNL
+fi
+
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-Bold.ttf b/home/dots/.local/share/fonts/IosevkaSS13-Bold.ttf
new file mode 100644
index 0000000..5adc20b
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-Bold.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-BoldItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-BoldItalic.ttf
new file mode 100644
index 0000000..65e4275
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-BoldItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-BoldOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-BoldOblique.ttf
new file mode 100644
index 0000000..58750b2
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-BoldOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-Extended.ttf b/home/dots/.local/share/fonts/IosevkaSS13-Extended.ttf
new file mode 100644
index 0000000..8bf150f
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-Extended.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedBold.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedBold.ttf
new file mode 100644
index 0000000..f23643d
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedBold.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedBoldItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedBoldItalic.ttf
new file mode 100644
index 0000000..61b9973
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedBoldItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedBoldOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedBoldOblique.ttf
new file mode 100644
index 0000000..8657c09
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedBoldOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBold.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBold.ttf
new file mode 100644
index 0000000..80d2dc7
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBold.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBoldItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBoldItalic.ttf
new file mode 100644
index 0000000..b6645bf
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBoldItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBoldOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBoldOblique.ttf
new file mode 100644
index 0000000..88f9585
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraBoldOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLight.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLight.ttf
new file mode 100644
index 0000000..22a7abe
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLight.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLightItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLightItalic.ttf
new file mode 100644
index 0000000..8fb491e
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLightItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLightOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLightOblique.ttf
new file mode 100644
index 0000000..bd84354
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedExtraLightOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavy.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavy.ttf
new file mode 100644
index 0000000..8cc72d2
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavy.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavyItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavyItalic.ttf
new file mode 100644
index 0000000..137df73
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavyItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavyOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavyOblique.ttf
new file mode 100644
index 0000000..e6a0cbc
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedHeavyOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedItalic.ttf
new file mode 100644
index 0000000..f15527d
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedLight.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedLight.ttf
new file mode 100644
index 0000000..8694293
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedLight.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedLightItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedLightItalic.ttf
new file mode 100644
index 0000000..ac366b5
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedLightItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedLightOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedLightOblique.ttf
new file mode 100644
index 0000000..5a90087
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedLightOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedMedium.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedMedium.ttf
new file mode 100644
index 0000000..903fca8
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedMedium.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedMediumItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedMediumItalic.ttf
new file mode 100644
index 0000000..48208ea
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedMediumItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedMediumOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedMediumOblique.ttf
new file mode 100644
index 0000000..a1e0f00
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedMediumOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedOblique.ttf
new file mode 100644
index 0000000..b92a407
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBold.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBold.ttf
new file mode 100644
index 0000000..02c954f
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBold.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBoldItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBoldItalic.ttf
new file mode 100644
index 0000000..d3a8451
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBoldItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBoldOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBoldOblique.ttf
new file mode 100644
index 0000000..1a1d2de
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedSemiBoldOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedThin.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedThin.ttf
new file mode 100644
index 0000000..9b294a9
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedThin.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedThinItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedThinItalic.ttf
new file mode 100644
index 0000000..e2a0c10
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedThinItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtendedThinOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedThinOblique.ttf
new file mode 100644
index 0000000..b9f5ee2
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtendedThinOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtraBold.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtraBold.ttf
new file mode 100644
index 0000000..91bdf22
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtraBold.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtraBoldItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtraBoldItalic.ttf
new file mode 100644
index 0000000..df36e15
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtraBoldItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtraBoldOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtraBoldOblique.ttf
new file mode 100644
index 0000000..4e6fa98
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtraBoldOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtraLight.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtraLight.ttf
new file mode 100644
index 0000000..d26599e
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtraLight.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtraLightItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtraLightItalic.ttf
new file mode 100644
index 0000000..d9856c1
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtraLightItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ExtraLightOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ExtraLightOblique.ttf
new file mode 100644
index 0000000..1accf09
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ExtraLightOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-Heavy.ttf b/home/dots/.local/share/fonts/IosevkaSS13-Heavy.ttf
new file mode 100644
index 0000000..24ae757
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-Heavy.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-HeavyItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-HeavyItalic.ttf
new file mode 100644
index 0000000..4bdb262
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-HeavyItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-HeavyOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-HeavyOblique.ttf
new file mode 100644
index 0000000..f31bb9b
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-HeavyOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-Italic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-Italic.ttf
new file mode 100644
index 0000000..b83c3ad
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-Italic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-Light.ttf b/home/dots/.local/share/fonts/IosevkaSS13-Light.ttf
new file mode 100644
index 0000000..34d4918
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-Light.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-LightItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-LightItalic.ttf
new file mode 100644
index 0000000..1d034fa
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-LightItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-LightOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-LightOblique.ttf
new file mode 100644
index 0000000..2c2f1aa
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-LightOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-Medium.ttf b/home/dots/.local/share/fonts/IosevkaSS13-Medium.ttf
new file mode 100644
index 0000000..25fa6e1
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-Medium.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-MediumItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-MediumItalic.ttf
new file mode 100644
index 0000000..851ac47
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-MediumItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-MediumOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-MediumOblique.ttf
new file mode 100644
index 0000000..6fb550d
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-MediumOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-Oblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-Oblique.ttf
new file mode 100644
index 0000000..fbc37e1
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-Oblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-Regular.ttf b/home/dots/.local/share/fonts/IosevkaSS13-Regular.ttf
new file mode 100644
index 0000000..88baaeb
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-Regular.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-SemiBold.ttf b/home/dots/.local/share/fonts/IosevkaSS13-SemiBold.ttf
new file mode 100644
index 0000000..6f22260
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-SemiBold.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-SemiBoldItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-SemiBoldItalic.ttf
new file mode 100644
index 0000000..c321a3d
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-SemiBoldItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-SemiBoldOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-SemiBoldOblique.ttf
new file mode 100644
index 0000000..7c43381
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-SemiBoldOblique.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-Thin.ttf b/home/dots/.local/share/fonts/IosevkaSS13-Thin.ttf
new file mode 100644
index 0000000..d9d0c5f
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-Thin.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ThinItalic.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ThinItalic.ttf
new file mode 100644
index 0000000..1c1b60c
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ThinItalic.ttf
Binary files differ
diff --git a/home/dots/.local/share/fonts/IosevkaSS13-ThinOblique.ttf b/home/dots/.local/share/fonts/IosevkaSS13-ThinOblique.ttf
new file mode 100644
index 0000000..3460e86
--- /dev/null
+++ b/home/dots/.local/share/fonts/IosevkaSS13-ThinOblique.ttf
Binary files differ
diff --git a/home/dots/.mbsyncrc b/home/dots/.mbsyncrc
new file mode 100644
index 0000000..ca00992
--- /dev/null
+++ b/home/dots/.mbsyncrc
@@ -0,0 +1,60 @@
+CopyArrivalDate yes # Don't mess up message timestamps when moving them between folders.
+Create Near # Automatically create new folders in the local copy.
+Remove Near # Automatically remove deleted folders from the local copy.
+Expunge Near # Expunge deleted messages from the local copy.
+
+# First section: remote IMAP account
+IMAPAccount Home
+Host imap.fastmail.com
+Port 993
+User marcc@fastmail.fr
+# For simplicity, this is how to read the password from another file.
+# For better security you should use GPG https://gnupg.org/
+PassCmd "pass fastmail/marcc"
+TLSType IMAPS
+TLSVersions +1.2
+
+IMAPStore Home-remote
+Account Home
+
+# This section describes the local storage
+MaildirStore Home-local
+Path ~/mail/home/
+Inbox ~/mail/home/INBOX
+SubFolders Verbatim
+
+# This section a "channel", a connection between remote and local
+Channel Home
+Far :Home-remote:
+Near :Home-local:
+Patterns *
+Expunge None
+CopyArrivalDate yes
+Sync All
+Create Both
+SyncState *
+
+
+# WORK
+IMAPAccount Work
+Host imap.gmail.com
+User marc.coquand@sustainably.app
+PassCmd "pass sustainably/gmail"
+TLSType IMAPS
+Timeout 60
+
+IMAPStore Work-remote
+Account Work
+
+MaildirStore Work-local
+Path ~/mail/work/
+Inbox ~/mail/work/INBOX
+SubFolders Verbatim
+
+Channel Work
+Far :Work-remote:
+Near :Work-local:
+Expunge Both
+Create Both
+Patterns *
+SyncState *
diff --git a/home/dots/.mozilla/firefox/p8ada7a1.default/chrome/userChrome.css b/home/dots/.mozilla/firefox/p8ada7a1.default/chrome/userChrome.css
new file mode 100644
index 0000000..ae8a6dd
--- /dev/null
+++ b/home/dots/.mozilla/firefox/p8ada7a1.default/chrome/userChrome.css
@@ -0,0 +1,10 @@
+#TabsToolbar {
+ visibility: collapse;
+}
+
+menubar, toolbar, nav-bar, #TabsToolbar > * {
+ background-color: white !important;
+ font-family: "Iosevka Aile";
+}
+
+
diff --git a/home/dots/.msmtprc b/home/dots/.msmtprc
new file mode 100644
index 0000000..170f86e
--- /dev/null
+++ b/home/dots/.msmtprc
@@ -0,0 +1,25 @@
+# Set default values for all following accounts.
+defaults
+auth on
+tls on
+tls_trust_file /etc/ssl/certs/ca-certificates.crt
+logfile ~/.msmtp.log
+
+# Work
+account work
+host smtp.gmail.com
+port 587
+from marc@baemingo.com
+user marc@baemingo.com
+passwordeval "pass baemingo/gmail"
+
+# Home
+account home
+host smtp.fastmail.com
+port 465
+tls_starttls off
+from marcc@fastmail.fr
+user marcc@fastmail.fr
+passwordeval "pass fastmail/marcc"
+
+account default : home
diff --git a/home/dots/.xsession.bak b/home/dots/.xsession.bak
new file mode 100755
index 0000000..5823726
--- /dev/null
+++ b/home/dots/.xsession.bak
@@ -0,0 +1,18 @@
+
+#!/usr/bin/env sh
+export _JAVA_AWT_WM_NONREPARENTING=1
+export VISUAL=emacsclient
+export EDITOR="$VISUAL"
+#autocutsel &
+xsetroot -solid '#FFFFFF' &
+#ulimit -c 0 &
+#xclock -digital -geometry +5+1402 -face "Iosevka Aile:pixelsize=18:style=regular" -bg \#282C34 -fg \#B8BCC4 -strftime "Bogo (%Y/%m/%d) %H:%M" &
+gsettings set org.gnome.desktop.interface document-font-name 'Iosevka Aile' &
+gsettings set org.gnome.desktop.interface font-name 'Iosevka Aile' &
+gsettings set org.gnome.desktop.interface cursor-size 32 &
+gsettings set org.gnome.desktop.interface cursor-theme Adwaita &
+# xkbcomp $HOME/.config/keymap_locked_modifier.xkb $DISPLAY &
+#xsetroot -cursor_name left_ptr &
+xset r rate 200 60 &
+emacs --daemon --eval "(require 'exwm)" -f exwm-enable
+exec dbus-launch emacsclient -c
diff --git a/home/profile b/home/profile
new file mode 100644
index 0000000..b8fa27f
--- /dev/null
+++ b/home/profile
@@ -0,0 +1,18 @@
+PATH=${PATH}:/home/mccd/go/bin:/home/mccd/.cargo/bin:/home/mccd/.local/bin
+
+export EDITOR="mg -n"
+export GDK_DPI_SCALE="1.5"
+export GDK_SCALE="1.5"
+export XCURSOR_SIZE="32"
+# So when you hover the desktop, it still uses Adwaita
+export XCURSOR_THEME="Adwaita"
+export PF_INFO="ascii title os editor shell wm"
+export PF_ALIGN="5"
+export PF_COLOR="0"
+export MOZ_ACCELERATED=1
+export HISTSIZE=65535
+export HISTFILE=$HOME/.history
+export STITCH_DIRECTORY=/home/mccd/notes
+export STITCH_GREP_CMD=ugrep
+
+