diff options
Diffstat (limited to 'kolwynia/home/bdunahu/files/.config/emacs/modules')
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 |
