Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
955 lines (785 sloc) 35 KB

My Emacs config

This is a literate configuration for Emacs. So even though this looks like a document explaining why I configured things a certain way, believe it or not, it actually is my config.

Feel free to take whatever you like! There are some neat little tricks and workarounds in here that might be useful to you person-who-is-reading this..!

This file changes over time, and new tricks are added occasionally. And if this file is able to help more than just myself, that’s kinda awesome.

Header

In the header of the config… We want the file to include lexical binding:

;; -*- lexical-binding: t -*-

This is used later for let closures.

Also, I include this library to give me some of the functions I like from Common Lisp:

;; For other Common Lisp-ish stuff in here
(require 'cl-lib)

Setting up the package manager

First, we want to require TLS…

;; SSL Support
(require 'tls)

The package manager in Emacs is pretty sweet, but the default repos are quite limited in their selection of packages… So instead, I add a couple more repos. (I am sure almost everyone has this in their configuration somewhere)

;; Package Manager URLs
(setq package-archives
  (cl-flet ((get-scheme (path) (concat (if (gnutls-available-p) "https://" "http://") path)))
    `(("gnu" . ,(get-scheme "elpa.gnu.org/packages/"))
      ("melpa" . ,(get-scheme "melpa.org/packages/"))
      ("org" . ,(get-scheme "orgmode.org/elpa/")))))

And then we initialize the package manager and use-package:

(package-initialize)

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

I also use quelpa to install packages that aren’t in the repos by default using git:

(use-package quelpa-use-package
  :ensure t
  :custom (quelpa-checkout-melpa-p nil))

I don’t even really care about the melpa updating stuff, so I disable that in here… (It seems it doesn’t respect setting that in customize-variable before it is loaded for some reason)

Convenience functions

Sometimes, its nice to have a few functions to make my configuration easier and more modular… That is the purpose of this section.

Path file checker

This is a function I wrote to check to see if there is any file in the current path that matches the passed in filename… The purpose behind this was to be able to check if there are binaries that Emacs can use for particular functionality… (Like Tern for example; I would only want to enable its functionality if a ”tern” binary existed somewhere on the system):

(defun exec-exists-p (filename)
  "Checks to see if Emacs can see a file in the execution path.

Returns \"t\" if the passed in filename exists in any of the
executable search directories (\"exec-path\"). Returns \"nil\"
otherwise."
  (cl-reduce (lambda (exists dir)
               (or exists (file-exists-p (concat dir "/" filename))))
             exec-path :initial-value nil))

Style options

I don’t care too much for the default appearance of Emacs… I generally like to remove the toolbar at the top of the screen:

;; Remove unsightly toolbar...
(tool-bar-mode 0)

As for in-depth styling, I have my own set of basic default faces:

(setq archenoth-faces
      (if (boundp 'archenoth-theme)
          archenoth-theme
        '((fringe ((t (:background "#111" :width expanded))))
          (linum ((t (:inherit (shadow default) :background "#111" :foreground "#e0e0e0"))) t)
          (pe/directory-face ((t (:inherit dired-directory :weight normal :height 0.9))) t)
          (pe/file-face ((t (:inherit default :background "#111" :weight normal :height 0.9))) t))))

This essentially is just a minimal set of sane defaults, though if the variable archenoth-theme is set, those faces will be used instead of the default.

The defaults do work reasonably well I think, though the way I have this final font setup in my .emacs

(add-to-list 'default-frame-alist
             '(font . "-unknown-M+ 1m-light-normal-normal-*-*-98-*-*-d-0-iso10646-1"))

This is not a part of the tangled code because it requires this awesome font. (Though I like to have it here for reference)

The following is the definition for the function that will handle the logic for switching from windowed to fullscreen (Mostly just small interface tweaks):

(defun set-fullscreen-settings ()
  "Sets the default theme I use for maximixed Emacs"
  (interactive)
  (set-face-attribute 'default (selected-frame) :height 113)
  (fringe-mode '(20 . 0))
  (scroll-bar-mode -1)
  (menu-bar-mode -1))

Now for windowed!

Since switching to windowed mode has some strange results with frame sizing, here is a function that can restore the size back to the normal windowed state:

(defun set-default-window-size ()
  "Sets the default window size..."
  (interactive)
  (modify-frame-parameters
   (selected-frame)
   '((width . 80) (height . 34))))

And now, here is the function that gets called to handle switching from fullscreen to windowed:

(defun set-window-settings ()
  "Sets the default theme I use for Windowed Emacs"
  (interactive)
  (set-face-attribute 'default (selected-frame) :height 98)
  (fringe-mode '(8 . 0))
  (scroll-bar-mode 1)
  (menu-bar-mode 1)
  (set-default-window-size))

Spifftastic! Now time to put it all together…

The actual style logic

What we want here is something that allows me to toggle between two style configurations, one for fullscreen mode, the other for windowed with the [F11] key.

For the toggling logic, we create this function:

(defun toggle-fullscreen ()
  "Toggles fullscreen emacs"
  (interactive)
  (if is-fullscreen
      (progn
        (set-frame-parameter nil 'fullscreen nil)
        (setq is-fullscreen nil)
        (set-window-settings))
    (progn
      (set-frame-parameter nil 'fullscreen 'fullboth)
      (setq is-fullscreen t)
      (set-fullscreen-settings))))

I also want a piece of advice for display-buffer to prefer to not create new windows when in fullscreen mode.

It will, when the is-fullscreen variable is set, make sure the action parameter is not set to ”t” when calling display-buffer, because that will pop up a new window:

(defun my-display-buffer (args)
  (cl-destructuring-bind (buffer-or-name &optional action frame) args
    (let ((action (unless (and is-fullscreen (null frame)
                               (or (eq action t) (eq action 'other-window)))
                    action)))
      (list buffer-or-name action frame))))

(advice-add 'display-buffer :filter-args #'my-display-buffer)

I also check for other-window explicitly, because some commands like compile-goto-error open new windows regardless of other settings by passing this value directly into display-buffer. This is really annoying when, for example, you are trying to grep a project, you click on a result, and it pops up as new window in your otherwise-fullscreen environment.

This, of course, doesn’t stop explicit actions from creating new windows, but it deters a lot of the defaults that drive me up the wall.

Now, of course, here is the use-package declarations for the Firecode theme which glues all of this together if there is a window system to work with.

(use-package firecode-theme
  :if window-system
  :ensure t

  :init
  (load-theme 'firecode t)
  (apply #'custom-set-faces archenoth-faces)
  (set-window-settings)

  (let ((is-fullscreen nil))
    <<toggle-fullscreen>>
    <<display-buffer-advice>>)

  :bind ("<f11>" . toggle-fullscreen))

And of course, Powerline is nice!

(use-package powerline
  :if window-system
  :ensure t
  :config (powerline-center-theme))

Languages

The following are package-loaded language support configurations:

Language agnostic

This section is all about the setup that is about programming, but not for a particular language.

Flymake

Of course, there are a few modes that I like to have Flymake. enabled on by default…

;; Flymake

Of those, we have perl-mode:

(add-hook 'perl-mode-hook (lambda () (flymake-mode t)))

And php-mode:

(use-package php-mode
  :ensure t
  :hook ((php-mode . flymake-mode)))

Autocomplete

Autocomplete is magnificent. I will have it enabled for almost every programming mode in existence.

(ac-config-default)

Company

A few packages use Company, but it’s not really my main autocomplete mode:

(use-package company :ensure t)

Compile

I generally like having a compile command as [F5]:

(define-key global-map (kbd "<f5>") 'compile)

No, compiling is not always relevant to all languages, but it doubles as a quick command-line, which is almost always useful.

Yasnippet

Snippets are great! Lots of things use them!

(use-package yasnippet :ensure t)

Apache configuration

Since I work with Apache2 servers a bunch, it’s worth it to have an Emacs mode that can handle them:

(use-package apache-mode :ensure t)

Bash

A neat little trick when editing shell scripts is to add the function executable-make-buffer-file-executable-if-script-p to the after-save-hook.

;; Shell scripting
(add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)

What this does it is means when creating or editing scripts, you don’t need to chmod +x it. Emacs will detect it as a script automagically, and do that for you.

C and C++

Emacs’ Semantic mode is really good at C… I have not tested it extensively with C++ though.

But with it, we get definition jumping and some quite intelligent autocomplete… So I simply define the jumping keybinding, the autocomplete sources, and add it to both C and C++ modes as hooks:

;; C and C++
(defun c-modes-hook ()
  (semantic-mode)
  (local-set-key (kbd "<f3>") #'semantic-ia-fast-jump)
  (semantic-idle-summary-mode 1)
  (setq ac-sources '(ac-source-semantic-raw
             ac-source-yasnippet)))
(add-hook 'c-mode-hook 'c-modes-hook)
(add-hook 'c++-mode-hook 'c-modes-hook)

Clojure

For Clojure, I turn on eldoc-mode and setup Autocomplete with ac-cider:

;; CIDER, Clojure
(use-package ac-cider
  :ensure t
  :bind (("<f3>" . cider-find-var))
  :hook ((cider-mode . eldoc-mode)
         (cider-mode . ac-cider-setup)
         (cider-repl-mode-hook . eldoc-mode)))

Common Lisp

The Common Lisp setup is largely just setting up Sly and Sly’s autocomplete source.

;; Common Lisp
(use-package sly
  :ensure ac-sly
  :config
  (defun sly-ac-hook ()
    (add-to-list 'ac-modes 'sly-mrepl-mode))

  :hook ((sly-mode . set-up-sly-ac)
         (sly-mrepl . set-up-sly-ac)
         (sly-mode . sly-ac-hook)))

Nothing really special here.

Dot

Sometimes I like to look at Graphviz dot files, and maybe write them?

(use-package graphviz-dot-mode :ensure t)

ELISP

;; ELISP

My ELISP configuration is largely just setting up erefactor and then adding it to the three ELISP modes.

So first I require the package:

(use-package erefactor
  :ensure t
  :hook ((emacs-lisp-mode lisp-interaction-mode ielm-mode) . erefactor-lazy-highlight-turn-on)
  :bind (:map emacs-lisp-mode-map ("<f3>" . find-function-at-point))
  :bind-keymap ("C-c C-v" . erefactor-map))

Then I define a hook that turns on erefactor’s scope highlighting, eldoc-mode, and defines a key for to start refactoring:

;; Hook for all ELISP modes
(defun el-hook ()
  (define-key emacs-lisp-mode-map "\C-c\C-v" erefactor-map)
  (erefactor-lazy-highlight-turn-on)
  (define-key emacs-lisp-mode-map (kbd "<f3>") 'find-function-at-point)
  (eldoc-mode t))

Then I simply assign the function as a hook for all of the ELISP modes:

;; And assigning to said modes
(add-hook 'emacs-lisp-mode-hook 'el-hook)
(add-hook 'lisp-interaction-mode-hook 'el-hook)
(add-hook 'ielm-mode-hook 'el-hook)

Feature

;; Feature mode

Since I work with Cucumber feature files reasonably often, of course I’d need a mode to edit and run tests from:

(use-package feature-mode
  :ensure t
  :mode "\\.feature$"
  :bind (:map feature-mode-map
              ("C-c C-c" . feature-verify-scenario-at-pos)
              ("C-c C-k" . feature-verify-all-scenarios-in-buffer)
              ("<f5>" . feature-verify-all-scenarios-in-project)))

I also find it useful to be able to jump right to the definition of some Cucumber step I am looking at. I also like Slime’s evaluation bindings, so I emulate those here:

(use-package cucumber-goto-step
  :ensure t
  :bind (:map feature-mode-map
              ("<f3>" . jump-to-cucumber-step)))

HTML, JSP, PHP, and so on…

For most markup-centric web development, I start up web-mode:

  ;; Web Mode for HTML, JSPs, etc...
(use-package web-mode
  :ensure t
  :after yasnippet

  :mode
  (("\\.[sj]?html?\\'" . web-mode)
   ("\\.jsp\\'" . web-mode)
   ("\\.phtml$" . web-mode)
   ("\\.php[34]?\\'" . web-mode)
   ("\\.erb$" . web-mode)
   ("\\.ejs$" . web-mode))

  :init
  (setq web-mode-engines-alist '(("jsp" . "\\.tag\\'")))
  (setq web-mode-html-offset 2)
  (setq web-mode-css-offset 2)
  (setq web-mode-script-offset 2))

For some niceties that let me do things like write blocks of HTML with only CSS selectors, here’s Emmet!

(use-package emmet-mode
  :ensure t
  :after web-mode
  :init (setq emmet-indentation 2)
  :hook
  ((web-mode . emmet-mode)))

And with Emmet enabled, I can also add some more niceties, like autocomplete for its snippets:

(use-package ac-emmet
  :ensure t
  :after emmet-mode
  :hook
  ((web-mode . ac-emmet-html-setup)
   (sgml-mode . ac-emmet-html-setup)
   (css-mode . ac-emmet-css-setup)))

Java

I don’t do much Java in Emacs, that generally is the job of Eclipse because of its super-intelligent support, integration with everything, and ridiculous debugger capabilities… But when I do… I only have two real tweaks to make:

;; Java
(add-hook 'java-mode-hook
          (lambda ()
            ;; Because Semantic jumping in Java is gnarly
            (local-set-key (kbd "<f3>") #'semantic-ia-fast-jump)
            ;; Because these tend to be a lot longer than 80 width
            ;; and wrapping is ugly.
            (toggle-truncate-lines t)
            ;; Because we like information about local variables.
            (semantic-idle-summary-mode 1)
            ;; Semantic does a good job of parsing Java now, so we
            ;; don't need to rely on words found in the buffers for
            ;; completion anymore.
            (setq ac-sources '(ac-source-semantic-raw
                               ac-source-yasnippet))))

JavaScript

;; JavaScript

The support for JavaScript in Emacs is ridiculous. We have an entire parser in the js2-mode package, which is very well-written.

(use-package js2-mode
  :ensure js2-mode
  :bind (:map js-mode-map ("<f3>" . js2-jump-to-definition))
  :mode "\\.js\\'")

We also possibly have Tern, which gives us even more advanced JavaScript IDE functionality like cross-file references, type inference, and lots of other neat things… But it requires an external executable. That means we need to check to see if it is set up on this system. Either way, we will want to act accordingly:

(defvar *tern-exists* (and tern-enabled (exec-exists-p "tern"))
  "Whether or not we can use Tern on this system. Set to \"t\"
  when we can, or \"nil\" when we can't.")

There is also great autocomplete support with ac-js2… And that allows for scope-intelligent jumping to definitions… I still want js2’s autocomplete for local variables because IMO it is superior to Tern, but having two jumping bindings is redundant, so I disable this one if we have Tern (By overriding it below):

(use-package ac-js2
  :ensure t
  :after js2-mode
  :hook ((js2-mode . ac-js2-mode)))

Now, using *tern-exists* from above, we will pick between using the tern or js2-refactor packages:

(if *tern-exists*
    <<package-tern>>
    <<package-js2-refactor>>)

Of course, if Tern does not exist, we can install it with the following (Assuming we have npm):

npm install -g tern

If Tern is enabled, our config looks like this:

(use-package tern
  :ensure tern-auto-complete
  :after js2-mode
  :config
  (defun tern-hook ()
    (setq-local ac-sources nil))

  :hook ((js2-mode . tern-hook)
         (js2-mode . tern-mode)
         (js2-mode . tern-ac-setup))

  :bind (:map js-mode-map
              ("M-R" . tern-rename-variable)
              ("<f3>" . tern-find-definition)))

Now, if Tern does not exist, we js2’s parser for things like js2-refactor, which allows for advanced automatic refactoring such as renaming variables and extracting code blocks with intelligent attention to scope (But it’s only local to the current file as of the time of writing):

(use-package js2-refactor
  :ensure t
  :after js2-mode
  :bind (:map js-mode-map ("M-R" . js2r-rename-var))
  :hook ((js2-mode . js2-refactor-mode)))

Lua

I sometimes write in Lua. Nothing overly special here:

(use-package lua-mode :ensure t)

Markdown mode

;; Markdown

As of the time of writing, I don’t think markdown mode has it set automagically start for files with the .md file extension, so:

(use-package markdown-mode
  :ensure markdown-mode+
  :mode "\\.md$")

nginx Configuration

I work with nginx configurations every now and then so:

(use-package nginx-mode :ensure t)

Python

I don’t really write Python, but for the times I do, Jedi is neat:

;; Jedi, for Python sweetness
(use-package jedi
  :ensure t
  :init (setq jedi:complete-on-dot t)
  :hook ((python-mode . jedi:ac-setup)))

Pico-8

Pico-8 is a neat little fantasy console, and someone wrote a pretty nice mode for it!

(use-package pico8-mode
  :after (company quelpa-use-package)
  :bind ("<f3>" . xref-find-definitions)
  :hook ((pico8-mode . company-mode))
  :quelpa ((pico8-mode :fetcher github :repo "Kaali/pico8-mode")))

Ruby

;; Ruby support

The default Ruby mode in Emacs is pretty good, partially because it was written by Matz himself. But there is still room for improvement. Notably, adding some kind of on-the-fly syntax checking can make things just lovely:

(use-package flymake-ruby
  :ensure t
  :hook ((ruby-mode . flymake-ruby-load)))

And, if we want to get completions from a Ruby REPL, we can get some extra support with Robe:

(use-package robe
  :ensure t
  :hook ((ruby-mode . robe-mode)))

Rust

;; Rust support

Rust is a pretty neat language. Racer is a pretty neat mode. Lets combine these a bit and get some autocomplete support while we’re at it

(add-hook 'rust-mode-hook #'flycheck-mode)
(add-hook 'rust-mode-hook #'racer-mode)
(add-hook 'racer-mode-hook #'eldoc-mode)
(add-hook 'racer-mode-hook #'ac-racer-setup)
(add-hook 'racer-mode-hook #'flycheck-rust-setup)

And to make auto-complete a little less annoying:

(add-hook 'racer-mode-hook
          (lambda ()
            (setq ac-sources '(ac-source-racer))
            (setq ac-auto-start nil)
            (setq ac-trigger-key "TAB")))

SQL

Emacs seems to fail at escaping backslashes in SQL files… So I have slightly modified the syntax entry for the backslash character in SQL files so it acts like a proper escape:

;; SQL, fix buffer escaping
(add-hook 'sql-mode-hook
          (lambda ()
            (modify-syntax-entry ?\\ "\\" sql-mode-syntax-table)))

Utility

The following are things that are nice to have set up during normal Emacs usage, but aren’t for any type of task in particular.

XWidget browser

Emacs now has a WebKit-based browser embedded in it with XWidget. This is cool and all, but its defaults are pretty much unusable, so here is my configuration to make it act like a slightly-reasonable browser:

First I define two functions, since [Home] and [End] functionality is sorely lacking. It just scrolls the browser itself out of view and doesn’t scroll. The alternative is to scroll a few pixels at a time until you are at the bottom. Annoying.

So:

(defun xwidget-webkit-scroll-top ()
  "Scroll webkit to the top of the page."
  (interactive)
  (xwidget-set-adjustment (xwidget-webkit-last-session) 'vertical nil 0))
(defun xwidget-webkit-scroll-bottom ()
  "Scroll webkit to the bottom of the page."
  (interactive)
  (xwidget-webkit-execute-script
   (xwidget-webkit-current-session)
   "window.scrollTo(0, document.body.scrollHeight);"))

This part is to define a bunch of keys to make the browser actually-usable. The following was largely stolen from this Reddit post, with a few modifications to add my own functions above:

;; Add usable keybindings whenever we try to use the XWidget browser
(add-hook
 'xwidget-webkit-mode-hook
 (lambda ()
   (define-key xwidget-webkit-mode-map [mouse-4] 'xwidget-webkit-scroll-down)
   (define-key xwidget-webkit-mode-map [mouse-5] 'xwidget-webkit-scroll-up)
   (define-key xwidget-webkit-mode-map (kbd "<up>") 'xwidget-webkit-scroll-down)
   (define-key xwidget-webkit-mode-map (kbd "<down>") 'xwidget-webkit-scroll-up)
   (define-key xwidget-webkit-mode-map (kbd "M-w") 'xwidget-webkit-copy-selection-as-kill)
   (define-key xwidget-webkit-mode-map (kbd "C-c") 'xwidget-webkit-copy-selection-as-kill)
   (define-key xwidget-webkit-mode-map (kbd "<home>") 'xwidget-webkit-scroll-top)
   (define-key xwidget-webkit-mode-map (kbd "<end>") 'xwidget-webkit-scroll-bottom)))

;; Whenever the window changes size and we are in the XWidget browser,
;; we will want to resize it.
(add-hook
 'window-configuration-change-hook
 (lambda ()
   (when (equal major-mode 'xwidget-webkit-mode)
     (xwidget-webkit-adjust-size-dispatch))))

Evil

I find that one of the first things I do when I start Emacs recently is start Evil… I may as well just put it in my config.

(use-package evil
  :ensure t
  :config (evil-mode 1))

Sauron

;; Supremely useful monitor -- Sauron

The all-seeing eye, Sauron is quite useful, though I want to add some functionality to the modeline with it, so I make higher-priority messages set a variable: sauron-alert:

(add-hook 'sauron-event-added-functions
          (lambda (what priority message &optional event)
            (when (<= 4 priority)
              (setq sauron-alert t))))

The above means you can do something like the following:

(when (boundp 'sauron-alert)
  "Code goes here for when Suaron sees something, yo.")

And of course, to set it back to nothingness:

(makunbound 'sauron-alert)

I actually use this in the modeline and have the modeline use the following function to generate a spooky eye that notifies me if Sauron has seen something of interest with clickable text to bring me to the Sauron buffer:

(defun make-sauron-text ()
  "Creates a clickable Sauron text that switches to the Sauron
buffer."
  (let ((map (make-keymap)))
    (define-key map [follow-link]
      (lambda (pos)
        (makunbound 'sauron-alert)
        (switch-to-buffer "*Sauron*" nil t)))
    (propertize " 0"
                'keymap map
                'face 'compilation-error
                'help-echo "Sauron has seen something"
                'pointer 'hand)))

And because I get notified of high-priority events normally with the above, I have no need for Sauron to be its own frame:

(setq sauron-separate-frame nil)

Expand Region

Expand Region is a very handy package for selecting arbitrary blocks of text, be it code or whatever.

;; Expand region
(use-package expand-region
  :ensure t
  :bind (("s-SPC" . er/expand-region)
         ("s-S-SPC" . er/contract-region)))

Multiple Cursors

From the famous Emacs Rocks video where it was introduced to the masses, my configuration for this super-handy mode is as follows (Just keybindings):

;; Multiple-cursors
(use-package multiple-cursors
  :ensure t
  :bind (("s-s" . mc/mark-next-like-this)
         ("C-s-s" . mc/mark-all-like-this)
         ("M-s-s" . mc/mark-next-symbol-like-this)
         ("s-S" . mc/mark-sgml-tag-pair)))

Projectile

Another really handy usability mode: Projectile!

I use Projectile with Helm to browse to files in the current project really fast:

(use-package helm-projectile :ensure t)

I use it exclusively with grizzl though, so:

(use-package grizzl :ensure t)

So, with all of this in play, here is my projectile config:

(use-package projectile
  :ensure t
  :after (grizzl helm-projectile)

  :init
  (setq projectile-enable-caching t)
  (setq projectile-completion-system 'grizzl)
  (projectile-global-mode)

  :bind (("C-M-f" . helm-projectile)))

Avy

Avy is a re-imagining of ace-jump-mode, which allows for very fast jumping around a buffer.

It is very handy for navigation regardless of mode, so:

(use-package avy
  :ensure t
  :after evil

  :bind (("s-/" . avy-goto-subword-1)
         ("s-?" . avy-goto-char)
         :map evil-motion-state-map
         ("p" . avy-goto-subword-1)
         ("P" . avy-goto-char)))

Show parenthesis mode

To my knowledge, there is not a single mode where this minor mode isn’t helpful or mildly amusing.

(show-paren-mode)

Pretty-print ^L characters

By default, Emacs uses the control character ^L pretty often and prints it as a control character in buffers.

I find this to be ugly, so instead, I install pretty-control-l-mode so I can make it look nice.

(use-package pp-c-l
  :ensure t
  :config (pretty-control-l-mode 1))

Magit

I don’t need to make any modifications to Magit, despite the fact that I use it quite regularly:

(use-package magit :ensure t)

Org Mode

Org mode deserves a section for itself because it is just that important.

My Org mode setup includes support for spell checking, grammar checking, tangling source files from Org mode, visual-line-mode, and syntax coloring:

;; Org mode
(use-package org-mode
  :ensure org-plus-contrib

  :init
  (setq-default indent-tabs-mode nil)
  (setq org-src-fontify-natively t)
  (setq org-export-latex-listings 'minted)

  :config
  (require 'org-install)
  (require 'ob-tangle)

  :hook ((org-mode . flyspell-mode)
         (org-mode . visual-line-mode)))

The grammar checking is done with langtool, and isn’t even really required, so no :ensure here:

(use-package langtool)

Nothing too crazy, because most of Org’s default configuration is pretty sweet.

As for evaluation, especially evaluation with images, It kinda annoys me that I have to re-run org-redisplay-inline-images whenever I eval a code block that spits out an image, so I stole this snippet to fix it:

(add-hook 'org-babel-after-execute-hook 'org-redisplay-inline-images)
;; Global org-mode bindings
(global-set-key (kbd "C-c a") 'org-agenda)
(global-set-key (kbd "C-c l") 'org-store-link)
(global-set-key (kbd "C-c n") 'org-capture)

I did, however, bind a few global Org-mode commands, things that can be useful anywhere…

Variables

;;;; Variables

There are some variables that I want to setq because I don’t want to have to customize them from their defaults.

Lock Files

I really don’t like Emacs lockfiles… They are annoying and mess up an otherwise clean folder:

(setq create-lockfiles nil) ;; Nasty at times

Tabs vs Spaces: The endless war

I am on the spaces side, because tab width screws up formatting hardcore on things like Github if you want to do granular spacing and their tabs are different from yours:

(setq-default indent-tabs-mode nil) ;; Screws up in other editors and Github

Come at me bro.

Auto-backup config

Stolen from here… Very useful to have backup files not mess up the current folder, and yet still exist:

;; Auto-backups
(setq backup-by-copying t      ; don't clobber symlinks
      backup-directory-alist
      '(("." . "~/.saves"))    ; don't litter my fs tree
      delete-old-versions t
      kept-new-versions 6
      kept-old-versions 2
      version-control t)       ; use versioned backups
(setq backup-directory-alist `((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms `((".*" ,temporary-file-directory t)))

Aliases

Aliases to replace one piece of functionality with another is super-handy.

Yes and No questions

Having to type “yes” is annoying when I just want to do something simple… So, I alias yes-or-no-p to the single-keystroke equivalent:

;; Make boolean questions less annoying
(defalias 'yes-or-no-p 'y-or-n-p)

Hooks

Hooks! A few small tweaks to suit my work style.

;;;; Hooks

Whitespace begone!

First of all, I dislike having messy whitespace in the files I am working with, so I am sure to delete trailing whitespace whenever I save a file… (This might become a problem sometime down the line, but so far everything is good.)

(add-hook 'before-save-hook 'delete-trailing-whitespace)

Bindings

;;;; Non-specific bindings

This is a section for key and event bindings that don’t fit anywhere else.

USR1 signal

When I am running Emacs, I don’t always think about starting a server of it, because I simply don’t need it… But what happens if something terrible happens to my desktop manager and Emacs is still intact? I can’t do a lot with it…

That is why I am going to make kill -USR1 $(pidof emacs) start an Emacs server.

(define-key special-event-map (kbd "<sigusr1>") 'server-start)

Metadata