diff --git a/README.org b/README.org index 61ad7f73..83194c93 100644 --- a/README.org +++ b/README.org @@ -1,4 +1,9 @@ -#+title: README +#+TITLE: README +#+AUTHOR: Evie Litherland-Smith +#+EMAIL: evie@xenia.me.uk + +[[file:./home/emacs/config.org][Emacs (babel) config]] + * Password store setup ** Transfer GPG key(s) #+begin_src bash diff --git a/home/default.nix b/home/default.nix index 52f25c6d..83b5a952 100644 --- a/home/default.nix +++ b/home/default.nix @@ -218,7 +218,7 @@ } rsync-local-config () { HOST=$1 - for TARGET in bat git emacs/init.el emacs/modules emacs/crafted-emacs emacs/snippets starship.toml; do + for TARGET in bat git emacs/config.org emacs/snippets starship.toml; do SOURCE="${config.xdg.configHome}/$TARGET" TMP_TARGET=/tmp/rsync-local-config TMP_SOURCE=$TMP_TARGET diff --git a/home/emacs/config.org b/home/emacs/config.org new file mode 100644 index 00000000..b92fed48 --- /dev/null +++ b/home/emacs/config.org @@ -0,0 +1,965 @@ +#+TITLE: Emacs Config +#+AUTHOR: Evie Litherland-Smith +#+EMAIL: evie@xenia.me.uk +#+FILETAGS: :emacs:config:org: +#+PROPERTY: header-args:emacs-lisp :tangle ./config.el :mkdirp yes + +* TODO Initial config + +* Copy (to sort) +For now I'll just copy all config into this file, to confirm that it works properly. +Will reorganise into separate sections later + +** Init.el +#+BEGIN_SRC emacs-lisp + ;;; Initial phase. + + ;; Load the custom file if it exists. Among other settings, this will + ;; have the list `package-selected-packages', so we need to load that + ;; before adding more packages. The value of the `custom-file' + ;; variable must be set appropriately, by default the value is nil. + ;; This can be done here, or in the early-init.el file. + (setq custom-file (locate-user-emacs-file "custom.el")) + (when (and custom-file (file-exists-p custom-file)) + (load custom-file nil 'nomessage)) + + ;; Setup package-archives and priorities + (when (require 'package nil :noerror) + (add-to-list 'package-archives '("stable" . "https://stable.melpa.org/packages/")) + (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) + + (setq package-archive-priorities '(("gnu" . 99) + ("nongnu" . 80) + ("stable" . 70) + ("melpa" . 0)))) + + ;; Add custom modules to the `load-path' + (add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) + + ;; Adds crafted-emacs modules to the `load-path' + (setq crafted-emacs-home (expand-file-name "crafted-emacs" user-emacs-directory)) + (add-to-list 'load-path (expand-file-name "modules" crafted-emacs-home)) + + ;;; Configuration phase + + (setq user-full-name "Evie Litherland-Smith" + user-mail-address "evie@xenia.me.uk") + + ;; Set default coding system (especially for Windows) + (set-default-coding-systems 'utf-8) + (set-terminal-coding-system 'utf-8) + (set-keyboard-coding-system 'utf-8) + + ;; Comment these out as these files will be further sections of this file + ;; (require 'custom-defaults-config) + ;; (pcase system-type ('gnu/linux (require 'custom-ui-config))) + + ;; (require 'custom-email-config) + ;; (require 'custom-feed-config) + ;; (require 'custom-ide-config) + ;; (require 'custom-ligatures-config) + ;; (require 'custom-media-config) + ;; (require 'custom-org-config) + ;; (require 'custom-project-config) + ;; (require 'custom-social-config) + + ;; (require 'crafted-completion-config) + ;; (require 'crafted-ide-config) + ;; (require 'crafted-org-config) + ;; (require 'crafted-workspaces-config) + ;; (require 'crafted-writing-config) + +#+END_SRC + +#+RESULTS: +: utf-8-unix + +** Defaults +#+BEGIN_SRC emacs-lisp + ;;; Code: + (setq load-prefer-newer t + indent-tabs-mode nil + global-auto-revert-non-file-buffers t + dired-auto-revert-buffer t + dired-dwim-target t + tab-always-indent 'complete + completion-cycle-threshold 3 + completions-detailed t + xref-show-definitions-function #'xref-show-definitions-completing-read + kill-do-not-save-duplicates t + auto-window-vscroll nil + fast-but-imprecise-scrolling t + scroll-conservatively 101 + scroll-margin 0 + scroll-preserve-screen-position 1) + + (global-auto-revert-mode +1) + (delete-selection-mode) + + ;; Misc useful keymaps + (keymap-global-set "M-#" #'dictionary-lookup-definition) + (keymap-global-set "C-c r" #'recentf) + (keymap-global-set "C-c b" #'ibuffer) + (keymap-global-set "C-c p l" #'list-packages) + (keymap-global-set "C-c p r" #'package-refresh-contents) + (keymap-global-set "C-c p i" #'package-install) + (keymap-global-set "C-c p d" #'package-delete) + + ;; turn on spell checking, if available. + (when (and (require 'ispell nil :noerror) (executable-find ispell-program-name)) + (add-hook 'text-mode-hook #'flyspell-mode) + (add-hook 'prog-mode-hook #'flyspell-prog-mode)) + + ;; Make shebang (#!) file executable when saved + (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p) + +#+END_SRC + +** UI +#+BEGIN_SRC emacs-lisp + (setq use-dialog-box nil + fill-column 80 + truncate-lines nil + truncate-partial-width-windows nil) + + (menu-bar-mode -1) + (tab-bar-mode -1) + (tool-bar-mode -1) + (scroll-bar-mode -1) + (line-number-mode) + (global-display-line-numbers-mode -1) + (global-prettify-symbols-mode +1) + (global-visual-line-mode +1) + ;; (set-frame-font "FiraCode Nerd Font-12") + ;; (set-frame-parameter nil 'alpha-background 80) + + ;; Nerd-Icons modes + (when (require 'nerd-icons) + (nerd-icons-set-font "Symbols Nerd Font Mono") + (when (require 'nerd-icons-dired nil :noerror) + (add-hook 'dired-mode-hook #'nerd-icons-dired-mode)) + + (when (require 'nerd-icons-ibuffer nil :noerror) + (add-hook 'ibuffer-mode-hook #'nerd-icons-ibuffer-mode)) + + (when (require 'nerd-icons-completion nil :noerror) + (nerd-icons-completion-mode) + (when (require 'marginalia nil :noerror) + (add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup)))) + + ;; Doom-Modeline + (setq doom-modeline-icon t + doom-modeline-mu4e nil ;; Use mu4e own formatting + doom-modeline-modal nil + doom-modeline-modal-icon nil + doom-modeline-persp-name nil + doom-modeline-persp-icon nil) + (when (require 'doom-modeline nil :noerror) + (doom-modeline-mode +1)) + + ;; Dashboard + (setq initial-buffer-choice 'dashboard-open + dashboard-icon-type 'nerd-icons + dashboard-set-heading-icons t + dashboard-set-file-icons t + dashboard-set-navigator t + dashboard-set-init-info t + dashboard-startup-banner 'ascii + dashboard-projects-backend 'project-el + dashboard-projects-switch-function 'project-switch-project + dashboard-projects-show-base t + dashboard-recentf-show-base 'align + dashboard-items '((recents . 5) + (agenda . 15)) + dashboard-heading-icons '((recents . "nf-oct-history") + (agenda . "nf-oct-calendar")) + dashboard-banner-ascii (concat " .000000. \n" + " .0. .0. \n" + " .00. .00. \n" + " .000cl. .lc000. \n" + ".0 0.\n" + "0. .o0000o. .0\n" + " 00 .0' '0. 00 \n" + " 00 .0 0. 00 \n" + " HHHHH HHHHHHHHHHHH HHHHH \n" + "HHHH HHH HHHHHHHHHHHHHH HHHH\n" + " HHHHHH HHHHHHHHH HHHHHHHH \n" + " HHH HHHH HHHHHHHHH HHHH \n" + " HHH HHHHHH \n" + " HHHHH HH \n")) + (when (require 'dashboard nil :noerror) + (keymap-global-set "C-c d" #'dashboard-open) + (add-hook 'dashboard-mode-hook #'khalel-import-events)) + + ;; Extra minor-modes + (when (require 'git-gutter nil :noerror) + (global-git-gutter-mode +1)) + + (when (require 'which-key nil :noerror) + (which-key-mode +1)) + + (when (require 'page-break-lines nil :noerror) + (global-page-break-lines-mode +1)) + + ;;;; Help Buffers + + ;; Make `describe-*' screens more helpful + (when (require 'helpful nil :noerror) + (keymap-set helpful-mode-map " " #'helpful-update) + (keymap-global-set " " #'helpful-command) + (keymap-global-set " " #'helpful-callable) + (keymap-global-set " " #'helpful-key) + (keymap-global-set " " #'helpful-symbol) + (keymap-global-set " " #'helpful-variable) + (keymap-global-set "C-h F" #'helpful-function)) + + ;; Bind extra `describe-*' commands + (keymap-global-set "C-h K" #'describe-keymap) + + ;; add visual pulse when changing focus, like beacon but built-in + ;; from from https://karthinks.com/software/batteries-included-with-emacs/ + (defun pulse-line (&rest _) + "Pulse the current line." + (pulse-momentary-highlight-one-line (point))) + + (dolist (command '(scroll-up-command + scroll-down-command + recenter-top-bottom + other-window)) + (advice-add command :after #'pulse-line)) + + + ;;; custom-ui-config.el ends here + +#+END_SRC + +** Email +#+BEGIN_SRC emacs-lisp + (setq sendmail-program (executable-find "msmtp") + send-mail-function #'smtpmail-send-it + message-sendmail-f-is-evil t + message-sendmail-extra-arguments '("--read-envelope-from") + message-send-mail-function #'message-send-mail-with-sendmail + message-kill-buffer-on-exit t + mail-user-agent 'mu4e-user-agent + read-mail-command 'mu4e + mu4e-maildir "~/Mail" + mu4e-attachment-dir "~/Downloads" + mu4e-get-mail-command "mbsync -a" + mu4e-update-interval (* 5 60) ; Every 5 minutes + mu4e-sent-messages-behavior 'sent + mu4e-change-filenames-when-moving t + mu4e-context-policy 'pick-first + mu4e-use-fancy-chars t + mu4e-headers-thread-single-orphan-prefix '("─>" . "─▶") + mu4e-headers-thread-orphan-prefix '("┬>" . "┬▶") + mu4e-headers-thread-connection-prefix '("│ " . "│ ") + mu4e-headers-thread-first-child-prefix '("├>" . "├▶") + mu4e-headers-thread-child-prefix '("├>" . "├▶") + mu4e-headers-thread-last-child-prefix '("└>" . "╰▶") + mu4e-modeline-all-read '("R:" . "󰑇 ") + mu4e-modeline-all-clear '("C:" . "󰚭 ") + mu4e-modeline-new-items '("N:" . "󰎔 ") + mu4e-modeline-unread-items '("U:" . "󰶊 ") + mu4e-search-full-label '("F" . "󱊖 ") + mu4e-search-hide-label '("H" . "󰘓 ") + mu4e-search-related-label '("R" . "󰌹 ") + mu4e-search-skip-duplicates-label '("D" . "󰆑 ") + mu4e-search-threaded-label'("T" . "󱇫 ") + mu4e-alert-modeline-formatter 'mu4e-alert-default-mode-line-formatter + mu4e-headers-fields '((:human-date . 12) + (:flags . 6) + (:from-or-to . 25) + (:subject)) + mu4e-headers-actions '(("org capture message" . mu4e-org-store-and-capture) + ("capture message" . mu4e-action-capture-message) + ("show this thread" . mu4e-action-show-thread)) + mu4e-maildir-shortcuts '((:maildir "/Proton/Inbox/" :key ?p) + (:maildir "/iCloud/Inbox/" :key ?i) + (:maildir "/Outlook/Inbox/" :key ?w))) + + (when (require 'mu4e nil :noerror) + (keymap-global-set "C-c m m" #'mu4e) + (keymap-global-set "C-c m u" #'mu4e-update-index) + (keymap-global-set "C-c m c" #'mu4e-compose-new) + + (when (require 'mu4e-alert nil :noerror) + (mu4e-alert-set-default-style 'libnotify) + (mu4e-alert-enable-notifications) + (mu4e-alert-enable-mode-line-display)) + + (setq mu4e-contexts (list + (make-mu4e-context + :name "Xenia" + :vars '((user-mail-address . "evie@xenia.me.uk") + (mu4e-sent-folder . "/Proton/Sent") + (mu4e-drafts-folder . "/Proton/Drafts") + (mu4e-trash-folder . "/Proton/Trash") + (mu4e-refile-folder . "/Proton/Archive"))) + (make-mu4e-context + :name "Proton" + :match-func (lambda (msg) (when msg (string-prefix-p "/Proton" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "e.litherlandsmith@proton.me") + (mu4e-sent-folder . "/Proton/Sent") + (mu4e-drafts-folder . "/Proton/Drafts") + (mu4e-trash-folder . "/Proton/Trash") + (mu4e-refile-folder . "/Proton/Archive"))) + (make-mu4e-context + :name "iCloud" + :match-func (lambda (msg) (when msg (string-prefix-p "/iCloud" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "e.litherlandsmith@icloud.com") + (mu4e-sent-folder . "/iCloud/Sent Messages") + (mu4e-drafts-folder . "/iCloud/Drafts") + (mu4e-trash-folder . "/iCloud/Deleted Messages") + (mu4e-refile-folder . "/iCloud/Archive"))) + (make-mu4e-context + :name "Work" + :match-func (lambda (msg) (when msg (string-prefix-p "/Outlook" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "evie.litherland-smith@ukaea.uk") + (mu4e-sent-folder . "/Outlook/Sent") + (mu4e-drafts-folder . "/Outlook/Drafts") + (mu4e-trash-folder . "/Outlook/Trash") + (mu4e-refile-folder . "/Outlook/Archive")))))) + +#+END_SRC + +** Feeds +#+BEGIN_SRC emacs-lisp + (let ((elfeed-base-directory "~/.elfeed")) + (setq elfeed-db-directory (expand-file-name "db" elfeed-base-directory) + elfeed-enclosure-default-dir (expand-file-name "enclosures" elfeed-base-directory) + rmh-elfeed-org-files (list (expand-file-name "feeds.org" elfeed-base-directory)))) + + (when (require 'elfeed nil :noerror) + (keymap-global-set "C-c f f" #'elfeed) + (add-hook 'elfeed-search-mode-hook #'elfeed-update) + (when (require 'elfeed-org nil :noerror) + (elfeed-org)) + (when (require 'elfeed-tube nil :noerror) + (elfeed-tube-setup))) +#+END_SRC + +** IDE +#+BEGIN_SRC emacs-lisp + (when (require 'rainbow-delimiters nil :noerror) + (add-hook 'prog-mode-hook #'rainbow-delimiters-mode)) + + (when (require 'treesit-aut nil :noerror) + (global-treesit-auto-mode +1)) + + (setq apheleia-remote-algorithm 'local) + (when (require 'apheleia nil :noerror) + (keymap-global-set "C-c c f" #'apheleia-format-buffer) + (apheleia-global-mode +1)) + + (when (require 'eglot nil :noerror) + (eglot-ensure)) + + (setq direnv-always-show-summary nil) + (when (require 'direnv nil :noerror) + (direnv-mode +1)) + + (when (require 'yasnippet nil :noerror) + (require 'yasnippet-snippets nil :noerror) + (yas-reload-all) + (add-hook 'prog-mode-hook #'yas-minor-mode)) +#+END_SRC + +*** Ligatures +#+BEGIN_SRC emacs-lisp + (defun fira-code-mode--make-alist (list) + "Generate prettify-symbols alist from LIST." + (let ((idx -1)) + (mapcar + (lambda (s) + (setq idx (1+ idx)) + (let* ((code (+ #Xe100 idx)) + (width (string-width s)) + (prefix ()) + (suffix '(?\s (Br . Br))) + (n 1)) + (while (< n width) + (setq prefix (append prefix '(?\s (Br . Bl)))) + (setq n (1+ n))) + (cons s (append prefix suffix (list (decode-char 'ucs code)))))) + list))) + + (defconst fira-code-mode--ligatures + '("www" "**" "***" "**/" "*>" "*/" "\\\\" "\\\\\\" + "{-" "[]" "::" ":::" ":=" "!!" "!=" "!==" "-}" + "--" "---" "-->" "->" "->>" "-<" "-<<" "-~" + "#{" "#[" "##" "###" "####" "#(" "#?" "#_" "#_(" + ".-" ".=" ".." "..<" "..." "?=" "??" ";;" "/*" + "/**" "/=" "/==" "/>" "//" "///" "&&" "||" "||=" + "|=" "|>" "^=" "$>" "++" "+++" "+>" "=:=" "==" + "===" "==>" "=>" "=>>" "<=" "=<<" "=/=" ">-" ">=" + ">=>" ">>" ">>-" ">>=" ">>>" "<*" "<*>" "<|" "<|>" + "<$" "<$>" "