Renamed dotfiles folder to assets

This commit is contained in:
Random936
2026-02-13 15:17:51 -05:00
parent b062663705
commit f3ea0b7922
61 changed files with 24 additions and 24 deletions

640
assets/.emacs.d/config.org Normal file
View File

@@ -0,0 +1,640 @@
* General Configuration
General configuration is configuration of vanilla Emacs. This includes making Emacs more minimal.
** Global Constants
Constants used throughout my emacs config.
#+begin_src emacs-lisp
(defconst jm/cloud-root "~/Nextcloud")
(defconst jm/notes-directory (expand-file-name "org" jm/cloud-root))
#+end_src
** Disable Error Bell
Disable error bell and visual bell. Visual bell would be nice on Linux, but on mac it is just annoying so I removed it temp.
#+begin_src emacs-lisp
(setq ring-bell-function 'ignore)
(setq visual-bell nil)
#+end_src
** Disable Dialog Box
Disables the dialog prompting box and instead prompts the user in the minibuffer.
#+begin_src emacs-lisp
(setq use-dialog-box nil)
#+end_src
** Global Auto Revert
Enabling global auto revert in Emacs so that changes across a shared file system are synced with emacs buffers.
#+begin_src emacs-lisp
(global-auto-revert-mode 1)
(setq auto-revert-use-notify nil)
(setq auto-revert-verbose 1)
#+end_src
** Relocate Custom File
Change location of custom file. This will stop *custom* from appending to the config file.
#+begin_src emacs-lisp
(setq custom-file "~/.emacs.d/custom.el")
(unless (file-exists-p custom-file)
(make-empty-file custom-file))
(load custom-file)
#+end_src
** Disable Docstring Warnings
#+begin_src emacs-lisp
(setq byte-compile-warnings '(not docstrings))
#+end_src
** Move Backup File
This moves the backup files so that Emacs doesn't clutter up directories with backup files.
#+begin_src emacs-lisp
(setq backup-directory-alist '(("." . "~/.emacs.d/backups/")))
#+end_src
** White Space
Various configuration relating to white-space.
#+begin_src emacs-lisp
(setq-default electric-ident-inhibit t) ; Stop indentation of the previous line.
#+end_src
*** Tabs/Spaces
Disable tabs and replace them with a custom number of spaces.
#+begin_src emacs-lisp
(setq-default indent-tabs-mode nil) ; Use spaces instead of tabs.
(setq-default tab-width 4)
(setq-default evil-shift-width tab-width)
; C Indentation
(setq-default c-basic-offset 4)
; Yara Indentation
(setq-default yara-indent-offset 4)
(setq-default yara-indent-section 4)
#+end_src
*** Visualizing White Space
Add a nice visualization for tabs and spaces. This can be helpful to identify which is which quickly to avoid submitting poorly spaced code.
#+begin_src emacs-lisp
(global-whitespace-mode)
(setq whitespace-global-modes '(not org-mode dired-mode erc-mode))
(setq whitespace-style '(face tabs spaces tab-mark space-mark trailing))
(custom-set-faces
'(whitespace-tab ((t (:foreground "#384551"))))
'(whitespace-space ((t (:foreground "#384551")))))
(setq whitespace-display-mappings
'((tab-mark 9 [187 9] [92 9])
(space-mark 32 [183] [46])))
#+end_src
** SSH Remoting with Tramp
Below are a few configuration changes to avoid TRAMP freezes when attempting to SSH into another system with more complex config files.
#+begin_src emacs-lisp
(setq tramp-remote-shell "/bin/sh")
(setq tramp-remote-shell-login "-l")
(setq tramp-remote-shell-args "-c")
#+end_src
** Updating PATH from User Shell
This package fixes issues with the path on MacOS by pulling the ~$PATH~ variable from the user's shell.
#+begin_src emacs-lisp
(use-package exec-path-from-shell
:config
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize)))
#+end_src
* Package Manager
Emacs and packages. Pretty much a requirement.
** Setup package
Initialize *package* and setup package archives. This lets you install packages from other archives such as [[https://melpa.org/][melpa]].
#+begin_src emacs-lisp
(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")
("elpa" . "https://elpa.gnu.org/packages/")))
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
#+end_src
** Use-package
Install use package for easier installation of other packages.
#+begin_src emacs-lisp
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t)
(setq use-package-compute-statistics t)
#+end_src
* Cosmetic
Packages that change the look of Emacs in some way.
** Cosmetic Configuration
Disable the useless features that make Emacs bloated.
#+begin_src emacs-lisp
; Disable startup message
(setq inhibit-startup-message t)
(scroll-bar-mode -1) ; Disable scrollbar
(tool-bar-mode -1) ; Disable toolbar
(tooltip-mode -1) ; Disable tooltips
(menu-bar-mode -1) ; Disable menu-bar
(set-fringe-mode 10) ; Add gaps on left and right
(setq scroll-margin 4) ; Scroll as cursor reaches bottom/top of page.
#+end_src
*** Change font
Pretty self explanatory.
#+begin_src emacs-lisp
(defun jm/set-font-faces ()
(set-face-attribute 'default nil :font "Maple Mono" :height 140))
#+end_src
Adding a fix for fonts when running Emacs as a daemon.
#+begin_src emacs-lisp
(if (daemonp)
(add-hook 'after-make-frame-functions
(lambda (frame)
(with-selected-frame frame
(jm/set-font-faces))))
(jm/set-font-faces))
#+end_src
** Doom Modeline
Use doom modeline to make the modeline look nicer.
#+begin_src emacs-lisp
(use-package all-the-icons) ; requirement
(use-package doom-modeline
:init (doom-modeline-mode 1)
:config
(setq doom-modeline-height 45)
(display-time))
#+end_src
In order to avoid missing icons, you should also install the package ~all-the-icons-install-fonts~ through the Emacs command line.
** Doom Themes
Install doom themes for better themes.
#+begin_src emacs-lisp
(use-package doom-themes
:init (load-theme 'doom-city-lights t))
#+end_src
** Rainbow Delimiters
Colors parenthesis for better lisp syntax highlighting.
#+begin_src emacs-lisp
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
#+end_src
** Line Numbers
This adds relative line numbers while excluding certain modes.
#+begin_src emacs-lisp
; Disable line numbers for certain modes
(dolist (mode '(org-mode-hook
erc-mode-hook
mu4e-main-mode-hook
term-mode-hook
vterm-mode-hook
shell-mode-hook
eshell-mode-hook))
(add-hook mode (lambda () (display-line-numbers-mode 0))))
; Enable relative line numbers
(setq-default display-line-numbers-type 'visual)
(global-display-line-numbers-mode t)
#+end_src
* Keybindings
Contains the configuration for any keybindings or packages relating to keybindings.
** General Configurations
Remap quit command to make it easier to rescue a buffer. With this function, escape will be used instead of ~C-g~.
#+begin_src emacs-lisp
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
#+end_src
** Which-key
Lists all possible keybindings off of prefix.
#+begin_src emacs-lisp
(use-package which-key
:init (which-key-mode)
:diminish which-key-mode)
#+end_src
** General
General allows you to setup a prefix key easily. This makes it really easy to setup a bunch of keybindings with ease.
#+begin_src emacs-lisp
(use-package general
:config
(general-create-definer jm/leader-keys
:keymaps '(normal insert visual emacs)
:prefix "SPC"
:global-prefix "C-SPC")
(jm/leader-keys
; Emacs related keybindings
"r" '(rename-buffer :which-key "Rename buffer")
"er" '((lambda () (interactive) (load-file "~/.emacs")) :which-key "Reload emacs config")
"es" '(eshell :which-key "Open eshell terminal")))
#+end_src
** Evil
Evil is a package that adds vim keybindings to Emacs.
#+begin_src emacs-lisp
;; Setup vim keybindings with evil
(use-package evil
:init
(setq evil-want-integration t)
(setq evil-want-keybinding nil) ; replaced with evil collection
(setq evil-want-C-u-scroll t)
(setq evil-want-C-i-jump nil)
:config
(evil-mode 1)
(define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state)
(define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join)
; Use visual line motions even outside of visual-line-mode buffers.
(evil-global-set-key 'motion "j" 'evil-next-visual-line)
(evil-global-set-key 'motion "k" 'evil-previous-visual-line)
; Modify which modes use vim keybindings.
(evil-set-initial-state 'messages-buffer-mode 'normal)
(evil-set-initial-state 'dashboard-mode 'normal))
#+end_src
*** Evil Collection
Evil collection is a package that replaces the bad ~evil-want-keybinding~ keybindings.
#+begin_src emacs-lisp
(use-package evil-collection
:after evil
:config (evil-collection-init))
#+end_src
*** Evil Numbers
The /Evil Numbers/ package implements the ability to increment or decrement numbers as you would with vim using ~C-a~ and ~C-x~.
#+begin_src emacs-lisp
(use-package evil-numbers
:after evil
:config
(evil-define-key '(normal visual) 'global (kbd "C-c =") 'evil-numbers/inc-at-pt)
(evil-define-key '(normal visual) 'global (kbd "C-c -") 'evil-numbers/dec-at-pt)
(evil-define-key '(normal visual) 'global (kbd "C-c C-=") 'evil-numbers/inc-at-pt-incremental)
(evil-define-key '(normal visual) 'global (kbd "C-c C--") 'evil-numbers/dec-at-pt-incremental))
#+end_src
** Undo-Tree
Undo tree's use is self explanatory. While the built-in Emacs undo system is fine for me, *undo-tree* is required as it fixes an issue with evil where you can't redo.
#+begin_src emacs-lisp
; Fix vim redo with undo tree
(use-package undo-tree
:after evil
:config
(evil-set-undo-system 'undo-tree)
(setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))
(global-undo-tree-mode 1))
#+end_src
* Other Packages
This is a list of installed packages not included in any other category.
** MacOS Environment Fix
When using emacs on MacOS, the environment variables are not synced properly and therefore require a separate package to fix this. In this case, this package is the ~exec-path-from-shell~.
#+begin_src emacs-lisp
;(use-package exec-path-from-shell
;:config
;(when (memq window-system '(mac ns x))
;(exec-path-from-shell-initialize)))
#+end_src
** Perspective
*Perspective* is a package to help with managing buffers. It allows for multiple /workspaces/ or /perspectives/ which each contain their own sub list of buffers.
#+begin_src emacs-lisp
(use-package perspective
:bind (("C-x b" . persp-switch-to-buffer*)
("C-x k" . persp-kill-buffer*))
:custom (persp-mode-prefix-key (kbd "C-x w"))
:init (persp-mode))
#+end_src
** Projectile
Projectile is a package for managing various /projects/ in emacs. It adds functionality to let you interact with various /projects/ such as quickly searching filenames, switching between all projects, grepping all files, etc.
#+begin_src emacs-lisp
(use-package projectile
:bind-keymap
("C-x p" . projectile-command-map)
:config
(projectile-mode +1)
:init
(when (file-directory-p "~/Projects")
(setq projectile-project-search-path '("~/Projects"))))
#+end_src
** Vertico
Vertico is a package that implements a drop-down like menu in the mini buffer allowing for much better searching.
#+begin_src emacs-lisp
(use-package vertico
:init
(vertico-mode))
#+end_src
When installing Vertico, the documentation mentions a few other packages that add some nice features that would come by default with something like /ivy/. I've added some descriptions of these below:
- ~savehist~ - One feature of Vertico that is really helpful is it's seamless integration with the built-in emacs package, ~savehist~, to save command history when navigating.
- ~marginalia~ - Similar to the definition of /marginalia/, this emacs package implements descriptions besides each option in Vertico completion. Some examples of this would be definitions for Elisp functions, more verbose file information, etc.
- ~orderless~ - By default, Vertico starts its completion from the start of the search the same way as default emacs completion. The ~orderless~ package changes this by implementing a nicer completion that searches for any similar options based on the provided search terms.
- ~consult~ - Adds a bunch of helpful search and navigation commands such as recursive file grepping, etc.
#+begin_src emacs-lisp
(use-package savehist
:init
(savehist-mode))
(use-package marginalia
:after vertico
:init
(marginalia-mode))
(use-package orderless
:custom
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion)))))
(use-package consult
:after vertico
:config
(jm/leader-keys
"pg" 'consult-git-grep
"pf" 'consult-find))
#+end_src
** Helpful
*Helpful* is a package that improves the builtin Emacs help menus. The config below installs helpful and sets the keybindings to call helpful functions instead of the default emacs help.
#+begin_src emacs-lisp
(use-package helpful
:bind (("C-h f" . #'helpful-callable)
("C-h v" . #'helpful-variable)
("C-h k" . #'helpful-key)
("C-h x" . #'helpful-command)))
#+end_src
** Magit
*Magit* adds several features to Emacs that make using git easier.
#+begin_src emacs-lisp
(use-package magit
:bind (("C-x g" . magit-status)
("C-x C-g" . magit-status))
:config
(jm/leader-keys "gc" 'magit-clone))
#+end_src
** Dashboard
The Emacs dashboard package provides a nice dashboard when first starting up emacs.
#+begin_src emacs-lisp
(use-package dashboard
:init
(setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*"))
dashboard-startup-banner 'logo
dashboard-icon-type 'nerd-icons
dashboard-set-file-icons t
dashboard-set-heading-icons t
dashboard-items '((projects . 5)
(recents . 5)
(agenda . 5)))
:config
(set-face-attribute 'dashboard-items-face nil :font "Maple Mono" :height 140)
(dashboard-setup-startup-hook))
#+end_src
** Ledger
Ledger is a Unix program that implements a finance tracking system or /ledger/. To implement this into emacs, you can install the ~ledger-mode~ emacs package.
#+begin_src emacs-lisp
(use-package ledger-mode
:mode ("\\.ledger\\'")
:config
(setq ledger-report-use-strict t
ledger-master-file (expand-file-name "Ledger/toc.ledger" jm/cloud-root)
ledger-accounts-file (expand-file-name "Ledger/accounts.ledger" jm/cloud-root))
(setq ledger-reports
`(("bal" ,(format "%%(binary) -f %s bal" ledger-master-file))
("budget" ,(format "%%(binary) -f %s --budget -p 'this month' bal Expenses" ledger-master-file))
("account" ,(format "%%(binary) -f %s reg %%(account)" ledger-master-file))
("monthly bal" ,(format "%%(binary) -f %s bal -p 'this month'" ledger-master-file))
("daily bal" ,(format "%%(binary) -f %s bal -p 'today'" ledger-master-file)))))
#+end_src
** Alert
Alert is another library that better implements system notifications through emacs. As I use both MacOS and Linux, notifications don't work out of the box for both systems. Using alert, I can change this by selecting a working notify system for each OS.
#+begin_src emacs-lisp
(use-package alert
:config
(setq alert-default-style
(if (eq system-type 'darwin)
'osx-notifier
'libnotify)))
#+end_src
* Builtin Package Config
** Dired
Dired is a built-in package in Emacs that allows for basic file navigation. While it serves its purpose, vanilla dired is far from a good file navigator. With some basic customization however, this can be changed.
#+begin_src emacs-lisp
(use-package dired
:ensure nil ; Melpa won't be able to find this package.
:commands (dired dired-jump)
:bind (("C-x C-j" . dired-jump))
:custom ((dired-listing-switches "-ahgo"))
:config
(evil-collection-define-key 'normal 'dired-mode-map
"h" 'dired-up-directory
"l" 'dired-find-file
"T" 'dired-create-empty-file))
#+end_src
*** All the Icons Dired
~all-the-icons-dired~ is a dired plugin that adds icons to each of the files.
#+begin_src emacs-lisp
(use-package all-the-icons-dired
:after dired
:hook (dired-mode . all-the-icons-dired-mode))
#+end_src
*** Hide Dotfiles
This hides all dotfiles in dired with the keybinding ~H~.
#+begin_src emacs-lisp
(use-package dired-hide-dotfiles
:hook (dired-mode . dired-hide-dotfiles-mode)
:config
(evil-collection-define-key 'normal 'dired-mode-map
"H" 'dired-hide-dotfiles-mode))
#+end_src
** ERC
ERC is a builtin package that adds IRC chatting functionality to emacs.
#+begin_src emacs-lisp
;; Shotcuts for general
(jm/leader-keys
"cc" '(erc-tls :which-key "Connect to IRC over TLS")
"cb" '(erc-switch-to-buffer :which-key "Switch IRC buffers"))
(use-package erc
:ensure nil
:defer t
:custom
(erc-nick "random936")
(erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE"
"353" "324" "329" "332" "333" "353" "477"))
(erc-autojoin-channels-alist '((".*\.libera\.chat" "#emacs" "#gentoo" "#systemcrafters")))
(erc-fill-column 120)
(erc-fill-function 'erc-fill-static)
(erc-fill-static-center 20)
(erc-kill-buffer-on-part t)
(erc-kill-queries-on-quit t)
(erc-kill-server-buffer-on-quit t)
:config
(add-to-list 'erc-modules 'notifications)
;; Fix for perspective.el not adding ERC buffers to active perspective.
(add-hook 'erc-join-hook (lambda (&rest args)
(persp-add-buffer (current-buffer)))))
#+end_src
*** ERC Extensions
To highlight each nickname with a different color, I can use the ~erc-hl-nicks~ package. I can also use the ~erc-image~ package to render images sent by other users over IRC.
#+begin_src emacs-lisp
(use-package erc-hl-nicks
:after erc
:config (add-to-list 'erc-modules 'hl-nicks))
(use-package erc-image
:after erc
:config
(setq erc-image-inline-rescale 300)
(add-to-list 'erc-modules 'image))
#+end_src
*** ERC Alert Integration
Alert is a notification system that works with MacOS, however it is not integrated by default. To fix this, you need to create a function to hook with the ERC text matching.
#+begin_src emacs-lisp
(defun jm/erc-alert-integration (match-type nick message)
(alert message :title (format "%s in %s" nick (buffer-name)) :category 'erc))
(add-hook 'erc-text-matched-hook 'jm/erc-alert-integration)
#+end_src
* Import Other Files
This is the section to include imports from other files.
#+begin_src emacs-lisp
(defun jm/load-config-if-exists (file-path)
(if (file-exists-p file-path)
(org-babel-load-file file-path)
(warn (concat "Failed to load config: " file-path))))
(jm/load-config-if-exists "~/.emacs.d/functions.org") ; Personal Elisp Functions
(jm/load-config-if-exists "~/.emacs.d/org.org") ; Org-mode
(jm/load-config-if-exists "~/.emacs.d/lsp.org") ; Language Server Protocol
(jm/load-config-if-exists "~/.emacs.d/terminal.org") ; Emacs Terminal
(jm/load-config-if-exists "~/.emacs.d/email.org") ; Mu4e/SMTP Config
;; Load EXWM configuration if environment variable set.
(let ((exwm-org-file "~/.emacs.d/exwm.org"))
(when (and (file-exists-p exwm-org-file) (getenv "USING_EXWM"))
(org-babel-load-file exwm-org-file)))
#+end_src

151
assets/.emacs.d/email.org Normal file
View File

@@ -0,0 +1,151 @@
#+TITLE: Email Configuration
* Initial Setup
Before installing any packages with emacs, there is some initial setup that needs to be done.
** Exporting TLS Certificates
After installing the ~proton-mail-bridge~, you will need to export the certificates by going to Settings > Advanced settings > Export TLS certificates. From here you should place this at the path ~~/.config/protonmail/bridge/~.
** Mu4e Installation
In this section, I'm setting up ~mu4e~ to give emacs the capability to send emails using my gmail account. To start, you need to install the ~mu4e~ package outside of Emacs.
#+begin_src bash
yay -S mu
#+end_src
After installing the ~mu~ client, I also need to run a initial index using the following command:
#+begin_src bash
mkdir ~/.mail && mbsync -a
mu init --maildir=~/.mail --my-address=jadenprovost@gmail.com
mu index
#+end_src
* Custom Functions
#+begin_src emacs-lisp
(defconst jm/email-filters-path "~/Nextcloud/filters.json")
(defun jm/any-string-match-p (needles haystack)
(when (listp needles)
(let (result)
(dolist (needle needles result)
(setq result (or result (s-matches-p needle haystack)))))))
(defun jm/load-email-filters (msg)
(let ((filters (append (json-read-file jm/email-filters-path) nil))
(trash-flag (member
(car (mu4e-string-to-flags "T"))
(mu4e-message-field msg :flags)))
folder)
(if trash-flag
"/Trash"
(dolist (filter filters)
(let ((subject (mu4e-message-field msg :subject))
(filter-folder (cdr (assoc-string "folder" filter)))
(subject-filters (append (cdr (assoc-string "subject" filter)) nil))
(from-filters (append (cdr (assoc-string "from-contact" filter)) nil))
(bcc-filters (append (cdr (assoc-string "bcc-contact" filter)) nil)))
(when (or (jm/any-string-match-p subject-filters subject)
(mu4e-message-contact-field-matches msg :from from-filters)
(mu4e-message-contact-field-matches msg :bcc bcc-filters))
(setq folder filter-folder))))
(if folder folder "/Archive"))))
#+end_src
* Mu4e
This section contains the ~mu4e~ emacs specific configuration.
#+begin_src emacs-lisp
(use-package mu4e
:ensure nil
:bind ("C-x m" . mu4e)
:config
(add-hook 'mu4e-compose-mode-hook (lambda () (use-hard-newlines -1)))
(setq mu4e-mu-binary (executable-find "mu")
mu4e-change-filenames-when-moving t ; Avoids syncing issues.
mu4e-search-results-limit 2000 ; Extend header view max message count.
mu4e-compose-format-flowed t) ; Disable hard line wrapping
;; Fix message citation style for gmail.
(setq message-cite-style message-cite-style-gmail
message-citation-line-format "On %a, %b %d, %Y at %H:%M %p %f wrote:"
message-citation-line-function 'message-insert-formatted-citation-line)
;; Refresh mail every X seconds. Set to 5 minutes currently
(setq mu4e-update-interval (* 5 60)
mu4e-get-mail-command "mbsync -a"
mu4e-maildir "~/.mail")
;; Config mu4e folders
(setq mu4e-drafts-folder "/Drafts"
mu4e-sent-folder "/Sent"
mu4e-trash-folder "/Trash"
mu4e-refile-folder #'jm/load-email-filters)
;; Config mu4e bookmarks
(setq mu4e-bookmarks
'((:name "Filtered unread messages" :query "flag:unread AND (maildir:/Archive OR maildir:/INBOX) AND NOT flag:trashed" :key ?u)
(:name "All unread messages" :query "flag:unread" :key ?U)
(:name "Today's messages" :query "date:today..now" :key ?t)
(:name "Last 7 days" :query "date:7d..now" :hide-unread t :key ?w)
(:name "Flagged messages" :query "flag:flagged" :key ?f)))
(setq mu4e-maildir-shortcuts
;; Proton folders
'((:maildir "/INBOX" :key ?i)
(:maildir "/Archive" :key ?a)
(:maildir "/Drafts" :key ?d)
(:maildir "/Sent" :key ?s)
(:maildir "/Spam" :key ?S)
(:maildir "/Trash" :key ?t)
;; My folders
(:maildir "/Folders/Finance" :key ?f)
(:maildir "/Folders/Packages" :key ?p)
(:maildir "/Folders/Work" :key ?w)
(:maildir "/Folders/Club" :key ?c)
(:maildir "/Folders/UCSC" :key ?u)
(:maildir "/Folders/Newsletters" :key ?n))))
#+end_src
Adding some configuration to correct ~mu4e~'s default values.
#+begin_src emacs-lisp
(setq user-full-name "Jaden Provost Maxwell-Comfort")
(setq user-mail-address "jadenprovost@proton.me")
#+end_src
* SMTP
In order to send mail with ~mu4e~, you must also configure an SMTP client. Based on the ~mu4e~ wiki, I was able to shamelessly steal some of the config for the gmail configuration found [[https://www.djcbsoftware.nl/code/mu/mu4e/Gmail-configuration.html][here]].
#+begin_src emacs-lisp
(use-package smtpmail
:after mu4e
:config
(setq smtpmail-stream-type 'starttls
smtpmail-smtp-server "127.0.0.1"
smtpmail-smtp-service 1025))
(setq send-mail-function 'smtpmail-send-it)
#+end_src
When running this however, you need to authenticate by creating an ~~/.authinfo~ file. This file is formatted as follows:
#+begin_src authinfo
# For gmail
machine smtp.gmail.com port 465 login "<USER>" password "<PASS>"
# For Proton Mail
# Copy the remaining information from the proton-mail-bridge for both IMAP and SMTP
machine 127.0.0.1 port <PORT> login "<USER>" password "<PASS>"
machine 127.0.0.1 port <PORT> login "<USER>" password "<PASS>"
#+end_src
Similarly to the password configured above for the IMAP server, you can also pass an ~authinfo.gpg~ file for some added security. If you are using proton mail, make sure this matches the path set in your ~.mbsyncrc~ file.

98
assets/.emacs.d/exwm.org Normal file
View File

@@ -0,0 +1,98 @@
* General Config
This section contains the general configuration for EXWM.
#+begin_src emacs-lisp
(defun jm/exwm-update-class ()
(exwm-workspace-rename-buffer exwm-class-name))
(use-package exwm
:config
; Set default number of workspaces
(setq exwm-workspace-number 5)
; Add key remaps
(start-process-shell-command "xmodmap" nil "xmodmap ~/.Xmodmap")
; Add hook to rename EXWM window to running application name
(add-hook 'exwm-update-class-hook #'jm/exwm-update-class)
;; These keys should always pass through to Emacs
(setq exwm-input-prefix-keys
'(?\C-x
?\C-w
?\C-u
?\C-h
?\M-x
?\M-`
?\M-&
?\M-:
?\C-\M-j ;; Buffer list
?\C-\ )) ;; Ctrl+Space
;; Set up global key bindings. These always work, no matter the input state!
;; Keep in mind that changing this list after EXWM initializes has no effect.
(setq exwm-input-global-keys
`(
;; Reset to line-mode (C-c C-k switches to char-mode via exwm-input-release-keyboard)
([?\s-r] . exwm-reset)
;; Move window to other workspace
([?\s-m] . exwm-workspace-move-window)
;; Launch applications via shell command
([?\s-&] . (lambda (command)
(interactive (list (read-shell-command "$ ")))
(start-process-shell-command command nil command)))
;; Switch workspace
([?\s-w] . exwm-workspace-switch)
([?\s-`] . (lambda () (interactive) (exwm-workspace-switch-create 0)))
;; 's-N': Switch to certain workspace with Super (Win) plus a number key (0 - 9)
,@(mapcar (lambda (i)
`(,(kbd (format "s-%d" i)) .
(lambda ()
(interactive)
(exwm-workspace-switch-create ,i))))
(number-sequence 0 9))))
(exwm-enable))
#+end_src
* Randr
EXWM Randr is a built-in plugin that allows you to add two monitor support. By default EXWM merges the two monitors into one making the desktop environment unusable.
#+begin_src emacs-lisp
(use-package exwm-randr
:ensure nil
:config
(exwm-randr-enable)
(start-process-shell-command "xrandr" nil "xrandr --output HDMI-1 --mode 2560x1080 --pos 0x694 --rotate normal --output DP-0 --off --output DP-1 --primary --mode 3440x1440 --pos 2560x0 --rotate normal --output DP-2 --off --output DP-3 --off --output DP-4 --off --output DP-5 --off")
;; This will need to be updated to the name of a display! You can find
;; the names of your displays by looking at arandr or the output of xrandr
(setq exwm-randr-workspace-monitor-plist '(2 "HDMI-1" 3 "HDMI-1")))
#+end_src
* System Tray
#+begin_src emacs-lisp
(use-package exwm-systemtray
:ensure nil
:config
(exwm-systemtray-enable))
#+end_src
* Volume Control
To control volume through EXWM you can install the ~pulseaudio-control~ package.
#+begin_src emacs-lisp
(use-package pulseaudio-control
:config
(pulseaudio-control-default-keybindings))
#+end_src

View File

@@ -0,0 +1,230 @@
#+TITLE: Custom Elisp Functions
* Org-Roam
** Refresh Org Roam Agenda
Creates a function to refresh the ~org-agenda-files~ variable to be set to include all org roam notes files.
#+begin_src emacs-lisp
(defun jm/org-roam-refresh-agenda-list ()
(interactive)
(org-roam-db-sync)
(let ((directory (expand-file-name org-roam-dailies-directory org-roam-directory)))
(setq org-agenda-files
(seq-filter
(lambda (file-path) (not (s-starts-with-p directory file-path)))
(org-roam-list-files)))))
#+end_src
** Custom Org-Roam Indexing Functions
Before getting into the main config for Org-roam, I've created a few functions for better indexing nodes stored in the org-roam database. Specifically, these functions separate the org roam dailies nodes from other nodes.
#+begin_src emacs-lisp
(defun jm/org-roam-find-filter (node)
(let ((directory (expand-file-name org-roam-dailies-directory org-roam-directory)))
(string= (file-name-directory (org-roam-node-file node))
directory)))
(defun jm/org-roam-dailies-find ()
(interactive)
(org-roam-node-find nil nil #'jm/org-roam-find-filter))
(defun jm/org-roam-find ()
(interactive)
(org-roam-node-find
nil nil
(lambda (node) (not (jm/org-roam-find-filter node)))))
#+end_src
** Org Roam Dailies Shortcuts
Shortcut to goto todays org-roam dailies document.
#+begin_src emacs-lisp
(defun jm/dailies-file-p ()
(when-let ((file (buffer-file-name))
(file-base (file-name-base (buffer-file-name))))
(s-matches-p "^[0-9]+-[0-9]+-[0-9]+$" file-base)))
(defun jm/org-roam-capture-today ()
(interactive)
(jm/org-roam-goto-day 0 t "t")
(delete-other-windows))
(defun jm/org-roam-goto-day (days &optional force-capture keys)
(let* ((base-time
(if (and (jm/dailies-file-p) (not (eq days 0)))
(date-to-time (file-name-base (buffer-file-name)))
(current-time)))
(rel-time (time-add base-time (days-to-time days)))
(path (format-time-string "%Y-%m-%d.org" rel-time))
(full-path (file-name-concat org-roam-directory "daily" path)))
(jm/org-roam-refresh-agenda-list)
(if (and (file-exists-p full-path) (not force-capture))
(find-file full-path)
(org-roam-dailies--capture rel-time nil keys))))
(jm/leader-keys
"oy" '((lambda () (interactive) (jm/org-roam-goto-day -1)) :which-key "Open/create yesterday's daily notes file")
"ot" '((lambda () (interactive) (jm/org-roam-goto-day 0)) :which-key "Open/create today's daily notes file")
"ok" '((lambda () (interactive) (jm/org-roam-goto-day 1)) :which-key "Open/create tomorrow's daily notes file"))
#+end_src
* Capture Template Functions
These functions are for my org roam daily capture template.
** Helper Functions
#+begin_src emacs-lisp
(defun jm/dt-filter-tasks (helper query)
(let ((entries (org-map-entries helper query 'agenda)))
(string-join (delq nil entries) "\n")))
(defun jm/dt-format-link (prefix)
(let ((item-name (org-entry-get nil "ITEM"))
(item-id (org-id-get-create))
(doc-title (org-get-title)))
(if doc-title
(format "%s [[id:%s][%s - %s]]" prefix item-id doc-title item-name)
(format "%s [[id:%s][%s]]" prefix item-id item-name))))
(defun jm/dt-concat-todos (todo-lists)
(let ((todos nil))
(dolist (todo todo-lists todos)
(setq todos (append todos (string-lines todo))))
(string-join (delete "" (delete-dups todos)) "\n")))
#+end_src
** Queries
#+begin_src emacs-lisp
(defun jm/dt-get-priority (priority &optional prompt)
(jm/dt-filter-tasks
(lambda () (when (equal priority (org-entry-get nil "PRIORITY"))
(jm/dt-format-link (or prompt "+"))))
"TODO=\"TODO\"|TODO=\"IN PROGRESS\""))
(defun jm/dt-get-status (status &optional prompt)
(jm/dt-filter-tasks (lambda () (jm/dt-format-link (or prompt "+ [ ]")))
(concat "TODO=\"" status "\"")))
(defconst jm/dt-deadline "DEADLINE")
(defconst jm/dt-scheduled "SCHEDULED")
(defun jm/dt-get-within (type days &optional prompt)
(unless (or (eq type jm/dt-deadline) (eq type jm/dt-scheduled))
(error "Invalid type for jm/dt-get-within."))
(let* ((time (or (org-capture-get :default-time) (current-time)))
(date (time-add time (days-to-time days))))
(jm/dt-filter-tasks
(lambda () (when (member (org-get-todo-state) '("TODO" "WAITING" "IN PROGRESS"))
(jm/dt-format-link (or prompt "+"))))
(concat type (format-time-string "<=\"<%Y-%m-%d>\"" date)))))
(defun jm/dt-get-due-within (days &optional prompt)
(jm/dt-get-within jm/dt-deadline days prompt))
(defun jm/dt-get-scheduled-within (days &optional prompt)
(jm/dt-get-within jm/dt-scheduled days prompt))
#+end_src
** Dynamic Habits
#+begin_src emacs-lisp
(defun jm/dt-habit (habit)
(let* ((org-date (or (org-capture-get :default-time) (current-time)))
(today (downcase (format-time-string "%a" org-date))))
(when (seq-contains-p (cdr habit) today)
(car habit))))
(defun jm/dt-habits (habits)
(let ((out-list '()))
(dolist (habit habits out-list)
(when-let (out (jm/dt-habit habit))
(push out out-list)))
(string-join out-list "\n")))
#+end_src
** Weekly Scorecard
Taken from the book /12 Week Year/, the weekly scorecard is a way to measure how well you've been acting on your plan towards your weekly goal. By seeing how effective you're execution is, you are forced to face the objective truths about your productivity.
+ [ ] My test checkbox.
+ [ ] Other checkbox.
+ [X] My test checkbox.
#+begin_src emacs-lisp
(defun jm/checkbox-checked-p (checkbox)
(eq 'on (org-element-property :checkbox checkbox)))
(defun jm/catalog-checkboxes (buffer)
(with-current-buffer buffer
(let* ((filter-fn (lambda (elem) (when (org-element-property :checkbox elem) elem)))
(elem-list (org-element-map (org-element-parse-buffer) 'item filter-fn)))
(delq nil elem-list))))
(defun jm/score-checkboxes (buffer &optional dictionary)
(dolist (box (jm/catalog-checkboxes buffer) dictionary)
(with-current-buffer buffer
(let* ((start (org-element-property :contents-begin box))
(end (progn (goto-char start)
(or (- (search-forward "\n" nil t) 1) (point-max))))
(key (buffer-substring-no-properties start end))
(checked (if (jm/checkbox-checked-p box) 1 0))
(pair (assoc key dictionary))
(counts (cdr pair)))
(if pair
(setcdr pair (list (+ checked (car counts)) (1+ (cadr counts))))
(push (cons key (list checked 1)) dictionary))))))
(defun jm/n-day-scorecard (n &optional start-time)
(let ((time (or start-time (org-capture-get :default-time) (current-time)))
(dailies-directory (expand-file-name org-roam-dailies-directory org-roam-directory))
(dict nil))
(dotimes (i n dict)
(let* ((day (time-subtract time (days-to-time i)))
(file-name (format-time-string "%Y-%m-%d.org" day))
(file-path (expand-file-name file-name dailies-directory))
(open (get-file-buffer file-path))
(buffer (find-file-noselect file-path)))
(setq dict (jm/score-checkboxes buffer dict))
(unless open (kill-buffer buffer))))))
(defun jm/scorecard-table (tasks)
(let* ((separator "|---|---|---|---|\n")
(table (concat "| Task | Completed | Total | Percentage |\n" separator))
(checked-sum 0)
(total-sum 0))
(dolist (box tasks table)
(let* ((name (car box))
(checked (cadr box))
(total (cadr (cdr box)))
(percentage (* (/ (float checked) total) 100)))
(setq total-sum (+ total total-sum)
checked-sum (+ checked checked-sum)
table (format "%s| %s | %d | %d | %d%% |\n"
table name checked total percentage))))
(format "%s%s| Average | %d | %d | %d%% |\n"
table separator checked-sum total-sum
(* (/ (float checked-sum) total-sum) 100))))
(defun jm/scorecard (days &optional start-time)
(interactive)
(jm/scorecard-table (jm/n-day-scorecard days start-time)))
(defun jm/scorecard-from-heading ()
(interactive)
(save-excursion
(save-restriction
(org-back-to-heading-or-point-min)
(org-narrow-to-subtree)
(let* ((score (jm/score-checkboxes (current-buffer)))
(table (jm/scorecard-table score)))
(org-end-of-subtree)
(insert "\n" table "\n")))))
(jm/leader-keys
"os" '(jm/scorecard-from-heading :which-key "Open/create yesterday's daily notes file"))
#+end_src

250
assets/.emacs.d/lsp.org Normal file
View File

@@ -0,0 +1,250 @@
Language servers provide auto completion and syntax highlighting capabilities making them essential for development.
* Lsp Mode
Lsp Mode is a package that adds language server functionalities to Emacs.
** Breadcrumb Header Line
This adds a headerline that shows the scope of where the cursor is in the code. For example if the user is in the main function, the headerline will contain main.
#+begin_src emacs-lisp
(defun jm/lsp-mode-setup ()
(setq lsp-headerline-breadcrumb-segments '(path-up-to-project file symbols))
(lsp-headerline-breadcrumb-mode))
#+end_src
** Install Lsp Mode
Below I am installing the actual package and adding some basic configuration.
#+begin_src emacs-lisp
(use-package lsp-mode
:init (setq lsp-keymap-prefix "C-c l") ; Lsp mode prefix
:hook (lsp-mode . jm/lsp-mode-setup)
:commands (lsp lsp-deferred) ; Startup commands
:config
(lsp-enable-which-key-integration t)
(setq lsp-enable-snippet nil))
#+end_src
** Lsp Additional Packages
#+begin_src emacs-lisp
(use-package lsp-ui
:hook (lsp-mode . lsp-ui-mode)
:config
(setq lsp-ui-sideline-enable t
lsp-ui-show-diagnostics t
lsp-ui-doc-enable t))
#+end_src
** Company Mode
Company is a package that automatically finds completions instead of making the user run a command for completions.
#+begin_src emacs-lisp
(use-package company
:after lsp-mode
:hook (lsp-mode . company-mode)
:bind (:map company-active-map ; Map tab to select completion
("<tab>" . company-complete-selection))
(:map lsp-mode-map
("<tab>" . company-indent-or-complete-common)))
#+end_src
** Flycheck
#+begin_src emacs-lisp
(use-package flycheck
:init (global-flycheck-mode))
#+end_src
** Direnv for Nix-Shell Integration
Direnv is a program that will automatically run ~nix-shell~ when a ~.envrc~ file is found. Using the ~emacs-direnv~ package, you can more easily integrate nix into your development environment.
#+begin_src emacs-lisp
(use-package direnv
:config
(direnv-mode))
#+end_src
* Language Servers
This will include any language server packages and configuration.
** HTML
#+begin_src emacs-lisp
(use-package web-mode
:defer t
:mode ("\\.html\\'" "\\.svelte\\'")
:hook (web-mode . lsp-deferred)
:init
(setq web-mode-engines-alist '(("svelte" . "\\.svelte\\'"))))
#+end_src
** JavaScript/Typescript
#+begin_src emacs-lisp
(use-package typescript-mode
:defer t
:mode ("\\.ts\\'" "\\.js\\'")
:hook (typescript-mode . lsp-deferred))
#+end_src
Install the ~typescript-language-server~ through npm.
#+begin_src sh
npm install -g typescript-language-server
#+end_src
** Python
#+begin_src emacs-lisp
(use-package python-mode
:defer t
:mode ("\\.py\\'")
:hook (python-mode . lsp-deferred))
#+end_src
Install the ~python-lsp-server~ though pip.
#+begin_src sh
pip install python-lsp-server
#+end_src
** C/C++
#+begin_src emacs-lisp
(use-package ccls
:defer t
:hook ((c-mode cc-mode c++-mode objc-mode cuda-mode) .
(lambda () (require 'ccls) (lsp)))
:config
(setq ccls-executable "/usr/bin/ccls"))
#+end_src
Install ~ccls~ with homebrew using the following command.
#+begin_src sh
sudo apt install ccls
#+end_src
** Golang
#+begin_src emacs-lisp
(use-package go-mode
:defer t
:hook (go-mode . lsp-deferred))
#+end_src
** Rust
#+begin_src emacs-lisp
(use-package rustic
:defer t
:hook (rust-mode . lsp-deferred)
:init
(let ((brew-prefix (string-trim (shell-command-to-string "brew --prefix"))))
(when (and (memq window-system '(mac ns x)) brew-prefix (f-directory-p brew-prefix))
(setenv "YARA_LIBRARY_PATH" (expand-file-name "lib" brew-prefix))
(setenv "YARA_INCLUDE_DIR" (expand-file-name "include" brew-prefix)))))
#+end_src
** C#
#+begin_src emacs-lisp
(use-package csharp-mode
:defer t
:hook (csharp-mode . lsp-deferred))
#+end_src
** JSON
#+begin_src emacs-lisp
(use-package json-mode
:defer t
:hook (json-mode . lsp-deferred))
#+end_src
** Yaml
#+begin_src emacs-lisp
(use-package yaml-mode
:defer t
:hook (yaml-mode . lsp-deferred))
#+end_src
** Yara
To install the corresponding LSP, you need to install ~yls~. Using the command ~pip install -U yls-yara~. Keep in mind that ~yls~ is dependent on an up to date version of ~yara-python~.
#+begin_src emacs-lisp
(use-package yara-mode
:defer t
:hook (yara-mode . lsp-deferred)
:config
(with-eval-after-load 'lsp-mode
(add-to-list 'lsp-language-id-configuration
'(yara-mode . "yara"))
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection "yls")
:activation-fn (lsp-activate-on "yara")
:server-id 'yls))))
#+end_src
** R
#+begin_src emacs-lisp
(use-package ess
:defer t
:hook (R-mode . lsp-deferred))
#+end_src
** Haskell
#+begin_src emacs-lisp
(use-package haskell-mode
:defer t
:hook (haskell-mode . lsp-deferred))
(use-package lsp-haskell
:defer t
:hook (lsp-literate-mode . lsp-deferred))
#+end_src
** Ebuild
Ebuild is the language used for Gentoo packages installed with the ~emerge~ utility. As this package is Gentoo specific, you will have to install it the command below:
#+begin_src bash
sudo emerge -v app-emacs/ebuild-mode
#+end_src
#+begin_src emacs-lisp
(use-package ebuild-mode
:ensure nil
:defer t
:hook (ebuild-mode . lsp-deferred))
#+end_src
** Nix
Nix is the language used by NixOS and the Nix package manager.
#+begin_src emacs-lisp
(use-package lsp-nix
:ensure lsp-mode
:after (lsp-mode)
:demand t
:custom (lsp-nix-nil-formatter ["nixpkgs-fmt"]))
(use-package nix-mode
:mode "\\.nix\\'"
:hook (nix-mode . lsp-deferred))
#+end_src

270
assets/.emacs.d/org.org Normal file
View File

@@ -0,0 +1,270 @@
Org is a package that allows you to create files like this one that look nice while also being able to run code. In this file, the code being run is stored in code blocks and all other text is disregarded.
* Org Setup
This installs the org package and creates a setup function to enable/disable certain functionalities.
#+begin_src emacs-lisp
;; Setup org mode
(defun jm/org-mode-setup ()
(org-indent-mode)
(flyspell-mode)
(variable-pitch-mode 1)
(visual-line-mode 1)
(add-to-list 'org-link-frame-setup '(file . find-file))) ; Open link in current window not other window.
(use-package org
:hook ((org-mode . jm/org-mode-setup)
(org-agenda-mode . jm/org-roam-refresh-agenda-list))
:config
(setq jm/inbox-file (expand-file-name "inbox.org" jm/notes-directory)
org-ellipsis ""
org-pretty-entities t
org-hide-emphasis-markers t
org-src-preserve-indentation t
;; Default export configuration
org-export-with-toc nil
org-export-with-section-numbers nil
org-export-with-sub-superscripts nil
org-latex-src-block-backend 'listings
org-format-latex-options (plist-put org-format-latex-options :scale 1.3)
;; Org agenda timestamp formatting
org-display-custom-times t
org-time-stamp-custom-formats '("%m-%d-%y %a" . "%m-%d-%y %a %I:%M %p")
;; Capture templates
org-capture-templates '(("i" "Inbox" entry (file jm/inbox-file)
"* TODO %^{Task}\nDEADLINE: %^t SCHEDULED: %^t")))
(jm/leader-keys
"oa" '(org-agenda :which-key "Org agenda")
"oc" '(org-capture :which-key "Org capture")
"oi" '((lambda () (interactive) (find-file jm/inbox-file)) :which-key "Open inbox file")))
#+end_src
* Cosmetics
** Org-Modern
Org-Modern is a package that adds several features to emacs to make it look more /modern/.
#+begin_src emacs-lisp
(use-package org-modern
:after org
:hook ((org-mode . org-modern-mode)
(org-agenda-finalize . org-modern-agenda))
:config
(setq org-modern-star 'replace
org-modern-replace-stars '("" "" "" "" "" "" "")))
#+end_src
Some examples:
** Font Changes
Org-faces changes the font size of the headings to make them bigger in the org file. Though this code also changes the font to a variable-pitch font. To make it so that only fixed-pitch fonts are used in things like code blocks, *set-face-attribute* is used below.
#+begin_src emacs-lisp
(with-eval-after-load 'org-faces
;; Set faces for heading size levels
(dolist (face '((org-level-1 . 1.2)
(org-level-2 . 1.1)
(org-level-3 . 1.05)
(org-level-4 . 1.0)
(org-level-5 . 1.0)
(org-level-6 . 1.0)
(org-level-7 . 1.0)
(org-level-8 . 1.0)))
(set-face-attribute (car face) nil :font "Maple Mono" :height (cdr face)))
;; Ensure that anything that should be fixed-pitch in Org files appears that way
(set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
(set-face-attribute 'org-table nil :inherit 'fixed-pitch)
(set-face-attribute 'org-formula nil :inherit 'fixed-pitch)
(set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch)
(set-face-attribute 'line-number nil :inherit 'fixed-pitch)
(set-face-attribute 'line-number-current-line nil :inherit 'fixed-pitch))
#+end_src
** Syntax Highlighting in Latex Exports
By default the syntax highlighting for latex/PDF documents exported with Emacs is pretty lackluster. To improve this, I can install the ~engrave-faces~ package.
#+begin_src emacs-lisp
(use-package engrave-faces
:after ox-latex
:config
(setq org-latex-src-block-backend 'engraved))
#+end_src
* Todo Items
** Custom States
Adds custom states to tasks such as ~IN PROGRESS~, ~CANCELLED~, etc. I've also added some changes to the color of the todo items based on the status. For example, turning the task face orange if it is /in progress/.
#+begin_src emacs-lisp
(setq org-todo-keyword-faces
'(("IN PROGRESS" . (:foreground "orange" :weight bold))
("WAITING" . (:foreground "yellow" :weight bold))))
(setq org-modern-todo-faces
'(("IN PROGRESS" . (:background "orange" :foreground "black" :weight bold))
("WAITING" . (:background "yellow" :foreground "black" :weight bold))))
(setq org-todo-keywords
'((sequence
"TODO(t)"
"IN PROGRESS(i)"
"WAITING(w)"
"|"
"DONE(d)"
"CANCELLED(c)"
"FAILED(f)")))
(setq org-clock-in-switch-to-state "IN PROGRESS")
#+end_src
** Refresh Checkboxes
Adds a hook to repeated tasks in org agenda that, when repeated, checkboxes will be reset to an unchecked state.
#+begin_src emacs-lisp
(add-hook 'org-todo-repeat-hook #'org-reset-checkbox-state-subtree)
#+end_src
** Automatic UUIDs
#+begin_src emacs-lisp
(add-hook 'org-after-todo-state-change-hook
(lambda () (when (org-get-todo-state)
(org-id-get-create))))
#+end_src
** Org Agenda
Org mode by default contains an /agenda/ system which is like a basic calendar that allows you to schedule todo items from org documents. All of the todo items from each org document are stored in a central area to allow for a formation of an /agenda/.
#+begin_src emacs-lisp
(setq org-agenda-start-with-log-mode t)
(setq org-log-done 'time)
(setq org-log-into-drawer t)
(setq org-priority-default ?D)
(setq org-priority-lowest ?D)
#+end_src
* Org Roam
Org-roam is a plain-text knowledge management system. It brings some of Roam's more powerful features into the Org-mode ecosystem such as org-file linking, etc. Below is the main config for org-roam.
#+begin_src emacs-lisp
(use-package org-roam
:init (require 'org-roam-dailies)
:custom
(org-roam-directory jm/notes-directory)
(org-roam-node-display-template "${title:60} ${file-title}")
:bind (("C-c n l" . org-roam-buffer-toggle)
("C-c n f" . jm/org-roam-find)
("C-c n d" . jm/org-roam-dailies-find)
("C-c n i" . org-roam-node-insert)
("C-c n c" . org-roam-capture)
("C-c n o" . org-id-get-create)
("C-c n y" . org-roam-dailies-capture-yesterday)
("C-c n t" . org-roam-dailies-capture-today)
("C-c n k" . org-roam-dailies-capture-tomorrow)
("C-c n r" . jm/org-roam-refresh-agenda-list))
:config
;; Config for org-roam capture templates.
(setq jm/org-roam-templates-directory (expand-file-name "templates" org-roam-directory)
org-roam-capture-templates
`(("d" "Default" plain "%?"
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
:unnarrowed t)
("p" "Project" plain
(file ,(expand-file-name "project.org" jm/org-roam-templates-directory))
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n")
:unnarrowed t)
("y" "12 Week Year" plain
(file ,(expand-file-name "12-week-year.org" jm/org-roam-templates-directory))
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n")
:unnarrowed t)))
(setq org-roam-dailies-capture-templates
`(("d" "Default" entry "* %?"
:target (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n"))
("r" "Reflection" entry
(file ,(expand-file-name "reflection.org" jm/org-roam-templates-directory))
:target (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")
:unnarrowed t)
("S" "Weekly Scorecard" entry
(file ,(expand-file-name "weekly-scorecard.org" jm/org-roam-templates-directory))
:target (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")
:unnarrowed t)
("s" "Daily Scorecard" entry
(file ,(expand-file-name "daily-scorecard.org" jm/org-roam-templates-directory))
:target (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")
:unnarrowed t)
("t" "Todos" entry
(file ,(expand-file-name "daily.org" jm/org-roam-templates-directory))
:target (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")
:unnarrowed t)))
;; Create org roam directory and templates directory if not found.
(unless (file-directory-p org-roam-directory)
(make-directory org-roam-directory))
(unless (file-directory-p jm/org-roam-templates-directory)
(make-directory jm/org-roam-templates-directory))
(org-roam-db-autosync-mode))
#+end_src
** Consult Integration
Consult Org Roam is a package that integrates searching from consult with ~org-roam~ which adds functionality such as full text searches over notes.
#+begin_src emacs-lisp
(use-package consult-org-roam
:after org-roam
:bind (("C-c n s" . consult-org-roam-search))
:init (consult-org-roam-mode 1))
#+end_src
* Other Packages
** Evil Org
By default, many of the org specific keybindings do not feel intuitive when using evil mode. ~evil-org~ is a package that attempts to fix this by rebinding many of the default org keybindings to work better with Evil mode.
#+begin_src emacs-lisp
(use-package evil-org
:after org
:hook (org-mode . (lambda () evil-org-mode))
:config
(require 'evil-org-agenda)
(evil-org-agenda-set-keys))
#+end_src
** Fix Snippets
This is required as of org 9.2 as snippets such as ~<s~ don't work. Without this fix, you are required to manually type out structures like code blocks.
#+begin_src emacs-lisp
(require 'org-tempo)
#+end_src
** Ispell
Configure ~Ispell~ to not spell check certain org mode specific keywords. By default, ~Ispell~ doesn't have a default dictionary selected. This can be changed by running ~ispell-change-dictionary~. If no dictionaries are found, you can install them from the ~hunspell-en_us~ pacman package.
#+begin_src emacs-lisp
(add-to-list 'ispell-skip-region-alist '(":\\(PROPERTIES\\|LOGBOOK\\):" . ":END:")) ;
(add-to-list 'ispell-skip-region-alist '("#\\+BEGIN_SRC" . "#\\+END_SRC"))
(add-to-list 'ispell-skip-region-alist '("~" . "~"))
(add-to-list 'ispell-skip-region-alist '("\\[\\[" . "\\]"))
#+end_src

4
assets/.emacs.d/start-exwm.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
export USING_EXWM=t
exec dbus-launch --exit-with-session emacs -mm --debug-init

View File

@@ -0,0 +1,45 @@
Emacs also has the functionality to run a terminal environment. While many other terminals will try to have similar capabilities with keybindings, nothing matches just integrating your terminal in emacs.
* VTerm
VTerm is a terminal emulator written in C. While emacs has a few built-in terminal all of them either lack speed or are missing many escape sequences.
#+begin_src emacs-lisp
(use-package vterm
:config
(setq vterm-max-scrollback 10000)
; Fixes vterm issue with cursor not updating
(advice-add #'vterm--redraw :after (lambda (&rest args) (evil-refresh-cursor evil-state))))
#+end_src
There are a few packages that you need to install in order to use VTerm.
#+begin_src bash
sudo apt install cmake libtool-bin
#+end_src
* Multi-Vterm
Multi-vterm is a package that adds the capability to easily create multiple vterm terminal buffers without having to manually rename them each time.
#+begin_src emacs-lisp
(use-package multi-vterm
:after vterm
:config
(jm/leader-keys
"vj" '(multi-vterm-next :which-key "Go to next vterm window")
"vk" '(multi-vterm-next :which-key "Go to previous vterm window")
"vn" '(multi-vterm :which-key "Create new vterm terminal")))
#+end_src
* Change Terminal Font
When using zsh with powerlevel10k, the ~MesloLGS NF~ font is required to make the prompt align properly. Due to this, this code is implemented to change the font only when VTerm is being used.
#+begin_src emacs-lisp
(add-hook 'vterm-mode-hook
(lambda ()
(set (make-local-variable 'buffer-face-mode-face) '(:family "MesloLGS NF" :height 135))
(buffer-face-mode t)))
#+end_src