alexandrepiveteau / elm-gap-buffer / Buffer.Gap

Functions for working with a Gap buffer.

Types


type Gap a

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.

Editing

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.

Inspection

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' ]

Moving in the buffer

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.