UP | HOME

Literate doom-emacs config

Table of Contents

  • 1. Doom Emacs Stuff
  • 2. R Helpers
  • 3. Org LaTeX
  • 4. Notes
  • 0.1 About

    This is a literate config file for doom-emacs by hlinssner. This is meant to be used with the develop branch. Much of the basic setup is pulled from the emacs literate starter by gilbertw1. The companion packages page describes the basic package setup, while the init.el is described on the project homepage.

    0.1.1 About that TOC..

    So as mentioned here there is trouble when org-export tries to create files while keeping the org-toc tag.

    It’s not really a problem since org-export actually generates a TOC for the files anyway.

    0.2 Personal Information

    Let’s set some variables with basic user information.

    (setq user-full-name "Rohit Goswami (HaoZeke)"
          user-mail-address "rohit.goswami@aol.com")
    

    1 Doom Emacs Stuff

    1.0.1 Visual tweaks

    1. Font Face

      Honestly the basic font setting is simply not pretty enough.

      (setq doom-font (font-spec :family "Attribute Mono" :size 20))
      (unless (find-font doom-font)
        (setq doom-font (font-spec :family "FuraCode Nerd Font" :size 20)))
      
    2. Unicode Fonts

      This should be implemented as fallback font once this is merged.

      (setq doom-unicode-font (font-spec :name "DejaVu Sans Mono" :size 20))
      
      
    3. Helm and Childframes

      I prefer the regular diminished font size, even for the childframes.

      ;; Undo the helm text enlargement in childframes
      (setq +helm-posframe-text-scale 0)
      
    4. Saner Dashboard

      I have trouble at work with the current DOOM dashboard. This one is from the doom-emacs lead developer, as found on Discord.

      (setq +doom-dashboard-banner-file (expand-file-name "banner.png" doom-private-dir))
      

    1.0.2 Helm changes

    This makes `helm` behave more like `ivy` while working with directories.

    (after! helm
      ;; I want backspace to go up a level, like ivy
      (add-hook! 'helm-find-files-after-init-hook
        (map! :map helm-find-files-map
              "<DEL>" #'helm-find-files-up-one-level)))
    

    1.0.3 Kill spellcheck

    This is really really really excruciatingly slow for LaTeX mode and maybe even for other random buffers.

    (setq-hook! 'LaTeX-mode-hook +spellcheck-immediately nil)
    
    1. Snippets

      I am not sure if these need to be initialized.

      ; hlissner
      (use-package! doom-snippets
        :after yasnippet)
      ; AndreaCrotti
      (use-package! yasnippet-snippets
        :after yasnippet)
      

    1.0.4 Kill over-eager literate after-save-hook

    This is a little to frequent for working with a git repo. Henrik mentioned an async version of the recompliation might be in the works, until then however I will probably only manually trigger the recompliation.

    (after! 'org
      (remove-hook 'after-save-hook #'+literate|recompile-maybe)
    )
    

    1.0.5 Kill Orgmode template

    These conflict with my other templates.

    (set-file-template! "\\.org$" :ignore t)
    

    1.0.6 Variables

    (setq
       org_notes (concat (getenv "HOME") "/Git/Gitlab/Mine/Notes/")
       zot_bib (concat (getenv "HOME") "/GDrive/zotLib.bib")
       org-directory org_notes
       deft-directory org_notes
       org-roam-directory org_notes
       )
    

    1.0.7 Do not Format on Save

    Formatting with styler takes forever.

    (setq +format-on-save-enabled-modes '(not emacs-lisp-mode ; works well enough without it
                                              sql-mode        ; sqlformat is broken
                                              tex-mode        ; latexindent is broken
                                              latex-mode      ; latexindent is broken
                                              ess-r-mode      ; styler takes forever
                                              web-mode      ; dunno who this is for
                                              ))
    

    1.1 Keybindings

    These are eventually going to with general anyway. So it’s better to load that for now and carry on. Later this block can be prevented from being tangled.

    1.1.1 DONE General

    • [X] Remove once merged upstream.

    This does very little other than load it and remind it that SPC is the leader for the other bindings to work.

    (use-package! general)
    ;; Creating a constant for making future changes simpler
    (defconst my-leader "SPC")
    ;; Tell general all about it
    (general-create-definer my-leader-def
      :prefix my-leader)
      ;; :prefix my-leader)
    ;; (general-create-definer my-local-leader-def
    ;;   ;; :prefix my-local-leader
    ;;   :prefix "SPC m")
    

    1.1.2 Evil Setup and Error Handling

    Actually this might not be ported over so I’m just going to put this elsewhere.

    ;; I like short names
    (general-evil-setup t)
    ;; Stop telling me things begin with non-prefix keys
    (general-auto-unbind-keys)
    

    1.1.3 Spacemacs Equivalency

    1. Kill buffer

      Also it’s inconvenient to have a key chord requiring two hands to close a buffer.

      ; Compatibility, delete when fully migrated
      (defconst my-leader "SPC")
      ; Bind a new key chord
      (map!
       (:leader
         (:prefix "b"
           :desc "Kill buffer" "d" #'kill-this-buffer)
         (:prefix ("k" . "kill")
           :desc "Save and kill" "e" 'save-buffers-kill-terminal
           :desc "Kill buffer" "b" 'my-kill-this-buffer
           :desc "Delete frame" "f" 'delete-frame
         (:prefix ("o" . "Other")
           :desc "Frames" "f" 'delete-other-frames
           :desc "Windows" "w" 'delete-other-windows
           )
         )
         ))
      
      1. general.el

        The binding syntax of the future, TODAY!

        ;; ** Global Keybindings
        ;; Normal mode?
        (nmap
         :prefix my-leader
         "b d" #'kill-this-buffer
          ;; kill things
          "k" '(:ignore t :which-key "kill")
          "k e" 'save-buffers-kill-terminal
          "k b" 'my-kill-this-buffer
          "k f" 'delete-frame
          "k o f" 'delete-other-frames
          "k o w" 'delete-other-windows
         "a" 'helm-mini)
        ;; (my-leader-def 'normal 'override
        ;;   "a" 'org-agenda)
        

    1.1.4 Global Maps

    1. Multiple Cursors

      These need practice. Many of these are already in the default configuration, but they are redefined here for mnemonic usage. Also to add the which-key hints.

      (nmap
        :prefix "gz"
        :keymaps 'global
        "r" '(mc/edit-lines :wk "Span region")
        "z" '(+evil/mc-make-cursor-here :wk "Place frozen cursor")
        )
      
    2. Replace Stuff

      There are way too many of these to keep using helm.

      (map! :leader
            (:prefix ("r" . "Replace")
            :desc "String" "s" 'replace-string
            :desc "Query" "q" 'query-replace
            (:prefix ("r" . "Regexp")
              :desc "String" "s" 'replace-regexp
              :desc "Query" "q" 'query-replace-regexp
              )
            )
            )
      
    3. Spelling
      (map! :leader
       :n "z" 'flyspell-correct-at-point)
      
    4. Insert Unicode

      This should hopefully propogate across all modes.

      (map! :leader
            (:prefix ("i" . "Insert")
             :desc "Unicode" "u" 'insert-char
             :desc "Snippet" "s" 'yas-insert-snippet
             :desc "From Clipboard" "y" '+default/yank-pop
             :desc "From Evil Registers" "r" 'counsel-evil-registers
            )
      )
      
    5. Wrap Words
      • [ ] Load conditionally

      This is for working with the various options enabled by +smartparens.

      (map! :leader
            (:prefix ("i" . "Insert")
              (:prefix ("w" . "Wrap")
                :desc "Backticks" "`" . 'sp-wrap-backtick
                :desc "Tildes" "~" . 'sp-wrap-tilde
                )))
      
    6. Lookup

      These were bound to really weird things.

      (nmap
        :prefix my-leader
        ;; look things up
        "l" '(:ignore t :wk "lookup")
        "l o" '(+lookup/online-select :wk "Online")
        "l f" '(+lookup/file :wk "File")
        )
      
    7. No ESC

      The escape key for exiting things seems very painful.

      (general-define-key
       :keymaps '(insert visual normal)
       "S-SPC" 'evil-force-normal-state)
      

    1.1.5 Markdown Improvements

    Local leader is already bound to `m` and there are few bindings, this just adds more.

    (map! :localleader
          :map markdown-mode-map
          :prefix ("i" . "Insert")
          :desc "Blockquote"    "q" 'markdown-insert-blockquote
          :desc "Bold"          "b" 'markdown-insert-bold
          :desc "Code"          "c" 'markdown-insert-code
          :desc "Emphasis"      "e" 'markdown-insert-italic
          :desc "Footnote"      "f" 'markdown-insert-footnote
          :desc "Code Block"    "s" 'markdown-insert-gfm-code-block
          :desc "Image"         "i" 'markdown-insert-image
          :desc "Link"          "l" 'markdown-insert-link
          :desc "List Item"     "n" 'markdown-insert-list-item
          :desc "Pre"           "p" 'markdown-insert-pre
          (:prefix ("h" . "Headings")
            :desc "One"   "1" 'markdown-insert-atx-1
            :desc "Two"   "2" 'markdown-insert-atx-2
            :desc "Three" "3" 'markdown-insert-atx-3
            :desc "Four"  "4" 'markdown-insert-atx-4
            :desc "Five"  "5" 'markdown-insert-atx-5
            :desc "Six"   "6" 'markdown-insert-atx-6))
    

    1.1.6 Org Noter

    These bindings should probably be after org-noter is loaded.

    (map! :localleader
          :map (org-mode-map pdf-view-mode-map)
          (:prefix ("o" . "Org")
            (:prefix ("n" . "Noter")
              :desc "Noter" "n" 'org-noter
              )))
    

    1.1.7 Org Mode additions

    Apart from extension specific bindings, here we define useful functions which are a part of org-mode.

    (after! org (map! :localleader
          :map org-mode-map
          :desc "Eval Block" "e" 'ober-eval-block-in-repl
          (:prefix "o"
            :desc "Tags" "t" 'org-set-tags
            :desc "Roam Bibtex" "b" 'orb-note-actions
            (:prefix ("p" . "Properties")
              :desc "Set" "s" 'org-set-property
              :desc "Delete" "d" 'org-delete-property
              :desc "Actions" "a" 'org-property-action
              )
            )
          (:prefix ("i" . "Insert")
            :desc "Link/Image" "l" 'org-insert-link
            :desc "Item" "o" 'org-toggle-item
            :desc "Citation" "c" 'org-ref-helm-insert-cite-link
            :desc "Footnote" "f" 'org-footnote-action
            :desc "Table" "t" 'org-table-create-or-convert-from-region
            :desc "Screenshot" "s" 'org-download-screenshot
            (:prefix ("h" . "Headings")
              :desc "Normal" "h" 'org-insert-heading
              :desc "Todo" "t" 'org-insert-todo-heading
              (:prefix ("s" . "Subheadings")
                :desc "Normal" "s" 'org-insert-subheading
                :desc "Todo" "t" 'org-insert-todo-subheading
                )
              )
            (:prefix ("e" . "Exports")
              :desc "Dispatch" "d" 'org-export-dispatch
              )
            )
          )
      )
    

    1.1.8 Anki Editor

    These are only relevant to org-mode. Nevertheless they are not part of org-mode so semantically it makes no sense to use o after the localleader.

    (map! :localleader
          :map org-mode-map
          (:prefix ("a" . "Anki")
            :desc "Push" "p" 'anki-editor-push-notes
            :desc "Retry" "r" 'anki-editor-retry-failure-notes
            :desc "Insert" "n" 'anki-editor-insert-note
            (:prefix ("c" . "Cloze")
              :desc "Dwim" "d" 'anki-editor-cloze-dwim
              :desc "Region" "r" 'anki-editor-cloze-region
              )
            )
     )
    

    1.1.9 CC Mode

    These are basically wrappers around various rtags functions.

    (nmap
    :prefix my-leader
    :keymaps 'c-mode-base-map
    "m" '(:ignore t :wk "Local Commands")
    "m r" '(:ignore t :wk "Rtags")
    "m r c" '(rtags-check-includes :wk "Check Includes")
    ;; All the find commands
    "m r f" '(:ignore t :wk "Find")
    "m r f s" '(:ignore t :wk "Symbol")
    "m r f s a" '(rtags-find-symbol-at-point :wk "At point")
    "m r f s s" '(rtags-find-symbol :wk "Symbol")
    "m r f s c" '(:ignore t :wk "Current")
    "m r f s c f" '(rtags-find-symbol-current-file :wk "File")
    "m r f s c d" '(rtags-find-symbol-current-dir :wk "Directory")
    "m r f f" '(rtags-find-functions-called-by-this-function :wk "Functions")
    "m r f r" '(rtags-find-references :wk "References")
    )
    
    

    1.1.10 Evil Colemak

    These are mostly because movement without hnei is horrible. Read about it here.

    (use-package! evil-colemak-basics
      :after evil
      :config
      (setq evil-colemak-basics-rotate-t-f-j t)
      (global-evil-colemak-basics-mode)
      )
    
    1. Visual Lines

      Since I tend to keep visual-line-mode all the time, evil-better-visual-line is a natural choice.

      (use-package! evil-better-visual-line
        :after evil-colemak-basics
        :config
        (evil-better-visual-line-on)
        (map! :map evil-colemak-basics-keymap
              (:nvm "n" 'evil-better-visual-line-next-line
               :nvm "e" 'evil-better-visual-line-previous-line
               :nvm "g n" 'evil-next-line
               :nvm "g e" 'evil-previous-line))
      )
      
    2. Search

      Harmonizing with Vimium.

      (after! evil (map! :map evil-motion-state-map
                         (:n :desc "Previous match" "K" 'evil-ex-search-previous
                          :n :desc "Next match" "k" 'evil-ex-search-next
                          :n :desc "Forward search" "/" 'evil-search-forward
                          )
                         ))
      
    3. Window Bindings

      These are somehow not part of the evil-colemak setup.

      (after! evil
        (map! :map evil-window-map
              (:leader
               (:prefix ("w" . "Select Window")
                :n :desc "Left"  "h" 'evil-window-left
                :n :desc "Up"    "e" 'evil-window-up
                :n :desc "Down"  "n" 'evil-window-down
                :n :desc "Right" "i" 'evil-window-right
                ))
              ))
      
    4. Page Movement

      Harmonizing with Zathura.

      (after! evil
        (map! :map evil-colemak-basics-keymap
            :nv "N" 'evil-scroll-page-down
            :nv "E" 'evil-scroll-page-up)
        )
      
    5. Evil Org

      Annoyingly, evil-org-mode had a map which kept overriding all my other settings. Thankfully it has a helper variable to set movement. I also do not need this anyway, at-least not by default.

      (after! org
        (remove-hook 'org-mode-hook 'evil-org-mode)
        (setq evil-org-movement-bindings
              '((up . "e") (down . "n")
                (left . "h") (right . "i"))
              )
      )
      

    1.1.11 DONE Neotree –> Treemacs

    1. CANCELLED Toggle pane

      This remaps SPC o N to use treemacs. I guess this doesn’t make all that much sense, but t and T and bound to terminals and that makes sense, so I guess this is fine.

      ;; Remap opening the sidebar
      (map! :leader
            :nv "o n" nil
            :desc "Open treemacs pane"
            :n "o n" #'+treemacs/toggle)
      ;; Remap finding stuff
      (map! :leader
            :nv "o N" nil
            :desc "Treemacs find file"
            :n "o N" 'treemacs-find-file)
      

      Cancelled since this commit on the develop branch.

    1.1.12 TeX Mode

    These are more semantic for me.

    (nmap
      :prefix my-leader
      :keymaps '(latex-mode-map tex-mode-map LaTeX-mode-map)
      ;; Folding Stuff
      "m f" '(:ignore t :wk "Fold Things")
      "m f c" '(TeX-fold-comment :wk "Comment")
      "m f e" '(TeX-fold-env :wk "Environment")
      "m f m" '(TeX-fold-math :wk "Math")
      ;; Insertions
      "m i" '(:ignore t :wk "Insert")
      "m i m" '(helm-insert-latex-math :wk "Math Symbols")
      "m i r" '(:ignore t :wk "References")
      "m i r h" '(helm-bibtex-with-local-bibliography :wk "Helm")
      "m i r r" '(reftex-citation :wk "Reftex")
      )
    

    1.2 Safe Evals and Variables

    1.2.1 Private Variables

    These are encrypted with gpg and are essentially set mostly by custom-*

    (use-package! epa-file
      :demand
      :config
      (epa-file-enable)
      (setq custom-file (concat doom-private-dir "local/private.el.gpg"))
      (load custom-file)
    )
    

    1.2.2 Safe Variables

    The problem is that packages.el isn’t being produced by the clever little ugly commit I tried so, this is a workaround to tangle any file to be produced in .el format in the same location.

    1. Tangle

      So adding the automatic tangling code doesn’t mangle things up everytime you open emacs. Basically this is adapted from this reddit thread.

      (add-to-list 'safe-local-variable-values
                   '(eval add-hook 'after-save-hook
                        (lambda () (org-babel-tangle))
                        nil t))
      
    2. TODO Export

      This is a catch all for the eventual org-mode based multiple target exports.

      (add-to-list 'safe-local-variable-values
                      '(eval add-hook 'after-save-hook 'haozeke/org-save-and-export-tex nil t)
                      '(eval add-hook 'after-save-hook 'haozeke/org-save-and-export-pdf nil t))
      
    3. TODO Caveats
      • This actually forms it relative to the exact path. (Gotta move it to the config folder)
      • The actual code is much more elegant in every way possible.
      • Seriously there has to be a way to not have to do this.

    1.2.3 TODO Safe Evals

    This enables the evaluation of these forms. Read more about this via docstrings sometime.

    (add-to-list 'safe-local-eval-forms (eval add-hook 'after-save-hook haozeke/org-save-and-export))
    

    1.2.4 Asynchronous Exports

    As per this interesting answer on the superuser forums, I need to set org-export-async-init-file.

    (setq org-export-async-init-file (concat doom-private-dir "local/async-ox.el"))
    

    1.3 Package Settings

    These should eventually go into a different module. Each of these.

    1.3.1 Word wrap

    This section is to work with the settings for the word-wrap doom module.

    ;; enable word-wrap in C/C++/ObjC/Java
    (add-hook! 'markdown-mode-hook #'+word-wrap-mode)
    (add-hook! 'text-mode-hook #'+word-wrap-mode)
    (add-hook! 'tex-mode-hook #'+word-wrap-mode)
    

    1.3.2 Magit Aids

    1. DONE Magit todos

      Of course this is not really meant to be here.. A variation of this was included upstream in the develop branch.

      (use-package! magit-org-todos
        :mode "\\COMMIT_EDITMSG\\'"
        :commands (magit-org-todods magit-org-todos-autoinsert)
        :config
        (magit-org-todos-autoinsert))
      
      (use-package! magit-todos)
      
    2. DONE Magithub

      This is for sweet github integration. Also integrated upstream.

      (use-package! magithub
        :after magit
        :commands (magithub-clone
                   magithub-completion-enable)
        ;; :ensure t
        :config
        (magithub-feature-autoinject t)
        (setq
         magithub-clone-default-directory "$HOME/Git/Github/"
         magithub-dir (concat doom-etc-dir "magithub/")
         magithub-preferred-remote-method 'clone_url))
      (use-package! evil-magit :after magit
        :init
        (setq evil-magit-state 'normal))
      

    1.3.3 PDF Tools

    These bindings are essentially part of org-noter however, they do not actually need to be bound in org-mode files. Also updated to have evil-colemak bindings.

    (after! pdf-view
      ;; open pdfs scaled to fit page
      (setq-default pdf-view-display-size 'fit-width)
      (add-hook! 'pdf-view-mode-hook (evil-colemak-basics-mode -1))
      ;; automatically annotate highlights
      (setq pdf-annot-activate-created-annotations t
            pdf-view-resize-factor 1.1)
       ;; faster motion
     (map!
       :map pdf-view-mode-map
       :n "g g"          #'pdf-view-first-page
       :n "G"            #'pdf-view-last-page
       :n "N"            #'pdf-view-next-page-command
       :n "E"            #'pdf-view-previous-page-command
       :n "e"            #'evil-collection-pdf-view-previous-line-or-previous-page
       :n "n"            #'evil-collection-pdf-view-next-line-or-next-page
       :localleader
       (:prefix "o"
        (:prefix "n"
         :desc "Insert" "i" 'org-noter-insert-note
         ))
     ))
    

    1.4 Anki Editor

    This is for my favorite anki interaction mechanism.

    (use-package! anki-editor
      :after org-noter
      :config
      ; I like making decks
      (setq anki-editor-create-decks 't))
    

    1.5 Org Additions

    These are numerous and complicated enough to be in a segment of their own.

    1.5.1 todo Modifications

    I like having the date on my TODO items.

    (setq org-log-done "time"
          org-log-done-with-time 't)
    

    1.5.2 File Handling

    This controls what is used to open links in org documents. Since there are only a few defaults defined, I am just prepending them to my changes instead of dealing with append and stuff.

    (setq org-file-apps
      '((auto-mode . emacs)
        ("\\.mm\\'" . default)
        ("\\.x?html?\\'" . default)
        ("\\.pdf\\'" . default)
        ("\\.png\\'" . viewnior)
        ("\\.jpg\\'" . viewnior)
        ("\\.svg\\'" . viewnior)
        ))
    

    1.5.3 KILL Ob-Julia

    So julia support is inbuilt, however the process variable needs to be set:

    (setq  inferior-julia-program-name "/bin/julia")
    

    1.5.4 Org Download

    This is already included in the standard doom setup. However, I was having trouble with relative exports so I have this one instead. Partially kanged from doom-emacs.

    (use-package! org-download
      :after org
      :config
      (setq-default org-download-image-dir "./images/"
                    org-download-screenshot-method "gnome-screenshot -a -f %s"
                    org-download-method 'directory
                    org-download-heading-lvl 1
                    )
      )
    

    1.5.5 Org Babel

    Julia and Mathematica are not set. Other languages might also be needed here eventually.

    (after! 'org
                (org-babel-do-load-languages 'org-babel-load-languages
                                             (append org-babel-load-languages
                                                     ;; '((julia . t))
                                                     '((mathematica . t))
                                                     ))
                )
    (setq org-babel-mathematica-command "~/.local/bin/mash")
    

    1.5.6 Async Org Babel

    From here. Now we can configure this.

    (use-package! org-babel-eval-in-repl
      :after org
      :config
      (setq eir-jump-after-eval nil)
      )
    

    1.5.7 Org Config

    These are just variables I need to set to prevent things from dying.

    1. Switching to XeLaTeX

      Since I use a lot of unicode math; it makes sense to switch from LaTeX to XeLaTeX everywhere. This section borrows heavily from here and here. Might possibly want to look at this later too.

      ;; Set after the default-packages list anyway
      (setq org-latex-packages-alist 'nil)
      (setq org-latex-default-packages-alist
        '(("AUTO" "inputenc"  t ("pdflatex"))
          ("T1"   "fontenc"   t ("pdflatex"))
          (""     "graphicx"  t)
          (""     "grffile"   t)
          (""     "minted"   t)
          ;; ("dvipsnames,svgnames*,x11names*,table"     "xcolor"   t)
          (""     "longtable" nil)
          (""     "wrapfig"   nil)
          (""     "rotating"  nil)
          ("normalem" "ulem"  t)
          (""     "amsmath"   t)
          (""     "amssymb"   t)
          (""     "unicode-math"   t)
          (""     "mathtools"   t)
          (""     "textcomp"  t)
          (""     "capt-of"   nil)
          (""     "hyperref"  nil)))
      ;; (add-to-list 'org-latex-default-packages-alist '("" "fontspec" t))
      ;; (setq org-latex-inputenc-alist '(("utf8" . "utf8x")))
      ;; (add-to-list 'org-latex-packages-alist '("" "unicode-math"))
      (plist-put org-format-latex-options :scale 2.2)
      (add-to-list 'org-preview-latex-process-alist '(dvixelatex :programs
               ("xetex" "convert")
               :description "pdf > png" :message "you need to install the programs: xetex and imagemagick." :image-input-type "pdf" :image-output-type "png" :image-size-adjust
               (1.0 . 1.0)
               :latex-compiler
               ("xelatex -no-pdf -interaction nonstopmode -output-directory %o %f")
               :image-converter
               ("dvisvgm %f -n -b min -c %S -o %O")))
      
      (add-to-list 'org-preview-latex-process-alist '(imagexetex :programs
               ("xelatex" "convert")
               :description "pdf > png" :message "you need to install the programs: xelatex and imagemagick." :image-input-type "pdf" :image-output-type "png" :image-size-adjust
               (1.0 . 1.0)
               :latex-compiler
               ("xelatex -interaction nonstopmode -output-directory %o %f")
               :image-converter
               ("convert -density %D -trim -antialias %f -quality 100 %O")))
      
    2. Inline images

      These need to be disabled by default otherwise emacs stalls often. Also, it turns out that dvipng has some bugs on my system, so Imagemagick works better, once security policies have been adjusted in /etc/ImageMagick-/policy.xml.

      (setq org-preview-latex-default-process 'imagexetex)
      (setq org-startup-with-inline-images 'nil)
      (setq org-image-actual-width 500)
      

    1.5.8 Org Rifle

    This probably needs to be refactored later. Or loaded elsewhere. The keymaps are defined in the following way:

    (use-package! helm-org-rifle
      :after org
      :general
      (:keymaps 'org-mode-map
                :states 'normal
                :prefix my-leader
                "m r" '(:ignore t :wk "Rifle (Helm)")
                "m r b" '(helm-org-rifle-current-buffer :wk "Rifle buffer")
                "m r e" '(helm-org-rifle :wk "Rifle every open buffer")
                "m r d" '(helm-org-rifle-directory :wk "Rifle from org-directory")
                "m r a" '(helm-org-rifle-agenda-files :wk "Rifle agenda")
                "m r o" '(:ignore t :wk "Occur (Persistent)")
                "m r o b" '(helm-org-rifle-current-buffer :wk "Rifle buffer")
                "m r o e" '(helm-org-rifle :wk "Rifle every open buffer")
                "m r o d" '(helm-org-rifle-directory :wk "Rifle from org-directory")
                "m r o a" '(helm-org-rifle-agenda-files :wk "Rifle agenda")
                )
      )
    

    1.5.9 Org Mind Map

    This is used to create graphiz graphs from org-mode stuff.

    (use-package! org-mind-map
      :general
      (:keymaps 'org-mode-map
                :states 'normal
                :prefix my-leader
                "m e m" '(org-mind-map-write :wk "Export mind-map") ))
    

    1.5.10 Org Drill

    This is much easier to work with compared to the Anki mode stuff.

    (use-package! org-drill
      :after org)
    

    1.5.11 Org Re-Reveal Refs

    This is apparently the org-ref for org-re-reveal.

    (use-package! org-re-reveal-ref)
    

    1.5.12 Hugo Settings

    This should be set for everything. I like to keep the last modified date, but only consider things to be modified if 12 hours have passed.

    (setq org-hugo-auto-set-lastmod 't
          org-hugo-section "posts"
          org-hugo-suppress-lastmod-period 43200.0
          org-hugo-export-creator-string "Emacs 26.3 (Org mode 9.4 + ox-hugo + HaoZeke)"
    )
    

    1.6 Syntax Highlighting

    This section is for setting up major modes for various file formats which are typically non-standard. These are matched by extensions.

    1.6.1 TODO Direnv Highlighting

    direnv is essentially a specialized bash script. Until I have time to make a proper font locking mode for it, this should suffice.

    (setq auto-mode-alist (append '(("\\.envrc$" . shell-script-mode))
                                  auto-mode-alist))
    

    1.6.2 PKGBUILD Mode

    This is the non doom way of loading this.

    (autoload 'pkgbuild-mode "pkgbuild-mode.el" "PKGBUILD mode." t)
    (setq auto-mode-alist (append '(("/PKGBUILD$" . pkgbuild-mode))
                                  auto-mode-alist))
    

    I use doom. So.

    (use-package! pkgbuild-mode
      :mode "\\PKGBUILD")
    

    1.6.3 LAMMPS Mode

    1. No doom setup

      For most users.

      (autoload 'lammps-mode "lammps-mode.el" "LAMMPS mode." t)
      (setq auto-mode-alist (append
                                    '(("in\\.'" . lammps-mode))
                                    '(("\\.lmp\\'" . lammps-mode))
                                    auto-mode-alist
                                    ))
      
    2. Doom Version

      With macros.

      (use-package! lammps-mode)
      (setq auto-mode-alist (append
                                    '(("in\\.'" . lammps-mode))
                                    '(("\\.lmp\\'" . lammps-mode))
                                    auto-mode-alist
                                    ))
      

    1.6.4 Pug Mode

    Need better font locking everywhere.

    (use-package! pug-mode
      :mode "\\.pug\\'")
    

    1.6.5 Conf Mode Files

    The rc files are usually encountered while building android stuff. They are handled well by conf-mode. Turns out that vmd files also look just like conf-mode things…

    (setq auto-mode-alist
                 (append
                 '(("\\.rc\\'" . conf-mode))
                 '(("\\.vmd\\'" . conf-mode))
                 auto-mode-alist
                 ))
    

    1.6.6 FORTRAN

    Strangely the default settings do not pick up a bunch of fortran files.

    (setq auto-mode-alist
                 (append
                 '(("\\.F90\\'" . fortran-mode))
                 auto-mode-alist
                 ))
    

    1.6.7 JVM Languages

    Since java+meghnada, clojure, and scala are covered by the standard doom config, the rest of these need to be loaded here.

    (use-package! kotlin-mode
      :mode "\\.kt\\'")
    
    (use-package! groovy-mode
      :mode "\\.groovy\\'")
    

    1.6.8 Systemd

    For all those user-units.

    (use-package! systemd
      :mode "\\.service\\'")
    

    1.6.9 Dart Mode

    Dart seems like a rather fun C-like language. Sort of fallen on the wayside what with Golang and what not but still might be worth a shot.

    (use-package! dart-mode
      :mode "\\.dart\\'")
    

    1.6.10 SaltStack

    I like having spell checks for everything.

    ;; Load it
    (use-package! salt-mode
      :config
    ;; Flyspell
    (add-hook 'salt-mode-hook
            (lambda ()
                (flyspell-mode 1))))
    

    1.6.11 Mathematica

    Apparently, wolfram-mode is the best for syntax highlighting.

    ;; Load it
    (use-package! wolfram-mode
      :config
      (setq mathematica-command-line "~/.local/bin/mash")
      (add-to-list 'org-src-lang-modes '("mathematica" . wolfram)))
    

    1.7 Aesthetics

    1.7.1 Wakatime

    Was removed from the core modules of doom-emacs.

    (use-package! wakatime-mode)
    

    1.8 Dockerfile Mode

    This package from spotify has support for building things as well as highlighting Dockerfiles.

    (use-package! dockerfile-mode
      :mode "Dockerfile\\'"
      :config
      (put 'dockerfile-image-name 'safe-local-variable #'stringp)
      )
    

    1.9 Functions

    1.9.1 Org-Export HTML with useful IDs

    This minor mode from here is crucial to having sane reveal-js slides which don’t keep jumping back to the title slide on every export.

    (define-minor-mode unpackaged/org-export-html-with-useful-ids-mode
      "Attempt to export Org as HTML with useful link IDs.
    Instead of random IDs like \"#orga1b2c3\", use heading titles,
    made unique when necessary."
      :global t
      (if unpackaged/org-export-html-with-useful-ids-mode
          (advice-add #'org-export-get-reference :override #'unpackaged/org-export-get-reference)
        (advice-remove #'org-export-get-reference #'unpackaged/org-export-get-reference)))
    
    (defun unpackaged/org-export-get-reference (datum info)
      "Like `org-export-get-reference', except uses heading titles instead of random numbers."
      (let ((cache (plist-get info :internal-references)))
        (or (car (rassq datum cache))
            (let* ((crossrefs (plist-get info :crossrefs))
                   (cells (org-export-search-cells datum))
                   ;; Preserve any pre-existing association between
                   ;; a search cell and a reference, i.e., when some
                   ;; previously published document referenced a location
                   ;; within current file (see
                   ;; `org-publish-resolve-external-link').
                   ;;
                   ;; However, there is no guarantee that search cells are
                   ;; unique, e.g., there might be duplicate custom ID or
                   ;; two headings with the same title in the file.
                   ;;
                   ;; As a consequence, before re-using any reference to
                   ;; an element or object, we check that it doesn't refer
                   ;; to a previous element or object.
                   (new (or (cl-some
                             (lambda (cell)
                               (let ((stored (cdr (assoc cell crossrefs))))
                                 (when stored
                                   (let ((old (org-export-format-reference stored)))
                                     (and (not (assoc old cache)) stored)))))
                             cells)
                            (when (org-element-property :raw-value datum)
                              ;; Heading with a title
                              (unpackaged/org-export-new-title-reference datum cache))
                            ;; NOTE: This probably breaks some Org Export
                            ;; feature, but if it does what I need, fine.
                            (org-export-format-reference
                             (org-export-new-reference cache))))
                   (reference-string new))
              ;; Cache contains both data already associated to
              ;; a reference and in-use internal references, so as to make
              ;; unique references.
              (dolist (cell cells) (push (cons cell new) cache))
              ;; Retain a direct association between reference string and
              ;; DATUM since (1) not every object or element can be given
              ;; a search cell (2) it permits quick lookup.
              (push (cons reference-string datum) cache)
              (plist-put info :internal-references cache)
              reference-string))))
    
    (defun unpackaged/org-export-new-title-reference (datum cache)
      "Return new reference for DATUM that is unique in CACHE."
      (cl-macrolet ((inc-suffixf (place)
                                 `(progn
                                    (string-match (rx bos
                                                      (minimal-match (group (1+ anything)))
                                                      (optional "--" (group (1+ digit)))
                                                      eos)
                                                  ,place)
                                    ;; HACK: `s1' instead of a gensym.
                                    (-let* (((s1 suffix) (list (match-string 1 ,place)
                                                               (match-string 2 ,place)))
                                            (suffix (if suffix
                                                        (string-to-number suffix)
                                                      0)))
                                      (setf ,place (format "%s--%s" s1 (cl-incf suffix)))))))
        (let* ((title (org-element-property :raw-value datum))
               (ref (url-hexify-string (substring-no-properties title)))
               (parent (org-element-property :parent datum)))
          (while (--any (equal ref (car it))
                        cache)
            ;; Title not unique: make it so.
            (if parent
                ;; Append ancestor title.
                (setf title (concat (org-element-property :raw-value parent)
                                    "--" title)
                      ref (url-hexify-string (substring-no-properties title))
                      parent (org-element-property :parent parent))
              ;; No more ancestors: add and increment a number.
              (inc-suffixf ref)))
          ref)))
    
    

    1.9.2 Org-mode export pdf when saved

    This one is to generate pdfs whenever a buffer is saved. Mainly taken from this stack exchange question.

    ; Pdf
    (defun haozeke/org-save-and-export-pdf ()
      (if (eq major-mode 'org-mode)
        (org-latex-export-to-pdf :async t)))
    

    1.9.3 Org-mode export koma-letter

    Since the koma-letter backend is separate, this needs a function as well.

    (defun haozeke/org-save-and-export-koma-letter-pdf ()
      (if (eq major-mode 'org-mode)
        (org-koma-letter-export-to-pdf)))
    

    1.9.4 Org-mode export TeX

    Similar to the one above, but tex generation is much faster and this way I can keep editing my files without waiting for it to finish creating the pdf.

    ; LaTeX
    (defun haozeke/org-save-and-export-latex ()
      (if (eq major-mode 'org-mode)
        (org-latex-export-to-latex)))
    (defun haozeke/org-save-and-export-beamer ()
      (if (eq major-mode 'org-mode)
        (org-beamer-export-to-latex)))
    

    1.9.5 TODO Caveats

    • Minted needs to be setup.
    • There are really a lot of optimizations to the above.

    1.9.6 Helper function

    Figure out if I can replicate this some other way. Taken from sam217pa’s github repo.

    ;; this function is used to append multiple elements to the list 'ox-latex
    (defun append-to-list (list-var elements)
      "Append ELEMENTS to the end of LIST-VAR. The return value is the new value of LIST-VAR."
      (unless (consp elements) (error "ELEMENTS must be a list"))
      (let ((list (symbol-value list-var)))
        (if list
            (setcdr (last list) elements)
          (set list-var elements)))
    (symbol-value list-var))
    

    1.9.7 Async Command without Buffers

    This supresses the output window. Useful for when I do async exports. From this question.

    (defun async-shell-command-no-window
        (command)
      (interactive)
      (let
          ((display-buffer-alist
            (list
             (cons
              "\\*Async Shell Command\\*.*"
              (cons #'display-buffer-no-window nil)))))
        (async-shell-command
         command)))
    

    1.9.8 Smarter Clang Formatting

    This is taken from this blog.

    (defun haozeke/clang-format-buffer-conditional ()
    (interactive)
      "Reformat buffer if .clang-format exists in the projectile root."
      (when (f-exists? (expand-file-name ".clang-format" (projectile-project-root)))
        (+format|buffer)))
    

    1.9.9 Org-mode export to Markdown

    This is a convinience function for working with nanoc.

    (defun haozeke/org-pandoc-markdown (dir &optional pargs)
      "A wrapper to generate yaml metadata markdown files. Takes the output
      directory followed by pandoc arguments"
      (if (not (file-exists-p dir)) (make-directory dir))
      (async-shell-command-no-window
       (concat "pandoc -f org -t markdown -s " pargs " " (buffer-name) " -o "
               dir "/" (file-name-sans-extension (buffer-name)) ".md"))
        )
    

    1.9.10 TODO Smartparens Wrapping

    • [ ] Make this conditional and only when +smartparens is active

    This is to define some more wrapping functions I use often (for markdown and org-mode inline code):

    (defun sp-wrap-backtick ()
      "Wrap following sexp in backticks."
      (interactive)
      (sp-wrap-with-pair "`"))
    (defun sp-wrap-tilda ()
      "Wrap following sexp in tildes."
      (interactive)
      (sp-wrap-with-pair "~"))
    

    1.10 Projects

    These are to help setup org-mode workflows.

    ; Make sure it's not set before adding to it
    (unless (boundp 'org-publish-project-alist)
      (setq org-publish-project-alist nil))
    

    1.10.1 dotDoom

    This is used to generate plain HTML for my dotDoom repo. The setup is taken from the worg documentation and this repository. It so turns out that we can host the entire thing from the master branch on GitHub, but only if it is in a docs/ subfolder… Plus org-html-export-to-html does not accept filenames which was a real bummer.

    ; dotDoom stuff
    ; This is a rather harmless useful variable
    (setq dotdoom-root-dir "~/.config/doom/")
    (setq dotdoom-publish-dir  (concat dotdoom-root-dir "docs"))
    

    Now that the variables are set, we can move on to actually setting up the rest of the export, this includes my own analytics and stuff. Infact maybe the analytics would be better handled by offloading the damn thing to Netlify, though their recent changes to the TOS are worrying, so Microsoft owned GitHub seems to be the better option for now.

    1. Org Setup

      It turns out that each part of the site which needs a separate publish function needs to be added to the org-publish-project-alist so we will define each rule.

      (add-to-list 'org-publish-project-alist
            `("dotdoom-org"
               :base-directory ,dotdoom-root-dir
               :publishing-directory ,dotdoom-publish-dir
               :base-extension "org"
               :infojs-opt "view:t toc:t ltoc:t mouse:underline buttons:0 path:https://thomasf.github.io/solarized-css/org-info.min.js"
               :html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"https://thomasf.github.io/solarized-css/solarized-dark.min.css\" />"
               :recursive t
               :publishing-function org-html-publish-to-html
               :auto-index nil ; I make my own from the readme.org
               ;; :html-head-include-default-style nil ; supresses the rest
               ;; :index-filename "README.org"
               ;; :index-title "index"
               ;; :auto-sitemap t                ; Generate sitemap.org automagically...
               ;; :sitemap-filename "index.org"  ; ... call it sitemap.org (it's the default)...
               ;; :sitemap-title "index"         ; ... with title 'sitemap'.
               :link-home "index.html"))
      
    2. Static Content

      We will at the very least need the .txt files to be transferred as is for keybase.

      (add-to-list 'org-publish-project-alist
            `("dotdoom-static"
               :base-directory ,dotdoom-root-dir
               :publishing-directory ,dotdoom-publish-dir
               :base-extension "txt"
               :recursive nil
               :publishing-function org-publish-attachment))
      
    3. Inherit and Combine

      Now we compose the previous projects, keeping in mind the fact that they are in the LTR order of preference.

      (add-to-list 'org-publish-project-alist
            `("dotdoom"
              :components ("dotdoom-org" "dotdoom-static")
              ))
      

    1.10.2 Firestarter

    Since I switched to using Nix for R I needed a way to reload my system-wide config.nix firestarter is the best of the auto-exec in my opinion, and would probably replace a lot of my other hooks eventually as well.

    (use-package! firestarter
      :ensure t
      :init
      (firestarter-mode)
      :config
      (setq firestarter-default-type t)
    )
    

    1.11 Hooks

    1.11.1 TODO Caveats

    Move all the hooks to this section if possible.

    1.11.2 Before Save Hooks

    1. CC Mode

      Currently I only need to use the clang formatting hook here.

      ; The interactive thing is REQUIRED
      (defun haozeke/clang-format-buffer-smart-on-save ()
      (interactive)
        "Add auto-save hook for clang-format-buffer-smart."
        (add-hook 'before-save-hook 'haozeke/clang-format-buffer-conditional nil t))
      ; This is a doom-emacs convinience macro
      (add-hook! (c-mode c++-mode cc-mode) #'haozeke/clang-format-buffer-smart-on-save)
      

    1.11.3 Disable Auto RDM

    This conflicts with the ArchLinux systemctl --user start rdm thing.

    ; Do not automatically try to run rdm
    (remove-hook 'c-mode-common-hook #'+cc|init-rtags)
    

    1.12 Troubleshooting

    These are strictly temporary hacks to resolve problems until they are fixed upstream.

    (after! doom-themes
      (remove-hook 'doom-load-theme-hook #'doom-themes-treemacs-config))
    

    2 R Helpers

    This section is essentially to configure working with R above and beyond the default ess configuration supplied by doom-emacs.

    2.0.1 R Markdown

    Basically only poly-markdown for rmd files.

    ;; Load
    (use-package! poly-R
    :config
    (map! (:localleader
          :map polymode-mode-map
          :desc "Export"   "e" 'polymode-export
          :desc "Errors" "$" 'polymode-show-process-buffer
          :desc "Weave" "w" 'polymode-weave
          ;; (:prefix ("n" . "Navigation")
          ;;   :desc "Next" "n" . 'polymode-next-chunk
          ;;   :desc "Previous" "N" . 'polymode-previous-chunk)
          ;; (:prefix ("c" . "Chunks")
          ;;   :desc "Narrow" "n" . 'polymode-toggle-chunk-narrowing
          ;;   :desc "Kill" "k" . 'polymode-kill-chunk
          ;;   :desc "Mark-Extend" "m" . 'polymode-mark-or-extend-chunk)
          ))
      )
    

    2.0.2 DONE Rmd to Rorg

    The idea is to replace md completely with org. Since polymode is pretty finicky for most of my org files, I will ensure it is only enabled for Rorg files.

    (use-package! poly-org
    :config
    (add-to-list 'auto-mode-alist '("\\.org" . org-mode))
    (add-to-list 'auto-mode-alist '("\\.Rorg" . poly-org-mode))
    (map! (:localleader
          :map polymode-mode-map
          :desc "Export"   "E" 'polymode-export
          :desc "Errors" "$" 'polymode-show-process-buffer
          :desc "Weave" "w" 'polymode-weave
          ))
      )
    

    3 Org LaTeX

    Portions of this section are to be mirrored in the async init file since. That’s also why here it’s better to not use very doom specific code. I think it would be a lot better to just work these into a single literate block instead of maintaining two different sets of syntax.

    3.0.1 Async Config

    This is essentially the same, only some extra packages are added.

    ;;; autoExport.el --- For async exports -*- lexical-binding: t; -*-
    
    (require 'package)
    (setq package-enable-at-startup nil)
    (package-initialize)
    
    (require 'org)
    (require 'ox)
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/org-mode/contrib/lisp/")
    (require 'ox-koma-letter)
    (require 'ox-beamer)
    
    ;; Org-Ref Stuff
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/org-ref/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/dash.el/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/helm.el/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/helm/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/build/helm/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/helm-bibtex/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/ivy/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/hydra/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/key-chord/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/s.el/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/f.el/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/pdf-tools/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/emacs-htmlize/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/parsebib/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/build/async/")
    (add-to-list 'load-path "~/.emacs.d/.local/straight/repos/biblio.el/")
    (require 'org-ref)
    
    ;; Path addtion
    (setenv "PATH" (concat (getenv "PATH") ":/usr/local/texlive/2020/bin/x86_64-linux"))
    (setq exec-path (append exec-path '("/usr/local/texlive/2020/bin/x86_64-linux")))
    
    ;; Functions
    ;; this function is used to append multiple elements to the list 'ox-latex
    (defun append-to-list (list-var elements)
      "Append ELEMENTS to the end of LIST-VAR. The return value is the new value of LIST-VAR."
      (unless (consp elements) (error "ELEMENTS must be a list"))
      (let ((list (symbol-value list-var)))
        (if list
            (setcdr (last list) elements)
          (set list-var elements)))
    (symbol-value list-var))
    ;; Feature parity with doom
    (eval-after-load 'ox '(require 'ox-koma-letter))
    (with-eval-after-load 'ox-latex
      ;; Compiler
      (setq org-latex-pdf-process (list "latexmk -shell-escape -f -pdfxe %f"))
      ;; Configuration
      (add-to-list 'org-latex-packages-alist '("" "minted" "xcolor"))
      (setq org-latex-listings 'minted)
      (setq org-latex-minted-options
        '(("bgcolor" "white") ("breaklines" "true") ("linenos" "true") ("style" "tango")))
      (append-to-list
       'org-latex-classes
       '(("tufte-book"
          "\\documentclass[a4paper, sfsidenotes, openany, justified]{tufte-book}"
          ("\\part{%s}" . "\\part*{%s}")
          ("\\chapter{%s}" . "\\chapter*{%s}")
          ("\\section{%s}" . "\\section*{%s}")
          ("utf8" . "utf8x")
          ("\\subsection{%s}" . "\\subsection*{%s}"))))
      (add-to-list 'org-latex-classes
                   '("koma-article" "\\documentclass{scrartcl}"
                     ("\\section{%s}" . "\\section*{%s}")
                     ("\\subsection{%s}" . "\\subsection*{%s}")
                     ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                     ("\\paragraph{%s}" . "\\paragraph*{%s}")
                     ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
      (add-to-list 'org-latex-classes
                   '("koma-report" "\\documentclass{scrreprt}"))
    )
    (provide 'autoExport)
    ;;; autoExport.el ends here
    

    3.0.2 Path Additions

    Due to my recent switch to using tlmgr, I had to make some modifications to the emacs path.

    (setenv "PATH" (concat (getenv "PATH") ":/usr/local/texlive/2020/bin/x86_64-linux"))
    (setq exec-path (append exec-path '("/usr/local/texlive/2020/bin/x86_64-linux")))
    

    3.0.3 Config

    This is the part which is exported normally.

    (eval-after-load 'ox '(require 'ox-koma-letter))
    (with-eval-after-load 'ox-latex
      ;; Compiler
      (setq org-latex-pdf-process (list "latexmk -shell-escape -f -pdfxe %f"))
      ;; Configuration
      (add-to-list 'org-latex-packages-alist '("" "minted" "xcolor"))
      (setq org-latex-listings 'minted)
      (setq org-latex-minted-options
        '(("bgcolor" "white") ("breaklines" "true") ("linenos" "true") ("style" "tango")))
      (append-to-list
       'org-latex-classes
       '(("tufte-book"
          "\\documentclass[a4paper, sfsidenotes, openany, justified]{tufte-book}"
          ("\\part{%s}" . "\\part*{%s}")
          ("\\chapter{%s}" . "\\chapter*{%s}")
          ("\\section{%s}" . "\\section*{%s}")
          ("utf8" . "utf8x")
          ("\\subsection{%s}" . "\\subsection*{%s}"))))
      (add-to-list 'org-latex-classes
                   '("koma-article" "\\documentclass{scrartcl}"
                     ("\\section{%s}" . "\\section*{%s}")
                     ("\\subsection{%s}" . "\\subsection*{%s}")
                     ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                     ("\\paragraph{%s}" . "\\paragraph*{%s}")
                     ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
      (add-to-list 'org-latex-classes
                   '("koma-report" "\\documentclass{scrreprt}"))
    )
    

    3.1 Shared Preferences

    3.1.1 Compiler

    It makes sense to use latexmk anyway. This way I can set sane defaults.

    ;; Compiler
    (setq org-latex-pdf-process (list "latexmk -shell-escape -f -pdfxe %f"))
    

    3.1.2 Packages

    Some of these are damn near universal given my set up, so they are declared here.

    ;; Configuration
    (add-to-list 'org-latex-packages-alist '("" "minted" "xcolor"))
    (setq org-latex-listings 'minted)
    (setq org-latex-minted-options
      '(("bgcolor" "white") ("breaklines" "true") ("linenos" "true") ("style" "tango")))
    

    3.2 Export Templates

    Most of the configuration is to be moved into the file snippets. However, class definitions and other packages are still to be loaded here. Though here in the config.el I could use doom semantics and might as well to keep things DRY, it appears that the async file needs to keep things in the old syntax.

    3.2.1 KOMA Article

    Inspired by the post here.

    (add-to-list 'org-latex-classes
                 '("koma-article" "\\documentclass{scrartcl}"
                   ("\\section{%s}" . "\\section*{%s}")
                   ("\\subsection{%s}" . "\\subsection*{%s}")
                   ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                   ("\\paragraph{%s}" . "\\paragraph*{%s}")
                   ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
    

    3.2.2 KOMA Report

    Inspired by the post here.

    (add-to-list 'org-latex-classes
                 '("koma-report" "\\documentclass{scrreprt}"))
    

    3.2.3 Tufte Book

    This is really ad-hoc right now and from this reddit thread.

    (append-to-list
     'org-latex-classes
     '(("tufte-book"
        "\\documentclass[a4paper, sfsidenotes, openany, justified]{tufte-book}"
        ("\\part{%s}" . "\\part*{%s}")
        ("\\chapter{%s}" . "\\chapter*{%s}")
        ("\\section{%s}" . "\\section*{%s}")
        ("utf8" . "utf8x")
        ("\\subsection{%s}" . "\\subsection*{%s}"))))
    

    3.3 LaTeX Preview for Org mode

    Basically I need to see math and physics. Originally borrowed from this stackexchange question.

    1. Process
      '(org-preview-latex-process-alist
             (quote
             ((dvipng :programs
               ("lualatex" "dvipng")
               :description "dvi > png" :message "you need to install the programs: latex and dvipng." :image-input-type "dvi" :image-output-type "png" :image-size-adjust
               (1.0 . 1.0)
               :latex-compiler
               ("lualatex -output-format dvi -interaction nonstopmode -output-directory %o %f")
               :image-converter
               ("dvipng -fg %F -bg %B -D %D -T tight -o %O %f"))
       (dvisvgm :programs
                ("latex" "dvisvgm")
                :description "dvi > svg" :message "you need to install the programs: latex and dvisvgm." :use-xcolor t :image-input-type "xdv" :image-output-type "svg" :image-size-adjust
                (1.7 . 1.5)
                :latex-compiler
                ("xelatex -no-pdf -interaction nonstopmode -output-directory %o %f")
                :image-converter
                ("dvisvgm %f -n -b min -c %S -o %O"))
       (imagemagick :programs
                    ("latex" "convert")
                    :description "pdf > png" :message "you need to install the programs: latex and imagemagick." :use-xcolor t :image-input-type "pdf" :image-output-type "png" :image-size-adjust
                    (1.0 . 1.0)
                    :latex-compiler
                    ("xelatex -no-pdf -interaction nonstopmode -output-directory %o %f")
                    :image-converter
                    ("convert -density %D -trim -antialias %f -quality 100 %O")))))
      
    2. Packages

      These are required to view math properly.

    3.4 Math support

    This is from this reddit thread.

    (use-package! cdlatex
        :after (:any org-mode LaTeX-mode)
        :hook
        ((LaTeX-mode . turn-on-cdlatex)
         (org-mode . turn-on-org-cdlatex)))
    
    (use-package! company-math
        :after (:any org-mode TeX-mode)
        :config
        (set-company-backend! 'org-mode 'company-math-symbols-latex)
        (set-company-backend! 'TeX-mode 'company-math-symbols-latex)
        (set-company-backend! 'org-mode 'company-latex-commands)
        (set-company-backend! 'TeX-mode 'company-latex-commands)
        (setq company-tooltip-align-annotations t)
        (setq company-math-allow-latex-symbols-in-faces t))
    

    3.5 Babel Tabs

    Evidently there was some sort of re-indentation going on during the export process which was breaking a lot of python, this should fix that: More generally, it is best set with # -*- org-src-preserve-indentation: t; org-edit-src-content: 0; -*- on a per-file basis, however given that the indentation is handled by the programming major mode, this is a good global setting as well.

    (setq org-src-preserve-indentation t
          org-edit-src-content-indentation 0)
    

    3.6 Pandoc Babel

    As fully described in this post, I felt the need to export some common pandoc formats with babel.

    3.6.1 Restructured Text

    (defun org-babel-execute:rst (body params)
      "Execute a block of rst code with org-babel.
    This function is called by `org-babel-execute-src-block'."
      (let* ((result-params (split-string (or (cdr (assoc :results params)) "")))
           (in-file (org-babel-temp-file "rst-"))
           (cmdline (cdr (assoc :cmdline params)))
           (to (cdr (assoc :to params)))
           (template (cdr (assoc :template params)))
           (cmd (concat "pandoc"
                        " -t  org"
                        " -i " (org-babel-process-file-name in-file)
                        " -f rst "
                        " " cmdline)))
        (with-temp-file in-file (insert body))
        (message cmd)
        (shell-command-to-string cmd))) ;; Send to results
    
    (defun org-babel-prep-session:rst (session params)
      "Return an error because rst does not support sessions."
      (error "rst does not support sessions"))
    

    3.7 Flycheck Additions

    These are basically meant to aid in development. The relevant linters are also added here.

    3.7.1 MELPA Helpers

    This includes settings for both flycheck and the packages it needs.

    (use-package! flycheck-package
      :after flycheck
      :config (flycheck-package-setup))
    

    4 Notes

    4.1 noteYoda

    This is largely inspired from this reddit comment. For clarity and extensibility this will be broken down into a per-package configuration. The heart of this is an rclone mega folder to manage all these transparently. With this setup links to the files are stored in zotero and managed by zotfile. Now described in this post.

    4.1.1 Org-Ref

    This seems like an ubiquitous choice for working with org files and references, though quite a bit of the config here relates to helm-bibtex. Commented sections are set in my private config.

    (use-package! org-ref
        ;; :init
        ; code to run before loading org-ref
        :config
        (setq
             org-ref-completion-library 'org-ref-ivy-cite
             org-ref-get-pdf-filename-function 'org-ref-get-pdf-filename-helm-bibtex
             org-ref-default-bibliography (list "/home/haozeke/GDrive/zotLib.bib")
             org-ref-bibliography-notes "/home/haozeke/Git/Gitlab/Mine/Notes/bibnotes.org"
             org-ref-note-title-format "* TODO %y - %t\n :PROPERTIES:\n  :Custom_ID: %k\n  :NOTER_DOCUMENT: %F\n :ROAM_KEY: cite:%k\n  :AUTHOR: %9a\n  :JOURNAL: %j\n  :YEAR: %y\n  :VOLUME: %v\n  :PAGES: %p\n  :DOI: %D\n  :URL: %U\n :END:\n\n"
             org-ref-notes-directory "/home/haozeke/Git/Gitlab/Mine/Notes/"
             org-ref-notes-function 'orb-edit-notes
        ))
    

    Apparently, org-ref is also able to fetch pdf files when DOI or URL links are dragged onto the .bib file. However, since zotero will handle the metadata, this remains to be considered.

    Ivy is used exclusively throughout doom, makes sense to use it here too, but I recently switched to helm. Turns out helm is probably faster for larger collections since it can be asynchronous. Basically, this is because using the minibuffer, as ivy does is a blocking action while the helm buffer may be opened asynchronously. Name aside, helm-bibtex also works for ivy. Basically meant to interface with bibliographies in general. However, since I’m using org-ref, I won’t be configuring or loading that anymore.

    4.1.2 Helm Bibtex

    For some reason, org-ref-notes isn’t working very nicely, so the setup above prioritizes the helm-bibtex note-taking setup.

    (after! org-ref
      (setq
       bibtex-completion-notes-path "/home/haozeke/Git/Gitlab/Mine/Notes/"
       bibtex-completion-bibliography "/home/haozeke/GDrive/zotLib.bib"
       bibtex-completion-pdf-field "file"
       bibtex-completion-notes-template-multiple-files
       (concat
        "#+TITLE: ${title}\n"
        "#+ROAM_KEY: cite:${=key=}\n"
        "#+ROAM_TAGS: ${keywords}\n"
        "* TODO Notes\n"
        ":PROPERTIES:\n"
        ":Custom_ID: ${=key=}\n"
        ":NOTER_DOCUMENT: %(orb-process-file-field \"${=key=}\")\n"
        ":AUTHOR: ${author-abbrev}\n"
        ":JOURNAL: ${journaltitle}\n"
        ":DATE: ${date}\n"
        ":YEAR: ${year}\n"
        ":DOI: ${doi}\n"
        ":URL: ${url}\n"
        ":END:\n\n"
        )
       )
    )
    

    4.1.3 Org-Roam

    Will also setup the org-roam-bibtex thing here. As foretold in the last line, there are more settings for ORB. The template is modified from here.

     (use-package! org-roam-bibtex
      :after (org-roam)
      :hook (org-roam-mode . org-roam-bibtex-mode)
      :config
      (setq org-roam-bibtex-preformat-keywords
       '("=key=" "title" "url" "file" "author-or-editor" "keywords"))
      (setq orb-templates
            '(("r" "ref" plain (function org-roam-capture--get-point)
               ""
               :file-name "${slug}"
               :head "#+TITLE: ${=key=}: ${title}\n#+ROAM_KEY: ${ref}\n#+ROAM_TAGS: 
    
    - keywords :: ${keywords}
    
    \n* ${title}\n  :PROPERTIES:\n  :Custom_ID: ${=key=}\n  :URL: ${url}\n  :AUTHOR: ${author-or-editor}\n  :NOTER_DOCUMENT: %(orb-process-file-field \"${=key=}\")\n  :NOTER_PAGE: \n  :END:\n\n"
    
               :unnarrowed t))))
    

    4.1.4 Org-Noter

    I decided to use org-noter over the more commonly described interleave because it has better support for working with multiple documents linked to one file.

    (use-package! org-noter
      :after (:any org pdf-view)
      :config
      (setq
       ;; The WM can handle splits
       org-noter-notes-window-location 'other-frame
       ;; Please stop opening frames
       org-noter-always-create-frame nil
       ;; I want to see the whole file
       org-noter-hide-other nil
       ;; Everything is relative to the rclone mega
       org-noter-notes-search-path (list org_notes)
       )
      )
    

    I have a rather involved setup in mind, so I have spun this section off from the rest. The basic idea is to use deft for short-to-long lookup notes, and org-capture templates with org-protocol for the rest. I am also considering notdeft since it might work better for what I want to achieve. Though it isn’t really part of a note taking workflow, I also intend to use michel2 to sync my tasks…

    4.2 Org Capture

    I am not really sure how to use these correctly, but I have the bare minimum required for the Firefox browser extension (setup from here), and a random article thing.

    4.2.1 Buffer Size

    (set-popup-rule! "^CAPTURE-.*\\.org$" :size 0.5 :quit nil :select t :autosave t)
    

    4.2.2 Functions

    These are needed for org-capture alone for now.

    ;; Fix some link issues
    (defun transform-square-brackets-to-round-ones(string-to-transform)
      "Transforms [ into ( and ] into ), other chars left unchanged."
      (concat
       (mapcar #'(lambda (c) (if (equal c ?\[) ?\( (if (equal c ?\]) ?\) c))) string-to-transform))
      )
    

    4.2.3 Templates

    This might get complicated but I am only trying to get the bare minimum for org-protocol right now. Will look into orca and doct.

    ;; Actually start using templates
    (after! org-capture
      ;; Firefox
      (add-to-list 'org-capture-templates
                   '("P" "Protocol" entry
                     (file+headline +org-capture-notes-file "Inbox")
                     "* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?"
                     :prepend t
                     :kill-buffer t))
      (add-to-list 'org-capture-templates
                   '("L" "Protocol Link" entry
                     (file+headline +org-capture-notes-file "Inbox")
                     "* %? [[%:link][%(transform-square-brackets-to-round-ones \"%:description\")]]\n"
                     :prepend t
                     :kill-buffer t))
      ;; Misc
      (add-to-list 'org-capture-templates
             '("a"               ; key
               "Article"         ; name
               entry             ; type
               (file+headline +org-capture-notes-file "Article")  ; target
               "* %^{Title} %(org-set-tags)  :article: \n:PROPERTIES:\n:Created: %U\n:Linked: %a\n:END:\n%i\nBrief description:\n%?"  ; template
               :prepend t        ; properties
               :empty-lines 1    ; properties
               :created t        ; properties
               ))
    )
    
    1. HTML Parsing

      The standard capture method isn’t too great, but this makes it better.

      (use-package! org-protocol-capture-html
        :after org-protocol
        :config
        (add-to-list 'org-capture-templates
                     '("w"
                       "Web site"
                       entry
                       (file+headline +org-capture-notes-file "Website")  ; target
                       "* %a :website:\n\n%U %?\n\n%:initial")
                     )
        )
      
      (setq org-roam-ref-capture-templates
              '(("r" "ref" plain (function org-roam--capture-get-point)
                 "%?"
                 :file-name "websites/${slug}"
                 :head "#+SETUPFILE:./hugo_setup.org
      #+ROAM_KEY: ${ref}
      #+HUGO_SLUG: ${slug}
      #+TITLE: ${title}
      

    Date: 2020:04:09

    Author: Rohit Goswami (HaoZeke) <rohit.goswami@aol.com>

    Created: 2020-07-05 Sun 16:31