Configuration

About this file

This is my personal config. It's really long, but that's partly
because I sometimes leave blog posts in it as commentary. (And also
because I've got a lot of little customizations that I might not even
remember. =) ). If you want to see a table of contents and other
useful niceties, go to http://sachachua.com/dotemacs . Other links for
this page: Org Mode version, Github repository

If you're new to Emacs Lisp, you probably don't want to copy and paste
large chunks of this code. Instead, copy small parts of it (always
making sure to copy a complete set of parentheses) into your
*scratch* buffer or some other buffer in emacs-lisp-mode. Use M-x
eval-buffer to evaluate the code and see if you like the way that
Emacs behaves. See An Introduction to Programming in Emacs Lisp for
more details on Emacs Lisp. You can also find the manual by using C-h
i (info) and choosing "Emacs Lisp Intro".

I've installed a lot of packages. See the package sources section to
add the repositories to your configuration. When you see use-package
and a package name you might like, you can use M-x package-install
to install the package of that name. Note that use-package is itself
provided by a package, so you'll probably want to install that and
bind-key.

If you're viewing the Org file, you can open source code blocks (those
are the ones in begin_src) in a separate buffer by moving your point
inside them and typing C-c ' (org-edit-special). This opens another
buffer in emacs-lisp-mode, so you can use M-x eval-buffer to load
the changes. If you want to explore how functions work, use M-x
edebug-defun to set up debugging for that function, and then call it.
You can learn more about edebug in the Emacs Lisp manual.

I like using (setq ...) more than Customize because I can neatly
organize my configuration that way. Ditto for use-package - I mostly
use it to group together package-related config without lots of
with-eval-after-load calls, and it also makes declaring keybindings
easier.

My ~/.emacs.d/init.el is now a symlink to Sacha.el, which is what
M-x org-babel-tangle (C-c C-v t) produces. A note about Org
updates: I like running Org Mode from checked-out source code instead
of package.el. I add the Lisp directories to my load-path, and I
also use the :load-path option in my first use-package org call to
set the load path. One of those is probably doing the trick and the
other one is redundant, but maybe it's a belt-and-suspenders sort of
thing. Using the git checkout also makes upgrading Org easy. All I
have to do is git pull; make, and stuff happens in an external Emacs
process. Since I create Sacha.el via org-babel-tangle, my Emacs
config can load Sacha.el without loading Org first.

Load secrets

I keep slightly more sensitive information in a separate file so that I can easily publish my main configuration.

(load "~/.emacs.secrets" t)

General configuration

Libraries

(use-packagedash)

Backups

This is one of the things people usually want to change right away. By default, Emacs saves backup files in the current directory. These are the files ending in ~ that are cluttering up your directory lists. The following code stashes them all in ~/.emacs.d/backups, where I can find them with C-x C-f (find-file) if I really need to.

Windows configuration drill

When you're starting out, the tool bar can be very helpful. (Emacs Basics: Using the Mouse). Eventually, you may want to reclaim that extra little bit of screenspace. The following code turns that thing off. (Although I changed my mind about the menu - I want that again.)

(tool-bar-mode -1)

Time in the modeline

I like having the clock.

(display-time-mode 1)

Winner mode - undo and redo window configuration

winner-mode lets you use C-c <left> and C-c <right> to switch between window configurations. This is handy when something has popped up a buffer that you want to look at briefly before returning to whatever you were working on. When you're done, press C-c <left>.

(use-packagewinner:defer t)

Sentences end with a single space

In my world, sentences end with a single space. This makes
sentence navigation commands work for me.

(setq sentence-end-double-space nil)

Helm - interactive completion

Helm makes it easy to complete various things. I find it to be easier
to configure than ido in order to get completion in as many places as
possible, although I prefer ido's way of switching buffers.

Getting Helm and org-refile to clock in or create tasks emacsorghelm

I've been thinking about how to improve the way that I navigate to,
clock in, and create tasks in Org Mode. If the task is one of the ones
I've planned for today, I use my Org agenda. If I know that the task
exists, I use C-u C-c C-w (org-refile) to jump to it, and then !
(one of my org-speed-commands-user options) to clock in and track it
on Quantified Awesome. If I want to resume an interrupted task, I use
C-u C-c j (my shortcut for org-clock-goto). For new tasks, I go to
the appropriate project entry and create it, although I really should
be using org-capture instead.

I thought about how I can reduce some of these distinctions. For
example, what if it didn't matter whether or not a task already
exists? I can modify the org-refile interface to make it easier for me
to create tasks if my description doesn't match anything. To make
things simpler, I'll just reuse one of my org-capture-templates, and
I'll pre-fill it with the candidate from Helm.

Next, I want to add this to the way that Helm prompts me to refile.
That means that my creation task should return something ready for
org-refile. Actually, maybe I don't have to do that if I know I'm
always going to call it when I want to jump to something. I might as
well add that bit of code that sets up clocking in, too.

Hooray! Now C-u C-c C-w (org-refile) also lets me use TAB or
F2 to select the alternative action of quickly clocking in on a
task. Mwahaha.

I think I'm getting the hang of tweaking Helm. Yay!

Mode line format

Display a more compact mode line

(use-packagesmart-mode-line)

Change "yes or no" to "y or n"

Lazy people like me never want to type "yes" when "y" will suffice.

(fset 'yes-or-no-p 'y-or-n-p)

Minibuffer editing - more space!

Sometimes you want to be able to do fancy things with the text
that you're entering into the minibuffer. Sometimes you just want
to be able to read it, especially when it comes to lots of text.
This binds C-M-e in a minibuffer) so that you can edit the
contents of the minibuffer before submitting it.

More window movement

(use-packageswitch-window:bind (("C-x o" . switch-window)))

Frequently-accessed files

Registers allow you to jump to a file or other location quickly. To
jump to a register, use C-x r j followed by the letter of the
register. Using registers for all these file shortcuts is probably a bit of a waste since I can easily define my own keymap, but since I rarely go beyond register A anyway. Also, I might as well add shortcuts for refiling.

Move to beginning of line

(defunmy/smarter-move-beginning-of-line (arg)
"Move point back to indentation of beginning of line.Move point to the first non-whitespace character on this line.If point is already there, move to the beginning of the line.Effectively toggle between the first non-whitespace character andthe beginning of the line.If ARG is not nil or 1, move forward ARG - 1 lines first. Ifpoint reaches the beginning or end of the buffer, stop there."
(interactive"^p")
(setq arg (or arg 1))
;; Move lines first
(when (/= arg 1)
(let ((line-move-visual nil))
(forward-line (1- arg))))
(let ((orig-point (point)))
(back-to-indentation)
(when (= orig-point (point))
(move-beginning-of-line 1))))
;; remap C-a to `smarter-move-beginning-of-line'
(global-set-key [remap move-beginning-of-line]
'my/smarter-move-beginning-of-line)

This lets me use C-c C-r to refile a capture and then jump to the
new location. I wanted to be able to file tasks under projects so that
they could inherit the QUANTIFIED property that I use to track time
(and any Beeminder-related properties too), but I also wanted to be
able to clock in on them.

I like looking at two days at a time when I plan using the Org
agenda. I want to see my log entries, but I don't want to see
scheduled items that I've finished. I like seeing a time grid so that
I can get a sense of how appointments are spread out.

Starting my weeks on Saturday

I like looking at weekends as week beginnings instead, so I want the
Org agenda to start on Saturdays.

(setq org-agenda-start-on-weekday 6)

Display projects with associated subtasks

I wanted a view that showed projects with a few subtasks underneath
them. Here's a sample of the output:

Headlines with TAGS match: +PROJECT
Press `C-u r' to search again with new search string
organizer: Set up communication processes for Awesome Foundation Toronto
organizer: TODO Announce the next pitch night
organizer: TODO Follow up with the winner of the previous pitch night for any news to include in the updates
organizer: Tidy up the house so that I can find things quickly
organizer: TODO Inventory all the things in closets and boxes :@home:
organizer: TODO Drop things off for donation :@errands:
organizer: Learn how to develop for Android devices

Make it easy to mark a task as done

Great for quickly going through the to-do list. Gets rid of one
extra keystroke. ;)

(defunmy/org-agenda-done (&optional arg)
"Mark current TODO as done.This changes the line at point, all other lines in the agenda referring tothe same tree node, and the headline of the tree node in the Org-mode file."
(interactive"P")
(org-agenda-todo "DONE"))
;; Override the key definition for org-exit
(define-key org-agenda-mode-map "x" 'my/org-agenda-done)

Make it easy to mark a task as done and create a follow-up task

(defunmy/org-agenda-mark-done-and-add-followup ()
"Mark the current TODO as done and add another task after it.Creates it at the same level as the previous task, so it's better to usethis with to-do items than with projects or headings."
(interactive)
(org-agenda-todo "DONE")
(org-agenda-switch-to)
(org-capture 0 "t"))
;; Override the key definition
(define-key org-agenda-mode-map "X" 'my/org-agenda-mark-done-and-add-followup)

Capture something based on the agenda

(defunmy/org-agenda-new ()
"Create a new note or task at the current agenda item.Creates it at the same level as the previous task, so it's better to usethis with to-do items than with projects or headings."
(interactive)
(org-agenda-switch-to)
(org-capture 0))
;; New key assignment
(define-key org-agenda-mode-map "N" 'my/org-agenda-new)

Projects

Reviews

Weekly review

I regularly post weekly reviews to keep track of what I'm done,
remind me to plan for the upcoming week, and list blog posts,
sketches, and links. I want to try out grouping tasks by topic first,
then breaking it down into previous/next week.

Monthly reviews

I want to be able to see what I worked on in a month so that I can write my monthly reviews. This code makes it easy to display a month's clocked tasks and time. I haven't been particularly thorough in tracking time before, but now that I have a shortcut that logs in Quantified Awesome as well as in Org, I should end up clocking more.

Quickly refiling Org Mode notes to headings in the same file

I wanted a quick way to organize random notes from my inbox into an
outline, organizing from the bottom up instead of starting with a
top-down hierarchy. My old code for refiling to an Org heading in the
current buffer didn't work any more, but helm-org-in-buffer-headings
seems to be promising. I made it a speed command (see the value of
org-use-speed-commands elsewhere in my config) so that I can easily
refile.

Org2blog

I use org2blog to post to my blog, which is Wordpress-based. I used to
use punchagan's org2blog, but there's a completely different one in
ELPA, so I figured I'd give that a try. UPDATE 2014-10-29: Overriding
it with the Git version (see the first section of this config) so that
I can use thumbnail support for now…

Share my Emacs configuration

This code gets around the fact that my config is called Sacha.org, but
I want it to export as sacha-emacs.org in my Dropbox's public
directory. Although now that I'm shifting to Github Pages, maybe I
don't need this any more…

Spreadsheets

(defunmy/org-days-between (start end)
"Number of days between START and END (exclusive).This includes START but not END."
(- (calendar-absolute-from-gregorian (org-date-to-gregorian end))
(calendar-absolute-from-gregorian (org-date-to-gregorian start))))

Literate programming

Editing source code

I don't want to get distracted by the same code in the other window, so I want org src to use the current window.

I manually categorize Emacs News links into an Org unordered list, and
then I reorganize the list by using M-S-up (org-shiftmetaup) and
M-S-down (org-shiftmetadown). I decide to combine or split categories
depending on the number of links. I have a pretty consistent order.
John Wiegley suggested promoting Emacs Lisp and Emacs development
links at the top of the list. I like to sort the rest of the list
roughly by interest: general links first, then Org, then coding, then
other links at the bottom.

Here's some code that sorts Org lists in a custom sequence, with
unknown items at the bottom for easy re-ordering. It will take a list like:

DONE Publishing Emacs News as plain text, HTML, and attached Org file

I've been publishing these weekly summaries of Emacs-related links on
my blog and to the emacs-tangents mailing list / newsgroup. I started
by posting plain text from Org Mode's ASCII export, and people asked
for Org Mode and HTML formats. So here's some code that prepares
things for pasting into a Gnus message buffer.

It turns out that order matters for multipart/alternative - start with
plain text, then include richer alternatives. First time around, I put
the HTML version first, so people didn't end up seeing it. Anyway,
here's something that shows up properly now: text/plain, then
text/html, with text/x-org attached. The heavy lifting is done with
org-export-string-as, which exports into different formats.

I've been working on memorizing Latin verb conjugations. I was looking
for a conjugation drill similar to these ones for and nouns and
pronouns, because I liked the instant feedback and the ability to
quickly get hints. I couldn't find an online drill I liked, though, so
I made my own with Emacs and Org. (Because… why not?)

I wrote some code to allow me to take a table like this:

present - 1st sing. - ago / agere

agO

present - 2nd sing. - ago / agere

agis

present - 3rd sing. - ago / agere

agit

present - 1st plu. - ago / agere

agimus

present - 2nd plu. - ago / agere

agitis

present - 3rd plu. - ago / agere

agunt

imperfect - 1st sing. - ago / agere

agEbam

imperfect - 2nd sing. - ago / agere

agEbAs

imperfect - 3rd sing. - ago / agere

agEbat

imperfect - 1st plu. - ago / agere

agEbAmus

imperfect - 2nd plu. - ago / agere

agEbAtis

imperfect - 3rd plu. - ago / agere

agEbant

future - 1st sing. - ago / agere

agam

future - 2nd sing. - ago / agere

agEs

future - 3rd sing. - ago / agere

agEt

future - 1st plu. - ago / agere

agEmus

future - 2nd plu. - ago / agere

agEtis

future - 3rd plu. - ago / agere

agent

I can call my/make-fill-in-quiz to get a quiz buffer that looks like
this. If I get stuck, ? shows me a hint in the echo area.

To make it easier, I've left case-fold-search set to nil so that I
don't have to match the case (uppercase vowels = macrons), but I can
set case-fold-search to t if I want to make sure I've got the
macrons in the right places.

New lines are always indented

(defunsanityinc/kill-back-to-indentation ()
"Kill from point back to the first non-whitespace character on the line."
(interactive)
(let ((prev-pos (point)))
(back-to-indentation)
(kill-region (point) prev-pos)))
(bind-key"C-M-<backspace>" 'sanityinc/kill-back-to-indentation)

Adapt to being on Windows

I'm on Windows, so I use Cygwin to add Unix-y tools to make my life easier.
These config snippets seem to help too.

The proper way to implement this is probably to patch or override the
definition of magit-git-insert-section so that it takes a list of
options to add at the end of the command, but that can wait for another time (or braver souls).

Mail

Gnus

synchronizes with my phone, which is handy for notifications and quick replies

filters most of the spam for me

works with a few interesting extensions such as Boomerang for Gmail

However, I like the way the Gnus mail/news client in Emacs gives me a
much more keyboard-friendly way to manage lots of mail, and I can even
write code to partially automate some of my common operations.

I used to have my config in in ~/.gnus, but people might find it
handy, so I've added it to my public Emacs configuration.

I like using Gmane to read mailing lists, and I use IMAP to read my Gmail.

I now use Dovecot with OfflineIMAP for local IMAP access to my mail
and synchronization with Gmail, but you can see the commented-out
information for Gmail in case you prefer that. I have two-factor
authentication enabled for Gmail, so I set up an app-specific password
for Gnus. I have GPG set up for encryption, and an ~/.authinfo.gpg
file set up with something like:

If you don't have GPG set up and you don't mind saving your passwords
in the clear, you can set up an ~/.authinfo file instead.

Sending e-mail on Windows was a bit of a pain. Fortunately, I
eventually found something that works. I've configured emailrelay to
accept the mail and forward it to Gmail. The server starts with this
batch file:

Emacs server

(server-start) permits the use of emacsclient, emacsclientw, and
org-protocol. I used to start a server as part of my config. Now I'm
switching to using emacs --daemon, which starts a server
automatically. Anyway, with --daemon, Emacs doesn't start off in a
graphical environment, so the frames that emacsclient -c creates
don't get the theme applied. This fixes that:

Deleting things

(defunzap-to-isearch (rbeg rend)
"Kill the region between the mark and the closest portion ofthe isearch match string. The behaviour is meant to be analogousto zap-to-char; let's call it zap-to-isearch. The deleted regiondoes not include the isearch word. This is meant to be bound onlyin isearch mode. The point of this function is that oftentimesyou want to delete some portion of text, one end of which happensto be an active isearch word. The observation to make is that ifyou use isearch a lot to move the cursor around (as you should,it is much more efficient than using the arrows), it happens alot that you could just delete the active region between the markand the point, not include the isearch word."
(interactive"r")
(when (not mark-active)
(error"Mark is not active"))
(let* ((isearch-bounds (list isearch-other-end (point)))
(ismin (apply 'min isearch-bounds))
(ismax (apply 'max isearch-bounds))
)
(if (< (mark) ismin)
(kill-region (mark) ismin)
(if (> (mark) ismax)
(kill-region ismax (mark))
(error"Internal error in isearch kill function.")))
(isearch-exit)
))
(define-key isearch-mode-map [(meta z)] 'zap-to-isearch)

TODO Get zap-to-isearch to work with helm-swoop

Network: TRAMP and editing files over SSH

Emacs lets you edit files on remote servers, which is pretty darn
cool. On Windows, these things help a little.

Encryption

Yaoddmuse

Building a today-I-learned habit, and displaying the documentation for random Emacs commands emacs

I'd like to build a habit of regularly learning one small thing each
day in one of three domains: tech, life, and learning. My measurable
output would probably be in the form of index cards, tweets, blog
posts, and notes (in org-capture, Dropbox, or Evernote). I can get
input from various sources like blog posts, videos, books, webpages,
and so on.

A little bit of randomness might be useful for learning more about
Emacs. Emacswiki has a random page function, but the chunks are often
a little large or irrelevant. On the other hand, displaying a random
command from the packages that I already have loaded into my Emacs -
that might be a good way to discover interesting things.

I started by looking at apropos-command, which led me to
apropos-internal, which is a C function that referred to obarray.
Using obarray by itself didn't work (suspiciously few elements, so I
often ended up looking at emms-related functions). I eventually found
mapatoms, which seems to do a better job at listing an appreciable
number of interactive functions. I filtered the list to include only
documented functions that had not been marked as obsolete: 8,415 in
my current Emacs, which should be plenty to go through. =)

I've added this to a key-chord + hydra keymap as a repeatable
function, so I can type hh to start my Hydra and then type r as
many times as I want in order to show the documentation for a random
interactive function. If you're curious about that, you can see the
key-chord section of my config.

Anyway, today I learned more about obarray and mapatoms - they're
not interactive functions, but they were handy for building this
little bit of code. We'll see how it goes! =)

DONE Scan ~/bin and turn the scripts into interactive commands

I want to automate little things on my computer so that I don't have
to look up command lines or stitch together different applications.
Many of these things make sense to turn into shell scripts. That way,
I can call them from other programs and assign keyboard shortcuts to
them. Still, I spend most of my computer time in Emacs, and I don't
want to think about whether I've defined a command in Emacs Lisp or in
a shell script. Besides, I like the way Helm lets me type parts of
commands in order to select and call them.

Emacs Lisp allows you to define a macro that results in Emacs Lisp
code. In this case, I want to define interactive functions so I can
call them with M-x. In case I decide to call them from Emacs Lisp,
such as (my/shell/rotate-screen "left"), I want to be able to pass
arguments. I'm also using dash.el to provide functions like -filter
and -not, although I could rewrite this to just use the standard
Emacs Lisp functions.

Here's the code that scans a given directory for executable files and
creates interactive functions, and some code that calls it for my ~/bin directory.

This uses Org Agenda's log mode to summarize the tasks that I checked
off. I still need to match it up with the plans for the previous week
to see which items I'd planned ahead, and which ones were new tasks.
(Hmm, is it important to track those separately? I might just skip it.)

Ido and Org

When I use org-refile to organize my notes, I like seeing the
latest entries on top. Ido-related and verify-related snippets
are from "Using ido-mode for org-refile (and archiving via
refile)" in Org Hacks.

Encryption

(require 'org-crypt)
(org-crypt-use-before-save-magic)
(setq org-tags-exclude-from-inheritance (quote ("crypt")))
(setq org-crypt-key nil)
;; GPG key to use for encryption;; Either the Key ID or set to nil to use symmetric encryption.;; (setq auto-save-default nil);; Auto-saving does not cooperate with org-crypt.el: so you need;; to turn it off if you plan to use org-crypt.el quite often.;; Otherwise, you'll get an (annoying) message each time you;; start Org.;; To turn it off only locally, you can insert this:;;;; # -*- buffer-auto-save-file-name: nil; -*-

Drawing

Digital index piles with Emacs

Somewhat daunted by the prospect of categorizing more than a hundred
sketches and blog posts for my monthly review, I spent some time
figuring out how to create the digital equivalent of sorting index
cards into various piles.

In fact, wouldn't it be super-cool if the items could automatically
guess which category they should probably go in, prompting me only if
it wasn't clear?

I wanted to write a function that could take a list structured like this:

Keyword A

Previous links

Keyword B

Previous links

Link 1 with Keyword A

Link 2 with Keyword B

Link 3 with Keyword A

Link 4

It should file Link 1 and 3 under Keyword A, Link 2 under Keyword B,
and prompt me for the category for Link 4. At that prompt, I should be
able to select Keyword A or Keyword B, or specify a new category.

First step: I needed to figure out the structure of the list, maybe
including a sample from the category to make it clearer what's
included. org-list.el seemed to have useful functions for this.
org-list-struct gave me the structure of the current list. Let's say
that a category is anything whose text does not match
org-bracket-link-regexp.

After that, I wrote a function that used Helm to prompt me for a
category in case it couldn't guess the category. It took me a while to
figure out that I needed to use :init instead of :candidates
because I wanted to read information from the buffer before Helm
kicked in.

I'm new to fiddling with Helm, so this implementation is not the best
it could be. But it's nifty and it works the way I want it to, hooray!
Now I can generate a list of blog posts and unblogged sketches,
categorize them quickly, and then tweak the categorizations
afterwards.

My next step for learning more about Helm sources is probably to write
a Helm command that creates a montage of selected images. John Kitchin
has a post about handling multiple selection in Helm, so I just need
to combine that with my code for using Imagemagick to create a montage
of images. Whee!

Using Emacs to prepare files for external applications like Autodesk Sketchbook Pro

To make it easier to draw using Autodesk Sketchbook Pro on my laptop
(a Lenovo X220 tablet PC), I've created several templates with
consistent dot grids and sizes. Since I want to minimize typing when
I'm drawing, I wrote a couple of functions to make it easier to copy
these templates and set up appropriately-named files. That way, I can
save them without the grid layer, flip between files using Sketchbook
Pro's next/previous file commands, and then process them all when I'm
ready.

Index cards

I've been experimenting with a habit of drawing at least five index
cards every day. Here's a function that creates five index cards (or a
specified number of them) and then opens the last one for me to edit.

I might tweak the files a little more after I rename them, so I don't
automatically upload them. When I'm happy with the files, I use a Node
script to upload the files to Flickr, move them to my To blog
directory, and copy Org-formatted text that I can paste into my
learning outline.

Automatically resize images

The image+ package is handy for displaying the images so
that they're scaled to the window size.

By using Emacs Lisp functions to set up files that I'm going to use in
an external application, I minimize fussing about with the keyboard
while still being able to take advantage of structured information.

Do you work with external applications? Where does it make sense to
use Emacs Lisp to make setup or processing easier?

TODO Move to-blog sketches to a staging folder for easier upload

This function moves the specified files from my To blog folder to my
Selection folder. That makes it easier to upload them to Wordpress
and then delete them afterwards. I use the Wordpress web interface
instead of org2blog's file upload support because sometimes the
Org2blog file uploads don't work as well as I'd like, and I haven't
looked into debugging that yet.