This builds off of #108. If you haven't taken a look at that PR, do that first :)
These changes are intended to make it easier to give Iota unicode support.
Changes
Changed many parts of the code to work with line and character indices rather than byte indices. Split Mark into two different methods of indexing a Buffer: Position, which is meant to be used as a way to index a buffer which can be used even after the buffer is mutated, and BufferSlice which is a range of positions in a buffer and holds a reference to the buffer so that the buffer can't be mutated (and therefore the BufferSlice can't be invalidated).
Implemented a more clear distinction between indices in a buffer that can be read from and indices that can be written to (the indices that can be written to are all the ones that can be read from plus the position immediately following the last character in the buffer).
Several changes to iterators:
Fixed an overflow bug in the Chars iterator where it would not be able to yield the first character in the buffer when running in reverse (and would panic instead).
Gave iterators bounds-checking abilities.
Changed iterators to implement DoubleEndedIterator instead of being reversible in order to be more consistent with the standard library.
Moved iterators to buffer.rs so that the iterators can access private fields of Buffer and BufferSlice.
Lines yields String rather than Vec<u8>.
Changed TextObject to not hold a reference to a specific place in the buffer. This means that, instead of representing a mapping from a buffer to an index in that buffer, they now represent a mapping from a tuple of buffer and "starting index" to an index in the buffer. They don't necessarily have to work this way; the reason I changed this is because the way it was implemented (by holding a reference to a Mark) effectively meant that only the cursor (and of course the start of the buffer) could be used as a starting point. Also removed Offset::Absolute, meaning that text objects now hold less redundant data (the start of the buffer can simply be used as the starting index).
Added some documentation comments.
Problems introduced
Because Buffer is still backed by GapBuffer<u8>, this Buffer implementation is less efficient than the non-unicode-aware one. However, the changes in this PR are meant to make it possible to switch to a more efficient, unicode-aware string data structure, and hopefully after that is done, Buffer will be more efficient than ever.
To-do list for things relating to unicode
Log still uses byte indexes rather than Position objects. A solution to this would probably involve either making Log operate on the string data structure rather than the Buffer itself, or changing it to use Position objects (or similar).
View still has an incorrect draw implementation.
Termbox doesn't work well with multi-character graphemes.
Hi,
This builds off of #108. If you haven't taken a look at that PR, do that first :)
These changes are intended to make it easier to give Iota unicode support.
Changes
Mark
into two different methods of indexing aBuffer
:Position
, which is meant to be used as a way to index a buffer which can be used even after the buffer is mutated, andBufferSlice
which is a range of positions in a buffer and holds a reference to the buffer so that the buffer can't be mutated (and therefore theBufferSlice
can't be invalidated).Chars
iterator where it would not be able to yield the first character in the buffer when running in reverse (and would panic instead).DoubleEndedIterator
instead of being reversible in order to be more consistent with the standard library.buffer.rs
so that the iterators can access private fields ofBuffer
andBufferSlice
.Lines
yieldsString
rather thanVec<u8>
.TextObject
to not hold a reference to a specific place in the buffer. This means that, instead of representing a mapping from a buffer to an index in that buffer, they now represent a mapping from a tuple of buffer and "starting index" to an index in the buffer. They don't necessarily have to work this way; the reason I changed this is because the way it was implemented (by holding a reference to aMark
) effectively meant that only the cursor (and of course the start of the buffer) could be used as a starting point. Also removedOffset::Absolute
, meaning that text objects now hold less redundant data (the start of the buffer can simply be used as the starting index).Problems introduced
Buffer
is still backed byGapBuffer<u8>
, thisBuffer
implementation is less efficient than the non-unicode-aware one. However, the changes in this PR are meant to make it possible to switch to a more efficient, unicode-aware string data structure, and hopefully after that is done,Buffer
will be more efficient than ever.To-do list for things relating to unicode
Log
still uses byte indexes rather thanPosition
objects. A solution to this would probably involve either makingLog
operate on the string data structure rather than theBuffer
itself, or changing it to usePosition
objects (or similar).View
still has an incorrectdraw
implementation.