\chapter{Writing new implementations}

\section{Introduction}

In general, we advise against the \texttt{:use} of packages other than
the \texttt{common-lisp} package.  For that reason, in the remainder
of this chapter, we use explicit package prefixes to make it clear
what symbols are referred to.

\section{Writing new line implementations}

\subsection{Package}

It is generally a good idea to define a new package for a new
implementation of the concept of a line.  For the remainder of this
section, we use the name \texttt{new-line} for this package.

\subsection{Classes}

A class that is a subclass of \texttt{cluffer:line} must be provided.
In the remainder of this section we refer to this class as
\texttt{new-line:line}.

It is not mandatory to provide any implementation of the \emph{cursor}
abstraction, but if such an abstraction is provided, it is recommended
that the root class of all cursor classes be a subclass of
\texttt{cluffer:cursor}.  In the remainder of this section we refer to
this class as \texttt{new-line:cursor}.

Both the \emph{standard line}
\seesec{sec-implementation-standard-line} and the \emph{simple line}
\seesec{sec-implementation-simple-line} provide two kinds of cursor
abstractions, namely \emph{left-sticky} cursors and
\emph{right-sticky} cursors.  If the new implementation provides
different kinds of cursors, the different behavior can be accomplished
either by subclassing as is done in both provided implementations, or
it can be accomplished by some other means such as storing additional
information in slots of the root class.

\subsection{Methods}

In addition to the methods documented in this section, a new
implementation may define methods on generic functions for which
default methods are provided.

In particular, \sysname{} provides default methods on many cursor
operations such as \texttt{delete-item}, \texttt{forward-item},
etc. that call more basic generic functions to accomplish the task.
It might be advantageous for performance reasons for a new
implementation to define methods on such functions in addition to the
ones document here.

\Defmethod {item-count} {(line \texttt{new-line:line})}

This method should return the number of items in \textit{line}.

If the new implementation defines subclasses of \texttt{new-line:line}
for which the item count is computed differently, as is the case for
the standard line \seesec{sec-implementation-standard-line} then this
method must be replaced by a method for each subclass with a specific
way of computing the item count.

\Defmethod {item-at-position} {(line \texttt{new-line:line}) position}

This method should return the item at \textit{position} in \textit{line}.

There is no need to check that \textit{position} is a valid item
position in \textit{line}.  This check is already taken care of by an
auxiliary method on \texttt{item-at-position}.

As with \texttt{item-count}, if the new implementation defines
subclasses of the root class \texttt{new-line:line} for which the item
at a particular position is computed differently, as is the case for
the standard line \seesec{sec-implementation-standard-line} then this
method must be replaced by a method for each subclass with a specific
way of computing the item count.

\Defmethod {insert-item-at-position} {(line \texttt{new-line:line}) item position}

This method should insert \textit{item} at \textit{position} in
\textit{line}.

There is no need to check that \textit{position} is a valid insertion
position in \textit{line}.  This check is already taken care of by an
auxiliary method on the generic function
\texttt{insert-item-at-position}.

\Defmethod {delete-item-at-position} {(line \texttt{new-line:line}) position}

This method should delete the item at \textit{position} in \textit{line}.

There is no need to check that \textit{position} is a valid item
position in \textit{line}.  This check is already taken care of by an
auxiliary method on the generic function
\texttt{delete-item-at-position}.

\Defmethod {items} {(line \texttt{new-line:line})}

This method should return all the items in \textit{line}.

The generic function \texttt{items} is typically not called by
implementations of the buffer protocol; only by client code.
Therefore, the data type used to return the items is a matter between
the line implementation and the application.  Both the simple line
\seesec{sec-implementation-simple-line} and the standard line
\seesec{sec-implementation-standard-line} return the items as a simple
vector.  For applications that allow only character items, it might be
a good idea to return the contents as a string instead.

It is even possible to omit this method altogether, since it is always
possible for client code to obtain the items of a line by calling the
generic function \texttt{item-at-position} for each possible position
of the line.

\Defmethod {cursor-attached-p} {(cursor new-line:cursor)}

This method should return \emph{true} if and only if \textit{cursor}
is currently attached to a line.


\Defmethod {cursor-position} {(cursor new-line:cursor)}

This method should return the position of \textit{cursor} in the line
to which \textit{cursor} is attached.

There is no need to check that \textit{cursor} is attached to a line.
This check is already taken care of by an auxiliary method on the
generic function \texttt{cursor-position}.

\Defmethod {(setf cursor-position)} {new-position (cursor new-line:cursor)}

This method should set the position of \textit{cursor} to
\textit{new-position} in the line to which \textit{cursor} is attached

There is no need to check that \textit{cursor} is attached to a line.
This check is already taken care of by an auxiliary method on
\texttt{(setf cursor-position)}.

There is also no need to check that \textit{new-position} is a valid
cursor position in the line to which \textit{cursor} is attached.
This check is already taken care of by another auxiliary method on the
generic function \texttt{(setf cursor-position)}.

\Defmethod {cluffer-internal:line-split-line} {(line new-line:line) position}

This method should split \textit{line} at \textit{position} and return
the newly-created line, i.e., the line that holds the items that are
initially located after \textit{position} in \textit{line}.

Cursors that are initially located after \textit{position} in
\textit{line} should be detached from \textit{line} and attached to
the newly-created line.

Cursors that are initially located exactly at \textit{position} can
either be left attached to \textit{line} (and will then be at the
end), or they can be detached from \textit{line} and attached to the
newly-created line (and will then be at the beginning).  Both the
simple line \seesec{sec-implementation-simple-line} and the standard
line \seesec{sec-implementation-standard-line} provide two different
kinds of cursors, namely \emph{left-sticky} and \emph{right-sticky}
cursors that behave differently in this situations in that left-sticky
cursors remain in the initial line and right-sticky cursors will be
attached to the newly-created line.

\Defmethod {cluffer-internal:line-join-line} {(line1 new-line:line) line2}

This method should join \textit{line1} and \textit{line2} by adding
the items of \textit{line2} to the end of \textit{line1}, detaching
any cursors attached to \textit{line2}, and attaching those cursors to
\textit{line1} in the appropriate position.

\section{Writing new buffer implementations}

\subsection{Package}

It is generally a good idea to define a new package for a new
implementation of the concept of a buffer.  For the remainder of this
section, we use the name \texttt{new-buffer} for this package.

\subsection{Classes}

A class that is a subclass of \texttt{cluffer:buffer} must be
provided.  In the remainder of this section, we refer to this class as
\texttt{new-buffer:buffer}.

A class that is a subclass of \texttt{cluffer-internal:dock} must be
provided.  The purpose of this class is to serve as an intermediate
between a line and the buffer in which the line is contained.
In the remainder of this section, we refer to this class as
\texttt{new-buffer:dock}.

\subsection{Methods}

\Defmethod {line-count} {(buffer new-buffer:buffer)}

This method should return the number of lines in \textit{buffer}.

\Defmethod {item-count} {(buffer new-buffer:buffer)}

This method should return the number of items in \textit{buffer}.
The number of items in the buffer is defined to be the sum of the
number of items in each line of the buffer.

\Defmethod {find-line} {(buffer new-buffer:buffer) line-number}

This method should return the line with the given \textit{line-number}
in \textit{buffer}.

There is no need to check that \textit{line-number} is valid.
This check is already taken care of by an auxiliary method on
\texttt{line-number}.

\Defmethod {cluffer-internal:buffer-line-number}\\
{(buffer new-buffer:buffer) (dock new-buffer:dock) line}

This method is part of the internal protocol for communicating between
the line implementation and the buffer implementation.

It should return the line number if \textit{line} in \textit{buffer}.
The parameter \textit{dock} is the dock to which the line is attached.

Implementations can choose to ignore either the \textit{buffer} or the
\textit{dock} parameter, depending on how the buffer is represented.

\Defmethod {cluffer-internal:buffer-split-line}\\
{(buffer new-buffer:buffer) (dock new-buffer:dock) (line cluffer:line) position}

This method is part of the internal protocol for communicating between
the line implementation and the buffer implementation.

It must call \texttt{cluffer-internal:line-split-line} with
\textit{line} and \textit{position} in order to obtain a new line to
insert into its buffer representation, and it must take into account
that \textit{line} now has fewer items in it as indicated by
\textit{position}.

Implementations can choose to ignore either the \textit{buffer} or the
\textit{dock} parameter, depending on how the buffer is represented.

\Defmethod {cluffer-internal:buffer-join-line}\\
{(buffer new-buffer:buffer) (dock new-buffer:dock) (line cluffer:line)}

This method is part of the internal protocol for communicating between
the line implementation and the buffer implementation.

It must call \texttt{cluffer-internal:line-join-line}, passing it
\textit{line} and the line following \textit{line} in \textit{buffer},
and it must eliminate the line following \textit{line} and take into
account that the items in it will be appended to \textit{line}.

Implementations can choose to ignore either the \textit{buffer} or the
\textit{dock} parameter, depending on how the buffer is represented.

\Defmethod {cluffer:update}\\
{(buffer new-buffer:buffer) time sync skip modify create}

This method is part of the update protocol.  It should implement the
update protocol as described in \refSec{sec-update-protocol}.
