From 6537c069aefeac53e2df591931ae0604b0e90463 Mon Sep 17 00:00:00 2001 From: cspark Date: Mon, 23 Feb 2026 18:32:53 +0000 Subject: [PATCH] Mail config, switch to elpaca, org mode journalling, alert fix --- .gitignore | 1 + early-init.el | 4 +- init.el | 309 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 226 insertions(+), 88 deletions(-) diff --git a/.gitignore b/.gitignore index 44b2b30..21c04ac 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ tutorial/ auto-save-list/ transient/ straight/ +elpaca/ eshell/history eshell/lastdir diff --git a/early-init.el b/early-init.el index 1d6ba05..ab0bb3d 100644 --- a/early-init.el +++ b/early-init.el @@ -1,2 +1,4 @@ -;; For straight.el +;; For elpaca + +;;; Code: (setq package-enable-at-startup nil) diff --git a/init.el b/init.el index 6a82ce1..aa00cf7 100644 --- a/init.el +++ b/init.el @@ -74,19 +74,50 @@ (define-key global-map [remap digit-argument] "") ;; Package management setup -; straight.el -(defvar bootstrap-version) -(let - ((bootstrap-file - (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) - (bootstrap-version 5)) - (unless (file-exists-p bootstrap-file) - (with-current-buffer - (url-retrieve-synchronously "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" 'silent 'inhibit-cookies) - (goto-char (point-max)) - (eval-print-last-sexp))) - (load bootstrap-file nil 'nomessage)) -(setq straight-use-package-by-default t) +; Elpaca +(defvar elpaca-installer-version 0.11) +(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) +(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory)) +(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory)) +(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" + :ref nil :depth 1 :inherit ignore + :files (:defaults "elpaca-test.el" (:exclude "extensions")) + :build (:not elpaca--activate-package))) +(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory)) + (build (expand-file-name "elpaca/" elpaca-builds-directory)) + (order (cdr elpaca-order)) + (default-directory repo)) + (add-to-list 'load-path (if (file-exists-p build) build repo)) + (unless (file-exists-p repo) + (make-directory repo t) + (when (<= emacs-major-version 28) (require 'subr-x)) + (condition-case-unless-debug err + (if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) + ((zerop (apply #'call-process `("git" nil ,buffer t "clone" + ,@(when-let* ((depth (plist-get order :depth))) + (list (format "--depth=%d" depth) "--no-single-branch")) + ,(plist-get order :repo) ,repo)))) + ((zerop (call-process "git" nil buffer t "checkout" + (or (plist-get order :ref) "--")))) + (emacs (concat invocation-directory invocation-name)) + ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch" + "--eval" "(byte-recompile-directory \".\" 0 'force)"))) + ((require 'elpaca)) + ((elpaca-generate-autoloads "elpaca" repo))) + (progn (message "%s" (buffer-string)) (kill-buffer buffer)) + (error "%s" (with-current-buffer buffer (buffer-string)))) + ((error) (warn "%s" err) (delete-directory repo 'recursive)))) + (unless (require 'elpaca-autoloads nil t) + (require 'elpaca) + (elpaca-generate-autoloads "elpaca" repo) + (let ((load-source-file-function nil)) (load "./elpaca-autoloads")))) +(add-hook 'after-init-hook #'elpaca-process-queues) +(elpaca `(,@elpaca-order)) +; Install use-package support +(elpaca elpaca-use-package + ;; Enable use-package :ensure support for Elpaca. + (elpaca-use-package-mode)) +(elpaca-wait) ;; Optimisation ; GCMH @@ -111,6 +142,7 @@ ) ; Fontification (jit-lock-mode 1) +(jit-lock-debug-mode 1) (setq jit-lock-stealth-time 1.25) (setq jit-lock-stealth-nice 0.5) ;; Seconds between font locking. (setq jit-lock-chunk-size 4096) @@ -124,9 +156,79 @@ (lambda () (setq jit-lock-defer-time 0)) nil t)) +;; Org Mode Config +;Agenda +;For Org-Agenda, you can set a location of your Org Agenda file here. Set Agenda Directory: +(use-package org + :ensure (:wait t) + :demand t + :config + (setq org-agenda-files '("~/Agenda")) + ;This is will integrate the Calendar/Diary into Org-Agenda, so you can get access to dates on public holidays etc. Set diary to true: + (setq org-agenda-include-diary t) + ;Ensure done date/closed timestamps are logged + (setq org-log-done 'time) + + ;Ensure agenda still shows DONE items + (setq org-agenda-skip-scheduled-if-done nil) + (setq agenda-skip-deadline-if-done nil) + + (setq org-startup-folded t) +) + +; For Org Pomodoro notification sound +(use-package sound-wav + :ensure t +) +; Org Pomodoro +(use-package org-pomodoro + :ensure t + :after org + :config + (setq org-pomodoro-manual-break t) + (setq org-pomodoro-keep-killed-pomodoro-time t) + (setq org-pomodoro-play-sounds t) + (setq org-pomodoro-ticking-sound-p nil) + (setq org-pomodoro-audio-player "mpv") +) +(defun sound-alert (alert) + (sound-wav-play (concat (expand-file-name "~") "/.emacs.d/elpaca/builds/org-pomodoro/resources/bell.wav")) + (message alert)) + +; System notifications of org agenda items +(use-package org-alert + :ensure t + :after org + :config + (setq alert-default-style 'libnotify) + (setq alert-libnotify-command '(sound-alert)) + (org-alert-enable) +) + +; Org Mode Journalling +(use-package org-journal + :ensure t + :after org + :config + (setq org-journal-dir "~/Journal/") + (setq org-journal-file-type 'daily) + (setq org-journal-file-format "%Y%m%d.org") +) + +;; Org Latex Preview Scale +; Automatically toggle Org mode LaTeX fragment previews as the cursor enters and exits them +(use-package org-fragtog + :ensure t + :after org + :config + (add-hook 'org-mode-hook 'org-latex-preview) + (add-hook 'org-mode-hook 'org-fragtog-mode) + (setq org-format-latex-options (plist-put org-format-latex-options :scale 3.0)) +) + ;; Emacs minibuffer configurations. (use-package emacs - :ensure t + :ensure nil :custom (tab-always-indent 'complete) @@ -151,11 +253,11 @@ :config ;; Global settings (defaults) (setq - doom-themes-enable-bold t ; if nil, bold is universally disabled - doom-themes-enable-italic t + doom-themes-enable-bold t ; if nil, bold is universally disabled + doom-themes-enable-italic t ; if nil, italics is universally disabled ) -) ; if nil, italics is universally disabled -(load-theme 'doom-gruvbox-light t) + (load-theme 'doom-gruvbox-light t) +) ;; Autocompletion configuration ;(use-package ido-vertical-mode @@ -196,7 +298,7 @@ ;; Persist history over Emacs restarts. Vertico sorts by history position. (use-package savehist - :ensure t + :ensure nil :init (savehist-mode) ) @@ -242,6 +344,7 @@ ; Like zoxide (use-package eshell-z :ensure t + :after tramp :config (add-hook 'eshell-mode-hook (defun my-eshell-mode-hook () @@ -263,14 +366,14 @@ ) ; Eat is a terminal emulator that can integrate nicely with eshell, allows us to run full ncurses applications inside eshell. (use-package eat - :straight '(eat :type git - :host codeberg - :repo "akib/emacs-eat" - :files ("*.el" ("term" "term/*.el") "*.texi" - "*.ti" ("terminfo/e" "terminfo/e/*") - ("terminfo/65" "terminfo/65/*") - ("integration" "integration/*") - (:exclude ".dir-locals.el" "*-tests.el"))) + ;:straight '(eat :type git + ; :host codeberg + ; :repo "akib/emacs-eat" + ; :files ("*.el" ("term" "term/*.el") "*.texi" + ; "*.ti" ("terminfo/e" "terminfo/e/*") + ; ("terminfo/65" "terminfo/65/*") + ; ("integration" "integration/*") + ; (:exclude ".dir-locals.el" "*-tests.el"))) :ensure t :init ;; For `eat-eshell-mode'. @@ -293,8 +396,11 @@ (setq tramp-auto-save-directory "~/.emacs.d/tramp-autosave") ;; Magit -(use-package magit +(use-package transient :ensure t) +(use-package magit + :ensure t + :after transient) ;; TRAMP ;TRAMP edit files over SSH configuration @@ -307,61 +413,100 @@ (setq tramp-default-method "plink")) ) -;; Org Mode Config -;Agenda -;For Org-Agenda, you can set a location of your Org Agenda file here. Set Agenda Directory: -(use-package org - :ensure t - :config - (setq org-agenda-files '("~/Agenda")) - ;This is will integrate the Calendar/Diary into Org-Agenda, so you can get access to dates on public holidays etc. Set diary to true: - (setq org-agenda-include-diary t) - ;Ensure done date/closed timestamps are logged - (setq org-log-done 'time) - - (setq org-startup-folded t) +;; Mu4e Mail Config +(if (executable-find "mu") + (use-package mu4e + :ensure nil + :config + (setq mu4e-mu-binary (executable-find "mu")) + + ;; This is set to 't' to avoid mail syncing issues when using mbsync + (setq mu4e-change-filenames-when-moving t) + + ;; Refresh mail using isync every 10 minutes + ;(setq mu4e-update-interval (* 10 60)) + (setq mu4e-get-mail-command "mbsync -a") + (setq mu4e-maildir "~/Mail") + + ;; Use completing read AKA vertico + (setq mu4e-completing-read-function 'completing-read) + + (setq mu4e-contexts + (list + ;; Work account + (make-mu4e-context + :name "A CSpark Work" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/work-cspark" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "work@cspark.dev") + (user-full-name . "Curt Spark (Work)") + (mu4e-inbox-folder . "/work-cspark/Inbox") + (mu4e-drafts-folder . "/work-cspark/Drafts") + (mu4e-sent-folder . "/work-cspark/Sent Mail") + (mu4e-trash-folder . "/work-cspark/Trash"))) + + ;; Services account + (make-mu4e-context + :name "B CSpark Services" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/services-cspark" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "services@cspark.dev") + (user-full-name . "Curt Spark (services)") + (mu4e-inbox-folder . "/services-cspark/Inbox") + (mu4e-drafts-folder . "/services-cspark/Drafts") + (mu4e-sent-folder . "/services-cspark/Sent Mail") + (mu4e-trash-folder . "/services-cspark/Trash"))) + + ;; Personal account + (make-mu4e-context + :name "C CSpark Personal" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/personal-cspark" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "personal@cspark.dev") + (user-full-name . "Curt Spark (personal)") + (mu4e-inbox-folder . "/personal-cspark/Inbox") + (mu4e-drafts-folder . "/personal-cspark/Drafts") + (mu4e-sent-folder . "/personal-cspark/Sent Mail") + (mu4e-trash-folder . "/personal-cspark/Trash"))) + + ;; Tuxtank Services account + (make-mu4e-context + :name "D Tuxtank Services" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/personal-tuxtank" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "personal@tuxtank.dev") + (user-full-name . "Tuxtank (personal)") + (mu4e-inbox-folder . "/personal-tuxtank/Inbox") + (mu4e-drafts-folder . "/personal-tuxtank/Drafts") + (mu4e-sent-folder . "/personal-tuxtank/Sent Mail") + (mu4e-trash-folder . "/personal-tuxtank/Trash")))) + ) + + ;(setq mu4e-maildir-shortcuts + ; '(("/Gmail/Inbox" . ?i) + ; ("/Gmail/[Gmail]/Sent Mail" . ?s) + ; ("/Gmail/[Gmail]/Trash" . ?t) + ; ("/Gmail/[Gmail]/Drafts" . ?d) + ; ("/Gmail/[Gmail]/All Mail" . ?a))) + ) ) -; Org Pomodoro -(use-package org-pomodoro +;; Rainbow delimiters +(use-package rainbow-delimiters :ensure t - :after org - :config - (setq org-pomodoro-manual-break t) - (setq org-pomodoro-keep-killed-pomodoro-time t) - (setq org-pomodoro-play-sounds t) - (setq org-pomodoro-ticking-sound-p nil) - (setq org-pomodoro-audio-player "mpv") -) -; For Org Pomodoro notification sound -(use-package sound-wav - :ensure t -) - -; System notifications of org agenda items -(use-package org-alert - :ensure t - :after org - :config - (org-alert-enable) -) - -; Org Latex Preview Scale -; Automatically toggle Org mode LaTeX fragment previews as the cursor enters and exits them -(use-package org-fragtog - :ensure t - :after org - :config - (add-hook 'org-mode-hook 'org-latex-preview) - (add-hook 'org-mode-hook 'org-fragtog-mode) - (setq org-format-latex-options (plist-put org-format-latex-options :scale 3.0)) -) - - + :hook + (prog-mode . rainbow-delimiters-mode)) ;; Treesit Config (use-package treesit :ensure nil - :straight nil :commands (treesit-install-language-grammar nf/treesit-install-all-languages) :init (setq treesit-language-source-alist @@ -402,42 +547,33 @@ ; Remap basic modes to treesit equivalent (use-package bash-ts-mode :ensure nil - :straight nil :mode "\\.sh\\'") (use-package c-ts-mode :ensure nil - :straight nil :mode "\\.c\\'") (use-package rust-ts-mode :ensure nil - :straight nil :mode "\\.rs\\'") (use-package swift-ts-mode :ensure t :mode "\\.swift\\'") (use-package nix-ts-mode :ensure nil - :straight nil :mode "\\.nix\\'") (use-package html-ts-mode :ensure nil - :straight nil :mode "\\.html\\'") (use-package css-ts-mode :ensure nil - :straight nil :mode "\\.css\\'") (use-package js-ts-mode :ensure nil - :straight nil :mode "\\.js\\'") (use-package typescript-ts-mode :ensure nil - :straight nil :mode "\\.ts\\'") (use-package tsx-ts-mode :ensure nil - :straight nil :mode "\\.tsx\\'") ;(use-package emacs-lisp-ts-mode ; :ensure t) @@ -478,7 +614,6 @@ ;; Flymake Configuration (use-package flymake :ensure nil - :straight nil :hook (prog-mode . flymake-mode) (emacs-lisp-mode . flymake-mode)