Reading by Marge Coahran

CSC201: Memory Management, Data Representation, and Formal Methods
Grinnell College


Laboratory: The Emacs Text Editor

Summary: This laboratory will introduce you to Emacs, one of the earliest and most popular text editors for UNIX and "UNIX-like" systems.

Prerequisites: Familiarity with the bash shell.

Contents:

In your previous courses you used Integrated Development Environments (IDEs), such as Eclipse and Dr. Scheme, to develop your programs. Similar IDEs exist for C, but it is more traditional among C programmers to use separate programs for editing, compiling, and debugging C code. Since part of the focus of the course is to become familiar with Linux and the UNIX tradition, we will follow this approach.

There are several text editors available on Linux in the MathLAN. The two that are the most commonly used by C programmers are Emacs and ViM. This laboratory will introduce you to Emacs, and an upcoming laboratory will introduce you to ViM. After you have gotten a good feel for both of them, I would like you to choose one of them to work with for the remainder of the course.

Exercises

Exercise 0: Preparation

Using the Linux utilities you have learned, create a file in your own account that contains the names and departments of all Grinnell faculty members. Recall that this data can be found in the following files:
  ~coahranm/share/csc201/humanfac.txt
  ~coahranm/share/csc201/sciencefac.txt
  ~coahranm/share/csc201/socialfac.txt

Exercise 1: Emacs Preliminaries

Keystroke Combinations

Emacs allows many editing operations to be performed via keystroke commands as well as via toolbar icons and menu selections. I highly recommend learning the keystrokes since they can be faster once you know them. However, I also warn you that they are likely to seem a bit foreign at first (i.e., many of them are really keystroke combinations, not single keystrokes), and they also conflict with the keystrokes you have probably already learned in the Windows environment. Ah well, what can be done?

Emacs also uses an unconventional notation for naming the keystrokes. Here are some examples, and what they mean:

Key combination: C-x C-f
Means: Hold down the ctrl key and press x, then lift the x key and press f. The ctrl key should be down when you press f. It does not matter whether you do or do not lift it in between.

Key combination: C-x 2
Means: Hold down the ctrl key and press x, then lift both keys and press 2.

Key combination: M-w
Means: The documentation refers to pressing the "Meta" key here, but on modern keyboards, use the Alt key instead. Thus, this key combination means hold down Alt and press w.

I will use this notation in the remainder of the lab since it is used in the Emacs help system and the Emacs menus.

Launching and Exiting Emacs

To launch Emacs, call it by name and (optionally) add the name of a file that you want to open. Since you will probably find it convenient to launch Emacs as a background process, you should also append an ampersand to the end of the command. Either example below works.

   emacs &
   emacs filename &

If you open Emacs without specifying a file to open, you will see an Emacs splash screen, and if you click on it, a "scratch buffer" will appear. This can be disconcerting at first, but it is harmless. (Go ahead and try this now, to see what I mean.)

You should resist the temptation to delete the text in the scratch window and begin typing there. Rather, if your intent is to begin a new file, you should "open" the file as described below, using a new file name. This will present you with an empty buffer to type in.

To exit Emacs, type C-x C-c (where the meaning of this is as described above).

Please try out any of the operations described above that you have not yet tried, so that we may proceed.

Opening, Closing, and Saving Files

To open a file from within Emacs, type C-x C-f. Then note the "command buffer" at the very bottom of the Emacs window. It should contain a prompt "Find file:" and a default directory (the directory from which you launched Emacs). Type the name of the file you want to open, and press Enter.

Note that to create a new file, you also "open" it as just described. Thus, from the outset, the file will be associated with a name.

Open the file which contains your copy of the Grinnell faculty listing. Then open a new file, naming it anything you like.

Note that there is no difficulty with having multiple files open at once. Each one is associated with an "input buffer." You can see a list of your open buffers or switch between buffers by selecting the Buffers menu, at the top of the Emacs window. Try using the Buffers menu to switch between the two files you have open.

If you don't feel like using the mouse, you can also switch buffers by going through the motions of "opening" the buffer you want again. Emacs knows it is already open, and will simply switch buffers.

To save a file, type C-x C-s.

To close a file, select Close (current buffer) from the File menu. To my knowledge there is no keystroke for this action. If you find that you really want one, you can define one yourself.

Cancel-ling Partial Commands (i.e., Getting Un-Stuck)

To cancel a partial command, type C-g (i.e., ctrl-g).

When might you need to do this? Suppose you intend to open a file, so you press C-x C-f. Now the command buffer is waiting for input, but suppose you change you mind. To clear the command buffer, make sure your cursor is in the command buffer, and then type C-g.

Go ahead and try this now, the better to help you remember it when you need it.

When you are first learning Emacs, it may happen every so often that you type a command key combination without intending to. Now the command buffer wants input from you, but you want it to go away. If you don't notice at first what the problem is, Emacs may start beeping at you, in an inarticulate attempt to get you to stop typing your whole program in the command buffer. You can use the mouse to put your cursor back in the edit butter, but you will find that the command buffer still lurks, and the next time you want to use it for something else, all you get is more beeping! A few go-rounds of this may render you inarticulate as well. But never fear, C-g to the rescue!

Backup Files, Autosave Files, and File Recovery

Backup Files:
If you open an exiting file and begin to edit it, the first time you save the file, Emacs writes the new version with the file's normal name, but it also retains the previous version and adds a tilde to the end of the name. For example, after you edit and save faculty.txt, you will have two files: faculty.txt and faculty.txt~.

Check your directory: you may already have a backup file there.

As you continue to work, it does not matter how many times you save your changes, the backup version of the file will still be the version that existed when you opened it.

Autosave Files:
As you work, if you have unsaved changes, Emacs will periodically create and update an autosave file. The name of the autosave file will be #filename#. Yes, indeed, the # characters are part of the file name.

Make some minor change to one of your open buffers, and then (without saving the change) look at a listing of the files in your current directory. You should see the autosave file there.

When you save your changes, Emacs will remove the autosave file. Try this, and confirm the behavior by getting another file listing.

Thus, if you save your changes before exiting Emacs, there will be no autosave file left behind. However, if you exit without saving your changes, or if Emacs closes abnormally for some reason, the autosave file will be retained, and it can be used to recover your changes.

File Recovery:
To recover your changes when a file was closed abnormally, open the file as you normally would (i.e., open the file you want to recover, not the autosave file). Then type M-x recover file. (Yes, you have to type both the keystrokes and the words.) Emacs will give a prompt in the command buffer, and you respond with the name of the file to be recovered (not the autosave file). Finally, Emacs asks if you really mean it, and you answer yes. Hopefully, you will never need this feature, but it is nice to have when you need it.

Exercise 2: Cursor Movement and Editing Operations

Now let's practice editing files with Emacs. To get started, please open the file you made that lists the Grinnell College faculty.

Cursor Movement

First off, let's practice navigating around within the file. Of course, much of this will come naturally to you -- you can use the arrow keys, the Page Up and Page Down keys, or the mouse to move your cursor position in obvious ways.

What may not be obvious though is how Emacs behaves when you scroll down past the bottom of the current screen. Give that a try now, and then try the opposite -- scrolling back up past the top of the current screen. This behavior may seem strange at first, but I think you will get used to it quickly.

It is also nice to have keystrokes that move you around the file more quickly than simple scrolling. Try the Home and End keys. If you prefer not to move your hands away from the normal typing position, you will find that Ctrl-a and Ctrl-e have the same effect.

Now try out what each of the four arrow keys does when combined with the Ctrl key.

Finally, try Ctrl-Home and Ctrl-End, as well as Ctrl-PageUp and Ctrl-PageDown. (Hereafter, I recommend avoiding Ctrl-PageDown, but if you ever see that result again, you will know how to recover: Ctrl-PageUp.)

Now please take a moment to notice the "mode line" near the bottom of the Emacs window. It should look something like the following:

--:--  faculty.txt         (TEXT)--L35--16%-------------------------------

Try moving around the file, while watching the mode line to determine what information is being displayed. Similarly, try making a change to the file, and then saving the file. How does this affect the mode line?

The entry "(TEXT)" indicates that Emacs recognizes the file to be a text file. Emacs recognizes many file types, including html and various programming languages. You will find the fact that Emacs knows when you are writing a C program to be very useful, but more on that a bit later on.

Editing Operations

To prepare for the next exercise, please move your cursor to the top of the file.

Searching
To search for a given word within a document, you begin with the keystroke C-s. Go ahead and try this. You should see the prompt I-search: appear in the command buffer. (I-search stands for incremental search, and you will see why in a moment.)

Suppose you want to search for the entry for Sam Rebelsky. For now, please type only the letter R to see what happens. Then add an e and observe the result. Finally add a b, and you should find the correct entry. Of course, Emacs does not yet know that you have found your target, so you need to tell it to leave search mode by pressing Enter.

Now suppose you want to search for Henry Walker, but you can't recall his last name. Please start a new search, and find the word "Henry." Uh-oh. I expect that you will find a "Henry," but not the one you want. To look for a second instance of "Henry," simply press C-s again. (Do not press Enter to re-start the search from scratch.)

Try pressing C-s a few more times. You should observe that after reaching the bottom of the file, the search wraps around to the top of the file and continues.

What happens if you search for an entry that is not in the file? Please think up an uncommon name to search for, or search for "Sigfried."

If you prefer to search upward through the file, it works the same way except that you begin with C-r (for "reverse").

Deleting Text
You will find that the Backspace and Delete keys work in the natural way.

It is also nice to be able to delete larger portions of text at a time, so try out Ctrl-Backspace and Ctrl-Delete to see what they do.

Next, experiment with C-k. What does it do? Does it matter where on the line you are positioned when you press it? One thing I frequently make use of is the following: position your cursor at the beginning of a line, and then press C-k twice.

You can also delete large portions of text by highlighting the text with the mouse, and then pressing C-w. Sure, why not give it a try.

Next, consider highlighting a portion of text with the mouse and then pressing delete. What do you expect to happen? What does happen? This is not the way to delete large tracts of text in Emacs, but you may find yourself doing it from time to time out of habit. (Unfortunately, although you will find it easy to learn the new Emacs keystrokes, you will probably also tend to use the wrong keystrokes from time to time when you switch back and forth between different applications.)

However, one thing you may have noticed by now is that the Emacs keystrokes do match the keystrokes available in the bash shell. This is because, by default, bash uses the Emacs keystrokes as its own. Once you have learned to use the ViM editor later this week, if you find that you prefer it, you can tell bash to obey the ViM keystrokes instead.

Undo-ing changes!
Luckily, we are also able to undo recent changes in Emacs. The keystroke for this is a bit awkward, but when you really want to undo, you'd probably be willing to do worse! To undo your last change, press C-_ (that is, ctrl-shift-hyphen or ctrl-underline). Nothing confusing about that... surely not.

Luckily again, you can use undo repeatedly. Go ahead and make a few changes to the file, and then undo several of them.

Cut/copy and paste
When you use any of the keystrokes you just learned for deleting text (except for the simple Backspace or Delete keys), the text that was cut is stored in a "cut buffer." You can then paste the current contents of the cut buffer using the keystroke C-y (or by pressing the "middle mouse button"). Give it a try now.

When you repeatedly cut text using keystrokes, and without performing some intervening operation such as moving the cursor or typing, the repeated cuts are appended to the cut buffer. Try cutting the names of several consecutive faculty members from the list, and then pasting them back, either in the same location or a different one.

So how do you copy text? One option is to cut the text, immediately paste it back, and then paste it again in the new location. Another option is to highlight the text with the mouse. This action replaces the contents of the cut buffer with the highlighted text (just as it usually does in Linux), and you can then proceed to paste the text where you want it with C-y. Go ahead and try both of these approaches to get used to them.

But now let me add a word of warning. It is wise, when you have a cut buffer that you want to paste somewhere else, to move to the desired location using keystrokes, rather than clicking in the new location. Why? Suppose you bobble just a little on the click, such that you accidentally highlight a letter or a line. What happens then? Your cut buffer gets overwritten by the bobble. That is mildly frustrating if the contents of the buffer was something you had copied into the buffer. It is worse if it is something you had cut into the buffer, but even then all is not lost. Just don't forget about undo!

At this point, it would probably be a good idea to try enacting the error described in the last paragraph to see it in action. Cut some large amount of text that you really wouldn't want to lose, and then "bobble" when you move to a new position in the file by highlighting a single character instead. Now paste. Ouch! Undo!

Exercise 3: Goodies for Programmers

Working with multiple windows open
It is frequently nice when programming to have two source files open (and visible) at once. In Emacs, this can be done by splitting your window. To try this, type C-x 2. Where you had one window before, you now have two.

At present both of the windows will be displaying the same file. This can actually be useful, since you can arrange to have the two windows display different portions of the file. If you choose to use it this way, you can edit text in either or both windows to update the file.

Alternatively, you can open a second file in one of the windows. To try this out, go ahead and open some other file, perhaps a source code file you wrote in a previous course.

The next thing you will want to know how to do is to move your cursor between the two windows. Certainly you can do this with the mouse. You can also do it with C-x o (where the last key is a lower-case letter o). What does that stand for? I don't know, maybe "other window"?

Now let's resize the windows. This can be done with the mouse, but it takes a bit of practice. The difficulty is to get the mouse in the right spot, and I think the following is the easiest way: position your mouse over the gray bar (the mode line) between the two windows, but do so toward the right side of the bar where there are lots of hyphens. When you see the mouse icon turn into a vertical double-headed arrow, you can click and drag the bar vertically. Go ahead and give it a go.

When you want to revert to having only a single window open, type C-x 1 (i.e., "I want one window open now").

An important aside: Please do not increase the width of your Emacs window when you are writing programs. This is because, if you do so, you will start producing source code that has a non-standard width. Who cares? Anyone who wants to look at your code in an Emacs window that has not been widened exactly as you widened yours, and anyone who wants to look at a printout of your source code. (If you generate source code that is very wide and then print it, or look at it in a standard size Emacs window, your long lines will wrap around quite unpleasantly. The resulting code will look terrible. It really will. And your professors and future employers are likely to take serious offense at code that looks terrible.)

Compiling programs from within Emacs
Here is a little C program (much littler than the corresponding Java program):

  #include <stdio.h>

  int main() {
    printf("Welcome to CSC201.\n");
    return 0;
  }

Please open a new file called welcome.c, and enter the program. Next, let's compile the program from the terminal window. (After that I'll show you how to arrange things such that you can compile it within Emacs.)

To invoke the GNU C Compiler, type the following command at the bash prompt.

  gcc -Wall welcome.c
(The -Wall option asks gcc to report all warnings, and I highly recommend that you make a habit of using it. In C you are likely to get many warnings, rather than compilation errors, for true bugs. This happens when the syntax you have used is not strictly illegal, but it may mean something quite different than what you intended.)

If you did not get any error messages, you should now have a compiled version of the program in a file named a.out in your current directory.

Run the program by typing "./a.out". Note that if you simply type "a.out", it probably will not work. This is because your current directory is unlikely to be on the search path which Linux uses to find executable programs, so Linux will not find the program. Pre-pending "./" to the file name tells Linux to look in the current directory.

Next, select Compile... from the Tools menu. You should see the following appear in the command buffer: make -k. That is the command we will use later in the course for compiling C programs that contain multiple files. However, until we learn about makefiles, the command won't work. So press C-g to get rid of it.

Instead, let us modify your Emacs configuration file to make Emacs use the compile command you just learned instead. Open the Emacs configuration file, which is located in your home directory and is named ".emacs". (Many complex programs have configurations files in your home directory with names that begin with a "dot".)

Now add the following lines to the bottom of the file:

   ; Set gcc (instead of make -k) as the default compile command.
   (setq compile-command '"gcc -Wall ")

Save your work, close Emacs, and re-open it. Doing so will invoke the commands in the updated configuration file.

Now re-open welcome.c, and select Compile... from the Tools menu. This time you should see the (partial) command "gcc -Wall " appear in the command buffer. Complete the command by typing welcome.c, and press Enter.

You should find that a new version of ./a.out has been created.

Emacs is smart about TABs
To see what I mean, remove all indentation from your welcome.c program, such that every line of code begins at the left margin. (I know it hurts, and you wouldn't be caught dead writing programs without nice indentation, but do it just this once.)

Now move your cursor to the line with the printf() function call, and press TAB. Voila! Emacs knows from your braces how far the line should be indented.

Now move your cursor to the middle of the return line, perhaps placing it on the space. Press TAB again. Double-voila! There is no need to move your cursor to the beginning of the line to get automatic (correct) indentation.

Now add an if-statement to the program, but leave the indentation crummy for just a moment. Perhaps something like the following:

  #include <stdio.h>

  int main() {
  int n = 3;

  if (n = 3)
    printf("Welcome to CSC201.\n");
  else
    printf("Welcome to the Twilight Zone.\n");

    return 0;
  }

Now, starting with the first line that is indented incorrectly, step through each line of your program, pressing TAB on each one, and Emacs will fix your indentation as you go.

It may not be obvious from this small example just how useful this feature is. But when you have a large program, and you make a structural change like adding an if-statement, it can be very nice to use a single keystroke per line to fix the indentation. Further, if you get in the habit of using this feature, you will find that Emacs can help you identify errors in the placement of your braces. (It will indent based on your braces, and if the indentation is not what you expect, your braces are not correct!)

Exercise 4: Parting Thoughts

Here are two more tips that you may find helpful, under right circumstances.

First, there are times when you may want to edit a file using Emacs, but you would rather not use the GUI interface. I do this every now and then. For example, it is necessary if I want to edit a file directly in my MathLAN account while working at home because I have a "high-speed connection" that transmits data at a paltry 1.5 Mbits/sec. This is not nearly fast enough to work with a GUI. (Note that hardwired connections transmit data at 100 Mbits/sec these days.) To open Emacs without the GUI interface, use the command option -nw, which stands for "no window" as follows: "emacs -nw filename". Give it a try. All the keystrokes you have learned will still work, but the mouse won't.

Second, if your colleagues, professors, or coursework start to get you down, you may want to get some help from the Emacs psychiatrist. Select Emacs Psychiatrist under the Help menu.


Written by Marge M. Coahran, January 2008.