diff --git a/README.org b/README.org index 8dcae0d9..9a731ab1 100644 --- a/README.org +++ b/README.org @@ -7,6 +7,7 @@ - [[#set-basic-ui-config][Set basic UI config]] - [[#lets-bootstrap-straightel][Let's bootstrap straight.el]] - [[#fix-nixos][Fix NixOS]] + - [[#spell-check][Spell Check]] - [[#keep-folders-clean][Keep Folders Clean]] - [[#ligatures][Ligatures]] - [[#keybindings][Keybindings]] @@ -90,6 +91,7 @@ Let's start by making some basic ui changes like turning off the scrollbar, tool (setq-default indent-tabs-mode nil) (setq comp-deferred-compilation-deny-list nil) +(setq frame-resize-pixelwise t) #+end_src In order to have this config work on both my desktop with regular joe-schmoe monitors and my laptop with new-hotness HiDPI monitor, I will set the font size if my system is the laptop to much higher. @@ -133,9 +135,6 @@ Then let's make sure line-numbers are relative and on. And let's turn on visual- (global-visual-line-mode +1) #+end_src -#+RESULTS: -: t - I'm adding a terminal to my workflow because sometimes that's better for me. #+begin_src emacs-lisp (defun on-frame-open (frame) @@ -145,8 +144,7 @@ I'm adding a terminal to my workflow because sometimes that's better for me. #+end_src Here are some ui changes I pulled from Doom Emacs -,#+begin_src emacs-lisp - +#+begin_src emacs-lisp ;; always avoid GUI (setq use-dialog-box nil) ;; Don't display floating tooltips; display their contents in the echo-area, @@ -161,16 +159,11 @@ Here are some ui changes I pulled from Doom Emacs split-height-threshold nil) #+end_src -#+RESULTS: - Let's make doc-view better #+begin_src emacs-lisp (setq doc-view-resolution 192) #+end_src -#+RESULTS: -: 192 - I need to fix evil-org and these seems about good as place as any to fix it. #+BEGIN_SRC emacs-lisp (fset 'evil-redirect-digit-argument 'ignore) @@ -181,17 +174,11 @@ Also, real quick let's make sure that ~~ works as the same as ~~ (global-set-key (kbd "") 'keyboard-escape-quit) #+end_src -#+RESULTS: -: keyboard-escape-quit - Let's also turn on =recentf-mode=. #+begin_src emacs-lisp (recentf-mode +1) #+end_src -#+RESULTS: -: t - Finally this is not part of the UI but let's do this early and start the server so I can use emacsclient from my WM. #+begin_src emacs-lisp (server-start) @@ -202,6 +189,12 @@ I will also add my personal scripts to emacs' PATH (add-to-list 'exec-path "/home/chris/scripts") #+end_src +Let's also set org-mode as the scratch buffer mode +#+begin_src emacs-lisp +(setq initial-major-mode 'org-mode) +(setq initial-scratch-message "#+TITLE: SCRATCH\n#+DESCRIPTION: This buffer is for temporary things") +#+end_src + ** Let's bootstrap straight.el To use straight we need to bootstrap it. This code is pulled right from Straight's github repo. #+begin_src emacs-lisp @@ -301,15 +294,40 @@ Let's make parens and other delimiters easier to tell apart by making nested one ** Fix NixOS I am currently using NixOS. In order for emacs to have access to certain programs, we need to set some environment variables -#+begin_src emacs-lisp +#+begin_src emacs-lisp :tangle no (add-to-list 'exec-path "/home/chris/.nix-profile/bin") +(add-to-list 'exec-path "/etc/profiles/per-user/chris/bin") (add-to-list 'exec-path "/run/current-system/sw/bin") +(add-to-list 'exec-path "/opt/android-sdk/cmdline-tools/latest/bin") + +(setq exec-directory "/run/current-system/sw/bin") (setenv "NIX_CONF_DIR" "/etc/nix") (setenv "NIX_OTHER_STORES" "/run/nix/remote-stores/*/nix") (setenv "NIX_PATH" "nixpkgs=%h/nixpkgs:nixos=%h/nixpkgs/nixos:nixos-config=/etc/nixos/configuration.nix") (setenv "NIX_PROFILES" "${pkgs.lib.concatStringsSep " " config.environment.profiles}") (setenv "NIX_REMOTE" "daemon") (setenv "NIX_USER_PROFILE_DIR" "/nix/var/nix/profiles/per-user/%u") +(load "site-paths" t) +#+end_src + +#+begin_src emacs-lisp :tangle no +(use-package exec-path-from-shell + :demand + :commands exec-path-from-shell-initialize + :custom + (exec-path-from-shell-arguments '("-l")) + :config + (exec-path-from-shell-initialize)) +#+end_src +** Spell Check +#+begin_src emacs-lisp +(executable-find "ssh") +(setq ispell-program-name "hunspell" + ispell-local-dictionary "en_US" + ispell-local-dictionary-alist + ;; Please note the list `("-d" "en_US")` contains ACTUAL parameters passed to hunspell + ;; You could use `("-d" "en_US,en_US-med")` to check with multiple dictionaries + '(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US") nil utf-8))) #+end_src ** Keep Folders Clean @@ -437,6 +455,7 @@ This evil-collection package includes a lot of other evil based things. "ht" '(which-key-show-top-level :which-key "show top-level keybindings") "ss" '(consult-line :which-key "consult search") "sr" '(consult-ripgrep :which-key "consult ripgrep") + "oP" '(proced :which-key "proced") "wo" '(other-window :which-key "other window") "wd" '(delete-window :which-key "other window") "wv" '(evil-window-vsplit :which-key "split window vertically") @@ -669,7 +688,8 @@ Part of this config includes some special capture templates for my work as a you "c" 'org-capture "rr" 'org-refile "e" 'org-export-dispatch - "oa" 'org-agenda-list) + "oa" 'org-agenda-list + "gt" 'org-babel-tangle) ('normal org-agenda-mode-map "q" 'org-agenda-quit "r" 'org-agenda-redo @@ -1792,6 +1812,7 @@ Since I like to make my window manager handle a lot of the window management, I ** Help #+begin_src emacs-lisp (use-package helpful + :ensure nil :commands (helpful-callable helpful-variable helpful-command helpful-key) :general (general-def 'normal 'helpful-mode-map @@ -2183,7 +2204,7 @@ Ledger mode #+end_src ** MU4E -#+begin_src emacs-lisp :tangle no +#+begin_src emacs-lisp (use-package mu4e :ensure nil :config @@ -2341,7 +2362,6 @@ Ledger mode "om" 'mu4e) (general-def 'normal mu4e-view-mode-map "ga" 'mu4e-view-save-attachments)) - #+end_src # (use-package org-mime @@ -2457,6 +2477,7 @@ I'd really like to have notifications for when things are scheduled so that I ge Use magit, because why wouldn't you? duh! #+begin_src emacs-lisp (use-package magit + :ensure nil :commands (magit-status magit-get-current-branch) :general (chris/leader-keys @@ -2559,7 +2580,6 @@ Let's add our own eshell prompt. and set the password cache to a significantly h (setenv "ANDROID_SDK_ROOT" "/opt/android-sdk") (setenv "CHROME_EXECUTABLE" "/usr/bin/qutebrowser") (setenv "JAVA_HOME" "/usr/lib/jvm/default") - (setenv "PATH" "/usr/local/bin:/usr/bin:/opt/android-sdk/cmdline-tools/latest/bin") (add-hook 'eshell-mode-hook '(display-line-numbers-mode -1)) @@ -3018,6 +3038,7 @@ Here we have a bunch of performance tweaks ;; receiving input, which should help with performance while scrolling. (setq redisplay-skip-fontification-on-input t) #+end_src + *** Garbage Collection We set the =gc-cons-threshold= variable to really high, now lets set it back low to make sure emacs performs properly. @@ -3073,6 +3094,7 @@ As of right now I haven't fully setup my early-init file, this does not export i ;; ;; we must prevent Emacs from doing it early! ;; (setq package-enable-at-startup nil) ;; (fset #'package--ensure-init-file #'ignore) ; DEPRECATED Removed in 28 +(setq package-enable-at-startup nil) ;; ;; `file-name-handler-alist' is consulted on every `require', `load' and various ;; ;; path/io functions. You get a minor speed up by nooping this. However, this diff --git a/early-init.el b/early-init.el index fd99b6ec..5de208cc 100644 --- a/early-init.el +++ b/early-init.el @@ -19,6 +19,7 @@ ;; ;; we must prevent Emacs from doing it early! ;; (setq package-enable-at-startup nil) ;; (fset #'package--ensure-init-file #'ignore) ; DEPRECATED Removed in 28 +(setq package-enable-at-startup nil) ;; ;; `file-name-handler-alist' is consulted on every `require', `load' and various ;; ;; path/io functions. You get a minor speed up by nooping this. However, this diff --git a/init.el b/init.el index a9f86353..8029997f 100644 --- a/init.el +++ b/init.el @@ -20,6 +20,7 @@ (setq-default indent-tabs-mode nil) (setq comp-deferred-compilation-deny-list nil) +(setq frame-resize-pixelwise t) (if (string-equal (system-name) "syl") (defvar chris/default-font-size 120) @@ -61,6 +62,19 @@ (set-face-background 'default "unspecified-bg" frame))) (add-hook 'after-make-frame-functions 'on-frame-open) +;; always avoid GUI +(setq use-dialog-box nil) +;; Don't display floating tooltips; display their contents in the echo-area, +;; because native tooltips are ugly. +(when (bound-and-true-p tooltip-mode) + (tooltip-mode -1)) +;; ...especially on linux +(setq x-gtk-use-system-tooltips nil) + + ;; Favor vertical splits over horizontal ones. Screens are usually wide. +(setq split-width-threshold 160 + split-height-threshold nil) + (setq doc-view-resolution 192) (fset 'evil-redirect-digit-argument 'ignore) @@ -73,6 +87,9 @@ (add-to-list 'exec-path "/home/chris/scripts") +(setq initial-major-mode 'org-mode) +(setq initial-scratch-message "#+TITLE: SCRATCH\n#+DESCRIPTION: This buffer is for temporary things") + (setq straight-fix-org t) (setq straight-check-for-modifications '(check-on-save find-when-checking)) (defvar bootstrap-version) @@ -138,14 +155,13 @@ (which-key-mode) :defer 1) -(add-to-list 'exec-path "/home/chris/.nix-profile/bin") -(add-to-list 'exec-path "/run/current-system/sw/bin") -(setenv "NIX_CONF_DIR" "/etc/nix") -(setenv "NIX_OTHER_STORES" "/run/nix/remote-stores/*/nix") -(setenv "NIX_PATH" "nixpkgs=%h/nixpkgs:nixos=%h/nixpkgs/nixos:nixos-config=/etc/nixos/configuration.nix") -(setenv "NIX_PROFILES" "${pkgs.lib.concatStringsSep " " config.environment.profiles}") -(setenv "NIX_REMOTE" "daemon") -(setenv "NIX_USER_PROFILE_DIR" "/nix/var/nix/profiles/per-user/%u") +(executable-find "ssh") +(setq ispell-program-name "hunspell" + ispell-local-dictionary "en_US" + ispell-local-dictionary-alist + ;; Please note the list `("-d" "en_US")` contains ACTUAL parameters passed to hunspell + ;; You could use `("-d" "en_US,en_US-med")` to check with multiple dictionaries + '(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US") nil utf-8))) (use-package no-littering) @@ -255,6 +271,7 @@ "ht" '(which-key-show-top-level :which-key "show top-level keybindings") "ss" '(consult-line :which-key "consult search") "sr" '(consult-ripgrep :which-key "consult ripgrep") + "oP" '(proced :which-key "proced") "wo" '(other-window :which-key "other window") "wd" '(delete-window :which-key "other window") "wv" '(evil-window-vsplit :which-key "split window vertically") @@ -472,7 +489,8 @@ "c" 'org-capture "rr" 'org-refile "e" 'org-export-dispatch - "oa" 'org-agenda-list) + "oa" 'org-agenda-list + "gt" 'org-babel-tangle) ('normal org-agenda-mode-map "q" 'org-agenda-quit "r" 'org-agenda-redo @@ -1256,6 +1274,7 @@ targets." "ww" '(ace-window :which-key "select window"))) (use-package helpful + :ensure nil :commands (helpful-callable helpful-variable helpful-command helpful-key) :general (general-def 'normal 'helpful-mode-map @@ -1484,6 +1503,164 @@ targets." (use-package ledger-mode) +(use-package mu4e + :ensure nil + :config + (setq mail-user-agent 'mu4e-user-agent) + (setq mu4e-maildir "~/Maildir" + user-full-name "Chris Cochrun" + mu4e-change-filenames-when-moving t + mu4e-get-mail-command "mbsync -a" + mu4e-update-interval (* 15 60) + mu4e-attachment-dir "/home/chris/nextcloud/home/Documents/attachments" + mu4e-completing-read-function #'completing-read) + + (setq mu4e-contexts + (list + (make-mu4e-context + :name "work" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/office" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "chris@tfcconnection.org") + (mu4e-sent-folder . "/office/Sent Items/") + (mu4e-drafts-folder . "/office/Drafts") + (mu4e-trash-folder . "/office/Deleted Items") + (mu4e-refile-folder . "/office/Archive") + (smtpmail-smtp-user . "chris@tfcconnection.org") + (smtpmail-starttls-credentials . '(("smtp.office365.com" 587 nil nil))) + (smtpmail-auth-credentials . '(("smtp.office365.com" 587 "chris@tfcconnection.org" nil))) + (smtpmail-smtp-server . "smtp.office365.com") + (mu4e-compose-signature . "Praising God in all things,\nChris Cochrun"))) + (make-mu4e-context + :name "outlook" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/outlook" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "chris.cochrun@outlook.com") + (mu4e-sent-folder . "/outlook/Sent/") + (mu4e-drafts-folder . "/outlook/Drafts") + (mu4e-trash-folder . "/outlook/Deleted") + (mu4e-refile-folder . "/outlook/Archive") + (smtpmail-smtp-user . "chris.cochrun@outlook.com") + (mu4e-compose-signature . "Praising God in all things,\nChris Cochrun"))) + (make-mu4e-context + :name "personal" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/cochrun" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "chris@cochrun.xyz") + (mu4e-sent-folder . "/cochrun/Sent/") + (mu4e-drafts-folder . "/cochrun/Drafts") + (mu4e-trash-folder . "/cochrun/Trash") + (mu4e-refile-folder . "/cochrun/Archive") + (smtpmail-smtp-user . "chris@cochrun.xyz") + (smtpmail-starttls-credentials . '(("mail.cochrun.xyz" 587 nil nil))) + (smtpmail-auth-credentials . '(("mail.cochrun.xyz" 587 "chris@cochrun.xyz" nil))) + (smtpmail-smtp-server . "mail.cochrun.xyz") + (mu4e-compose-signature . "Praising God in all things,\nChris Cochrun"))) + (make-mu4e-context + :name "gmail" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/gmail" (mu4e-message-field msg :maildir)))) + :vars '((user-mail-address . "ccochrun21@gmail.com") + (mu4e-sent-folder . "/gmail/[Gmail].Sent Mail/") + (smtpmail-smtp-user . "ccochrun21@gmail.com") + (mu4e-compose-signature . "Praising God in all things,\nChris Cochrun"))))) + + ;; Add the ability to send email + (setq message-send-mail-function 'smtpmail-send-it + starttls-use-gnutls t + smtpmail-default-smtp-server "mail.cochrun.xyz" + smtpmail-smtp-service 587) + + ;; shortcuts in the jumplist by pressing "J" in the mu4e buffer + (setq mu4e-maildir-shortcuts + '((:maildir "/office/Archive" :key ?a) + (:maildir "/office/INBOX" :key ?i) + (:maildir "/cochrun/INBOX" :key ?p) + (:maildir "/outlook/INBOX" :key ?l) + (:maildir "/office/Junk Email" :key ?j) + (:maildir "/office/INBOX/Website Forms" :key ?f) + (:maildir "/gmail/INBOX" :key ?g) + (:maildir "/office/Sent Items" :key ?s))) + + ;; (add-to-list mu4e-headers-actions ("org capture message" . mu4e-org-store-and-capture)) + + (setq mu4e-bookmarks + '((:name "Unread messages" + :query "flag:unread AND NOT flag:trashed AND NOT maildir:\"/outlook/Junk\" AND NOT maildir:\"/office/Junk Email\" AND NOT maildir:\"/outlook/Deleted\" AND NOT maildir:\"/office/Deleted Items\"" + :key 117) + (:name "Today's messages" + :query "date:today..now" + :key 116) + (:name "Last 7 days" + :query "date:7d..now" + :hide-unread t + :key 119) + (:name "Messages with images" + :query "mime:image/*" + :key 112))) + + (setq mu4e-mu-binary "/usr/bin/mu" + mu4e-view-prefer-html nil + shr-color-visible-luminance-min 80) + + (setq mu4e-use-fancy-chars t + mu4e-headers-draft-mark '("D" . "") + mu4e-headers-flagged-mark '("F" . "") + mu4e-headers-new-mark '("N" . " ") + mu4e-headers-passed-mark '("P" . "") + mu4e-headers-replied-mark '("R" . "") + mu4e-headers-seen-mark '("S" . " ") + mu4e-headers-trashed-mark '("T" . " ") + mu4e-headers-attach-mark '("a" . " ") + mu4e-headers-encrypted-mark '("x" . "") + mu4e-headers-signed-mark '("s" . " ") + mu4e-headers-unread-mark '("u" . " ")) + + (setq mu4e-headers-fields + '((:human-date . 12) + (:flags . 6) + (:from . 22) + (:subject))) + + (setq mu4e-view-actions + '(("capture message" . mu4e-action-capture-message) + ("view in browser" . mu4e-action-view-in-browser) + ("show this thread" . mu4e-action-show-thread))) + + (defun chris/setup-mu4e-headers () + (toggle-truncate-lines +1) + (display-line-numbers-mode -1)) + + + (defun chris/setup-mu4e-view () + (display-line-numbers-mode -1) + (toggle-truncate-lines +1) + (setq visual-fill-column-center-text t) + (setq visual-fill-column-width 100) + (visual-fill-column-mode +1)) + + (remove-hook 'mu4e-main-mode-hook '(display-line-numbers-mode -1)) + (add-hook 'mu4e-headers-mode-hook #'chris/setup-mu4e-headers) + (add-hook 'mu4e-view-mode-hook #'chris/setup-mu4e-view) + + + (mu4e t) + :general + (chris/leader-keys + :states 'normal + :keymaps 'override + "om" 'mu4e) + (general-def 'normal mu4e-view-mode-map + "ga" 'mu4e-view-save-attachments)) + (use-package org-msg :hook (mu4e-compose-mode . org-msg-edit-mode) :config @@ -1562,6 +1739,7 @@ targets." (org-wild-notifier-mode +1)) (use-package magit + :ensure nil :commands (magit-status magit-get-current-branch) :general (chris/leader-keys @@ -1660,7 +1838,6 @@ targets." (setenv "ANDROID_SDK_ROOT" "/opt/android-sdk") (setenv "CHROME_EXECUTABLE" "/usr/bin/qutebrowser") (setenv "JAVA_HOME" "/usr/lib/jvm/default") - (setenv "PATH" "/usr/local/bin:/usr/bin:/opt/android-sdk/cmdline-tools/latest/bin") (add-hook 'eshell-mode-hook '(display-line-numbers-mode -1))