Added emacs config

This commit is contained in:
Random936
2025-08-01 21:22:01 -07:00
commit 5ec5e4613b
9 changed files with 946 additions and 0 deletions

30
.emacs Normal file
View File

@@ -0,0 +1,30 @@
; Enable following symlinks
(setq vc-follow-symlinks t)
; Load the main config file for emacs
(require 'org)
(org-babel-load-file
(expand-file-name "config.org"
user-emacs-directory))
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(package-selected-packages
'(alert all-the-icons-dired cape ccls company consult-org-roam corfu
dashboard dired-hide-dotfiles direnv doom-modeline
doom-themes engrave-faces erc-hl-nicks erc-image ess
evil-collection evil-numbers evil-org flycheck general
go-mode haskell-mode helpful json-mode ledger-mode
lsp-haskell lsp-ui magit marginalia mu4e multi-vterm
nix-mode orderless org-modern perspective projectile
python-mode rainbow-delimiters rustic typescript-mode
undo-tree vertico web-mode yaml-mode yara-mode)))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(whitespace-space ((t (:foreground "#384551"))))
'(whitespace-tab ((t (:foreground "#384551")))))

328
.emacs.d/config.org Normal file
View File

@@ -0,0 +1,328 @@
* General Config
** Disable Annoying Features
Disable the useless features that make Emacs bloated.
#+begin_src elisp
(setq ring-bell-function 'ignore
visual-bell nil
use-dialog-box nil
inhibit-startup-message t
scroll-margin 4) ; Scroll as cursor reaches bottom/top of page.
(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
#+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 elisp
(global-auto-revert-mode 1)
(setq auto-revert-use-notify nil)
(setq auto-revert-verbose 1)
#+end_src
** Remap Quit Key
Remap quit command to make it easier to rescue a buffer. With this function, escape will be used instead of ~C-g~.
#+begin_src elisp
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
#+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 elisp
(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
** Line Numbers
This adds relative line numbers while excluding certain modes.
#+begin_src elisp
; 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
** Package Manager Setup
Setting up package archives:
#+begin_src elisp
(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
Installing ~use-package~ macros:
#+begin_src elisp
(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
* Cosmetics
** Update Font
#+begin_src elisp
(defun jm/set-font-faces ()
(set-face-attribute 'default nil :font "Maple Mono" :height 140))
; Fix for fonts when running Emacs as a daemon.
(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 Packages
#+begin_src elisp
(use-package all-the-icons)
(use-package doom-modeline
:init (doom-modeline-mode 1)
:config (display-time))
(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
* Keybindings
** 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 elisp
(use-package general
:config
(general-create-definer jm/leader-keys
:keymaps '(normal insert visual emacs)
:prefix "SPC"
:global-prefix "C-SPC"))
#+end_src
Emacs related keybindings:
#+begin_src elisp
(jm/leader-keys
"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
** Which-Key
#+begin_src elisp
(use-package which-key
:init (which-key-mode)
:diminish which-key-mode)
#+end_src
** Evil
~evil~ is a package that adds vim keybindings to Emacs.
#+begin_src elisp
(use-package evil
:init
(setq evil-want-keybinding nil)
:config
(evil-mode 1))
#+end_src
*** Evil Collection
Collection of ~evil~ keybindings for parts of emacs that are not properly covered by default (eg. ~help-mode~ and ~M-x calendar~).
#+begin_src elisp
(use-package evil-collection
:after evil
:config (evil-collection-init))
#+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 elisp
(use-package undo-tree
:after evil
:config
(setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))
(evil-set-undo-system 'undo-tree)
(global-undo-tree-mode 1))
#+end_src
* Programming
** Auto-completion
*** Corfu
~corfu~ is a package that allows for in-buffer completion.
#+begin_src elisp
(use-package corfu
:custom
(corfu-cycle t)
(tab-always-indent 'complete)
(text-mode-ispell-word-completion nil)
:init
(global-corfu-mode)
(corfu-history-mode))
(use-package dabbrev
:bind (("M-/" . dabbrev-completion)
("C-M-/" . dabbrev-expand))
:config
(add-to-list 'dabbrev-ignored-buffer-regexps "\\` ")
(add-to-list 'dabbrev-ignored-buffer-modes 'authinfo-mode)
(add-to-list 'dabbrev-ignored-buffer-modes 'doc-view-mode)
(add-to-list 'dabbrev-ignored-buffer-modes 'pdf-view-mode)
(add-to-list 'dabbrev-ignored-buffer-modes 'tags-table-mode))
(use-package cape
:defer 10
:init
(add-to-list 'completion-at-point-functions #'cape-file)
(add-to-list 'completion-at-point-functions #'cape-dabbrev))
#+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 elisp
(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 eamples 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 elisp
(use-package savehist
:init (savehist-mode))
(use-package marginalia
:after vertico
:init (marginalia-mode))
(use-package orderless
:custom
(completion-styles '(orderless basic))
(completion-category-defaults nil)
(completion-category-overrides '((file (styles partial-completion)))))
(use-package consult
:after vertico
:config
(jm/leader-keys
"pg" 'consult-git-grep
"pf" 'consult-find))
#+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 elisp
(use-package projectile
:bind-keymap
("C-x p" . projectile-command-map)
:config
(projectile-mode +1)
:init
(when (file-directory-p "~/Developer")
(setq projectile-project-search-path '("~/Developer"))))
#+end_src
** Magit
~magit~ adds several features to Emacs that make using git easier.
#+begin_src elisp
(use-package magit
:bind (("C-x g" . magit-status)
("C-x C-g" . magit-status)))
#+end_src
* Import Other Files
Function to include other config files.
#+begin_src elisp
(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))))
#+end_src
Load other files:
#+begin_src elisp
(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
#+end_src

38
.emacs.d/dired.org Normal file
View File

@@ -0,0 +1,38 @@
* 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 elisp
(use-package dired
:ensure nil
: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 elisp
(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 elisp
(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

230
.emacs.d/functions.org Normal file
View File

@@ -0,0 +1,230 @@
* 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

45
.emacs.d/irc.org Normal file
View File

@@ -0,0 +1,45 @@
* ERC
ERC is a built-in package that adds IRC chatting functionality to emacs.
#+begin_src elisp
;; 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" "#nixos" "#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))
#+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 elisp
(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

21
.emacs.d/lsp.org Normal file
View File

@@ -0,0 +1,21 @@
* Eglot
~eglot~ is the Emacs built-in package for LSP integration.
#+begin_src elisp
(use-package eglot)
#+end_src
* Language Servers
** Rust
#+begin_src emacs-lisp
(use-package rustic
:defer t
: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

252
.emacs.d/org.org Normal file
View File

@@ -0,0 +1,252 @@
* Org
Enable/disable certain ~org~ mode functionalities:
#+begin_src elisp
(defconst jm/cloud-root "~/Nextcloud")
(defconst jm/notes-directory (expand-file-name "org" jm/cloud-root))
(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)))
#+end_src
Setup ~org~ mode:
#+begin_src elisp
(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 elisp
(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
** 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 elisp
(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
* 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

2
.stow-local-ignore Normal file
View File

@@ -0,0 +1,2 @@
\.git
README.org

0
README.org Normal file
View File