#+TITLE: DOOM Emacs Configuration #+STARTUP: indent #+PROPERTY: header-args :tangle yes * Dashboard #+begin_src emacs-lisp (defun my/choice (&rest things) (let ((index (random (length things)))) (nth index things))) (defun my/dashboard-randomize () (interactive) (let ((logo (my/choice "~/Pictures/Patreon/Jon Bliss/phoenix-and-catgirl-500.png" "~/Pictures/Patreon/Jon Bliss/Bassist-final-transparent-500.png" "~/Pictures/Patreon/Jon Bliss/catgirl-final-transparent-500.png" "~/Pictures/Patreon/Jon Bliss/lapiz-final-transparent-500.png" "~/Pictures/Patreon/Jon Bliss/Poledancer-final-transparent-500.png" "~/Pictures/Patreon/Jon Bliss/Hacker-final-transparent-500.png"))) (setq fancy-splash-image logo) (if (called-interactively-p) (+doom-dashboard-reload)))) (my/dashboard-randomize) (map! :map +doom-dashboard-mode-map "g" #'my/dashboard-randomize) #+end_src * Org :PROPERTIES: :header-args: :tangle no :noweb-ref org :END: #+begin_src emacs-lisp :noweb yes :tangle yes :noweb-ref org-all (after! org <>) #+end_src ** Override DOOM indentation behavior #+begin_src emacs-lisp (defun my/org-init-babel () (setq org-src-preserve-indentation nil)) (add-hook! 'org-mode-hook #'my/org-init-babel) #+end_src ** Disable DOOM's centralized attachment system It's incompatible with all of the org files I already have using the standard setup. #+begin_src emacs-lisp (setq org-attach-directory "data/") (remove-hook! 'org-load-hook #'(+org-init-centralized-attachments-h)) #+end_src ** Agenda #+begin_src emacs-lisp (after! org-agenda (require 'f) (setq my/agenda-files '((personal . ("~/Dropbox/org/personal.org")) (work . ("~/Dropbox/org/aweber.org"))) org-agenda-files (-filter #'f-exists? (-concat (if (string-equal (system-name) "s1118ofclair.local") (cdr (assoc 'work my/agenda-files)) (cdr (assoc 'personal my/agenda-files)))))) (setq org-agenda-files (-flatten (-map #'cdr my/agenda-files))) (setq org-stuck-projects '("+LEVEL=1/-DONE" ("TODO" "NEXT" "NEXTACTION") nil "")) ;; https://www.tompurl.com/2015-12-29-emacs-eisenhower-matrix.html (setq org-tag-alist '(("important" . ?i) ("urgent" . ?u))) (setq org-agenda-custom-commands '(("n" "Agenda and all TODOs" ((agenda "") (tags-todo "DEADLINE<=\"<+7d>\"" ((org-agenda-overriding-header "Due soon"))) ;; Eisenhower Matrix quadrants (tags-todo "+important+urgent" ((org-agenda-overriding-header "Do"))) (tags-todo "+important-urgent" ((org-agenda-overriding-header "Decide"))) (tags-todo "-important+urgent" ((org-agenda-overriding-header "Delegate"))) (tags-todo "-important-urgent" ((org-agenda-overriding-header "Delete")))) ((org-agenda-start-with-log-mode t) (org-agenda-start-day nil) (org-agenda-span 'day) (org-agenda-log-mode-items '(clock state closed))) ("~/Public/agenda.html" "~/Public/agenda.ics")) ("l" "Log" agenda "" ((org-agenda-span 'fortnight) (org-agenda-start-day "-1w") (org-agenda-start-with-log-mode t) (org-agenda-log-mode-items '(clock state closed)) (org-agenda-include-deadlines nil) (org-agenda-skip-scheduled-delay-if-deadline t)) ("~/Public/agenda-log.html")) ("e" "Eisenhower Matrix" ((tags-todo "+important+urgent" ((org-agenda-overriding-header "Do"))) (tags-todo "+important-urgent" ((org-agenda-overriding-header "Decide"))) (tags-todo "-important+urgent" ((org-agenda-overriding-header "Delegate"))) (tags-todo "-important-urgent" ((org-agenda-overriding-header "Delete")))) ((org-agenda-start-with-log-mode t) (org-agenda-span 'day) (org-agenda-log-mode-items '(clock state closed)))))) (defun my/org-agenda-timeline () (interactive) (let ((org-agenda-files (list (buffer-file-name)))) (org-agenda))) (setq org-agenda-start-on-weekday nil) (setq org-agenda-span 'fortnight) (setq org-agenda-todo-ignore-scheduled 'future) (setq org-agenda-tags-todo-honor-ignore-options t) (setq org-agenda-skip-deadline-prewarning-if-scheduled t) (add-hook 'org-agenda-finalize-hook (lambda () (hl-line-mode))) (setq org-icalendar-use-scheduled '(todo-start event-if-todo) org-icalendar-combined-agenda-file (expand-file-name "~/Documents/org.ics"))) #+end_src ** LaTeX Export *** Document Classes #+BEGIN_SRC emacs-lisp (use-package! ox-latex :config (seq-map (apply-partially #'add-to-list 'org-latex-classes) '(("koma-letter" "\\documentclass{scrlttr2}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("koma-article" "\\documentclass{scrartcl}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("koma-book" "\\documentclass{scrbook}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("koma-book-chapters" "\\documentclass{scrbook}" ("\\chapter{%s}" . "\\chapter*{%s}") ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("koma-report" "\\documentclass{scrreprt}" ("\\chapter{%s}" . "\\chapter*{%s}") ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("memoir" "\\documentclass{memoir}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("hitec" "\\documentclass{hitec}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("paper" "\\documentclass{paper}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("letter" "\\documentclass{letter}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("tufte-handout" "\\documentclass{tufte-handout}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("tufte-book" "\\documentclass{tufte-book}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("tufte-book-chapters" "\\documentclass{tufte-book}" ("\\chapter{%s}" . "\\chapter*{%s}") ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("labbook" "\\documentclass{labbook}" ("\\chapter{%s}" . "\\chapter*{%s}") ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\labday{%s}") ("\\subsubsection{%s}" . "\\experiment{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))) #+END_SRC ** Capture templates #+begin_src emacs-lisp (setq org-capture-templates `( ;; Personal ("j" "Journal Entry" plain (file+datetree "~/org/journal.org") "%U\n\n%?" :empty-lines-before 1) ("t" "TODO" entry (file+headline "~/Dropbox/org/personal.org" "Unsorted") "* TODO %^{Description}\n%?") ("n" "Note" entry (file+headline "~/Dropbox/org/personal.org" "Notes") "* %^{Description}\n%U\n\n%?") ;; Org-Protocol ("b" "Bookmark" entry (file+headline "~/org/bookmarks.org" "Unsorted") "* %^{Title}\n\n Source: %u, %c\n\n %i") ("p" "Webpage" entry (file "~/org/articles.org") "* %a\n\n%U %?\n\n%:initial") ;; Email ;; https://martinralbrecht.wordpress.com/2016/05/30/handling-email-with-emacs/ ("r" "respond to email (mu4e)" entry (file+headline "~/org/todo.org" "Email") "* REPLY to [[mailto:%:fromaddress][%:fromname]] on %a\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+1d\"))\n%U\n\n" :immediate-finish t :prepend t) ;; Work ("w" "Work") ("wt" "Work TODO" entry (file+headline "~/Dropbox/org/aweber.org" "Unsorted") "* TODO %^{Description}\n%?") ("wl" "Log Work Task" entry (file+datetree "~/org-aweber/worklog.org") "* %^{Description} %^g\nAdded: %U\n\n%?" :clock-in t :clock-keep t) ("wL" "Log Work Task (no clock)" entry (file+datetree "~/org-aweber/worklog.org") "* %^{Description} %^g\nAdded: %U\n\n%?") ("wj" "Log work on JIRA issue" entry (file+datetree "~/org-aweber/worklog.org") ,(concat "* %?\n" ":PROPERTIES:\n" ":JIRA_ID: %^{JIRA_ID}\n" ":END:\n" "Added: %U\n\n" "[[jira:%\\1][%\\1]]") :clock-in t :clock-keep t) ("wr" "respond to email (mu4e)" entry (file+headline "~/Dropbox/org/aweber.org" "Unsorted") "* REPLY to [[mailto:%:fromaddress][%:fromname]] on %a\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+1d\"))\n%U\n\n" :immediate-finish t :prepend t))) #+end_src ** Custom ID generation Because I'm all kinds of crazy, I like the custom IDs of my work log entries to be based on their headings. #+begin_src emacs-lisp (use-package! org-id :after org :config ;; https://writequit.org/articles/emacs-org-mode-generate-ids.html#automating-id-creation (defun eos/org-custom-id-get (&optional pom create prefix) "Get the CUSTOM_ID property of the entry at point-or-marker POM. If POM is nil, refer to the entry at point. If the entry does not have an CUSTOM_ID, the function returns nil. However, when CREATE is non nil, create a CUSTOM_ID if none is present already. PREFIX will be passed through to `org-id-new'. In any case, the CUSTOM_ID of the entry is returned." (interactive) (org-with-point-at pom (let ((id (org-entry-get nil "CUSTOM_ID"))) (cond ((and id (stringp id) (string-match "\\S-" id)) id) (create (setq id (org-id-new (concat prefix "h"))) (org-entry-put pom "CUSTOM_ID" id) (org-id-add-location id (buffer-file-name (buffer-base-buffer))) id))))) (defun eos/org-add-ids-to-headlines-in-file () "Add CUSTOM_ID properties to all headlines in the current file which do not already have one. Only adds ids if the `auto-id' option is set to `t' in the file somewhere. ie, ,#+OPTIONS: auto-id:t" (interactive) (save-excursion (widen) (goto-char (point-min)) (when (re-search-forward "^#\\+OPTIONS:.*auto-id:t" (point-max) t) (org-map-entries (lambda () (eos/org-id-get (point) 'create))))) (save-excursion (widen) (goto-char (point-min)) (when (re-search-forward "^#\\+OPTIONS:.*auto-id:worklog" (point-max) t) (let ((my/org-worklog-id-depth 2)) (org-map-entries (lambda () (my/org-worklog-id-get (point) 'create)))))) (save-excursion (widen) (goto-char (point-min)) (when (re-search-forward "^#\\+OPTIONS:.*auto-id:readable" (point-max) t) (let ((my/org-worklog-id-depth 0)) (org-map-entries (lambda () (my/org-worklog-id-get (point) 'create))))))) ;; automatically add ids to saved org-mode headlines (add-hook 'org-mode-hook (lambda () (add-hook 'before-save-hook (lambda () (when (and (eq major-mode 'org-mode) (eq buffer-read-only nil)) (eos/org-add-ids-to-headlines-in-file)))))) (defun my/org-remove-all-ids () (interactive) (save-excursion (widen) (goto-char (point-min)) (org-map-entries (lambda () (org-entry-delete (point) "CUSTOM_ID"))))) (defvar my/org-worklog-id-depth 2) (defun my/org-worklog-id-new (&optional prefix) (let ((path (or (-drop my/org-worklog-id-depth (org-get-outline-path t)) (last (org-get-outline-path t))))) (mapconcat (lambda (s) (->> s (s-downcase) (s-replace-regexp "[^[:alnum:]]+" "-"))) path "-"))) (defun my/org-worklog-id-get (&optional pom create prefix) (interactive) (org-with-point-at pom (let ((id (org-entry-get nil "CUSTOM_ID"))) (cond ((and id (stringp id) (string-match "\\S-" id)) id) (create (setq id (my/org-worklog-id-new prefix)) (org-entry-put pom "CUSTOM_ID" id) id)))))) #+end_src ** Publish projects #+begin_src emacs-lisp (setq org-html-mathjax-options '((path "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS-MML_HTMLorMML"))) (setq org-reveal-root "https://cdn.jsdelivr.net/reveal.js/3.0.0/") (defun my/org-work-publish-to-html (plist filename pub-dir) (message "Publishing %s" filename) (cond ((string-match-p "slides.org$" filename) (org-reveal-publish-to-reveal plist filename pub-dir)) (t (let ((org-html-head (concat ;; Tufte ;; "" ;; "" ;; Org-Spec ;; "" ;; "" ;; "" ;; ReadTheOrg "" "" "" "" "" "" "" ;; Bigblow ;; "" ;; "" ;; "" ;; "" ;; "" ;; "" ;; "" ;; "" ;; "" ;; "" ;; "" ))) (save-excursion (save-restriction (org-html-publish-to-html plist filename pub-dir))))))) ;; (setq my/org-base-url (concat "/~" (getenv "USER") "/org/")) (setq my/org-base-url "/") (setq my/org-base-url "https://github.aweber.io/pages/correlr/org/") (setq org-publish-project-alist `( ;; ("work-common" ;; :base-directory "~/org/common" ;; :publishing-directory "~/Public/org" ;; :base-extension "css\\|gif\\|jpe?g\\|png\\|svg" ;; :recursive t ;; :publishing-function org-publish-attachment) ("work-themes" :base-directory "~/.emacs.local.d/org-html-themes/styles" :publishing-directory "~/Public/org/styles" :base-extension "js\\|css\\|gif\\|jpe?g\\|png\\|svg\\|ogv" :recursive t :publishing-function org-publish-attachment) ("work-html" :base-directory "~/org-aweber" :base-extension "org" ;; :exclude "\\(^knowledge-transfer.org$\\|-archive.org$\\)" :exclude "\\(^README.org$\\)" :publishing-directory "~/Public/org" :publishing-function (my/org-work-publish-to-html org-org-publish-to-org org-babel-tangle-publish ) :htmlized-source t ;; :html-head "" ;; :html-head-extra "" ;; :setup-file "~/.emacs.local.d/org-html-themes/setup/theme-readtheorg-local.setup" :html-link-home ,my/org-base-url :html-doctype "html5" :html-html5-fancy t :with-sub-superscript nil ;; :infojs-opt "path:http://thomasf.github.io/solarized-css/org-info.min.js view:showall" :auto-sitemap t :sitemap-filename "index.org" :sitemap-title "Correl Roush's Org Documents" :sitemap-sort-folders last :recursive t) ("work-assets" :base-directory "~/org-aweber" :base-extension "css\\|gif\\|jpe?g\\|png\\|svg\\|pdf\\|ogv\\|py\\|html\\|ya?ml" :include (".gitlab-ci.yml") :publishing-directory "~/Public/org" :publishing-function org-publish-attachment :recursive t) ("work" :components ("work-html" "work-assets" "work-themes")) ("dotfiles-common" :base-directory "~/dotfiles" :publishing-directory "~/Public/dotfiles" :base-extension "css\\|gif\\|jpe?g\\|png\\|svg" :recursive t :publishing-function org-publish-attachment) ("dotfiles-html" :base-directory "~/dotfiles" :base-extension "org" :publishing-directory "~/Public/dotfiles" :publishing-function (org-html-publish-to-html org-babel-tangle-publish) :htmlized-source t :html-head "" :html-head-extra "" :html-link-home "/~croush/dotfiles/" :html-doctype "html5" :html-html5-fancy t :with-sub-superscript nil :infojs-opt "path:http://thomasf.github.io/solarized-css/org-info.min.js view:showall" :auto-sitemap t :sitemap-filename "index.org" :sitemap-title "Correl Roush's Dotfiles" :sitemap-sort-folders last :recursive t) ("dotfiles-assets" :base-directory "~/dotfiles" :base-extension "css\\|gif\\|jpe?g\\|png\\|svg" :publishing-directory "~/Public/dotfiles" :publishing-function org-publish-attachment :recursive t) ("dotfiles" :components ("dotfiles-common" "dotfiles-html" "dotfiles-assets")) ("personal-themes" :base-directory "~/.emacs.local.d/org-html-themes/styles" :publishing-directory "~/Public/personal/styles" :base-extension "js\\|css\\|gif\\|jpe?g\\|png\\|svg" :recursive t :publishing-function org-publish-attachment) ("personal-html" :base-directory "~/org" :base-extension "org" :publishing-directory "~/Public/personal" :recursive t :with-toc t :auto-sitemap t :sitemap-title "Correl Roush's Org Files" :sitemap-filename "index.org" :publishing-function org-html-publish-to-tufte-html :html-head ,(concat ;; Tufte "" "" ;; Org-Spec ;; "" ;; "" )) ("personal-files" :base-directory "~/org" :base-extension "css\\|gif\\|jpe?g\\|png\\|svg" :publishing-directory "~/Public/personal" :recursive t :publishing-function org-publish-attachment) ("personal-assets" :base-directory "~/org" :base-extension "css\\|gif\\|jpe?g\\|png\\|svg\\|pdf" :publishing-directory "~/Public/personal" :publishing-function org-publish-attachment :recursive t) ("personal" :components ("personal-themes" "personal-html" "personal-files" "personal-assets")) ("journal" :base-directory "~/org" :exclude ".*" :include ("journal.org") :publishing-directory "~/journal" :publishing-function (org-html-publish-to-html org-latex-export-to-pdf)) ("sicp-html" :base-directory "~/code/sicp" :base-extension "org" :publishing-directory "~/Public/sicp" :publishing-function (org-html-publish-to-html org-org-publish-to-org org-babel-tangle-publish) :htmlized-source t :html-head "" :html-link-home "/" :html-doctype "html5" :html-html5-fancy t :with-sub-superscript nil :auto-sitemap t :sitemap-filename "index.org" :sitemap-title "SICP Exercises and Notes" :sitemap-sort-folders last :recursive t) ("sicp-assets" :base-directory "~/code/sicp" :base-extension "css\\|gif\\|jpe?g\\|png\\|svg\\|scheme\\|pl" :publishing-directory "~/Public/sicp" :publishing-function org-publish-attachment :recursive t) ("sicp" :components ("sicp-html" "sicp-assets")) )) ;; Don't prompt for babel evaluation, ever. (setq org-confirm-babel-evaluate nil) (require 'ox-confluence)(defun my/org-publish () (interactive) (org-publish "work") (shell-command "org-publish")) (bind-key "C-c o p" #'my/org-publish) #+end_src ** Enhanced Confluence export #+begin_src emacs-lisp (use-package! ox-confluence-en :after ox :commands ox-confluence-en-export-as-confluence) #+end_src * MU4E #+begin_src emacs-lisp (use-package! mu4e :bind (("" . mu4e)) :config (require 'f) (setq mu4e-maildir "~/Mail") (setq user-full-name "Correl Roush") (setq mu4e-contexts (list (make-mu4e-context :name "work" :vars `((user-mail-address . "correlr@aweber.com") (mu4e-drafts-folder . "/Work/[Gmail].Drafts") (mu4e-sent-folder . "/Work/[Gmail].Sent Mail") (mu4e-trash-folder . "/Work/[Gmail].Trash") (mu4e-maildir-shortcuts . (("/Work/INBOX" . ?i) ("/Work/[Gmail].All Mail" . ?a) ("/Work/[Gmail].Starred" . ?S) ("/Work/[Gmail].Sent Mail" . ?s) ("/Work/[Gmail].Trash" . ?t))) (mu4e-compose-signature . ,(with-temp-buffer (insert-file-contents "~/.signature-aweber") (buffer-string))))))) (when (f-exists? (f-join mu4e-maildir "Personal")) (add-to-list 'mu4e-contexts (make-mu4e-context :name "personal" :vars `((user-mail-address . "correl@gmail.com") (mu4e-drafts-folder . "/Personal/[Gmail].Drafts") (mu4e-sent-folder . "/Personal/[Gmail].Sent Mail") (mu4e-trash-folder . "/Personal/[Gmail].Trash") (mu4e-maildir-shortcuts . (("/Personal/INBOX" . ?i) ("/Personal/[Gmail].All Mail" . ?a) ("/Personal/[Gmail].Starred" . ?S) ("/Personal/[Gmail].Sent Mail" . ?s) ("/Personal/[Gmail].Trash" . ?t))) (mu4e-compose-signature . ,(with-temp-buffer (insert-file-contents "~/.signature") (buffer-string))))))) (setq mu4e-context-policy 'pick-first) (setq mu4e-compose-dont-reply-to-self t) (setq mu4e-user-mail-address-list '("correlr@aweber.com" "correl@gmail.com"))) #+end_src * Prodigy Manage background services #+begin_src emacs-lisp (use-package! prodigy :defer 2 :config (global-set-key (kbd "") 'prodigy) (prodigy-define-tag :name 'work) (prodigy-define-tag :name 'personal) ;; https://martinralbrecht.wordpress.com/2016/05/30/handling-email-with-emacs/ (when (executable-find "imapnotify") (prodigy-define-tag :name 'email :ready-message "Checking Email using IMAP IDLE. Ctrl-C to shutdown.") (prodigy-define-service :name "imapnotify-work" :command "imapnotify" :args (list "-c" (expand-file-name "~/.config/imap_inotify/work.js")) :tags '(email work autostart) :kill-signal 'sigkill) (unless (string-equal "croush" (user-login-name)) (prodigy-define-service :name "imapnotify-personal" :command "imapnotify" :args (list "-c" (expand-file-name "~/.config/imap_inotify/personal.js")) :tags '(email personal autostart) :kill-signal 'sigkill))) (when (f-exists? (expand-file-name "~/code/elm-dashboard")) (prodigy-define-service :name "elm-dashboard" :command "python" :args '("-m" "SimpleHTTPServer" "3000") :cwd (expand-file-name "~/code/elm-dashboard") :tags '(personal elm) :stop-signal 'sigkill :kill-process-buffer-on-stop t)) (when (f-exists? (expand-file-name "~/git/www")) (prodigy-define-service :name "AWeber WWW" :command "npm" :args '("start") :cwd (expand-file-name "~/git/www") :tags '(work))) (when (f-exists? (expand-file-name "~/Public/org")) (prodigy-define-service :name "Org Documents" :command "python" :args '("-m" "http.server" "3001") :cwd (expand-file-name "~/Public/org") :tags '(work autostart) :kill-signal 'sigkill)) (mapcar #'prodigy-start-service (-concat (prodigy-services-tagged-with 'autostart)))) #+end_src * Projectile #+begin_src emacs-lisp (after! projectile (require 'dash) (require 'f) (setq projectile-switch-project-action #'magit-status) (let ((project-directories (-filter #'f-directory? '("~/code" "~/git")))) (-map (lambda (directory) (-map (lambda (project) (-> (concat project "/") ;; Projectile likes trailing slashes (projectile-add-known-project))) (-filter (lambda (f) (and (not (s-ends-with? "." f)) (f-directory? f))) (-map (lambda (f) (concat directory "/" f)) (directory-files directory))))) project-directories)) (projectile-cleanup-known-projects)) #+end_src * Elfeed #+begin_src emacs-lisp (use-package! elfeed :commands (elfeed my/elfeed my/elfeed-emacs my/elfeed-blogs) :bind (("" . elfeed) ("C-c n n" . my/elfeed) ("C-c n a" . my/elfeed-all) ("C-c n e" . my/elfeed-emacs) ("C-c n b" . my/elfeed-blogs)) :init (global-set-key [f2] 'elfeed) :config (use-package! elfeed-org :config (progn (elfeed-org) (setq rmh-elfeed-org-files '("~/org/elfeed.org")))) (defun my/elfeed-with-filters (filters) (elfeed) (setq elfeed-search-filter (if (listp filters) (mapconcat #'identity filters " ") filters)) (elfeed-search-update :force)) (defun my/elfeed () (interactive) (my/elfeed-with-filters "@6-months-ago +unread")) (defun my/elfeed-all () (interactive) (my/elfeed-with-filters "@6-months-ago")) (defun my/elfeed-emacs () (interactive) (my/elfeed-with-filters "@6-months-ago +emacs +unread")) (defun my/elfeed-blogs () (interactive) (my/elfeed-with-filters "@6-months-ago +unread +blog"))) #+end_src * Paredit #+begin_src emacs-lisp (use-package! paredit :hook ((emacs-lisp-mode . enable-paredit-mode))) #+end_src * UUID Generation #+begin_src emacs-lisp (use-package! uuidgen :commands (uuidgen)) #+end_src