On this page:

Dealing with the doldrums

I’m not always a cheerful, energetic ray of sunshine. Sometimes I feel meh, too. Whether it’s due to the disruption of routines or momentum, frustration with uncertainty, or factors beyond my control, it happens. During these doldrums, it’s harder to work on creative tasks. It’s harder to move, even. There’s the temptation to spend the time browsing the Web or playing games instead–tempting activities that don’t require a lot of thinking and have a false sense of progress.

Instead of getting stuck–or pretending it doesn’t happen–I’d rather think about how I can hack my way around it. Sometimes it’s good to just relax into it, relying on the buffer from good relationships and good finances. After all, I don’t often give myself permission to take a long afternoon nap, or read fiction, or watch a movie. It can actually be quite satisfying to see things chugging along even if I don’t feel like I’m my usual self. We still keep the house running smoothly, the financial markets still do well. (I hope that if any “meh” periods coincide with market corrections, I’ll have the presence of mind to think, “Oh, stocks are on sale!”)

Sometimes little things I do can dislodge me enough from the Sargasso sea of suckitude. One of the things I find helpful is to think about the difference between how this feels and other ways I’ve felt before. Sure, I might feel meh at the moment, but there have also been moments when I’ve felt awesome, accomplished, productive, energetic, and even smug (in a good way =) ). Thinking about those different feelings helps me remember that meh-ness is temporary, and it also helps me figure out some things I can do that might move me closer to other feelings. For example, I feel awesome when I learn interesting technical things that help me save time or make tools. I feel accomplished when I finish a large batch of cooking or I cross off plenty of items on my TODO list. I feel energetic when I exercise and when I solve problems. I feel an extra burst of smugness when I bike, especially if it’s been raining.

It can be hard to get over that activation threshold, though. Many things that give me that positive buzz are creative in nature (programming, writing, etc.). Fortunately, there are a few activities that I can do even if my mind’s wandering. Walking is a great use of meh-brain time. I feel somewhat proud of myself because of the exercise. I went for a 1.5-hour walk the other day, and that felt much better than sitting at home playing video games. Tidying is another good use of meh-time, and paperwork is like that too. I can practise drawing, too – copying figures or slowly untangling my thoughts.

Writing this, I’m already starting to feel that usual sense of “Actually, things are pretty awesome.” =) I don’t expect myself to be 100% on, and it makes no sense to beat myself up for not being on all the time. But it’s nice to know that the occasional “meh”-ness in my life is temporary, and I can choose to either relax and enjoy it or play around with some ways to nudge myself out of it.

Read Lisp Tweak Emacs (Beginner 3/4): How can I make things more convenient?

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

“How can I customize Emacs to make things more convenient?”

After this module, you’ll be able to:

  • define your own keyboard shortcuts so that you can call functions more easily
  • work with custom functions that other people have defined in their configurations
  • copy and use anonymous functions

Keyboard shortcuts

The default keyboard shortcuts (or “keybindings”) can be difficult to remember, and many useful functions don’t have any keyboard shortcuts at all. People often set up their own keyboard shortcuts to make other commands easier to use. There are different ways to assign keys depending on where you want the keybinding to be available.

Setting keybindings in all buffers

You can assign a key to a function globally, which means that it will be available in buffers of any type if there are no mode maps or local keybindings that override it. (Mode maps are set by major modes like emacs-lisp-mode or minor modes like auto-fill-mode.) Setting a global keybinding is usually done with global-set-key, although sometimes you’ll see it done with define-key and global-map.

You can use global-set-key interactively by calling it with M-x global-set-key. Type the keyboard shortcut you would like to set, then specify the name of the function you would like Emacs to call. Note that the function must be interactive – that is, it must be something you can call with M-x and it should include (interactive ...) in its definition. For example, try M-x global-set-key, then press <f10>, and assign it to save-buffer. After you do that, you should be able to press <f10> to save the current buffer.

If you like a keybinding that you’ve interactively set, use C-x ESC ESC (repeat-complex-command) to see the Emacs Lisp code for it. You can copy and paste that into your configuration. For example, setting the keybinding above will result in:

(global-set-key [f10] (quote save-buffer))

You can also write keybindings from scratch. For example, the code below redefines the Return key (or the Enter key) so that it calls the newline-and-indent function by default.

(global-set-key (kbd "RET") 'newline-and-indent)

Remember, ​'newline-and-indent and (quote newline-and-indent) are the same thing – they both refer to the name of a thing (a function, in this case) instead of its value.

(global-set-key (kbd "C-+") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)

These set C-+ (Ctrl and <plus>) and C-- (Ctrl and <minus>) to increase and decrease the font size when you’re running Emacs in a graphical environment.

If you want to set a keyboard shortcut only in particular modes or types of files, jump ahead to Setting keybindings in a particular mode.

What does kbd do? How can I figure out which key it sets?

If you’ve gone through the Emacs Tutorial (Help – Emacs Tutorial or C-h t), you’ll be familiar with many of the conventions used for writing keyboard shortcuts. C- stands for the Ctrl key, M- stands for the Meta key (which is probably Alt or Option on your keyboard). There are other prefixes as well. S- is for Shift, H- is for Hyper, and s- is for Super. Some people use operating system tools (such as setxkbmap for Linux) to change keys on their keyboard to Super or Hyper in order to enable even more keyboard shortcuts.

Uppercase or lowercase depends on the character in the shortcut. C-x means Control + x, while C-X is actually Control + Shift + X. You can also specify shift by adding S-, so C-X and C-S-x are the same.

In addition, there are some special characters: RET, SPC, TAB, and ESC must be written in uppercase to mean the special keys they refer to. (There’s also LFD and NUL, but you’re probably not going to encounter those as often.) You can use angle brackets to refer to some other keys, like <return>, <up>, <down>, <left>, <right>. Function keys are written like this: <f1>.

There are different ways to specify the key. Many people use (kbd ...) because it makes bindings easy to read.

(global-set-key (kbd "M-/") 'hippie-expand)

This is the same as

(global-set-key "\M-/" 'hippie-expand)

or

(global-set-key [?\M-/] 'hippie-expand)

You can use ^ to mean Control, so

(global-set-key (kbd "C-s") 'isearch-forward-regexp)

is the same as either of these lines:

(global-set-key "\C-s" 'isearch-forward-regexp)
(global-set-key (kbd "^s") 'isearch-forward-regexp)

but C- is probably easier to read.

When you use kbd, whitespace doesn’t usually matter, but it’s easier to read if you use space to separate the keys to type. For more information about the syntax used by kbd, see C-h f (describe-function) for kbd, then follow the link to the documentation for edmacro-mode.

In general, you can use C-h k (describe-key) followed by a keyboard shortcut to see if it’s already bound, and if so, what function it calls. If you type C-h k and the key you’re interested in, and Emacs is still waiting for another key, then you’re probably looking at a prefix key. For example, C-x is a prefix key that’s used in keyboard shortcuts like C-x C-e (eval-last-sexp).

Multi-key shortcuts

You can set up keybindings that use more than one key combination. This is a popular technique since you can only have so many short keybindings. For example, the following code changes C-x C-b to call ibuffer, which lists your buffers and makes it easy to jump to another buffer.

(global-set-key (kbd "C-x C-b") 'ibuffer)

You don’t have to start with C-c or C-x. Consider using one of your function keys like <f9> as the start of your keyboard shortcuts. Then you can create shortcuts that don’t involve using Ctrl, Alt, or other modifier keys. For example:

(global-set-key (kbd "<f9> b") 'ibuffer)

Read other people’s configurations to get a sense of useful commands and handy keyboard shortcuts. By convention, shortcuts like C-c followed by a lowercase or uppercase letter are reserved for your use, as are the function keys <f5> to <f9>. Other keyboard shortcuts are likely to already be defined by modes. You can override them if you want.

Some people like using a function key followed by letters in order to minimize the need to press Control or Meta. For example, you might use:

(global-set-key (kbd "C-c r") 'query-replace)

or

(global-set-key (kbd "<f9> r") 'query-replace)

to make it easier to replace strings. You can even bind it to both shortcuts.

Binding keys to other keys

In addition to setting keyboard shortcuts for functions, you can also define keys to expand to a longer sequence of keystrokes. You can use this for inserting strings or calling keyboard macros. For example:

(global-set-key (kbd "<f7> e") "[email protected]")
(global-set-key (kbd "<f7> w") "http://example.com")
(global-set-key (kbd "<f7> u") (kbd "C-x C-s"))

These might be handy for quickly inserting your e-mail address or website.

Dealing with errors: “Key sequence __ starts with non-prefix key _

If you want to create a multi-key shortcut, the preceding keys must not already be assigned to functions. For example, if you want M-t l to call transpose-lines, you’ll need to get rid of M-t‘s default binding to transpose-words first. To unset a key, bind it to nil or use global-unset-key. Here’s a group of shortcuts you can try.

(global-set-key (kbd "M-t") nil) ;; Remove the old keybinding
(global-set-key (kbd "M-t c") 'transpose-chars)
(global-set-key (kbd "M-t w") 'transpose-words)
(global-set-key (kbd "M-t t") 'transpose-words)
(global-set-key (kbd "M-t M-t") 'transpose-words)
(global-set-key (kbd "M-t l") 'transpose-lines)
(global-set-key (kbd "M-t e") 'transpose-sexps)
(global-set-key (kbd "M-t s") 'transpose-sentences)
(global-set-key (kbd "M-t p") 'transpose-paragraphs)

The example above has three bindings for transpose-words. M-t w uses the mnemonic of t-ranspose w-ords. M-t t is similar to the original binding for transpose-words, which was M-t. M-t M-t may seem like overkill, but sometimes you’ll find it easier to hold the Meta key down and hit t twice quickly instead of typing M-t, releasing Meta, and then typing t. As you read other people’s keybindings, you’ll get a sense of how people have configured their keyboard shortcuts to speed up typing and minimize thinking.

Setting keybindings in a particular mode

Sometimes you want keys to do different things in different types of files. Modes are how Emacs changes behaviour based on context. For example, Java files use java-mode, Org files use org-mode, and so forth. In addition to the major mode for a buffer, you may have several minor modes that modify the behaviour. Each mode has a keybinding map (or a “keymap”). You can assign a key in a mode map, which means it will override global keybindings in buffers with that mode. You can do this with define-key if you know the name of the keymap you want to change, which is generally the name of the mode + -map. For example:

(define-key emacs-lisp-mode-map (kbd "C-c f") 'find-function)

changes the C-c f keyboard shortcut to find-function (which jumps to the definition of a function), but only in Emacs Lisp buffers.

Note that if you use define-key with a mode map, the mode must already be loaded by the time this code is run. That’s why you’ll often see this after a require (which loads the code) or inside an eval-after-load (which postpones the code until after the mode is loaded). See Adding more features to Emacs for information on loading packages and adding new functions to Emacs.

Other ways people bind keys

The bind-key package provides a function that makes it easier to see your personal keybindings, but bind-key is not part of Emacs by default. I use bind-key a lot in my configuration. The syntax is similar to global-set-key, except it automatically wraps the keyboard shortcut string in kbd. It also keeps track of which keyboard shortcuts you’ve overridden so that you can use M-x describe-personal-keybindings to review them.

(bind-key "C-+" 'text-scale-increase)
(bind-key "C--" 'text-scale-decrease)

You’ll need to install and use the bind-key package before you can use that code.

Because keybinding is something that lots of people do to customize their Emacs, you may find other ways that people have simplified writing keybindings for themselves. When in doubt, use C-h f (describe-function) to explore how something works. If the function can’t be found, see if it’s in a package somewhere, or search the Web for more information.

For more about keybindings, see the Emacs manual and this Mastering Emacs post on keybindings.

Defuns – function definitions

In addition to the functions built into Emacs or available in packages, many people define their own with the defun function.

People often distinguish custom functions by starting them with my/ or their initials. This makes it easier to tell which functions they’ve customized and which ones are part of a package. It also minimizes the risk of accidentally overriding a function defined elsewhere. You can change the name of a function as long as you make sure you change the name wherever it’s called, such as in keyboard shortcuts, hooks, or other functions.

For example, here’s a custom function from Jorgan Schaefer’s config:

(defun fc/kill-to-beginning-of-line ()
  "Kill from the beginning of the line to point."
  (interactive)
  (kill-region (point-at-bol) (point)))

This creates a function called fc/kill-to-beginning-of-line. () is the argument list. Since it doesn’t contain anything, that means this function does not take arguments. ​"Kill from the beginning of the line to point."​ is a documentation string (or docstring) that describes what the function does. Docstrings are optional, but highly recommended. (interactive) means that this can be called with M-x (execute-extended-command) or bound to a keyboard shortcut.

If a function does not have the (interactive) keyword, you won’t be able to call it with M-x or assign it to a keyboard shortcut, but you will still be able to write Emacs Lisp code that calls the function. This means M-x (execute-extended-command) lists only the commands that people will probably find useful while working directly with Emacs, skipping internal functions used by code.

Once you’ve defined a custom function, you can bind it to a keyboard shortcut if you want. The code below binds the fc/kill-to-beginning-of-line function to C-c C-u:

(global-set-key (kbd "C-c C-u") 'fc/kill-to-beginning-of-line)

You will often see custom functions added to hooks. A hook is a list of functions that’s called by some other code. Modes usually define a hook that’s called after the mode is initialized so that you can further customize its behaviours. For example, emacs-lisp-mode has an associated emacs-lisp-mode-hook which is run when a buffer is set up in Emacs Lisp Mode. You can add built-in functions or custom functions to hooks, and they’ll be run when that hook is called.

People sometimes use hook functions to set up keybindings instead of using define-key. For example, this code:

(add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)
(define-key emacs-lisp-mode-map (kbd "C-c f") 'find-function)

can also be written as:

(defun my/set-up-emacs-lisp-shortcuts ()
  "Set up some conveniences for Emacs Lisp."
  (turn-on-eldoc-mode)
  (local-set-key (kbd "C-c f") 'find-function))
(add-hook 'emacs-lisp-mode-hook 'my/set-up-emacs-lisp-shortcuts)

Lambdas – anonymous functions

Sometimes people just want to create a keyboard binding or process some data without defining a new function. lambda creates an anonymous function, which is a function that doesn’t have a name. Here’s an example:

(global-set-key (kbd "C-c e") (lambda () (interactive) (find-file "~/.emacs.d/init.el")))

This binds C-c e to an anonymous function. The () means it doesn’t take any arguments. (interactive) means it can be called through a keyboard shortcut, although since it’s anonymous, it can’t be called with M-x. The function opens the ~/.emacs.d/init.el file, which is a handy way to edit your configuration.

  1. Look for an Emacs configuration file that defines keybindings that you’re curious about. Install any packages or copy any custom functions needed. Experiment with using those keybindings. Do you like them? Do you want to tweak them further?
  2. Think about how you use Emacs. What kinds of keyboard shortcuts would make your work easier? How can you adapt some of the functions you’ve read into things that would make them even more convenient for you?
You can find the draft of the complete course at emacslife.com/how-to-read-emacs-lisp.html. Enjoy!
Series Navigation« Read Lisp Tweak Emacs [Beginner 2/4]: How to understand what Emacs Lisp code doesRead Lisp, Tweak Emacs (Beginner 4/4): “How can I add more features? How do I deal with errors?” »

Baby steps towards investing

When you’re learning something complex, it can help to break it down into small steps and figure out what sequence is right for you–especially if there are lots of other people who want to influence your decision.

Let’s take investing, for example. There are all sorts of businesses built around making you want to earn more, all sorts of complex instruments that seem to enrich advisors more than clients, and all sorts of decisions that you can make that can either help you or screw up your life. Me, I’m trying to learn slowly.

I’m a simple investor. I don’t need to beat the market. In fact, I’d like to stay as close to average as I can. I don’t need to be smarter than other people who are buying and selling. Even if I have plenty of time, I don’t want to spend that time and attention on tracking financial news. Baby steps – one lesson at a time.

I started by saving up. Then I opened up an investing account with TD and started with their e-series funds, since those had low management expense ratios and no commissions. After years of annually stashing money into TD e-series index funds, I’m now relatively confident about my ability to not panic based on the ups and downs of the market. The stock market has been practically all up since I started, actually. I’ve been investing at the rate I previously set for myself. I haven’t figured out the best way of transferring larger amounts from the corporation yet, but that can wait. In the meantime, it’s a good buffer for emergencies, and it means I can think of corrections as a good thing.

Over the past two years, I’ve gradually learned to think of my TFSA + RRSP + locked-in RRSP + non-registered investments as one big bucket to manage instead of having multiple allocations in multiple accounts. I sold some units (for the first time!) in order to shuffle my allocation around, simplifying my paperwork a little. I still have some duplicates because there’s only so much each account can hold, but ah well. I’ve only ever sold units within tax-sheltered accounts, so I still haven’t gone through the exercise of calculating my adjusted cost base for the e-funds in my non-registered account.

I briefly considered real estate, but I don’t think real estate is the right fit for me (yet? at all?). It’s a big commitment that I don’t know enough about. Sure, there are probably upsides, but there are also scary downsides–especially with Ontario’s tenant laws, which make it difficult to evict people if there are problems.

I’ve also thought about ETFs. After crunching the numbers, I don’t think my portfolio size is large enough to justify switching. I’d probably save a little in fees, but it adds complexity.

For me, the next step is probably to sell a token amount from my non-registered holdings so that I can practice calculating the adjusted cost basis (and so that any tax penalties are also pretty small in case I totally mess up). Slowly leveling up!

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).

Realistic expectations, ruthless elimination, and rapid exploration

“You’re pretty organized, right? Do you have a system for productivity that I could use?” someone said to me. She sounded frustrated by her lack of progress on some long-standing projects. I shrugged, unsure how to help.

I don’t consider myself super-productive. I am, however, less stressed than many people seem to be. I’ve been learning to keep realistic expectations, get rid of less-important tasks, and work in quick, small, useful chunks.

Realistic expectations: We tend to overestimate how much we can do, particularly if we’re looking a week or two ahead. Even if last week was derailed by interruptions, we hope next week will be a smooth ride. I’m guilty of this myself. I compensate by expecting little of myself – just one to three important tasks each day, moving forward a little bit at a time. If I find myself with spare time and motivation, I check my other tasks for something to work on. It’s okay if I end up procrastinating something. That usually means I spent the time on something I valued more.

Ruthless elimination: “But how do I motivate myself?” This is another thing that people often struggle with. I use different strategies depending on what I need. For example, I’m currently working on a project with a high risk of failure and a fair bit of work. For me, it helps to amplify the perceived benefits, downplay the small pieces of work that I need to do (it’s just a small task), and downplay the risks (failure isn’t all that bad). On some other projects, I might decide that my lack of motivation is a clue that I should just wrap up the project, get rid of specific tasks, delegate work, or transform those tasks into things I might enjoy more.

Rapid exploration: After I adjust for realistic expectations and get rid of tasks through ruthless elimination, I think of tiny tasks that will help me move towards my goals. That way, I can explore and get feedback faster. Then I try to get as much value as I can from those steps, usually ending up with blog post ideas and lessons learned in addition to the thing itself. This also means that I can squeeze work into 15- to 2-hour chunks instead of waiting for a 4-hour span of uninterrupted, energetic time.

There are a bunch of other things that help me out (keeping outlines of projects and tasks in Org Mode, documenting as much as I can, knowing my tools well), but those three behaviours above seem to be different from the way many people around me work. Hope that helps!

In the garden

The garden is doing pretty well. We have salad every other day or so, and I’m constantly thinking of recipes to use the herbs before they totally take over the garden. =)

  • Various leafy greens, with tomatoes and peas in the background

    Various leafy greens, with tomatoes and peas in the background

  • The strawberries are tiny

    The strawberries are tiny

  • Garlic, other herbs

    Garlic, oregano, mint

  • The cilantro towers over the other herbs

    The cilantro towers over the other herbs in this planter

  • Thai basil is pretty dense

    Thai basil is pretty dense

  • The sweet basil is quite happy, too

    The sweet basil is quite happy, too