#+TITLE: Emacs Configuration #+AUTHOR: Camden Dixie O'Brien #+ATTR_LATEX: :float t Shout out to Harry R. Schwartz; A whole bunch of this config (including the idea of embeddeding the lot in an Org document) is yanked from [[https://github.com/hrs/dotfiles][his dotfiles repo]]. The rest of this config grabs packages via =use-package=, so that needs to be set up to install them if they aren't already. #+begin_src emacs-lisp (require 'use-package-ensure) (setq use-package-always-ensure t) #+end_src * UI The start-up message gets pretty annoying, so disable that. #+begin_src emacs-lisp (setq inhibit-startup-screen t) #+end_src I like a little more line spacing than default. #+begin_src emacs-lisp (setq-default line-spacing 0.2) #+end_src Also, the menu-, tool- and scroll-bar are ugly, take up space and I don't use them. #+begin_src emacs-lisp (menu-bar-mode -1) (tool-bar-mode -1) (scroll-bar-mode -1) #+end_src ** Colour Scheme Currently using =spacemacs-theme='s light variant, but I prefer a pure white background to the off-white it has by default. #+begin_src emacs-lisp (use-package spacemacs-theme :defer t) (setq spacemacs-theme-custom-colors '((bg1 . "#ffffff") (comment-bg . "#ffffff"))) (load-theme 'spacemacs-light t) #+end_src * Org-mode I use a couple non-standard bits and pieces, but not a whole bunch. I really like the =") 'org-insert-heading-after-current))) #+end_src ** Source Blocks Pressing tab inside a source block should indent appropriately for its language. #+begin_src emacs-lisp (setq org-src-tab-acts-natively t) #+end_src =babel= lets us evaluate Org documents containing source blocks! I've left the enabling of this for most languages to the section for that language, but I'll add Emacs Lisp and shell here. #+begin_src emacs-lisp (org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t) (shell . t))) #+end_src By default trying to execute a source block prompts you, which is super annoying since I'm realistically not going to try to run any code from Org documents I haven't written, so that needs disabling. You can do that by setting [[help:org-confirm-babel-evaluate][org-confirm-babel-evaluate]] to =nil=. #+begin_src emacs-lisp (setq org-confirm-babel-evaluate nil) #+end_src Another annoying thing that happens by default is the clobbering of the window layout when you open a source block. You can change that by setting [[help:org-src-window-setup][org-src-window-setup]]. #+begin_src emacs-lisp (setq org-src-window-setup 'split-window-below) #+end_src ** Exporting I very rarely want a table of contents, as most of my org documents are pretty short. #+begin_src emacs-lisp (setq org-export-with-toc nil) #+end_src *** HTML =htmlize= is needed for decent HTML exporting, but there is no need for all that stuff at the bottom. #+begin_src emacs-lisp (use-package htmlize) (setq org-html-postamble nil) #+end_src *** LaTeX Use =minted= (LaTeX package) to do syntax highlighting in code blocks: #+begin_src emacs-lisp (add-to-list 'org-latex-packages-alist '("" "minted")) (setq org-latex-listings 'minted) #+end_src =minted= actually calls =pygments= through the shell, which =pdflatex= doesn't like; you have to tell it not to worry, and that everything is going to be OK. #+begin_src emacs-lisp (setq org-latex-pdf-process '("xelatex -shell-escape -interaction nonstopmode -output-directory %o %f" "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f" "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f")) #+end_src Also, I don't like Emacs' built-in PDF viewer, so open PDFs in Evince instead: #+begin_src emacs-lisp (eval-after-load "org" '(progn (setcdr (assoc "\\.pdf\\'" org-file-apps) "evince %s"))) #+end_src * Start up Org is better suited as scratch space than Funamental, I'd say. #+begin_src emacs-lisp (setq initial-major-mode 'org-mode) (setq initial-scratch-message "") #+end_src * Magit =magit= is truly a wonderful creation! Only deviations from defaults here are a keybinding for =magit-status= and a maximum length for the summary line of commit messages (after which the excess is highlighted). #+begin_src emacs-lisp (use-package magit :bind ("C-x g" . magit-status) :config (setq git-commit-summary-max-length 72)) #+end_src * Language Integrations Generally, 8-character-wide tabs are not my thing. #+begin_src emacs-lisp (setq-default tab-width 4) (setq-default basic-offset 4) #+end_src And generally indenting with spaces is more common, so make that the default: #+begin_src emacs-lisp (setq-default indent-tabs-mode nil) #+end_src ** C For C, I like to indent with tabs and align with spaces: this behaviour is provided by =smart-tabs-mode=. #+begin_src emacs-lisp (use-package smart-tabs-mode) (smart-tabs-insinuate 'c) #+end_src I'll generally format my code in BSD style but I also use =clang-format= a lot, so I have a keybinding to run that. #+begin_src emacs-lisp (setq c-default-style "bsd") (use-package clang-format) (add-hook 'c-mode-hook (lambda () (define-key c-mode-map (kbd "C-M-f") 'clang-format-buffer))) #+end_src Meson is my build system of choice for C, but I also use CMake a lot. #+begin_src emacs-lisp (use-package meson-mode) (use-package cmake-mode) #+end_src ** Haskell My workflow with Haskell is very REPL-based, so I always want =interactive-haskell-mode= on. #+begin_src emacs-lisp (use-package haskell-mode) (require 'haskell-interactive-mode) (add-hook 'haskell-mode-hook 'interactive-haskell-mode) #+end_src And, of course, that REPL needs to be taking advantage of parallelism! #+begin_src emacs-lisp (require 'haskell-process) (set-variable 'haskell-process-args-ghci '("-threaded" "+RTS" "-N8" "-RTS")) #+end_src ** Idris The only thing to change from the defaults here is to add a more convenient way to case-split. #+begin_src emacs-lisp (use-package idris-mode) (add-hook 'idris-mode-hook (lambda () (define-key idris-mode-map (kbd "C-c SPC") 'idris-case-split))) #+end_src ** Rust I never really use Rust without Cargo, so always turn on the minor mode for Cargo in Rust buffers. #+begin_src emacs-lisp (use-package rust-mode) (use-package cargo) (add-hook 'rust-mode-hook 'cargo-minor-mode) #+end_src ** Lisps *** Racket Get =racket-mode= for some Racket-specific things, like searching documentation #+begin_src emacs-lisp (use-package racket-mode) #+end_src *** Common Lisp Use SLIME and Quicklisp for Common Lisp (SBCL), with a convenient binding for =slime-selector= #+begin_src emacs-lisp (use-package slime) (setq inferior-lisp-program "sbcl") (global-set-key (kbd "C-c s") 'slime-selector) (load (expand-file-name "~/.quicklisp/slime-helper.el")) #+end_src And we also want to enable execution of CL source blocks in Org mode, which we do by adding an item to [[help:org-babel-load-languages][org-babel-load-languages]]. #+begin_src emacs-lisp (org-babel-do-load-languages 'org-babel-load-languages '((lisp . t))) #+end_src *** Paredit =paredit= is generally very useful for balancing parenthesis so we want that turned on for all the lisps. Additionally, it's nice to have an entire expression highlighted when the cursor is on one of its enclosing parens. #+begin_src emacs-lisp (use-package paredit) (setq lispy-mode-hooks '(emacs-lisp-mode-hook lisp-mode-hook racket-mode-hook scheme-mode-hook)) (dolist (hook lispy-mode-hooks) (add-hook hook (lambda () (setq show-paren-style 'expression) (paredit-mode)))) #+end_src * EXWM One must fulfil the meme of doing everything with Emacs... #+begin_src emacs-lisp (use-package exwm :config (require 'exwm-config) (exwm-config-default)) #+end_src