From 4456cd5ec1a5d03bd9bf181001a716564c1c6ce3 Mon Sep 17 00:00:00 2001 From: Ryan Kavanagh Date: Fri, 5 Jan 2024 18:20:53 -0500 Subject: Don't whitespace-cleanup in markdown --- dot_emacs | 1081 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1081 insertions(+) create mode 100644 dot_emacs (limited to 'dot_emacs') diff --git a/dot_emacs b/dot_emacs new file mode 100644 index 0000000..5863e8e --- /dev/null +++ b/dot_emacs @@ -0,0 +1,1081 @@ +;; -*- emacs-lisp -*- +;; (setq debug-on-error t) + +(require 'package) +(setq package-enable-at-startup nil) +(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/")) +(let ((default-directory "~/.emacs.d/lisp/")) + (normal-top-level-add-subdirs-to-load-path)) +(package-initialize) + +;; Bootstrap `use-package' +(unless (package-installed-p 'use-package) + (package-refresh-contents) + (package-install 'use-package)) + +(eval-when-compile + (require 'use-package)) + +;;; General emacs configuration +(use-package emacs + :init ; executed before package is loaded + (fset 'yes-or-no-p 'y-or-n-p) + (put 'narrow-to-region 'disabled nil) + :hook ; add functions onto hook; only basename needed + ((text-mode . turn-on-auto-fill) + (before-save . whitespace-cleanup)) + :bind ; key bindings + (("C-x a r" . align-regexp)) + :config ; executed after package is loaded + (defadvice ; align-regexp should use spaces. + align-regexp + (around align-regexp-with-spaces activate) + (let ((indent-tabs-mode nil)) ad-do-it)) + :custom + (inhibit-startup-screen t) + (default-input-method "TeX") + (user-full-name "Ryan Kavanagh") + (user-mail-address "rak@rak.ac") + :custom-face + (default ((t (:family "Iosevka"))))) + +(if (string= (system-name) "demeter.rak.ac") + (use-package leuven-theme ; nice theme for lecturing / projectors + :ensure t + :config + (load-theme 'leuven t)) + (use-package moe-theme + :ensure t + :after powerline ; must be loaded after for powerline-moe-theme to work + :config + (moe-dark) + (moe-theme-powerline))) + +(defun single-lines-only () + "Replace multiple blank lines with a single one" + (interactive) + (goto-char (point-min)) + (while (re-search-forward "\\(^\\s-*$\\)\n" nil t) + (replace-match "\n") + (forward-char 1))) + +(use-package ace-window + :ensure t + :custom + ;; home row keys + (aw-keys '(?h ?t ?n ?s ?a ?o ?e ?u ?i ?d)) + :bind (("M-o" . ace-window)) + :config + ;; need to redefine a few of these because the defaults + ;; overlap with customized aw-keys + (setq aw-dispatch-alist + '((?x aw-delete-window "Delete Window") + (?m aw-swap-window "Swap Windows") + (?M aw-move-window "Move Window") + (?c aw-copy-window "Copy Window") + (?j aw-switch-buffer-in-window "Select Buffer") + (?f aw-flip-window) + (?p aw-switch-buffer-other-window "Switch Buffer Other Window") + (?c aw-split-window-fair "Split Fair Window") + (?v aw-split-window-vert "Split Vert Window") + (?b aw-split-window-horz "Split Horz Window") + (?1 delete-other-windows "Delete Other Windows") + (?? aw-show-dispatch-help)))) + +(use-package aggressive-indent + :ensure t + :config + (global-aggressive-indent-mode 1)) + +(use-package autorevert + :diminish auto-revert-mode) + +(use-package avy + :ensure t + :config + (avy-setup-default) + :bind + (("C-c C-j" . avy-resume) + ("C-;" . avy-goto-char))) + +(use-package beluga-mode + :load-path "~/.opam/default/.opam-switch/sources/beluga/tools/" + :mode "\\.bel\'") + +(use-package bibtex + :mode ("\\.bib\'" . bibtex-mode) + :custom + (bibtex-dialect 'biblatex) + (bibtex-maintain-sorted-entries 'crossref) + ;; Use only the first author name if there are more than 2 authors + (bibtex-autokey-names 1) + ;; Otherwise use both names + (bibtex-autokey-names-stretch 1) + (bibtex-autokey-name-separator "_") + (bibtex-autokey-name-year-separator "_") + (bibtex-autokey-year-length 4) + (bibtex-autokey-year-title-separator ":_") + (bibtex-autokey-titleword-length 5) + (bibtex-autokey-titlewords 3) + ;; Make all title words lowercase + (bibtex-autokey-preserve-case 1) + :bind (:map bibtex-mode-map + ("C-c C-c" . org-ref-clean-bibtex-entry) + ("C-c s" . bibtex-sort-buffer)) + :config + (defun my/bibtex-generate-autokey (autogenerated) + (let ((key (bibtex-autokey-get-field "_key"))) + (if (string= "" key) autogenerated key))) + (advice-add 'bibtex-generate-autokey :filter-return #'my/bibtex-generate-autokey) + ;; stolen from bibtex.el and modified to handle "Mac Lane" + (defun my/bibtex-autokey-demangle-name (fullname) + "Get the last part from a well-formed FULLNAME and perform abbreviations." + (let* (case-fold-search + (name (cond ((string-match "\\(\\(Ma?c\\|De\\) +[[:upper:]][^, ]*\\)[^,]*," fullname) + ;; Name is of the form "Mac Last, First" or + ;; "Mac Last, Jr, First" or "Mc Last, First" or + ;; "Mc Last, Jr, First" + ;; --> Take Mac Last or Mc Last, as appropriate + ;; and replace spaces by concatenation + (let ((mclast (match-string 1 fullname))) + (when (string-match split-string-default-separators mclast) + (replace-match "" nil nil mclast)))) + ((string-match "\\([[:upper:]][^, ]*\\)[^,]*," fullname) + ;; Name is of the form "von Last, First" or + ;; "von Last, Jr, First" + ;; --> Take the first capital part before the comma + (match-string 1 fullname)) + ((string-match "\\([^, ]*\\)," fullname) + ;; Strange name: we have a comma, but nothing capital + ;; So we accept even lowercase names + (match-string 1 fullname)) + ((string-match "\\(\\<[[:lower:]][^ ]* +\\)+\\([[:upper:]][^ ]*\\)" + fullname) + ;; name is of the form "First von Last", "von Last", + ;; "First von von Last", or "d'Last" + ;; --> take the first capital part after the "von" parts + (match-string 2 fullname)) + ((string-match "\\([^ ]+\\) *\\'" fullname) + ;; name is of the form "First Middle Last" or "Last" + ;; --> take the last token + (match-string 1 fullname)) + (t (error "Name `%s' is incorrectly formed" fullname))))) + (funcall bibtex-autokey-name-case-convert-function + (bibtex-autokey-abbrev name bibtex-autokey-name-length)))) + (advice-add 'bibtex-autokey-demangle-name :override 'my/bibtex-autokey-demangle-name) + ;; Until https://debbugs.gnu.org/cgi/bugreport.cgi?bug=36252 gets fixed + (defun bibtex-autokey-get-year () + "Return year field contents as a string obeying `bibtex-autokey-year-length'. +If the year field is absent, extract the year from a valid ISO8601-2 +Extended Format date in the date field and return it as a string obeing +`bibtex-autokey-year-length'." + (let ((yearfield (bibtex-autokey-get-field "year")) + (datefield (bibtex-autokey-get-field "date")) + (shortener (lambda (year) + (substring year (max 0 (- (length year) + bibtex-autokey-year-length)))))) + (if (string= "" yearfield) + (cond ((string-match "[./]*\\(-?[[:digit:]]+X*\\)\\([-/.[:digit:]:T~?%X]*\\)" + datefield) + ;; Matches ISO8601-2 Extended Format specification level 1 + ;; examples listed in tables 3, 4, and 5 on pp. 38-40 of the + ;; biblatex package manual, version 3.12 + (funcall shortener (match-string 1 datefield))) + (t (error "Date field `%s' is incorrectly formed" datefield))) + (funcall shortener yearfield)))) + ;; Don't have accented characters in keys + (let ((charMap '(;; This list based on Xah Lee's http://ergoemacs.org/emacs/emacs_zap_gremlins.html + ;; Case-sensitivity (see bibtex-autokey-name-change-strings) requires us to + ;; duplicate everything + ("ß" . "ss") + ("á\\|à\\|â\\|ä\\|ā\\|ǎ\\|ã\\|å\\|ą\\|ă\\|ạ\\|ả\\|ả\\|ấ\\|ầ\\|ẩ\\|ẫ\\|ậ\\|ắ\\|ằ\\|ẳ\\|ặ" . "a") + ("æ" . "ae") + ("ç\\|č\\|ć" . "c") + ("é\\|è\\|ê\\|ë\\|ē\\|ě\\|ę\\|ẹ\\|ẻ\\|ẽ\\|ế\\|ề\\|ể\\|ễ\\|ệ" . "e") + ("í\\|ì\\|î\\|ï\\|ī\\|ǐ\\|ỉ\\|ị" . "i") + ("ñ\\|ň\\|ń" . "n") + ("ó\\|ò\\|ô\\|ö\\|õ\\|ǒ\\|ø\\|ō\\|ồ\\|ơ\\|ọ\\|ỏ\\|ố\\|ổ\\|ỗ\\|ộ\\|ớ\\|ờ\\|ở\\|ợ" . "o") + ("ú\\|ù\\|û\\|ü\\|ū\\|ũ\\|ư\\|ụ\\|ủ\\|ứ\\|ừ\\|ử\\|ữ\\|ự" . "u") + ("ý\\|ÿ\\|ỳ\\|ỷ\\|ỹ" . "y") + ("þ" . "th") + ("ď\\|ð\\|đ" . "d") + ("ĩ" . "i") + ("ľ\\|ĺ\\|ł" . "l") + ("ř\\|ŕ" . "r") + ("š\\|ś" . "s") + ("ť" . "t") + ("ž\\|ź\\|ż" . "z") + ("œ" . "oe") + (" " . " ") ; thin space etc + ("–" . "-") + ("—\\|一" . "--")))) + ;; For some reason, *-name-* and *-titleword-* get clobbered, even + ;; though the original value in decribe-variable clearly shows + ;; them having been based on the extended + ;; bibtex-autokey-transcriptions. Force them to be the right + ;; thing. + (progn (seq-do (lambda (pair) (add-to-list 'bibtex-autokey-transcriptions pair)) charMap) + (seq-do (lambda (pair) (add-to-list 'bibtex-autokey-name-change-strings pair)) charMap) + (seq-do (lambda (pair) (add-to-list 'bibtex-autokey-titleword-change-strings pair)) charMap)))) + +(use-package bibtex-completion + :ensure ivy-bibtex + :custom + (bibtex-completion-bibliography "~/Documents/papers/library.bib") + (bibtex-completion-library-path '("~/Documents/papers/pdfs/")) + (bibtex-completion-notes-path "~/Documents/papers/notes/") + (bibtex-completion-notes-extension ".org") + (bibtex-completion-pdf-extension '(".pdf" ".djvu" ".txt"))) + +(use-package cc-mode + :custom + (c-default-style "bsd")) + +(use-package company + :ensure t + :diminish + :bind + ("" . company-indent-or-complete-common) + :hook + (after-init . global-company-mode)) + +(use-package company-auctex + :ensure t + :after latex + :config + (company-auctex-init)) + +(use-package company-bibtex + :ensure t + :hook + (bibtex-mode . (lambda () (add-to-list 'company-backends 'company-bibtex)))) + +(use-package company-box + :ensure t + :diminish + :hook (company-mode . company-box-mode)) + +(use-package company-coq + :ensure t + :hook (coq-mode . company-coq-mode)) + +(use-package company-math + :ensure t + :config + (add-to-list 'company-backends 'company-math-symbols-unicode) + (add-to-list 'company-backends 'company-latex-commands)) + +(use-package company-org-block + :ensure t + :hook ((org-mode . (lambda () + (setq-local company-backends '(company-org-block)) + (company-mode +1))))) + +(use-package counsel + :ensure t + :bind + (("C-x b" . counsel-switch-buffer) + ("C-x C-b" . counsel-ibuffer) + ("C-x C-f" . counsel-find-file) + ("M-x" . counsel-M-x) + ("M-y" . counsel-yank-pop) + (" i" . counsel-info-lookup-symbol) + (" j" . counsel-set-variable) + (" u" . counsel-unicode-char)) + :config + (add-to-list 'ivy-initial-inputs-alist + '(counsel-M-x . ""))) + +(use-package cus-edit + :custom + (custom-file null-device "Don't store customizations")) + +(use-package diary + :ensure diary-lib + :custom + (diary-display-function 'diary-fancy-display) + :hook ((diary-list-entries . diary-include-other-diary-files) + (diary-list-entries . diary-sort-entries))) + +(use-package dictem) + +(use-package diminish + :ensure t) + +(use-package doi-utils + ;; provided by org-ref + :ensure org-ref) + +(use-package dtrt-indent + :ensure t) + +(use-package dune + :ensure t) + +(use-package dune-format + :ensure t) + +(use-package eldoc + :diminish) + +(use-package elpher + :ensure t) + +(use-package elpy + :ensure t + :after python + :config (elpy-enable) + :custom + (elpy-rpc-python-command "python3")) + +(use-package ess + :ensure t) + +(use-package fill-column-indicator + :ensure t) + +(use-package flyspell + :bind + (("" . flyspell-auto-correct-previous-word)) + :config + (unbind-key "C-;" flyspell-mode-map)) + +(use-package flyspell-correct-ivy + :ensure t + :after flyspell + :bind + ("C-" . flyspell-correct-wrapper) + :config + (setq flyspell-correct-interface #'flyspell-correct-ivy)) + +(use-package gnus + :ensure t + :defer t + :bind + ;; (:map gnus-summary-buffer-map + ;; ("SPC" . (gnus-summary-goto-next-page) + :custom + (gnus-select-method + '(nntp "news.club.cc.cmu.edu" + (nntp-address "news.club.cc.cmu.edu") + (nntp-via-address "news-cclub") + (nntp-via-rlogin-command "ssh") + (nntp-open-connection-function nntp-open-via-rlogin-and-netcat))) + (gnus-home-score-file "gnus.SCORE") + (gnus-secondary-select-methods + '((nntp "news.gmane.io") + (nnimap "imap.rak.ac") + (nnimap "mail.cs.mcgill.ca"))) + (gnus-parameters + '(("^nntp+.*" (address . "rak@rak.ac")) + ("^nnimap+imap\\.rak\\.ac:.*" + (posting-style + (address . "rak@rak.ac") + (gcc "nnimap+imap.rak.ac:Sent"))) + ("^nnimap+mail\\.cs\\.mcgill\\.ca:.*" + (posting-style + (address . "rkavanagh@cs.mcgill.ca") + (gcc "nnimap+mail.cs.mcgill.ca:INBOX.Sent"))))) + (gnus-cloud-method "nnimap:imap.rak.ac") + (gnus-cloud-storage-method 'base64) + (gnus-cloud-synced-files + '("~/.newsrc" "~/.newsrc.eld" (:directory "~/News" :match ".*.SCORE\\'"))) + (gnus-update-message-archive-method t) + (gnus-message-archive-method + '(nnfolder "archive" ; this gets included in the server buffer + (nnfolder-inhibit-expiry t) + (nnfolder-get-new-mail nil) + (nnfolder-active-file "~/News/sent/active") + (nnfolder-directory "~/News/sent"))) + (gnus-check-new-newsgroups nil) + (gnus-group-line-format "%M%S%p%P%5y:%B%(%G%) %z\n") + (gnus-topic-display-empty-topics nil) + (gnus-posting-styles + '((".*" + (signature-file "~/.signature")))) + :hook + (message-send . gnus-score-followup-article) + (gnus-group-mode . gnus-topic-mode)) + +(use-package haskell-mode + :ensure t + :hook ((haskell-mode . turn-on-haskell-doc-mode) + (haskell-mode . turn-on-haskell-indentation))) + +(use-package info-look + :ensure t) + +(use-package ispell + :ensure t + :defer t + :custom + (ispell-dictionary "en_CA-w_accents")) + +(use-package ivy + :ensure t + :diminish + :bind + (("C-c v" . ivy-push-view) + ("C-c V" . ivy-pop-view) + ("C-c C-r" . ivy-resume)) + :custom + (ivy-use-virtual-buffers t) + (ivy-count-format "(%d/%d) ") + :config + (ivy-mode 1)) + +(use-package ivy-bibtex + :ensure t + :bind (("C-c b" . ivy-bibtex))) + +(use-package ivy-hydra + :ensure t) + +(use-package latex + :ensure auctex + :after info-look + :mode ("\\.tex\\'" . TeX-latex-mode) + :init + ;; http://www.cs.au.dk/~abizjak/emacs/2016/03/06/latex-fill-paragraph.html + (defun ales/fill-paragraph (&optional P) + "When called with prefix argument call `fill-paragraph'. +Otherwise split the current paragraph into one sentence per line." + (interactive "P") + (if (not P) + (save-excursion + (let ((fill-column 12345678)) ;; relies on dynamic binding + (fill-paragraph) ;; this will not work correctly if the paragraph is + ;; longer than 12345678 characters (in which case the + ;; file must be at least 12MB long. This is unlikely.) + (let ((end (save-excursion + (forward-paragraph 1) + (backward-sentence) + (point-marker)))) ;; remember where to stop + (beginning-of-line) + (while (progn (forward-sentence) + (<= (point) (marker-position end))) + (just-one-space) ;; leaves only one space, point is after it + (delete-char -1) ;; delete the space + (newline) ;; and insert a newline + (LaTeX-indent-line) ;; I only use this in combination with late, so this makes sense + )))) + ;; otherwise do ordinary fill paragraph + (fill-paragraph P))) + :hook + ((LaTeX-mode . turn-on-reftex) + (LaTeX-mode . turn-off-auto-fill) + (LaTeX-mode . turn-on-flyspell) + (LaTeX-mode . LaTeX-math-mode) + (LaTeX-mode . (lambda () (set (make-local-variable 'TeX-electric-math) + (cons "\\(" "\\)")))) + (LaTeX-mode . (lambda () + (LaTeX-add-environments + '("axiom" LaTeX-env-label) + '("theorem" LaTeX-env-label) + '("proposition" LaTeX-env-label) + '("definition" LaTeX-env-label) + '("corollary" LaTeX-env-label) + '("lemma" LaTeX-env-label) + '("example" LaTeX-env-label) + '("conjecture" LaTeX-env-label) + '("figure" LaTeX-env-label)))) + (LaTeX-mode . (lambda () + ;; This must be a hook. Trying to set it in :config + ;; causes the variable to become buffer-local, so + ;; it never actually takes effect in all + ;; latex-moded buffers. So much time wasted debugging. + (add-to-list 'LaTeX-label-alist '("axiom" . "ax:")) + (add-to-list 'LaTeX-label-alist '("conjecture" . "conj:")) + (add-to-list 'LaTeX-label-alist '("corollary" . "cor:")) + (add-to-list 'LaTeX-label-alist '("definition" . "def:")) + (add-to-list 'LaTeX-label-alist '("proposition" . "prop:")) + (add-to-list 'LaTeX-label-alist '("theorem" . "theorem:")) + (add-to-list 'LaTeX-label-alist '("example" . "ex:")) + (add-to-list 'LaTeX-label-alist '("lemma" . "lemma:")) + (add-to-list 'LaTeX-label-alist '("figure" . "fig:"))))) + :config + (info-lookup-add-help :mode 'LaTeX-mode + :regexp ".*" + :parse-rule "\\\\?[a-zA-Z]+\\|\\\\[^a-zA-Z]" + :doc-spec '(("(latex2e)Concept Index") + ("(latex2e)Command Index"))) + :bind + (:map LaTeX-mode-map + ("M-q" . ales/fill-paragraph))) + +(use-package libmpdel + ;; used by mpdel to connect to mpd + :custom + (libmpdel-hostname "asteria.home.arpa")) + +(use-package magit + :ensure t + :config + (put 'magit-clean 'disabled nil) + :custom + (magit-diff-refine-hunk 'all)) + +(use-package markdown-mode + :ensure t + :init + (autoload 'markdown-mode "markdown-mode" + "Major mode for editing Markdown files" t) + :hook ((markdown-mode . (lambda () + (setq-default indent-tabs-mode nil) + (setq-default whitespace-style nil)))) + :mode (("\\.markdown\\'" . markdown-mode) + ("\\.mdown\'" . markdown-mode))) + +(use-package menu-bar + :config + (menu-bar-mode -1) + :bind + ([S-f10] . menu-bar-mode)) + +(use-package merlin + ;; ocaml assistant + :ensure t) + +(use-package message + :config + (defun message-whitespace-cleanup () + "Clean whitespace in message-mode + + Runs whitespace-cleanup on a message body and signature, + while also preserving the space at the end of the '-- ' + delimiter between body and signature. + + This function is dumb and implicitly assumes the existence + of a delimiter." + (interactive) + (save-excursion + (save-restriction + (widen) + (let ((body-min + (progn + (message-goto-body) + (point))) + (body-max + (progn + (message-goto-signature) + (previous-line) + (point))) + (signature-min + (progn + (message-goto-signature) + (point))) + (whitespace-style '(trailing))) + (progn + (narrow-to-region body-min body-max) + (whitespace-cleanup) + (widen) + (narrow-to-region signature-min (point-max)) + (whitespace-cleanup)))))) + :hook + ((message-mode . (lambda () (remove-hook 'before-save-hook 'whitespace-cleanup t))) + (message-mode . (lambda () (add-hook 'before-save-hook 'message-whitespace-cleanup nil t)))) + :custom + (message-citation-line-function 'message-insert-formatted-citation-line) + (message-send-mail-function 'message-send-mail-with-sendmail)) + +(use-package mingus + ;; mpd client + :custom + (mingus-mpd-host "asteria.home.arpa")) + +(use-package minibuffer + :config + (add-to-list 'completion-styles 'substring) + :custom + ;; Cycle through tab-completions with tab if there are less than 5 + (completion-cycle-threshold 5)) + +(use-package mpc + ;; mpd client + :custom + (mpc-host "asteria.home.arpa")) + +(use-package mpdel + ;; mpd client + ;; host/port customization under libmpdel package + :ensure t + :diminish + :config + (mpdel-mode)) + +(use-package ocp-indent + :ensure t) + +(use-package octave + :mode ("\\.m\'" . octave-mode)) + +(use-package org + :bind (:map org-mode-map + ("" . org-cycle)) + :hook + (org-mode . visual-line-mode) + :custom + (org-link-file-path-type 'relative)) + +(use-package org-chef + :ensure t) + +(use-package org-noter + :ensure t + :custom + ;; Surely there's an easier way of setting this? + (org-noter-notes-search-path '("~/Documents/papers/notes/"))) + +(use-package org-ref + :ensure t + :after ivy-bibtex) + +(use-package org-ref-arxiv + :ensure org-ref + :custom + (arxiv-entry-format-string "@Misc{%s, +title = {%s}, +author = {%s}, +eprinttype = {arxiv}, +date = {%s}, +eprint = {%s}, +eprintclass = {%s}, +abstract = {%s}, +pagetotal = {MISSING}, +_checked = {NOT CHECKED}, +_source = {ev}, +}") + ;; redefine it to use a sensible date and stuff. + ;; my version of arxiv-get-bibtex-entry-via-arxiv-api + :config + (defun my/arxiv-get-bibtex-entry-via-arxiv-api (arxiv-number) + "Retrieve meta data for ARXIV-NUMBER. +Returns a formatted BibTeX entry." + (with-current-buffer + (url-retrieve-synchronously (format "http://export.arxiv.org/api/query?id_list=%s" arxiv-number) t) + (let* ((parse-tree (libxml-parse-xml-region + (progn (goto-char 0) + (search-forward "