#+TITLE: Literate Doom Emacs config
#+AUTHOR: Amolith

-----

*Note:* you do not need to run ~doom sync~ after modifying this file!

-----

Here are some additional functions/macros that could help configure Doom:

- ~load!~ for loading external ~*.el~ files relative to this one
- ~use-package!~ for configuring packages
- ~after!~ for running code after a package has loaded
- ~add-load-path!~ for adding directories to the ~load-path~, relative to
  this file. Emacs searches the ~load-path~ when loading packages with
  ~require~ or ~use-package~.
- ~map!~ for binding new keys

To get information about any of these functions/macros, move the cursor over the
highlighted symbol at press ~K~ (non-evil users must press ~C-c c k~). This will
open documentation for it, including demos of how they're used. ~gd~ (or ~C-c c d~)
will also jump to their definition for viewing how they're implemented.

First off, enable [[https://www.emacswiki.org/emacs/DynamicBindingVsLexicalBinding][lexical binding]]:
#+BEGIN_SRC emacs-lisp
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
#+END_SRC

* Identity configuration
Some functionality uses this to identify the user, e.g. GPG configuration, email
clients, file templates and snippets.
#+BEGIN_SRC emacs-lisp
(setq user-full-name "Amolith"
      user-mail-address "amolith@secluded.site")
#+END_SRC

* UI settings
Doom exposes five (optional) variables for controlling fonts in Doom. Here
are the three important ones:

+ ~doom-font~
+ ~doom-variable-pitch-font~
+ ~doom-big-font~ — used for ~doom-big-font-mode~; use this for
  presentations or streaming.

They all accept either a font-spec, font string (~"Input Mono-12"~), or ~xlfd~
font string. Generally, only these two are needed:
#+BEGIN_SRC emacs-lisp
(setq doom-font (font-spec :family "Triplicate T4c" :size 16)
      doom-variable-pitch-font (font-spec :family "Valkyrie T4" :size 16))
#+END_SRC

There are two ways to load a theme. Both assume the theme is installed and
available. Either set ~doom-theme~ or manually load a theme with the ~load-theme~
function.
#+BEGIN_SRC emacs-lisp
(setq doom-theme 'doom-dracula)
#+END_SRC

This determines the style of line numbers in effect. Disable line numbers by
setting it this to ~nil~. For relative line numbers, set this to ~relative~.
#+BEGIN_SRC emacs-lisp
(setq display-line-numbers-type t)
#+END_SRC

Keep point in about the centre of the screen
#+BEGIN_SRC emacs-lisp
(use-package smooth-scrolling
  :ensure t
  :config
  (smooth-scrolling-mode 1)
  (setq smooth-scroll-margin 20))
#+END_SRC

Use fancy lambdas
#+BEGIN_SRC emacs-lisp
(global-prettify-symbols-mode t)
#+END_SRC

When splitting windows, I want to switch to the new one immediately. By default,
you have to press a few bindings. This makes that automatic.
#+BEGIN_SRC emacs-lisp
(defun amo/split-window-below-and-switch ()
  "Split the window horizontally, then switch to the new pane."
  (interactive)
  (split-window-below)
  (balance-windows)
  (other-window 1))
(defun amo/split-window-right-and-switch ()
  "Split the window vertically, then switch to the new pane."
  (interactive)
  (split-window-right)
  (balance-windows)
  (other-window 1))
(global-set-key (kbd "C-x 2") 'amo/split-window-below-and-switch)
(global-set-key (kbd "C-x 3") 'amo/split-window-right-and-switch)
#+END_SRC

* Org Mode settings
If you use ~org~ and don't want your org files in the default location below,
change ~org-directory~. It must be set before org loads!
#+BEGIN_SRC emacs-lisp
(setq org-directory "~/Org/")
#+END_SRC

Prettify bullets
#+BEGIN_SRC emacs-lisp
(use-package org-bullets
  :init
  (add-hook 'org-mode-hook 'org-bullets-mode))
#+END_SRC

Replace ellipsis with downward-pointing arrow
#+BEGIN_SRC emacs-lisp
(setq org-ellipsis " ⤵")
#+END_SRC

Format Org text and hide markers
#+BEGIN_SRC emacs-lisp
(setq org-hide-emphasis-markers t)
#+END_SRC

Prevent Emacs from indenting Org headers
#+BEGIN_SRC emacs-lisp
(setq org-adapt-indentation nil)
#+END_SRC

Allow export to Markdown and Beamer (for presentations).
#+BEGIN_SRC emacs-lisp
(require 'ox-md)
(require 'ox-beamer)
#+END_SRC

Don't ask before evaluating code blocks
#+BEGIN_SRC emacs-lisp
(setq org-confirm-babel-evaluate nil)
#+END_SRC

Use =htmlize= to ensure that exported code blocks use syntax highlighting.
#+BEGIN_SRC emacs-lisp
(use-package htmlize)
#+END_SRC

Translate regular old straight quotes to typographically-correct curly quotes
when exporting.
#+BEGIN_SRC emacs-lisp
(setq org-export-with-smart-quotes t)
#+END_SRC

Add ~ox-hugo~ for exporting ~blog.org~ files to Hugo-compatible markdown
#+BEGIN_SRC emacs-lisp
(use-package ox-hugo
  :ensure t
  :after ox)
#+END_SRC

* Other environments

Use ~mail-mode~ for syntax highlighting and bindings in neomutt compositions
#+BEGIN_SRC emacs-lisp
(add-to-list 'auto-mode-alist '("/tmp/neomutt-*" . mail-mode))
#+END_SRC

Always use =pdflatex= when compiling LaTeX documents. I don't really have any use
for DVIs.
#+BEGIN_SRC emacs-lisp
(setq TeX-PDF-mode t)
#+END_SRC

** Music
I've taken to charting my guitar music out with [[https://www.chordpro.org][ChordPro]]. [[https://github.com/sciurius/chordpro-mode][Chordpro mode]] just
adds a major mode for syntax highlighting and some keybinds.
#+BEGIN_SRC emacs-lisp
(setq auto-mode-alist (cons '("\\.cho$" . chordpro-mode) auto-mode-alist))
(autoload 'chordpro-mode "chordpro-mode")
#+END_SRC

I use [[https://lilypond.org/][LilyPond]] for writing standard sheet music. When you install the package,
it comes with some elisp files that Emacs needs to load and configure.
#+BEGIN_SRC emacs-lisp
(require 'lilypond-mode)
(add-to-list 'auto-mode-alist '("\\.ly$" . LilyPond-mode))
;; Set PDF viewer to zathura, my personal preference
(setq LilyPond-pdf-command "zathura")
#+END_SRC

** General prose settings
Define prose modes for enabling prose-related niceties
#+BEGIN_SRC emacs-lisp
(defvar prose-modes
  '(gfm-mode
    git-commit-mode
    markdown-mode
    message-mode
    mail-mode
    org-mode
    text-mode))
(defvar prose-mode-hooks
  (mapcar (lambda (mode) (intern (format "%s-hook" mode)))
          prose-modes))
#+END_SRC

Enable spell-checking for all prose-related modes
#+BEGIN_SRC emacs-lisp
(use-package flyspell
  :config
  (dolist (hook prose-mode-hooks)
    (add-hook hook 'flyspell-mode)))
#+END_SRC

Wrap prose paragraphs automatically
#+BEGIN_SRC emacs-lisp
(dolist (hook prose-mode-hooks)
  (add-hook hook 'turn-on-auto-fill))
#+END_SRC

- Associate ~.md~ files with GitHub-flavoured Markdown
- Use ~pandoc~ to render the results
- Apply syntax highlighting in code blocks
#+BEGIN_SRC emacs-lisp
(use-package markdown-mode
  :commands gfm-mode
  :mode (("\\.md$" . gfm-mode))
  :config
  (custom-set-faces
   '(markdown-pre-face ((t nil))))
  (setq markdown-command "pandoc --standalone --mathjax --from=markdown"
        markdown-fontify-code-blocks-natively t))
  #+END_SRC

Add a path both to the ~$PATH~ variable and to Emacs' exec-path
#+BEGIN_SRC emacs-lisp
(defun amo/append-to-path (path)
  (setenv "PATH" (concat (getenv "PATH") ":" path))
  (add-to-list 'exec-path path))
#+END_SRC

Look for various executables
#+BEGIN_SRC emacs-lisp
(amo/append-to-path "/usr/local/bin")
(amo/append-to-path "~/.local/bin")
#+END_SRC

** Python settings
#+BEGIN_SRC emacs-lisp
(add-hook 'python-mode-hook 'auto-virtualenv-set-virtualenv)
#+END_SRC

** Go settings
#+BEGIN_SRC emacs-lisp
(gofmt-before-save)
(setq lsp-go-use-placeholders nil)
(setq lsp-go-link-target "godocs.io")
(setq lsp-go-use-gofumpt t)
;;(setq lsp-go-build-flags ["mage"])
#+END_SRC

** SuperCollider
#+BEGIN_SRC emacs-lisp
(require 'sclang)
(add-hook 'sclang-mode-hook 'sclang-extensions-mode)
#+END_SRC

** Tree-sitter
#+BEGIN_SRC emacs-lisp
(global-tree-sitter-mode)
(add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode)
#+END_SRC

** Editor metrics
[[https://github.com/wakatime/wakatime-mode][wakatime-mode]] connected to self-hosted [[https://wakapi.dev/][Wakapi]] instance to get interesting stats
about the time I spend in an editor

#+BEGIN_SRC emacs-lisp
(global-wakatime-mode)
(setq wakatime-cli-path "/usr/bin/wakatime")
#+END_SRC

* Custom bindings
Following established Doom conventions, bind ~SPC g p~ to
~magit-push-current-to-upstream~

#+BEGIN_SRC emacs-lisp
(map! :leader :desc "Push upstream" "g p" #'magit-push-current-to-upstream)
#+END_SRC
