Setting Up Doom Emacs

Links: Home CV Notes Blogs

Disable spelling suggestions from Company

(set-company-backend! 'text-mode '(company-dabbrev company-yasnippet :separate))

Fixes [0/4]

  • [ ] Fix pdf-tools-install
  • Capture templates [0/3]
    • [ ] Add Submission capture template
    • [ ] Add quote capture template
    • [ ] Add joke capture template

Always compile vterm

(setq vterm-always-compile-module t)

User details

Place your private configuration here! Remember, you do not need to run 'doom sync' after modifying this file!

Some functionality uses this to identify you, e.g. GPG configuration, email clients, file templates and snippets. It is optional.

(setq user-full-name "Adithya Bhat"
      user-mail-address "dth.bht@gmail.com")

Font

Doom exposes five (optional) variables for controlling fonts in Doom:

  • `doom-font' – the primary font to use
  • `doom-variable-pitch-font' – a non-monospace font (where applicable)
  • `doom-big-font' – used for `doom-big-font-mode'; use this for presentations or streaming.
  • `doom-unicode-font' – for unicode glyphs
  • `doom-serif-font' – for the `fixed-pitch-serif' face
(setq
 doom-font (font-spec :family "Iosevka Nerd Font" :size 21 :weight 'medium)
 doom-big-font (font-spec :family "Iosevka Nerd Font" :size 26)
 doom-variable-pitch-font (font-spec :family "SF Pro Text" :size 21))

Word count

Enable showing a word count in the modeline. This is only shown for the modes listed in doom-modeline-continuous-word-count-modes (Markdown, GFM and Org by default).

(setq doom-modeline-enable-word-count t)

Theme

(setq doom-theme 'doom-one)

Default directory

(setq default-directory "~")

Disable mouse

Sometimes the mouse gets in the way. Especially in org-agenda.

(setq mouse-avoidance-mode 'banish)

Line number

This determines the style of line numbers in effect. If set to `nil', it disables all the line numbers. For relative line numbers, set this to `relative'.

(setq display-line-numbers-type t)

MacOS specific setup

To ensure that the LaTeX related buffers function properly.

(setenv "PATH" (concat (getenv "PATH") ":/Library/TeX/texbin"))
;; (setenv "PKG_CONFIG_PATH" (concat "/usr/local/Cellar/poppler/22.06.0_1/lib/pkgconfig:" (getenv "PKG_CONFIG_PATH")))
(setq exec-path (append exec-path '("/Library/TeX/texbin")))
(cond (IS-MAC
       (setq mac-command-modifier       'super
             mac-option-modifier        'meta
             mac-right-option-modifier  'meta)))

Full size window on startup

FIXME. With yabai, this may not be necessary.

(add-to-list 'default-frame-alist '(ns-transparent-titlebar . t))
(add-to-list 'default-frame-alist '(ns-appearance . dark))

Auto-revert files that changed on the disk

Somehow the below configuration is not working

(global-auto-revert-mode t)

Splash screen

(setq fancy-splash-image (file-name-concat doom-private-dir "splash.png"))

Allow tiling

This allows yabai to work correctly with the Emacs windows.

(menu-bar-mode t)

Spelling

Close buffer if the compilation was successful

(defun bury-compile-buffer-if-successful (buffer string)
  "Bury a compilation buffer if succeeded without warnings "
  (when (and (eq major-mode 'comint-mode)
             (string-match "finished" string)
             (not
              (with-current-buffer buffer
                (search-forward "warning" nil t))))
    (run-with-timer 1 nil
                    (lambda (buf)
                      (let ((window (get-buffer-window buf)))
                        (when (and (window-live-p window)
                                   (eq buf (window-buffer window)))
                          (delete-window window))))
                    buffer)))

(add-hook 'compilation-finish-functions #'bury-compile-buffer-if-successful)

Helm Locate Patch

(after! helm
  (setq helm-locate-command "mdfind -name \\\"%2$s\\\""))

Commenting shortcuts

(map! :ne "M-/" #'comment-or-uncomment-region)

Agenda shortcut

Configuration

(setq org-agenda-custom-commands
      '(("." . "Custom Commands")
        (".a" "Regular Agenda"
         ((agenda nil
                  ((org-agenda-span 'day)
                   (org-agenda-skip-deadline-prewarning-if-scheduled 't)
                   (org-agenda-time-grid nil)
                   (org-agenda-overriding-header "Tasks for today")
                   (org-agenda-skip-function '(org-agenda-skip-entry-if 'todo '("NEXT" "CURRENT")))
                   (org-agenda-prefix-format " %i %-12:c%?-12t ")))
          (todo "NEXT"
                ((org-agenda-overriding-header "Next Tasks")
                 (org-agenda-prefix-format "  %i %-12:c [%e] %b ")))
          (agenda nil
                  ((org-agenda-span 7)
                   (org-deadline-warning-days 0)
                   (org-agenda-time-grid nil)
                   (org-agenda-deadline-leaders '("Deadline: " "(%3d d) " "(%3d d. ago) "))
                   (org-agenda-overriding-header "Deadlines")
                   (org-agenda-entry-types '(:deadline))))
          (todo "CURRENT"
                ((org-agenda-overriding-header "Current Projects")))))
        (".b" "Weekly Review"
         ((todo "PROJ"
                ((org-agenda-overriding-header "Inactive Projects")))
          (tags-todo "+TODO=\"DONE\"|+TODO=\"KILL\""
                     ((org-agenda-overriding-header "Finished tasks (Archive)")))
          (tags-todo "+tag-re=\"On+*\""
                     ((org-agenda-overriding-header "On Tags")))
          (todo "WAIT"
                ((org-agenda-overriding-header "Waiting (Check for Follow-up)")))
          (todo "TODO"
                ((org-agenda-overriding-header "All Todos")))))))
(defun hermitsage/org-agenda ()
  "Open all my open loops"
  (interactive)
  (org-agenda nil ".a"))
(defun hermitsage/org-weekly-review ()
  "Open all the tasks"
  (interactive)
  (org-agenda nil ".b"))
(map! :leader
      :prefix "a"
      "a" #'hermitsage/org-agenda
      "b" #'org-agenda-list
      "c" #'hermitsage/org-weekly-review)

jk to exit normal mode

The default was too fast for me.

(after! evil-escape
  (setq evil-escape-delay 1.0 ))

Support encrypting entries

Root Org Directory

Point to an iCloud directory.

(setq org-directory "~/iCloud/Research Notes/")

Setup org-modern

Sweet font rendering for org buffers.

(use-package! org-modern
  :hook (org-mode . global-org-modern-mode))

Capture templates

(setq +org-capture-todo-file "todo.org"
      +org-capture-notes-file "notes.org")
(setq my/org-capture-project-todo-file "todo.org"
      my/org-capture-project-notes-file "notes.org"
      my/org-capture-project-changelog-file "changes.org")
(after! org
  (setq org-capture-templates
        '(("t" "Personal todo" entry
           (file+headline +org-capture-todo-file "00-Inbox") ;; personal.org
           "* TODO %?\nSCHEDULED: <%<%Y-%m-%d %a>>\nCreated: %u\n%a\n%i" :prepend t)
          ("a" "Packages" entry
           (file+headline +org-capture-todo-file "Packages") ;; personal.org
           "* WAIT 📦 %?\n SCHEDULED: <%<%Y-%m-%d %a>>\nCreated: %u\n%a\n%i")
          ("b" "Book Recommendation" entry
           (file+headline "books.org" "Recommendations")
           "- [ ] 📖 %? by ?\nCreated: %u\n")
          ("n" "Personal notes" entry
           (file+headline +org-capture-notes-file "00-Notes") ;; notes.org
           "* %?\n%i\n%a\nCreated: %u" :prepend t)
          ("i" "Research Idea" entry
           (file+headline +org-capture-notes-file "00-Ideas") ;; notes.org
           "* %?\n%u")
          ("r" "Review" entry (file+headline "work.org" "PC work") "* PROJ %?\nDEADLINE: <%<%Y-%m-%d %a>>\nCreated: %u\n- Link to review\n- Link to PDF")
          ("x" "X Deep Topic" checkitem (file+headline "personal.org" "Deep Topics"))
          ("p" "Templates for projects")
          ("pt" "Project-local todo" entry
           (file+headline +org-capture-project-todo-file "Inbox")
           "* TODO %?\n%a\nCreated: %u\n%i\n" :prepend t)
          ("pn" "Project-local notes" entry
           (file+headline +org-capture-project-notes-file "Notes")
           "* %?\n%a\n%i\nCreated: %u" :prepend t)
          ("pc" "Project-local changelog" entry
           (file+headline +org-capture-project-changelog-file "Unreleased")
           "* %U %?\n%a\n%i" :prepend t))))

Task management keywords

(after! org
  (setq
   org-todo-keywords '((sequence
                        "TODO(t)" ; Need this task to be done
                        "WAIT(w@/!)" ; Waiting for an external event to occur to process this
                        "DELEGATED(x@/!)" ; Asked for someone's help for this
                        "BLOCKED(b@)" ; Don't know how to proceed with this task, need help
                        "NEXT(n)" ; This is the next item that needs to be done for this task
                        "|"
                        "DONE(d)" ; Finished the task successfully
                        "KILL(k@)") ; Cancelled the task
                       (sequence
                        "CURRENT(c)"; A collection of active tasks
                        "PROJ(q)" ; A collection of inactive tasks
                        "|"
                        "DONE(d)"
                        "KILL(k@)")
                       ;; Basic Todos for Checkboxes TSWD
                       (sequence "[ ](T)" "[-](S)" "[?](W@/!)" "|" "[X](D)"))))

Bibliography

The idea is to use Zotero to maintain one updated References.bib file in ~/Overleaf/References.bib. Then manually add symbolic links to this file once in org-directory. For every Overleaf document, add a symbolic link from the root directory ..

(setq bibtex-completion-bibliography '("~/Overleaf/References.bib")
      bibtex-completion-pdf-open-function
      (lambda (fpath)
        (call-process "open" nil 0 nil "-a" "/Applications/Skim.app" fpath)))

Setting up sunrise and sunset times in org-agenda

;; Set org agenda sunrise, sunset times
(setq
 calendar-latitude 40.425869
 calendar-longitude -86.908066)

Start org-agenda from current day

Setting org-agenda-start-on-weekday to nil means that the agenda view – even in the 7-days-at-a-time view – will always begin on the current day. This is important, since while using org-mode as a day planner, you never want to think of days gone past. That’s something you do in other ways, such as when reviewing completed tasks.

(after! org
  (setq org-agenda-start-on-weekday nil)
  (setq org-agenda-start-day "-0d"))

Refresh org-agenda files at runtime and startup

(defun my/org-roam-refresh-agenda-list ()
  (interactive)
  (setq org-agenda-files (append
                          (list "mobile.org" "work.org" "todo.org" "daily.org" "personal.org" "calendar-beorg.org")
                          (directory-files (concat org-directory "100-projects") t "\\.org$"))))

;; Build the agenda list the first time for the session
(my/org-roam-refresh-agenda-list)
(after! org
  (setq org-todo-repeat-to-state t
        org-agenda-skip-scheduled-if-done t
        org-agenda-skip-deadline-if-done t
        org-log-done 'time
        org-export-with-toc nil
        org-log-into-drawer t))

Setup org-roam

(after! org-roam
  :ensure t
  :init
  (setq org-roam-v2-ack t)
  :custom
  (setq org-roam-directory (file-name-concat org-directory "RoamNotes"))
  (setq org-roam-completion-everywhere t)
  (setq org-roam-capture-templates
        '(("d" "default" plain
           "%?"
           :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
           :unnarrowed t)
          ("r" "bibliography reference" plain
           "%?\n%^{author} published %^{entry-type} in %^{date}: fullcite:%\\1."
           :target (file+head "%<%Y%m%d%H%M%S>-${citekey}.org" "#+title: ${title}\n")
           :unnarrowed t)
          ))
  :config
  (org-roam-db-autosync-enable))

Setup org-roam-ui

(use-package! websocket
  :after org-roam)

(use-package! org-roam-ui
  :after org-roam ;; or :after org
  ;;         normally we'd recommend hooking orui after org-roam, but since org-roam does not have
  ;;         a hookable mode anymore, you're advised to pick something yourself
  ;;         if you don't care about startup time, use
  ;; :hook (after-init . org-roam-ui-mode)
  :config
  (setq org-roam-ui-sync-theme t
        org-roam-ui-follow t
        org-roam-ui-update-on-save t
        org-roam-ui-open-on-start t))

Preserve sub-tree when archiving

(defadvice org-archive-subtree (around my-org-archive-subtree activate)
  (let ((org-archive-location
         (if (save-excursion (org-back-to-heading)
                             (> (org-outline-level) 1))
             (concat (car (split-string org-archive-location "::"))
                     "::* "
                     (car (org-get-outline-path)))
           org-archive-location)))
    ad-do-it))

Add ACM Latex classes to Org Export

Add ACM articles to the list of org-latex-classes.

(after! ox-latex
  :config
  (add-to-list 'org-latex-classes
               '("acmart"
                 "\\documentclass{acmart}"
                 ("\\section{%s}" . "\\section*{%s}")
                 ("\\subsection{%s}" . "\\subsection*{%s}")
                 ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))

Do not inherit statistics from tree

Reset sub-tasks

To reset sub-tasks on completion. I have repeating projects like laundry, cleaning my car, etc. which on completion needs to reset with all the sub-tasks.

(defun org-reset-subtask-state-subtree ()
  "Reset all subtasks in an entry subtree."
  (interactive "*")
  (if (org-before-first-heading-p)
      (error "Not inside a tree")
    (save-excursion
      (save-restriction
        (org-narrow-to-subtree)
        (org-fold-show-subtree)
        (goto-char (point-min))
        (beginning-of-line 2)
        (narrow-to-region (point) (point-max))
        (org-map-entries
         '(when (member (org-get-todo-state) org-done-keywords)
            (if (org-entry-get (point) "REPEAT_TO_STATE")
                (org-todo (org-entry-get (point) "REPEAT_TO_STATE"))
              (org-todo (car org-todo-keywords)))))))))

(defun org-reset-subtask-state-maybe ()
  "Reset all subtasks in an entry if the `RESET_SUBTASKS' property is set"
  (interactive "*")
  (if (org-entry-get (point) "RESET_SUBTASKS")
      (org-reset-subtask-state-subtree)))

(defun org-subtask-reset ()
  (when (member org-state org-done-keywords) ;; org-state dynamically bound in org.el/org-todo
    (org-reset-subtask-state-maybe)
    (org-update-statistics-cookies t)))

(after! org
  :custom
  (setq org-default-properties (cons "RESET_SUBTASKS" org-default-properties))
  (add-hook 'org-after-todo-state-change-hook 'org-subtask-reset)
  (provide 'org-subtask-reset))

Org Roam BibTeX

Configuration

(use-package! org-roam-bibtex
  :after org-roam
  :config
  (require 'org-ref)
  (setq orb-roam-ref-format 'org-ref-v3)
  (setq bibtex-completion-notes-path org-roam-directory)) ; optional: if using Org-ref v2 or v3 citation links
(after! helm-bibtex
  (setq helm-bibtex-full-frame nil)
  (org-roam-bibtex-mode))

Keybindings

(map!
 :after org-roam
 :map org-roam-mode-map
 :localleader
 :desc "Orb note actions" "b" #'orb-note-actions)

Personal Website

Packages

(use-package! ox-extra
  :config
  (ox-extras-activate '(latex-header-blocks ignore-headlines)))

TODO Export function

Implement

  • auto-push to Github
  • auto add latest configuration
(defun my/org-publishing-function (plist filename pubdir)
  (interactive)
  (org-html-publish-to-html plist filename pubdir))

Configuration

(defcustom website-folder (file-name-concat "~/Github" "personal-website")
  "The folder containing the source files for the website."
  :type '(string))
(defcustom website-build-folder (file-name-concat website-folder "_site")
  "The folder to output the built HTML"
  :type '(string))
(defcustom website-assets-folder (file-name-concat website-folder "assets")
  "The folder containing all the assets for the website"
  :type '(string))
(defcustom website-assets-build-folder (file-name-concat website-build-folder "assets")
  "The folder to output the assets"
  :type '(string))

(defun prefix-all-lines (pre body)
  (with-temp-buffer
    (insert body)
    (string-insert-rectangle (point-min) (point-max) pre)
    (buffer-string)))

(defun org-babel-execute:latex-macros (body _params)
  (concat
   (prefix-all-lines "#+LATEX_HEADER: " body)
   "\n#+HTML_HEAD_EXTRA: <div style=\"display: none\"> \\(\n"
   (prefix-all-lines "#+HTML_HEAD_EXTRA: " body)
   "\n#+HTML_HEAD_EXTRA: \\)</div>\n"))

(setq org-publish-project-alist
      (list
       `("org"
         :recursive t
         :base-directory ,website-folder
         :publishing-directory ,website-build-folder
         :section-numbers nil
         :auto-sitemap t
         :makeindex t
         :publishing-function my/org-publishing-function)
       `("static"
         :recursive t
         :base-directory ,website-assets-folder
         :publishing-directory ,website-assets-build-folder
         :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|pptx"
         :publishing-function org-publish-attachment)
       '("personal-website" :components ("org" "static"))))

Projectile

Configuration

(setq projectile-project-search-path
      (list "~/Overleaf" "~/Github" website-build-folder))

Broken search fix

from https://github.com/doomemacs/doomemacs/issues/3038

;; Will only work on macos/linux
(after! counsel
  (setq counsel-rg-base-command "rg -M 10000 --with-filename --no-heading --line-number --color never %s || true"))

Default action is to open dired

(defun my/projectile-dired-open ()
  "Open the project root in Dired."
  (dired (projectile-project-root)))
(after! projectile
  (setq projectile-switch-project-action #'projectile-dired))

Project local snippets

Inspired from here: https://www.reddit.com/r/emacs/comments/57i41t/projectlocal_snippets/

(after! helm-projectile
  (defun crshd/set-projectile-yas-dir ()
    "Append a projectile-local YAS snippet dir to yas-snippet-dirs."
    (interactive)
    (let ((local-yas-dir (concat (projectile-project-root) ".snippets")))
      (when (file-directory-p local-yas-dir)
        (add-to-list 'yas-snippet-dirs local-yas-dir)
        (yas-reload-all))))

  (add-hook 'projectile-find-file-hook 'crshd/set-projectile-yas-dir))

LaTeX

Prevent compiler from stealing focus

Tweaked the code from https://github.com/doomemacs/doomemacs/blob/master/modules/lang/latex/%2Bviewers.el so that Skim uses the -g option which prevents Skim from stealing the focus.

(after! tex
  :config
  (dolist (viewer (reverse +latex-viewers))
    (pcase viewer
      (`skim
       (when-let
           (app-path
            (and IS-MAC
                 (file-exists-p! (or "/Applications/Skim.app"
                                     "~/Applications/Skim.app"))))
         (add-to-list 'TeX-view-program-selection '(output-pdf "Skim"))
         (add-to-list 'TeX-view-program-list
                      (list "Skim" (format "%s/Contents/SharedSupport/displayline -r -b -g %%n %%o %%b"
                                           app-path)))))))
  )

Remove Superscript and subscript specialization

(setq font-latex-fontify-script nil)

Disable company in latex mode

Company is annoying in LaTeX mode.

;; (after! company (cl-callf nconc company-global-modes (list 'latex-mode)))

Remove spellcheck in latex mode

(add-hook! 'TeX-mode-hook
           ;;(hl-todo-mode) ; TODO
           ;; Flycheck with both chktex and lacheck both just bother me with
           ;; worthless advice all the time. when my paper doesn't compile I'll re-
           ;; enable them.
           (flycheck-mode -1))

Key Bindings

(map!
 :map LaTeX-mode-map
 :localleader
 :desc "Insert Environment" "e" #'LaTeX-environment)
(map!
 :map LaTeX-mode-map
 :localleader
 :desc "Insert Yasnippet" "y" #'yas-insert-snippet)
(map!
 :map LaTeX-mode-map
 :localleader
 :desc "Insert Section" "s" #'LaTeX-section)
(map!
 :map LaTeX-mode-map
 :localleader
 :desc "Insert Macros" "." #'TeX-insert-macro)
(map!
 :map LaTeX-mode-map
 :localleader
 :desc "Insert Fonts" "t" #'TeX-font)
(map!
 :map projectile-mode-map
 :desc "Open the terminal" "C-j" #'+vterm/toggle)

Output files in build folder

Please do not corrupt my source directory with trash.

(setq-default TeX-output-dir "build")

Use LTeX for better grammar

(use-package lsp-ltex
  :ensure t
  :hook (TeX-mode . (lambda ()
                      (require 'lsp-ltex)
                      (lsp)))  ; or lsp-deferred
  :init
  (setq lsp-ltex-version "16.0.0")
  (setq lsp-ltex-disabled-rules '(:en ["MORFOLOGIK_RULE_EN_US"])))
;; Set LTeX LS variables

Use digestif LSP server

If texlab is not installed, digestif is the default lsp server.

  • Install digestif using luarocks install digestif
  • Install texlab using brew install texlab
;; (after! lsp
;; :config
;; (setq lsp-tex-server 'digestif))

LaTeX do not ignore warnings

(setq TeX-ignore-warnings t)

(FIX) Mu4e [0/3]

FIX Sending mail does not work

FIX Auto-sync does not work

Try removing the password/encryption in mutt_oauth2.py

Configuration

(use-package! mu4e
  :config
  (setq
   mu4e-change-filenames-when-moving t
   mu4e-get-mail-command "mbsync -a"
   mu4e-context-policy 'pick-first
   mu4e-update-interval (* 10 60))
  (setq mu4e-contexts
        (list
         ;; Personal account
         (make-mu4e-context
          :name "Personal"
          :match-func
          (lambda (msg)
            (when msg
              (string-prefix-p "/gmail" (mu4e-message-field msg :maildir))))
          :vars `((user-mail-address . "dth.bht@gmail.com")
                  (user-full-name . "Adithya Bhat")
                  (mu4e-drafts-folder . "/gmail/Drafts")
                  (mu4e-sent-folder . "/gmail/Sent Mail")
                  (mu4e-refile-folder . "/gmail/All Mail")
                  (mu4e-trash-folder . "/gmail/Trash")))
         ;; Work account
         (make-mu4e-context
          :name "Work"
          :match-func
          (lambda (msg)
            (when msg
              (string-prefix-p "/purdue" (mu4e-message-field msg :maildir))))
          :vars '((user-mail-address . "bhat24@purdue.edu")
                  (user-full-name . "Adithya Bhat")
                  (mu4e-drafts-folder . "/purdue/Drafts")
                  (mu4e-sent-folder . "/purdue/Sent Mail")
                  (mu4e-refile-folder . "/purdue/All Mail")
                  (mu4e-trash-folder . "/purdue/Trash"))))))

;; (after! mu4e
;;   (setq
;;    sendmail-program (executable-find "msmtp")
;;    message-sendmail-extra-arguments '("--read-envelope-from")
;;    message-send-mail-function #'message-send-mail-with-sendmail
;;    send-mail-function #'smtpmail-send-it))
;; ;;     ;; message-sendmail-f-is-evil t

Others

Helper functions

Fresh install

A function to do things that I need to do on every doom upgrade run like compile vterm and pdf-tools.

(defun my/after-fresh-install ()
  (interactive)
  (pdf-tools-install)
  (vterm-module-compile))

LaTeX add chktex shortcut

(after! tex
  (map! :localleader
        :map latex-mode-map
        :desc "Check Latex for Warnings (chktex)" "w" #'tex-chktex-command))

Configure LSP

(use-package! lsp-mode
  :ensure
  :custom
  (lsp-inlay-hint-enable t)
  (add-hook 'rustic-mode #'lsp-inlay-hints-mode)
  (lsp-auto-execute-action nil)
  (lsp-rust-analyzer-display-lifetime-elision-hints-enable "skip_trivial")
  (lsp-rust-analyzer-display-chaining-hints t)
  (lsp-rust-analyzer-display-parameter-hints t)
  (lsp-rust-analyzer-display-closure-return-type-hints t)
  :config
  (add-hook 'lsp-mode-hook 'lsp-ui-mode))
(map!
 :after rust-mode
 :map rustic-mode-map
 :localleader
 :desc "Custom actions" "a" #'lsp-rust-analyzer-open-cargo-toml)
(use-package lsp-ui
  :ensure
  :custom
  (lsp-ui-peek-always-show t)
  (lsp-ui-sideline-show-hover t)
  (lsp-ui-sideline-show-diagnostics t)
  (lsp-ui-sideline-show-code-actions t)
  (lsp-ui-doc-enable nil))

Custom Functions

Get all files in an attachment folder

(defun my/org/find-attachments-in-directory (directory)
  "Find all attachments in DIRECTORY and output Org links with filenames as link names."
  (interactive "DDirectory: ")
  (let ((attachments (directory-files-recursively directory ".*")))
    (dolist (file attachments)
      (let ((filename (file-name-nondirectory file)))
        (insert (format "- [[file:%s][%s]]\n" file filename))))))

Get all tasks with DONE and KILL keywords

(add-to-list 'org-modules 'org-ql)

(defun my/weekly-review/org-find-done-kill-wait-tasks-in-agenda-files ()
  "Find all Org tasks with DONE, KILL, and WAIT keywords in all Org agenda files and output a list with links to these tasks."
  (interactive)
  (let ((output-file "~/weekly-review.org")
        (done-kill-tasks '())
        (wait-tasks '())
        (proj-tasks '()))

    ;; Helper function to get the heading and link for each task
    (defun my/get-task-link ()
      (let ((heading (org-get-heading t t t t))
            (link (org-id-get-create)))
        (format "[[id:%s][%s]]" link heading)))

    ;; Query for DONE and KILL tasks
    (setq done-kill-tasks
          (org-ql-query
           :select '(my/get-task-link)
           :from (org-agenda-files)
           :where '(or (todo "DONE")
                       (todo "KILL"))))

    ;; Query for WAIT tasks
    (setq wait-tasks
          (org-ql-query
           :select '(my/get-task-link)
           :from (org-agenda-files)
           :where '(todo "WAIT")))

    ;; Query for PROJ tasks
    (setq proj-tasks
          (org-ql-query
           :select '(my/get-task-link)
           :from (org-agenda-files)
           :where '(todo "PROJ")))

    ;; Write results to output file
    (with-temp-buffer
      (insert "#+TITLE: Weekly Review\n\n")
      (insert "* Tasks to Archive [/]\n")
      (dolist (task done-kill-tasks)
        (insert (format "- [ ] %s\n" task)))
      (insert "* Waiting Tasks [/]\n")
      (dolist (task wait-tasks)
        (insert (format "- [ ] %s\n" task)))
      (insert "* Non-current Projects [/]\n")
      (dolist (task proj-tasks)
        (insert (format "- [ ] %s\n" task)))
      (write-file output-file))
    (message "Tasks with DONE, KILL, WAIT, and PROJ keywords have been written to %s" output-file)))

Co-pilot

(setq copilot-node-executable "/opt/homebrew/bin/node")
;; accept completion from copilot and fallback to company
(use-package! copilot
  :hook ((prog-mode . copilot-mode)
         (TeX-mode . copilot-mode))
  :bind (:map copilot-completion-map
              ("<tab>" . 'copilot-accept-completion)
              ("TAB" . 'copilot-accept-completion)
              ("C-TAB" . 'copilot-accept-completion-by-word)
              ("C-<tab>" . 'copilot-accept-completion-by-word)))

Org Modules

  1. Get org-checklist so that we can reset checkboxes in a todo item.

    ;; https://orgmode.org/worg/org-contrib/org-checklist.html
    (add-to-list 'org-modules 'org-checklist)
    
  2. Get org-depend so that we can use :TRIGGER: chain-siblings(TODO), and :TRIGGER: chain-siblings-scheduled

    ;; https://orgmode.org/worg/org-contrib/org-depend.html
    (add-to-list 'org-modules 'org-depend)
    
(insert-file-contents "~/.config/doom/config.org")

Date: June 10, 2023

Author: Adithya Bhat

Created: 2024-07-31 Wed 22:13