(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 "") '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 "") 'elfeed-visit-maybe-external) (define-key elfeed-search-mode-map (kbd "") '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-") 'gptel-send) ;; (define-key gptel-mode-map (kbd "C-c C-m") 'gptel-menu) )))) )