packages feed

vty-ui-1.6: doc/ch5/TextZipper.tex

\section{The Text Zipper}

The \fw{TextZipper} module provides a
\textit{zipper}\footnote{\url{http://www.haskell.org/haskellwiki/Zipper}}
data structure to manage the text editing process of multi-line text
buffers.  A \fw{TextZipper} stores text and a \textit{cursor position}
at which editing operations are applied.  The zipper implementation
works for any string representation type that provides implementations
of \fw{drop}, \fw{take}, \fw{length}, \fw{last}, \fw{init}, and
\fw{null}.  The module provides a default implementation (used by the
\fw{Edit} widget) based on the \fw{Data.Text.Text} type.  Its
constructor, \fw{textZipper}, takes a list of \fw{Text} values and
creates a zipper.

\begin{haskellcode}
 let z = textZipper []
\end{haskellcode}

To extract the text content of the zipper, use \fw{getText}:

\begin{haskellcode}
 let theLines = getText z
\end{haskellcode}

The module provides the following \textit{editing transformations}:

\begin{itemize}
\item \fw{moveCursor (row, col)} - Move the cursor to the specified
  cursor position.  Invalid positions will be ignored.
\item \fw{insertChar c} - Insert \fw{c} at the cursor position.
\item \fw{breakLine} - Insert a line break at the cursor position.
\item \fw{killToEOL} - Kill (delete) all text after the cursor
  position up to the end of the current line.
\item \fw{gotoEOL} - Move the cursor past the end of the current line.
\item \fw{gotoBOL} - Move the cursor to just before the beginning of
  the current line.
\item \fw{deletePrevChar} - Delete the character preceding the cursor
  position.  If the cursor is at the beginning of a line, the current
  line will be appended onto the previous line.
\item \fw{deleteChar} - Delete the character at the cursor position.
  If the cursor is at the end of a line, the following line will be
  appended onto the current line.
\item \fw{moveRight} - Move the cursor one position to the right,
  wrapping to the following line if necessary.
\item \fw{moveLeft} - Move the cursor one position to the left,
  wrapping to the preceding line if necessary.
\item \fw{moveUp} - Move the cursor up by one row.
\item \fw{moveDown} - Move the cursor down by one row.
\end{itemize}

These transformations can be composed in natural ways to create a
sequence of editing transformations.  For example:

\begin{haskellcode}
 import Control.Arrow

 doEdits :: TextZipper a -> TextZipper a
 doEdits = foldl (>>>) id [ moveRight
                          , insertChar 'x'
                          , insertChar 'z'
                          , moveLeft
                          , insertChar 'y'
                          , deletePrevChar
                          ]
 -- Later:
 let edited = doEdits $ textZipper theLines
\end{haskellcode}