aboutsummaryrefslogtreecommitdiffstats
path: root/doom/.config/doom/config.org
diff options
context:
space:
mode:
Diffstat (limited to 'doom/.config/doom/config.org')
-rw-r--r--doom/.config/doom/config.org1409
1 files changed, 1409 insertions, 0 deletions
diff --git a/doom/.config/doom/config.org b/doom/.config/doom/config.org
new file mode 100644
index 0000000..6b9534b
--- /dev/null
+++ b/doom/.config/doom/config.org
@@ -0,0 +1,1409 @@
+#+title: Org configuration
+#+property: header-args:emacs-lisp :tangle config.el
+
+* Top-Level Configuration
+
+#+begin_src emacs-lisp
+(setq doom-font (font-spec :family "Iosevka YMHG Medium" :size 16))
+(when (eq system-type 'darwin)
+ (setq doom-variable-pitch-font (font-spec :family "Alegreya" :size 20))
+ (setq doom-serif-font (font-spec :family "Alegreya" :size 20)))
+#+end_src
+
+#+begin_src emacs-lisp
+(setq org-directory "~/Dropbox/org/")
+
+(setq display-line-numbers-type nil)
+;; Remove the ring for emacs
+(setq ring-bell-function 'ignore)
+;; Automatically refresh files
+(global-auto-revert-mode 1)
+(setq auto-revert-verbose nil)
+
+;; Set sentence to end with double space
+(setq sentence-end-double-space t)
+;; Remove automatic `auto-fill-mode', and replace it by `visual-line-mode', which is a personal
+;; preference.
+(setq-default fill-column 100)
+;;(remove-hook 'text-mode-hook #'auto-fill-mode)
+(add-hook 'text-mode-hook #'auto-fill-mode)
+;;(add-hook 'text-mode-hook #'+word-wrap-mode)
+;;(add-hook 'text-mode-hook #'visual-fill-column-mode)
+;;;; Removes performance problems with opening coq files.
+(add-to-list 'doom-detect-indentation-excluded-modes 'coq-mode)
+
+;; Projectile compilation buffer not there anymore for some reason
+(setq compilation-buffer-name-function #'compilation--default-buffer-name)
+
+;; optimisations from https://200ok.ch/posts/2020-09-29_comprehensive_guide_on_handling_long_lines_in_emacs.html
+(setq-default bidi-paragraph-direction 'left-to-right)
+(if (version<= "27.1" emacs-version)
+ (setq bidi-inhibit-bpa t))
+
+(setq abbrev-file-name
+ "~/.config/doom/abbrev-defs")
+(add-hook 'text-mode-hook #'abbrev-mode)
+#+end_src
+
+#+begin_src emacs-lisp
+(use-package ef-themes
+ :defer nil
+ :bind ("<f6>" . ef-themes-select)
+ :config
+ (custom-theme-set-faces! ef-themes-collection
+ '(proof-locked-face :inherit hl-line)
+ '(proof-queue-face :inherit region))
+ (setq ef-themes-height-0 2.0736
+ ef-themes-height-1 1.728
+ ef-themes-height-2 1.44
+ ef-themes-height-3 1.2
+ ef-themes-height-4 1.0
+ ef-themes-height-5 1.0
+ ef-themes-height-6 1.0
+ ef-themes-height-7 1.0
+ ef-themes-height-8 1.0)
+ (setq doom-theme 'ef-autumn))
+
+(use-package modus-themes
+ :defer nil
+ :init
+ ;; Add all your customizations prior to loading the themes
+ (setq modus-themes-region '(bg-only no-extend))
+
+ ;; Load the theme files before enabling a theme
+ (modus-themes-load-themes)
+ (custom-theme-set-faces! '(modus-vivendi modus-operandi)
+ '(proof-locked-face :inherit modus-themes-nuanced-cyan)
+ '(proof-queue-face :inherit modus-themes-nuanced-magenta))
+ :config
+ ;; Load the theme of your choice:
+ ;;(modus-themes-load-operandi) ;; OR (modus-themes-load-vivendi)
+ ;;:bind ("<f6>" . modus-themes-toggle))
+ )
+#+end_src
+
+#+begin_src emacs-lisp
+;; Disable stuff
+(global-prettify-symbols-mode -1)
+(electric-indent-mode -1)
+(menu-bar-mode -1)
+
+(add-hook 'text-mode-hook (lambda () (company-mode -1)))
+#+end_src
+
+#+begin_src emacs-lisp
+(use-package! projectile
+ :config
+ (add-to-list 'projectile-globally-ignored-directories ".direnv"))
+#+end_src
+
+** Key Binding Customisations
+
+#+begin_src emacs-lisp
+;; Stop emacs from freezing when trying to minimize it on a tiling WM.
+(global-unset-key (kbd "C-z"))
+(global-set-key (kbd "M-u") #'upcase-dwim)
+(global-set-key (kbd "M-l") #'downcase-dwim)
+(global-set-key (kbd "M-c") #'capitalize-dwim)
+(global-set-key (kbd "C-c z") #'quick-calc)
+(global-set-key (kbd "<f5>") #'revert-buffer)
+(global-set-key (kbd "C-.") (lambda () (interactive) (other-window -1)))
+(global-set-key (kbd "C-,") #'other-window)
+(global-set-key (kbd "C-c l") #'org-store-link)
+(global-set-key (kbd "C-c a") #'org-agenda)
+(global-set-key (kbd "C-c /") #'avy-goto-word-1)
+(global-set-key (kbd "M-=") #'count-words)
+(global-set-key (kbd "C-x m") #'+notmuch/compose)
+(global-set-key (kbd "C-M-x") #'scroll-other-window-down)
+
+;; Set undo-only correctly
+(global-set-key (kbd "C-\\") 'undo-only)
+
+;; Revert C-a and C-e to go to the beginning and end of line, not a fan of the
+;; default smart functions.
+(global-set-key (kbd "C-a") #'beginning-of-line)
+(global-set-key (kbd "C-e") #'end-of-line)
+
+;; Define functions to push and pop from mark.
+(defun push-mark-no-activate ()
+ "Pushes `point' to `mark-ring' and does not activate the region
+ Equivalent to \\[set-mark-command] when \\[transient-mark-mode] is disabled"
+ (interactive)
+ (push-mark (point) t nil)
+ (message "Pushed mark to ring"))
+
+(defun jump-to-mark ()
+ "Jumps to the local mark, respecting the `mark-ring' order.
+ This is the same as using \\[set-mark-command] with the prefix argument."
+ (interactive)
+ (set-mark-command 1))
+
+(global-set-key (kbd "C-`") #'push-mark-no-activate)
+(global-set-key (kbd "M-`") #'jump-to-mark)
+
+;; Swap two window positions.
+(defun y/swap-windows ()
+ "Swaps two windows and leaves the cursor in the original one"
+ (interactive)
+ (ace-swap-window)
+ (aw-flip-window))
+
+(defun ymhg/pass (query)
+ "Return the password as a string from QUERY."
+ (s-trim (shell-command-to-string (concat "pass show " query))))
+
+;; Define a custom key map for other useful commands.
+(define-prefix-command 'y-map)
+(global-set-key (kbd "C-c y") 'y-map)
+
+(define-key y-map (kbd "p") #'password-store-copy)
+(define-key y-map (kbd "q") #'password-store-otp-token-copy)
+(define-key y-map (kbd "i") #'password-store-insert)
+(define-key y-map (kbd "g") #'password-store-generate)
+;(define-key y-map (kbd "r") #'toggle-rot13-mode)
+(define-key y-map (kbd "c") #'calendar)
+(define-key y-map (kbd "C-r") #'ymhg/reload-keywords)
+(define-key y-map (kbd "d") #'y/insert-date)
+(define-key y-map (kbd "C-g") #'org-zettelkasten-goto-id)
+(define-key y-map (kbd "C-t") #'org-babel-detangle)
+(define-key y-map (kbd "C-l") #'org-agenda-open-link)
+(define-key y-map (kbd "C-p") #'org-previous-link)
+(define-key y-map (kbd "C-n") #'org-next-link)
+(define-key y-map (kbd "s")
+ (lambda () (interactive)
+ (let ((org-agenda-files
+ '("~/Dropbox/zk/hls.org"
+ "~/Dropbox/zk/computing.org"
+ "~/Dropbox/zk/verification.org"
+ "~/Dropbox/zk/mathematics.org"
+ "~/Dropbox/zk/hardware.org"))) (org-search-view))))
+
+(setq browse-url-handlers
+ '(("wikipedia\\.org" . eww-browse-url)
+ ("yannherklotz\\.com" . eww-browse-url)
+ ("ymhg\\.org" . eww-browse-url)
+ ("archlinux\\.org" . eww-browse-url)
+ ("sachachua\\.com" . eww-browse-url)
+ ("comonad\\.com" . eww-browse-url)
+ ("drewdevault\\.com" . eww-browse-url)
+ ("wordpress\\.com" . eww-browse-url)
+ ("mathbabe\\.org" . eww-browse-url)
+ ("ethz\\.ch" . eww-browse-url)
+ ("pragmaticemacs\\.com" . eww-browse-url)))
+
+(defun y/insert-date ()
+ "Insert a timestamp according to locale's date and time format."
+ (interactive)
+ (insert (format-time-string "%c" (current-time))))
+#+end_src
+
+** Mac Specific Customisations
+
+#+begin_src emacs-lisp
+;; Mac configuration
+(when (eq system-type 'darwin)
+ (progn (setq mac-right-option-modifier 'none
+ mac-command-modifier 'meta
+ mac-option-modifier nil)
+
+ (defun ymhg/apply-theme (appearance)
+ "Load theme, taking current system APPEARANCE into consideration."
+ (mapc #'disable-theme custom-enabled-themes)
+ (pcase appearance
+ ('light (load-theme 'ef-day t))
+ ('dark (load-theme 'ef-autumn t))))
+
+ (add-hook 'ns-system-appearance-change-functions #'ymhg/apply-theme)))
+#+end_src
+
+** Backup Settings
+
+#+begin_src emacs-lisp
+;; Set backup directories into the tmp folder
+(defvar --backup-directory (concat user-emacs-directory "backups"))
+(if (not (file-exists-p --backup-directory))
+ (make-directory --backup-directory t))
+(setq backup-directory-alist `(("." . ,--backup-directory)))
+(setq make-backup-files t ; backup of a file the first time it is saved.
+ backup-by-copying t ; don't clobber symlinks
+ version-control t ; version numbers for backup files
+ delete-old-versions t ; delete excess backup files silently
+ delete-by-moving-to-trash t
+ kept-old-versions 6 ; oldest versions to keep when a new numbered backup is made (default: 2)
+ kept-new-versions 9 ; newest versions to keep when a new numbered backup is made (default: 2)
+ auto-save-default t ; auto-save every buffer that visits a file
+ auto-save-timeout 20 ; number of seconds idle time before auto-save (default: 30)
+ auto-save-interval 200 ; number of keystrokes between auto-saves (default: 300)
+ )
+#+end_src
+
+** Whitespace Settings
+
+#+begin_src emacs-lisp
+;; Configure activation for whitespace mode
+(use-package! whitespace
+ :bind (("C-x w" . whitespace-mode))
+ :init
+ (setq whitespace-style '(newline newline-mark))
+ (setq whitespace-display-mappings '((newline-mark 10 [?¬ 10]))))
+
+;; Configure expand-region mode.
+(use-package! expand-region
+ :bind ("M-o" . er/expand-region))
+
+;; Delete all whitespace until the first non-whitespace character.
+(use-package! hungry-delete
+ :config
+ (global-hungry-delete-mode)
+ ;; disable hungry delete in minibuffer-mode: https://github.com/abo-abo/swiper/issues/2761
+ (add-to-list 'hungry-delete-except-modes 'minibuffer-mode))
+#+end_src
+
+* Tramp
+
+#+begin_src emacs-lisp
+(setq tramp-auto-save-directory "/tmp")
+(defvar disable-tramp-backups '(all))
+(eval-after-load "tramp"
+ '(progn
+ ;; Modified from https://www.gnu.org/software/emacs/manual/html_node/tramp/Auto_002dsave-and-Backup.html
+ (setq backup-enable-predicate
+ (lambda (name)
+ (and (normal-backup-enable-predicate name)
+ ;; Disable all tramp backups
+ (and disable-tramp-backups
+ (member 'all disable-tramp-backups)
+ (not (file-remote-p name 'method)))
+ (not ;; disable backup for tramp with the listed methods
+ (let ((method (file-remote-p name 'method)))
+ (when (stringp method)
+ (member method disable-tramp-backups)))))))
+
+ (defun tramp-set-auto-save--check (original)
+ (if (funcall backup-enable-predicate (buffer-file-name))
+ (funcall original)
+ (auto-save-mode -1)))
+
+ (advice-add #'tramp-set-auto-save :around #'tramp-set-auto-save--check)
+
+ ;; Use my ~/.ssh/config control master settings according to https://puppet.com/blog/speed-up-ssh-by-reusing-connections
+ (setq tramp-ssh-controlmaster-options "")))
+#+end_src
+
+* Language Settings
+** Flycheck
+
+#+begin_src emacs-lisp
+(use-package! flycheck
+ :config
+ (setq flycheck-idle-change-delay 1)
+ (setq flycheck-display-errors-delay 1.0)
+ (setq-default flycheck-disabled-checkers '(haskell-stack-ghc))
+ (remove-hook 'flycheck-mode-hook #'+syntax-init-popups-h))
+#+end_src
+
+** Magit
+
+#+begin_src emacs-lisp
+;; Set up magit when C-c g is called
+(use-package! magit
+ :bind (("C-x g" . magit-status))
+ :config
+ (add-hook 'magit-status-sections-hook #'magit-insert-modules 90))
+#+end_src
+
+** Org mode
+
+#+begin_src emacs-lisp
+;; Org configuration
+(use-package! org
+ :mode ("\\.org\\'" . org-mode)
+ :init
+ (map! :map org-mode-map
+ "M-n" #'outline-next-visible-heading
+ "M-p" #'outline-previous-visible-heading
+ "C-c ]" #'ebib-insert-citation
+ "C-," nil
+ "C-c C-." #'org-time-stamp-inactive)
+ (setq org-src-window-setup 'current-window
+ org-return-follows-link t
+ org-confirm-babel-evaluate nil
+ org-use-speed-commands t
+ org-hide-emphasis-markers nil
+ org-adapt-indentation nil
+ org-cycle-separator-lines 2
+ org-startup-folded 'content
+ org-structure-template-alist '(("a" . "export ascii")
+ ("c" . "center")
+ ("C" . "comment")
+ ("e" . "example")
+ ("E" . "export")
+ ("h" . "export html")
+ ("l" . "export latex")
+ ("q" . "quote")
+ ("s" . "src")
+ ("v" . "verse")
+ ("el" . "src emacs-lisp")
+ ("d" . "definition")
+ ("t" . "theorem")))
+ ;;(customize-set-variable 'org-blank-before-new-entry
+ ;; '((heading . nil)
+ ;; (plain-list-item . nil)))
+ (require 'oc)
+ (require 'oc-biblatex)
+ (require 'oc-csl)
+ (setq org-cite-export-processors '((latex biblatex)
+ (t csl))
+ org-cite-csl-styles-dir "~/projects/csl-styles"
+ org-cite-global-bibliography '("~/Dropbox/bibliography/references.bib")))
+
+(use-package! citeproc)
+
+(use-package! org-attach
+ :config
+ (setq org-attach-auto-tag "attach"))
+
+(use-package! org-crypt
+ :after org
+ :config
+ (org-crypt-use-before-save-magic)
+ (setq org-tags-exclude-from-inheritance '("crypt"))
+ (setq org-crypt-key "8CEF4104683551E8"))
+
+;;(use-package! org-contacts
+;; :after org
+;; :init
+;; (setq org-contacts-files '("~/Dropbox/org/contacts.org")))
+
+(use-package org-auto-tangle
+ :hook (org-mode . org-auto-tangle-mode))
+
+;; Disable org indent mode and remove C-, from the org-mode-map.
+(after! org
+ (setq org-element-use-cache nil)
+ ;; Set agenda files, refile targets and todo keywords.
+ (setq org-startup-indented nil)
+ (setq org-log-done 'time
+ org-log-into-drawer t)
+ (setq org-agenda-files (mapcar 'expand-file-name
+ (list "~/Dropbox/org/inbox.org"
+ "~/Dropbox/org/main.org"
+ "~/Dropbox/org/tickler.org"
+ "~/Dropbox/org/projects.org"
+ (format-time-string "~/Dropbox/org/%Y-%m.org")
+ "~/Dropbox/bibliography/reading_list.org")))
+ (setq org-agenda-tag-filter '("-backed"))
+ (setq org-refile-targets `(("~/Dropbox/org/main.org" :level . 1)
+ ("~/Dropbox/org/someday.org" :level . 1)
+ ("~/Dropbox/org/projects.org" :maxlevel . 2)
+ (,(format-time-string "~/Dropbox/org/%Y-%m.org") :level . 1)))
+ ;; Set custom agenda commands which can be activated in the agenda viewer.
+ (setq org-agenda-custom-commands
+ '(("w" "At work" tags-todo "@work"
+ ((org-agenda-overriding-header "Work")))
+ ("h" "At home" tags-todo "@home"
+ ((org-agenda-overriding-header "Home")))
+ ("u" "At uni" tags-todo "@uni"
+ ((org-agenda-overriding-header "University")))))
+
+ (setq org-agenda-span 7
+ org-agenda-start-day "."
+ org-agenda-start-on-week 1)
+ (setq org-agenda-include-diary t)
+
+ (setq org-icalendar-include-todo t)
+ (setq org-icalendar-include-bbdb-anniversaries t)
+
+ (setq org-capture-templates
+ `(("t" "Todo" entry (file "inbox.org")
+ "* TODO %?
+:PROPERTIES:
+:ID: %(org-id-uuid)
+:END:
+:LOGBOOK:
+- State \"TODO\" from \"\" %U
+:END:" :empty-lines 1)
+ ("l" "Link Todo" entry (file "inbox.org")
+ "* TODO %?
+:PROPERTIES:
+:ID: %(org-id-uuid)
+:END:
+:LOGBOOK:
+- State \"TODO\" from \"\" %U
+:END:
+
+%a" :empty-lines 1)
+ ("c" "Contacts" entry (file "~/Dropbox/org/contacts.org")
+ "* %(org-contacts-template-name)
+ :PROPERTIES:
+ :EMAIL: %(org-contacts-template-email)
+ :END:" :empty-lines 1))
+
+ org-todo-keywords
+ '((sequence
+ "TODO(t)" ; A task that needs doing & is ready to do
+ "PROJ(p)" ; A project, which usually contains other tasks
+ "STRT(s)" ; A task that is in progress
+ "WAIT(w)" ; Something external is holding up this task
+ "HOLD(h)" ; This task is paused/on hold because of me
+ "DELG(l)" ; This task is delegated
+ "SMDY(m)" ; todo some day
+ "|"
+ "DONE(d!)" ; Task successfully completed
+ "KILL(k)") ; Task was cancelled, aborted or is no longer applicable
+ (sequence
+ "[ ](T)" ; A task that needs doing
+ "[-](S)" ; Task is in progress
+ "[?](W)" ; Task is being held up or paused
+ "|"
+ "[X](D)"))
+ org-todo-keyword-faces '(("[-]" . +org-todo-active)
+ ("STRT" . +org-todo-active)
+ ("[?]" . +org-todo-onhold)
+ ("WAIT" . +org-todo-onhold)
+ ("HOLD" . +org-todo-onhold)
+ ("DELG" . +org-todo-onhold)
+ ("SMDY" . +org-todo-onhold)
+ ("PROJ" . +org-todo-project)
+ ("NO" . +org-todo-cancel)
+ ("KILL" . +org-todo-cancel))); Task was completed
+;; (setq org-html-head-extra
+;; "<script src=\"https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.min.js\"></script>
+;;<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.css\">
+;;<link rel=\"stylesheet\" type=\"text/css\" href=\"file:///Users/yannherklotz/Projects/orgcss/src/css/org.css\"/>"
+ (setq org-html-head-include-default-style nil
+ org-html-head-include-scripts nil
+ org-html-doctype "html5"
+ org-html-html5-fancy t
+ org-html-container-element "section"
+ org-html-postamble-format
+ '(("en" ""))
+ org-html-postamble t
+ org-html-divs '((preamble "header" "header")
+ (content "article" "content")
+ (postamble "footer" "postamble")))
+
+ (setq org-export-with-broken-links t)
+ (require 'org-habit)
+
+ (require 'calendar)
+ (setq calendar-mark-diary-entries-flag t)
+ (setq calendar-mark-holidays-flag t)
+ (setq calendar-mode-line-format nil)
+ (setq calendar-time-display-form
+ '(24-hours ":" minutes
+ (when time-zone
+ (format "(%s)" time-zone))))
+ (setq calendar-week-start-day 1) ; Monday
+ (setq calendar-date-style 'iso)
+ (setq calendar-date-display-form calendar-iso-date-display-form)
+ (setq calendar-time-zone-style 'numeric) ; Emacs 28.1
+
+ (require 'cal-dst)
+ (setq calendar-standard-time-zone-name "+0000")
+ (setq calendar-daylight-time-zone-name "+0100")
+
+ (require 'diary-lib)
+ (setq diary-file "~/Dropbox/org/diary")
+ (setq diary-date-forms diary-iso-date-forms)
+ (setq diary-comment-start ";;")
+ (setq diary-comment-end "")
+ (setq diary-nonmarking-symbol "!")
+ (setq diary-show-holidays-flag t)
+ (setq diary-display-function #'diary-fancy-display) ; better than its alternative
+ (setq diary-header-line-format nil)
+ (setq diary-list-include-blanks nil)
+ (setq diary-number-of-entries 2)
+ (setq diary-mail-days 2)
+ (setq diary-abbreviated-year-flag nil)
+
+ (add-hook 'calendar-today-visible-hook #'calendar-mark-today)
+ (add-hook 'diary-list-entries-hook #'diary-fix-timezone t)
+ (add-hook 'diary-list-entries-hook #'diary-sort-entries t)
+
+
+ (add-hook 'diary-list-entries-hook 'diary-include-other-diary-files)
+ (add-hook 'diary-mark-entries-hook 'diary-mark-included-diary-files)
+ ;; Prevent Org from interfering with my key bindings.
+ (remove-hook 'calendar-mode-hook #'org--setup-calendar-bindings)
+
+ (let ((map calendar-mode-map))
+ (define-key map (kbd "s") #'calendar-sunrise-sunset)
+ (define-key map (kbd "l") #'lunar-phases)
+ (define-key map (kbd "i") nil) ; Org sets this, much to my chagrin (see `remove-hook' above)
+ (define-key map (kbd "i a") #'diary-insert-anniversary-entry)
+ (define-key map (kbd "i c") #'diary-insert-cyclic-entry)
+ (define-key map (kbd "i d") #'diary-insert-entry) ; for current "day"
+ (define-key map (kbd "i m") #'diary-insert-monthly-entry)
+ (define-key map (kbd "i w") #'diary-insert-weekly-entry)
+ (define-key map (kbd "i y") #'diary-insert-yearly-entry)
+ (define-key map (kbd "M-n") #'calendar-forward-month)
+ (define-key map (kbd "M-p") #'calendar-backward-month))
+
+ (defun diary-schedule (y1 m1 d1 y2 m2 d2 dayname)
+ "Entry applies if date is between dates on DAYNAME.
+ Order of the parameters is M1, D1, Y1, M2, D2, Y2 if
+ `european-calendar-style' is nil, and D1, M1, Y1, D2, M2, Y2 if
+ `european-calendar-style' is t. Entry does not apply on a history."
+ (let ((date1 (calendar-absolute-from-gregorian (list m1 d1 y1)))
+ (date2 (calendar-absolute-from-gregorian (list m2 d2 y2)))
+ (d (calendar-absolute-from-gregorian date)))
+ (if (and
+ (<= date1 d)
+ (<= d date2)
+ (= (calendar-day-of-week date) dayname)
+ (not (calendar-check-holidays date)))
+ entry)))
+
+ (defun diary-fix-timezone ()
+ (let ((eqtimezone (string=
+ (replace-regexp-in-string
+ "\n" ""
+ (shell-command-to-string "date +%z"))
+ (replace-regexp-in-string
+ "\n" ""
+ (shell-command-to-string "TZ=\"Europe/London\" date +%z")))))
+ (setq diary-entries-list
+ (mapcar (lambda (entry)
+ (pcase entry
+ (`(,date ,time ,sdate . ,rest)
+ (let ((dt (diary-entry-time time))
+ (string-date (apply (lambda (a b c) (format "%d-%d-%d" c a b)) date)))
+ (if (or eqtimezone (= dt diary-unknown-time))
+ entry
+ (let* ((tr (org-tz-conv (concat string-date " " (number-to-string dt)) "Europe/London" "from"))
+ (split (split-string tr "[- ]"))
+ (year (car split))
+ (month (cadr split))
+ (day (caddr split))
+ (hour (cadddr split)))
+ (cons (mapcar #'string-to-number (list month day year))
+ (cons (concat hour (replace-regexp-in-string "^[^ ]+" "" time))
+ (cons (format "%s-%s-%s" year month day) rest)))))))))
+ diary-entries-list))))
+
+ (defun org-tz-conv (stamp tz way)
+ "Convert a STAMP to or from TZ depending on WAY.
+
+This function uses the date command line tool to do it."
+ (let* ((current-tz-offset (replace-regexp-in-string
+ "\n" ""
+ (shell-command-to-string "date +%z")))
+ (stamp1 (concat (replace-regexp-in-string "[<>]" "" stamp)))
+ (date-cmd-p0 "TZ=%s gdate -d \"%s\"")
+ (date-cmd-p1 "gdate --date=\"TZ=\\\"%s\\\" %s\"")
+ (date-cmd-p2 " +\"%F %H:%M\"")
+ (date-cmd-from (concat (format date-cmd-p1 tz stamp1) date-cmd-p2))
+ (date-cmd-to (concat (format date-cmd-p0 tz
+ (concat stamp1 " " current-tz-offset))
+ date-cmd-p2))
+
+ (shell-result-from (shell-command-to-string date-cmd-from))
+ (shell-result-to (shell-command-to-string date-cmd-to))
+
+ (result-from (replace-regexp-in-string "\n" "" shell-result-from))
+ (result-to (replace-regexp-in-string "\n" "" shell-result-to)))
+ (cond ((string-equal way "from") result-from)
+ ((string-equal way "to") result-to))))
+
+ (require 'ox-extra)
+ (ox-extras-activate '(ignore-headlines))
+
+ (require 'ox-beamer)
+ (require 'ox-latex)
+ (add-to-list 'org-latex-classes
+ '("beamer"
+ "\\documentclass\[presentation\]\{beamer\}"
+ ("\\section\{%s\}" . "\\section*\{%s\}")
+ ("\\subsection\{%s\}" . "\\subsection*\{%s\}")
+ ("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}")))
+ (add-to-list 'org-latex-classes
+ '("scrartcl"
+ "\\documentclass\{scrartcl\}"
+ ("\\section\{%s\}" . "\\section*\{%s\}")
+ ("\\subsection\{%s\}" . "\\subsection*\{%s\}")
+ ("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}")
+ ("\\paragraph{%s}" . "\\paragraph*{%s}")))
+ (add-to-list 'org-latex-packages-alist '("" "minted"))
+ (setq org-latex-listings 'minted)
+ (setq org-latex-pdf-process '("latexmk -f -pdf -%latex -shell-escape -interaction=nonstopmode -output-directory=%o %f"))
+ (setq org-beamer-environments-extra '(("onlyenv" "o" "\\begin{onlyenv}%a{%h}" "\\end{onlyenv}")
+ ("onlyenvNH" "o" "\\begin{onlyenv}%a" "\\end{onlyenv}")
+ ("blockNH" "o" "\\begin{block}%a{}" "\\end{block}")
+ ("oeblock" "o" "\\only%a{\\begin{block}%a{%h}" "\\end{block}}")
+ ("oeblockNH" "o" "\\only%a{\\begin{block}%a{}" "\\end{block}}")
+ ("minipage" "o" "\\begin{minipage}[t]%o[t]{1.0\\textwidth}" "\\end{minipage}")))
+
+ (add-to-list 'org-latex-packages-alist '("" "tikz" t))
+ (eval-after-load "preview"
+ '(add-to-list 'preview-default-preamble
+ "\\PreviewEnvironment{tikzpicture}" t)))
+
+(use-package appt
+ :config
+ (setq appt-display-diary nil)
+ (setq appt-disp-window-function #'appt-disp-window)
+ (setq appt-display-mode-line t)
+ (setq appt-display-interval 3)
+ (setq appt-audible nil)
+ (setq appt-warning-time-regexp "appt \\([0-9]+\\)")
+ (setq appt-message-warning-time 15)
+ (run-at-time 10 nil #'appt-activate 1))
+
+(use-package! org-transclusion
+ :after org
+ :config
+ (setq org-transclusion-exclude-elements nil)
+ (advice-remove 'org-link-search '+org--recenter-after-follow-link-a))
+
+(use-package! org-superstar
+ :hook (org-mode . org-superstar-mode)
+ :config
+ (setq org-superstar-headline-bullets-list '("♚" "♛" "♜" "♝" "♞" "♔" "♕" "♖" "♗" "♘" "♙")
+ org-superstar-special-todo-items t))
+
+(use-package! org-id
+ :after org
+ :config
+ (setq org-id-link-to-org-use-id 'use-existing)
+ (setq org-id-track-globally t))
+
+;; Set up org registers to quickly jump to files that I use often.
+(set-register ?l (cons 'file "~/.emacs.d/loader.org"))
+(set-register ?m (cons 'file "~/Dropbox/org/meetings.org"))
+(set-register ?i (cons 'file "~/Dropbox/org/inbox.org"))
+(set-register ?p (cons 'file "~/Dropbox/org/projects.org"))
+(set-register ?c (cons 'file (format-time-string "~/Dropbox/org/%Y-%m.org")))
+#+end_src
+
+#+begin_src emacs-lisp
+(use-package! ox-context
+ :after org
+ :config
+ (add-to-list
+ 'org-context-presets-alist
+ '("ymhg-article" .
+ (:literal "\\setupwhitespace[none]"
+ :template "article"
+ :snippets
+ ("description-article" "quote-article" "verse-article"
+ "table-article" "title-ymhg" "sectioning-article" "page-numbering-article"))))
+ (add-to-list 'org-context-snippets-alist
+ '("title-ymhg" . "\\setuphead[title][align=middle]
+\\definestartstop[OrgTitlePage]
+\\define\\OrgMakeTitle{%
+ \\startalignment[center]
+ \\blank[force,2*big]
+ \\title{\\documentvariable{metadata:title}}
+ \\doifnot{\\documentvariable{metadata:subtitle}}{}{
+ \\blank[force,1*big]
+ \\tfa \\documentvariable{metadata:subtitle}}
+ \\doifelse{\\documentvariable{metadata:author}}{}{
+ \\blank[2*medium]
+ {\\tfa \\documentvariable{metadata:email}}
+ }{
+ \\blank[force,2*medium]
+ {\\it by \\documentvariable{metadata:author}}, on \\documentvariable{metadata:date}
+ }
+ \\blank[3*medium]
+ \\stopalignment}
+\\setupsectionblock[frontpart][page=no]
+\\setupsectionblock[bodypart][page=no]
+\\setuppagenumbering[location={footer,middle}]"))
+ (setq org-context-headline-command
+ '("OrgHeadline" . "\\def\\OrgHeadline#1[#2]{%
+ \\getparameters
+ [OrgHeadline]
+ [Todo=,
+ TodoType=,
+ Priority=,
+ Text=,
+ Tags=,
+ #2]%
+ \\doifnot{\\OrgHeadlineTodo}{}{{\\sansbold{\\smallcaps{\\OrgHeadlineTodo}}\\space}}%
+ \\doifnot{\\OrgHeadlinePriority}{}{{\\inframed{\\OrgHeadlinePriority}\\space}}%
+ \\OrgHeadlineText%
+ \\doifnot{\\OrgHeadlineTags}{}{{\\hfill\\tt\\OrgHeadlineTags}}%
+}")))
+#+end_src
+
+** Latex/Context
+
+#+begin_src emacs-lisp
+(after! pdf-tools
+ (pdf-tools-install))
+
+(after! latex
+ (setq TeX-view-program-selection '((output-pdf "PDF Tools"))
+ TeX-source-correlate-start-server t)
+ (setq-default TeX-command-extra-options "-shell-escape")
+ (add-hook 'TeX-after-compilation-finished-functions
+ #'TeX-revert-document-buffer))
+
+(after! context
+ (setq TeX-command-list
+ (append
+ '(("context"
+ "context --purgeall %s"
+ TeX-run-command nil t :help "Run ConTeXt")) TeX-command-list))
+ (map! :map ConTeXt-mode-map
+ "C-c ]" #'ebib-insert-citation)
+ (add-hook 'ConTeXt-mode-hook #'reftex-mode))
+
+(use-package! ox-gfm :after ox)
+(use-package! ox-hugo :after ox)
+
+(use-package! elfeed-org
+ :config
+ (elfeed-org)
+ (setq rmh-elfeed-org-files (list "~/Dropbox/org/elfeed.org"))
+ (run-at-time nil (* 8 60 60) #'elfeed-update))
+
+(use-package! mmm-mode
+ :config
+ (mmm-add-group
+ 'fancy-context
+ '((embedded-lua
+ :submode lua-mode
+ :front "\\\\startluacode"
+ :back "\\\\stopluacode")
+ (embedded-C
+ :submode c-mode
+ :front "\\\\starthlC"
+ :back "\\\\stophlC")
+ (embedded-metapost
+ :submode metapost-mode
+ :front "\\\\startuseMPgraphic"
+ :back "\\\\stopuseMPgraphic")
+ ))
+
+ (mmm-add-mode-ext-class 'ConTeXt-en/PS nil 'fancy-context)
+ (setq mmm-global-mode 'maybe)
+ ;;(setq mmm-never-modes
+ ;; (append '(ediff-mode) '(text-mode) mmm-never-modes))
+ )
+
+(require 'mmm-auto)
+
+#+end_src
+
+*** Zettelkasten
+
+#+begin_src emacs-lisp
+(use-package! org-zettelkasten
+ :config
+ (add-hook 'org-mode-hook #'org-zettelkasten-mode)
+
+ (defun org-zettelkasten-search-current-id ()
+ "Use `consult-ripgrep' to search for the current ID in all files."
+ (interactive)
+ (let ((current-id (org-entry-get nil "CUSTOM_ID")))
+ (consult-ripgrep org-zettelkasten-directory (concat "[\\[:]." current-id "\\]#"))))
+
+ (define-key org-zettelkasten-mode-map (kbd "r") #'org-zettelkasten-search-current-id)
+ (setq org-zettelkasten-directory "~/Dropbox/zk")
+
+ (defun org-zettelkasten-goto-id (id)
+ "Go to an ID."
+ (interactive "sID: #")
+ (cond ((string-prefix-p "1" id)
+ (org-link-open-from-string
+ (concat "[[file:" org-zettelkasten-directory
+ "/hls.org::#" id "]]")))
+ ((string-prefix-p "2" id)
+ (org-link-open-from-string
+ (concat "[[file:" org-zettelkasten-directory
+ "/computing.org::#" id "]]")))
+ ((string-prefix-p "3" id)
+ (org-link-open-from-string
+ (concat "[[file:" org-zettelkasten-directory
+ "/verification.org::#" id "]]")))
+ ((string-prefix-p "4" id)
+ (org-link-open-from-string
+ (concat "[[file:" org-zettelkasten-directory
+ "/mathematics.org::#" id "]]")))
+ ((string-prefix-p "5" id)
+ (org-link-open-from-string
+ (concat "[[file:" org-zettelkasten-directory
+ "/hardware.org::#" id "]]"))))))
+#+end_src
+
+#+begin_src emacs-lisp
+;; Set up zettelkasten mode
+(use-package! zettelkasten
+ :bind-keymap
+ ("C-c k" . zettelkasten-mode-map))
+#+end_src
+
+** Verilog
+
+#+begin_src emacs-lisp
+;; Set sensitive data mode
+(setq auto-mode-alist
+ (append
+ (list ;;'("\\.\\(vcf\\|gpg\\)\\'" . sensitive-minor-mode)
+ '("\\.sv\\'" . verilog-mode)
+ '("\\.mkiv\\'" . context-mode)
+ '("\\.mkii\\'" . context-mode)
+ '("\\.mkxl\\'" . context-mode))
+ auto-mode-alist))
+
+(after! verilog-mode
+ (setq verilog-simulator "iverilog"))
+#+end_src
+
+** Ebib
+
+#+begin_src emacs-lisp
+;; Bibtex stuff
+(use-package! ebib
+ :bind (("C-c y b" . ebib))
+ :init
+ (defun ymhg/ebib-create-identifier (key _) key)
+ (setq ebib-preload-bib-files '("~/Dropbox/bibliography/references.bib")
+ ebib-notes-default-file "~/Dropbox/bibliography/notes.org"
+ ebib-notes-template "* %T\n:PROPERTIES:\n%K\n:NOTER_DOCUMENT: papers/%k.pdf\n:END:\n%%?\n"
+ ebib-keywords (expand-file-name "~/Dropbox/bibliography/keywords.txt")
+ ebib-reading-list-file "~/Dropbox/bibliography/reading_list.org"
+ ebib-notes-storage 'multiple-notes-per-file)
+ :config
+ (add-to-list 'ebib-notes-template-specifiers '(?k . ymhg/ebib-create-identifier))
+ (add-to-list 'ebib-file-search-dirs "~/Dropbox/bibliography/papers")
+ (if (eq system-type 'darwin)
+ (add-to-list 'ebib-file-associations '("pdf" . "open"))
+ (add-to-list 'ebib-file-associations '("pdf" . nil)))
+ (add-to-list 'ebib-citation-commands '(org-mode (("ref" "[cite:@%(%K%,)]"))))
+ (add-to-list 'ebib-citation-commands '(context-mode (("cite" "\\cite[%(%K%,)]")
+ ("authoryear" "\\cite[authoryear][%(%K%,)]")
+ ("authoryears" "\\cite[authoryears][%(%K%,)]")
+ ("entry" "\\cite[entry][%(%K%,)]")
+ ("author" "\\cite[author][%(%K%,)]"))))
+
+ (advice-add 'bibtex-generate-autokey :around
+ (lambda (orig-func &rest args)
+ (replace-regexp-in-string ":" "" (apply orig-func args))))
+ (remove-hook 'ebib-notes-new-note-hook #'org-narrow-to-subtree)
+
+ (map! :map ebib-index-mode-map
+ "D" #'ebib-download-pdf-from-doi))
+
+(defun sci-hub-pdf-url (doi)
+ "Get url to the pdf from SCI-HUB using DOI."
+ (setq *doi-utils-pdf-url* (concat "https://sci-hub.hkvisa.net/" doi) ;captcha
+ ,*doi-utils-waiting* t
+ )
+ ;; try to find PDF url (if it exists)
+ (url-retrieve (concat "https://sci-hub.hkvisa.net/" doi)
+ (lambda (_)
+ (goto-char (point-min))
+ (while (search-forward-regexp
+ "\\(https:\\|sci-hub.hkvisa.net/downloads\\).+download=true'" nil t)
+ (let ((foundurl (match-string 0)))
+ (message foundurl)
+ (if (string-match "https:" foundurl)
+ (setq *doi-utils-pdf-url* foundurl)
+ (setq *doi-utils-pdf-url* (concat "https:" foundurl))))
+ (setq *doi-utils-waiting* nil))))
+ (while *doi-utils-waiting* (sleep-for 0.1))
+ (replace-regexp-in-string "\\\\" "" *doi-utils-pdf-url*))
+
+(defun acm-pdf-url (doi)
+ "Retrieve a DOI pdf from the ACM."
+ (concat "https://dl.acm.org/doi/pdf/" doi))
+
+(defun ieee-pdf-url (doi)
+ "Retrieve a DOI pdf from the IEEE."
+ (when (string-match "\\.\\([0-9]*\\)$" doi)
+ (let ((doi-bit (match-string 1 doi)))
+ (concat "https://ieeexplore.ieee.org/stampPDF/getPDF.jsp?tp=&arnumber=" doi-bit "&ref="))))
+
+(defun springer-pdf-url (doi)
+ "Retrieve a DOI pdf from the Springer."
+ (concat "https://link.springer.com/content/pdf/" doi ".pdf"))
+
+(defun arxiv-pdf-url (epr)
+ (concat "https://arxiv.org/pdf/" epr ".pdf"))
+
+(defun download-pdf-from-doi (key &optional doi publisher eprint journal organization url)
+ "Download pdf from doi with KEY name."
+ (let ((pub (or publisher ""))
+ (epr (or eprint ""))
+ (jour (or journal ""))
+ (org (or organization ""))
+ (link (or url "")))
+ (url-copy-file (cond
+ ((not doi) link)
+ ((or (string-match "ACM" (s-upcase pub))
+ (string-match "association for computing machinery" (s-downcase pub)))
+ (acm-pdf-url doi))
+ ((string-match "arxiv" (s-downcase pub))
+ (arxiv-pdf-url epr))
+ ((or (string-match "IEEE" (s-upcase pub))
+ (string-match "IEEE" (s-upcase jour))
+ (string-match "IEEE" (s-upcase org)))
+ (ieee-pdf-url doi))
+ ((string-match "springer" (s-downcase pub))
+ (springer-pdf-url doi))
+ (t (sci-hub-pdf-url doi)))
+ (concat (car ebib-file-search-dirs) "/" key ".pdf"))))
+
+(defun download-pdf-from-link (link key)
+ (url-copy-file link
+ (concat (car ebib-file-search-dirs) "/" key ".pdf")))
+
+(defun download-pdf-from-downloads (key)
+ (copy-file (concat "~/Downloads/" key ".pdf")
+ (concat (car ebib-file-search-dirs) "/" key ".pdf") t))
+
+(defun get-bib-from-doi (doi)
+ "Get the bibtex from DOI."
+ (shell-command (concat "curl -L -H \"Accept: application/x-bibtex; charset=utf-8\" "
+ "https://doi.org/" doi)))
+
+(defun ebib-download-pdf-from-doi ()
+ "Download a PDF for the current entry."
+ (interactive)
+ (let* ((key (ebib--get-key-at-point))
+ (doi (ebib-get-field-value "doi" key ebib--cur-db 'noerror 'unbraced 'xref))
+ (publisher (ebib-get-field-value "publisher" key ebib--cur-db 'noerror 'unbraced 'xref))
+ (eprinttype (ebib-get-field-value "eprinttype" key ebib--cur-db 'noerror 'unbraced 'xref))
+ (eprint (ebib-get-field-value "eprint" key ebib--cur-db 'noerror 'unbraced 'xref))
+ (journal (ebib-get-field-value "journal" key ebib--cur-db 'noerror 'unbraced 'xref))
+ (journaltitle (ebib-get-field-value "journaltitle" key ebib--cur-db 'noerror 'unbraced 'xref))
+ (organization (ebib-get-field-value "organization" key ebib--cur-db 'noerror 'unbraced 'xref))
+ (url (ebib-get-field-value "url" key ebib--cur-db 'noerror 'unbraced 'xref)))
+ (unless key
+ (error "[Ebib] No key assigned to entry"))
+ (download-pdf-from-doi key doi (or publisher eprinttype) eprint (or journal journaltitle) organization url)))
+
+(defun ebib-check-file ()
+ "Download a PDF for the current entry."
+ (interactive)
+ (let ((key (ebib--get-key-at-point)))
+ (unless (file-exists-p (concat (car ebib-file-search-dirs) "/" key ".pdf"))
+ (error "[Ebib] No PDF found."))
+ t))
+#+end_src
+
+** Ocaml
+
+#+begin_src emacs-lisp
+(after! tuareg-mode
+ (add-hook 'tuareg-mode-hook
+ (lambda ()
+ (define-key tuareg-mode-map (kbd "C-M-<tab>") #'ocamlformat)
+ (add-hook 'before-save-hook #'ocamlformat-before-save))))
+#+end_src
+
+** Spell check
+
+#+begin_src emacs-lisp
+;; Set up dictionaries
+(setq ispell-dictionary "british")
+
+(use-package! spell-fu
+ :config
+ (add-hook 'spell-fu-mode-hook
+ (lambda ()
+ (spell-fu-dictionary-add (spell-fu-get-ispell-dictionary "en_GB"))
+ (spell-fu-dictionary-add (spell-fu-get-ispell-dictionary "de_DE"))
+ (spell-fu-dictionary-add (spell-fu-get-ispell-dictionary "fr_FR"))
+ (spell-fu-dictionary-add
+ (spell-fu-get-personal-dictionary "fr-personal" "~/.aspell.en_GB.pws"))
+ (spell-fu-dictionary-add
+ (spell-fu-get-personal-dictionary "de-personal" "~/.aspell.de_DE.pws"))
+ (spell-fu-dictionary-add
+ (spell-fu-get-personal-dictionary "fr-personal" "~/.aspell.fr_FR.pws")))))
+
+(after! flyspell
+ (define-key flyspell-mode-map (kbd "C-.") nil)
+ (define-key flyspell-mode-map (kbd "C-,") nil)
+ (setq flyspell-mouse-map (make-sparse-keymap)))
+#+end_src
+
+** Coq configuration
+
+#+begin_src emacs-lisp
+(use-package! proof-general
+ :config
+ (setq proof-splash-enable nil
+ proof-auto-action-when-deactivating-scripting 'retract
+ proof-delete-empty-windows nil
+ proof-multiple-frames-enable nil
+ proof-three-window-enable nil
+ proof-auto-raise-buffers nil
+ coq-compile-before-require nil
+ coq-compile-vos t
+ coq-compile-parallel-in-background t
+ coq-max-background-compilation-jobs 4
+ coq-compile-keep-going nil
+ coq-compile-quick 'no-quick))
+
+(use-package! company-coq
+ :after coq
+ :config
+ (setq company-idle-delay 1
+ company-coq-disabled-features '(prettify-symbols hello company-defaults spinner smart-subscripts snippets compile-command)))
+#+end_src
+
+** Mail
+
+#+begin_src emacs-lisp
+(setq message-send-mail-function 'message-send-mail-with-sendmail)
+(setq message-fill-column 80)
+
+(use-package! sendmail
+ :config
+ (if (eq system-type 'darwin)
+ (setq sendmail-program "/usr/local/bin/msmtp")
+ (setq sendmail-program "/usr/bin/msmtp")))
+
+(setq message-signature "Yann Herklotz
+Imperial College London
+https://yannherklotz.com")
+
+(setq auth-sources '("~/.authinfo" "~/.authinfo.gpg" "~/.netrc"))
+
+(setq mail-specify-envelope-from t
+ message-sendmail-envelope-from 'header
+ mail-envelope-from 'header)
+
+(use-package! notmuch
+ :config
+ (defun ymhg/notmuch-search-delete-mail (&optional beg end)
+ "Delete a message."
+ (interactive (notmuch-interactive-region))
+ (if (member "deleted" (notmuch-search-get-tags))
+ (notmuch-search-tag (list "-deleted"))
+ (notmuch-search-tag (list "+deleted" "-unread") beg end)))
+
+ (defun ymhg/notmuch-show-delete-mail (&optional beg end)
+ "Delete a message."
+ (interactive (notmuch-interactive-region))
+ (if (member "deleted" (notmuch-show-get-tags))
+ (notmuch-show-tag (list "-deleted"))
+ (notmuch-show-tag (list "+deleted" "-unread") beg end)))
+
+ (setq notmuch-archive-tags '("-inbox" "-unread" "+archive"))
+
+ (map!
+ :map notmuch-show-mode-map
+ "d" #'ymhg/notmuch-show-delete-mail)
+ (map!
+ :map notmuch-search-mode-map
+ "d" #'ymhg/notmuch-search-delete-mail)
+
+ (setq notmuch-saved-searches
+ '((:name "inbox" :query "date:last_month..this_month and tag:inbox not tag:deleted" :key "n")
+ (:name "flagged" :query "tag:flagged" :key "f")
+ (:name "sent" :query "tag:sent" :key "s")
+ (:name "drafts" :query "tag:draft" :key "d")
+ (:name "mailbox" :query "date:last_month..this_month and (tag:mailbox and tag:inbox) and not tag:deleted and not tag:sent" :key "m")
+ (:name "imperial" :query "date:last_month..this_month and (tag:imperial and tag:inbox) and not tag:deleted and not tag:sent" :key "i")
+ (:name "all recent" :query "date:last_month..this_month" :key "r")))
+
+ (setq notmuch-fcc-dirs
+ '(("yann@yannherklotz.com" . "mailbox/Sent -inbox +sent -unread +mailbox -new")
+ ("git@ymhg.org" . "mailbox/Sent -inbox +sent -unread +mailbox -new")
+ ("yann.herklotz15@imperial.ac.uk" . "\"imperial/Sent Items\" -inbox +sent -unread +imperial -new")))
+
+ (setq +notmuch-home-function (lambda () (notmuch-search "tag:inbox"))))
+
+(after! shr (setq shr-use-fonts nil
+ shr-max-image-proportion 0.5))
+#+end_src
+
+** Smartparens
+
+#+begin_src emacs-lisp
+(use-package! smartparens
+ :config
+ (map! :map smartparens-mode-map
+ "M-[" #'sp-backward-unwrap-sexp
+ "M-]" #'sp-unwrap-sexp
+ "C-M-f" #'sp-forward-sexp
+ "C-M-b" #'sp-backward-sexp
+ "C-M-d" #'sp-down-sexp
+ "C-M-a" #'sp-backward-down-sexp
+ "C-M-e" #'sp-up-sexp
+ "C-M-u" #'sp-backward-up-sexp
+ "C-M-t" #'sp-transpose-sexp
+ "C-M-n" #'sp-next-sexp
+ "C-M-p" #'sp-previous-sexp
+ "C-M-k" #'sp-kill-sexp
+ "C-M-w" #'sp-copy-sexp
+ "C-)" #'sp-forward-slurp-sexp
+ "C-}" #'sp-forward-barf-sexp
+ "C-(" #'sp-backward-slurp-sexp
+ "C-{" #'sp-backward-barf-sexp
+ "M-D" #'sp-splice-sexp
+ "C-]" #'sp-select-next-thing-exchange
+ "C-<left_bracket>" #'sp-select-previous-thing
+ "C-M-]" #'sp-select-next-thing
+ "M-F" #'sp-forward-symbol
+ "M-B" #'sp-backward-symbol
+ "M-r" #'sp-split-sexp)
+ (require 'smartparens-config)
+ (show-smartparens-global-mode +1)
+ (smartparens-global-mode 1)
+;;(sp-pair "'" nil :actions :rem)
+ (sp-local-pair 'coq-mode "'" nil :actions nil))
+#+end_src
+
+#+begin_src emacs-lisp
+(after! writeroom-mode (setq +zen-text-scale 1))
+
+(use-package! direnv :config (direnv-mode))
+
+(use-package alert
+ :custom
+ (alert-default-style 'osx-notifier))
+
+(use-package ledger-mode)
+
+(defun diary-last-day-of-month (date)
+ "Return `t` if DATE is the last day of the month."
+ (let* ((day (calendar-extract-day date))
+ (month (calendar-extract-month date))
+ (year (calendar-extract-year date))
+ (last-day-of-month
+ (calendar-last-day-of-month month year)))
+ (= day last-day-of-month)))
+
+(use-package! calc-forms
+ :config
+ (add-to-list 'math-tzone-names '("AOE" 12 0))
+ (add-to-list 'math-tzone-names '("IST" (float -55 -1) 0)))
+
+(use-package! orderless
+ :custom (completion-styles '(substring orderless)))
+
+(use-package! vertico
+ :init
+ (vertico-mode))
+
+(use-package! savehist
+ :init
+ (savehist-mode))
+
+(use-package! marginalia
+ :bind (("M-A" . marginalia-cycle)
+ :map minibuffer-local-map
+ ("M-A" . marginalia-cycle))
+ :init
+ ;; Must be in the :init section of use-package such that the mode gets
+ ;; enabled right away. Note that this forces loading the package.
+ (marginalia-mode))
+#+end_src
+
+** Embark
+
+#+begin_src emacs-lisp
+(use-package! embark
+ :bind
+ (("C-;" . embark-act))
+ :init
+ ;; Optionally replace the key help with a completing-read interface
+ (setq prefix-help-command #'embark-prefix-help-command)
+ :config
+ (add-to-list 'display-buffer-alist
+ '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
+ nil
+ (window-parameters (mode-line-format . none)))))
+
+(use-package! embark-consult
+ :after (embark consult)
+ :demand t ; only necessary if you have the hook below
+ ;; if you want to have consult previews as you move around an
+ ;; auto-updating embark collect buffer
+ :hook
+ (embark-collect-mode . consult-preview-at-point-mode))
+#+end_src
+
+** Consult
+
+#+begin_src emacs-lisp
+;; Example configuration for Consult
+(use-package! consult
+ ;; Replace bindings. Lazily loaded due by `use-package'.
+ :bind (;; C-c bindings (mode-specific-map)
+ ("C-c h" . consult-history)
+ ("C-c m" . consult-mode-command)
+ ("C-c b" . consult-bookmark)
+ ("C-c k" . consult-kmacro)
+ ;; C-x bindings (ctl-x-map)
+ ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
+ ("C-x b" . consult-buffer) ;; orig. switch-to-buffer
+ ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
+ ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
+ ;; Custom M-# bindings for fast register access
+ ("M-#" . consult-register-load)
+ ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
+ ("C-M-#" . consult-register)
+ ;; Other custom bindings
+ ("M-y" . consult-yank-pop) ;; orig. yank-pop
+ ("<help> a" . consult-apropos) ;; orig. apropos-command
+ ;; M-g bindings (goto-map)
+ ("M-g e" . consult-compile-error)
+ ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
+ ("M-g g" . consult-goto-line) ;; orig. goto-line
+ ("M-g M-g" . consult-goto-line) ;; orig. goto-line
+ ("M-g o" . consult-outline) ;; Alternative: consult-org-heading
+ ("M-g m" . consult-mark)
+ ("M-g k" . consult-global-mark)
+ ("M-g i" . consult-imenu)
+ ("M-g I" . consult-imenu-multi)
+ ;; M-s bindings (search-map)
+ ("M-s f" . consult-find)
+ ("M-s F" . consult-locate)
+ ("M-s g" . consult-grep)
+ ("M-s G" . consult-git-grep)
+ ("M-s r" . consult-ripgrep)
+ ("M-s l" . consult-line)
+ ("M-s L" . consult-line-multi)
+ ("M-s m" . consult-multi-occur)
+ ("M-s k" . consult-keep-lines)
+ ("M-s u" . consult-focus-lines)
+ ;; Isearch integration
+ ("M-s e" . consult-isearch)
+ :map isearch-mode-map
+ ("M-e" . consult-isearch) ;; orig. isearch-edit-string
+ ("M-s e" . consult-isearch) ;; orig. isearch-edit-string
+ ("M-s l" . consult-line) ;; needed by consult-line to detect isearch
+ ("M-s L" . consult-line-multi)) ;; needed by consult-line to detect isearch
+
+ ;; Enable automatic preview at point in the *Completions* buffer.
+ ;; This is relevant when you use the default completion UI,
+ ;; and not necessary for Vertico, Selectrum, etc.
+ :hook (completion-list-mode . consult-preview-at-point-mode)
+
+ ;; The :init configuration is always executed (Not lazy)
+ :init
+
+ (setq register-preview-delay 0
+ register-preview-function #'consult-register-format)
+
+ (advice-add #'register-preview :override #'consult-register-window)
+
+ ;; Use Consult to select xref locations with preview
+ (setq xref-show-xrefs-function #'consult-xref
+ xref-show-definitions-function #'consult-xref)
+ :config
+ ;; Optionally configure the narrowing key.
+ ;; Both < and C-+ work reasonably well.
+ (setq consult-narrow-key "<") ;; (kbd "C-+")
+
+ (setq consult-project-root-function
+ (lambda ()
+ (when-let (project (project-current))
+ (car (project-roots project))))))
+#+end_src
+
+** Scheme
+
+#+begin_src emacs-lisp
+(use-package! geiser-chicken
+ :config
+ (setq geiser-chicken-binary "chicken-csi"))
+
+(use-package! geiser
+ :init
+ (map! :map geiser-mode-map "C-." nil)
+ (map! :map geiser-repl-mode-map "C-." nil))
+#+end_src
+
+** Emacs
+
+#+begin_src emacs-lisp
+(use-package! emacs
+ :init
+ ;; Do not allow the cursor in the minibuffer prompt
+ (setq minibuffer-prompt-properties
+ '(read-only t cursor-intangible t face minibuffer-prompt))
+ (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
+
+ ;; Emacs 28: Hide commands in M-x which do not work in the current mode.
+ ;; Vertico commands are hidden in normal buffers.
+ (setq read-extended-command-predicate
+ #'command-completion-default-include-p)
+
+ ;; Enable recursive minibuffers
+ (setq enable-recursive-minibuffers t))
+
+(use-package! boogie-friends)
+
+(use-package! ol-notmuch :after org)
+
+(use-package! circe
+ :config
+ (setq circe-network-options
+ `(("soju" :host "chat.sr.ht" :port 6697 :tls t
+ :sasl-username "ymherklotz/irc.libera.chat"
+ :sasl-password ,(ymhg/pass "sr.ht/chat.sr.ht")
+ :nick "ymherklotz"))))
+
+(defun ymhg/reset-coq-windows ()
+ "Resets the Goald and Response windows."
+ (interactive)
+ (other-frame 1)
+ (delete-other-windows)
+ (split-window-below)
+ (switch-to-buffer "*goals*")
+ (other-window 1)
+ (switch-to-buffer "*response*")
+ (other-frame 1))
+
+(define-key y-map (kbd "o") #'ymhg/reset-coq-windows)
+
+(defun ymhg--reset-coq-indentation ()
+ "Reset slow indentation."
+ (setq-local indent-line-function #'indent-relative))
+
+(after! coq-mode
+ (add-hook 'coq-mode-hook #'ymhg--reset-coq-indentation t)
+ (define-key coq-mode-map (kbd "C-c TAB") #'smie-indent-line)
+ (setq coq-indent-modulestart 0))
+
+(use-package! alectryon
+ :hook (coq-mode . alectryon-mode)
+ :config
+ (when (eq system-type 'darwin)
+ (setq alectryon-executable "/nix/store/bvlk3hyrjdgl0sg93rrdr2z71hgza0m9-python3.9-alectryon-1.4.0/bin/alectryon"))
+ (map! :map alectryon-mode-map
+ "C-c u t" #'alectryon-toggle
+ "C-c u p" #'ymhg/alectryon-preview)
+ (defun ymhg/alectryon-preview ()
+ "Display an HTML preview of the current buffer."
+ (interactive)
+ (let* ((html-fname (make-temp-file "alectryon" nil ".html"))
+ (args `("-r" "5" "-" ,html-fname)))
+ (apply #'call-process-region nil nil "rst2html5" nil nil nil args)
+ (message "Compilation complete")
+ (browse-url html-fname))))
+
+(use-package! rst
+ :config
+ (add-hook 'rst-mode-hook (lambda () (setq fill-column 80))))
+
+(use-package! ox-tufte
+ :after org
+ :config)
+
+(use-package! scroll-other-window
+ :hook (ConTeXt-mode . sow-mode))
+
+(use-package! cdlatex
+ :hook (ConTeXt-mode . turn-on-cdlatex)
+ :init
+ (setq cdlatex-command-alist nil)
+ (setq cdlatex-math-modify-alist nil))
+
+(use-package! boogie-friends
+ :config
+ (setq flycheck-dafny-executable (executable-find "dafny"))
+ (setq dafny-verification-backend 'cli))
+
+;;(add-to-list 'load-path "/usr/local/Cellar/agda/2.6.2.2/cabal/store/ghc-8.10.7/Agd-2.6.2.2-3bca6588/share/emacs-mode")
+;;
+;;(use-package! agda2-mode)
+#+end_src