diff options
| author | Robby Zambito <contact@robbyzambito.me> | 2026-04-05 12:52:04 -0400 |
|---|---|---|
| committer | Robby Zambito <contact@robbyzambito.me> | 2026-04-05 12:55:17 -0400 |
| commit | 75a24d542a2f358eec68d98f3c65d32437bf0c8e (patch) | |
| tree | 13a90980d1c4149fb596b8cbf171621f44a0ca08 /config/emacs.scm | |
| parent | 8cc138dfbbb13fad87acea77abfc085f3a73fc63 (diff) | |
refactor: move emacs config to separate package
Diffstat (limited to 'config/emacs.scm')
| -rw-r--r-- | config/emacs.scm | 433 |
1 files changed, 433 insertions, 0 deletions
diff --git a/config/emacs.scm b/config/emacs.scm new file mode 100644 index 0000000..13e5773 --- /dev/null +++ b/config/emacs.scm @@ -0,0 +1,433 @@ +(define-library (config emacs) + (export emacs-config) + (import (scheme base) + (scheme write) + (gnu packages) + (guix packages) + (guix derivations) + (guix store) + (guix transformations) + (config-generation sexp))) + +(begin + (define emacs-config + (string-append + ";; See /home/robby/.config/guix-home/home-configuration.scm\n" + (scm->string + ;; Load the secrets file + `((when (not (load "/home/robby/.config/emacs/secrets.el")) + (message "could not load secrets!")) + + ;; Load the Nord theme when launching an emacsclient GUI + (if (daemonp) + (add-hook 'after-make-frame-functions + (lambda (frame) + (with-selected-frame + frame + (load-theme 'nord t)))) + (load-theme 'nord t)) + + ;; Safe variables + (custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(safe-local-variable-values + '((auto-save-default) + (org-download-image-dir . "~/org/pictures") + (eval progn + (require 'lisp-mode) + (defun emacs27-lisp-fill-paragraph + (&optional justify) + (interactive "P") + (or + (fill-comment-paragraph justify) + (let + ((paragraph-start + (concat paragraph-start "\\|\\s-*\\([(;\"]\\|\\s-:\\|`(\\|#'(\\)")) + (paragraph-separate + (concat paragraph-separate "\\|\\s-*\".*[,\\.]$")) + (fill-column + (if + (and + (integerp emacs-lisp-docstring-fill-column) + (derived-mode-p 'emacs-lisp-mode)) + emacs-lisp-docstring-fill-column fill-column))) + (fill-paragraph justify)) + t)) + (setq-local fill-paragraph-function + (syntax emacs27-lisp-fill-paragraph))) + (eval modify-syntax-entry 43 "'") + (eval modify-syntax-entry 36 "'") + (eval modify-syntax-entry 126 "'") + (eval let + ((root-dir-unexpanded + (locate-dominating-file default-directory ".dir-locals.el"))) + (when root-dir-unexpanded + (let* + ((root-dir + (file-local-name + (expand-file-name root-dir-unexpanded))) + (root-dir* + (directory-file-name root-dir))) + (unless + (boundp 'geiser-guile-load-path) + (defvar geiser-guile-load-path 'nil)) + (make-local-variable 'geiser-guile-load-path) + (require 'cl-lib) + (cl-pushnew root-dir* geiser-guile-load-path :test + (syntax string-equal))))) + (eval with-eval-after-load 'yasnippet + (let + ((guix-yasnippets + (expand-file-name "etc/snippets/yas" + (locate-dominating-file default-directory ".dir-locals.el")))) + (unless + (member guix-yasnippets yas-snippet-dirs) + (add-to-list 'yas-snippet-dirs guix-yasnippets) + (yas-reload-all)))) + (eval setq-local guix-directory + (locate-dominating-file default-directory ".dir-locals.el")) + (eval add-to-list 'completion-ignored-extensions ".go")))) + + ;; Do not open windows in the same Emacs frame. + ;; (setq pop-up-frames 'graphic-only) + + (setq inferior-lisp-program "/home/robby/.guix-home/profile/bin/sbcl") + + ;; Enable which-key mode + (which-key-mode) + + ;; Automatically create closing pairs + (electric-pair-mode 1) + + ;; Show matching parenthesis + (show-paren-mode 1) + (setq show-paren-delay 0) + + ;; Hide the tool bar + (tool-bar-mode -1) + + ;; Hide the menu bar + (menu-bar-mode -1) + + ;; Hide the scroll bar + (scroll-bar-mode -1) + + ;; Highlight the current line + (global-hl-line-mode 1) + + ;; Enable line numbers + (global-display-line-numbers-mode) + (setq display-line-numbers-type 'relative) + + ;; Disable line numbers for certain modes + (add-hook 'eshell-mode-hook (lambda () (display-line-numbers-mode -1))) + + ;; Show the column number + (setq column-number-mode t) + + ;; Add e as an alias for find-file. Useful for eshell. + (defalias 'e (function find-file)) + + ;; Eshell visual commands + (setq eshell-visual-subcommands '(("guix" "search") + ("pipe-viewer") + ("keepassxc-cli" "open"))) + + ;; Open init file + (defun open-init-file () + "Open the init file." + (interactive) + (find-file "~/src/guix-dotfiles/home.scm")) + + (global-set-key (kbd "C-x i") 'open-init-file) + + ;; Function to create a new eshell. Used for Sway binding. + (defvar next-eshell -1) + (defun new-eshell () + (setq next-eshell (+ 1 next-eshell)) + (eshell next-eshell)) + + ;; Power + (defun eshell/poweroff () + "Shutdown the computer." + (call-process "loginctl" null-device nil nil "poweroff")) + + (defun eshell/reboot () + "Reboot the computer." + (call-process "loginctl" null-device nil nil "reboot")) + + ;; For using tramp guix->guix + (require 'tramp) + ;; (setq tramp-remote-path + ;; (append tramp-remote-path + ;; '(tramp-own-remote-path))) + + ;; Scheme extra file extensions + (setq auto-mode-alist (append '(("\\.sld\\'" . scheme-mode)) auto-mode-alist)) + + ;; Code folding + ;; (require 'origami) + ;; Add mode hooks + ;; (dolist (mode '(nxml-mode-hook csharp-mode-hook c-mode-hook scheme-mode-hook emacs-lisp-mode-hook)) + ;; (add-hook mode 'origami-mode)) + ;; Specify extra parsers + ;; (dolist (parser-pair '((scheme-mode . origami-elisp-parser) (csharp-mode . origami-c-style-parser))) + ;; (add-to-list 'origami-parser-alist parser-pair)) + ;; (define-key origami-mode-map (kbd "<C-tab>") 'origami-recursively-toggle-node) + + ;;; Org mode config + (require 'org-download) + (setq org-startup-with-inline-images t) + (add-hook 'org-mode-hook 'org-indent-mode) + (add-hook 'org-mode-hook 'toc-org-mode) + + ;; Org bullets + (require 'org-bullets) + (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))) + + ;; Org babel language support + (org-babel-do-load-languages + 'org-babel-load-languages + '((emacs-lisp . t) + (eshell . t) + (C . t) + (scheme . t))) + + ;; Org link abbreviations + (setq org-link-abbrev-alist + '(("wikipedia" . "https://en.wikipedia.org/wiki/") + ("wiki" . "https://wiki.zambito.xyz/index.php?title=") + ("gh" . "https://github.com/") + ("guix" . "elisp:(guix-packages-by-name \"%s\")") + ("isbn" . "https://www.bookfinder.com/isbn/") + ("man" . "elisp:(man \"%s\")"))) + + ;; Org roam + (require 'org-roam) + (setq org-roam-directory "~/org" + org-roam-capture-templates '(("d" "default" plain + "%?" + :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}") + :unnarrowed t) + ("p" "person" plain + (file "~/org/templates/person.org") + :target (file "%<%Y%m%d%H%M%S>-${slug}.org") + :unnarrowed t) + ("b" "book" plain + (file "~/org/templates/book.org") + :target (file "%<%Y%m%d%H%M%S>-${slug}.org") + :unnarrowed t)) + org-roam-dailies-capture-templates '(("d" "default" entry "* %?" + :target (file+head "%<%Y-%m-%d>.org" + "#+title: %<%Y-%m-%d>\n")) + ("v" "Value" entry "* %?" + :target (file+head+olp "%<%Y-%m-%d>.org" + "#+title: %<%Y-%m-%d>\n" + ("What do I value?"))) + ("t" "Trajectory" entry "* %?" + :target (file+head+olp "%<%Y-%m-%d>.org" + "#+title: %<%Y-%m-%d>\n" + ("What is my trajectory today?"))))) + (add-to-list 'org-roam-file-exclude-regexp "par/") + (org-roam-db-autosync-enable) + (global-set-key (kbd "C-c n i") 'org-roam-node-insert) + (global-set-key (kbd "C-c n f") 'org-roam-node-find) + (global-set-key (kbd "C-c n r") 'org-roam-node-random) + (global-set-key (kbd "C-c n t") 'org-roam-buffer-toggle) + (global-set-key (kbd "C-c d c t") 'org-roam-dailies-capture-today) + (global-set-key (kbd "C-c d c n") 'org-roam-dailies-capture-tomorrow) + (global-set-key (kbd "C-c d c p") 'org-roam-dailies-capture-yesterday) + (global-set-key (kbd "C-c d c d") 'org-roam-dailies-capture-date) + (global-set-key (kbd "C-c d f t") 'org-roam-dailies-goto-today) + (global-set-key (kbd "C-c d f n") 'org-roam-dailies-goto-next-note) + (global-set-key (kbd "C-c d f p") 'org-roam-dailies-goto-previous-note) + (global-set-key (kbd "C-c d f d") 'org-roam-dailies-goto-date) + + (add-to-list 'load-path "~/src/org-roam-ui/") + (require 'org-roam-ui) + (setq org-roam-ui-sync-theme t + org-roam-ui-follow t + org-roam-ui-update-on-save t + org-roam-ui-open-on-start nil) + (org-roam-ui-mode 1) + + ;; Emojify + (global-emojify-mode 1) + + ;; ERC + ;; See: https://gist.github.com/chumpage/1243771 + (require 'erc-services) + (erc-services-mode 1) + + (setq erc-server "irc.libera.chat" + erc-nick "Zambyte" + erc-port 6697 + erc-prompt-for-nickserv-password nil + erc-prompt-for-password t + erc-nickserv-passwords (list (list 'Libera.Chat (list (cons "Zambyte" (cdr (assoc 'libera secrets)))))) + erc-autojoin-channels-alist '((Libera.Chat "#archlinux" + "#c" + "#emacs" + "#fsf" + "#gnu" + "#guile" + "#guix" + "#hurd" + "#lisp" + "#mastodon" + "#pleroma" + "#pleroma-dev" + "#scheme" + "#sway" + "#minetest" + "#lojban" + "#ckule" + "#jbosnu" + "#proga" + "#lowellmakes"))) + + ;; Email + (require 'mu4e) + (setq mu4e-get-mail-command "SSL_CERT_DIR=/home/robby/.guix-profile/etc/ssl/certs mbsync personal") + (setq user-full-name "Robby Zambito" + user-mail-address "contact@robbyzambito.me" + send-mail-function (function smtpmail-send-it) + smtpmail-smtp-server "mail.gandi.net" + smtpmail-stream-type 'starttls + smtpmail-smtp-service 587) + (global-set-key (kbd "C-x C-m") 'mu4e) + + ;; Music + (emms-all) + (setq emms-player-list '(emms-player-mpv) + emms-info-functions '(emms-info-native) + ;; emms-player-mpv-parameters '("--ao=pipewire") + ) + + ;; RSS + (require 'elfeed) + (require 'elfeed-show) + (require 'elfeed-org) + (elfeed-org) + (setq rmh-elfeed-org-files (list "~/org/20230517231456-elfeed.org") + elfeed-search-filter "@6-months-ago +unread -reddit -hn -politics") + + ;; TODO: this doesn't work + ;; Fixed? TODO: Check if it works + (add-hook 'elfeed-mode-hook + (lambda () + (define-key elfeed-mode-map "C-c C-u" + 'elfeed-update))) + + ;; Source https://github.com/skeeto/elfeed/issues/267 + (defun elfeed-play-with-mpv () + "Play entry link with mpv." + (interactive) + (let ((entry (if (eq major-mode 'elfeed-show-mode) elfeed-show-entry (elfeed-search-selected :single))) + (quality-arg "") + (quality-val (completing-read "Max height resolution (0 for unlimited): " '("0" "480" "720") nil nil))) + (setq quality-val (string-to-number quality-val)) + (message "Opening %s with heightâÃÂä%s with mpv..." (elfeed-entry-link entry) quality-val) + (when (< 0 quality-val) + (setq quality-arg (format "--ytdl-format=[height<=?%s]" quality-val))) + (start-process "elfeed-mpv" nil "mpv" quality-arg (elfeed-entry-link entry)))) + + (defun elfeed-open-with-eww () + "Open in eww with `eww-readable'." + (interactive) + (let ((entry (if (eq major-mode 'elfeed-show-mode) elfeed-show-entry (elfeed-search-selected :single)))) + (eww (elfeed-entry-link entry)) + (add-hook 'eww-after-render-hook 'eww-readable nil t))) + + (defvar elfeed-visit-patterns + '(("youtu\\.?be" . elfeed-play-with-mpv) + ("v\\.redd\\.it" . elfeed-play-with-mpv) + ("reddit" . elfeed-play-with-mpv) + ("phoronix" . elfeed-open-with-eww) + ("jcs\\.org" . elfeed-play-with-mpv)) + "List of (regexps . function) to match against elfeed entry link to know +whether how to visit the link.") + + (defun elfeed-visit-maybe-external () + "Visit with external function if entry link matches `elfeed-visit-patterns', +visit otherwise." + (interactive) + (let ((entry (if (eq major-mode 'elfeed-show-mode) + elfeed-show-entry + (elfeed-search-selected :single))) + (patterns elfeed-visit-patterns)) + (while (and patterns (not (string-match (caar patterns) (elfeed-entry-link entry)))) + (setq patterns (cdr patterns))) + (cond + (patterns + (elfeed-untag entry 'unread) + (elfeed-search-update-entry entry) + (funcall (cdar patterns))) + ((eq major-mode 'elfeed-search-mode) + (call-interactively 'elfeed-search-show-entry)) + (t (elfeed-show-visit))))) + + ;; https://github.com/skeeto/elfeed/issues/317 and + ;; https://github.com/skeeto/elfeed/pull/448#issuecomment-1120336279 + ;; Speeds up getting elfeed feeds + (setq flycheck-global-modes '(not . (elfeed-search-mode))) + + (define-key elfeed-show-mode-map (kbd "<C-return>") 'elfeed-visit-maybe-external) + (define-key elfeed-search-mode-map (kbd "<C-return>") 'elfeed-visit-maybe-external) + (global-set-key (kbd "C-x w") 'elfeed) + + ;; Pleroma + (add-to-list 'load-path "/home/robby/src/mastodon.el/lisp/") + (require 'mastodon) + (setq mastodon-instance-url "https://zoinks.one" + mastodon-active-user "robby") + + ;; Programming + + ;; https://www.youtube.com/watch?v=Vx0bSKF4y78 + ;; https://github.com/minad/corfu + ;; (require 'corfu) + ;; (setq corfu-cycle t + ;; corfu-auto t + ;; corfu-auto-delay 0 + ;; corfu-quit-no-match 'separator + ;; corfu-echo-documentation 0.25 + ;; corfu-preselect-first nil) + ;; (global-corfu-mode) + ;; (corfu-history-mode) + + ;; ;; https://github.com/minad/cape + ;; (require 'cape) + ;; (add-to-list 'completion-at-point-functions (function cape-dabbrev)) + ;; (add-to-list 'completion-at-point-functions (function cape-file)) + + ;; (("C-c p p" . completion-at-point) ;; capf + ;; ("C-c p t" . complete-tag) ;; etags + ;; ("C-c p d" . cape-dabbrev) ;; or dabbrev-completion + ;; ("C-c p h" . cape-history) + ;; ("C-c p f" . cape-file) + ;; ("C-c p k" . cape-keyword) + ;; ("C-c p s" . cape-symbol) + ;; ("C-c p a" . cape-abbrev) + ;; ("C-c p i" . cape-ispell) + ;; ("C-c p l" . cape-line) + ;; ("C-c p w" . cape-dict) + ;; ("C-c p \\" . cape-tex) + ;; ("C-c p _" . cape-tex) + ;; ("C-c p ^" . cape-tex) + ;; ("C-c p &" . cape-sgml) + ;; ("C-c p r" . cape-rfc1345)) + + ;; (require 'gptel) + ;; (setq gptel-default-mode 'org-mode) + ;; (setq gptel-default-mode 'text-mode) ; I cannot use org-mode, as there is a bug: https://github.com/karthink/gptel/issues/81 + ;; (define-key gptel-mode-map (kbd "C-c RET") 'gptel-send) + ;; (define-key gptel-mode-map (kbd "C-c C-<return>") 'gptel-send) + ;; (define-key gptel-mode-map (kbd "C-c C-m") 'gptel-menu) + + )))) + + ) |
