Compare commits

...

10 commits

Author SHA1 Message Date
d22c40a7c4 Changes for Claude 2026-09-11 10:34:12 -05:00
150efd922e New packages 2026-09-11 10:33:50 -05:00
9b3d56e418 No tree-sitter for Nix 2026-09-11 10:32:59 -05:00
4d6b1e0e98 Other niceities 2026-09-11 09:43:23 -05:00
dc727a4992 Org Mode Enhancements 2026-09-11 09:42:14 -05:00
c8e8ea71c7 AI Enhancements 2026-09-11 09:41:17 -05:00
c4d2e452b7 Remove Pocket (RIP) 2026-09-11 09:31:41 -05:00
b1fbc1d2da Fix org-hugo link export to render proper Markdown links
- Handle http/https/ftp links explicitly using :raw-link for full URL
- Resolve org-id links via org-id-find to use filename slug instead of raw UUID
- Replace unused path alias with raw-link property

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 14:07:43 -06:00
5594248f21 Add CLAUDE.md and update Doom Emacs config
- Add CLAUDE.md for Claude Code guidance
- Update gptel config to use Claude Sonnet 4 with key from ~/.secrets/claude_key
- Update elfeed filters to exclude -wait tag
- Enable terraform module in init.el
- Update org agenda files for 2026
- Fix org-hugo link rendering for vanilla Markdown

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 13:43:50 -06:00
c0186c8b7e Update Doom Config for 5/22 2025-05-22 20:51:27 -05:00
4 changed files with 480 additions and 156 deletions

53
CLAUDE.md Normal file
View file

@ -0,0 +1,53 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Repository Purpose
Personal dotfiles repository for Shawn Borton's development environment. Configs for Doom Emacs, Vim, Bash, and tmux — primarily targeting Linux (Arch Linux and NixOS systems: archie, peregrine) with some historical macOS artifacts.
## File Overview
| File | Purpose |
|------|---------|
| `config.el` | Primary Doom Emacs private config (keybindings, UI, packages config) |
| `init.el` | Doom Emacs module selection |
| `packages.el` | Additional Doom Emacs package declarations |
| `.vimrc` | Vim config with vim-plug plugin manager |
| `.bash_profile` | Shell aliases, prompt, NVM setup |
| `.tmux.conf` | tmux keybindings and status bar |
## Doom Emacs Workflow
After editing `config.el`, `init.el`, or `packages.el`:
```bash
doom sync # Sync packages and modules (required after packages.el changes)
doom reload # Reload config without restarting (for config.el/init.el changes)
```
## Key Conventions
**Doom Emacs:**
- Uses Evil mode with `jk` as the escape sequence
- Leader key bindings are defined in `config.el` under `map!` blocks
- Custom packages are declared in `packages.el` using `package!` with optional `:recipe` for git sources
- Modules are toggled in `init.el` with flags like `(python +lsp +pyright +tree-sitter)`
- Fonts: JetBrains Mono (14pt) for fixed-pitch, Overpass Nerd Font (18pt) for variable-pitch
- Theme: `doom-oceanic-next`
**Vim:**
- Plugin manager: vim-plug (auto-installs to `~/.vim/autoload/plug.vim` on first run)
- Run `:PlugInstall` after adding new plugins to `.vimrc`
**tmux:**
- Prefix is `C-a` (not the default `C-b`)
- Reload config with `C-a r`
## Notable Integrations in config.el
- **Elfeed** (RSS): Connects to a self-hosted Fever API at `rss.onionpatch.cloud`; feeds are tagged and filtered with custom keybindings under the leader key
- **Pocket**: Integrated with elfeed for article saving via `pocket-reader`
- **gptel / chatgpt-shell**: LLM/ChatGPT integration packages declared in `packages.el`
- **org-roam**: Unpinned in `packages.el` for a custom version; roam2 module enabled in `init.el`
- **Dired**: Custom `h`/`l` navigation keys; Thunar integration for GUI file manager

397
config.el
View file

@ -2,9 +2,24 @@
;; Place your private configuration here! Remember, you do not need to run 'doom ;; Place your private configuration here! Remember, you do not need to run 'doom
;; sync' after modifying this file! ;; sync' after modifying this file!
;; ** Default Init File
;; Load the default init file. This is the place where distro packagers can place
;; their own configuration. Doom disables it as an optimization, but it's useful
;; for storing information that can only reliably be obtained through package
;; managers. More specifically, it's used in this dotfiles to specify the full path
;; to some commands used by Doom. Doing so removes the need to clutter =PATH= with
;; commands not needed outside of Doom.
;;
;;
;;#+begin_src emacs-lisp
;;(load "default" 'noerror 'nomessage)
;;#+end_src
;; Sane defaults ;; Sane defaults
(defvar is-archie-p (equal (system-name) "archie")) (defvar is-archie-p (equal (system-name) "archie"))
(defvar is-peregrine-p (equal (system-name) "peregrine"))
(defvar is-macos-p (equal (system-name) "Shawns-Macbook-Pro.local")) (defvar is-macos-p (equal (system-name) "Shawns-Macbook-Pro.local"))
(setq-default window-combination-resize t) (setq-default window-combination-resize t)
(setq global-auto-revert-non-file-buffers t) (setq global-auto-revert-non-file-buffers t)
@ -13,8 +28,11 @@
password-cache-expiry nil ; Trust your computers. password-cache-expiry nil ; Trust your computers.
scroll-margin 2 ; It's nice to maintain a little margin scroll-margin 2 ; It's nice to maintain a little margin
window-resize-pixelwise t window-resize-pixelwise t
reb-re-syntax 'string ; Normalize Emacs regexps
) )
(setq auth-sources "~/.authinfo.gpg") ;;; (setq auth-sources "~/.authinfo.gpg")
;;;(setq auth-sources
;;; '((:source "~/.authinfo.gpg")))
(display-time-mode 1) (display-time-mode 1)
(global-subword-mode 1) (global-subword-mode 1)
@ -49,11 +67,12 @@
;; `load-theme' function. This is the default: ;; `load-theme' function. This is the default:
;;(use-package! all-the-icons) ;;(use-package! all-the-icons)
(setq doom-font (font-spec :family "JetBrains Mono" :style "Regular" :size 14) (setq doom-font (font-spec :family "JetBrains Mono" :style "Regular" :size 14)
doom-variable-pitch-font (font-spec :family "JetBrains Mono" :size 18) doom-variable-pitch-font (font-spec :family "Overpass Nerd Font" :style "Regular" :size 18)
doom-big-font (font-spec :family "JetBrains Mono" :style "Regular" :size 26)) doom-big-font (font-spec :family "JetBrains Mono" :style "Regular" :size 26))
(defvar sb-org-font (font-spec :family "Source Code Pro" :style "Regular" :size 14)) (defvar sb-org-font (font-spec :family "SauceCodePro" :style "Regular" :size 14))
(setq doom-theme 'doom-nord) ;; (setq doom-theme 'doom-nord)
(setq doom-theme 'doom-oceanic-next)
(after! doom-themes (after! doom-themes
;;(load-theme 'doom-nano-dark t) ;;(load-theme 'doom-nano-dark t)
(setq doom-themes-enable-bold t (setq doom-themes-enable-bold t
@ -61,6 +80,10 @@
(map! :leader (map! :leader
:desc "Load new theme" :desc "Load new theme"
"h t" #'counsel-load-theme) "h t" #'counsel-load-theme)
(funcall (lambda ()
(set-frame-parameter nil 'alpha-background 95)
(add-to-list 'default-frame-alist '(alpha-background . 95))
))
;; This determines the style of line numbers in effect. If set to `nil', line ;; This determines the style of line numbers in effect. If set to `nil', line
;; numbers are disabled. For relative line numbers, set this to `relative'. ;; numbers are disabled. For relative line numbers, set this to `relative'.
@ -77,7 +100,7 @@
;; remove the modes from `doom-modeline-continuous-word-count-modes'. ;; remove the modes from `doom-modeline-continuous-word-count-modes'.
;; ;;
(after! doom-modeline (after! doom-modeline
(setq doom-modeline-height 18) (setq doom-modeline-height 28)
(setq doom-modeline-bar-width 6) (setq doom-modeline-bar-width 6)
(setq doom-modeline-enable-word-count t) (setq doom-modeline-enable-word-count t)
(setq doom-modeline-continuous-word-count-modes '(markdown-mode org-mode))) (setq doom-modeline-continuous-word-count-modes '(markdown-mode org-mode)))
@ -90,6 +113,10 @@
(consult-buffer)) (consult-buffer))
(setq +ivy-buffer-preview t) (setq +ivy-buffer-preview t)
;; Escape insert mode with 'jk':
(after! evil-escape
(setq! evil-escape-key-sequence "jk"))
;; Here are some additional functions/macros that could help you configure Doom: ;; Here are some additional functions/macros that could help you configure Doom:
;; ;;
;; - `load!' for loading external *.el files relative to this one ;; - `load!' for loading external *.el files relative to this one
@ -170,18 +197,18 @@
;; (map! :leader ;; (map! :leader
;; :desc "Edit agenda file" ;; :desc "Edit agenda file"
;; "- a" #'(lambda () (interactive) (find-file "~/Org/agenda.org")) ;; "- a" #'(lambda () (interactive) (find-file "~/Org/agenda.org"))
(map! :leader ;; (map! :leader
:desc "Edit eshell aliases" ;; :desc "Edit eshell aliases"
"- e" #'(lambda () (interactive) (find-file "~/.doom.d/aliases")) ;; "- e" #'(lambda () (interactive) (find-file "~/.doom.d/aliases"))
:leader ;; :leader
:desc "Edit doom init.el" ;; :desc "Edit doom init.el"
"- i" #'(lambda () (interactive) (find-file "~/.doom.d/init.el")) ;; "- i" #'(lambda () (interactive) (find-file "~/.doom.d/init.el"))
:leader ;; :leader
:desc "Edit doom config.el" ;; :desc "Edit doom config.el"
"- c" #'(lambda () (interactive) (find-file "~/.doom.d/config.el")) ;; "- c" #'(lambda () (interactive) (find-file "~/.doom.d/config.el"))
:leader ;; :leader
:desc "Edit doom packages.el" ;; :desc "Edit doom packages.el"
"- p" #'(lambda () (interactive) (find-file "~/.doom.d/packages.el"))) ;; "- p" #'(lambda () (interactive) (find-file "~/.doom.d/packages.el")))
;; (after! mastodon ;; (after! mastodon
;; (setq mastodon-auth-source-file "~/.authinfo") ;; (setq mastodon-auth-source-file "~/.authinfo")
@ -197,11 +224,24 @@
;;(setq rmh-elfeed-org-files (list "~/Dropbox/Org/feedly.org")) ;;(setq rmh-elfeed-org-files (list "~/Dropbox/Org/feedly.org"))
(setq elfeed-use-curl t) (setq elfeed-use-curl t)
(setq elfeed-protocol-fever-update-unread-only t) (setq elfeed-protocol-fever-update-unread-only t)
(setq elfeed-protocol-feeds (list (setq elfeed-protocol-feeds '(("fever+https://shawnb@rss.onionpatch.cloud"
(list "fever+https://shawnb@rss.onionpatch.cloud"
:api-url "https://rss.onionpatch.cloud/api/fever.php" :api-url "https://rss.onionpatch.cloud/api/fever.php"
:password ")9vwibuQmv9pr" :password ")9vwibuQmv9pr"
:autotags '(("https://www.axios.com" news)("Hacker News" technology))))) :autotags (("https://feeds.arstechnica.com/arstechnica/index" secondary)
("https://api.axios.com/feed/" nooz)
("https://rss.csmonitor.com/feeds/all" nooz secondary)
("https://hnrss.org/newest?points=150")
("https://theimaginativeconservative.org/feed" primary)
("https://kill-the-newsletter.com/feeds/nnug6b0e4e7h8swq.xml" bellingcat nooz primary)
("https://planet.emacslife.com/atom.xml" primary emacs)
("https://www.plough.com/en/Plough-RSS-Feed" primary religion)
("https://reason.com/feed/" nooz secondary)
("https://www.readtangle.com/rss/" primary nooz)
("https://tracydurnell.com/feed/" primary blog)
("https://www.voanews.com/api/zqboml-vomx-tpeivmy" nooz primary)
("https://www.voanews.com/api/zpbovl-vomx-tpe_vmr" primary)
("https://www.voanews.com/api/zyritl-vomx-tpettmq" techno primary)
("https://www.voanews.com/api/zmbjqvl-vomx-tpeyvror" primary)))))
;; enable elfeed-protocol ;; enable elfeed-protocol
(setq elfeed-protocol-enabled-protocols '(fever)) (setq elfeed-protocol-enabled-protocols '(fever))
(elfeed-protocol-enable) (elfeed-protocol-enable)
@ -242,11 +282,8 @@
:desc "Get Hacker News items" :desc "Get Hacker News items"
"r h" #'(lambda () (interactive) (elfeed-search-set-filter "@1-week-ago +unread =Hacker")) "r h" #'(lambda () (interactive) (elfeed-search-set-filter "@1-week-ago +unread =Hacker"))
:leader :leader
:desc "Add entry to Pocket" :desc "Get MetaFilter items"
"r k e" #'(lambda () (interactive) (pocket-reader-elfeed-entry-add-link)) "r m" #'(lambda () (interactive) (elfeed-search-set-filter "@1-week-ago +unread =Meta"))
:leader
:desc "Add search item to Pocket"
"r k s" #'(lambda () (interactive) (pocket-reader-elfeed-search-add-link))
:leader :leader
:desc "Get News items" :desc "Get News items"
"r n e" #'(lambda () (interactive) (elfeed-search-set-filter "@1-week-ago +unread +News")) "r n e" #'(lambda () (interactive) (elfeed-search-set-filter "@1-week-ago +unread +News"))
@ -262,6 +299,9 @@
:leader :leader
:desc "Get Writing items" :desc "Get Writing items"
"r w" #'(lambda () (interactive) (elfeed-search-set-filter "@1-week-ago +unread +Writing"))) "r w" #'(lambda () (interactive) (elfeed-search-set-filter "@1-week-ago +unread +Writing")))
;; :leader
;; :desc "Get AI summary"
;; "r z" #'(lambda () (interactive) (elfeed-summarize-search-toggle-summary)))
(use-package! elfeed-goodies (use-package! elfeed-goodies
:init :init
(elfeed-goodies/setup) (elfeed-goodies/setup)
@ -280,35 +320,45 @@
(setq elfeed-goodies/entry-pane-position 'bottom) (setq elfeed-goodies/entry-pane-position 'bottom)
(setq elfeed-search-filter "@1-week-ago +unread " (setq elfeed-search-filter "@1-week-ago +unread "
elfeed-search-title-min-width 80) elfeed-search-title-min-width 80
;;elfeed-show-refresh-function #'+rss/elfeed-show-refresh--better-style) shr-max-image-proportion 0.6)
;; (defface elfeed-show-title-face '((t (:weight ultrabold :slant italic :height 1.5))) ;; (defface elfeed-show-title-face '((t (:weight ultrabold :slant italic :height 1.5)))
;; "title face in elfeed show buffer" ;; "title face in elfeed show buffer"
;; :group 'elfeed) ;; :group 'elfeed)
;; (defface elfeed-show-author-face `((t (:weight light)))
;; "title face in elfeed show buffer"
;; :group 'elfeed)
;; (set-face-attribute 'elfeed-search-title-face nil
;; :foreground 'nil
;; :weight 'light)
;; (after! elfeed-show (defun sbinfo/elfeed-filter-by-ordinality ()
;; (require 'url)) "Select a default filter and update elfeed."
(defun +rss/elfeed-show-refresh--better-style ()
"Update the buffer to match the selected entry, using a mail-style."
(interactive) (interactive)
(let* ((inhibit-read-only t) (let* ((filters
(title (elfeed-entry-title elfeed-show-entry)) '(("Default - 3 Days" . "@3-days-ago +unread -Sports -Videos -wait")
(date (seconds-to-time (elfeed-entry-date elfeed-show-entry))) ("Default - 7 Days" . "@7-days-ago +unread -Sports -Videos -wait")
(author (elfeed-meta elfeed-show-entry :author)) ("Default with Videos" . "@7-days-ago +unread")
(link (elfeed-entry-link elfeed-show-entry)) ("Primary - 7 Days" . "@7-days-ago +unread +primary")
(tags (elfeed-entry-tags elfeed-show-entry)) ("Secondary - 7 Days" . "@7-days-ago +unread +secondary")
(tagsstr (mapconcat #'symbol-name tags ", ")) ("Weekly News" . "@7-days-ago +nooz")
(nicedate (format-time-string ("%a, %e %b %Y %T %Z" date)) ("Wait Items" . "@7-days-ago +unread +wait")))
(content (elfeed-deref (elfeed-entry-content elfeed-show-entry))) ;; ("Third (3rd)" . "@7-days-ago +3rd +unread")
(type (elfeed-entry-content-type elfeed-show-entry)) ;; ("Outlets" . "@2-days-ago +outlet")))
(feed (elfeed-entry-feed elfeed-show-entry)) (filter
(feed-title (elfeed-feed-title feed)) (completing-read "Elfeed Filter: " filters nil t)))
(base (and feed (elfeed-compute-base (elfeed-feed-url feed))))) (setq elfeed-search-filter
(erase-buffer) (alist-get filter filters nil nil #'string=))
(insert "\n"))) (elfeed-search-update :force)))
)
(use-package! wombag
:config
(setq wombag-host "https://read.onionpatch.cloud" ;where you access Wallabag
wombag-username "shawnb"
wombag-password "6!EzrhCk94qxm"
wombag-client-id "3_2c3vfqmpkqm8oosg8ccwo4scgoscosc0oowssgcs8oowc0w844"
wombag-client-secret "5otka1i1kpc84wwwwsc404o8o0wow4sgcksk0ok8s8ws0c4c8g"))
;; ⌘-b ; browse to URL in foreground ;; ⌘-b ; browse to URL in foreground
@ -334,7 +384,7 @@
(interactive) (interactive)
;; (zen/toggle) ;; (zen/toggle)
(buffer-face-mode) (buffer-face-mode)
(linum-mode 0) ;;(linum-mode 0)
(blink-cursor-mode) (blink-cursor-mode)
(visual-line-mode 1) (visual-line-mode 1)
(setq truncate-lines nil (setq truncate-lines nil
@ -342,14 +392,17 @@
display-line-numbers nil)) display-line-numbers nil))
(add-hook 'markdown-mode-hook 'writing-mode) (add-hook 'markdown-mode-hook 'writing-mode)
(setq ispell-program-name "/usr/bin/aspell") ;; (setq ispell-program-name "/usr/bin/aspell")
(setq ispell-program-name "/home/shawnb/.nix-profile/bin/aspell")
(setq ispell-list-command "--list") (setq ispell-list-command "--list")
(defun sbinfo/org-mode-setup () (defun sbinfo/org-mode-setup ()
(setq +zen-text-scale 0)
(org-indent-mode) (org-indent-mode)
(org-superstar-mode 1) ;; (org-superstar-mode 1)
(org-bullets-mode 1)) (org-bullets-mode 1)
;; (variable-pitch-mode 1) (display-line-numbers-mode -1)
(variable-pitch-mode 1))
;; (visual-line-mode 1)) ;; (visual-line-mode 1))
(defun sbinfo/org-font-setup () (defun sbinfo/org-font-setup ()
@ -362,25 +415,46 @@
(org-level-6 . 1.0) (org-level-6 . 1.0)
(org-level-7 . 1.0) (org-level-7 . 1.0)
(org-level-8 . 1.0))) (org-level-8 . 1.0)))
;; (set-face-attribute (car face) nil :font "JetBrains Mono" :weight 'regular :height (cdr face)))) (set-face-attribute (car face) nil :font "Overpass Nerd Font" :weight 'regular :height (cdr face)))
;; (set-face-attribute (car face) nil :font "Fira Code Retina" :weight 'regular :height (cdr face))))
;; (set-face-attribute (car face) nil :font "Source Code Pro" :weight 'regular :height (cdr face)))
(set-face-attribute (car face) nil :font "Source Code Pro" :height (cdr face))))
;; Ensure that anything that should be fixed-pitch in Org files appears that way ;; 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-block nil :foreground nil :inherit 'fixed-pitch)
;; (set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch)) (set-face-attribute 'org-hide nil :inherit 'fixed-pitch)
;; (set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch)) (set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch))
;; (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch)) (set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch))
;; (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch)) (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
;; (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch)) (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
;; (set-face-attribute 'org-checkbox nil :inherit '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 (car face) nil :font "Fira Code Retina" :weight 'regular :height (cdr face))))
;; (set-face-attribute (car face) nil :font "Source Code Pro" :weight 'regular :height (cdr face)))
;; (set-face-attribute (car face) nil :font "SauceCodePro" :height (cdr face))))
(defvar sbinfo/open-ai-key "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") ;; AI
(defun gptel-add-key ()
"Read API key from file and ensure it's clean."
(string-trim
(with-temp-buffer
;; (insert-file-contents "~/.secrets/claude_key")
(insert-file-contents "~/.secrets/opencode_key")
(buffer-string))))
(after! chatgpt-shell (after! chatgpt-shell
(setq chatgpt-shell-openai-key sbinfo/open-ai-key)) (setq chatgpt-shell-openai-key sbinfo/open-ai-key))
(use-package! elfeed-summarize
;; :ensure
:after elfeed
:init (require 'llm-openai)
:config
(setq elfeed-summarize-llm-provider
(make-llm-openai-compatible
:key (gptel-add-key)
:url "https://opencode.ai/zen/v1/"
:chat-model "nemotron-3-ultra-free"))
(elfeed-summarize-mode 1))
(after! org-ai (after! org-ai
(add-hook 'org-mode-hook #'org-ai-mode) (add-hook 'org-mode-hook #'org-ai-mode)
(org-ai-install-yasnippets) (org-ai-install-yasnippets)
@ -388,16 +462,35 @@
(setq org-ai-openai-api-token sbinfo/open-ai-key)) (setq org-ai-openai-api-token sbinfo/open-ai-key))
(use-package! gptel (use-package! gptel
:config :custom
(setq! gptel-api-key sbinfo/open-ai-key)) ;;(setq gptel-model "claude-3-7-sonnet-20250219")
(setq gptel-model "claude-sonnet-4-6")
:config (gptel-add-key)
(setq gptel-backend
(gptel-make-anthropic "Claude"
:stream t
:key #'gptel-add-key)))
;; (use-package! gptel
;; :config
;; )
(use-package! org-web-tools
:commands org-web-tools--url-as-readable-org)
(after! org (after! org
(add-hook! org-mode :append
#'flymake-vale-load)
(add-hook 'org-mode-hook #'sbinfo/org-mode-setup)
(setq org-directory "~/org/" (setq org-directory "~/org/"
org-agenda-files '("agenda.org" "goals_2024.org" "job_search_2022.org") org-agenda-files '("agenda.org" "goals_2026.org" "Pillbox.org")
org-agenda-start-with-follow-mode t org-agenda-start-with-follow-mode t
org-default-notes-file (expand-file-name "notes.org" org-directory) org-default-notes-file (expand-file-name "notes.org" org-directory)
org-ellipsis " ▼ " org-ellipsis " ▼ "
org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●") org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●")
org-adapt-indentation t
org-indent-indentation-per-level 4 org-indent-indentation-per-level 4
org-log-done 'time org-log-done 'time
org-roam-directory "~/org/roam/" org-roam-directory "~/org/roam/"
@ -424,17 +517,80 @@
'(("b" "Bookmark" entry '(("b" "Bookmark" entry
(file "~/org/bookmarksv2.org") (file "~/org/bookmarksv2.org")
"* %^{title}\n#+date: %U\n- URL: %^{link}\n- Context: %?") "* %^{title}\n#+date: %U\n- URL: %^{link}\n- Context: %?")
("t" "Personal todo" entry ("c" "Coral Lane To-Do" checkitem
(file+headline "~/org/agenda.org" "Inbox") (file+headline "~/org/coral_lane_activities.org" "To Dos")
"* [ ] %?\n%i\n%a") " [ ] %?\n")
("n" "Personal notes" entry ("h" "Templates for hockey games")
("hp" "Playoff Game" entry
(file "~/org/dalvsminrd12026.org")
(file "~/org/templates/playoffcapture.orgtmpl") :unnarrowed t)
("hr" "Regular Game" entry
(file+headline "~/org/dallasstars20262027.org" "Dallas Stars 2026-2027 Season")
(file "~/org/templates/regular.orgtmpl") :unnarrowed t)
("i" "IT Request" checkitem
(file+headline "~/org/notes.org" "Future IT Requests")
" [ ] %?\n")
("n" "Personal Notes")
("nn" "Captured notes" entry
(file+headline "~/org/notes.org" "Inbox") (file+headline "~/org/notes.org" "Inbox")
"* %u %?\n%i\n%a" :prepend t))) "* %u %?\n%i\n%a" :prepend t)
("np" "Note via org-protocol" entry
(file+headline "~/org/notes.org" "Web Clipper")
(file "~/org/templates/webclipper.orgtmpl") :immediate-finish nil)
("s" "Shopping Item" checkitem
(file+headline "~/org/Shopping.org" "Needs")
" [ ] %?\n")
("t" "Personal todo" entry
(file "~/org/agenda.org")
"* TODO %?\n%i\n"))
org-roam-capture-ref-templates
'(("w" "ref" plain "%(org-web-tools--url-as-readable-org \"${ref}\")"
:target (file+head "clips/${slug}.org" "#+title: ${title}\n")
:unnarrowed t))
)
;;("j" "Journal" entry ;;("j" "Journal" entry
;;(file+olp+datetree +org-capture-journal-file) ;;(file+olp+datetree +org-capture-journal-file)
;;"* %U %?\n%i\n%a" :prepend t))) ;;"* %U %?\n%i\n%a" :prepend t)))
(sbinfo/org-font-setup)) (sbinfo/org-font-setup))
(setq org-agenda-custom-commands
'(("d" "Today's Agenda"
(
(tags-todo "+afterfocus+SCHEDULED<\"<tomorrow>\""
((org-agenda-overriding-header "After Focus Items")))
(agenda "" ((org-agenda-span 3)
(org-agenda-start-day "-1d")))))
("p" "Pills Against the Ageless Ills" (
(agenda "" ((org-agenda-files '("/home/shawnb/org/Pillbox.org"))
(org-agenda-entry-types '(:scheduled))
(org-scheduled-past-days 0)
(org-agenda-overriding-header "Pills Against the Ageles Ills")))))))
(use-package! org-modern
:hook (org-mode . org-modern-mode)
:config
(setq org-modern-star '("◉" "○" "✸" "✿" "✤" "✜" "◆" "▶")
org-modern-table-vertical 1
org-modern-table-horizontal 0.2
org-modern-list '((43 . "➤")
(45 . "–")
(42 . "•"))
org-modern-todo-faces
'(("TODO" :inverse-video t :inherit org-todo)
("BLOG" :inverse-video t :inherit +org-todo-project)
("PROJ" :inverse-video t :inherit +org-todo-project)
("WAIT" :inverse-video t :inherit +org-todo-onhold)
("CANCELLED" :inverse-video t :inherit +org-todo-cancel))
org-modern-footnote
(cons nil (cadr org-script-display))
org-modern-block-fringe nil
org-modern-progress nil
org-modern-priority nil
org-modern-horizontal-rule (make-string 36 ?─)
)
(custom-set-faces! '(org-modern-statistics :inherit org-checkbox-statistics-todo)))
(use-package! websocket (use-package! websocket
:after org-roam) :after org-roam)
@ -479,6 +635,12 @@
;; Todoist ;; Todoist
(setq todoist-token "344745a4ca6497cbce38cc957cad0c59c5d91613") (setq todoist-token "344745a4ca6497cbce38cc957cad0c59c5d91613")
;; Vale
(defvar my-flymake-vale-executable "/home/shawnb/.nix-profile/bin/vale")
(use-package! flymake-vale
:config
(setq flymake-vale-program my-flymake-vale-executable))
;; Auto create directories recursively ;; Auto create directories recursively
;; See https://emacsredux.com/blog/2022/06/12/auto-create-missing-directories/ ;; See https://emacsredux.com/blog/2022/06/12/auto-create-missing-directories/
(defun er-auto-create-missing-dirs () (defun er-auto-create-missing-dirs ()
@ -486,7 +648,96 @@
(unless (file-exists-p target-dir) (unless (file-exists-p target-dir)
(make-directory target-dir t)))) (make-directory target-dir t))))
;; Run du -hc on a directory in Dired
(defun sbinfo/dired-du ()
"Run 'du -hc' on the directory under the cursor in Dired."
(interactive)
(let ((current-dir (dired-get-file-for-visit)))
(if (file-directory-p current-dir)
(dired-do-async-shell-command "du -hc" nil (list current-dir))
(message "The current point is not a directory."))))
(add-to-list 'find-file-not-found-functions #'er-auto-create-missing-dirs) (add-to-list 'find-file-not-found-functions #'er-auto-create-missing-dirs)
;; ACe Window ;; ACe Window
(global-set-key (kbd "M-o") 'ace-window) (global-set-key (kbd "M-o") 'ace-window)
(setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)) (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
;; nov
(use-package! nov
:config
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
)
(after! ledger-mode
(setq ledger-binary-path "hledger.sh")
(setq ledger-default-date-format "%Y-%m-%d"))
;; ================
;; Helper functions
;; ================
(defun my/org-hugo-link-vanilla-markdown (link desc info)
"Render org links as vanilla Markdown links instead of Hugo relref."
(let* ((type (org-element-property :type link))
(raw-path (org-element-property :path link))
(raw-link (org-element-property :raw-link link)))
(cond
;; External links - plain markdown
((member type '("http" "https" "ftp"))
(format "[%s](%s)" (or desc raw-link) raw-link))
;; ID links - resolve org-id to file slug
((string= type "id")
(let* ((id-location (org-id-find raw-path))
(file (when id-location (car id-location)))
(slug (if file
(file-name-sans-extension (file-name-nondirectory file))
raw-path)))
(format "[%s](%s)" (or desc slug) slug)))
;; Fuzzy/internal links - convert to anchor links
((string= type "fuzzy")
(format "[%s](#%s)" (or desc raw-path)
(org-hugo-slug raw-path)))
;; Default: use original behavior for other link types
(t nil))))
(defun my/org-hugo-link-advice (orig-fun link desc info)
"Advice to use vanilla Markdown links."
(or (my/org-hugo-link-vanilla-markdown link desc info)
(funcall orig-fun link desc info)))
(advice-add 'org-hugo-link :around #'my/org-hugo-link-advice)
;; (advice-remove 'org-hugo-link #'my/org-hugo-link-advice)
;; https://jamesendreshowell.com/2026-04-04-my-first-advice-in-emacs-lisp.html
(defun sbinfo/file-to-string (file)
"Return a string that is the contents of FILE."
(with-temp-buffer
(insert-file-contents file)
(buffer-string)))
;; Keeping count of pills/puffs in the Pillbox. Designed to mark a Pillbox task as CANCELLED
;; if the supply runs out.
;; Thanks, Claude
(defun sbinfo/decrement-org-property (property)
"Decrement PROPERTY on current heading by 1, clamping at zero.
When the value reaches zero, mark the task as CANCELLED."
(let* ((val (org-entry-get nil property))
(num (and val (string-to-number val))))
(when num
(cond
((> num 1)
(org-entry-put nil property (number-to-string (1- num))))
((= num 1)
(org-entry-put nil property "0")
(org-todo "CANCELLED")) ;; Already at zero — do nothing
))))
(defun sbinfo/on-recurring-task-done ()
"Decrement :REMAINING: when a recurring task is completed."
(when (and (string= org-state "DONE")
(org-entry-get nil "REMAINING"))
(sbinfo/decrement-org-property "REMAINING")))
(add-hook 'org-after-todo-state-change-hook #'sbinfo/on-recurring-task-done)
(defun sbinfo/org-capture-frame ()
(set-frame-parameter nil 'name "org-capture")
(org-capture))

50
init.el
View file

@ -21,17 +21,18 @@
;;layout ; auie,ctsrnm is the superior home row ;;layout ; auie,ctsrnm is the superior home row
:completion :completion
company ; the ultimate code completion backend ;;company ; the ultimate code completion backend
(corfu +orderless +dabbrev) ; complete with cap(f), cape and a flying feather!
;;helm ; the *other* search engine for love and life ;;helm ; the *other* search engine for love and life
;;ido ; the other *other* search engine... ;;ido ; the other *other* search engine...
;;ivy ; a search engine for love and life ;;ivy ; a search engine for love and life
vertico ; the search engine of the future (vertico +icons) ; the search engine of the future
:ui :ui
;;deft ; notational velocity for Emacs ;;deft ; notational velocity for Emacs
doom ; what makes DOOM look the way it does doom ; what makes DOOM look the way it does
doom-dashboard ; a nifty splash screen for Emacs doom-dashboard ; a nifty splash screen for Emacs
;;doom-quit ; DOOM quit-message prompts when you quit Emacs doom-quit ; DOOM quit-message prompts when you quit Emacs
;;(emoji +unicode) ; 🙂 ;;(emoji +unicode) ; 🙂
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
;;hydra ;;hydra
@ -42,21 +43,21 @@
;;nav-flash ; blink cursor line after big motions ;;nav-flash ; blink cursor line after big motions
;;neotree ; a project drawer, like NERDTree for vim ;;neotree ; a project drawer, like NERDTree for vim
ophints ; highlight the region an operation acts on ophints ; highlight the region an operation acts on
(popup +defaults) ; tame sudden yet inevitable temporary windows (popup +all +defaults) ; tame sudden yet inevitable temporary windows
;;tabs ; a tab bar for Emacs ;;tabs ; a tab bar for Emacs
;;treemacs ; a project drawer, like neotree but cooler ;;treemacs ; a project drawer, like neotree but cooler
;;unicode ; extended unicode support for various languages ;;unicode ; extended unicode support for various languages
(vc-gutter +pretty) ; vcs diff in the fringe (vc-gutter +pretty) ; vcs diff in the fringe
vi-tilde-fringe ; fringe tildes to mark beyond EOB vi-tilde-fringe ; fringe tildes to mark beyond EOB
;;window-select ; visually switch windows window-select ; visually switch windows
workspaces ; tab emulation, persistence & separate workspaces workspaces ; tab emulation, persistence & separate workspaces
;;zen ; distraction-free coding or writing zen ; distraction-free coding or writing
:editor :editor
(evil +everywhere); come to the dark side, we have cookies (evil +everywhere); come to the dark side, we have cookies
file-templates ; auto-snippets for empty files file-templates ; auto-snippets for empty files
fold ; (nigh) universal code folding fold ; (nigh) universal code folding
;;(format +onsave) ; automated prettiness (format +onsave) ; automated prettiness
;;god ; run Emacs commands without modifier keys ;;god ; run Emacs commands without modifier keys
;;lispy ; vim for lisp, for people who don't like vim ;;lispy ; vim for lisp, for people who don't like vim
multiple-cursors ; editing in many places at once multiple-cursors ; editing in many places at once
@ -67,35 +68,35 @@
;;word-wrap ; soft wrapping with language-aware indent ;;word-wrap ; soft wrapping with language-aware indent
:emacs :emacs
dired ; making dired pretty [functional] (dired +icons) ; making dired pretty [functional]
electric ; smarter, keyword-based electric-indent electric ; smarter, keyword-based electric-indent
;;ibuffer ; interactive buffer management (ibuffer +icons) ; interactive buffer management
undo ; persistent, smarter undo for your inevitable mistakes undo ; persistent, smarter undo for your inevitable mistakes
vc ; version-control and Emacs, sitting in a tree vc ; version-control and Emacs, sitting in a tree
:term :term
eshell ; the elisp shell that works everywhere ;; eshell ; the elisp shell that works everywhere
;;shell ; simple shell REPL for Emacs ;;shell ; simple shell REPL for Emacs
;;term ; basic terminal emulator for Emacs ;;term ; basic terminal emulator for Emacs
;;vterm ; the best terminal emulation in Emacs ;;vterm ; the best terminal emulation in Emacs
:checkers :checkers
syntax ; tasing you for every semicolon you forget syntax ; tasing you for every semicolon you forget
(spell +flyspell) ; tasing you for misspelling mispelling (spell +aspell +flyspell) ; tasing you for misspelling mispelling
;;grammar ; tasing grammar mistake every you make ;;grammar ; tasing grammar mistake every you make
:tools :tools
;;ansible ;;ansible
;;biblio ; Writes a PhD for you (citation needed) ;;biblio ; Writes a PhD for you (citation needed)
;;debugger ; FIXME stepping through code, to help you add bugs ;;debugger ; FIXME stepping through code, to help you add bugs
;;direnv direnv
;;docker ;;docker
;;editorconfig ; let someone else argue about tabs vs spaces ;;editorconfig ; let someone else argue about tabs vs spaces
;;ein ; tame Jupyter notebooks with emacs ;;ein ; tame Jupyter notebooks with emacs
(eval +overlay) ; run code, run (also, repls) (eval +overlay) ; run code, run (also, repls)
;;gist ; interacting with github gists ;;gist ; interacting with github gists
lookup ; navigate your code and its documentation (lookup +dictionary) ; navigate your code and its documentation
(lsp +eglot) ; M-x vscode lsp ; M-x vscode
magit ; a git porcelain for Emacs magit ; a git porcelain for Emacs
;;make ; run make tasks from Emacs ;;make ; run make tasks from Emacs
;;pass ; password manager for nerds ;;pass ; password manager for nerds
@ -103,9 +104,9 @@
;;prodigy ; FIXME managing external services & code builders ;;prodigy ; FIXME managing external services & code builders
;;rgb ; creating color strings ;;rgb ; creating color strings
;;taskrunner ; taskrunner for all your projects ;;taskrunner ; taskrunner for all your projects
;;terraform ; infrastructure as code terraform ; infrastructure as code
;;tmux ; an API for interacting with tmux ;;tmux ; an API for interacting with tmux
;;tree-sitter ; syntax and parsing, sitting in a tree... tree-sitter ; syntax and parsing, sitting in a tree...
;;upload ; map local to remote projects via ssh/ftp ;;upload ; map local to remote projects via ssh/ftp
:os :os
@ -147,20 +148,25 @@
;;kotlin ; a better, slicker Java(Script) ;;kotlin ; a better, slicker Java(Script)
;;latex ; writing papers in Emacs has never been so fun ;;latex ; writing papers in Emacs has never been so fun
;;lean ; for folks with too much to prove ;;lean ; for folks with too much to prove
;;ledger ; be audit you can be ledger ; be audit you can be
;;lua ; one-based indices? one-based indices ;;lua ; one-based indices? one-based indices
markdown ; writing docs for people to ignore markdown ; writing docs for people to ignore
;;nim ; python + lisp at the speed of c ;;nim ; python + lisp at the speed of c
nix ; I hereby declare "nix geht mehr!" (nix +lsp) ; I hereby declare "nix geht mehr!"
;;ocaml ; an objective camel ;;ocaml ; an objective camel
(org (org
+pretty +pretty
+hugo +hugo
+noter
+pandoc
+roam2) ; organize your plain life in plain text +roam2) ; organize your plain life in plain text
;;php ; perl's insecure younger brother ;;php ; perl's insecure younger brother
;;plantuml ; diagrams for confusing people more ;;plantuml ; diagrams for confusing people more
;;purescript ; javascript, but functional ;;purescript ; javascript, but functional
(python +lsp +pyright) ; beautiful is better than ugly (python
+lsp
+pyright
+tree-sitter) ; beautiful is better than ugly
;;qt ; the 'cutest' gui framework ever ;;qt ; the 'cutest' gui framework ever
;;racket ; a DSL for DSLs ;;racket ; a DSL for DSLs
;;raku ; the artist formerly known as perl6 ;;raku ; the artist formerly known as perl6
@ -176,7 +182,9 @@
;;swift ; who asked for emoji variables? ;;swift ; who asked for emoji variables?
;;terra ; Earth and Moon in alignment for performance. ;;terra ; Earth and Moon in alignment for performance.
;;web ; the tubes ;;web ; the tubes
yaml ; JSON, but readable (yaml
+lsp
+tree-sitter) ; JSON, but readable
;;zig ; C, but simpler ;;zig ; C, but simpler
:email :email
@ -187,7 +195,7 @@
:app :app
;;calendar ;;calendar
;;emms ;;emms
;;everywhere ; *leave* Emacs!? You must be joking everywhere ; *leave* Emacs!? You must be joking
;;irc ; how neckbeards socialize ;;irc ; how neckbeards socialize
rss ; emacs as an RSS reader rss ; emacs as an RSS reader
;;twitter ; twitter client https://twitter.com/vnought ;;twitter ; twitter client https://twitter.com/vnought

View file

@ -62,8 +62,15 @@
(package! elfeed-goodies) (package! elfeed-goodies)
;;(package! elfeed-org) ;;(package! elfeed-org)
(package! elfeed-protocol) (package! elfeed-protocol)
(package! elfeed-summarize
:recipe (:host github
:repo "fritzgrabo/elfeed-summarize"))
(package! ement) (package! ement)
(package! flymake-vale
:recipe (:host github
:repo "tpeacock19/flymake-vale"))
(package! gptel) (package! gptel)
(package! nov)
(package! org-ai) (package! org-ai)
(package! org-bullets) (package! org-bullets)
(package! org-roam-ui) (package! org-roam-ui)
@ -72,9 +79,14 @@
:repo "brunoarine/org-similarity" :repo "brunoarine/org-similarity"
:branch "main")) :branch "main"))
(package! org-web-tools :pin "8f8b5c6") (package! org-web-tools :pin "8f8b5c6")
(package! pocket-reader :pin "5354082") (package! pocket-reader :pin "7f55668")
;; (package! org-web-tools)
;; (package! pocket-reader)
(package! todoist) (package! todoist)
(package! twittering-mode) (package! twittering-mode)
(package! wc-mode) (package! wc-mode)
(package! wombag
:recipe (:host github
:repo "karthink/wombag"))
(package! writegood-mode) (package! writegood-mode)
(package! wordsmith-mode) ;; (package! wordsmith-mode)