From 37ad814b53e7a10933688fdf0288860a74029a12 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 2 Nov 2016 23:30:12 -0400 Subject: [PATCH] begin working on Cursor movement routines --- src/core/GapBuffer.cc | 80 +++++++++++++++++++++++++++++++++++++++++++ src/core/GapBuffer.h | 22 ++++++++++++ 2 files changed, 102 insertions(+) diff --git a/src/core/GapBuffer.cc b/src/core/GapBuffer.cc index cc9d60c..267d98c 100644 --- a/src/core/GapBuffer.cc +++ b/src/core/GapBuffer.cc @@ -8,6 +8,7 @@ GapBuffer::GapBuffer(Encoding::Type encoding) m_size = 0u; m_gap_position = 0u; m_encoding = encoding; + tabstop = 4u; } GapBuffer::GapBuffer(uint8_t * buffer, size_t buffer_size, size_t size, Encoding::Type encoding) @@ -17,6 +18,7 @@ GapBuffer::GapBuffer(uint8_t * buffer, size_t buffer_size, size_t size, Encoding m_size = size; m_gap_position = size; m_encoding = encoding; + tabstop = 4u; } GapBuffer::~GapBuffer() @@ -86,3 +88,81 @@ bool GapBuffer::Iterator::check_back() } return false; } + + +bool GapBuffer::Cursor::is_start_of_line() +{ + Iterator i2 = m_iterator; + if (!i2.check_back()) + { + /* Iterator cannot go backwards so it is at beginning of buffer. */ + return true; + } + return *i2 == '\n'; +} + +bool GapBuffer::Cursor::go_start_of_line() +{ + /* TODO */ +} + +bool GapBuffer::Cursor::go_end_of_line() +{ + /* TODO */ +} + +bool GapBuffer::Cursor::go_left() +{ + if (!is_start_of_line()) + { + uint32_t chr = *m_iterator; + if (m_iterator.check_back()) + { + if (chr == '\t') + { + calculate_column(); + } + else + { + /* TODO: handle multi-column characters */ + m_column--; + } + return true; + } + } + return false; +} + +bool GapBuffer::Cursor::go_right() +{ + if (!is_end_of_line()) + { + if (m_iterator.check_forward()) + { + uint32_t chr = *m_iterator; + if (chr == '\t') + { + uint8_t tabstop = m_iterator.gap_buffer()->tabstop; + m_column += tabstop - (m_column + 1u) % tabstop; + } + else + { + /* TODO: handle multi-column characters */ + m_column++; + } + return true; + } + } + return false; +} + +void GapBuffer::Cursor::calculate_column() +{ + Cursor tmp_cursor = *this; + tmp_cursor.go_start_of_line(); + while (tmp_cursor < *this) + { + tmp_cursor.go_right(); + } + m_column = tmp_cursor.m_column; +} diff --git a/src/core/GapBuffer.h b/src/core/GapBuffer.h index 8589107..0a2347d 100644 --- a/src/core/GapBuffer.h +++ b/src/core/GapBuffer.h @@ -41,6 +41,11 @@ public: return 0xFFFFFFFFu; } } + GapBuffer * gap_buffer() { return m_gap_buffer; } + bool operator<(const Iterator & other) + { + return m_offset < other.m_offset; + } protected: GapBuffer * m_gap_buffer; @@ -56,13 +61,30 @@ public: m_line = 0u; m_column = 0u; } + bool is_start_of_line(); + bool is_end_of_line() + { + return *m_iterator == '\n'; + } + bool go_start_of_line(); + bool go_end_of_line(); + bool go_left(); + bool go_right(); + bool operator<(const Cursor & other) + { + return m_iterator < other.m_iterator; + } protected: Iterator m_iterator; size_t m_line; size_t m_column; + + void calculate_column(); }; + uint8_t tabstop; + GapBuffer(Encoding::Type encoding); GapBuffer(uint8_t * buffer, size_t buffer_size, size_t size, Encoding::Type encoding); ~GapBuffer();