\section{Previous work}
\label{sec-previous-work}

\subsection{Representing items in a buffer}

There are two basic techniques for representing the items in an editor
buffer, namely \emph{gap buffer} and \emph{line oriented}.

\subsubsection{Gap buffer}
\label{sec-previous-gap-buffer}

A gap buffer can be thought of as a vector holding the items of the
buffer but with some additional free space.  In a typical gap-buffer
implementation, a possibly empty \emph{prefix} of the buffer content
is stored at the beginning of the vector, and a possibly empty
\emph{suffix} of the content is stored at the end of the vector,
leaving a possibly empty \emph{gap} between the prefix and the suffix.
This representation is illustrated in \refFig{fig-gap-buffer}.

\begin{figure}
\begin{center}
\inputfig{fig-gap-buffer.pdf_t}
\end{center}
\caption{\label{fig-gap-buffer}
Gap buffer.}
\end{figure}

Buffer items are moved from the end of the prefix to the beginning of
the suffix, and vice-versa, in order to position the gap where an item
is about to be inserted or deleted.  The typical use case for text
editing has a very high probability that two subsequent editing
operations will be \emph{close} to each other (in terms of the number
of items between the two).  Therefore, in most cases, few
items will have to be moved, making this data structure very
efficient for editing operations corresponding to this use case.

Clearly, in the worst case, all buffer items must be moved for every
editing operation.  This case happens when editing operations
alternate between the beginning of the buffer and the end of the
buffer.  Even so, moving all the items even in a very large buffer
does not represent a serious performance problem.  For example, on a
64-bit 3MHz%
\footnote{For this experiment, memory latency is of course much more
  important than CPU clock frequency.  We intend this experiment to
  provide a rough idea of the expected performance, rather than exact
  number, which is why detailed information on the system is omitted.}
Intel-based GNU/Linux system purchased in 2010 and runing
SBCL, using the \commonlisp{} function \texttt{replace} to move $10^8$
full words in a vector takes less than a second, and that number of
words is several orders of magnitude larger than most files being
edited.  Furthermore, the pathological case can be largely avoided by
considering the vector holding the items as being \emph{circular} (as
Flexichain \cite{flexichain} does).

The gap-buffer representation has one great advantage, namely that a
large region of text can be treated as a single interval, even when
the region covers several lines of text.  Newlines are handled just
like any other character, making operations on a region simple no
matter how large that region is.

Perhaps the main disadvantage of representing the entire buffer as a
single gap buffer is that it is difficult to associate additional
information with specific points in the buffer.  One might, for
instance, want to associate some state of an \emph{incremental parser}
that keeps track of the buffer content in a more structured form.
One possible solution to this problem is to introduce a \emph{cursor}%
\footnote{What we call a \emph{cursor} in this paper is called a
  \emph{point} in GNU Emacs terminology.} at the points where it is
desirable to attach information.

Another difficulty with the gap-buffer representation has to do with
updating possibly multiple \emph{views}.  As we discussed in
\refSec{sec-introduction}, views are updated at the frequency of the
event loop, whereas the manipulation of \emph{regions} of items and
especially the use of \emph{keyboard macros} may make the frequency of
editing operations orders of magnitude higher.

Finally, using a gap buffer for the entire buffer makes it more
difficult to handle multiple threads of control that simultaneously
update different parts of the buffer, such as in a scenario with
collaborative editing, or when the buffer is updated by a running
program while a user is editing that same buffer.

\subsubsection{Line oriented}
\label{sec-previous-line-oriented}

Another common way of representing the editor buffer recognizes that
text is usually divided into \emph{lines}, where each line typically
has a very moderate number of items in it.

In a line-oriented representation, we are dealing with a
\emph{two-level sequence}.  At the outer level, we have a sequence of
lines, and each element of that sequence is a sequence of items.
Every possible combination of representations of these two sequences
is possible.  However, since the number of items in an individual line
is usually small, most existing editors do not go to great lengths to
optimize the representation of individual lines.  Furthermore, while
the number of lines in a buffer is typically significantly greater
than the number of items in a line, a typical buffer may contain at
most a few thousand lines, making the representation of the outer
sequence fairly insignificant as well.

Perhaps the main disadvantage of a line-oriented representation
compared to a gap-buffer representation is that transferring items to
and from a file is slower.  With a gap-buffer representation, the
representation in memory and the representation in a file are very
similar, making the transfer almost trivial.  With a line-oriented
representation, when a buffer is created from the content of a file,
each line separator must be handled by the creation of a new
representation of a line.

However, with modern processors, the time to load and store a buffer
is likely to be dominated by the input/output operations.
Furthermore, the number of lines in a typical buffer is usually very
modest.  For that reason, a line-oriented representation does not
incur any serious performance penalty compared to a gap buffer.

Another disadvantage with a line-oriented representation is that
operations on regions that span over several lines become more
difficult.  For example, deleting such a region, may involve deleting
one or more lines, and modifying the contents of the line where the
region starts as well as the one where it ends.

\subsection{Updating views}

When interactive full-display text editors first started to appear,
the main issue with updating a view was to minimize the number of
bytes that had to be sent to a CRT terminal; this issue was due to the
relative slowness of the communication line between the computer and
the terminal.  To accomplish this optimization, the \emph{redisplay}
function compared the previous view to the next one, and attempted to
issue terminal-specific editing operations to turn the screen content
into the updated version.  Of course, most of the time, the task
consisted of positioning the cursor and inserting a single character.

Today, there is no need to minimize the number of editing operations
on a terminal; it is perfectly feasible to redraw the entire view for
each iteration of the event loop.  However, today we have many more
requirements on a text editor.  In the most advanced cases, we would
like for an \emph{incremental parser} in the view to keep a structured
version of the buffer content, for various purposes, such as syntax
highlighting, language-specific completion and parsing, etc.  An
incremental parser may require considerable computing power.  It is
therefore of utmost importance that as little work as possible is done
each time around the event loop.  Representing the entire editor
buffer as a gap buffer does not lend itself to such advanced
incremental processing.

In fact, most existing editors have very primitive parsers, mainly
because the buffer representation does not necessarily lend itself to
efficient incremental parsing.

\subsection{Existing editors}

\subsubsection{GNU Emacs}

GNU Emacs \cite{CraftOfTextEditiing,GNUEmacsLispReferenceManual} uses
a \emph{gap buffer} for the entire buffer of text, as described in
\refSec{sec-previous-gap-buffer}.

Creating sophisticated parsers for the content of a buffer in GNU
Emacs is not trivial.  For that reason, existing parsers are typically
fairly simple.  For example, the parser for \commonlisp{} source code
is unable to recognize the role of symbols in different contexts, such
as the use of a \commonlisp{} symbol as a lexical variable.  As a
result, syntax highlighting can become confusing, and indentation is
sometimes incorrect.

\subsubsection{\multics{} Emacs}

\multics{} Emacs%
\footnote{The description in this section is a summary of the
  information found here: http://www.multicians.org/mepap.html}
\cite{Greenberg:1980:MEC:800087.802784}
was the first Emacs implementation written in \lisp{}, specifically,
\multics{} \maclisp{}.  It therefore pre-dates GNU Emacs.

\multics{} Emacs used a doubly linked list of lines, with the line
content itself separate from the linked structure.  All but a single
line were said to be \emph{closed}, and the content of a closed line
was represented as a compact character string.

For the current line, a new \maclisp{} data type was added to the
\multics{} \maclisp{} implementation, and it was called a
\emph{rplacable string}.  Such a string could be seen as an ordinary
\maclisp{} string, but could also have characters inserted or deleted
through the use of primitives written in assembler and using special
instructions on the GE 645 processor.

\subsubsection{Climacs}

Like GNU Emacs, Climacs%
\footnote{https://common-lisp.net/project/climacs/}
uses a gap buffer for the entire buffer.  It
avoids the bad case by using a circular buffer.  In fact, it uses
Flexichain \cite{flexichain}.

Climacs is able to accommodate fairly sophisticated parsers for the
buffer content.  But in order to avoid a complete analysis of the
entire buffer content for each view update, such parsers must be
\emph{incremental}.

Information about the state of such parsers at various positions in
the buffer must be kept and compared between view updates.
Unfortunately, the gap-buffer representation does not necessarily lend
itself to storing such information.  The workaround used in Climacs is
to define a large number of \emph{cursors} to hold parser state at
various places in the buffer, but managing these cursors is a
non-trivial task.

\subsubsection{Others}

Hemlock%
\footnote{https://www.cons.org/cmucl/hemlock/index.html}
uses a doubly linked list of lines.  Each line is a \texttt{struct}
containing a reference to the previous line and a reference to the
next line.  No more than one line is \emph{open} at any point in time,
and then the content is stored separately in a gap buffer.  The
gap-buffer data is contained in special variables and not encapsulated
in a class or a \texttt{struct}.

Goatee%
\footnote{Goatee is part McCLIM which can be found at this location:
https://github.com/robert-strandh/McCLIM}
was written to be the input editor of McCLIM.  Like Hemlock, it
uses a doubly linked list of lines, with the difference that the line
content itself is separate from the doubly linked structure.  Lines
are represented by a gap buffer.  The gap buffer is encapsulated in
a library called Flexivector, which was later extended to become the
Flexichain library.

To take one example that is not a member of the Emacs family, VIM%
\footnote{https://github.com/vim/} represents the buffer contents as a
tree of blocks.  A block contains one or more lines of text.  A line
can not span block boundaries.  Most blocks are exactly one page (as
defined by the operating system) in size.  Only a block containing a
(single) line that is larger than one page can be larger than a page.
Blocks are file backed, making it possible to represent text buffers
that are larger than the swap space of the computer.
