Functions for working with a Gap
buffer.
A Gap
is a gap buffer which never shrinks:
length empty == 0
length (Extra.fromString "hello") == 5
Note : You can do amortized constant-time insertions and deletions at the current cursor position. Moving the cursor takes a linear time in the amount that it gets moved.
empty : Gap a
Creates an empty gap buffer.
length empty == 0
toArray empty == Array.empty
initialize : Basics.Int -> (Basics.Int -> a) -> Gap a
Initialize a gap buffer. initialize n f
creates a buffer of length n with the element at
index i
initialized to the result of f i
toArray (initialize 4 identity) == Array.fromList [ 0, 1, 2, 3 ]
toArray (initialize 4 (always 0)) == Array.fromList [ 0, 0, 0, 0 ]
fromArray : Array a -> Gap a
Create a gap buffer from an Array
.
fromList : List a -> Gap a
Create a gap buffer from a List
.
put : a -> Gap a -> Gap a
Add an element onto the cursor of the gap buffer.
toArray (put 1 empty) == Array.fromList [ 1 ]
Array.fromList [ 1, 3, 2 ]
== empty
|> put 1
|> put 2
|> left
|> put 3
|> toArray
insert : Array a -> Gap a -> Gap a
Add multiple elements onto the cursor of the gap buffer.
insert (Array.fromList [ 1, 2, 3 ]) empty == fromArray (Array.fromList [ 1, 2, 3 ])
delete : Basics.Int -> Gap a -> Gap a
Delete removes characters from the current cursor position: delete n gap
. If the cursor is
at the position zero, no items will be removed.
length : Gap a -> Basics.Int
Return the length of a gap buffer.
length empty == 0
length (Extra.fromString "hello") 5
isEmpty : Gap a -> Basics.Bool
Return true if a gap buffer is empty.
isEmpty empty == True
at : Basics.Int -> Gap a -> Maybe a
Return Just
the element at the index or Nothing
if the index is out of range.
at 0 (Extra.fromString "hi") == Just 'h'
at 1 (Extra.fromString "hi") == Just 'i'
at -1 (Extra.fromString "hi") == Nothing
at 5 (Extra.fromString "hi") == Nothing
cursor : Gap a -> Basics.Int
Return the cursor position of a gap buffer.
cursor empty == 0
cursor (Extra.fromString "hi") == 2
foldl : (a -> b -> b) -> b -> Gap a -> b
Reduce a gap from the left over all its contents. Read foldl
as fold from the left.
foldl (::) [] (fromList [ 1, 2, 3 ]) == [ 3, 2, 1 ]
foldr : (a -> b -> b) -> b -> Gap a -> b
Reduce a gap from the right over all its contents. Read foldr
as fold from the right.
foldr (::) [] (fromList [ 1, 2, 3 ]) == [ 1, 2, 3 ]
foldlRange : Basics.Int -> Basics.Int -> (a -> b -> b) -> b -> Gap a -> b
Reduce a gap from the left over an inclusive-exclusive range. Read foldl
as fold from the
left.
foldlRange 1 3 (::) [] (Extra.fromString "abcde") == [ 'c', 'b' ]
foldrRange : Basics.Int -> Basics.Int -> (a -> b -> b) -> b -> Gap a -> b
Reduce a gap from the left over an inclusive-exclusive range. Read foldr
as fold from the
right.
foldrRange 1 3 (::) [] (Extra.fromString "abcde") == [ 'b', 'c' ]
slice : Basics.Int -> Basics.Int -> Gap a -> Array a
Get a sub-section of a gap buffer: (slice start end gap)
. The start
is a zero-based index
where we will start our slice. The end
is a zero-based index that indicates the slice end. The
slice extracts up to but not including end
.
slice 0 0 empty == Array.empty
slice 0 3 (Extra.fromString "hello") == Array.fromList [ 'h', 'e', 'l' ]
If start
or end
are out of the bounds of the gap buffer, they will default to the closest value
within the bounds of the buffer.
slice 2 1000 (Extra.fromString "hello") == Array.fromList [ 'l', 'l', 'o' ]
slice -1 5 (Extra.fromString "hello") == Array.fromList [ 'h', 'e', 'l', 'l', 'o' ]
toList : Gap a -> List a
Create a List
from the elements of the buffer.
toList (Extra.fromString "hi") == [ 'h', 'i' ]
toArray : Gap a -> Array a
Create an Array
from the elements of the buffer.
toArray (Extra.fromString "hi") == Array.fromList [ 'h', 'i' ]
left : Gap a -> Gap a
Move the cursor by one index to the left. The index will remain in the bounds of the buffer.
right : Gap a -> Gap a
Move the cursor by one index to the right. The index will remain in the bounds of the buffer.
move : Basics.Int -> Gap a -> Gap a
Move the cursor to the given index using the left
or right
functions.