summaryrefslogtreecommitdiff
path: root/kolwynia/home/bdunahu/files/.config/emacs/modules
diff options
context:
space:
mode:
Diffstat (limited to 'kolwynia/home/bdunahu/files/.config/emacs/modules')
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--browse.el146
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--buffer.el32
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--chat.el118
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--devel.el237
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--dictionary.el20
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--emms.el68
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--exwm.el115
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--files.el92
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--gpg.el59
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--image.el22
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--minibuffer.el171
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--modeline.el99
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--notes.el77
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--org.el255
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--project.el18
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--shells.el135
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--tabs.el43
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--themes.el115
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--utility.el160
-rw-r--r--kolwynia/home/bdunahu/files/.config/emacs/modules/bd--window.el59
20 files changed, 2041 insertions, 0 deletions
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--browse.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--browse.el
new file mode 100644
index 0000000..7ba6513
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--browse.el
@@ -0,0 +1,146 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+(require 'selector)
+(require 'dash)
+(require 'fill-column)
+
+(defun bd/browse (url &optional pref &rest _)
+ "Given PREF, launches URL in an external browser or eww."
+ (interactive)
+ (pcase pref
+ ('eww (eww url))
+ ('tor (start-process "torbrowser" nil "torbrowser" "--new-window" url))
+ ('chromium (start-process "chromium" nil "chromium" "--new-window" url))
+ (_ (start-process "browser" nil (getenv "BROWSER") "--new-window" url))))
+
+(defun bd/selector-bookmarks ()
+ "Selector source for all bookmarks."
+ (selector-source-create
+ "Bookmarks"
+ :candidates
+ (-map
+ (lambda (b) (selector-candidate-create (car b) :value (cdr b)))
+ bd/bookmarks)
+ :actions
+ (list (lambda (x) (apply #'bd/browse x)))))
+
+(defmacro bd/search-candidate (name url pref)
+ "Syntax for a search candidate given NAME, URL, and PREF."
+ `(selector-candidate-create
+ ,(concat "Search " name)
+ :type 'dummy
+ :action (lambda (_) (browse-url (concat ,url (selector-input)) ,pref))))
+
+(defun rip-video (url)
+ "Play URL (or search string) in mpv."
+ (message "Ludu %s" url)
+ (start-process "rip" nil
+ "mpv" "--force-window=yes"
+ (concat (if (string-match "https://.*" url)
+ "ytdl://"
+ "ytdl://ytsearch:") url)))
+
+(defun rip-html (url)
+ "Open an HTML document in an emacs org buffer."
+ (with-current-buffer-window url
+ '((display-buffer-same-window))
+ nil
+ (princ
+ (shell-command-to-string
+ (concat "curl --silent " url " | pandoc --from=html --to=org --standalone")))
+ (org-mode)))
+
+(defun bd/selector-rip-video ()
+ "Selector source for streaming a video off of youtube."
+ (selector-candidate-create
+ "Search Immediate"
+ :type 'dummy
+ :action (lambda (_) (rip-video (selector-input)))))
+
+(defun bd/selector-search ()
+ "Selector source for all search engines."
+ (selector-source-create
+ "Browser"
+ :candidates
+ (list (bd/search-candidate "DuckDuckGo" "https://duckduckgo.com/html/?q=" 'wolf)
+ (bd/search-candidate "SearXNG" "https://searx.operationnull.com/searxng/search?q=" 'wolf)
+ (bd/search-candidate "SearXNG-E" "https://searx.operationnull.com/searxng/search?q=" 'eww)
+ (bd/search-candidate "Wikipedia" "https://en.wikipedia.org/w/index.php?search=" 'eww)
+ (bd/search-candidate "Invidious" "https://inv.nadeko.net/search?q=" 'eww)
+ (bd/search-candidate "Urban Dictionary" "https://www.urbandictionary.com/define.php?term=" 'wolf)
+ (bd/search-candidate "Nethack Wiki" "https://nethackwiki.com/w/index.php?search=" 'eww)
+ (bd/search-candidate "Archive of Our Own" "https://archiveofourown.org/works/search?work_search%5Bquery%5D=" 'eww)
+ (bd/search-candidate "Archwiki" "https://wiki.archlinux.org/index.php?title=Special%3ASearch&search=" 'eww)
+
+ (bd/selector-rip-video)
+ (bd/search-candidate "Torbrowser" "" 'tor)
+ (bd/search-candidate "Librewolf" "" 'wolf))))
+
+(defun bd/browse-dispatcher ()
+ "Select and `browse-url' a bookmark or search feature."
+ (interactive)
+ (unwind-protect
+ (selector
+ (list (bd/selector-bookmarks)
+ (bd/selector-search)))))
+
+(setopt browse-url-handlers
+ `((,(regexp-opt '("youtube.com" "youtu.be" "vid.puffyan.us" "deezer.page" "deezer.com")) .
+ (lambda (url &rest _) (rip-video url))))
+ url-privacy-level '(email os emacs lastloc cookies))
+
+(use-package elpher
+ :bind
+ (:map elpher-mode-map
+ ("l" . #'elpher-back)
+ ("d" . #'elpher-download)
+ ("w" . #'elpher-copy-current-url)
+ ("A" . #'elpher-copy-link-url)
+ ("E" . #'elpher-bookmark-current)
+ ("TAB" . #'elpher-next-link)
+ ("g" . #'elpher-reload)
+ ("G" . #'elpher-go))
+ :config
+ (defun bd/elpher (original url &optional new-window)
+ "Handle gemini links."
+ (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url)
+ (elpher-go url))
+ (t (funcall original url new-window))))
+ (advice-add 'eww :around 'bd/elpher)
+ (setopt elpher-default-url-type "gemini"
+ elpher-connection-timeout 120
+ elpher-gemini-max-fill-width 85
+ elpher-use-emacs-bookmark-menu t))
+
+(use-package eww
+ :defer 1
+ :bind
+ (:map eww-mode-map
+ ("i" . eww-toggle-images)
+ ("o" . (lambda () (interactive) (rip-html (eww-current-url)))))
+ :hook
+ ;; eww-mode by default sets this as local var to eww-browse-url
+ ((eww-mode .
+ (lambda ()
+ (setq-local browse-url-browser-function #'bd/browse)))
+ (eww-after-render . eww-readable))
+ :config
+ (setopt eww-search-prefix "https://searx.operationnull.com/searxng/search?q="
+ eww-auto-rename-buffer 'title
+ eww-browse-url-new-window-is-tab nil
+ browse-url-browser-function 'bd/browse
+ browse-url-secondary-browser-function #'browse-url-default-browser
+ eww-header-line-format "%t: %u"
+ eww-use-browse-url (regexp-opt '("mailto:"
+ "youtube.com"
+ "youtu.be"))
+ shr-use-fonts nil
+ shr-inhibit-images t
+ shr-cookie-policy nil
+ shr-max-width 90))
+
+
+(provide 'bd--browse)
+;;; bd--browse.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--buffer.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--buffer.el
new file mode 100644
index 0000000..4a09805
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--buffer.el
@@ -0,0 +1,32 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(use-package autorevert
+ :init
+ (global-auto-revert-mode)
+ :config
+ (setopt global-auto-revert-non-file-buffers t
+ auto-revert-interval 30))
+
+(use-package midnight
+ :config
+ ;; kill forgotten browser windows
+ (push
+ "\.\*\\(LibreWolf\\|Chromium\\|IceCat\\|Tor\sBrowser\\)"
+ clean-buffer-list-kill-regexps)
+ ;; never kill irc buffers
+ (push
+ ".*operationnull.com"
+ clean-buffer-list-kill-never-regexps)
+ (setopt clean-buffer-list-delay-special 1800
+ midnight-period (* 12 3600)))
+
+(use-package atomic-chrome
+ :config
+ (atomic-chrome-start-server))
+
+
+(provide 'bd--buffer)
+;;; bd--buffer.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--chat.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--chat.el
new file mode 100644
index 0000000..5fa0c2d
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--chat.el
@@ -0,0 +1,118 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(require 'fill-column)
+(use-package rcirc
+ :bind (:map rcirc-mode-map
+ ("C-c j" . #'bd/rcirc-jump-net)
+ ("C-c q" . #'bd/rcirc-detach-buffer))
+ :hook
+ ((rcirc-mode . (lambda ()
+ (setq-local fill-column-desired-width 80)
+ (fill-column-mode)
+ (rcirc-omit-mode))))
+ :config
+ (setopt bd/rcirc-networks '("libera" "furnet"))
+ (defun bd/rcirc-jump-net ()
+ "Prompts the user for a irc network in BD/RCIRC-NETWORKS, then issues
+ZNC to hop networks."
+ (interactive)
+ (let ((buffer (current-buffer)))
+ (when (and (buffer-local-value 'rcirc-server-buffer buffer)
+ (eq (process-status (rcirc-buffer-process)) 'open))
+ (let ((target (completing-read "Jump to: " bd/rcirc-networks)))
+ (if (stringp target)
+ (rcirc-send-string (rcirc-buffer-process)
+ "PRIVMSG" "*status" :
+ (concat "JUMPNETWORK " target)))))))
+ (defun bd/rcirc-detach-buffer ()
+ "If the current buffer is an rcirc channel, detaches through ZNC and
+deletes the buffer. This bypasses the default behavior of deleting an active
+channel, which is issuing the PART command."
+ (interactive)
+ (let ((buffer (current-buffer)))
+ (when (and (rcirc-buffer-process)
+ (eq (process-status (rcirc-buffer-process)) 'open))
+ (with-rcirc-server-buffer
+ (setq rcirc-buffer-alist
+ (rassq-delete-all buffer rcirc-buffer-alist)))
+ (rcirc-update-short-buffer-names)
+ (if (rcirc-channel-p rcirc-target)
+ (rcirc-send-string (rcirc-buffer-process)
+ "PRIVMSG" "*status" :
+ (concat "DETACH " rcirc-target))))
+ (setq rcirc-target nil)
+ (kill-buffer buffer)))
+ (setopt rcirc-fill-column 80
+ rcirc-omit-threshold 5
+ rcirc-reconnect-delay 60
+ rcirc-omit-responses '("JOIN" "PART" "QUIT" "NICK" "AWAY")
+ rcirc-track-minor-mode t
+ rcirc-track-ignore-server-buffer-flag t
+ rcirc-server-alist
+ '(("operationnull.com"
+ :nick "Gondul"
+ :user-name "Gondul"
+ :port 6697
+ :encryption tls))))
+
+(use-package gptel
+ :bind (("C-c g" . gptel-menu)
+ ("C-c k" . (lambda () (interactive) (gptel "*evka*") (switch-to-buffer "*evka*"))))
+ :config
+ (defvar bd/llama-cpp-buffer-name "*llama-cpp-proc*")
+ (defvar bd/llama-cpp-reasoning-buffer-name "*llama-cpp-reasoning*")
+ (defvar bd/llama-cpp-port "4568")
+ (defvar bd/llama-cpp-threads "8")
+ (defvar bd/llama-cpp-model-file "Qwen3-8B.Q4_K_M.gguf")
+ ;; most models seem to ignore this, or llama-cpp doesn't add /no_think like it's supposed to
+ (defvar bd/llama-cpp-reasoning-budget nil)
+ (defun bd/gptel-start-backend ()
+ (interactive)
+ (let ((process (get-buffer-process bd/llama-cpp-buffer-name)))
+ (if process
+ (message "llama-cpp process is already running!")
+ (progn
+ (start-process-shell-command
+ "llama-cpp" bd/llama-cpp-buffer-name
+ (concat "llama-server --reasoning-budget "
+ (if bd/llama-cpp-reasoning-budget "-1" "0")
+ " --port " bd/llama-cpp-port
+ " -t " bd/llama-cpp-threads
+ " -m " (expand-file-name bd/llama-cpp-model-file "~/.config/guix/assets/"))))
+ (unless (get-buffer bd/llama-cpp-reasoning-buffer-name)
+ (generate-new-buffer bd/llama-cpp-reasoning-buffer-name)))))
+ (defun bd/gptel-stop-backend ()
+ (interactive)
+ (let ((process (get-buffer-process bd/llama-cpp-buffer-name)))
+ (if process
+ (progn
+ (delete-process process)
+ (kill-buffer bd/llama-cpp-buffer-name)
+ (message "Killed %s." process))
+ (message "No llama-cpp process is running."))))
+ (defun bd/gptel-restart-backend ()
+ (interactive)
+ (bd/gptel-stop-backend)
+ (bd/gptel-start-backend))
+
+ (bd/gptel-start-backend)
+
+ (add-to-list 'gptel-directives
+ '(evka . "You are a wolf (furry) named Evka hired as a secretary to complete language-based tasks. First describe an action your character does, e.x.: *I tap my claws on the desk*. Finish by responding to the task tersely, in character./no_think"))
+
+ (setopt gptel-model 'qwen-4b
+ gptel-backend (gptel-make-openai "llama-cpp"
+ :stream t
+ :protocol "http"
+ :host (concat "localhost:" bd/llama-cpp-port)
+ :models '(qwen-4b))
+ gptel-max-tokens 500
+ gptel--system-message (alist-get 'evka gptel-directives)
+ gptel-include-reasoning bd/llama-cpp-reasoning-buffer-name))
+
+
+(provide 'bd--chat)
+;;; bd--chat.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--devel.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--devel.el
new file mode 100644
index 0000000..dfc9f15
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--devel.el
@@ -0,0 +1,237 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+(require 'selector)
+(require 'dash)
+
+(setopt display-line-numbers-type 'relative)
+(defvar bd/enable-line-numbers-in-hooks
+ '(prog-mode-hook)
+ "List of hook symbols to add `display-line-numbers-mode' to.")
+(mapc
+ (lambda (hook)
+ (add-hook hook #'display-line-numbers-mode))
+ bd/enable-line-numbers-in-hooks)
+
+;; skr (skribe) is a scheme extension
+(add-to-list 'auto-mode-alist '("\\.skr\\'" . scheme-mode))
+
+(defun bd/beginning-of-visual-line-dwim (&optional n)
+ (interactive "P")
+ (let ((pt (point)))
+ (back-to-indentation)
+ (when (or n (eq pt (point)))
+ (beginning-of-visual-line n))))
+
+(define-minor-mode dwim-cursor-mode
+ "Toggle dwim-cursor-mode."
+ :init-value nil
+ :group 'quality
+ :light " SC"
+ :keymap (list
+ (cons (kbd "C-a") #'bd/beginning-of-visual-line-dwim)))
+
+(use-package prog-mode
+ :hook
+ ((js-mode . (lambda ()
+ (add-to-list 'prettify-symbols-alist '("function" . ?ƒ))))
+ (prog-mode . (lambda ()
+ (font-lock-add-keywords
+ nil '(("\\<\\(FIX\\(ME\\)?\\|TODO\\)"
+ 1 font-lock-warning-face t)))))
+ (prog-mode . dwim-cursor-mode))
+ :config
+ (global-prettify-symbols-mode 1))
+
+(use-package tramp
+ :config
+ (defun request-sudo ()
+ "Uses TRAMP to edit current opened file as root."
+ (interactive)
+ (when buffer-file-name
+ (find-alternate-file
+ (concat "/sudo:root@localhost:"
+ buffer-file-name))))
+ (setopt tramp-remote-path
+ (append tramp-remote-path
+ '(tramp-own-remote-path
+ "~/.guix-profile/bin" "~/.guix-profile/sbin"))))
+
+(use-package vc
+ :bind (("C-x v B" . #'bd/vc-browse-remote))
+ :config
+ (defun bd/vc-browse-remote (&optional current-line)
+ "Open the repository's remote URL in the browser.
+If CURRENT-LINE is non-nil, point to the current branch, file, and line.
+Otherwise, open the repository's main page."
+ (interactive "P")
+ (let* ((remote-url (string-trim (vc-git--run-command-string nil "config" "--get" "remote.origin.url")))
+ (branch (string-trim (vc-git--run-command-string nil "rev-parse" "--abbrev-ref" "HEAD")))
+ (file (string-trim (file-relative-name (buffer-file-name) (vc-root-dir))))
+ (line (line-number-at-pos)))
+ (message "Opening remote on browser: %s" remote-url)
+ (if (and remote-url (string-match "\\(?:git@\\|https://\\)\\([^:/]+\\)[:/]\\(.+?\\)\\(?:\\.git\\)?$" remote-url))
+ (let ((host (match-string 1 remote-url))
+ (path (match-string 2 remote-url)))
+ ;; Convert SSH URLs to HTTPS (e.g., git@github.com:user/repo.git -> https://github.com/user/repo)
+ (when (string-prefix-p "git@" host)
+ (setq host (replace-regexp-in-string "^git@" "" host)))
+ ;; Construct the appropriate URL based on CURRENT-LINE
+ (browse-url
+ (if current-line
+ (format "https://%s/%s/blob/%s/%s#L%d" host path branch file line)
+ (format "https://%s/%s" host path))))
+ (message "Could not determine repository URL")))))
+
+(use-package hl-line
+ :hook
+ ((prog-mode . hl-line-mode)
+ (text-mode . hl-line-mode)))
+
+(use-package compile
+ :demand t
+ :hook ((compilation-filter . ansi-color-compilation-filter))
+ :config
+ (setopt compilation-always-kill t
+ compilation-scroll-output 'first-error
+ compilation-ask-about-save nil
+ ansi-color-for-compilation-mode t)
+ (defun bd/compile-dwim (f)
+ (let ((default-directory (bd/get-directory-dwim)))
+ (call-interactively f)))
+ (add-to-list 'display-buffer-alist
+ '((major-mode . compilation-mode)
+ (display-buffer-in-side-window)
+ (side . bottom)
+ (slot . -1)
+ (width . 0.15)
+ (post-command-select-window t)))
+
+ (keymap-set prog-mode-map
+ "C-," #'(lambda ()
+ (interactive)
+ (bd/compile-dwim #'recompile)))
+ (keymap-set prog-mode-map
+ "C-<" #'(lambda ()
+ (interactive)
+ (bd/compile-dwim #'compile))))
+
+(use-package man
+ :config
+ (setopt Man-notify-method 'pushy))
+
+(use-package eldoc
+ :init
+ (global-eldoc-mode))
+
+(use-package flymake
+ :bind (("C-c f f" . #'flymake-mode)
+ :map flymake-mode-map
+ ("C-c f s" . #'flymake-start)
+ ("C-c f n" . #'flymake-goto-next-error)
+ ("C-c f p" . #'flymake-goto-prev-error)
+ ("C-c f b" . #'flymake-show-buffer-diagnostics)
+ ("C-c f d" . #'flymake-show-project-diagnostics))
+ :config
+ (setopt flymake-no-changes-timeout nil
+ flymake-start-on-flymake-mode t
+ flymake-start-on-save-buffer t
+ flymake-proc-compilation-prevents-syntax-check t
+ flymake-wrap-around nil
+ flymake-show-diagnostics-at-end-of-line nil))
+
+(require 'geiser)
+(require 'geiser-mode)
+(require 'geiser-guile)
+
+(use-package cider)
+
+(use-package gdb-mi
+ :config
+ (setopt gdb-debuginfod-enable-setting nil))
+
+(use-package eglot
+ :defer t
+ :bind (:map eglot-mode-map
+ ("C-c C-f" . eglot-format)
+ ("C-c C-e" . eglot-rename))
+ :config
+ (setopt eglot-autoshutdown t
+ eglot-prefer-plaintext t
+ jsonrpc-event-hook nil)
+ (add-to-list 'eglot-server-programs
+ '(c-mode . ("ccls" "--init={\"clang\": {\"extraArgs\": [\"-std=c++20\"]}}"))))
+
+(use-package rainbow-mode
+ :hook css-mode)
+
+(use-package lua-mode
+ :config
+ (setopt lua-indent-level 4
+ lua-indent-nested-block-content-align nil)
+ (defun lua-at-most-one-indent (old-function &rest arguments)
+ (let ((old-res (apply old-function arguments)))
+ (if (> old-res lua-indent-level) lua-indent-level old-res)))
+ (advice-add #'lua-calculate-indentation-block-modifier
+ :around #'lua-at-most-one-indent))
+
+(use-package clojure-mode)
+
+(use-package slime
+ :defer t
+ :commands slime
+ :bind (:map slime-mode-map
+ ("C-c C-k" . slime-eval-buffer))
+ :config
+ ;; more memory for ml libraries
+ (setopt inferior-lisp-program "sbcl --dynamic-space-size 4096"))
+
+(use-package yasnippet
+ :hook (vc-git-log-edit-mode . yas-minor-mode)
+ :config
+ (add-to-list 'yas-snippet-dirs (expand-file-name "~/pt/guix/etc/snippets/yas")))
+
+(use-package paren
+ :config
+ (setopt show-paren-delay 0
+ show-paren-style 'mixed
+ show-paren-highlight-openparen t
+ show-paren-context-when-offscreen t
+ show-paren-when-point-in-periphery t
+ show-paren-when-point-inside-paren t))
+
+(use-package rainbow-delimiters
+ :hook prog-mode)
+
+(use-package paredit
+ :hook (ielm-mode
+ emacs-lisp-mode
+ eshell-mode
+ geiser-repl-mode
+ clojure-mode
+ cider-repl-mode
+
+ lisp-mode
+ scheme-mode
+ slime-repl-mode
+ lisp-interaction-mode)
+ :config
+ (defun bd/paredit-preserve-repl (f &rest args)
+ "Wrapper around F (paredit-RET), discarding ARGS."
+ (pcase (cons major-mode (eolp))
+ ('(inferior-emacs-lisp-mode . t) (ielm-return))
+ ('(eshell-mode . t) (eshell-send-input))
+ ('(geiser-repl-mode . t) (geiser-repl-maybe-send))
+ ('(cider-repl-mode . t) (eshell-send-input))
+ ('(slime-repl-mode . t) (slime-repl-return))
+ (_ (funcall f))))
+ (advice-add #'paredit-RET :around #'bd/paredit-preserve-repl)
+ (eldoc-add-command
+ 'paredit-backward-delete
+ 'paredit-close-round))
+
+(use-package copyright)
+
+(provide 'bd--devel)
+;;; bd--devel.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--dictionary.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--dictionary.el
new file mode 100644
index 0000000..e032837
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--dictionary.el
@@ -0,0 +1,20 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(use-package dictionary
+ :bind (("C-c i" . dictionary-lookup-definition))
+ :config
+ (setopt dictionary-server "localhost"
+ dictionary-use-single-buffer t))
+
+(use-package powerthesaurus
+ :bind (("C-c t" . powerthesaurus-transient))
+ :config
+ (setopt powerthesaurus-show-rating nil
+ powerthesaurus-user-agent "Chrome/138.0.0.0"))
+
+
+(provide 'bd--dictionary)
+;;; bd--dictionary.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--emms.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--emms.el
new file mode 100644
index 0000000..f4e5064
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--emms.el
@@ -0,0 +1,68 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(use-package emms
+ :bind (("C-z C-s" . #'emms-quickstart)
+ ("C-z C-m" . #'switch-to-emms)
+ :map emms-playlist-mode-map
+ ("q" . #'quit-window))
+ :config
+ (emms-all)
+
+ (defun emms-quickstart ()
+ "Queues a shuffled playlist and starts
+playback."
+ (interactive)
+ (emms-stop)
+ (when (bufferp emms-playlist-buffer-name)
+ (kill-buffer emms-playlist-buffer-name))
+ (emms-play-directory-tree (expand-file-name "~/ik/"))
+ (emms-shuffle))
+ (defun switch-to-emms ()
+ (interactive)
+
+ (if (get-buffer emms-playlist-buffer-name)
+ (emms-playlist-mode-go)
+ (message "The Ainur cannot hear you...")))
+
+ (add-to-list 'emms-player-list 'emms-player-mpv)
+ (emms-playing-time-disable-display)
+ (setq-default emms-playlist-default-major-mode 'emms-playlist-mode
+
+ emms-player-list '(emms-player-mpv)
+ emms-player-mpv-environment '("PULSE_PROP_media.role=music")
+ emms-player-mpv-parameters '("--quiet" "--really-quiet" "--no-audio-display" "--force-window=no" "--vo=null"))
+ (setopt
+ emms-track-description-function
+ '(lambda (track)
+ (let ((artist (emms-track-get track 'info-artist))
+ (title (emms-track-get track 'info-title)))
+ (cond
+ ((and artist title)
+ (concat artist " - " title))
+ (title
+ title)
+ (t
+ (emms-track-simple-description track))))))
+ (setopt emms-source-file-default-directory (expand-file-name "~/ik/playlists/")
+ emms-info-report-each-num-tracks 2000
+ emms-playlist-buffer-name "*Playlist*"
+ emms-mode-line-icon-enabled-p nil
+ emms-mode-line-length-limit 35
+ emms-mode-line-format " [%s] "
+ emms-repeat-playlist t
+ emms-info-functions '(emms-info-native
+ emms-info-exiftool))
+ (add-to-list 'display-buffer-alist
+ '((major-mode . emms-playlist-mode)
+ (display-buffer-in-side-window)
+ (side . left)
+ (slot . 0)
+ (width . 0.2)
+ (post-command-select-window t))))
+
+
+(provide 'bd--emms)
+;;; bd--emms.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--exwm.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--exwm.el
new file mode 100644
index 0000000..1738ebe
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--exwm.el
@@ -0,0 +1,115 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(use-package exwm
+ :demand t
+ :config
+
+ (require 'exwm-randr)
+ (setopt exwm-randr-workspace-monitor-plist '(0 "HDMI-1" 1 "eDP-1")
+ exwm-workspace-number 10)
+ (add-hook 'exwm-randr-screen-change-hook
+ (lambda ()
+ (start-process-shell-command
+ "xrandr" nil
+ "xrandr --output HDMI-1 --mode 2560x1440 --primary --auto --left-of eDP-1 --output eDP-1 --mode 1920x1080")
+ (bd/set-bg)))
+ (exwm-randr-mode)
+
+ (defun bd/exwm-update-title ()
+ "Changes the buffer name to reflect the class name for
+that buffer."
+ (exwm-workspace-rename-buffer exwm-title))
+ (add-hook 'exwm-update-title-hook #'bd/exwm-update-title)
+ (define-key exwm-mode-map [?\C-q] 'exwm-input-send-next-key)
+ (exwm-enable)
+ (setopt exwm-replace nil
+ exwm-manage-force-tiling nil
+ exwm-input-prefix-keys
+ `([?\C-x]
+ [?\C-u]
+ [?\C-g]
+ [?\C-h]
+ [?\C-z]
+ [?\C-`]
+ [?\M-x]
+ [?\M-`]
+ [?\M-&]
+ [?\M-:]
+ [?\M-!]
+ ,@(mapcar (lambda (i)
+ (kbd (concat "s-" (number-to-string i))))
+ (number-sequence 0 9)))
+
+ exwm-input-global-keys
+ `(([?\s-n] . other-window)
+ ([?\s-p] . (lambda ()
+ (interactive)
+ (other-window -1)))
+ ([?\s-L] . bd/lock)
+ ([f2] . bd/toggle-mute)
+ ([f5] . bd/decrement-volume)
+ ([f6] . bd/increment-volume)
+ ([f7] . bd/decrement-brightness)
+ ([f8] . bd/increment-brightness)
+ ([f9] . emms-previous)
+ ([f10] . emms-next)
+ ([print] . bd/shoot-part)
+ ([S-print] . bd/shoot-full)
+ ([?\s-O] . bd/browse-dispatcher)
+ ([?\s-P] . bd/password)
+ ([?\s-r] . exwm-reset)
+ ([?\s-d] . toggle-window-dedicated)
+ ([?\s-t] . bd/toggle-tab-bar)
+ ([?\s-q] . kill-current-buffer)
+ ([?\s-x] . (lambda (command)
+ (interactive (list (read-shell-command "s-x ")))
+ (start-process-shell-command command nil command)))
+ ,@(mapcar (lambda (i)
+ `(,(kbd (format "s-%s" (car i))) .
+ (lambda ()
+ (interactive
+ (exwm-workspace-switch-create ,(car (cdr i)))))))
+ '((! 0) (@ 1) (\# 2) ($ 3) (% 4) (^ 5) (& 6) (* 7) (\( 8) (\) 9))))
+
+ exwm-input-simulation-keys
+ '(([?\C-b] . [left])
+ ([?\C-f] . [right])
+ ([?\C-p] . [up])
+ ([?\C-n] . [down])
+ ([?\C-a] . [home])
+ ([?\C-e] . [end])
+ ([?\C-j] . [S-return])
+ ([?\C-m] . [return])
+ ([?\M-v] . [prior])
+ ([?\C-v] . [next])
+ ([?\C-d] . [delete])
+ ([?\C-k] . [S-end delete])
+ ([?\M-w] . [C-c])
+ ([?\C-y] . [C-v])
+ ([?\C-s] . [C-g])
+ ([?\C-r] . [C-S-g])
+ ([?\M-d] . [C-delete])
+ ([?\M-b] . [C-left])
+ ([?\M-f] . [C-right]))))
+
+(use-package exwm-outer-gaps
+ :defer 1
+ :config
+ (setopt exwm-outer-gaps-mode 1
+ exwm-outer-gaps-width 10)
+ (exwm-outer-gaps-apply))
+
+(use-package server
+ :defer 1
+ :config
+ (setopt server-client-instructions nil)
+ (unless (server-running-p)
+ (server-start)))
+
+(setopt tab-bar-select-tab-modifiers '(super))
+
+(provide 'bd--exwm)
+;;; bd--exwm.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--files.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--files.el
new file mode 100644
index 0000000..c2f3df8
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--files.el
@@ -0,0 +1,92 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(use-package files
+ :config
+ (setopt safe-local-variable-directories
+ '("/home/bdunahu/pt/guix")))
+
+(use-package recentf
+ :demand t
+ :bind
+ (("C-x g" . recentf-open))
+ :init
+ (recentf-mode 1)
+ :config
+ (setopt recentf-max-saved-items 3500
+ recentf-auto-cleanup 300))
+
+(defun bd/zathura (file)
+ "Open FILE with zathura."
+ (start-process "zathura" nil "zathura" (expand-file-name file)))
+(defun bd/mpv (file)
+ "Open FILE with mpv."
+ (start-process "mpv" nil "mpv" "--force-window=yes" (expand-file-name file)))
+(defun bd/info (file)
+ "Open FILE with info."
+ (info file))
+(defun bd/nsxiv (file)
+ "Open FILE with nsxiv."
+ (start-process "nsxiv" nil "nsxiv" (expand-file-name file)))
+(defun bd/qemu (file)
+ "Open FILE with QEMU."
+ (let ((options `("qemu-system" nil "qemu-system-x86_64" ,(expand-file-name file)
+ "-net" "nic" "-net""user,hostfwd=tcp:127.0.0.1:2222-:22"
+ "--accel" "kvm" "-m" "8G")))
+ (unless (string-match-p "graphic" file)
+ (setq options (append options (list "-nographic"))))
+ (apply 'start-process options)))
+(defun bd/rom (file)
+ "Open FILE with an emulator."
+ (let ((command
+ (cdr (assoc (file-name-extension file)
+ '(("gba" . "mgba")
+ ("z64" . "mupen64plus")
+ ("iso" . "dolphin-emu")
+ ("ciso" . "dolphin-emu")
+ ("n64" . "mupen64plus")
+ ("sfc" . "bsnes"))))))
+ (start-process command nil command (expand-file-name file))))
+
+(defun bd/external-find-file-wrapper (f &rest args)
+ "Wrapper around F (find-file), passing ARGS."
+ (defun bd/open-with-function (f)
+ (funcall f (car args))
+ (recentf-add-file (car args)))
+
+ (let ((ext (or (file-name-extension (car args)) "")))
+ (cond
+ ((string-match (regexp-opt '("epub" "pdf")) ext)
+ (bd/open-with-function #'bd/zathura))
+ ((string-match (regexp-opt '("mkv" "mov" "mp4" "webm" "m4v"
+ "wav" "mp3" "opus" "ogv" "flac"
+ "m4a" "ogg")) ext)
+ (bd/open-with-function #'bd/mpv))
+ ((string-match (regexp-opt '("info")) ext)
+ (bd/open-with-function #'bd/info))
+ ((string-match (regexp-opt '("jpg" "jpeg" "png" "webp"
+ "ico" "gif" "JPG" "PNG")) ext)
+ (bd/open-with-function #'bd/nsxiv))
+ ((string-match (regexp-opt '("qcow2")) ext)
+ (bd/open-with-function #'bd/qemu))
+ ((string-match (regexp-opt '("gba" "z64" "n64" "sfc" "iso" "ciso")) ext)
+ (bd/open-with-function #'bd/rom))
+ (t (apply f args)))))
+(advice-add #'find-file :around #'bd/external-find-file-wrapper)
+
+(use-package dired
+ :demand t
+ :config
+ (setopt dired-listing-switches "-alhLG --time-style=long-iso --group-directories-first"
+ dired-recursive-copies 'always
+ dired-recursive-deletes 'always
+ dired-auto-revert-buffer t
+ dired-dwim-target t
+ dired-guess-shell-alist-user
+ `((,(regexp-opt '(".pdf")) "pdftotext -nopgbrk -enc UTF-8 -eol unix -layout"))))
+
+
+(provide 'bd--files)
+;;; bd--files.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--gpg.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--gpg.el
new file mode 100644
index 0000000..88d9425
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--gpg.el
@@ -0,0 +1,59 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(defvar bd/password-store-kill-ring-pointer nil
+ "The tail of the kill ring whose car is the password.")
+(defvar bd/password-store-time-before-clear 10
+ "The time before a killed password is cleared.")
+
+(defun bd/password-store-list ()
+ "List password-store entries."
+ (mapcar (lambda (file)
+ (file-name-sans-extension (file-relative-name file "~/.password-store/")))
+ (directory-files-recursively "~/.password-store" ".*\\.gpg$")))
+
+(defun bd/password-store-clear (id)
+ "Clears the most recent password copied to the kill ring, printing ID."
+ (when bd/password-store-kill-ring-pointer
+ (setcar bd/password-store-kill-ring-pointer nil)
+ (kill-new "")
+ (setq bd/password-store-kill-ring-pointer nil)
+ (message "Cleared password for %s from the kill ring and system clipboard." id)))
+
+(defun bd/read-password (id)
+ "Read the password-store entry corresponding to ID."
+ (bd/password-store-clear "id")
+ (let ((find-file-hook (remq 'recentf-track-opened-file find-file-hook)))
+ (find-file (concat "~/.password-store/" id ".gpg"))
+ (goto-char 1)
+ (kill-new (buffer-substring-no-properties (line-beginning-position) (line-end-position)))
+ (setq bd/password-store-kill-ring-pointer kill-ring-yank-pointer)
+ (kill-buffer (current-buffer))
+ (run-at-time bd/password-store-time-before-clear nil
+ (lambda () (funcall #'bd/password-store-clear id)))
+ (message "Copied password for %s to the kill ring and system clipboard. Will clear in %s seconds."
+ id bd/password-store-time-before-clear)))
+
+(defun bd/password ()
+ "Interactively select a password-store password."
+ (interactive)
+ (bd/read-password (completing-read "Yank: " (bd/password-store-list))))
+
+(use-package pinentry
+ :defer 1
+ :config
+ (pinentry-start)
+ (defun pinentry-toggle ()
+ "Stops and starts Pinentry service. Workaround
+for a bug I've encountered."
+ (interactive)
+ (pinentry-stop)
+ (pinentry-start))
+ (setopt enable-recursive-minibuffers t
+ pinentry-popup-prompt-window nil))
+
+
+(provide 'bd--gpg)
+;;; bd--gpg.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--image.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--image.el
new file mode 100644
index 0000000..1d5876c
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--image.el
@@ -0,0 +1,22 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; not loaded bd 10/28/24
+;;; Code:
+
+
+(use-package image-mode
+ :config
+ (defun toggle-mode-line ()
+ "If the mode line is displayed, toggle it off.
+If the mode line is off, set it to the default value."
+ (interactive)
+ (setq mode-line-format
+ (if mode-line-format
+ nil
+ (default-value 'mode-line-format))))
+ (add-hook 'image-mode-hook 'toggle-mode-line)
+ (keymap-set image-mode-map "l" #'toggle-mode-line))
+
+
+(provide 'bd--image)
+;;; bd--image.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--minibuffer.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--minibuffer.el
new file mode 100644
index 0000000..cf5641b
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--minibuffer.el
@@ -0,0 +1,171 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(require 's)
+(use-package icomplete
+ :demand t
+ :bind
+ ((:map icomplete-minibuffer-map
+ ("RET" . icomplete-force-complete-and-exit)))
+ :config
+ (setopt completing-read-function #'completing-read-default
+ read-file-name-function #'read-file-name-default
+ completion-styles '(basic
+ substring
+ initials
+ flex)
+ icomplete-delay-completions-threshold 0
+ icomplete-compute-delay 0.10
+ icomplete-show-matches-on-no-input nil
+ icomplete-separator " | "
+ completions-max-height '30
+ completions-detailed t)
+ (icomplete-vertical-mode t))
+
+(use-package completion-preview
+ :hook
+ ((comint-mode . completion-preview-mode)
+ (c-mode . completion-preview-mode)
+ (c++-mode . completion-preview-mode)
+ (emacs-lisp-mode . completion-preview-mode)))
+
+(use-package selector
+ :demand t
+ :config
+ (setopt selector-minibuffer-lines 15)
+ (defvar bd/navigate-recent-display-number 6
+ "The number of recent buffers that show up in bd/navigate.")
+ (defvar bd/blacklisted-buffer-regexp-list
+ '(
+ "\\*Async Shell Command\\*"
+ "\\*http"
+ "\\magit-process"
+ "\\*Minibuf"
+ "\\*Echo Area"
+ "\\*newsticker"
+ "\\*Org Preview LaTeX Output\\*"
+ "\\*Shell Command Output\\*"
+ "\\*tramp"
+ "\\*eldoc"
+ "\\*server\\*"
+ )
+ "Buffers that should not show up in buffer-related
+selection commands.")
+
+ (defun bd/buffer-blacklisted-p (buf)
+ "Return non-nil if BUF is blacklisted."
+ (cl-reduce (lambda (x y) (or x y)) (mapcar (lambda (r) (string-match r buf))
+ bd/blacklisted-buffer-regexp-list)))
+
+ (defun bd/buffer-list ()
+ "Return a list of non-blacklisted buffers."
+ (cl-remove-if #'bd/buffer-blacklisted-p (mapcar 'buffer-name (buffer-list))))
+
+ (defun bd/selector-recent-buffers ()
+ (selector-source-create
+ "Recent"
+ :candidates
+ (take bd/navigate-recent-display-number
+ (cl-remove-if (lambda (b)
+ (get-buffer-window b 'visible))
+ (bd/buffer-list)))
+ :actions
+ selector-buffer-actions))
+
+ (defun bd/selector-project-files ()
+ (selector-source-create
+ "Project Files"
+ :candidates
+ (let ((proj (project-current)))
+ (when proj
+ (project-files proj)))
+ :actions
+ selector-file-actions))
+
+ (defmacro bd/selector-buffer-type (name c)
+ `(selector-source-create
+ ,name
+ :candidates
+ (cl-remove-if-not ,c (bd/buffer-list))
+ :actions
+ selector-buffer-actions))
+
+ (defun bd/navigate ()
+ (interactive)
+ (selector
+ (list
+ (bd/selector-recent-buffers)
+ (bd/selector-buffer-type "EWW" #'bd/buffer-eww-p)
+ (bd/selector-buffer-type "EXWM" #'bd/buffer-exwm-p)
+ (bd/selector-buffer-type "Shell" #'bd/buffer-shell-p)
+ (bd/selector-buffer-type "IRC" #'bd/buffer-irc-p)
+ (bd/selector-buffer-type "Text" #'bd/buffer-text-p)
+ (bd/selector-buffer-type "Source" #'bd/buffer-prog-p)
+ (bd/selector-buffer-type "Scratch" #'bd/buffer-scratch-p)
+ (bd/selector-buffer-type "Directories" #'bd/buffer-dired-p)
+ (bd/selector-buffer-type "Ordinary" #'bd/buffer-ordinary-p)
+ (bd/selector-project-files)
+ (selector-recentf-source))))
+ (keymap-global-set "C-x b" 'bd/navigate)
+
+ (defun bd/selector-rg ()
+ "Sources for lines found via grep (or a clone)."
+ (interactive)
+ (let ((query (read-string "rg: ")))
+ (defun conv (x)
+ (cons (car x) (cons (- (string-to-number (cadr x)) 1) (caddr x))))
+ (defun all-in-file (key list)
+ (--map (to-candidate (cdr it)) (--filter (s-equals? key (car it)) list)))
+ (defun to-candidate (x)
+ (selector-candidate-create (cdr x) :value (car x)))
+ (let* ((dir (expand-file-name (bd/get-directory-dwim)))
+ (result (with-temp-buffer
+ (call-process "rg" nil t nil "-n" "-." query dir)
+ (buffer-string)))
+ (lines (--map (conv (s-split-up-to ":" it 2)) (--filter (not (s-blank? it)) (s-split "\n" result))))
+ (files (-uniq (-map #'car lines)))
+ (sources (--map (selector-source-create
+ it
+ :candidates (all-in-file it lines)
+ :actions (selector-file-contents-actions it))
+ files)))
+ (when (not (null sources))
+ (selector sources)))))
+ (keymap-global-set "C-z s" 'bd/selector-rg)
+ (keymap-global-set "C-z d" 'bd/selector-occur))
+
+(defun bd/selector-occur ()
+ "Sources for lines in the current file."
+ (interactive)
+ (when-let ((file (buffer-file-name)))
+ (selector (list (selector-file-contents-source file)))))
+
+(defun bd/selector-rg ()
+ "Sources for lines found via grep (or a clone)."
+ (interactive)
+ (let ((query (read-string "rg: ")))
+ (defun conv (x)
+ (cons (car x) (cons (- (string-to-number (cadr x)) 1) (caddr x))))
+ (defun all-in-file (key list)
+ (--map (to-candidate (cdr it)) (--filter (s-equals? key (car it)) list)))
+ (defun to-candidate (x)
+ (selector-candidate-create (cdr x) :value (car x)))
+ (let* ((dir (expand-file-name (bd/get-directory-dwim)))
+ (result (with-temp-buffer
+ (call-process "rg" nil t nil "-n" "-." query dir)
+ (buffer-string)))
+ (lines (--map (conv (s-split-up-to ":" it 2)) (--filter (not (s-blank? it)) (s-split "\n" result))))
+ (files (-uniq (-map #'car lines)))
+ (sources (--map (selector-source-create
+ it
+ :candidates (all-in-file it lines)
+ :actions (selector-file-contents-actions it))
+ files)))
+ (when (not (null sources))
+ (selector sources)))))
+
+
+(provide 'bd--minibuffer)
+;;; bd--minibuffer.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--modeline.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--modeline.el
new file mode 100644
index 0000000..2ca7ccb
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--modeline.el
@@ -0,0 +1,99 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+;;;; remove all the stupid stupid stupid crap
+(define-minor-mode minor-mode-blackout-mode
+ "Hides minor modes from the mode line."
+ t)
+
+(catch 'done
+ (mapc (lambda (x)
+ (when (and (consp x)
+ (equal (cadr x) '("" minor-mode-alist)))
+ (let ((original (copy-sequence x)))
+ (setcar x 'minor-mode-blackout-mode)
+ (setcdr x (list "" original)))
+ (throw 'done t)))
+ mode-line-modes))
+(global-set-key (kbd "C-c ,") 'minor-mode-blackout-mode)
+
+(defvar-local bd/buffer-identification-mode-line
+ '(:eval (format "%s" (propertize (buffer-name) 'face
+ (if (mode-line-window-selected-p)
+ 'modus-themes-fg-cyan-intense
+ 'mode-line-inactive))))
+ "Formats the modeline-buffer-name.")
+
+(defvar-local bd/project-mode-line
+ '(:eval
+ (when-let ((project (project-current))
+ (file? (buffer-file-name)))
+ (let ((last-coding-system-used last-coding-system-used))
+ (format "%s "
+ (propertize
+ (project-name project)
+ 'face 'shadow
+ 'mouse-face 'mode-line-highlight
+ 'help-echo "mouse-1: Project menu"
+ 'local-map project-mode-line-map))))))
+
+(defvar-local bd/global-mode-string
+ '(:eval (when (mode-line-window-selected-p)
+ global-mode-string))
+ "Displays the global mode string only on the current window.")
+
+(column-number-mode 1)
+(setopt mode-line-position-column-line-format '("%l:%c")
+ mode-line-percent-position nil)
+(defvar-local bd/line-position
+ '(:eval
+ (when (mode-line-window-selected-p)
+ mode-line-position)))
+
+(defvar-local bd/vc-mode-line
+ '(:eval (when vc-mode
+ (format "%s "
+ (propertize (cadr (split-string vc-mode "[:-]")) 'face 'shadow))))
+ "Formats the checked out git repository.")
+
+(defvar-local bd/modeline-window-dedicated
+ '(:eval
+ (when (window-dedicated-p)
+ (format "%s -- "
+ (propertize "LK" 'face 'font-lock-comment-face))))
+ "Indicator for dedicated window.")
+
+(dolist (construct '(bd/buffer-identification-mode-line
+ bd/project-mode-line
+ bd/vc-mode-line
+ bd/global-mode-string
+ bd/line-position
+ bd/modeline-window-dedicated))
+ (put construct 'risky-local-variable t))
+
+
+(setopt mode-line-right-align-edge 'window)
+(setq-default mode-line-format
+ '("%e"
+ mode-line-front-space
+ bd/project-mode-line
+ bd/buffer-identification-mode-line
+ " -- "
+ mode-line-modes
+ "-- "
+ bd/line-position
+ mode-line-format-right-align
+ bd/modeline-window-dedicated
+ bd/vc-mode-line
+ mode-line-mule-info
+ mode-line-modified
+ mode-line-front-space
+ bd/global-mode-string
+ mode-line-front-space
+ ))
+
+
+(provide 'bd--modeline)
+;;; bd--modeline.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--notes.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--notes.el
new file mode 100644
index 0000000..13f80f4
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--notes.el
@@ -0,0 +1,77 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(defvar scratch-buffer nil
+ "Non-nil if the current buffer is a scratch buffer.")
+(make-variable-buffer-local 'scratch-buffer)
+(defun bd/send-to-scratch ()
+ "Creates/switches to the scratch for `major-mode',
+then pastes the active region."
+ (interactive)
+ (let* ((mode major-mode)
+ (name (format "*scratch for %s*" mode))
+ (contents (when (region-active-p)
+ (buffer-substring-no-properties
+ (region-beginning) (region-end))))
+ (buf (get-buffer name)))
+ (pop-to-buffer
+ (with-current-buffer (get-buffer-create name)
+ (funcall mode)
+ (setq-local scratch-buffer t)
+ (when contents
+ (insert (format "\n\n%s" contents)))
+ (current-buffer)))))
+(keymap-global-set "C-c s" #'scratch-buffer)
+(keymap-global-set "C-c C-s" #'bd/send-to-scratch)
+;; default *scratch* must have var set
+(add-hook 'emacs-startup-hook
+ (lambda ()
+ (with-current-buffer "*scratch*"
+ (setq-local scratch-buffer t))))
+(advice-add 'scratch-buffer :after (lambda () (setq-local scratch-buffer t)))
+
+(use-package denote
+ :defer 1
+ :hook
+ ((dired-mode . denote-dired-mode-in-directories))
+ :bind (("C-c d d" . 'denote)
+ ("C-c d f" . 'denote-open-or-create)
+ :map org-mode-map
+ ("C-c l" . 'denote-link))
+ :config
+
+ (defconst bd/denote-skribe-front-matter
+ "(post
+ :title \"%s\"
+ :date %s
+ :tags '(\"%s\")
+ ;; identifier: %s
+\n\n)")
+ (defun bd/denote-skribe-format-date (date)
+ "Format DATE as a scheme procedure."
+ (format-time-string "(make-date* %Y %m %d %H %M)" date))
+ (defun bd/denote-format-keywords-for-skribe-front-matter (keywords)
+ "Format front matter KEYWORDS for skribe file type.
+KEYWORDS is a list of strings."
+ (string-join keywords "\" \""))
+ :config
+ (setopt denote-file-type 'org
+ denote-known-keywords
+ '("ss" "writing" "reading" "art"
+ "csu" "umass" "cs" "guix"
+ "emacs" "programs" "mem")
+ denote-directory (expand-file-name "~/dc/")
+ denote-prompts '(title file-type keywords subdirectory)
+ denote-dired-directories (list denote-directory)))
+
+(use-package denote-journal
+ :bind (("C-c d j" . 'denote-journal-new-or-existing-entry))
+ :config
+ (setopt denote-journal-directory (expand-file-name "~/dc/log")
+ denote-journal-title-format 'day-date-month-year))
+
+
+(provide 'bd--notes)
+;;; bd--notes.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--org.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--org.el
new file mode 100644
index 0000000..b88a72b
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--org.el
@@ -0,0 +1,255 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(require 'fill-column)
+(use-package org
+ :demand t
+ :hook
+ ((org-mode . (lambda ()
+ (org-indent-mode)
+ (org-toggle-inline-images)
+ (fill-column-mode)
+ (abbrev-mode)
+ (org-latex-preview '(16)))))
+ :config
+ (setopt org-ellipsis " ▾"
+ org-babel-python-command "python3"
+ org-confirm-babel-evaluate nil
+ org-hide-emphasis-markers t
+ org-startup-folded 'showeverything
+ org-src-window-setup 'current-window)
+ (plist-put org-format-latex-options :scale 1.3)
+ (push '("\\.pdf\\'" . "zathura %s") org-file-apps)
+ (add-hook 'org-babel-after-execute-hook #'org-redisplay-inline-images)
+ (org-babel-do-load-languages
+ 'org-babel-load-languages
+ '((emacs-lisp . t)
+ (shell . t)
+ (lisp . t)
+ (scheme . t)
+ (dot . t)
+ (latex . t)
+ (python . t)))
+ (define-abbrev org-mode-abbrev-table
+ "lbm" "\\begin{equation*}\n\\begin{bmatrix}\n\\end{bmatrix}\n\\end{equation*}")
+ (define-abbrev org-mode-abbrev-table
+ "lca" "\\begin{equation*}\n\\begin{cases}\n\\end{cases}\n\\end{equation*}")
+ (define-abbrev org-mode-abbrev-table
+ "gvd" "#+begin_src dot :file images/1.png\ndigraph g {\nrankdir=LR;\n\tnode [shape = doublecircle]; A;\n\tnode [shape = point]; qi\n\tnode[shape=circle];\n}\n#+end_src")
+ (define-abbrev org-mode-abbrev-table
+ "les" "\\begin{equation*}\n\\end{equation*}")
+ (define-abbrev org-mode-abbrev-table
+ "lbm" "\\begin{equation*}\n\\begin{bmatrix}\n\\end{bmatrix}\n\\end{equation*}")
+ (define-abbrev org-mode-abbrev-table
+ "lds" "\\begin{drawstack}\n\\end{drawstack}"))
+
+(use-package ox
+ :config
+ (add-to-list 'org-latex-packages-alist '("" "listings"))
+ (setopt org-latex-toc-command "\\tableofcontents \\clearpage"
+ org-latex-src-block-backend 'listings
+ org-latex-image-default-width ".6\\linewidth"
+ org-latex-compiler "xelatex"
+ org-export-with-toc nil
+ org-export-preserve-breaks nil
+ org-latex-classes
+ '(("article"
+ "\\PassOptionsToPackage{svgnames}{xcolor}
+\\documentclass[11pt]{article}
+\\usepackage[margin=1in]{geometry}
+\\usepackage{xcolor,color,tikz,amsmath,amssymb,amsthm,amsfonts,graphicx,enumitem,listings,comment}
+\\lstset{frame=single,aboveskip=1em,
+ framesep=.5em,backgroundcolor=\\color{AliceBlue},
+ rulecolor=\\color{Black},framerule=1pt}
+\\usepackage{xcolor}
+\\newcommand\\basicdefault[1]{\\scriptsize\\color{Black}\\fontfamily{pcr}\\selectfont}
+\\lstset{basicstyle=\\basicdefault{\\spaceskip1em}}
+\\lstset{keywordstyle=\\color{DarkGreen}\\bfseries,
+ identifierstyle=\\color{DarkRed},
+ commentstyle=\\color{DimGray}\\upshape,
+ stringstyle=\\color{DarkBlue}\\upshape,
+ emphstyle=\\color{Chocolate}\\upshape,
+ showstringspaces=false,
+ columns=fullflexible,
+ keepspaces=true}
+\\lstset{columns=fullflexible,basicstyle=\\ttfamily}
+\\setlength{\\headsep}{0.75 in}
+\\setlength{\\parskip}{0.1 in}
+
+\\makeatletter
+\\renewcommand{\\maketitle}{%
+ \\begingroup\\parindent0pt
+ \\begin{center}
+ \\LARGE{\\bfseries\\@title}\\par\\bigskip
+ \\large{\\@author}\\par\\medskip
+ \\normalsize\\@date\\par\\bigskip
+ \\end{center}
+ \\endgroup\\@afterindentfalse\\@afterheading}
+\\makeatother
+[DEFAULT-PACKAGES]
+\\hypersetup{linkcolor=Blue,urlcolor=DarkBlue,
+ citecolor=DarkRed,colorlinks=true}
+[PACKAGES]
+[EXTRA]"
+ ("\\section{%s}" . "\\section*{%s}")
+ ("\\subsection{%s}" . "\\subsection*{%s}")
+ ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
+ ("\\paragraph{%s}" . "\\paragraph*{%s}")
+ ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
+ ("report" "\\documentclass[11pt]{report}"
+ ("\\part{%s}" . "\\part*{%s}") ("\\chapter{%s}" . "\\chapter*{%s}")
+ ("\\section{%s}" . "\\section*{%s}")
+ ("\\subsection{%s}" . "\\subsection*{%s}")
+ ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))
+ ("acmart" "\\PassOptionsToPackage{svgnames}{xcolor}
+\\documentclass[sigconf,authorversion,nonacm]{acmart}
+\\usepackage{xcolor,color,tikz,amsmath,amssymb,amsthm,amsfonts,graphicx,enumitem,listings,comment}
+\\usepackage{xcolor}
+\\lstset{frame=single,aboveskip=1em,
+ framesep=.5em,backgroundcolor=\\color{AliceBlue},
+ rulecolor=\\color{Black},framerule=1pt}
+\\lstset{keywordstyle=\\color{DarkGreen}\\bfseries,
+ identifierstyle=\\color{DarkRed},
+ commentstyle=\\color{DimGray}\\upshape,
+ stringstyle=\\color{DarkBlue}\\upshape,
+ emphstyle=\\color{Chocolate}\\upshape,
+ showstringspaces=false,
+ columns=fullflexible,
+ keepspaces=true}"
+ ("\\section{%s}" . "\\section*{%s}")
+ ("\\subsection{%s}" . "\\subsection*{%s}")
+ ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
+ ("\\paragraph{%s}" . "\\paragraph*{%s}")
+ ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
+ ("book" "\\documentclass[11pt]{book}" ("\\part{%s}" . "\\part*{%s}")
+ ("\\chapter{%s}" . "\\chapter*{%s}")
+ ("\\section{%s}" . "\\section*{%s}")
+ ("\\subsection{%s}" . "\\subsection*{%s}")
+ ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))))
+
+(use-package oc
+ :config
+ (setopt org-cite-global-bibliography
+ (directory-files-recursively
+ (concat (xdg-user-dir "DOCUMENTS") "/bib/")
+ ".*\\.bib$")
+ org-cite-export-processors
+ '((latex biblatex))))
+
+(use-package org-agenda
+ :bind
+ (("C-c n a" . org-agenda)
+ ("C-c n c" . org-capture)
+ ("C-c n s" . org-schedule)
+ ("C-c n d" . org-deadline)
+ ("C-c n r" . org-refile))
+ :config
+ (advice-add 'org-refile :after 'org-save-all-org-buffers)
+
+ (defvar-local bd/course-list
+ '(("598" . ?0))
+ "Courses for tagging, capturing, and various
+agenda views.")
+
+ (defvar-local bd/device-list
+ '(("garmr" . ?G)
+ ("heimdallr" . ?H)
+ ("hodr" . ?M)
+ ("surt" . ?I)
+ ("vali" . ?V))
+ "Devices for tagging, capturing, and various
+agenda views.")
+
+ (defun bd/combine-tags (tag-alist add? or-p)
+ "Given TAG-ALIST in the form of
+ORG-TAG-ALIST, returns a concatenated string
+representing all the tags ORd or ANDed together."
+ (apply #'concat
+ (mapcar (lambda (e)
+ (concat (when or-p "|") (if add? "+" "-") (car e)))
+ tag-alist)))
+
+ (setopt org-log-done 'time
+ org-deadline-warning-days 7
+ org-log-into-drawer "history"
+ org-agenda-restore-windows-after-quit t
+ org-agenda-show-future-repeats nil
+ org-agenda-block-separator nil
+ org-deadline-warning-days 0
+ org-todo-keywords
+ '((sequence "TODO(t)" "NEXT(n!)" "HOLD(h!)" "|" "DONE(d)" "CANC(c)"))
+ org-tag-alist
+ `(("noexport" . ?e)
+
+ ("chore" . ?C)
+ ,@bd/device-list
+
+ ("idea" . ?i)
+ ("programming" . ?p)
+ ("web" . ?s)
+ ("writing" . ?w)
+ ("reading" . ?r)
+
+ ,@bd/course-list)
+ org-directory "~/dc/agenda/"
+
+ org-agenda-files (list org-directory)
+ org-refile-use-outline-path 'file
+ org-refile-targets '((org-agenda-files :level . 0))
+ org-capture-templates
+ `(("t" "Task Entry" entry
+ (file ,(concat org-directory "inbox.org"))
+ "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n%i\nrecorded visiting: %a"
+ :empty-lines 1)))
+
+ (let ((orphan-view '(tags-todo "-{.*}"
+ ((org-agenda-overriding-header "\nUnfiltered Items\n")))))
+ (setopt org-agenda-custom-commands
+ `(("c" "Chores"
+ ((agenda "" ((org-agenda-entry-types '(:deadline))
+ (org-agenda-show-all-dates nil)
+ (org-agenda-span 21)
+ (org-agenda-skip-function
+ '(org-agenda-skip-entry-if 'notregexp
+ (regexp-opt (cons "chore" (mapcar #'car bd/device-list)))))
+ (org-agenda-overriding-header "Priority Deadlines (+21d)\n")))
+ (tags-todo (concat "chore" (bd/combine-tags bd/device-list nil nil))
+ ((org-agenda-overriding-header "\nMundane\n")))
+ ,@(mapcar (lambda (e)
+ `(tags-todo ,(car e)
+ ((org-agenda-overriding-header
+ (concat "\nDevice: " ,(capitalize (car e)) "\n")))))
+ bd/device-list)
+ ,orphan-view))
+ ("r" "Recreational"
+ ((tags-todo "+idea"
+ ((org-agenda-skip-function
+ '(org-agenda-skip-entry-if 'regexp "chore"))
+ (org-agenda-overriding-header "Ideas\n")))
+ (tags-todo "+reading|+writing"
+ ((org-agenda-skip-function
+ '(org-agenda-skip-entry-if 'regexp "chore"))
+ (org-agenda-overriding-header "\nReading/Writing\n")))
+ (tags-todo "+programming|+web"
+ ((org-agenda-skip-function
+ '(org-agenda-skip-entry-if 'regexp "chore"))
+ (org-agenda-overriding-header "\nProgramming\n")))
+ ,orphan-view))
+ ("s" "College"
+ ((tags-todo (bd/combine-tags bd/course-list t t)
+ ((org-agenda-overriding-header "\nAll Courses\n")))
+ (agenda "" ((org-agenda-entry-types '(:deadline :scheduled))
+ (org-agenda-show-all-dates nil)
+ (org-agenda-span 15)
+ (org-scheduled-past-days 7)
+ (org-agenda-skip-function
+ '(org-agenda-skip-entry-if 'notregexp
+ (regexp-opt (mapcar #'car bd/course-list))))
+ (org-agenda-overriding-header "\nUpcoming Deadlines (+15d)\n")))
+ ,orphan-view))))))
+
+
+(provide 'bd--org)
+;;; bd--org.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--project.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--project.el
new file mode 100644
index 0000000..243e3cd
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--project.el
@@ -0,0 +1,18 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(use-package project
+ :defer t
+ :config
+ (setopt project-switch-commands
+ '((project-find-file "Find file")
+ (project-find-regexp "Find regexp")
+ (project-find-dir "Find directory")
+ (magit-project-status "Magit")
+ (project-shell "Shell"))))
+
+
+(provide 'bd--project)
+;;; bd--project.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--shells.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--shells.el
new file mode 100644
index 0000000..1072694
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--shells.el
@@ -0,0 +1,135 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(add-to-list 'exec-path "/home/bdunahu/.local/bin")
+
+(use-package vterm
+ :config
+ (with-eval-after-load "term" (defalias 'term 'vterm))
+ ;; use vterm for visual visual commands
+ (defun bd/eshell-exec-visual (&rest args)
+ "Run the specified PROGRAM in a vterm emulation buffer.
+ARGS are passed to the program. At the moment, no piping of input is
+allowed."
+ (let* (eshell-interpreter-alist
+ (interp (eshell-find-interpreter (car args) (cdr args)))
+ (program (car interp))
+ (args (mapconcat #'shell-quote-argument
+ (flatten-tree
+ (eshell-stringify-list (append (cdr interp)
+ (cdr args)))) " "))
+ (term-buf
+ (generate-new-buffer
+ (concat "*" (file-name-nondirectory program) "*")))
+ (eshell-buf (current-buffer))
+ (vterm-shell (concat (shell-quote-argument
+ (file-local-name program))
+ " " args)))
+ (save-current-buffer
+ (switch-to-buffer term-buf)
+ (vterm-mode)
+ (setq-local eshell-parent-buffer eshell-buf)
+ (let ((proc (get-buffer-process term-buf)))
+ (if (and proc (eq 'run (process-status proc)))
+ (set-process-sentinel proc #'eshell-term-sentinel)
+ (error "Failed to invoke visual command")))))
+ nil)
+ (advice-add #'eshell-exec-visual :override #'bd/eshell-exec-visual))
+
+(use-package esh-module
+ :config
+ (add-to-list 'eshell-modules-list 'eshell-smart))
+
+(use-package esh-mode
+ :config
+ (setopt eshell-scroll-to-bottom-on-input 'this))
+
+(use-package em-banner
+ :config
+ (setopt eshell-banner-message (concat "\n" (propertize " " 'display (create-image (expand-file-name "images/wolf.png" user-emacs-directory) 'png nil :scale 0.8 :align-to "center")) "\n")))
+
+(use-package em-hist
+ :config
+ (setopt eshell-hist-ignoredups t
+ eshell-history-append t))
+
+(use-package em-term
+ :config
+ (mapc (lambda (x) (add-to-list 'eshell-visual-commands x))
+ '(
+ "angband"
+ "nethack"
+ "r2"
+ ))
+ (setopt eshell-destroy-buffer-when-process-dies t))
+
+(use-package em-unix
+ :config
+ (setopt eshell-cp-overwrite-files nil
+ eshell-mv-overwrite-files nil))
+
+(use-package em-prompt
+ :config
+ (defun bd/get-prompt-path ()
+ (abbreviate-file-name (eshell/pwd)))
+ (defun bd/eshell-prompt ()
+ "Return a prettified shell prompt."
+ (concat
+ (system-name)
+ (format " %s" (bd/get-prompt-path))
+ " >\n"))
+ (setopt eshell-prompt-function 'bd/eshell-prompt
+ eshell-prompt-regexp (rx bol (eval (system-name)) (one-or-more anything) " >\n")))
+
+(use-package eshell
+ :bind
+ (:map eshell-mode-map
+ ("<tab>" . #'completion-at-point))
+ :config
+ (defun eshell/clear (&optional scrollback)
+ "Clear the eshell buffer and output the banner message."
+ (interactive)
+ (let ((inhibit-read-only t))
+ (delete-all-overlays)
+ (set-text-properties (point-min) (point-max) nil)
+ (erase-buffer)
+ (eval eshell-banner-message)))
+ (defun eshell/c (&optional scrollback)
+ (eshell/clear scrollback))
+ (defun eshell/o (file)
+ (interactive)
+ (find-file file))
+ (setopt eshell-buffer-maximum-lines 7500))
+
+
+(use-package shell
+ :bind
+ (:map shell-mode-map
+ ("C-c C-k" . #'comint-clear-buffer))
+ :config
+ (setopt shell-command-prompt-show-cwd t
+ shell-highlight-undef-enable t
+ shell-kill-buffer-on-exit t
+ comint-prompt-read-only t))
+
+
+(use-package proced
+ :defer t
+ :hook (proced-mode .
+ (lambda ()
+ (visual-line-mode -1)
+ (toggle-truncate-lines 1)
+ (proced-toggle-auto-update 1)))
+ :config
+ (setopt proced-enable-color-flag t
+ proced-tree-flag t
+ proced-auto-update-flag 'visible
+ proced-auto-update-interval 3
+ proced-descend t
+ proced-filter 'user))
+
+
+(provide 'bd--shells)
+;;; bd--shells.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--tabs.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--tabs.el
new file mode 100644
index 0000000..6d4f12f
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--tabs.el
@@ -0,0 +1,43 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(use-package tab-bar
+ :demand t
+ :config
+ (defun bd/get-mode-line-modes (buffer)
+ (with-current-buffer buffer
+ (format-mode-line (remove '(t erc-modified-channels-object) mode-line-modes))))
+ (defun bd/tab-bar-name-function ()
+ (concat (tab-bar-tab-name-current)
+ " "
+ (bd/get-mode-line-modes (window-buffer (minibuffer-selected-window)))))
+ (defun bd/toggle-tab-bar ()
+ (interactive)
+ (setopt tab-bar-show (not tab-bar-show))
+ ;; required to wait for the frame to update
+ (sit-for 0)
+ ;; dumb outer-gaps bug
+ (exwm-outer-gaps-apply))
+
+ (tab-bar-select-tab 1)
+ (tab-bar-mode)
+ (tab-bar-history-mode)
+ (setopt tab-bar-tab-name-function #'bd/tab-bar-name-function
+ tab-bar-show t
+
+ tab-bar-select-restore-windows nil
+
+ ;; remove useless gui elements
+ tab-bar-format
+ '(tab-bar-format-tabs)
+ tab-bar-close-button-show nil
+ tab-bar-auto-width-max nil
+
+ ;; add useless text elements
+ tab-bar-tab-hints nil))
+
+
+(provide 'bd--tabs)
+;;; bd--tabs.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--themes.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--themes.el
new file mode 100644
index 0000000..cd24cab
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--themes.el
@@ -0,0 +1,115 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(use-package modus-themes
+ :load-path (lambda () (expand-file-name "themes/" data-directory))
+ :demand t
+ :init
+ (load-theme 'modus-vivendi-tinted t)
+ :hook
+ ((modus-themes-post-load . bd/modus-set-faces))
+ :config
+ (defun bd/modus-set-faces (&rest _)
+ "Blends the modeline with the echo area,
+and some other minor face changes."
+ (modus-themes-with-colors
+ (custom-set-faces
+ `(eshell-prompt ((,c :foreground ,fg-main :background ,bg-prose-block-contents :height 1.1 :extend t))))))
+ (setopt modus-themes-to-toggle '(modus-operandi-tinted modus-vivendi-tinted)
+ modus-themes-mixed-fonts t
+ modus-themes-italic-constructs t
+ modus-themes-bold-constructs t
+ modus-themes-variable-pitch-ui t
+ modus-themes-prompts '(bold)
+ modus-themes-headings
+ '((0 variable-pitch regular 1.4)
+ (1 variable-pitch regular 1.4)
+ (2 variable-pitch regular 1.3)
+ (3 variable-pitch regular 1.2)
+ (t variable-pitch regular 1.2))
+ modus-themes-common-palette-overrides
+ '((bg-main "#000B0E") ;; primary
+ (bg-active bg-main)
+ (fg-main "#c6b7ad")
+ (fg-active fg-main)
+ (fg-mode-line-active "#008EA2")
+ (bg-mode-line-active "#012C31") ;; primary
+ (fg-mode-line-inactive "#8D6D91")
+ (bg-mode-line-inactive "#442c50") ;; secondary
+ (border-mode-line-active nil)
+ (border-mode-line-inactive nil)
+ (bg-tab-bar bg-main)
+ (bg-tab-current "#042429") ;; primary
+ (bg-tab-other "#100014") ;; secondary
+
+ (fg-heading-0 "#b2ebf2")
+ (fg-heading-1 "#98fb98")
+ (fg-heading-2 "#fa80e6")
+ (fg-heading-3 "#ff7f50")
+ (fg-heading-4 "#ffd700")
+
+ (fg-prompt "#FF4E00") ;; tertiary
+ (bg-prompt unspecified)
+
+ (bg-region "#E65C19") ;; tertiary
+ (fg-region "#fffff0")
+
+ (bg-hl-line "#034852") ;; primary
+
+ (fg-line-number-active fg-main)
+ (fg-line-number-inactive "#a9a9a9")
+ (bg-line-number-active unspecified)
+ (bg-line-number-inactive "#0D5D62") ;; primary
+
+ (fringe bg-main)
+ (cursor "#FF5300") ;; tertiary
+
+ (fg-prose-verbatim "#af9fff")
+ (bg-prose-block-contents "#244449") ;; primary
+ (fg-prose-block-delimiter "#c6b7ad")
+ (bg-prose-block-delimiter bg-prose-block-contents)
+
+ (keyword "#4dd0e1")
+ (builtin "#a490ff")
+ (comment "#afa7b0")
+ (string "#50f2ca")
+ (fnname "#d8afd8")
+ (type "#89c6f9")
+ (variable "#98fb98")
+ (docstring "#f0e68c")
+ (constant "#fa80e6"))))
+(run-hooks 'modus-themes-post-load-hook)
+
+(defun bd/enable-variable-pitch-exempt ()
+ "Text modes to exempt from variable pitch fonts."
+ (unless (derived-mode-p 'latex-mode 'mhtml-mode 'nxml-mode 'yaml-mode)
+ (variable-pitch-mode 1)))
+
+(defvar bd/enable-variable-pitch-in-hooks
+ '(text-mode-hook)
+ "List of hook symbols to add `variable-pitch-mode'
+to.")
+
+(mapc
+ (lambda (hook)
+ (add-hook hook #'bd/enable-variable-pitch-exempt))
+ bd/enable-variable-pitch-in-hooks)
+
+(set-face-attribute 'variable-pitch nil
+ :family "Dejavu Serif"
+ :height 130)
+(set-face-attribute 'fixed-pitch nil
+ :family "Iosevka"
+ :height 100)
+(set-face-attribute 'default nil
+ :family "Iosevka"
+ :height 140)
+(set-face-attribute 'modus-themes-ui-variable-pitch nil
+ :family "Iosevka"
+ :height 90)
+
+
+(provide 'bd--themes)
+;;; bd--themes.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--utility.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--utility.el
new file mode 100644
index 0000000..ee74f58
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--utility.el
@@ -0,0 +1,160 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+(require 'project)
+(require 'xdg)
+
+
+(defun bd/set-frame-alpha (value)
+ "Set the transparency of ALL frame backgrounds to VALUE. 0=transparent/100=opaque."
+ (interactive "nTransparency Value (50 - 100 opaque): ")
+ (setq value (max 50 (min value 100)))
+ (mapc (lambda (f)
+ (set-frame-parameter f 'alpha `(,value . ,value)))
+ (frame-list))
+ (message "Alpha set to %d" value))
+
+(defun bd/set-bg (&optional arg)
+ "Set the current wallpaper using feh.
+ARG can be one of the following:
+
+- nil: set the most recent wallpaper
+- directory: set a random image from the directory
+- file: set the specified file"
+ (interactive
+ (list (read-file-name
+ "Select a wallpaper: "
+ (expand-file-name "~/wf/wall/") nil t)))
+ (let ((wall (expand-file-name "~/wf/wall/current")))
+ (when arg
+ (cond
+ ((file-regular-p arg) (copy-file arg wall t))
+ ((file-directory-p arg)
+ (let* ((images (directory-files arg (lambda (f) (string-match-p "\\.jpeg\\'" f))))
+ (rfile (nth (random (length images)) images)))
+ (and rfile (copy-file rfile wall t))))))
+ (start-process "set wallpaper" nil "feh" "--bg-fill" wall)
+ (message "Set wallpaper.")))
+
+(defun bd/lock ()
+ "Lock the screen."
+ (interactive)
+ (start-process "lock" nil "slock"))
+
+(defun bd/shoot-full ()
+ "Take a full-screen screenshot."
+ (interactive)
+ (let ((default-directory (xdg-user-dir "PICTURES")))
+ (start-process-shell-command "flameshot" nil "flameshot full")))
+
+(defun bd/shoot-part ()
+ "Take a selective screen screenshot."
+ (interactive)
+ (let ((default-directory (xdg-user-dir "PICTURES")))
+ (start-process-shell-command "flameshot" nil "flameshot launcher")))
+
+(defun bd/toggle-mute ()
+ "Toggle between muted and unmuted."
+ (interactive)
+ (start-process "sound toggle" nil "pactl" "set-sink-mute" "@DEFAULT_SINK@" "toggle"))
+
+(defun bd/set-volume (value)
+ "Set the volume to VALUE."
+ (start-process "set volume" nil "pactl" "set-sink-volume" "@DEFAULT_SINK@" value))
+
+(defun bd/decrement-volume ()
+ "Decrements the volume."
+ (interactive)
+ (bd/set-volume "-4%"))
+
+(defun bd/increment-volume ()
+ "Increments the volume."
+ (interactive)
+ (bd/set-volume "+4%"))
+
+(defun bd/set-brightness (value)
+ "Set the brightness to VALUE."
+ (start-process "set brightness" nil "brightnessctl" "set" value))
+
+(defun bd/decrement-brightness ()
+ "decrements the brightness."
+ (interactive)
+ (bd/set-brightness "5%-"))
+
+(defun bd/increment-brightness ()
+ "Increments the brightness."
+ (interactive)
+ (bd/set-brightness "5%+"))
+
+(defun bd/get-directory-dwim ()
+ "Return the directory you always wanted."
+ (or (when (project-current)
+ (project-root (project-current))) ;; git
+ (locate-dominating-file "." "Makefile") ;; make
+ (locate-dominating-file "." "manifest.scm") ;; guix
+ default-directory))
+
+(defun bd/buffer-eww-p (buf)
+ "Return non-nil if BUF is a `eww-mode' buffer."
+ (member
+ (buffer-local-value 'major-mode (get-buffer buf))
+ '(eww-mode)))
+
+(defun bd/buffer-exwm-p (buf)
+ "Return non-nil if BUF is an `exwm-mode' buffer and is in the current workspace."
+ (and (member
+ (buffer-local-value 'major-mode (get-buffer buf))
+ '(exwm-mode))
+ (eq (exwm-workspace--position exwm-workspace--current)
+ (alist-get 'exwm--desktop (buffer-local-variables (get-buffer buf))))))
+
+(defun bd/buffer-scratch-p (buf)
+ "Return non-nil if BUF is a scratch buffer."
+ (buffer-local-value 'scratch-buffer (get-buffer buf)))
+
+(defun bd/buffer-text-p (buf)
+ "Return non-nil if BUF derives from `text-mode'."
+ (provided-mode-derived-p (buffer-local-value 'major-mode (get-buffer buf)) 'text-mode))
+
+(defun bd/buffer-prog-p (buf)
+ "Return non-nil if BUF derives from `prog-mode'."
+ (provided-mode-derived-p (buffer-local-value 'major-mode (get-buffer buf)) 'prog-mode))
+
+(defun bd/buffer-shell-p (buf)
+ "Return non-nil if BUF derives from `text-mode'."
+ (member
+ (buffer-local-value 'major-mode (get-buffer buf))
+ '(shell-mode eshell-mode term-mode vterm-mode)))
+
+(defun bd/buffer-dired-p (buf)
+ "Return non-nil if BUF is a `dired-mode' buffer."
+ (member
+ (buffer-local-value 'major-mode (get-buffer buf))
+ '(dired-mode)))
+
+(defun bd/buffer-irc-p (buf)
+ "Return non-nil if BUF is an `irc-mode' buffer."
+ (member
+ (buffer-local-value 'major-mode (get-buffer buf))
+ '(rcirc-mode erc-mode)))
+
+(defun bd/buffer-ordinary-p (buf)
+ "Return non-nil if BUF does not fit into known categories."
+ (not (or (bd/buffer-eww-p buf)
+ (bd/buffer-exwm-p buf)
+ (bd/buffer-text-p buf)
+ (bd/buffer-prog-p buf)
+ (bd/buffer-shell-p buf)
+ (bd/buffer-scratch-p buf)
+ (bd/buffer-dired-p buf)
+ (bd/buffer-irc-p buf))))
+
+(defun bd/kill-quietly (proc)
+ "Kill PROC quietly."
+ (ignore-errors (cond ((bufferp proc) (kill-buffer proc))
+ ((stringp proc) (interrupt-process proc)))))
+
+
+(provide 'bd--utility)
+;;; bd--utility.el ends here
diff --git a/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--window.el b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--window.el
new file mode 100644
index 0000000..bdc173b
--- /dev/null
+++ b/kolwynia/home/bdunahu/files/.config/emacs/modules/bd--window.el
@@ -0,0 +1,59 @@
+;;; -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(require 'transient)
+
+(setopt switch-to-buffer-obey-display-actions t
+ switch-to-buffer-in-dedicated-window 'pop)
+;; C-u C-h a ^display-buffer-[^-]
+(add-to-list 'display-buffer-alist
+ '("^\\*Async Shell Command\\*.*$"
+ (display-buffer-no-window)))
+
+(defun bd/layout--do-with-haste (f)
+ (let* ((args (transient-args 'bd/layout-dispatcher))
+ (haste (if (member "haste" args) 3 1)))
+ (funcall f haste)))
+(transient-define-prefix bd/layout-dispatcher ()
+ ["Dispatcher > Layout\n"
+ ["Infixes"
+ ("s" "haste" "haste")]]
+ [["Commands"
+ ("-" "text decrease"
+ (lambda () (interactive) (bd/layout--do-with-haste #'text-scale-decrease))
+ :transient t)
+ ("=" "text increase"
+ (lambda () (interactive) (bd/layout--do-with-haste #'text-scale-increase))
+ :transient t)
+ ("b" "narrow"
+ (lambda () (interactive) (bd/layout--do-with-haste #'shrink-window-horizontally))
+ :transient t)
+ ("f" "widen"
+ (lambda () (interactive) (bd/layout--do-with-haste #'enlarge-window-horizontally))
+ :transient t)
+ ("p" "shrink"
+ (lambda () (interactive) (bd/layout--do-with-haste #'shrink-window))
+ :transient t)
+ ("n" "enlarge"
+ (lambda () (interactive) (bd/layout--do-with-haste #'enlarge-window))
+ :transient t)
+ ("|" "balance" balance-windows)]
+ [""
+ ("N" "shift down" windmove-swap-states-down :transient t)
+ ("P" "shift up" windmove-swap-states-up :transient t)
+ ("F" "shift right" windmove-swap-states-right :transient t)
+ ("B" "shift left" windmove-swap-states-left :transient t)]
+ [""
+ ("a" "alpha" bd/set-frame-alpha)
+ ("w" "wallpaper" bd/set-bg)
+ ("t" "theme" load-theme)]
+ [""
+ ("z" "widen gaps" exwm-outer-gaps-increment :transient t)
+ ("x" "shrink gaps" exwm-outer-gaps-decrement :transient t)]])
+(keymap-global-set "C-c w" #'bd/layout-dispatcher)
+
+
+(provide 'bd--window)
+;;; bd--window.el ends here