Category Archives: geek

On this page:

Summarizing the last meeting dates in Org Contacts

Steffan Heilmann wanted to be able to quickly see the last time he interacted with someone if he tracked interactions in org-contacts. That is, given something like this:

* John Smith
** DONE Conversation
[2014-01-20]
** DONE E-mail
[2014-01-15]
* Jane Smith
** DONE Conversation
[2014-01-07]

… we want to see the latest timestamps for each contact entry.

Here’s the code that I came up with. It scans backward for timestamps or headings. Whenever it finds a timestamp, it compares the timestamp with the one that it has previously stored and keeps the later timestamp. Whenever it encounters a level-1 heading, it sets the property and clears the stored timestamp.

(defun sacha/org-update-with-last-meeting ()
  "Update each level 1 heading with the LASTMEETING property."
  (interactive)
  (goto-char (point-max))
  (let (last-meeting)
    (while (re-search-backward
            (concat "\\(" org-outline-regexp "\\)\\|\\("
                    org-maybe-keyword-time-regexp "\\)") nil t)
      (cond
       ((and (match-string 1)
             (= (nth 1 (save-match-data (org-heading-components))) 1)
             last-meeting)
        ;; heading
        (save-excursion (org-set-property "LASTMEETING" last-meeting))
        (setq last-meeting nil))
       ((and (match-string 2))
        (if (or (null last-meeting) (string< last-meeting (match-string 2)))
            (setq last-meeting (match-string 2))))))))

Scanning backwards works well here because that makes it easy to add information to the top-level heading we’re interested in. If we scanned it the other way around (say, with org-map-entries), we might need to backtrack in order to set the property on the top-level heading.

The result is something like this:

* John Smith
  :PROPERTIES:
  :LASTMEETING: [2014-01-20]
  :END:
** DONE E-mail
[2014-01-15]
** DONE Conversation
[2014-01-20]
* Someone without a meeting
* Jane Smith
  :PROPERTIES:
  :LASTMEETING: [2014-01-07]
  :END:
** DONE Conversation
[2014-01-07]

You can then use something like:

#+COLUMNS: %25ITEM %LASTMEETING %TAGS %PRIORITY %TODO
#+BEGIN: columnview :maxlevel 1
| ITEM                        | LASTMEETING  | TAGS | PRIORITY | TODO |
|-----------------------------+--------------+------+----------+------|
| * John Smith                | [2014-01-20] |      |          |      |
| * Someone without a meeting |              |      |          |      |
| * Jane Smith                | <2014-01-07> |      |          |      |
#+END:

… or even use M-x org-sort to sort the entries by the LASTMEETING property (R will reverse-sort by property).

Read Lisp Tweak Emacs [Beginner 2/4]: How to understand what Emacs Lisp code does

This entry is part 2 of 4 in the series Read Lisp, Tweak Emacs

Some conventions we’ll use:

  • Inline code will be boxed and monospace in the HTML version and generally surrounded by equal signs in plain text.
  • Code samples will be monospace and in boxes in the HTML version, and enclosed in #+begin_src#+end_src in plain text. Example:
    (message "Hello world")
    

After this module, you should be able to

  • learn more about the functions and variables that you find in Emacs Lisp code
  • pay attention to important details when copying code, such as ‘ (quote) and . (dot notation)
  • add to and remove items from lists

Learn more about functions

The symbol after ( is usually a function name, unless it’s part of a list of literals (numbers, strings, etc.). You’ll learn how to recognize literal lists later.

In math, operators like + and * go between the numbers they will work on. In Emacs Lisp, the operator (or the “function”) is at the start of the expression, followed by the things it’s going to operate on (“arguments”).

Here’s how to calculate (1 + 2) * 3 in Emacs Lisp. Note that the multiplication is surrounded by parentheses, even if we usually leave out the parentheses in math. That’s because in Emacs Lisp, all function calls have their own set of parentheses.

(* (+ 1 2) 3)

Let’s take a closer look:

( ( 1 + 2 ) * 3 )    Math expression
( * ( + 1 2 ) 3 )    Emacs Lisp expression

math-to-emacs-lisp.png

See how the operators are at the beginning of whatever they’re working on, and the parentheses enclose everything that’s related to that operator?

Understanding this will let you read code like:

(global-hl-line-mode)

This calls the global-hl-line-mode function, which highlights the current line.

(show-paren-mode)

This calls the show-paren-mode function, which shows matching parentheses when your cursor is after them.

(blink-cursor-mode -1)

This calls the blink-cursor-mode function with -1 as the argument, which turns blinking cursors off.

(find-file "~/todo.org")

This calls the find-file function with the todo.org file in your home directory. It opens the file, creating it if it doesn’t exist yet.

(turn-on-eldoc-mode)

This turns on eldoc-mode, which displays the argument list for the current function. You can move your cursor around to see argument lists for other functions.

(add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)

This turns on eldoc-mode when a buffer is switched to Emacs Lisp mode. You’ll learn more about why some things have ​'​ and some don’t in the section “Some things are taken literally” in this module.

To find out if something is a function, what it does, what arguments it takes, and if it has any keyboard shortcuts, use the C-h f (describe-function) command. Give it the function name. For example, C-h f add-hook will show you the documentation for add-hook, and C-h f show-paren-mode will show you the documentation for that.

The documentation for show-paren-mode starts with “show-paren-mode is an interactive autoloaded Lisp function”. Interactive functions are functions that can be called with M-x or with keyboard shortcuts, and they’re usually functions that you’ll find useful while interacting with Emacs. Non-interactive functions tend to be for internal use, such as code that other Emacs Lisp code will call. Read the description of the function to learn more about arguments that you can pass to change its behavior. If it mentions a prefix argument, that means that you can change its behaviour by typing C-u before you call the function.

Emacs is extensively documented. Whenever you come across a strange function, check it out with C-h f (describe-function). If you have the Emacs Lisp sources installed, you can learn more about how the functions work. Just follow the link from the documentation, or use M-x find-function to learn more.

In fact, you can learn more about functions even if you don’t know what they’re called. For example, if you know the keyboard shortcut or you can see the item on one of the menus, use C-h k (describe-key) to learn more about that command. Emacs will show you the function that’s associated with that keyboard shortcut or menu item. You can also look up functions by keyword if you use M-x apropos.

  1. Use C-h f (describe-function) to learn more about the following functions:
  2. describe-function: Yes, this is also a function! The documentation will give you alternative keyboard shortcuts such as F1 f.
  3. find-file: You can use this to open specific files. See the function description to learn how to use this with remote files.
  4. message: This is an example of a function that has a variable number of arguments. The first argument says how the message will be displayed, and the rest of the arguments contain the values.
  5. just-one-space: Handy way to clean up space. What keyboard shortcut is it bound to?
  6. Look for Emacs configuration code that you would like to understand further. Use C-h f (describe-function) to learn more about the functions in the code. For example, here are some snippets from my configuration. What do the functions do?
    (savehist-mode 1)
    (tooltip-mode -1)
    (tool-bar-mode -1)
    (menu-bar-mode -1)
    (scroll-bar-mode -1)
    (prefer-coding-system 'utf-8)
    

Learn more about variables

Variables are containers that can hold different values. In Emacs Lisp, you can change the value of a variable as many times as you want, and you can change it to different types of data as needed.

Like the way you can use C-h f (describe-function) to learn more about a function, you can use C-h v (describe-variable) to learn more about a variable by name. For example, use C-h v to look up the documentation for visible-bell. It says:

Non-nil means try to flash the frame to represent a bell.

A non-nil value is anything that isn’t nil, such as t or 1. If you would like to configure your Emacs to flash instead of ringing the bell,
you could add the following code to your ~/.emacs.d/init.el:

(setq visible-bell t)

Here’s another useful snippet:

(setq column-number-mode t)

This turns on the display of the column number in the modeline.

Many variables have the same value no matter what you’re looking at. Some variables change depending on the buffer you’re in, and are called “buffer-local” variables. Use C-h v to find out if a variable is buffer-local. For example, the documentation for tab-width includes:

Automatically becomes buffer-local when set.

This means you can’t globally set it with setq, because any changes you make will only be applied to the current buffer. However, you can set the default value with setq-default like this:

(setq-default tab-width 2)

To make it easier for you to customize Emacs without writing Emacs Lisp code, many variables give you an interface for setting the variable. If you use describe-variable to look up the definition, you’ll often see a line like “You can customize this variable.” Click on the customize link in the documentation or move your point to it and press RET. You can change the value there and try it temporarily, or you can save it to your configuration. The Customize interface is good for exploring, but because the code that it generates can difficult to read or share, many people skip it and use Emacs Lisp code instead.

  1. Use C-h v (describe-variable) to learn more about the variables in the following code snippet:
    (setq-default indicate-empty-lines t)
    (setq-default show-trailing-whitespace t)
    
  2. Look for Emacs configuration code that has variables you would like to learn more about. Use C-h v (describe-variable) to look up their definition and the values they can be set to.

Understand symbols

Let’s take a closer look at this example.

(add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)

add-hook is a function. ‘emacs-lisp-mode-hook and ‘turn-on-eldoc-mode have single quotes, which tells Emacs to skip evaluating them. They refer to the name of the thing instead of its value. emacs-lisp-mode-hook is a variable that contains a list of functions to run, and turn-on-eldoc-mode is a function that we’re adding to that list.

The single quote means take it literally – treat it as the name of something. If you remove the quote from emacs-lisp-mode-hook, Emacs will look up the value in that variable and use that as the name of the variable to actually set, and you’ll probably get an error.

Use M-: (eval-expression) or another way to evaluate expressions to tell the difference between:

emacs-lisp-mode-hook

and

'emacs-lisp-mode-hook

The first one does not have a quotation mark, and Emacs replaces it with the value that the variable emacs-lisp-mode-hook contains. The second one is quoted, so Emacs treats it as the name of a thing.

Here’s another example:

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

This calls the fset function, which sets the function definition of yes-or-no-p to the function y-or-n-p. In short, it changes the “yes” or “no” prompts to “y” or “n”, which can be convenient.

Not everything is quoted. You’ll often see lines like this in Emacs configuration files:

(setq delete-old-versions -1)

setq stands for “set quoted”. This is actually the same code as (set 'delete-old-versions -1) or (set (quote delete-old-versions) -1), but
setq is shorter, so it’s more common.

This can be confusing. When you’re starting out, copy code carefully. If there’s a single quote, make sure there’s a single quote in your copy. If there isn’t, skip it.

Work with lists

You can set the value of a variable to multiple things. In Emacs configuration files, you’ll often see ‘ used for lists. For example,

(setq diff-switches '("-b" "-u"))

sets the options for the diff command to a list containing two items, -b and -u. Quoting the list creates a list and quotes all the content in it as needed. You can create lists with the list function instead. The code above is the same as:

(setq diff-switches (list "-b" "-u"))

The code above sets the value of the variable to a list, ignoring any previous values it had.

Add to a list

Most of the time, though, you want to add to a list instead of completely replacing it. You’ll often see something like this in people’s configuration files:

(add-to-list 'load-path "~/elisp")

This adds the ~/elisp directory to the beginning of the list of directories that Emacs checks when loading libraries. If the directory is already in the list, add-to-list does nothing.

Hooks

Hooks are lists of functions that are called from Emacs Lisp in order to modify the behaviour of something. For example, different modes have their own hooks so that you can add functions that will run when that mode is initialized. You saw this example earlier in the module:

(add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)

This is equivalent to:

(add-to-list 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)

It adds the turn-on-eldoc-mode function to the list of functions
when a buffer is initialized with emacs-lisp-mode.

Deleting from a list

If you need to delete something from a list, you can use the delete function like this:

(setq load-path (delete "~/elisp" load-path))

This deletes the specified member from the list. Note that the second argument for delete is not quoted, so Emacs Lisp uses the value instead of treating it as the name of a list.

Hooks are lists of functions, so you can delete items using delete. Alternatively, a cleaner way to remove a hook is to use remove-hook like this:

(remove-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)

Dot notation

Some things look like lists, but there’s a dot between the first element and the last element. Whether something should have a dot or not depends on what’s expected by the function that uses the data. For example:

(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/"))

This calls the add-to-list function with two arguments. The first argument (‘package-archives) specifies the list to add an item to, and the second argument (‘("melpa" . "http://melpa.milkbox.net/packages/")) is the data to add.

The dot (x . y) shows that this is a cons cell, which is something that has two parts. These parts are called the car and the cdr, and can contain symbols, values, lists, and so on. A cons cell like ("abc" . "def") looks like this:

       car              cdr
+----------------+----------------+
|     "abc"      |     "def"      |
+----------------+----------------+

A list like ‘("abc" "def") is made up of several cons cells.

       car              cdr                         car             cdr
+----------------+----------------+         +----------------+----------------+
|     "abc"      |       ------------------>|      "def"     |      nil       |
+----------------+----------------+         +----------------+----------------+

In Emacs Lisp, ‘("abc" "def") is equivalent to (cons "abc" (cons "def" nil)), and it’s not the same as (cons "abc" "def"). Here’s something that shows the differences:

(cdr '("abc" . "def"))  ;; Returns "def", which is a string
(cdr '("abc" "def"))    ;; Returns ("def"), which is a list

If the function you’re calling expects a string instead of a list, or the other way around, you’ll run into errors. That’s why you have to be careful about whether something uses dots or not. A good way to find out is by reading other people’s configuration and seeing how they use that variable.

Because lists are made up of cons cells, you’ll sometimes see people add to lists like this:

(setq load-path (cons "~/elisp" load-path))

This adds ~/elisp to the beginning of the load-path list. It does this by using cons to create a new cons cell that has ~/elisp at the beginning and a pointer to the rest of the values in load-path, and then storing that in load-path. It’s the same as (add-to-list 'load-path "~/elisp"), assuming load-path does not already have that directory. If it does, cons adds it anyway, but add-to-list does not.

Lists can also contain lists. For example, here’s some code that saves backup files (the ones that end in ~) to ~/.emacs.d/backups.

(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))

This is how the second argument breaks down:

( ;; a list with one item
 ("." . "~/.emacs.d/backups") ;; a cons cell with a car of "." and a cdr of "~/.emacs.d/backups"
)

If you want to learn more about cons cells, see the Emacs Lisp Reference.

Advanced: Backquotes or backticks (`) are special. They quote the expression that follows them, but they also allow you to substitute values or evaluate expressions. Backquotes are useful for more complex structures or when you’re working with macros. They do basically the same thing as ‘ for lists, but anything preceded by a comma (,) is evaluated. They’re less common, but if you do come across them, note that ` is not the same as ‘. See the Emacs Lisp Reference for more information. Here’s a quick example:

(setq backup-directory-alist `((".*" . ,temporary-file-directory)))

This stores backup files in the directory specified by temporary-file-directory.

Review

Look for Emacs configuration code that you would like to understand further. Use C-h f (describe-function) to learn more about functions and C-h v (describe-variable) to learn more about variables in the code. Can you figure out what the code does and how you might modify it slightly to fit your needs even better?

Series Navigation« Read Lisp, Tweak Emacs [Beginner 1/4]: How to try Emacs LispRead Lisp Tweak Emacs (Beginner 3/4): How can I make things more convenient? »

Quantified Awesome: Added sparklines and percentages

As I was answering the standard question of “Who are you and what do you do?”, I thought it might be interesting to come up with the percentages for what I actually do based on my time records. After all, I have the data. In the past, I used to export my records to a spreadsheet and do some easy number-crunching. Why bother, though, if I can program the system to do this for me?`

I ended up spending 3.5 hours adding percentages and sparklines to Quantified Awesome, updating my RSpec tests along the way. (100% coverage, yay!) Here’s what the result looks like:

2014-06-11 13_34_46-quantified awesome

The sparklines let me easily see trends and exceptions, while percentages can be easily multiplied by 168 hours to get weekly estimates or 24 hours to get daily ones. For example, sleep took up 35.8% of my time from 2012-02-17 to 2014-06-11, or an average of 8.6 hours a day. Activities directly related to earning money took up 10.9% of my time, or roughly 18.3 hours a week. The sprints and spikes are easier to see with sparklines than with tabular data, and they were easy to implement with JQuery Sparklines.

So now I can be more accurate when answering the question: “What do you do?” It doesn’t make sense to include all the minutiae. People don’t really answer that question with “Sleep,” even though that takes up much of people’s time. However, I can pick a threshold (1%?) and look at the activities above that. That is, for the ~28 months of this 5-year experiment so far, I:

  • consult (10.3%)
  • connect with people (5.0%)
  • write (3.0%)
  • draw (2.5%)
  • cook (2.3%)
  • bike (2.0%)
  • work on Emacs (1.2%) and
  • work on Quantified Awesome and other tracking tools (1%)

Data! Mwahahaha…

Slowly getting the hang of Clojure

At least in terms of 4clojure problems. =) I’ve worked my way through the elementary and easy problems (woohoo!), with 88 exercises completed so far. It took me a while to get the hang of lazy-seq, since Emacs Lisp doesn’t do lazy evaluation. Once I started thinking of it as a macro, though, I finally got the hang of it. Here’s my solution for the exercise for reimplementing map:

(fn my-map [func input]
      (if (sequential? input) 
        (cons (func (first input))
              (lazy-seq (my-map func (next input))))))

There are more exercises to do, and it’s fun to feel the different concepts start coming together. I might not do the hard exercises, though. I still haven’t thought of any practical purposes I’d like to use it for, though…

SSL issues after moving to Ubuntu Precise

My Rails script for checking library due dates and renewing items stopped working the other day to BadGateway errors. While debugging I ended up going down this rabbit-hole of trying to upgrade RVM’s OpenSSL and Ruby versions. rvmsudo rvm pkg install openssl failed in my production environment because the Linode VPS was now 64-bit, so even though I had the appropriate development libraries installed, the code still didn’t compile. I tried all sorts of things like rvm get head; rvm reload and gem update --system.

I kept running into errors like There was an error while trying to resolve rubygems version for 'latest'. when reinstalling Ruby and /usr/bin/ld: cannot find -lz when using RVM to reinstall OpenSSL (even though I had zlib1g-dev installed).

After an hour and a half of searching through StackOverflow and mailing list messages, I finally paid attention to the curl error message:

error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

I searched for that and Ubuntu Precise. As it turns out, the upgrade from Ubuntu 10 to Ubuntu 12 resulted in some issues with Verisign-certified sites. I know, I know, old news (almost two years old!) but I hadn’t gotten around to upgrading off Lucid until recently.

Anyway, I followed the recommended steps to copy the text from https://knowledge.verisign.com/support/ssl-certificates-support/index?page=content&id=AR1556 into /usr/local/share/ca-certificates/verisign.crt and ran update-ca-certificates. After that, rvm reinstall 2.0.0 worked, and so did my script.

Harumph! Anyway, I’m glad that’s fixed.

What could Emacs coaching look like?

I asked people on Twitter how much they might pay for 30-60 minutes of Emacs coaching. Based on replies and e-mails, the general consensus seems to be about $25-35 for 30 minutes and $35-50 for an hour, depending on the level of tweaking.

This is how I imagine it might work and why it might be worth it:

Troubleshooting
You could spend days (or weeks!) posting and replying to mailing lists or StackOverflow, or you could spend an interactive session quickly digging into what’s wrong and how to work around or fix it. In addition, you’ll probably pick up lots of tips by watching someone’s problem-solving or debugging process. This probably works as a quick e-mail describing the problem, a 30-60 minute troubleshooting session over screen sharing or SSH/tmux, and possibly a free or paid-for follow-up if more investigation is needed. Probably a good idea to have a satisfaction guarantee, since some problems are harder to solve than others.
Guidance, pair programming, or coding
You’ve got an idea for an Emacs customization or major mode, but it requires more Emacs Lisp geekery than you’re comfortable with or you don’t know how to go about implementing it. A few high-level pointers might get you going: check out these examples, use this function to do that, etc. Or you might want to write most of the code yourself while having someone around so that you can ask questions if you get stuck – maybe a lower rate for the virtual equivalent of hanging out in a cafe together while working on separate things? Alternatively, a code review can point out how you can debug or improve things. Lastly, there’s also the option of handing off most of the coding, with some interactive sessions as you nail down exactly how you want it to behave.
Coaching
I think this is where incredible is, actually – getting help when you don’t even know what you don’t know. Emacs is really big. It can be difficult to get a sense of what’s possible or what’s surprisingly easy, so you might be plodding along with an inefficient workflow that could be tweaked with a little configuration or a few changed practices. A good coach can discuss your goals, watch how you do things, demonstrate better ways to work, and help you implement those changes.
Gradual learning
On a related note, it’s also easy to get intimidated by how much there is. It can help to have a gradual learning path. I’ve talked to quite a few people who found Org Mode task management overwhelming and had hundreds of tasks piled up in their text files. Ditto for Emacs Lisp learning! Imagine having the Emacs equivalent of a personal trainer who can help you come up with an individualized program of learning so that you’re focused on one small chunk at a time. =)

Plot twist! This is actually for Bastien Guerry (Org Mode maintainer, also http://emacs-doctor.com/), not for me. I’ve been doing Emacs-related Helpouts for a token fee and I’m happy to chat with people about Emacs gratis as well, but I think it would be even awesomer to see if someone as wonderful as Bastien can build a nice little business out of it.

How wonderful is Bastien? Well, if you’ve seen my Emacs Chat with him or read his posts on the Org Mode mailing list, you know that he’s smart, experienced, and friendly. In fact, the more I think about what Emacs consulting might be like, the more I want to sign up too. I use Org a lot and I’m generally comfortable tinkering with the source code, but there are a few things that I haven’t quite wrapped by mind around yet: more export tweaks, more Babel/tangling, a better capture workflow… And I have yet to get around to setting up proper autocomplete and other development tools, too!

Bastien’s travelling at the moment, but wouldn’t it be lovely if he got back to a bunch of e-mails to [email protected] with requests or suggestions? =) E-mail him if you’re interested, and help him figure out what’s a good way to help you. He mentioned being open to pay-what-you-want pricing. If money is tight, reach out to him anyway – and if you want to donate more as a way of thanking him for all the other stuff he does, that’s also a great excuse to ask him to help improve how you use Emacs.

Hey, if there are Eclipse consultants… Surely we can get even more value out of Emacs consulting!