Fe User Guide
Yet another editor? Yes, and like all other editors, its special
design goals may or may not make it your personal favourite. Fe
is a folding editor, often also called outline editor. I believe
that folding is as important as the progress from line editors to
screen editors. Fe is a small editor and needs little resources,
but still offers many advanced commands. Instead of an extension
language, that forces learning yet another programming language
and bloats the editor, it is designed as a C library containing
editor primitives and a user interface module. This module can easily be
changed if you want extensions or a different user interface.
Right now there is only one user interface, which is similar to Emacs,
in particular to the Emacs-like interface of Origami.
Copyright and usage conditions
fe (Folding editor) is copyright (c) by Michael Haardt <firstname.lastname@example.org>, 1995-2003.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
The source is available from http://www.moria.de/~michael/fe/.
First things first
The first thing you will notice in fe is the status line, which tells you
a lot: If it starts with a star,
the buffer contains unsaved changes. Then comes the version number
of the editor. After, enclosed in parentheses, you see the current
fold language and any modes you should be aware of. Next is the file
name associated with the buffer you are editing. If switched on, it
is followed by the cursor position. As the last, you see the current
local time, which can also be switched off.
At the bottom of the screen is the prompt line. If you type a command
that consists of multiple keys, you will see any typed but not yet
processed keys. The notation for keys is:
Several commands print a prompt and put you in a line editor in the
prompt line. This command line editor has a history function,
used by the cursor up and down keys. There are history
lists for the following things:
- Hold the CONTROL key while pressing the character chr.
Thus, C-f would be: hold the CONTROL key and press f.
Some people may be used to see ^F or CTRL F, here it is
- If your keyboard has a META key, that prefixes the character with an
ESC, then hold it down while typing chr. Alternatively,
press the ESCAPE key and release it, then press the character
- Hold down META and CONTROL while typing chr.
If you have no META key, then press the ESCAPE key and
release it, then hold the CONTROL key while pressing the character
The command line editor further does file name completion with the
tab key (C-i).
- File names
- Line numbers
- Strings to search for or replace
Although it is commonly said that you edit a file, what you really doing
is loading the file into a buffer in memory, edit this buffer and later
write it back into a file. As such, if you do not save the buffer, all
your work, no matter how much, is lost. It is advised to save regularly,
because the system might crash because of a software or hardware failure.
If you are a new user, then read below for the most important commands:
- This brings you into the main menu. Using the menu is slower than
directly typing the commands you want to use, but if you are a new
user, it may help you until you know all commands. You can leave any
menu with C-g.
- Save the buffer and exit the editor.
- C-x C-c
- Exit the editor. If there are unsaved changes, you will be asked if
you want to exit anyway, which means to lose the changes.
- Redraw the screen. This is useful after you received output from
or talk(1), or if you got line noise.
Files and Buffers
- C-x C-b
- Name buffer.
- C-x C-i
- Insert file. The mark will be set at the beginning of the inserted
file and the cursor will be at its end.
- C-x C-r
- Load buffer from file. The mark will be set to the end of the file and
the cursor to its beginning.
- C-x C-s
- Save buffer to file.
- C-x C-w
- Save buffer to a different file. Fe will ask for a file name and if you want to
omit all fold marks. Sometimes people insist on getting files that do not contain
all those confusing braces. ;-)
Many commands take an numerical argument. In general, a positive argument
repeats the command as often as the argument says, whereas a negative
argument repeats the opposite commands as often. Nevertheless, read
the description of each command to get to know what an argument does
for it, if anything at all.
- This starts setting a negative argument.
- If used as the first command to set an argument, this sets a positive
argument. Once you start setting an argument, you can type regular
digits or M-digit to continue typing the argument.
Moving the cursor
Moving the cursor is an important thing in an editor.
The most basic commands are:
previous line: C-p
backward character: C-b <---+---> forward character: C-f
next line: C-n
If you use an argument, any of these will be repeated argument times.
A negative argument will repeat them just as much, but in the opposite
direction. If your terminal supports cursor keys, those will work as
Knowing these commands gets the job done, but it will not be efficient
on bigger files. For that reason, you should also look to use the more
complicated cursor movement commands, they make editing more pleasant and
save much time:
- Go to the beginning of the line. If the cursor is already at the first
non-white space character of the line, it will go to the very first
character of the line, else to the first non-white space character.
Press C-a a few times to see how it works.
- Go to the end of the line. If the cursor is already at the last
non-white space character of the line, it will go to the very last
character of the line, else to the last non-white space character.
- C-v, next page
- Go to the next page or until the end of the current fold. If an
argument is given, this causes repetition of this command. If the
argument is negative, the cursor will move to the previous page or the
beginning of the current fold.
- M-v, previous page
- Go to the previous page or until the beginning of the current fold. If
an argument is given, this causes repetition of this command. If the
argument is negative, the cursor will move to the next page or until the
end of the current fold.
- Go to the beginning of the buffer.
- Go to the end of the buffer.
- Go to the last line inside the fold.
- Go to the first line inside the fold.
- Move one word forward.
- Move one word backward.
- Go to line. The number of the line if given by the argument, if you
specify one, else you will be prompted for it.
- Center display (put the current line in the middle of the display).
This is not a cursor motion, but it saves moving the cursor to get just
the same effect.
- Go to matching fence, that is a matching paren, brace or bracket.
- Delete the character under the cursor. You can not delete fold marks or
remove a newline which could cause two fold marks to be in one line. An
argument causes deletion of argument characters under the cursor,
a negative argument causes deletion of -argument characters left
to the cursor.
- C-m, Return
- Insert a newline character and indent the new line as much as the
previous line. If auto-indent mode is switched off, C-m and
C-j have reversed meanings.
- C-j, Linefeed
- Insert a newline character. If auto-indent mode is switched off,
C-m and C-j have reversed meanings.
- Delete the word right under the cursor. You can not delete fold marks
or remove a newline, that could cause two fold marks to be in one line.
An argument causes deletion of argument words under the cursor, a
negative argument causes deletion of -argument words left to the
- Delete the word left to the cursor. You can not delete fold marks or
remove a newline, that could cause two fold marks to be in one line. An
argument causes deletion of argument words left to the cursor, a
negative argument causes deletion of -argument words right to the
- C-h, backspace
- Delete the character left to the cursor. You can not delete fold marks
or remove a newline, that could cause two fold marks to be in one line.
An argument causes deletion of argument characters left to the
cursor, a negative argument causes deletion of -argument
characters under the cursor.
- Quote character. Sometimes you may want to insert a character, that is
also part of an editor command. The solution is to quote the character
using this command. Example: C-q C-@ inserts a null character.
Further, this function composes ISO-8859-1 characters from ASCII
characters using the same pair used by many terminals and X11 servers,
e.g. ss gives a sharp s and a" gives a small a with
diaeresis. A positive argument inserts as many characters as specified.
- Transpose characters.
- C-x =
- Describe line.
- Capitalise word.
- Lower case word.
- Upper case word.
- C-x #
- Insert the value of the counter and increment it.
Regions and the kill ring
A region is the amount of text between an invisible mark you can set
and the cursor. For many operations, like removing regions, they must
respect the fold structure, i.e.amp; you can not remove a region, that only
contains the begin of a fold. Similar to the cursor, typing at the mark
position pushes the mark forward, so when edit a previously empty buffer,
the mark will always be at its end until you set it elsewhere.
Besides the buffer, that holds your file contents, there is a ring of
buffers for text you have killed (which means removed, erased,
wiped out). You can yank any element of this ring back to your text.
This is universal, as it allows you to duplicate killed
text, move it, exchange regions of text and much more. Kill commands
that directly follow each other will append the killed text to the
current ring element, but if you do anything else in between, a new
element will be created.
The following commands manipulate regions and the kill ring:
- Set the invisible mark, which marks one end of a region at the current
cursor position. On some terminals, you have to type C-@, on others
CONTROL-space is fine. Some even accept both. Some ancient ones
accept neither, which is why there is a second, less handy, keyboard
- C-x C-x
- Swap cursor and mark.
- This command kills all text from the cursor position to the end of the
line. If the concerned part contains the beginning of a fold, the whole
fold will be killed. If the line is empty, the terminating new line
character will be killed. This is a short-cut for setting a mark, moving
the cursor appropiately and killing the region.
- Kill region.
- Copy region.
- Yank kill ring element back.
- Replace the just yanked back text with the previous element of the kill ring.
That way you can browse through the kill ring until you found what you are
looking for. A negative argument moves forward.
- C-x C-f
- Filter region. The marked region will be read as standard input by
the command which name you will be prompted for. The standard output
of this command replaces the marked region, if the command terminated
successfully and if it could be read correctly. Further, the old and the
new contents are put in the kill ring, so if filtering did not generate
the intended result, you can walk back in the kill ring with M-y
to get the old region back. A common application of this function is
to reformat a paragraph by filtering a region through
- C-x |
- Pipe region. The marked region will be read as standard input by
the command which name you will be prompted for. The standard output
of this command will be placed in a new buffer. This command is useful
diction, or just any command that analyses
- Fold region.
- Open fold.
- Close fold. A positive argument closes the given number of folds, a
negative argument opens them.
Search and replace
- Incremental search. This differs from the usual searching by searching
as you type what to search for, so you can stop typing the rest of the
search string if you already found what you were looking for by typing
its beginning. Incremental search has the following commands:
- C-h, backspace
- Delete the last character from the search string.
- Move to the next occurence of the search string in the buffer and switch
search direction to forward.
- Move to the previous occurence of the search string in the buffer and
switch search direction to backwards.
- C-p, cursor up
- Switch to the previous search string in the history.
- C-n, cursor down
- Switch to the next search string in the history.
- Quote/compose character.
- C-g, cancel
- Abort searching, move the cursor back to where it was before starting
incremental search. The search string will not be stored in the history.
- Quit searching and leave the cursor where it is. The search string will
be stored in the history.
- any other character
- Append the character to the search string.
- Incremental search, but starting with search direction backwards.
- Search backwards, go to the last line, that contains the string you will
be prompted for.
- Search forward, go to the next line, that contains the string you will
be prompted for.
- Search and replace. You will be promted for what to search and what
to replace it by. If no argument is given, all occurences of the search
string from the cursor position until the end of the text will be
replaced. An argument limits the number of substitutions and a negative
argument causes searching backwards.
- Query search and replace. You will be promted for what to search and
what to replace it by. If no argument is given, you will be asked for
each occurences of the search string from the cursor position until the
end of the text, if you want to replace it. An argument limits the
number of substitutions and a negative argument causes searching
backwards. The replace menu offers the following choices:
- Replace the string and proceed.
- Do not replace the string and proceed.
- Rest, !
- Replace the rest without asking any more.
- Do not replace the string and abort.
- Replace and abort, .
- Replace the string and abort.
Modes and variables
Modes are switches, that change the general behaviour of the editor
for a certain buffer:
The following modes exist:
- C-x m mode
- Adds (enables) the specified mode.
- C-x C-m mode
- Deletes (disables) the specified mode.
Additionally, the insert key toggles insert/overwrite mode.
- Show begin and end marks of a file in a fashion similar to Origami.
- Auto-indent mode. While being in this mode, return causes the new
new line to be indented as much as the previous line, while C-j just
creates a new line. If auto-indent mode is switched off, the two keys
have the reversed function.
- Display the line number of each line.
- Magic mode. Searching (regular and incremental) will search for regular
expressions instead of strings.
- Overwrite characters instead of inserting them. You can not overwrite
newline characters or fold marks and no auto-indenting will be done
in overwrite mode.
- Show the cursor position in the status line.
- Read-only. This mode is automatically set, if you load a file on which
you have no write permission. Fe will offer to check in a file to an
RCS archive, if you set this mode and offer to check it out if you
delete the mode.
- Always redraw the screen immediatly instead of only redrawing it when
there are no characters typed ahead.
- Scroll the whole screen sideways instead of only scrolling the current
- Show the current local time in the status line.
- Display fold marks in a bold font.
In contrary to modes, which can only be switched on or off, variables
can be set to one of many values.
The following variables exist:
- C-x : variable
- Set the specified variable.
- Display/window size. The size of a window can be changed by setting this
- Set the folding language, which determines which comments will be used
to encapsulate fold marks.
- Tab width. Setting the tab width to 0 causes tabs to be displayed
- Counter/increment. The counter is global for all displays, whereas the
other variables are per-display. It is handy when enumerating
something and usually used in recorded macros. Its default value is 0
and the default increment is 1.
Sometimes during editing, you will find that you press the same
key sequences over and over. In that case you should record the
sequence of keys once and then replay it when you need it. Such
a recorded sequence of keys is called a macro. The following
commands deal with macros:
- C-x (
- Start recording a macro.
- C-x )
- Stop recording a macro.
- C-x e
- Execute the previously recorded macro. A positive argument repeats
the number of executions.
Windows make editing considerably easier. You can split your screen
and either edit the same file in two windows (which is why windows
are called displays at times) or edit different files.
The following commands split and merge windows:
- C-x 2
- Split the screen in two windows.
- C-x 0
- Delete the current window.
- C-x o
- Switch to the next window.
The following commands are the interface to the shell:
- C-x c
- Start an interactive sub-shell.
- C-x !
- Start a non interactive shell command.
- Suspend fe.
A few words on the design of fe
After working with Origami for many years, both as user and developer,
I have decided to implement a new folding editor: fe. There are a few
basic design decisions which make it different from Origami:
Origami is partially written in its extension language. While being
more of a hack in the beginning, it has changed to a full programming
language. As such, it takes time to be learnt. Code written in it is
not well usable by most people who don't know it. The conclusion for
fe is not to support any extension language, neither a homebrew one or
a standardised language, like scheme. Instead, fe is implemented as
a library of basic editor primitives. Its is easy to write your own
editor by using that library. fe can be modified easy without
having to learn a new programming language. The editor also stays
small and elegant this way, while Origami has to offer zillions hooks
for extension functions.
Origami implements folds as double-linked n-trees, with nodes being
single lines or folds. This allows quick manipulation of folds
or lines. But region oriented functions become hard to implement and are
mostly not too quick any more. fe uses a gap buffer to store text, folds
are represented as meta-characters in the flat buffer. This means basic
fold primitives are slower than in Origami, but more complex and region
oriented functions are faster. During development of the first prototype
of fe, I found many functions in Origami not to be as canonical as they
should be after I implemented them in fe. From my past experience, the
performance of typical personal computers to have increased by a factor of 10
every 5 years in the last decade, so the circumstances for
editor design have clearly changed over time.
Folding has its merits, because it adds a structure to flat files. But,
it also means that by bad structure design and badly commented folds
the file will get harder to understand, not easier. This can happen
up to the point where you want all folds to be gone to see what the
file contains. If you need to keep many folds open during development
to see their contents, you are probably prepraring that situation at
least for others. Although in general I don't like programs forcing
me to do something, fe makes an exception here for two reasons: If the
structure is obvious, you want the editor to close folds for
you automatically. If it is not, you want to recognise that
before it is too late. For that reason, fe closes all folds when you leave them.
If you want to transport code from one fold to another, just split the
current display and edit the file at two places. If both places are
sufficient far away from each other, that's what you even had to do if
you could leave folds open.