Safe Haskell | None |
---|---|
Language | Haskell2010 |
TextZipper
is designed to be help manipulate the contents of a text input field. It keeps track of the logical lines of text (i.e., lines separated by user-entered newlines) and the current cursor position. Several functions are defined in this module to navigate and edit the TextZipper from the cursor position.
TextZipper
s can be converted into DisplayLines
, which describe how the contents of the zipper will be displayed when wrapped to fit within a container of a certain width. It also provides some convenience facilities for converting interactions with the rendered DisplayLines back into manipulations of the underlying TextZipper.
Synopsis
- data TextZipper = TextZipper {}
- mapZipper :: (Char -> Char) -> TextZipper -> TextZipper
- left :: TextZipper -> TextZipper
- leftN :: Int -> TextZipper -> TextZipper
- right :: TextZipper -> TextZipper
- rightN :: Int -> TextZipper -> TextZipper
- up :: TextZipper -> TextZipper
- down :: TextZipper -> TextZipper
- pageUp :: Int -> TextZipper -> TextZipper
- pageDown :: Int -> TextZipper -> TextZipper
- home :: TextZipper -> TextZipper
- end :: TextZipper -> TextZipper
- top :: TextZipper -> TextZipper
- insertChar :: Char -> TextZipper -> TextZipper
- insert :: Text -> TextZipper -> TextZipper
- deleteLeft :: TextZipper -> TextZipper
- deleteRight :: TextZipper -> TextZipper
- deleteLeftWord :: TextZipper -> TextZipper
- tab :: Int -> TextZipper -> TextZipper
- value :: TextZipper -> Text
- empty :: TextZipper
- fromText :: Text -> TextZipper
- data Span tag = Span tag Text
- data DisplayLines tag = DisplayLines {
- _displayLines_spans :: [[Span tag]]
- _displayLines_offsetMap :: Map Int Int
- _displayLines_cursorY :: Int
- displayLines :: Int -> tag -> tag -> TextZipper -> DisplayLines tag
- wrapWithOffset :: Int -> Int -> Text -> [Text]
- splitAtWidth :: Int -> Text -> (Text, Text)
- takeWidth :: Int -> Text -> Text
- dropWidth :: Int -> Text -> Text
- charWidth :: Char -> Int
- offsetMap :: [[Text]] -> Map Int Int
- goToDisplayLinePosition :: Int -> Int -> DisplayLines tag -> TextZipper -> TextZipper
- spansWidth :: [Span tag] -> Int
- spansLength :: [Span tag] -> Int
- textWidth :: Text -> Int
- widthI :: Stream Char -> Int
Documentation
data TextZipper Source #
A zipper of the logical text input contents (the "document"). The lines before the line containing the cursor are stored in reverse order. The cursor is logically between the "before" and "after" text. A "logical" line of input is a line of input up until a user-entered newline character (as compared to a "display" line, which is wrapped to fit within a given viewport width).
Instances
Show TextZipper Source # | |
Defined in Data.Text.Zipper showsPrec :: Int -> TextZipper -> ShowS # show :: TextZipper -> String # showList :: [TextZipper] -> ShowS # | |
IsString TextZipper Source # | |
Defined in Data.Text.Zipper fromString :: String -> TextZipper # |
mapZipper :: (Char -> Char) -> TextZipper -> TextZipper Source #
Map a replacement function over the characters in a TextZipper
left :: TextZipper -> TextZipper Source #
Move the cursor left one character, if possible
leftN :: Int -> TextZipper -> TextZipper Source #
Move the cursor left by the given number of characters, or, if the document isn't long enough, to the beginning of the document
right :: TextZipper -> TextZipper Source #
Move the cursor right one character, if possible
rightN :: Int -> TextZipper -> TextZipper Source #
Move the character right by the given number of characters, or, if the document isn't long enough, to the end of the document
up :: TextZipper -> TextZipper Source #
Move the cursor up one logical line, if possible
down :: TextZipper -> TextZipper Source #
Move the cursor down one logical line, if possible
pageUp :: Int -> TextZipper -> TextZipper Source #
Move the cursor up by the given number of lines
pageDown :: Int -> TextZipper -> TextZipper Source #
Move the cursor down by the given number of lines
home :: TextZipper -> TextZipper Source #
Move the cursor to the beginning of the current logical line
end :: TextZipper -> TextZipper Source #
Move the cursor to the end of the current logical line
top :: TextZipper -> TextZipper Source #
Move the cursor to the top of the document
insertChar :: Char -> TextZipper -> TextZipper Source #
Insert a character at the current cursor position
insert :: Text -> TextZipper -> TextZipper Source #
Insert text at the current cursor position
deleteLeft :: TextZipper -> TextZipper Source #
Delete the character to the left of the cursor
deleteRight :: TextZipper -> TextZipper Source #
Delete the character under/to the right of the cursor
deleteLeftWord :: TextZipper -> TextZipper Source #
Delete a word to the left of the cursor. Deletes all whitespace until it finds a non-whitespace character, and then deletes contiguous non-whitespace characters.
tab :: Int -> TextZipper -> TextZipper Source #
Insert up to n spaces to get to the next logical column that is a multiple of n
value :: TextZipper -> Text Source #
The plain text contents of the zipper
empty :: TextZipper Source #
The empty zipper
fromText :: Text -> TextZipper Source #
Constructs a zipper with the given contents. The cursor is placed after the contents.
A span of text tagged with some metadata that makes up part of a display line.
data DisplayLines tag Source #
Information about the document as it is displayed (i.e., post-wrapping)
DisplayLines | |
|
Instances
Show tag => Show (DisplayLines tag) Source # | |
Defined in Data.Text.Zipper showsPrec :: Int -> DisplayLines tag -> ShowS # show :: DisplayLines tag -> String # showList :: [DisplayLines tag] -> ShowS # |
:: Int | Width, used for wrapping |
-> tag | Metadata for normal characters |
-> tag | Metadata for the cursor |
-> TextZipper | The text input contents and cursor state |
-> DisplayLines tag |
Given a width and a TextZipper
, produce a list of display lines
(i.e., lines of wrapped text) with special attributes applied to
certain segments (e.g., the cursor). Additionally, produce the current
y-coordinate of the cursor and a mapping from display line number to text
offset
Wraps a logical line of text to fit within the given width. The first wrapped line is offset by the number of columns provided. Subsequent wrapped lines are not.
takeWidth :: Int -> Text -> Text Source #
Takes the given number of columns of characters. For example
takeWidth 3 "ᄀabc" == "ᄀa"
because the first character has a width of 2 (see charWidth
for more on that).
This function will not take a character if its width exceeds the width it seeks to take.
dropWidth :: Int -> Text -> Text Source #
Drops the given number of columns of characters. For example
dropWidth 2 "ᄀabc" == "abc"
because the first character has a width of 2 (see charWidth
for more on that).
This function will not drop a character if its width exceeds the width it seeks to drop.
charWidth :: Char -> Int Source #
Get the display width of a Char
. "Full width" and "wide" characters
take two columns and everything else takes a single column. See
https://www.unicode.org/reports/tr11/ for more information.
:: [[Text]] | The outer list represents logical lines, and the inner list represents the display lines into which the logical line has been wrapped |
-> Map Int Int | A map from the index (row) of display line to the text offset from the beginning of the document to the first character of the display line |
For a given set of wrapped logical lines, computes a map
from display line index to text offset in the original text.
This is used to help determine how interactions with the displayed
text map back to the original text.
For example, given the document "AA\nBBB\nCCCCCCCC\n"
wrapped to 5 columns,
this function will compute the offset in the original document of each character
in column 1:
AA... (0, 0) BBB.. (1, 3) CCCCC (2, 7) -- (this line wraps to the next row) CCC.. (3, 12) ..... (4, 16)
goToDisplayLinePosition :: Int -> Int -> DisplayLines tag -> TextZipper -> TextZipper Source #
Move the cursor of the given TextZipper
to the logical position indicated
by the given display line coordinates, using the provided DisplayLines
information. If the x coordinate is beyond the end of a line, the cursor is
moved to the end of the line.
spansWidth :: [Span tag] -> Int Source #
Get the width of the text in a set of Span
s, taking into account unicode character widths
spansLength :: [Span tag] -> Int Source #
Get the length (number of characters) of the text in a set of Span
s