My Emacs Writing Setup

Due to the interest in my post on Writing Tools, I’ve published an HTML document on my Emacs writing setup.

If you want to know how I plan and plot stories, you may find the document interesting.  You’ll probably find it more interesting if you use Emacs yourself.

A Note on Emacs

I think of Emacs as a text editors’ tool. As I spend most of my life working with text, either programming or writing, I want to do it as efficiently as possible.
It first struck me when I was editing my novel Divergence just how inefficient I was being in pressing the arrow key and waiting for the cursor to get to where I wanted. That got me thinking about the time spent deleting text, transposing words, moving around paragraphs… I realised there must be a quicker way.
And then I remembered Emacs.

It makes sense for someone who spends most of their time manipulating text to learn a group of obscure key combinations. It saves time and increases productivity. Learning to use Emacs properly reminds me of playing Jazz on the piano. I’ve learnt all those chords and runs and fills so that I can use them without thinking when I’m improvising. Likewise, I’ve practised using Emacs key strokes such as M-f, M–M-c and C-M-<Space> so often I use them without thinking when editing. I rely on M-/ to complete words, and I can’t do without M-h and C-e to select and move around text.

I practice using Emacs because it makes me a more productive writer. If you’re interested, I’ve written up some of those tips and exercises on my Emacs Workout.

Calc Mode 1: Binary Numbers

Thanks to Andrew Hyatt for inspiring this entry

Here’s how to use Emacs to convert 8 numbers to binary. Why? Read on…

  1. Write the numbers: 127, 54, 32, 178, 199, 244, 3, 255
  2. Mark the region of the numbers and hit C-x * g. This grabs the numbers into calc mode as a vector
  3. In calc mode, hit d 2 to display the numbers in binary
  4. Still in calc mode, hit d z to show the leading zeroes. This shows them as 32 bit words
  5. Hit b w 8 to set the word size to 8 bits.
  6. Finally, and still in calc mode, hit y to yank the numbers back into the last buffer you were using.
  7. Add a table, tidy things up, and you’ve got a worksheet like the one below for a set of students and the answers for yourself.

Convert the 8 bit unsigned numbers to denary

  1. 01111111
  2. 00110110
  3. 00100000
  4. 10110010
  5. 11000111
  6. 11110100
  7. 00000011
  8. 11111111

Emacs Characters

Who would have thought that three dots could cause so many problems?

Most of the Aethernet Magazine writers use the ellipsis …

The Guardian Style Guide suggests leaving a space before and after the ellipsis.

In the Aethernet style guide the ellipsis is always followed by a space

“Is it… ?”

“Yes… ”

Preparing texts proves to be an interesting Emacs exercise.

It’s easy to search for three dots … , but there also exists a unicode character …
Now, as everyone knows, Emacs characters are saved as integers. You can insert any character on Emacs by hitting C-q and then the appropriate code in octal, in this case:

C-q 20046       gives …

If you want to enter the codes in denary, evaluate the following: (setq read-quoted-char-radix 10)

Evaluate the above and now…

C-q 8230 gives  …

Better yet, place the code in your .emacs file. Set the value to 16 if you want to quote in hexadecimal.

It’s easy to find a character’s value:

C-x = gives information about a character under the point.

For example, the ellipsis gives

Char: … (8230, #o20046, #x2026, file ...)

There are easier ways to insert non-keyboard characters using C-x 8

C-x 8 ' e prints é
C-x 8 `e prints è
C-x 8 ^ e prints ê
C-x 8 " u prints ü
C-x 8 / / prints ÷
C-x 8 C prints © copyright

The above are just a few examples

C-x 8 C-h to see all characters

If you want to hurry (dépêcher in French) you might get tired of typing C-x 8 all the time. The following allows you to omit the C-x 8 section

M-x set-input-method latin-9-prefix

Okay, what now… ?

Air Force Collaboratory

The US Air Force have sent me details of details of their Air Force Collaboratory project, which they describe as “the first collaborative platform dedicated to solving some of our science and technology challenges.”
As it says on their website

Solving the Air Force’s toughest challenges requires a collaboration platform unlike any other. The Collaboratory was built from the ground up so you and a community of peers could work alongside real Airmen on real Air Force projects. Your idea could change everything. So let’s get started.

This looks to be a well designed website working on high end problems, you might find it fascinating…

Find out more here: https://collaboratory.airforce.com/

Upgrading to Ubuntu 13.10

I’ve just upgraded some of the computers in my house to Ubuntu 13.10. The main PCs, the ones used by my wife and I are still on Ubuntu 12.04 LTS, due to the fact that they are essential to our jobs. We can’t afford a break in work whilst we sort out an unsuccessful upgrade.

Aethernet Magazine is due out in three days time. We’ve been caught out before by broadband outages, hardware failures, and simple but the worst trouble we’ve had was my upgrading to org mode 8 just days before going to press. Org mode 8 is a worthwhile upgrade, but we wasted valuable time having to read up on the new features and configuration settings when we should have been upgrading.

So why bother upgrading the other computers?

Because this is how we pay back the open source community. There are complaints about the direction that Ubuntu is going, about the Unity interface, about Amazon sponsorship of search results. And all this is right and proper, these debates will determine the future direction of the software, maybe not such much as we would like, but there are always other operating systems. Personally, I like the Unity interface, the only thing that really irritates me is the fact the menu items appear at the top of the screen. But that’s just my opinion, and, actually, it’s irrelevant to the question of upgrading.

At the end of the day, we are getting an operating system for free. Installing the upgrades mean we’re submitting crash reports and bug fixes. It can be a pain, particularly if the system doesn’t reboot as happened to me on two PCs with the upgrade to 13.04. Actually, it can be more than a pain: it’s incredibly annoying, particularly when something that was working before the upgrade, like the sound, stops working. It’s frustrating, it’s annoying, it can leave you cursing the stupid developers who released this incomplete implementation. But’s the deal. Things are going to go wrong. That’s why you’re upgrading. If you don’t like it, stick with the LTS version. If it’s really that bad, switch to another distro, or better yet go to Microsoft or Apple.

After all, they’re perfect. They never go wrong.

Similar Entries

Repeating Commands

Repeating Commands

C-x z   Repeats the last command.  Hitting z repeatedly keeps on repeating that command.

Once you know this trick, many other apparently complicated Emacs commands suddenly become clear. For example, why is the command to widen a window the extremely time consuming C-x }? That takes four keypresses on my keyboard, as I have to hold down shift to access the }. Surely it’s faster to use a mouse?
Not if you remember C-x z. Try it now:

C-x 3   Split into two vertical windows
C-x }   Widen the window one space
C-x z   Repeat the last command.  Now hit z until the window is wide enough.

Granted, this is still pretty complicated at first sight. If you’ve stumbled across this page whilst looking for something else you’re probably wondering why on Earth anyone would want to use Emacs, but that’s to miss the point. C-x z is another useful command that you can chain together with others to produce new results.

Whilst we’re here, here’s some useful window commands to remember

C-x -   Shrink the window to the size of the buffer text, if it's smaller
C-x +   Make windows the same size
C-x 4 0 Kill buffer and window
C-M-v   Scroll other window down
S-C-M-v Scroll other window up

 

3 Interactive Functions that work on Regions

1 Start Point, End Point and Contents of a Region

The following function prints the contents of the selected region, together with its start and end points.

1: (defun region-contents (rStart rEnd)
2:   "Prints region contents of region selected, and the start and end positions of that region"
3:   (interactive "r")
4:   (setq rStr (buffer-substring rStart rEnd))
5:   (message "The string of the selected region is %s.  It starts at  %d and ends at %d"  rStr  rStart rEnd)
6: )

2 Iterate through the words in a region

You might want to iterate through the words in a selected region. The following function gives an example of this, it prints out the words in the region in reverse order.

1: (defun reverse-region-message (rStart rEnd)
2:   "Reverses order of words"
3:   (interactive "r")
4:   (setq myStr (buffer-substring rStart rEnd))
5:   (setq myWords (split-string myStr))
6:   (setq reversed (reverse myWords))
7:   (message (mapconcat 'identity reversed " "))
8: )

Note the use of the following functions:

  • split-string: splits the string into a list of words
  • reverse: reverses a list
  • mapconcat: Convert a list into a string

It’s interesting to compare the mapconcat function with the concat function. Note that concat does not accept lists, as you might expect at first glance. You can get round this using the apply function.

(concat "this" "that" "other") => "thisthatother"
(concat '("this" "that" "other")) => error
(apply 'concat '("this" "that"  "other")) => "thisthatother"
(mapconcat 'identity '("this" "that" "other") " ") => "thisthatother"

Here’s the function, rewritten to delete the selected region and to replace it with the words in reverse order.

1: (defun reverse-region (rStart rEnd)
2:   "Reverses order of words"
3:   (interactive "r")
4:   (setq myStr (buffer-substring rStart rEnd))
5:   (delete-region rStart rEnd)
6:   (setq myWords (split-string myStr))
7:   (setq reversed (reverse myWords))
8:   (insert (mapconcat 'identity reversed " "))
9:  )

3 Iterate through the letters in a region

You can spend a lot of time writing code to solve a problem only to find that Emacs Lisp already provides a function to do what you want.
For example, suppose you want to iterate through the letters in a region to convert SEPARATE to S-E-P-A-R-A-T-E. The easiest way is to use the mapconcat function, as seen in the previous section.

(mapconcat 'string "SEPARATE" "-")

Here’s the separator as a function that operates on the selected region.

1: (defun region-seperator (rStart rEnd)
2:   "Reverses order of words"
3:   (interactive "r")
4:   (setq rStr (buffer-substring rStart rEnd))
5:   (delete-region rStart rEnd)
6:   (insert (mapconcat 'string rStr "-"))
7:  )

3.1 string-to-list, mapcar and apply

The function string-to-list converts a string to characters.

(setq rStr (string-to-list "example")) => (101 120 97 109 112 108 101)

use char-to-string to convert a character code to a string

(char-to-string 101) => "e"

Note the use of apply, as discussed previously.

(apply 'string (reverse (string-to-list "example"))) => "elpmaxe"

Note that apply returns a value. If you want a list of characters, use mapcar

(mapcar 'char-to-string (string-to-list "example")) => ("e" "x" "a" "m" "p" "l" "e")

Remember, mapcar returns a list, apply returns a value. Many of the errors you make when beginning come down to confusing the two return types.
Finally, use a lambda function (discussed later) for complex functions in mapcar

(mapcar 'char-to-string (mapcar '(lambda (x) (+ x 1)) (string-to-list "foo")))

4 Enclose a Region

This tutorial has been written using emacs org mode. The code samples are marked up using the tags

#+BEGIN_SRC emacs-lisp -n
and
#+END_SRC

I wrote the following function to make the markup easier. Now I just select the region and run the function. The appropriate tags are placed at the start and end of the region.

1: (defun myMark-elisp-region (rStart rEnd)
2:   "Mark region as Elisp source code for org mode export."
3:   (interactive "r")
4:   (save-excursion
5:     (goto-char rEnd) (insert "\n#+END_SRC\n")
6:     (goto-char rStart) (insert "#+BEGIN_SRC emacs-lisp -n\n"))
7: )

Note the use of the save-excursion function to return the point to where it was before the function was run. Note also the way the above function is laid out. An interesting exercise is to reverse the order of lines 5 and 6. See if you can figure out why the function doesn’t work as you might expect.

5 Find and Replace in a Region: Strip Smart Quotes in a Region

These are smart quotes: “ ” ‘ ’
For editing purposes I sometimes need to replace these with the plain quotes ” and ‘. I only want this to replacement to occur on a specified region of text, not on the whole buffer.
Here’s a function to do this. It narrows to a region, uses save-restriction to remember how things were before the narrowing and then uses two regex searches to find first double quotes and then single quotes, replacing both with plain quotes.

 1: (defun strip-smart-quotes (rStart rEnd)
 2:   "Replace smart quotes with plain quotes in text"
 3:   (interactive "r")
 4:   (save-restriction
 5:   (narrow-to-region rStart rEnd)
 6:   (goto-char (point-min))
 7:   (while (re-search-forward "[“”]" nil t) (replace-match "\"" nil t))
 8:   (goto-char (point-min))
 9:   (while (re-search-forward "[‘’]" nil t) (replace-match "'" nil t))
10: ))

6 Choosing between Operating on a Region or the Whole Buffer

The previous example only stripped smart quotes from the selected region. This function uses the (when (uses-region-p) …) construction to determine whether or not a region is selected. If no region is selected, the whole buffer is operated upon.

 1: (defun region-or-buffer ()
 2:  "Strip smart quotes from region, or whole buffer if region not set"
 3:  (interactive)
 4:  (save-excursion
 5:    (save-restriction
 6:      (when (use-region-p) (narrow-to-region (region-beginning) (region-end)))
 7:      (goto-char (point-min))
 8:      (while (re-search-forward "[“”]" nil t) (replace-match "\"" nil t))
 9:      (goto-char (point-min))
10:      (while (re-search-forward "[‘’]" nil t) (replace-match "'" nil t))
11: )))

Next: Yodaizer – Manipulating Strings Example

7 GTD: Doing

  • If you’re not totally sure what your job is it will always feel overwhelmed
  • Lack of time is not the major issue. Things rarely get stuck because of lack of time, they get stuck because the doing of them has not been defined
  • You can’t do a project, you can only do the action steps it involves

It’s very easy to get caught up in your GTD system and to forget about the actual doing part.

Decide what to do according to the following four criteria:
– Context
– Time Available
– Energy Available
– Priority

If you’ve tagged your tasks properly you’ll have, for example:

Context: a list of phone calls to make when you’re on the phone, or emails to browse whilst sitting on a train

Time Available: A list of quick jobs to do when you have the odd five minutes

Energy Available: A list of jobs requiring little mental or creative horsepower

Priority: A calendar telling you what you must do today

I find it especially useful to tag the five minute jobs and the low energy jobs. I usually do the five minute jobs when I’ve got a little spare time before teaching a class, the low energy jobs can be fun things to read or enjoy.

Related Links

6 GTD: Reviewing

Now that you’ve got yourself organised, you need to remind yourself what the jobs are that you need to do.

Review appropriate lists at appropriate times. For example

  • Check Calendar at the start of the day
  • Look at General Tasks to be done
  • When on the phone, look for tasks marked phone
  • When in a meeting, look at the tasks for that meeting

Review your whole system once a week.

  • Check Calendar for forthcoming events
  • Check projects have a Next Action
  • Check Next Actions are being performed
  • Check Wait list to see if anything needs chasing
  • Check Maybe list to see if anything is ready to proceed
  • Pause or drop projects that aren’t going ahead

If you’re not up to date at the weekly review you won’t be able to convince yourself that your system is remembering for you. You’ll go back to worrying that you’ve forgotten something.

Related Links

5 GTD: Organize

One mistake I made at the beginning was to try and process and organize as I collected. What I mean by this is I’d try and write jobs under different headings in my GTD file as I was collecting them. This is a mistake. One of the key principles of GTD is you only do one thing at a time. If you’re collecting, you shouldn’t be organizing.  Collecting is dealt with in a previous post.  Let’s assume you’ve collected, now it’s time to organize.

Organizing involves putting the jobs into the appropriate categories: writing them under the appropriate heading, if you like.

Here are example headings I use for my general GTD file:

  • General Tasks
  • Dated (Scheduled) Tasks
  • Waiting Tasks
  • Meeting with Julie
  • Meeting with Links
  • Meeting with Craig
  • Maybe
  • View, Watch, Read
  • Long Term

The Dated Tasks should go in your calendar.

The Waiting Tasks are those for which I’m awaiting a response. For example, a reply to an email or an answer to a query.

Note how I have separate headings for regular meetings with different people.

The View, Watch, Read heading is for books, video clips, articles I would like to read if I had more time. I look at the things here when I have the odd ten minutes.

The Maybe heading is for things I don’t have time to do at the moment. I review this occasionally, and may get round to them someday.

Long Term tasks are mainly reminders of things that will happen in at least a year’s time: reminders of contract renewals etc.

I also have a reference file and a projects file. These two have a section all to themselves, later on in this tutorial.

Organising is important. It might seem from the above that all you’ve done is simply moved your todo list around, but what you’ve really done is separated out your “inbox”. You’ve separated the reference from the actions, and eliminated the chaff. This is the secret of GTD. It’s simple but effective.

Related Links