Alex’s Emacs Configuration
;; -*- lexical-binding: t -*-
Documentation
Introduction
I stole the outline of this from qDot, and then someone else’s init.el
, and then bashed things together until they worked right.
Basic Setup
Variables
Anything in this section relates to the core setup of emacs. Since I’m not using the weird Ouroboric self-tangling
thing qDot was,
we’ve already got use-package
, org
, and cl-lib
loaded.
Prefer UTF-8 everywhere:
(prefer-coding-system 'utf-8) (set-default-coding-systems 'utf-8) (set-language-environment "UTF-8")
Set up some simple platform finding variables.
(defvar linux-p (eq system-type 'gnu/linux) "True if using Linux, nil otherwise") (defvar macosx-p (eq system-type 'darwin) "True if using Mac OS X, nil otherwise") (defvar mswindows-p (eq system-type 'windows-nt) "True if using windows, nil otherwise")
Don’t need startup screens.
(setq inhibit-splash-screen t)
Make the bell blink, but only on non-Mac platforms. I prefer the Mac OS-level vbell.
(unless macosx-p (setq visible-bell t))
Don’t end sentences with a double space. This is important for fill functions.
(setq sentence-end-double-space nil)
Make sure message log is really, really big in case I screw something up.
(setq message-log-max 5000)
Make sure there’s no dialog on platforms that might try to bring one up. https://superuser.com/questions/125569/how-to-fix-emacs-popup-dialogs-on-mac-os-x
(when (or mswindows-p macosx-p) (defadvice y-or-n-p (around prevent-dialog-yorn activate) "Prevent y-or-n-p from activating a dialog" (let ((use-dialog-box nil)) ad-do-it)) (defadvice yes-or-no-p (around prevent-dialog activate) "Prevent yes-or-no-p from activating a dialog" (let ((use-dialog-box nil)) ad-do-it)))
Put autosave files (ie #foo#
) in one place, not scattered all over
the file system.
(defvar alexm/autosave-dir (concat user-emacs-directory "autosaves/")) (make-directory alexm/autosave-dir t) (setq auto-save-file-name-transforms `((".*" ,alexm/autosave-dir t)))
Kill the fuck out of backup files.
(setq make-backup-files nil)
Scroll by up to 20 lines to get point back on screen.
(setq scroll-conservatively 20)
Make sure page up and page down are symmetric, so M-v undoes C-v perfectly.
(setq scroll-preserve-screen-position 'always)
Ensure files end with lines.
(setq require-final-newline t)
I like seeing keystrokes after a bit.
(setq echo-keystrokes 0.5)
I like seeing garbage collection and up the limit a bunch.
(setq garbage-collection-messages t gc-cons-threshold (* 64 1024 1024))
Clean up some bozotic defaults:
(setq-default Custom-buffer-done-kill t backward-delete-char-untabify-method nil case-fold-search t calendar-week-start-day 1 calendar-latitude 56.0 calendar-longitude 2.0 completion-show-help nil default-frame-scroll-bars nil diff-switches "-u" enable-recursive-minibuffers t indent-tabs-mode nil js-indent-level 2 ispell-program-name "aspell" kill-read-only-ok t kill-whole-line t read-quoted-char-radix 16 recenter-positions '(bottom middle) remote-shell-program "/usr/bin/ssh" send-mail-function 'sendmail-send-it vertical-scroll-bar nil whois-server-name "whois.geektools.com" word-wrap t x-select-enable-clipboard t yow-file "~/.emacs.d/yow.lines" ) (when (fboundp 'set-scroll-bar-mode) (set-scroll-bar-mode nil))
Functions
Facefucker
Something to make setting faces easier — this works a lot like custom-set-faces
but doesn’t use that machinery. You can call it with customize
blobs, though.
(defun alexm/set-faces-by-spec (&rest specs) "Maps SPECS through face-spec-set." (mapc #'(lambda (f) (apply #'face-spec-set f)) specs))
Rot13 as Message
Do a rot13, but display it in a message instead of modifying the buffer.
(defun alexm/rot13-region (start end) "Display the ROT13 encryption of the region between START and END in current buffer." (interactive "r") (display-message-or-buffer (rot13 (filter-buffer-substring start end))))
Timestamp Utilities
Define a macro because there’s three time-formatting functions coming up.
These are, eventually, bound all the way down there.
(defmacro alexm/defstamper (name format) `(defun ,name (arg) (interactive "P") (let ((stamp (format-time-string ,format nil t))) (if arg (kill-new stamp) (insert stamp)))))
Kill, or with a prefix argument, insert, the current timestamp in modified ISO8601.
(alexm/defstamper alexm/stamp-m8601 "%Y.%m.%d..%H.%M.%S")
Kill, or with a prefix argument, insert, the current datestamp in modified ISO8601.
(alexm/defstamper alexm/stamp-m8601-date "%Y.%m.%d")
Kill, or with a prefix argument, insert, the current datestamp in RFC-2822 format.
(alexm/defstamper alexm/stamp-rfc2822 "%a, %d %b %Y %T %z")
(defun alexm/restore-text-scale nil "Return text size to normal" (interactive) (text-scale-increase 0))
Text cleansers
(defun alexm/clean-up-mesos-stacktraces nil "Make a Mesos stack-trace readable. Intended to be invoked immediately after pasting the offending trace." (interactive) (save-excursion (let ((end-of-trace (point))) (goto-char (search-backward "Traceback (most recent call last):")) (while (and (< (point) end-of-trace) (re-search-forward (rx (seq "/var/lib/mesos" (* nonl) "sandbox") (? "/.pex/" (| "code" "install") "/") (* (not (any "/"))) "/") )) (replace-match "")))))
Convenience tools
Don’t kill on first Cmd-Q
Only kill emacs if I hit Cmd-Q twice in ten seconds.
(defun alexm/dont-kill-on-first-cmd-q (_) "Beep, message the user, and then clear confirm-kill-emacs for 10 seconds." (prog1 (ding) (message "Repeat that command within 10 seconds if you're sure.") (setq confirm-kill-emacs nil) (run-with-timer 10 nil #'(lambda nil (setq confirm-kill-emacs #'alexm/dont-kill-on-first-cmd-q))))) (setq confirm-kill-emacs #'alexm/dont-kill-on-first-cmd-q)
OS X Location hook
Maintain
the variables
set by
osx-location
,
which see.
Also, start the timer for celestial-mode-line, if it’s not already running.
(defun alexm/osx-location-changed nil (setq calendar-latitude osx-location-latitude calendar-longitude osx-location-longitude calendar-location-name (format "%s, %s" osx-location-latitude osx-location-longitude)) (unless celestial-mode-line--timer (celestial-mode-line-start-timer)))
Theme, Display, Font, and Modeline setup
Set the theme.
(load-theme 'wombat t)
Correct highlight
face
to not have
underlining,
and to not
modify the foreground.
Also,
make the inactive modeline
less ugly.
(alexm/set-faces-by-spec '(region ((t (:background "#a0df00" :foreground unspecified)))) '(highlight ((t (:underline nil :foreground unspecified :background "#455445")))) '(mode-line-inactive ((t (:foreground "#999999")))))
Use fonts we either know we have, or can check for. Symbola is used to fill in missing glyphs for odd emoticons that pop up on IRC/IM usually.
(when (member "Symbola" (font-family-list)) (set-fontset-font "fontset-default" nil (font-spec :size 12 :name "Symbola"))) (when macosx-p (set-face-font 'default "Menlo-10")) (when mswindows-p (set-face-font 'default "consolas-10")) (when linux-p (set-face-font 'default "Fixed-11"))
Set up modeline and display variables.
(setq-default display-time-format "%Y%m%dT%H%M" display-time-world-list '(("America/Los_Angeles" "Seattle") ("America/Denver" "Santa Fe") ("America/New_York" "New York") ("UTC" "UTC")) mode-line-format '("%e" mode-line-mule-info mode-line-modified " " mode-line-buffer-identification " " mode-line-position " " mode-line-modes " " (vc-mode vc-mode) " " mode-line-misc-info mode-line-end-spaces)) (display-time) (column-number-mode t)
Actually show the region we’re selecting when marking.
(transient-mark-mode t)
If a file is reverted outside of emacs, and its buffer has NOT been edited inside emacs, automatically revert it.
(global-auto-revert-mode t)
Transparently open compressed files.
(auto-compression-mode t)
Save a list of recent files visited.
(recentf-mode 1) (add-to-list 'recentf-exclude "-autoloads\\.el\\'") (add-to-list 'recentf-exclude "\\.el\\.gz\\'") (add-to-list 'recentf-exclude "ido\\.last\\'")
Just expect font lock to be on everywhere, and turn up the gaudiness.
(setq font-lock-maximum-decoration t) (global-font-lock-mode 1)
Back-tab sometimes gets fucky. Unfuck it.
(define-key key-translation-map "\M-[Z" (kbd "<backtab>"))
OS X thinks of Insert as Help, of all things. Stop that.
(when macosx-p (define-key key-translation-map (kbd "<help>") (kbd "<insert>")))
Set up default window sizes.
(setq initial-frame-alist '((tool-bar-lines . 0) (menu-bar-lines . 0) (width . 80) (height . 60)) default-frame-alist initial-frame-alist) (set-scroll-bar-mode nil)
Package Configuration
This section contains installation and configuration information for all the packages I use.
In order to quickly access configurations, the org nodes are named after the mode the package exposes, as well as having each configuration node tagged with the ’package’ tag.
Passacre
I use passacre for password management. I prefer that it prompt for confirmation.
(require 'passacre) (setq passacre-confirm t)
IRC
A lot of my goddamn life is on IRC.
circe package
Here comes my IRC config! Watch out, it’s a DOOZY!
(use-package circe :ensure t :bind (:map lui-mode-map ("M-a" . tracking-next-buffer) ("C-u" . lui-kill-to-beginning-of-line)) :load-path "~/package/circe-discord" :config (require 'circe-chanop) (require 'circe-lagmon) (ignore-errors (require 'circe-rainbow) (require 'circe-probe)) (require 'circe-color-nicks) (require 'circe-new-day-notifier) (require 'lui-irc-colors) (add-hook 'circe-chat-mode-hook #'alexm/circe-chat-mode) (add-hook 'circe-server-mode-hook #'alexm/circe-server-mode) (add-hook 'circe-server-connected-hook #'alexm/server-connected) (add-hook 'circe-channel-mode-hook #'alexm/channel-mode) (add-hook 'circe-query-mode-hook #'alexm/query-mode) (alexm/set-faces-by-spec '(circe-my-message-face ((t (:foreground "grey95")))) '(circe-fool-face ((t (:foreground "grey20")))) '(circe-highlight-nick-face ((t (:foreground "magenta" :weight bold)))) '(circe-prompt-face ((t (:foreground "#00eebb" :background "unspecified")))) '(circe-server-face ((t (:foreground "steelblue" :weight unspecified)))) '(lui-irc-colors-bg-5-face ((t (:background "sienna4")))) '(lui-irc-colors-bg-7-face ((t (:background "orange4")))) '(lui-irc-colors-bg-11-face ((t (:background "#00e5e5")))) '(lui-irc-colors-bg-12-face ((t (:background "steelblue1")))) '(lui-irc-colors-fg-2-face ((t (:foreground "#66ccff")))) '(lui-irc-colors-fg-3-face ((t (:foreground "#66ff66")))) '(lui-irc-colors-fg-4-face ((t (:foreground "#ff0000")))) '(lui-irc-colors-fg-5-face ((t (:foreground "sienna3")))) '(lui-irc-colors-fg-7-face ((t (:foreground "orange2")))) '(lui-irc-colors-fg-8-face ((t (:foreground "yellow2")))) '(lui-irc-colors-fg-9-face ((t (:foreground "#00ff00")))) '(lui-irc-colors-fg-11-face ((t (:foreground "LightCyan3")))) '(lui-irc-colors-fg-12-face ((t (:foreground "lightblue1")))) '(lui-time-stamp-face ((t (:foreground "green" :weight bold))))) (setq lui-fill-column 0 lui-fill-type nil lui-highlight-keywords '(("atax1a" circe-highlight-nick-face)) lui-logging-flush-delay 0 lui-max-buffer-size 300000 lui-scroll-behavior 'post-output lui-time-stamp-format "%H:%M" lui-time-stamp-position 'right-margin tracking-frame-behavior nil tracking-ignored-buffers nil tracking-most-recent-first t ) (fset 'circe-command-J 'circe-command-JOIN) (fset 'circe-command-Q 'circe-command-QUERY) (fset 'circe-command-WI 'circe-command-WHOIS) (add-to-list 'circe-format-not-tracked 'circe-new-day-notifier-format-message) (enable-circe-color-nicks) (enable-circe-new-day-notifier) (enable-lui-track-bar) (add-to-list 'lui-pre-output-hook 'lui-irc-colors) (defadvice circe-new-day-notification (before ddate activate) (setq circe-new-day-notifier-format-message (replace-regexp-in-string "\n" " " (concat "*** " (shell-command-to-string "ddate"))))))
Functions
Override the default TIME
handler with one that conforms to Erisian norms.
(defun irc-handle-ctcp--ctcp-time (conn _event sender _target _argument) "Handle a CTCP TIME request." (irc-send-ctcpreply conn (irc-userstring-nick sender) "TIME" (replace-regexp-in-string "\n" " " (shell-command-to-string "ddate"))))
Chat modes require margins for the timestamps.
(defun alexm/circe-chat-mode nil (setq right-margin-width 5 lui-logging-directory "~/.circe-logs" lui-logging-file-format "{target}@{network}_%Y-%m.txt" lui-logging-format "[%Y%m%d_%T] {text}"))
Server, query, and channels need shorter modeline names; certain channels also get special treatment.
(defun alexm/circe-server-mode nil (setq mode-name "C-s")) (defun alexm/query-mode nil (setq mode-name "C-q") (smartparens-mode -1)) (defun alexm/channel-mode nil (setq mode-name "C-C") (smartparens-mode -1) (when (member-ignore-case circe-chat-target (list "&bitlbee" "#techcrap")) (setq circe-reduce-lurker-spam t)))
When connecting to the server, rename the buffer to something reasonable.
(defun alexm/server-connected nil (rename-buffer (concat circe-nick "@" circe-network ":" (number-to-string circe-port)) t))
Haven’t gotten around to this…
(defun alexm/start-circe nil nil)
Variables
(setq circe-completion-suffix ", " circe-default-nick "Pi" circe-default-user "pi" circe-fool-list '("wolfgang" "kyhwana" "Shad0w" "Oeskeso" "^Xenofur" "^crabs!" "~kes@" "^arcbot!" "^zetathustra!" "^Brule!" "^hal!" "^buttbot!" "^joepie91!" "^TONKA!" "Bauer") circe-format-self-say "<{mynick}> {body}" circe-format-server-topic "*** Topic change by {userhost}: {new-topic}\n*** Previously: {old-topic}\n*** Diff: {topic-diff}" circe-highlight-nick-type 'occurrence circe-new-buffer-behavior 'display circe-server-flood-penalty 1 circe-server-send-unknown-command-p t circe-unknown-message-destination 'last-active circe-use-cycle-completion t lui-track-bar-behavior 'before-switch-to-buffer)
Emacs Customization
browse-kill-ring package
See and update/select kill ring history.
(use-package browse-kill-ring :ensure t :commands browse-kill-ring :bind (("C-x y" . browse-kill-ring)))
diminish package
Load up the diminish package to hide minor modes.
(use-package diminish :ensure t)
dired package
Set up dired with extensions, make sure beginning/end commands move inside directory listings instead of buffer.
wdired allows text editing of the dired buffer to do things like changing permissions via string/regexp replacement.
(use-package dired :commands dired :bind ("C-x d" . dired) :config (progn ;; Additions to dired ;; http://nflath.com/2009/07/dired/ (load "dired-x") (load "wdired") (setq wdired-allow-to-change-permissions 'advanced) (defun alexm/quit-dired (_k) "Quit dired and do what I want with it like mutt" (interactive "i") (dired-do-flagged-delete t) (quit-window t)) ;; dired modifications (bind-keys :map dired-mode-map ("$" . dired-do-flagged-delete) ("&" . dired-flag-garbage-files) ("c" . find-file) ("j" . dired-next-line) ("k" . dired-previous-line) ("q" . alexm/quit-dired) ("r" . wdired-change-to-wdired-mode)) ;; http://whattheemacsd.com/setup-dired.el-02.html (defun dired-back-to-top () (interactive) (goto-char (point-min)) (dired-next-line (if dired-omit-mode 2 4))) (define-key dired-mode-map [remap beginning-of-buffer] 'dired-back-to-top) (defun dired-jump-to-bottom () (interactive) (goto-char (point-max)) (dired-next-line -1)) (define-key dired-mode-map [remap end-of-buffer] 'dired-jump-to-bottom)))
csv package
Load up CSV mode.
(use-package csv-mode :ensure t)
dns package
Load up DNS mode and make it handle .com
and .net
and .biz
files.
(use-package dns-mode :mode "\\.\\(com\\|net\\|biz\\)\\'")
exec-path-from-shell
It’s REALLY ANNOYING to not get a decent $PATH
. This fixes that.
(use-package exec-path-from-shell :if macosx-p :ensure t :config (exec-path-from-shell-initialize))
expand-region package
Hit M-m, expand up to the next largest region based on mode-context sensitive scope.
(use-package expand-region :ensure expand-region :bind (("M-#" . er/mark-symbol) ("M-m" . er/expand-region)) :commands (er/expand-region er/enable-mode-expansions))
flyspell-mode package
Spelling correction with wiggly red lines!
(use-package flyspell :diminish flyspell-mode :config (setq flyspell-duplicate-distance 0 flyspell-issue-message-flag nil flyspell-issue-welcome-flag nil flyspell-use-meta-tab nil))
ido package
Make selecting files/buffers in minibuffer easier
(use-package ido :config (progn (ido-mode t) (ido-everywhere t) (setq ido-create-new-buffer 'always ido-decorations '("«" "»" " " "…" "⎡" "⎦" " [No match]" " [Matched]" " [Not readable]" " [Too big]" " [Confirm]") ido-enable-flex-matching t ido-ignore-buffers '(":[0-9]" "\\` ") ido-use-virtual-buffers t)))
ido-completing-read+ package
magit
wants this. give it what it wants.
(use-package ido-completing-read+ :ensure t)
fish-mode package
I use, for better or for worse, fish shell.
(use-package fish-mode :ensure t)
flx-ido package
Make fuzzy matching for ido work better.
(use-package flx-ido :ensure flx-ido :config (progn (flx-ido-mode 1) (setq ido-enable-flex-matching t) (setq ido-use-faces nil)))
ibuffer package
List buffers in a dired-ish way. Try to group based on modes or what kind of project something may be related to.
(use-package ibuffer :commands (ibuffer ibuffer-list-buffers ibuffer-other-window) :init (setq ibuffer-default-sorting-mode 'major-mode ibuffer-always-show-last-buffer t ibuffer-view-ibuffer t ibuffer-formats '((mark modified read-only " " (name 32 32 :left :elide) " " (size 9 -1 :right) " " (mode 16 16 :left :elide) " " filename-and-process) (mark " " (name 16 -1) " " filename))))
ledger package
I should be doing accounting in Ledger-mode.
(defun alexm/ledger-mode nil (add-hook 'before-save-hook #'ledger-mode-clean-buffer t t) (add-hook 'before-save-hook #'delete-trailing-whitespace t)) (use-package ledger-mode :init (setq ledger-clear-whole-transactions t) :mode "\\.ledger\\'" :config (add-hook 'ledger-mode-hook #'alexm/ledger-mode) (alexm/set-faces-by-spec '(ledger-occur-xact-face ((t (:background "#233223" :inherit nil))))))
lorem-ipsum package
(use-package lorem-ipsum :ensure t :bind (("M-s l" . lorem-ipsum-insert-sentences) ("M-s L" . lorem-ipsum-insert-paragraphs)))
multiple-cursors package
Work with multiple cursors simultaneously.
(use-package multiple-cursors :commands (mc/mark-next-like-this mc/mark-previous-like-this mc/mark-all-like-this mc/mark-more-like-this-extended mc/mark-pop) :init (use-package phi-search :ensure t) :bind (("C->" . mc/mark-next-like-this) ("C-<" . mc/mark-previous-like-this) ("C-*" . mc/mark-all-like-this) ("C-&" . mc/mark-more-like-this-extended) ("C-S-SPC" . mc/mark-pop)) :ensure t)
paradox package
Paradox makes the package list pretty and adds some stats to the listings.
(use-package paradox :ensure t :commands (paradox-list-packages) :config (setq paradox-github-token t))
rect-mark package
Make rectangular region marking easier.
(use-package rect-mark :ensure nil :bind (("C-x r C-SPC" . rm-set-mark) ("C-x r C-x" . rm-exchange-point-and-mark) ("C-x r C-k" . rm-kill-region) ("C-x r M-w" . rm-kill-ring-save)))
savehist package
Save minibuffer history, so oft-used functions bubble to the top.
(use-package savehist :config '(progn (savehist-mode 1) (setq savehist-file (concat user-emacs-directory "savehist") savehist-save-minibuffer-history 1 savehist-additional-variables '(search-ring regexp-search-ring))))
saveplace package
Make sure I always come back to the same place in a file after closing/opening. http://groups.google.com/group/comp.emacs/browse_thread/thread/c5e4c18b77a18512
saveplace tends to screw with buffers that have automatically folded layouts, like org-mode. It’ll open trees with none of the parents open, which causes weird problems. So org-mode is ignored.
(use-package saveplace :demand :config (save-place-mode t) ;; saveplace and org-mode do not play well together, reset the regexp to include ;; org and org_archive files (setq-default save-place-ignore-files-regexp "\\(?:COMMIT_EDITMSG\\|hg-editor-[[:alnum:]]+\\.txt\\|svn-commit\\.tmp\\|bzr_log\\.[[:alnum:]]+\\|.*\\.org\\|.*\\.org_archive\\)$"))
scala package
Let’s play with Scala!
(use-package scala-mode :ensure t)
tramp package
Tramp should default to the sshx
mode.
(use-package tramp :commands tramp :config (setq tramp-default-method "sshx"))
undo-tree package
Allow undo to branch, and be visualized as a graph.
(use-package undo-tree :ensure undo-tree :diminish undo-tree-mode :config (global-undo-tree-mode 1))
uniquify package
Make buffer names unique, handy when opening files with similar names
(use-package uniquify :config (progn (setq uniquify-buffer-name-style 'post-forward-angle-brackets uniquify-after-kill-buffer-p t uniquify-ignore-buffers-re "^\\*")))
vc-fossil package
(use-package vc-fossil :ensure t :commands (vc-fossil-registered) :config (add-to-list 'vc-handled-backends 'Fossil))
mm package
This sets the HTML viewer.
(use-package mm-view :config (add-to-list 'mm-text-html-renderer-alist '(elinks mm-inline-render-with-file nil "elinks" "-dump-charset" "utf8" "-dump" file)) (setq mm-text-html-renderer 'elinks))
message-mode package
Add Cc and Bcc headers to the message buffer
(use-package message :commands message-mode :no-require t :config (progn (setq mail-envelope-from 'header mail-specify-envelope-from t message-default-mail-headers "Cc: \nBcc: \n" message-forward-as-mime t message-kill-buffer-on-exit t message-send-mail-function 'message-send-mail-with-sendmail message-sendmail-envelope-from 'header message-make-forward-subject-function 'message-forward-subject-fwd) (add-hook 'message-mode-hook 'turn-on-flyspell 'append)))
messages-are-flowing package
This composes emails with hard newlines, allowing them to flow properly on narrow screens.
(use-package messages-are-flowing :ensure t :config (add-hook 'message-mode-hook 'messages-are-flowing-use-and-mark-hard-newlines))
notmuch-mode package
Define spam/unspam twitchers.
(use-package notmuch :commands notmuch-hello :bind (("C-c m" . notmuch-hello)) :config (progn (unless (or (file-exists-p "~/Mail/store/.notmuch") (file-exists-p "~/Maildir/.notmuch")) (setq notmuch-command "notmuch-spigot")) (setq notmuch-search-oldest-first t notmuch-hello-hide-tags '(".bf_spam" ".bf_ham") notmuch-hello-thousands-separator "." notmuch-saved-search-sort-function 'notmuch-sort-saved-searches notmuch-archive-tags '("-inbox" "-unread")) (setq notmuch-search-line-faces '(("unread" . notmuch-search-unread-face) ("flagged" . notmuch-search-flagged-face) ("pagerduty" :foreground "green" :background "red") ("concur" :foreground "green" :background "red") ("alerts" :background "grey30") ("cron" :background "grey30") ("review" :background "#2B2900") ("ticket" :background "#260026") ("dogfood" :background "#012000") ("lists/transtaskforce" :background "#090033") ))))
Productivity
org-mode package
Define a new-day function for work.
(defun alexm/org-new-day nil (interactive) (goto-char (point-max)) (unless (looking-at-p "^$") (newline)) (insert "* ") (alexm/stamp-m8601-date nil) (org-insert-subheading (list 1)))
The package is already loaded by virtue of init.el
, but do some configuration of it anyway.
(use-package org :commands (org-agenda) :bind (("C-c l" . org-store-link) ("C-c a" . org-agenda) ("C-M-r" . org-capture) :map org-mode-map ("C-x @ N" . alexm/org-new-day)) :mode (("\\.org_archive\\'" . org-mode) ("\\.org\\'" . org-mode)))
(defun alexm/upcase-tempo nil "make tempo templates uppercase" (dolist (sym (seq-filter (lambda (x) (and (symbolp x) (string-prefix-p "tempo-template-org-" (symbol-name x)) (not (string-match-p "latex" (symbol-name x))))) obarray)) (let ((new (mapcar (lambda (s) (if (and (stringp s) (string-prefix-p "#+" s)) (upcase s) s)) (eval sym)))) (set sym new))))
Try to enable Tempo if it’s available.
(use-package org-tempo :if (version<= "9.2" org-version))
Install Twitter Bootstrap exporter.
(use-package ox-twbs :ensure t)
org-mode configuration
- Variables
Add markdown export backend, habits module. Set habit graph over to the right.
(load "ox-publish") (add-to-list 'org-export-backends 'md) (add-to-list 'org-modules 'org-habit) (add-to-list 'org-modules 'org-notmuch) (setq org-habit-graph-column 60)
Look for org files in my fossil checkout.
(add-to-list 'org-agenda-files "~/package/jerkcity/pi")
Timestamps take notes by default.
(setq org-log-done 'note)
Keep drawer for logs too.
(setq org-drawers '("PROPERTIES" "LOGBOOK"))
Save clock data and state changes and notes in the LOGBOOK drawer.
(setq org-log-into-drawer t)
Show notes in a task first.
(setq org-reverse-note-order nil)
How much to indent in from the node level.
(setq org-indent-indentation-per-level 2)
Use IDO for target completion.
(setq org-completion-use-ido t)
Disable priorities.
(setq org-enable-priority-commands nil)
Don’t use super/subscript globally, makes exports weird due to underscores. If they need to be used, set them on a per file level
(setq org-use-sub-superscripts nil)
Use speed commands (single key commands that can be used when cursor is at beginning of a line for a node).
(setq org-use-speed-commands t)
I like links being active ret.
(setq org-return-follows-link t)
Make lists cycle whether they’re nodes or plain.
(setq org-cycle-include-plain-lists t)
Fontify org-src blocks like their language mode.
(setq org-src-fontify-natively t)
Turn on sticky agendas so we don’t have to regenerate them.
(setq org-agenda-sticky nil)
If there’s a region, do whatever it is I’m trying to do to ALL headlines in region.
(setq org-loop-over-headlines-in-active-region t)
Changes the effect of C-a/C-e when used on org node lines. Does things like making C-a go to point after stars. I agree with qDot. It’s really annoying, so turn it off.
(setq org-special-ctrl-a/e nil)
Do special stuff when cutting in a headline.
(setq org-special-ctrl-k t)
When yanking subtrees, promote/demote levels based on the node being yanked into, if any.
(setq org-yank-adjusted-subtrees t)
Weeks start on Monday.
(setq org-agenda-start-on-weekday 1)
Start agenda showing the next week by default.
(setq org-agenda-span 7)
Multiple pass pdf generation.
(setq org-latex-to-pdf-process '("xelatex -interaction nonstopmode %f" "xelatex -interaction nonstopmode %f"))
I HATE INVISIBLE EDITS. So show me where it’s happening and then make sure it doesn’t happen.
(setq org-catch-invisible-edits 'show-and-error)
No blank lines before headings
(setq org-blank-before-new-entry '((heading) (plain-list-item . auto)))
Tune the agenda view.
(setq org-agenda-skip-scheduled-if-done nil org-agenda-skip-deadline-if-done t)
Set export options for LaTeX and disable other annoying export shit.
(setq org-export-latex-packages-alist '(("utf8" "inputenc") ("osf,sc" "mathpazo") ("" "amsmath")) org-html-postamble nil org-twbs-postamble nil org-export-with-LaTeX-fragments t org-export-with-tags nil org-export-with-author nil org-export-with-smart-quotes t org-export-with-section-numbers nil org-export-with-email nil org-export-with-date nil)
Keep it from turning on annoying modes at startup.
(setq org-startup-truncated nil)
Deadlines should show up 3 days before, by default.
(setq org-deadline-warning-days 3)
- Publishing
Experiment: publish personal web sites via
org-publish
, with Twitter Bootstrap theme.(defun alexm/replace-org-project (x) (add-to-list 'org-publish-project-alist x t '(lambda (a b) (equal (car a) (car b))))) (let ((site-root "~/package/jerkcity/pi/sites") (document-root "~/public_html")) (alexm/replace-org-project `("statics" :base-directory ,site-root :base-extension "\\(?:cs\\|j\\)s\\|\\(?:png\\|jpe?g\\)" :publishing-directory ,document-root :recursive t :publishing-function org-publish-attachment)) (cl-defun alexm/org-add-project (basename &rest options &key (publishing-function 'org-html-publish-to-html) &allow-other-keys) (alexm/replace-org-project `(,basename :base-directory ,(concat site-root "/" basename) :base-extension "org" :publishing-directory ,(concat document-root "/" basename) :auto-preamble nil :creator-info nil :html-doctype "html5" :html-html5-fancy t :html-postamble nil :publishing-function ,publishing-function :recursive t :section-numbers nil :sub-superscript nil :todo-keywords nil :with-latex t :with-properties t :with-toc nil ,@options))) (alexm/org-add-project "pi.pihost.us" :headline-levels 1 :author (list "Pi Irrational") :html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">" :html-head-extra "<meta name=\"viewport\" value=\"width=device-width\">" :with-author t ) (alexm/org-add-project "se30.xyz" :headline-levels 1 :publishing-function 'org-twbs-publish-to-html :auto-sitemap t :author '("Alex Maestas") :html-head-include-scripts nil :html-head "<link href=\"/bootstrap.min.css\" rel=\"stylesheet\">" :with-author t) (alexm/org-add-project "vivisector.org" :headline-levels 1 :author '("Vivisector Crew") :auto-sitemap nil :html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"/style.css\">" :with-author nil) (alexm/org-add-project "laurenjsmith.com" :author '("Lauren Smith") :headline-levels 1 :auto-sitemap nil :with-author t))
- Hooks
Flyspell mode for spell checking everywhere.
(add-hook 'org-mode-hook 'turn-on-flyspell)
Always indent text using outline. Also delete trailing whitespace on save.
(defun alexm/org-mode-hook nil (org-indent-mode t) (alexm/upcase-tempo) (add-hook 'before-save-hook 'delete-trailing-whitespace t t)) (add-hook 'org-mode-hook #'alexm/org-mode-hook t)
- Speed key bindings
Using speedkeys, s will narrow to the subtree, but you have to call widen explicitly. Set capital S to widen.
(setq org-speed-commands-user '(("S" . widen)))
- Faces
Sasha Chua’s org done faces http://sachachua.com/blog/2012/12/emacs-strike-through-headlines-for-done-tasks-in-org/
(setq org-fontify-done-headline t) (alexm/set-faces-by-spec '(org-done ((t (:foreground "PaleGreen" :weight normal :strike-through t)))) '(org-headline-done ((((class color) (min-colors 16) (background dark)) (:foreground "LightSalmon" :strike-through t))))) ;; Set org babel backgrounds so we get nice blocks (set-face-background 'org-block-begin-line "#333") (set-face-background 'org-block-end-line "#333")
- Refile settings
Don’t allow refiling into anything that’s set to DONE.
(defun alexm/verify-refile-target () "Exclude todo keywords with a done state from refile targets" (not (member (nth 2 (org-heading-components)) org-done-keywords))) (setq org-refile-target-verify-function 'alexm/verify-refile-target)
- Org Babel
Set up languages that babel will handle.
(org-babel-do-load-languages 'org-babel-load-languages '( (emacs-lisp . t) (shell t) (org t)))
Programming
rainbow-delimiters package
(use-package rainbow-delimiters :ensure rainbow-delimiters :commands (rainbow-delimiters-mode rainbow-delimiters-mode-enable) :config (alexm/set-faces-by-spec '(rainbow-delimiters-depth-1-face ((t (:foreground "green" :weight extra-bold)))) '(rainbow-delimiters-depth-2-face ((t (:foreground "forestgreen" :weight bold)))) '(rainbow-delimiters-depth-3-face ((t (:foreground "lightseagreen" :weight bold)))) '(rainbow-delimiters-depth-4-face ((t (:foreground "lightskyblue" :weight bold)))) '(rainbow-delimiters-depth-5-face ((t (:foreground "cyan" :weight bold)))) '(rainbow-delimiters-depth-6-face ((t (:foreground "steelblue" :weight bold)))) '(rainbow-delimiters-depth-7-face ((t (:foreground "orchid" :weight bold)))) '(rainbow-delimiters-depth-8-face ((t (:foreground "purple" :weight bold)))) '(rainbow-delimiters-depth-9-face ((t (:foreground "hotpink" :weight bold)))) '(rainbow-delimiters-unmatched-face ((t (:background "red" :foreground "green" :weight bold))))))
smartparens package
Smarter paren matching without going the paredit route.
Turning off deferred loading because this is useful almost everywhere.
(use-package smartparens :ensure smartparens :diminish smartparens-mode :bind (("<s-right>" . sp-forward-slurp-sexp) ("<s-left>" . sp-forward-barf-sexp) ("<s-M-right>" . sp-backward-slurp-sexp) ("<s-M-left>" . sp-backward-barf-sexp)) :config (progn (smartparens-global-mode t) (show-smartparens-global-mode 1) (setq sp-highlight-pair-overlay nil) (load "smartparens-config")))
cc-mode package
Settings for C/C++ modes.
(defun alexm/cc-mode-hook () (c-add-style "alexm/cc-code-style" '("bsd" (arglist-close . c/lineup-arglist) (arglist-intro . c/lineup-arglist-intro-after-paren) (c-basic-offset . 4) (knr-argdecl . 5) (label . 0) (statement-case-open . +) (substatement-open . 0))) (c-set-style "alexm/cc-code-style") (c-set-offset 'innamespace 0) (bind-keys :map c-mode-map ("C-m" . newline-and-indent)) (bind-keys :map c++-mode-map ("C-m" . newline-and-indent)) (subword-mode 1)) (add-hook 'c-mode-common-hook 'alexm/cc-mode-hook)
http://stackoverflow.com/questions/3312114/how-to-tell-emacs-to-open-h-file-in-c-mode
;; function decides whether .h file is C or C++ header, sets C++ by ;; default because there's more chance of there being a .h without a ;; .cc than a .h without a .c (ie. for C++ template files) (defun alexm/c-c++-header () "sets either c-mode or c++-mode, whichever is appropriate for header" (interactive) (let ((c-file (concat (substring (buffer-file-name) 0 -1) "c"))) (if (file-exists-p c-file) (c-mode) (c++-mode)))) (add-to-list 'auto-mode-alist '("\\.h\\'" . alexm/c-c++-header))
compilation package
Compilation mode.
(use-package compile :commands (compile) :config (setq compilation-disable-input nil compilation-auto-jump-to-first-error nil compilation-scroll-output 'first-error mode-compile-always-save-buffer-p t))
edebug-x package
(use-package edebug-x :ensure edebug-x :commands (edebug-x-modify-breakpoint-wrapper edebug-x-show-breakpoints edebug-x-show-instrumented edebug-x-show-data))
emacs-lisp-mode package
Preconfigure eldoc-mode.
(use-package eldoc :commands (eldoc-mode) :diminish eldoc-mode)
Coalesce a bunch of individual hooks:
(defun alexm/remove-elc-on-save nil "If you're saving an elisp file, likely the .elc is no longer valid." (if (file-exists-p (concat buffer-file-name "c")) (delete-file (concat buffer-file-name "c")))) (defun alexm/emacs-lisp-mode nil (add-to-list 'flycheck-disabled-checkers 'emacs-lisp-checkdoc) (add-hook 'emacs-lisp-mode-hook 'alexm/remove-elc-on-save nil t) (rainbow-delimiters-mode-enable) (eldoc-mode 1))
eldoc mode shows function calls in the minibuffer. \(0.275\) seconds is somewhere in the middle of the average length of a blink.
(setq eldoc-idle-delay 0.275)
Default lisp indentation looks weird.
(setq lisp-indent-function 'common-lisp-indent-function) (add-hook 'emacs-lisp-mode-hook #'alexm/emacs-lisp-mode) (add-hook 'lisp-interaction-mode-hook #'eldoc-mode) (define-key emacs-lisp-mode-map (kbd "C-c v") 'eval-buffer) (define-key lisp-mode-shared-map (kbd "RET") 'reindent-then-newline-and-indent) ;; Enable jumping to elisp via help mode ;; http://emacsredux.com/blog/2014/06/18/quickly-find-emacs-lisp-sources/ (define-key 'help-command (kbd "C-l") 'find-library) (define-key 'help-command (kbd "C-f") 'find-function) (define-key 'help-command (kbd "C-k") 'find-function-on-key) (define-key 'help-command (kbd "C-v") 'find-variable)
flycheck package
Using flycheck instead of flymake
(use-package flycheck :ensure flycheck :commands flycheck-mode :config (bind-key "M-n" #'flycheck-next-error flycheck-mode-map) (bind-key "M-p" #'flycheck-previous-error flycheck-mode-map) (bind-key "C-c ! !" #'flycheck-list-errors flycheck-mode-map) (setq flycheck-checker-error-threshold 4000))
fuel package
fu.el
is the factor interaction mode.
(use-package fuel :ensure t :no-require t :commands (run-factor))
gdb package
(setq gdb-non-stop-setting nil gdb-many-windows t gdb-show-main t gud-chdir-before-run nil gud-tooltip-mode t)
git-gutter package
(use-package git-gutter+ :ensure git-gutter+ :diminish git-gutter+-mode :commands (git-gutter+-mode) :config (setq git-gutter+-hide-gutter nil))
magit package
git management in emacs.
(use-package magit :ensure magit :bind (("M-g s" . magit-status)) :commands (magit magit-status) :init ;; omfg shut up magit I am fine with auto reverting (setq magit-last-seen-setup-instructions "1.4.0") :config (progn (setq magit-completing-read-function 'magit-ido-completing-read) (add-hook 'magit-log-edit-mode-hook 'turn-on-flyspell 'append) (setq magit-auto-revert-mode nil) ;; Set up diffing faces, and always full screen magit (eval-after-load 'magit '(progn (set-face-foreground 'magit-diff-added "green1") (set-face-foreground 'magit-diff-removed "red1") (set-face-background 'magit-diff-added "#004400") (set-face-background 'magit-diff-removed "#440000") (set-face-background 'magit-section-highlight "#1f2727") ;; full screen magit-status (defadvice magit-status (around magit-fullscreen activate) (window-configuration-to-register :magit-fullscreen) ad-do-it (delete-other-windows)) (defun magit-quit-session () "Restores the previous window configuration and kills the magit buffer" (interactive) (kill-buffer) (jump-to-register :magit-fullscreen)) (define-key magit-status-mode-map (kbd "q") 'magit-quit-session)))))
perl-mode package
I am, for better or for worse, a Perl hacker.
(use-package cperl-mode :ensure t :init (defalias 'perl-mode 'cperl-mode) :config (setq cperl-close-paren-offset -4 cperl-continued-statement-offset 4 cperl-indent-level 4 cperl-indent-parens-as-block t cperl-tab-always-indent t ))
prog-mode package
Set up defaults for all programming modes.
Always indent 4.
(setq-default c-basic-offset 4)
Spaces, not tabs. Everywhere.
(setq-default indent-tabs-mode nil)
Set up fill column and whitespace-mode settings when starting programming mode.
(defun alexm/programming-mode-hook () (setq whitespace-style '(face lines-tail) show-trailing-whitespace t) (add-hook 'before-save-hook 'delete-trailing-whitespace t t) (set-fill-column 80) (flycheck-mode) (rainbow-delimiters-mode-enable) (git-gutter+-mode) (unless org-export-current-backend (whitespace-mode))) (add-hook 'prog-mode-hook 'alexm/programming-mode-hook)
Always check spelling in comments and documentation.
(add-hook 'prog-mode-hook 'flyspell-prog-mode)
python-mode package
Bring in the mode.
(use-package python :config (setq python-fill-docstring-style 'pep-257-nn))
Sort Python imports.
(defun isort nil "Sort python imports" (interactive) (shell-command-on-region (point-min) (point-max) "isort -" nil t nil t))
smerge-mode package
Adds commands for dealing with conflicted merge files (i.e. >>>>>>> and <<<<<<< files)
http://atomized.org/2010/06/resolving-merge-conflicts-the-easy-way-with-smerge-kmacro/
(use-package smerge-mode :commands (smerge-mode)) (defun sm-try-smerge () (save-excursion (goto-char (point-min)) (when (re-search-forward "^<<<<<<< " nil t) (smerge-mode 1)))) (add-hook 'find-file-hook 'sm-try-smerge t)
Writing
htmlize package
Used for HTMLizing buffers, but mostly for code block export in org-mode.
(use-package htmlize :ensure htmlize)
LaTeX package
Set some LaTeX settings.
(use-package tex :if (executable-find "latex") :ensure auctex :commands (LaTeX-mode) :config (setq LaTeX-default-verb-delimiter ?= LaTeX-verbatim-environments '("verbatim" "verbatim*" "lstlisting") TeX-newline-function 'newline-and-indent))
text-mode package
Set text-mode hook to strip trailing whitespace.
(defun alexm/text-mode-hook nil (add-hook 'before-save-hook 'delete-trailing-whitespace t t)) (use-package text-mode :config (add-hook 'text-mode-hook #'alexm/text-mode-hook))
markdown-mode package
Markdown. Used mostly for blogging and README files.
(use-package markdown-mode :mode (("\\.markdown\\'" . markdown-mode) ("\\.md\\'" . markdown-mode)) :ensure markdown-mode :config (add-hook 'markdown-mode-hook #'alexm/programming-mode-hook))
yaml-mode package
Yaml.
(use-package yaml-mode :mode (("\\.yaml\\'" . yaml-mode) ("\\.yml\\'" . yaml-mode)) :ensure yaml-mode)
Terminals
ansi-color package
Turn on ansi in shells
(use-package ansi-color :ensure ansi-color :commands shell :config (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on))
Misc
easy-pg package
gpg file auto query/loading
(use-package epa-file :defer t :config (progn (epa-file-enable) (setq epa-file-cache-passphrase-for-symmetric-encryption t)))
proced package
(use-package proced :commands (proced proced-toggle-auto-update) :config (progn (setq proced-auto-update-interval 2) (defun alexm/proced-settings () (proced-toggle-auto-update t)) (add-hook 'proced-mode-hook 'alexm/proced-settings)))
midnight-mode package
(use-package midnight :ensure t :init (setq midnight-period (* 6 60 60) midnight-delay (random 60)) (add-to-list 'clean-buffer-list-kill-never-regexps "@[^:]+:[1-9][0-9]*$") (add-to-list 'clean-buffer-list-kill-never-regexps "^[#&]"))
osx-location package
Enabling this
gets us
better results from
celestial-mode-line
,
which see.
(use-package osx-location :if macosx-p :ensure t :after (celestial-mode-line solar) :config (add-hook 'osx-location-changed-hook #'alexm/osx-location-changed) (osx-location-watch))
solar package
Utility.
(use-package solar)
celestial-mode-line package
Get the modeline to display moon phase and sunset.
(use-package celestial-mode-line :if macosx-p :ensure t :config (add-to-list 'global-mode-string 'celestial-mode-line-string t))
Keybinds
(bind-key "C-c C-d" 'delete-region) (bind-key "C-c d" 'delete-region) (bind-key "C-x C-d" 'ido-dired) (bind-key "C-c e" 'eval-and-replace) (bind-key "C-x C-k" 'kill-region) (bind-key "C-x C-b" 'ibuffer-other-window) (bind-key "C-M-g" 'goto-line) (bind-key "M-o" 'other-window) (bind-key "C-w" 'backward-kill-word) ;; make this like shell. (bind-key "C-x ^" 'what-cursor-position) (bind-key "C-x +" 'enlarge-window) (bind-key "C-x -" 'shrink-window) (bind-key "C-x =" 'balance-windows) (bind-key "C-x i" #'alexm/start-or-switch-to-circe) (bind-key "M-s ?" #'alexm/rot13-region) (bind-key "M-s i" #'isort python-mode-map) (bind-key "C-x @ p" #'browse-url-at-point) (bind-key "C-x @ n" #'alexm/stamp-m8601) (bind-key "C-x @ d" #'alexm/stamp-m8601-date) (bind-key "C-x @ r" #'alexm/stamp-rfc2822) (bind-key "s-=" #'text-scale-increase) (bind-key "s--" #'text-scale-decrease) (bind-key "s-0" #'alexm/restore-text-scale) (bind-key "C-x M" #'alexm/clean-up-mesos-stacktraces) (bind-key "C-x w" #'delete-trailing-whitespace)
Toggle Map
;; http://endlessparentheses.com/the-toggle-map-and-wizardry.html (define-prefix-command 'alexm/toggle-map) ;; The manual recommends C-c for user keys, but C-x t is ;; always free, whereas C-c t is used by some modes. (define-key ctl-x-map "t" 'alexm/toggle-map) (define-key alexm/toggle-map "a" 'global-auto-revert-mode) (define-key alexm/toggle-map "d" 'toggle-debug-on-error) (define-key alexm/toggle-map "e" 'toggle-debug-on-error) (define-key alexm/toggle-map "f" 'auto-fill-mode) (define-key alexm/toggle-map "#" 'linum-mode) (define-key alexm/toggle-map "l" 'toggle-truncate-lines) (define-key alexm/toggle-map "q" 'toggle-debug-on-quit) (define-key alexm/toggle-map "t" 'tags-reset-tags-tables) (autoload 'tags-reset-tags-tables "etags" nil t) (define-key alexm/toggle-map "v" 'visual-line-mode) ;;; Generalized version of `read-only-mode'. (define-key alexm/toggle-map "r" 'dired-toggle-read-only) (autoload 'dired-toggle-read-only "dired" nil t) ;; http://endlessparentheses.com/emacs-narrow-or-widen-dwim.html (defun narrow-or-widen-dwim (p) "If the buffer is narrowed, it widens. Otherwise, it narrows intelligently. Intelligently means: region, subtree, or defun, whichever applies first. With prefix P, don't widen, just narrow even if buffer is already narrowed." (interactive "P") (declare (interactive-only)) (cond ((and (buffer-narrowed-p) (not p)) (widen)) ((region-active-p) (narrow-to-region (region-beginning) (region-end))) ((derived-mode-p 'org-mode) (org-narrow-to-subtree)) (t (narrow-to-defun)))) (define-key alexm/toggle-map "n" 'narrow-or-widen-dwim)