In class today, we will once again write compile and edit a program, just as we did last time. This time, however, we will do all of the work inside the emacs editor.
Though Unix does not have a graphical user interface, the emacs editor is almost as good as one. It lets you split the window and lets you work on two things at the same time. It also makes it easy to find syntax errors and to debug programs.
Emacs and g++ are both written by the Free Software Foundation, and they work well together. You can edit, compile and run your program without leaving the emacs editor. The advantage of working this way is that all of the commands that work the same way.
Emacs is not the easiest editor to learn, and you might have guessed form the size of the book that describes it. Still, learning emacs is a crucial skill to have if you write programs. If you major in Computer Science, it will be invaluable.
To get started, log onto your account on Troi. Once there, start emacs by typing ``emacs'' at the command prompt.
1 troi% emacs
Lets look at the screen right now. The most obvious thing about it is there is a line in inverse video at the bottom of the screen that starts ``-----Emacs *scratch*.'' Above that line is a window that shows the contents of the buffer called *scratch*, below the line is a window that shows the contents of a buffer called the mini-buffer. The large buffers are regions in memory that are set aside for you to enter text into the editor; the mini-buffer is where commands appear.
So far we have seen the following terms:
GNU Emacs 19.19.3 of Mon Nov 15 1993 on bridge.cc.rochester.edu (berkeley-unix) Copyright (C) 1993 Free Software Foundation, Inc. Type C-h for help; C-x u to undo changes. (`C-' means use CTRL key.) To kill the Emacs job, type C-x C-c. Type C-h t for a tutorial on using Emacs. Type C-h i to enter Info, which you can use to read GNU documentation. GNU Emacs comes with ABSOLUTELY NO WARRANTY; type C-h C-w for full details. You may give out copies of Emacs; type C-h C-c to see the conditions. Type C-h C-d for information on getting the latest version. -----Emacs: *scratch* (Lisp Interaction)--All---------------------------
Emacs uses three keys keys that shift the meaning of the letters on the keyboard: the shift key, the control key, and the meta key. The shift key is the most familiar. As on a typewriter, holding down the shift key changes the character typed from lower case to upper case. I will just use the capital letter to designate holding down the shift key. (e.g. X instead of x) You are probably also familiar with the control key. It works like the shift key except that instead of sending a bit stream corresponding to a capital letter, it sends a bit stream that a program interprets as a command. I will use C- to as a prefix to a letter to denote holding down the control key while typing. (e.g. C-x instead of x. Note that C-X means that you hold down the control key and the shift key while hitting the x key.)
Finally the meta key is probably the key that you are least familiar with. Unfortunately, few modern keyboards have meta keys, so we must make use of the escape key. You have to hit the escape key, which is usually in the upper left hand corner of the keyboard and which is usually labeled ``esc.'' The escape key does not work like the control key does; you hit it once, then hit the key you want to use. I will denote the meta key by M- (e.g. M-x instead of x. Note that M-X means hit the escape key once, then hold down the shift key while typing ``x''. M-C-X means hit the escape key once then hold down both the control and the shift key while typing ``x''. If you hold down the escape key, you will see ``Eval:'' in the minibuffer.
So far we have seen three key description conventions, all of which can be combined.
With these conventions and terms in mind, let's start generating the
files we will need. Today, we will create two files:
hello_world.cc and hello_world.h. We will want to keep
the files together, so first create a directory called Hello to
hold the files. Remember, from your home directory type mkdir
Hello.
Emacs associates files with buffers. That is, when you open a file with emacs, it reads the contents of the file into a buffer. You can then edit the file and write it back onto the secondary storage from which it came.
The command for loading a file is C-x C-f. Let's try loading a
file called hello_world.h from the Hello directory.
First hit C-x C-f. Notice that the minibuffer now says
Find file: ~/. Emacs is telling you that it is looking for a
file in your home directory. We want the file to be in the
Hello directory, so we type Hello/hello_world.h into the
minibuffer. This tells emacs that we want to edit the file called
hello_world.h in the Hello directory.
The first thing you will notice is that that the following information appears in the buffer.
// // hello_world.h // // Nat Martin, csc171@cs.rochester.edu, 17 Jan 1997 // Time-stamp: <> // #ifndef _hello_world_h #define _hello_world_h #endif
This information appears whenever you create a file with a .h
extension. It will have your name, your user name, and the time and
date at which you last saved the buffer. In addition, it has several
lines that begin with #. These lines tell the compiler to load
the file only once. We will discuss these lines more when we talk
about pre-processor directive. For now, just make sure that
everything you write is between the #define _hello_world.h and
the #endif
Notice that the inverse video line in emacs changes so that it now
begins with ----Emacs: hello_world.h Emacs is telling you that
it has created a buffer called hello_world.h. This buffer,
when it is saved, will be saved in a file called hello_world.h.
Also, the minibuffer says ``(New file)''. This tells you that there
was not already a file called hello_world.h.
Emacs is now ready for you to type in the contents of
hello_world.h. Add void hello_world(); to the file.
When you are done, The buffer should like like this:
// // hello_world.h // // Nat Martin, csc171@cs.rochester.edu, 17 Jan 1997 // Time-stamp: <97/01/17 11:29:46 csc171> // #ifndef _hello_world_h #define _hello_world_h void hello_world(); #endif
You will need to use the delete key to erase items from the
keyboard, and not the backspace key. If you use the
backspace key you will see C-h (Type ? for further
options)- in the minibuffer. Hit C-g to ignore the command
and continue with the delete key.
The C-g command tells emacs to abort the command you are doing. It is a good thing to try when you don't know what is happening.
The arrow keys will move you around the buffer. The command C-d
deletes the character immediately under the cursor. This means that
the <delete> key tends to delete from the left and the C-d
command tends to delete from the right.
When you have complete typing in the hello_world.h, save it.
The command to save a file in emacs is C-x C-s. Hitting this
command will make the minibuffer say Wrote
/u/cs/martin/Hello/hello_world.h.
When you have saved your makefile, load another one by using the
command C-x C-f. This time the minibuffer will say ``Find
file: /Hello/.'' Emacs is asking you which file in the directory
Hello you want to edit. Emacs always starts from the directory
that the current file came from. Because the hello_world.h is
in Hello, it guesses that you want to open another file from
that directory. It is right this time. Open a file called
``hello_world.cc''.
When the file opens add information until it looks like this:
//
// hello_world.cc
//
// Nat Martin, csc171@cs.rochester.edu, 17 Jan 1997
// Time-stamp: <>
//
#include <iostream.h>
#include "hello_world.h"
main()
{
hello_world();
}
void hello_world()
{
cout << "Hello world\n";
}
Notice the line #include "hello_world.h". This tells the C++
compiler to insert the file we wrote earlier before it compiles the
program.
The old buffer hello_world.h has not gone away, it is just
hidden under the hello_world.cc buffer. You can switch back
and forth between the files using the command C-x b. (Note that
is is C-x b, not C-x C-b. If you type C-x C-b
you will get a second window with a list of buffers. To make the
second window go away type C-x 1.) The command C-x b
prompts you for a buffer to switch to. Hit <enter> to go back
to the hello_world.h buffer. Once there type C-x b to get
back to the hello_world.cc buffer.
Once you have finished typing in the program, you will want to compile
and run it. The command to compile a program (in emacs) is
C-c C-c. When you type in the command, the minibuffer will say
Compile command: g++. Type hello_world.cc and hit
return. Note that the compile command g++ hello_world.cc is
the same command you typed at the Unix shell prompt last time. Here,
we are using emacs as our shell.
cd ~/Hello/ g++ hello_world.cc Compilation finished at Fri Jan 17 12:29:46
If you do not see this, check your hello_world.cc and
hello_world.h to make sure you typed them in correctly.
Compiling the program has split your window in half; hit C-x 1
to make it go back to a single window.
When you have compiled your program, run it. The program runs from
the Troi prompt, but emacs give you a way to get there without leaving
the editor. The command to get a Troi prompt inside an editor buffer
is C-c s. When you type this command the line separating the
buffer will notify you that your are in a buffer called
*shell*, and in the window you will see a Troi prompt. This
will work the same way that the usual Troi prompt works.
To see the program work, type a.out at the Unix prompt. That is
the name you gave the program when you compiled it.
Go back to the hello_world.cc buffer, and change the world
cout in the next to the last line with cot. Now try
compiling it again using C-c C-c. This time they compilation buffer
will look like this:
cd ~/Hello/ g++ hello_world.cc hello_world.cc: In function `void hello_world()': hello_world.cc:18: `cot' undeclared (first use this function) hello_world.cc:18: (Each undeclared identifier is reported only once hello_world.cc:18: for each function it appears in.) Compilation exited abnormally with code 1 at Fri Jan 17 12:38:46The compiler is telling you that there is a syntax error in you program. Hit C-x ` (The second symbol is a back-quote, it is in the upper left hand side of your keyboard. Do not confuse it with the apostrophe or single-quote which is next to the return key. On the Macintosh, you will have to hold down the Apple key while you hit they backquote key. Otherwise the key will send an Escape.) When you hit this combination of keys, the cursor should jump to the line that has
cot in it. Change cot back to cout and
compile again.
The process we have just complete will be the process by which you write programs. Once you have completed a design, you will go into a cycle of editing, compiling, and running until the program is complete. It is much easier to write programs if you do not add very much to the program before compiling and running it. As a rule of thumb, you should not add more than five lines before compiling a program, and you should not add more than ten lines before running a program.
The steps are as follows:
a.out to run the program