Change BufferView and BufferLineWalker to return iterator objects for iteration instead of using lambdas for callbacks.
This commit is contained in:
parent
b89f348602
commit
4b3e1ea7e7
@ -2,100 +2,100 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a BufferLineWalker.
|
* Construct a BufferLineWalker.
|
||||||
|
*
|
||||||
|
* @param buffer The Buffer we're iterating.
|
||||||
|
* @param start_of_line Buffer iterator pointing to the beginning of the buffer line.
|
||||||
|
* @param view_width View width, beyond which characters will wrap to the next line.
|
||||||
|
* @param character_width_determiner Functor to return the width (in columns) of a character.
|
||||||
*/
|
*/
|
||||||
BufferLineWalker::BufferLineWalker(
|
BufferLineWalker::BufferLineWalker(
|
||||||
std::shared_ptr<Buffer> buffer,
|
std::shared_ptr<Buffer> buffer,
|
||||||
|
std::shared_ptr<Buffer::Iterator> start_of_line,
|
||||||
|
int view_width,
|
||||||
CharacterWidthDeterminer & character_width_determiner)
|
CharacterWidthDeterminer & character_width_determiner)
|
||||||
: m_buffer(buffer),
|
: m_buffer(buffer),
|
||||||
m_character_width_determiner(character_width_determiner)
|
m_character_width_determiner(character_width_determiner)
|
||||||
{
|
{
|
||||||
m_width = 1;
|
m_view_width = view_width;
|
||||||
|
m_row_offset = 0;
|
||||||
|
m_screen_column = 0;
|
||||||
|
m_virtual_column = 0;
|
||||||
|
m_iterator = std::make_shared<Buffer::Iterator>(*start_of_line);
|
||||||
|
process_new_character();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void BufferLineWalker::process_new_character()
|
||||||
* Set the view width.
|
|
||||||
*
|
|
||||||
* @param width View width.
|
|
||||||
*/
|
|
||||||
void BufferLineWalker::set_width(int width)
|
|
||||||
{
|
{
|
||||||
m_width = std::max(1, width);
|
if ((!m_iterator) || (!m_iterator->valid()))
|
||||||
|
{
|
||||||
|
m_code_point = '\n';
|
||||||
|
m_character_width = 0;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
m_code_point = **m_iterator;
|
||||||
* Invoke the callback for each character in the buffer line, wrapping to the
|
|
||||||
* next screen line and taking into account multi-column characters.
|
if (m_code_point == '\n')
|
||||||
*
|
|
||||||
* Callback parameters:
|
|
||||||
* - row_offset
|
|
||||||
* - screen column
|
|
||||||
* - virtual column
|
|
||||||
* - character width
|
|
||||||
* - buffer iterator
|
|
||||||
* If the callback function returns true, iteration continues. Otherwise
|
|
||||||
* iteration is terminated.
|
|
||||||
*
|
|
||||||
* @param start_of_line Buffer iterator pointing to the beginning of the buffer line.
|
|
||||||
* @param callback Function to call for each character in the line.
|
|
||||||
*/
|
|
||||||
void BufferLineWalker::walk_line(
|
|
||||||
const Buffer::Iterator & start_of_line,
|
|
||||||
std::function<bool(int, int, int, int, const Buffer::Iterator &)> callback)
|
|
||||||
{
|
{
|
||||||
int row_offset = 0;
|
m_character_width = 0;
|
||||||
int screen_column = 0;
|
return;
|
||||||
int virtual_column = 0;
|
|
||||||
Buffer::Iterator i = start_of_line;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
uint32_t code_point = *i;
|
|
||||||
if ((code_point == '\n') || (!i.valid()))
|
|
||||||
{
|
|
||||||
callback(row_offset, screen_column, virtual_column, 0, i);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
int c_width;
|
|
||||||
if (code_point == '\t')
|
if (m_code_point == '\t')
|
||||||
{
|
{
|
||||||
uint8_t tabstop = m_buffer->tabstop();
|
uint8_t tabstop = m_buffer->tabstop();
|
||||||
c_width = tabstop - virtual_column % tabstop;
|
m_character_width = tabstop - m_virtual_column % tabstop;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
m_character_width = m_character_width_determiner(m_code_point);
|
||||||
|
|
||||||
|
if (((m_screen_column + m_character_width) > m_view_width) &&
|
||||||
|
(m_screen_column > 0))
|
||||||
{
|
{
|
||||||
c_width = m_character_width_determiner(code_point);
|
m_row_offset++;
|
||||||
if (((screen_column + c_width) > m_width) &&
|
m_screen_column = 0;
|
||||||
(screen_column > 0))
|
|
||||||
{
|
|
||||||
row_offset++;
|
|
||||||
screen_column = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!callback(row_offset, screen_column, virtual_column, c_width, i))
|
|
||||||
|
void BufferLineWalker::operator++(int unused)
|
||||||
{
|
{
|
||||||
break;
|
if (!m_iterator)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((m_code_point == '\n') || (!m_iterator->valid()))
|
||||||
|
{
|
||||||
|
m_code_point = '\n';
|
||||||
|
m_iterator.reset();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
virtual_column += c_width;
|
|
||||||
if (code_point == '\t')
|
/* Adjust virtual column. */
|
||||||
|
m_virtual_column += m_character_width;
|
||||||
|
|
||||||
|
/* Adjust screen position. */
|
||||||
|
if (m_code_point == '\t')
|
||||||
{
|
{
|
||||||
screen_column += c_width;
|
m_screen_column += m_character_width;
|
||||||
while (screen_column >= m_width)
|
while (m_screen_column >= m_view_width)
|
||||||
{
|
{
|
||||||
screen_column -= m_width;
|
m_screen_column -= m_view_width;
|
||||||
row_offset++;
|
m_row_offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((screen_column + c_width) >= m_width)
|
if ((m_screen_column + m_character_width) >= m_view_width)
|
||||||
{
|
{
|
||||||
row_offset++;
|
m_row_offset++;
|
||||||
screen_column = 0;
|
m_screen_column = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
screen_column += c_width;
|
m_screen_column += m_character_width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i.go_forward();
|
|
||||||
}
|
m_iterator->go_forward();
|
||||||
|
process_new_character();
|
||||||
}
|
}
|
||||||
|
@ -14,16 +14,42 @@ class BufferLineWalker
|
|||||||
public:
|
public:
|
||||||
BufferLineWalker(
|
BufferLineWalker(
|
||||||
std::shared_ptr<Buffer> buffer,
|
std::shared_ptr<Buffer> buffer,
|
||||||
|
std::shared_ptr<Buffer::Iterator> start_of_line,
|
||||||
|
int view_width,
|
||||||
CharacterWidthDeterminer & character_width_determiner);
|
CharacterWidthDeterminer & character_width_determiner);
|
||||||
void set_width(int width);
|
void operator++() { return (*this)++; }
|
||||||
void walk_line(
|
void operator++(int unused);
|
||||||
const Buffer::Iterator & start_of_line,
|
bool is_eol() const
|
||||||
std::function<bool(int, int, int, int, const Buffer::Iterator &)> callback);
|
{
|
||||||
|
if (is_valid())
|
||||||
|
{
|
||||||
|
return (m_code_point == '\n');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool is_valid() const
|
||||||
|
{
|
||||||
|
return (bool)m_iterator;
|
||||||
|
}
|
||||||
|
int row_offset() const { return m_row_offset; }
|
||||||
|
int screen_column() const { return m_screen_column; }
|
||||||
|
int virtual_column() const { return m_virtual_column; }
|
||||||
|
int character_width() const { return m_character_width; }
|
||||||
|
uint32_t code_point() const { return m_code_point; }
|
||||||
|
std::shared_ptr<Buffer::Iterator> iterator() const { return m_iterator; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<Buffer> m_buffer;
|
std::shared_ptr<Buffer> m_buffer;
|
||||||
|
std::shared_ptr<Buffer::Iterator> m_iterator;
|
||||||
CharacterWidthDeterminer & m_character_width_determiner;
|
CharacterWidthDeterminer & m_character_width_determiner;
|
||||||
int m_width;
|
int m_view_width;
|
||||||
|
int m_row_offset;
|
||||||
|
int m_screen_column;
|
||||||
|
int m_virtual_column;
|
||||||
|
int m_character_width;
|
||||||
|
uint32_t m_code_point;
|
||||||
|
|
||||||
|
void process_new_character();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,20 +5,22 @@
|
|||||||
BufferView::BufferView(std::shared_ptr<Buffer> buffer,
|
BufferView::BufferView(std::shared_ptr<Buffer> buffer,
|
||||||
std::shared_ptr<Buffer::Iterator> iterator,
|
std::shared_ptr<Buffer::Iterator> iterator,
|
||||||
CharacterWidthDeterminer & character_width_determiner)
|
CharacterWidthDeterminer & character_width_determiner)
|
||||||
: m_iterator(iterator)
|
: m_buffer(buffer),
|
||||||
|
m_iterator(iterator),
|
||||||
|
m_character_width_determiner(character_width_determiner)
|
||||||
{
|
{
|
||||||
|
m_width = 1;
|
||||||
m_height = 1;
|
m_height = 1;
|
||||||
m_scroll_offset = 0;
|
m_scroll_offset = 0;
|
||||||
m_cursor_screen_row = 0;
|
m_cursor_screen_row = 0;
|
||||||
m_cursor_screen_column = 0;
|
m_cursor_screen_column = 0;
|
||||||
m_cursor_virtual_column = 0;
|
m_cursor_virtual_column = 0;
|
||||||
m_cursor_row_offset = 0;
|
m_cursor_row_offset = 0;
|
||||||
m_buffer_line_walker = std::make_shared<BufferLineWalker>(buffer, character_width_determiner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferView::resize(int width, int height)
|
void BufferView::resize(int width, int height)
|
||||||
{
|
{
|
||||||
m_buffer_line_walker->set_width(width);
|
m_width = std::max(1, width);
|
||||||
m_height = std::max(1, height);
|
m_height = std::max(1, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,21 +29,12 @@ void BufferView::set_scroll_offset(int scroll_offset)
|
|||||||
m_scroll_offset = std::max(0, scroll_offset);
|
m_scroll_offset = std::max(0, scroll_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferView::iter_lines(
|
BufferView::Iterator BufferView::vert_iter()
|
||||||
std::function<bool(int, const Buffer::Iterator &)> callback)
|
|
||||||
{
|
{
|
||||||
if (m_iterator->valid())
|
if (m_iterator->valid())
|
||||||
{
|
{
|
||||||
|
/* TODO: user calls update() before vert_iter(). */
|
||||||
update();
|
update();
|
||||||
Buffer::Iterator i = *m_first_line;
|
|
||||||
int row_offset = m_first_line_row_offset;
|
|
||||||
while (row_offset < m_height)
|
|
||||||
{
|
|
||||||
callback(row_offset, i);
|
|
||||||
row_offset += calculate_rows_in_line(i);
|
|
||||||
if (!i.go_next_line())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -49,6 +42,7 @@ void BufferView::iter_lines(
|
|||||||
m_cursor_screen_column = 0;
|
m_cursor_screen_column = 0;
|
||||||
m_cursor_virtual_column = 0;
|
m_cursor_virtual_column = 0;
|
||||||
}
|
}
|
||||||
|
return Iterator(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
@ -58,12 +52,12 @@ void BufferView::iter_lines(
|
|||||||
void BufferView::update()
|
void BufferView::update()
|
||||||
{
|
{
|
||||||
std::list<std::pair<int, std::shared_ptr<Buffer::Iterator>>> backward_lines;
|
std::list<std::pair<int, std::shared_ptr<Buffer::Iterator>>> backward_lines;
|
||||||
Buffer::Iterator start_of_line = *m_iterator;
|
auto start_of_line = std::make_shared<Buffer::Iterator>(*m_iterator);
|
||||||
start_of_line.go_start_of_line();
|
start_of_line->go_start_of_line();
|
||||||
int rows_in_cursor_line = calculate_rows_in_cursor_line(start_of_line);
|
int rows_in_cursor_line = calculate_rows_in_cursor_line(start_of_line);
|
||||||
int so = effective_scroll_offset();
|
int so = effective_scroll_offset();
|
||||||
int rows_above = screen_rows_above_line(*m_iterator, backward_lines) + m_cursor_row_offset;
|
int rows_above = screen_rows_above_line(start_of_line, backward_lines) + m_cursor_row_offset;
|
||||||
int rows_below = screen_rows_below_line(*m_iterator) + std::max(0, rows_in_cursor_line - m_cursor_row_offset - 1);
|
int rows_below = screen_rows_below_line(start_of_line) + std::max(0, rows_in_cursor_line - m_cursor_row_offset - 1);
|
||||||
int min_rows_to_leave_above = std::min(rows_above, so);
|
int min_rows_to_leave_above = std::min(rows_above, so);
|
||||||
int min_rows_to_leave_below = std::min(rows_below, so);
|
int min_rows_to_leave_below = std::min(rows_below, so);
|
||||||
m_cursor_screen_row = std::min(m_height - min_rows_to_leave_below - 1, m_cursor_screen_row);
|
m_cursor_screen_row = std::min(m_height - min_rows_to_leave_below - 1, m_cursor_screen_row);
|
||||||
@ -89,49 +83,51 @@ void BufferView::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int BufferView::calculate_rows_in_line(const Buffer::Iterator & start_of_line)
|
int BufferView::calculate_rows_in_line(std::shared_ptr<Buffer::Iterator> start_of_line)
|
||||||
{
|
{
|
||||||
int saved_row_offset = 0;
|
int saved_row_offset = 0;
|
||||||
walk_line(start_of_line, [&saved_row_offset](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & i) -> bool {
|
for (auto it = horiz_iter(start_of_line); it.is_valid(); it++)
|
||||||
uint32_t code_point = *i;
|
|
||||||
if ((code_point != '\n') &&
|
|
||||||
(code_point != Buffer::Iterator::INVALID_CODE_POINT))
|
|
||||||
{
|
{
|
||||||
saved_row_offset = row_offset;
|
if (!it.is_eol())
|
||||||
return true;
|
{
|
||||||
|
saved_row_offset = it.row_offset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
});
|
|
||||||
return saved_row_offset + 1;
|
return saved_row_offset + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BufferView::calculate_rows_in_cursor_line(const Buffer::Iterator & start_of_line)
|
int BufferView::calculate_rows_in_cursor_line(std::shared_ptr<Buffer::Iterator> start_of_line)
|
||||||
{
|
{
|
||||||
int saved_row_offset = 0;
|
int saved_row_offset = 0;
|
||||||
walk_line(start_of_line, [this, &saved_row_offset](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & i) -> bool {
|
for (auto it = horiz_iter(start_of_line); it.is_valid(); it++)
|
||||||
uint32_t code_point = *i;
|
|
||||||
if (i == *m_iterator)
|
|
||||||
{
|
{
|
||||||
m_cursor_virtual_column = virtual_column;
|
if (*it.iterator() == *m_iterator)
|
||||||
m_cursor_screen_column = screen_column;
|
|
||||||
m_cursor_row_offset = row_offset;
|
|
||||||
}
|
|
||||||
if ((code_point != '\n') &&
|
|
||||||
(code_point != Buffer::Iterator::INVALID_CODE_POINT))
|
|
||||||
{
|
{
|
||||||
saved_row_offset = row_offset;
|
m_cursor_virtual_column = it.virtual_column();
|
||||||
return true;
|
m_cursor_screen_column = it.screen_column();
|
||||||
|
m_cursor_row_offset = it.row_offset();
|
||||||
|
}
|
||||||
|
if (!it.is_eol())
|
||||||
|
{
|
||||||
|
saved_row_offset = it.row_offset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
});
|
|
||||||
return saved_row_offset + 1;
|
return saved_row_offset + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BufferView::screen_rows_below_line(const Buffer::Iterator & line)
|
int BufferView::screen_rows_below_line(std::shared_ptr<Buffer::Iterator> line)
|
||||||
{
|
{
|
||||||
Buffer::Iterator i = line;
|
auto i = std::make_shared<Buffer::Iterator>(*line);
|
||||||
int rows = 0;
|
int rows = 0;
|
||||||
while ((rows < m_height) && i.go_next_line())
|
while ((rows < m_height) && i->go_next_line())
|
||||||
{
|
{
|
||||||
rows += calculate_rows_in_line(i);
|
rows += calculate_rows_in_line(i);
|
||||||
}
|
}
|
||||||
@ -139,16 +135,16 @@ int BufferView::screen_rows_below_line(const Buffer::Iterator & line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int BufferView::screen_rows_above_line(
|
int BufferView::screen_rows_above_line(
|
||||||
const Buffer::Iterator & line,
|
std::shared_ptr<Buffer::Iterator> line,
|
||||||
std::list<std::pair<int, std::shared_ptr<Buffer::Iterator>>> & backward_lines)
|
std::list<std::pair<int, std::shared_ptr<Buffer::Iterator>>> & backward_lines)
|
||||||
{
|
{
|
||||||
Buffer::Iterator i = line;
|
auto i = std::make_shared<Buffer::Iterator>(*line);
|
||||||
int rows = 0;
|
int rows = 0;
|
||||||
while ((rows < m_height) && i.go_previous_line())
|
while ((rows < m_height) && i->go_previous_line())
|
||||||
{
|
{
|
||||||
int rows_in_this_line = calculate_rows_in_line(i);
|
int rows_in_this_line = calculate_rows_in_line(i);
|
||||||
rows += rows_in_this_line;
|
rows += rows_in_this_line;
|
||||||
backward_lines.push_back(std::pair<int, std::shared_ptr<Buffer::Iterator>>(rows_in_this_line, std::make_shared<Buffer::Iterator>(i)));
|
backward_lines.push_back(std::pair<int, std::shared_ptr<Buffer::Iterator>>(rows_in_this_line, std::make_shared<Buffer::Iterator>(*i)));
|
||||||
}
|
}
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
@ -13,45 +13,89 @@
|
|||||||
class BufferView
|
class BufferView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
class Iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Iterator(BufferView & bv) : m_buffer_view(bv)
|
||||||
|
{
|
||||||
|
if (bv.m_iterator->valid())
|
||||||
|
{
|
||||||
|
m_iterator = std::make_shared<Buffer::Iterator>(*m_buffer_view.m_first_line);
|
||||||
|
m_row_offset = m_buffer_view.m_first_line_row_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void operator++()
|
||||||
|
{
|
||||||
|
(*this)++;
|
||||||
|
}
|
||||||
|
void operator++(int unused)
|
||||||
|
{
|
||||||
|
if (is_valid())
|
||||||
|
{
|
||||||
|
m_row_offset += m_buffer_view.calculate_rows_in_line(m_iterator);
|
||||||
|
if ((m_row_offset >= m_buffer_view.m_height) || (!m_iterator->go_next_line()))
|
||||||
|
{
|
||||||
|
m_iterator.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool is_valid()
|
||||||
|
{
|
||||||
|
return (bool)m_iterator;
|
||||||
|
}
|
||||||
|
int row_offset() const
|
||||||
|
{
|
||||||
|
return m_row_offset;
|
||||||
|
}
|
||||||
|
std::shared_ptr<Buffer::Iterator> iterator() const
|
||||||
|
{
|
||||||
|
return m_iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BufferView & m_buffer_view;
|
||||||
|
std::shared_ptr<Buffer::Iterator> m_iterator;
|
||||||
|
int m_row_offset;
|
||||||
|
};
|
||||||
|
|
||||||
BufferView(std::shared_ptr<Buffer> buffer,
|
BufferView(std::shared_ptr<Buffer> buffer,
|
||||||
std::shared_ptr<Buffer::Iterator> iterator,
|
std::shared_ptr<Buffer::Iterator> iterator,
|
||||||
CharacterWidthDeterminer & character_width_determiner);
|
CharacterWidthDeterminer & character_width_determiner);
|
||||||
void resize(int width, int height);
|
void resize(int width, int height);
|
||||||
void set_scroll_offset(int scroll_offset);
|
void set_scroll_offset(int scroll_offset);
|
||||||
void iter_lines(
|
Iterator vert_iter();
|
||||||
std::function<bool(int, const Buffer::Iterator &)> callback);
|
BufferLineWalker horiz_iter(std::shared_ptr<Buffer::Iterator> start_of_line)
|
||||||
void walk_line(
|
|
||||||
const Buffer::Iterator & start_of_line,
|
|
||||||
std::function<bool(int, int, int, int, const Buffer::Iterator &)> callback)
|
|
||||||
{
|
{
|
||||||
m_buffer_line_walker->walk_line(start_of_line, callback);
|
return BufferLineWalker(m_buffer, start_of_line, m_width, m_character_width_determiner);
|
||||||
}
|
}
|
||||||
int cursor_screen_row() const { return m_cursor_screen_row; }
|
int cursor_screen_row() const { return m_cursor_screen_row; }
|
||||||
int cursor_screen_column() const { return m_cursor_screen_column; }
|
int cursor_screen_column() const { return m_cursor_screen_column; }
|
||||||
int cursor_virtual_column() const { return m_cursor_virtual_column; }
|
int cursor_virtual_column() const { return m_cursor_virtual_column; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
std::shared_ptr<Buffer> m_buffer;
|
||||||
std::shared_ptr<Buffer::Iterator> m_iterator;
|
std::shared_ptr<Buffer::Iterator> m_iterator;
|
||||||
std::shared_ptr<Buffer::Iterator> m_first_line;
|
std::shared_ptr<Buffer::Iterator> m_first_line;
|
||||||
int m_first_line_row_offset;
|
int m_first_line_row_offset;
|
||||||
|
int m_width;
|
||||||
int m_height;
|
int m_height;
|
||||||
int m_scroll_offset;
|
int m_scroll_offset;
|
||||||
int m_cursor_screen_row;
|
int m_cursor_screen_row;
|
||||||
int m_cursor_screen_column;
|
int m_cursor_screen_column;
|
||||||
int m_cursor_virtual_column;
|
int m_cursor_virtual_column;
|
||||||
int m_cursor_row_offset;
|
int m_cursor_row_offset;
|
||||||
std::shared_ptr<BufferLineWalker> m_buffer_line_walker;
|
CharacterWidthDeterminer & m_character_width_determiner;
|
||||||
|
|
||||||
int effective_scroll_offset()
|
int effective_scroll_offset()
|
||||||
{
|
{
|
||||||
return std::min(m_scroll_offset, (m_height - 1) / 2);
|
return std::min(m_scroll_offset, (m_height - 1) / 2);
|
||||||
}
|
}
|
||||||
void update();
|
void update();
|
||||||
int calculate_rows_in_line(const Buffer::Iterator & start_of_line);
|
int calculate_rows_in_line(std::shared_ptr<Buffer::Iterator> start_of_line);
|
||||||
int calculate_rows_in_cursor_line(const Buffer::Iterator & start_of_line);
|
int calculate_rows_in_cursor_line(std::shared_ptr<Buffer::Iterator> start_of_line);
|
||||||
int screen_rows_below_line(const Buffer::Iterator & line);
|
int screen_rows_below_line(std::shared_ptr<Buffer::Iterator> line);
|
||||||
int screen_rows_above_line(
|
int screen_rows_above_line(
|
||||||
const Buffer::Iterator & line,
|
std::shared_ptr<Buffer::Iterator> line,
|
||||||
std::list<std::pair<int, std::shared_ptr<Buffer::Iterator>>> & backward_lines);
|
std::list<std::pair<int, std::shared_ptr<Buffer::Iterator>>> & backward_lines);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,60 +16,58 @@ class MyCharacterWidthDeterminer : public CharacterWidthDeterminer
|
|||||||
}
|
}
|
||||||
} cld;
|
} cld;
|
||||||
|
|
||||||
TEST(BufferLineWalkerTest, calls_callback_once_for_empty_line)
|
TEST(BufferLineWalkerTest, iterats_once_for_empty_line)
|
||||||
{
|
{
|
||||||
static const uint8_t data[] = "\n";
|
static const uint8_t data[] = "\n";
|
||||||
std::shared_ptr<Buffer> b = std::make_shared<Buffer>(data, 1u);
|
std::shared_ptr<Buffer> b = std::make_shared<Buffer>(data, 1u);
|
||||||
BufferLineWalker blw(b, cld);
|
|
||||||
blw.set_width(20);
|
|
||||||
std::shared_ptr<Buffer::Iterator> start_of_line = b->add_iterator();
|
std::shared_ptr<Buffer::Iterator> start_of_line = b->add_iterator();
|
||||||
int times_called = 0;
|
BufferLineWalker blw(b, start_of_line, 20, cld);
|
||||||
blw.walk_line(*start_of_line, [×_called](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & it) -> bool {
|
int iter_count = 0;
|
||||||
times_called++;
|
for (; blw.is_valid(); blw++)
|
||||||
EXPECT_EQ(0, row_offset);
|
{
|
||||||
EXPECT_EQ(0, screen_column);
|
EXPECT_EQ(0, blw.row_offset());
|
||||||
EXPECT_EQ(0, virtual_column);
|
EXPECT_EQ(0, blw.screen_column());
|
||||||
EXPECT_EQ(0, character_width);
|
EXPECT_EQ(0, blw.virtual_column());
|
||||||
return true;
|
EXPECT_EQ(0, blw.character_width());
|
||||||
});
|
EXPECT_TRUE(blw.is_eol());
|
||||||
EXPECT_EQ(1, times_called);
|
iter_count++;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(1, iter_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BufferLineWalkerTest, walks_correctly_with_tabs_and_no_line_wrapping)
|
TEST(BufferLineWalkerTest, walks_correctly_with_tabs_and_no_line_wrapping)
|
||||||
{
|
{
|
||||||
static const char data[] = "\t1\t12\t123\t1234\t!";
|
static const char data[] = "\t1\t12\t123\t1234\t!";
|
||||||
std::shared_ptr<Buffer> b = std::make_shared<Buffer>((const uint8_t *)data, strlen(data));
|
std::shared_ptr<Buffer> b = std::make_shared<Buffer>((const uint8_t *)data, strlen(data));
|
||||||
BufferLineWalker blw(b, cld);
|
|
||||||
blw.set_width(100);
|
|
||||||
std::shared_ptr<Buffer::Iterator> start_of_line = b->add_iterator();
|
std::shared_ptr<Buffer::Iterator> start_of_line = b->add_iterator();
|
||||||
int times_called = 0;
|
BufferLineWalker blw(b, start_of_line, 100, cld);
|
||||||
blw.walk_line(*start_of_line, [×_called](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & it) -> bool {
|
|
||||||
EXPECT_EQ(0, row_offset);
|
|
||||||
static int expected_screen_columns[] = {
|
static int expected_screen_columns[] = {
|
||||||
0, 4, 5, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 24, 25
|
0, 4, 5, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 24, 25
|
||||||
};
|
};
|
||||||
static int expected_character_widths[] = {
|
static int expected_character_widths[] = {
|
||||||
4, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 0
|
4, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 0
|
||||||
};
|
};
|
||||||
EXPECT_LT(times_called, (int)(sizeof(expected_screen_columns)/sizeof(expected_screen_columns[0])));
|
int iter_count = 0;
|
||||||
EXPECT_EQ(expected_screen_columns[times_called], screen_column);
|
for (; blw.is_valid(); blw++)
|
||||||
EXPECT_EQ(expected_screen_columns[times_called], virtual_column);
|
{
|
||||||
EXPECT_EQ(expected_character_widths[times_called], character_width);
|
EXPECT_EQ(0, blw.row_offset());
|
||||||
times_called++;
|
EXPECT_LT(iter_count, (int)(sizeof(expected_screen_columns)/sizeof(expected_screen_columns[0])));
|
||||||
return true;
|
EXPECT_EQ(expected_screen_columns[iter_count], blw.screen_column());
|
||||||
});
|
EXPECT_EQ(expected_screen_columns[iter_count], blw.virtual_column());
|
||||||
EXPECT_EQ((int)strlen(data) + 1, times_called);
|
EXPECT_EQ(expected_character_widths[iter_count], blw.character_width());
|
||||||
|
iter_count++;
|
||||||
|
}
|
||||||
|
EXPECT_EQ((int)strlen(data) + 1, iter_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BufferLineWalkerTest, walks_correctly_with_tabs_and_line_wrapping)
|
TEST(BufferLineWalkerTest, walks_correctly_with_tabs_and_line_wrapping)
|
||||||
{
|
{
|
||||||
static const char data[] = "\t1\t12\t123\t1234\t!";
|
static const char data[] = "\t1\t12\t123\t1234\t!";
|
||||||
std::shared_ptr<Buffer> b = std::make_shared<Buffer>((const uint8_t *)data, strlen(data));
|
std::shared_ptr<Buffer> b = std::make_shared<Buffer>((const uint8_t *)data, strlen(data));
|
||||||
BufferLineWalker blw(b, cld);
|
|
||||||
blw.set_width(5);
|
|
||||||
std::shared_ptr<Buffer::Iterator> start_of_line = b->add_iterator();
|
std::shared_ptr<Buffer::Iterator> start_of_line = b->add_iterator();
|
||||||
int times_called = 0;
|
BufferLineWalker blw(b, start_of_line, 5, cld);
|
||||||
blw.walk_line(*start_of_line, [×_called](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & it) -> bool {
|
|
||||||
static int expected_screen_columns[] = {
|
static int expected_screen_columns[] = {
|
||||||
0, 4, 0, 3, 4, 0, 2, 3, 4, 0, 1, 2, 3, 4, 0, 4, 0
|
0, 4, 0, 3, 4, 0, 2, 3, 4, 0, 1, 2, 3, 4, 0, 4, 0
|
||||||
};
|
};
|
||||||
@ -82,26 +80,26 @@ TEST(BufferLineWalkerTest, walks_correctly_with_tabs_and_line_wrapping)
|
|||||||
static int expected_character_widths[] = {
|
static int expected_character_widths[] = {
|
||||||
4, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 0
|
4, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 0
|
||||||
};
|
};
|
||||||
EXPECT_LT(times_called, (int)(sizeof(expected_screen_columns)/sizeof(expected_screen_columns[0])));
|
int iter_count = 0;
|
||||||
EXPECT_EQ(expected_row_offsets[times_called], row_offset);
|
for (; blw.is_valid(); blw++)
|
||||||
EXPECT_EQ(expected_screen_columns[times_called], screen_column);
|
{
|
||||||
EXPECT_EQ(expected_virtual_columns[times_called], virtual_column);
|
EXPECT_LT(iter_count, (int)(sizeof(expected_screen_columns)/sizeof(expected_screen_columns[0])));
|
||||||
EXPECT_EQ(expected_character_widths[times_called], character_width);
|
EXPECT_EQ(expected_row_offsets[iter_count], blw.row_offset());
|
||||||
times_called++;
|
EXPECT_EQ(expected_screen_columns[iter_count], blw.screen_column());
|
||||||
return true;
|
EXPECT_EQ(expected_virtual_columns[iter_count], blw.virtual_column());
|
||||||
});
|
EXPECT_EQ(expected_character_widths[iter_count], blw.character_width());
|
||||||
EXPECT_EQ((int)strlen(data) + 1, times_called);
|
iter_count++;
|
||||||
|
}
|
||||||
|
EXPECT_EQ((int)strlen(data) + 1, iter_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BufferLineWalkerTest, walks_correctly_with_multi_column_characters_and_line_wrapping)
|
TEST(BufferLineWalkerTest, walks_correctly_with_multi_column_characters_and_line_wrapping)
|
||||||
{
|
{
|
||||||
static const char data[] = "ab\002xyz\003.";
|
static const char data[] = "ab\002xyz\003.";
|
||||||
std::shared_ptr<Buffer> b = std::make_shared<Buffer>((const uint8_t *)data, strlen(data));
|
std::shared_ptr<Buffer> b = std::make_shared<Buffer>((const uint8_t *)data, strlen(data));
|
||||||
BufferLineWalker blw(b, cld);
|
|
||||||
blw.set_width(4);
|
|
||||||
std::shared_ptr<Buffer::Iterator> start_of_line = b->add_iterator();
|
std::shared_ptr<Buffer::Iterator> start_of_line = b->add_iterator();
|
||||||
int times_called = 0;
|
BufferLineWalker blw(b, start_of_line, 4, cld);
|
||||||
blw.walk_line(*start_of_line, [×_called](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & it) -> bool {
|
|
||||||
static int expected_screen_columns[] = {
|
static int expected_screen_columns[] = {
|
||||||
0, 1, 2, 0, 1, 2, 0, 2, 3
|
0, 1, 2, 0, 1, 2, 0, 2, 3
|
||||||
};
|
};
|
||||||
@ -114,26 +112,26 @@ TEST(BufferLineWalkerTest, walks_correctly_with_multi_column_characters_and_line
|
|||||||
static int expected_character_widths[] = {
|
static int expected_character_widths[] = {
|
||||||
1, 1, 2, 1, 1, 1, 2, 1, 0
|
1, 1, 2, 1, 1, 1, 2, 1, 0
|
||||||
};
|
};
|
||||||
EXPECT_LT(times_called, (int)(sizeof(expected_screen_columns)/sizeof(expected_screen_columns[0])));
|
int iter_count = 0;
|
||||||
EXPECT_EQ(expected_row_offsets[times_called], row_offset);
|
for (; blw.is_valid(); blw++)
|
||||||
EXPECT_EQ(expected_screen_columns[times_called], screen_column);
|
{
|
||||||
EXPECT_EQ(expected_virtual_columns[times_called], virtual_column);
|
EXPECT_LT(iter_count, (int)(sizeof(expected_screen_columns)/sizeof(expected_screen_columns[0])));
|
||||||
EXPECT_EQ(expected_character_widths[times_called], character_width);
|
EXPECT_EQ(expected_row_offsets[iter_count], blw.row_offset());
|
||||||
times_called++;
|
EXPECT_EQ(expected_screen_columns[iter_count], blw.screen_column());
|
||||||
return true;
|
EXPECT_EQ(expected_virtual_columns[iter_count], blw.virtual_column());
|
||||||
});
|
EXPECT_EQ(expected_character_widths[iter_count], blw.character_width());
|
||||||
EXPECT_EQ((int)strlen(data) + 1, times_called);
|
iter_count++;
|
||||||
|
}
|
||||||
|
EXPECT_EQ((int)strlen(data) + 1, iter_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BufferLineWalkerTest, does_not_push_down_a_row_when_a_multi_column_character_is_wider_than_view_width)
|
TEST(BufferLineWalkerTest, does_not_push_down_a_row_when_a_multi_column_character_is_wider_than_view_width)
|
||||||
{
|
{
|
||||||
static const char data[] = "\002\003";
|
static const char data[] = "\002\003";
|
||||||
std::shared_ptr<Buffer> b = std::make_shared<Buffer>((const uint8_t *)data, strlen(data));
|
std::shared_ptr<Buffer> b = std::make_shared<Buffer>((const uint8_t *)data, strlen(data));
|
||||||
BufferLineWalker blw(b, cld);
|
|
||||||
blw.set_width(1);
|
|
||||||
std::shared_ptr<Buffer::Iterator> start_of_line = b->add_iterator();
|
std::shared_ptr<Buffer::Iterator> start_of_line = b->add_iterator();
|
||||||
int times_called = 0;
|
BufferLineWalker blw(b, start_of_line, 1, cld);
|
||||||
blw.walk_line(*start_of_line, [×_called](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & it) -> bool {
|
|
||||||
static int expected_screen_columns[] = {
|
static int expected_screen_columns[] = {
|
||||||
0, 0, 0
|
0, 0, 0
|
||||||
};
|
};
|
||||||
@ -146,35 +144,15 @@ TEST(BufferLineWalkerTest, does_not_push_down_a_row_when_a_multi_column_characte
|
|||||||
static int expected_character_widths[] = {
|
static int expected_character_widths[] = {
|
||||||
2, 2, 0
|
2, 2, 0
|
||||||
};
|
};
|
||||||
EXPECT_LT(times_called, (int)(sizeof(expected_screen_columns)/sizeof(expected_screen_columns[0])));
|
int iter_count = 0;
|
||||||
EXPECT_EQ(expected_row_offsets[times_called], row_offset);
|
for (; blw.is_valid(); blw++)
|
||||||
EXPECT_EQ(expected_screen_columns[times_called], screen_column);
|
|
||||||
EXPECT_EQ(expected_virtual_columns[times_called], virtual_column);
|
|
||||||
EXPECT_EQ(expected_character_widths[times_called], character_width);
|
|
||||||
times_called++;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
EXPECT_EQ((int)strlen(data) + 1, times_called);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BufferLineWalkerTest, stops_iterating_when_callback_returns_false)
|
|
||||||
{
|
{
|
||||||
static const char data[] = "abcdef";
|
EXPECT_LT(iter_count, (int)(sizeof(expected_screen_columns)/sizeof(expected_screen_columns[0])));
|
||||||
std::shared_ptr<Buffer> b = std::make_shared<Buffer>((const uint8_t *)data, strlen(data));
|
EXPECT_EQ(expected_row_offsets[iter_count], blw.row_offset());
|
||||||
BufferLineWalker blw(b, cld);
|
EXPECT_EQ(expected_screen_columns[iter_count], blw.screen_column());
|
||||||
blw.set_width(6);
|
EXPECT_EQ(expected_virtual_columns[iter_count], blw.virtual_column());
|
||||||
std::shared_ptr<Buffer::Iterator> start_of_line = b->add_iterator();
|
EXPECT_EQ(expected_character_widths[iter_count], blw.character_width());
|
||||||
int times_called = 0;
|
iter_count++;
|
||||||
blw.walk_line(*start_of_line, [×_called](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & it) -> bool {
|
|
||||||
times_called++;
|
|
||||||
if (times_called >= 3)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else
|
EXPECT_EQ((int)strlen(data) + 1, iter_count);
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
EXPECT_EQ(3, times_called);
|
|
||||||
}
|
}
|
||||||
|
@ -40,34 +40,34 @@ class MyCharacterWidthDeterminer : public CharacterWidthDeterminer
|
|||||||
}
|
}
|
||||||
} Cwd;
|
} Cwd;
|
||||||
|
|
||||||
static int LineNumber(const Buffer::Iterator & iterator)
|
static int LineNumber(std::shared_ptr<Buffer::Iterator> iterator)
|
||||||
{
|
{
|
||||||
int line_number = 0;
|
int line_number = 0;
|
||||||
Buffer::Iterator i = iterator;
|
auto i = std::make_shared<Buffer::Iterator>(*iterator);
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
uint32_t c = *i;
|
uint32_t c = **i;
|
||||||
if ((c < '0') || (c > '9'))
|
if ((c < '0') || (c > '9'))
|
||||||
break;
|
break;
|
||||||
line_number *= 10;
|
line_number *= 10;
|
||||||
line_number += ((int)c - '0');
|
line_number += ((int)c - '0');
|
||||||
i.go_forward();
|
i->go_forward();
|
||||||
}
|
}
|
||||||
return line_number;
|
return line_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BufferViewTest, iter_lines_does_not_call_callback_for_empty_buffer)
|
TEST(BufferViewTest, does_not_iterate_for_empty_buffer)
|
||||||
{
|
{
|
||||||
std::shared_ptr<Buffer> b = buffer_empty();
|
std::shared_ptr<Buffer> b = buffer_empty();
|
||||||
std::shared_ptr<Buffer::Iterator> iterator = b->add_iterator();
|
std::shared_ptr<Buffer::Iterator> iterator = b->add_iterator();
|
||||||
BufferView bv(b, iterator, Cwd);
|
BufferView bv(b, iterator, Cwd);
|
||||||
bv.resize(40, 8);
|
bv.resize(40, 8);
|
||||||
int times_called = 0;
|
int iter_count = 0;
|
||||||
bv.iter_lines([×_called](int row_offset, const Buffer::Iterator & iterator) -> bool {
|
for (auto it = bv.vert_iter(); it.is_valid(); it++)
|
||||||
times_called++;
|
{
|
||||||
return true;
|
iter_count++;
|
||||||
});
|
}
|
||||||
EXPECT_EQ(0, times_called);
|
EXPECT_EQ(0, iter_count);
|
||||||
EXPECT_EQ(0, bv.cursor_screen_row());
|
EXPECT_EQ(0, bv.cursor_screen_row());
|
||||||
EXPECT_EQ(0, bv.cursor_screen_column());
|
EXPECT_EQ(0, bv.cursor_screen_column());
|
||||||
EXPECT_EQ(0, bv.cursor_virtual_column());
|
EXPECT_EQ(0, bv.cursor_virtual_column());
|
||||||
@ -79,13 +79,13 @@ TEST(BufferViewTest, iterates_through_screen_lines_with_no_wrapping)
|
|||||||
std::shared_ptr<Buffer::Iterator> iterator = b->add_iterator();
|
std::shared_ptr<Buffer::Iterator> iterator = b->add_iterator();
|
||||||
BufferView bv(b, iterator, Cwd);
|
BufferView bv(b, iterator, Cwd);
|
||||||
bv.resize(40, 8);
|
bv.resize(40, 8);
|
||||||
int times_called = 0;
|
int iter_count = 0;
|
||||||
bv.iter_lines([×_called](int row_offset, const Buffer::Iterator & iterator) -> bool {
|
for (auto it = bv.vert_iter(); it.is_valid(); it++)
|
||||||
EXPECT_EQ(times_called, LineNumber(iterator));
|
{
|
||||||
times_called++;
|
EXPECT_EQ(iter_count, LineNumber(it.iterator()));
|
||||||
return true;
|
iter_count++;
|
||||||
});
|
}
|
||||||
EXPECT_EQ(8, times_called);
|
EXPECT_EQ(8, iter_count);
|
||||||
EXPECT_EQ(0, bv.cursor_screen_row());
|
EXPECT_EQ(0, bv.cursor_screen_row());
|
||||||
EXPECT_EQ(0, bv.cursor_screen_column());
|
EXPECT_EQ(0, bv.cursor_screen_column());
|
||||||
EXPECT_EQ(0, bv.cursor_virtual_column());
|
EXPECT_EQ(0, bv.cursor_virtual_column());
|
||||||
@ -97,15 +97,15 @@ TEST(BufferViewTest, iterates_through_screen_lines_with_wrapping)
|
|||||||
std::shared_ptr<Buffer::Iterator> iterator = b->add_iterator();
|
std::shared_ptr<Buffer::Iterator> iterator = b->add_iterator();
|
||||||
BufferView bv(b, iterator, Cwd);
|
BufferView bv(b, iterator, Cwd);
|
||||||
bv.resize(3, 10);
|
bv.resize(3, 10);
|
||||||
int times_called = 0;
|
int iter_count = 0;
|
||||||
int expected_row_offsets[] = {0, 1, 2, 4, 5, 6, 7};
|
int expected_row_offsets[] = {0, 1, 2, 4, 5, 6, 7};
|
||||||
bv.iter_lines([×_called, &expected_row_offsets](int row_offset, const Buffer::Iterator & iterator) -> bool {
|
for (auto it = bv.vert_iter(); it.is_valid(); it++)
|
||||||
EXPECT_EQ(times_called, LineNumber(iterator));
|
{
|
||||||
EXPECT_EQ(expected_row_offsets[times_called], row_offset);
|
EXPECT_EQ(iter_count, LineNumber(it.iterator()));
|
||||||
times_called++;
|
EXPECT_EQ(expected_row_offsets[iter_count], it.row_offset());
|
||||||
return true;
|
iter_count++;
|
||||||
});
|
}
|
||||||
EXPECT_EQ(7, times_called);
|
EXPECT_EQ(7, iter_count);
|
||||||
EXPECT_EQ(0, bv.cursor_screen_row());
|
EXPECT_EQ(0, bv.cursor_screen_row());
|
||||||
EXPECT_EQ(0, bv.cursor_screen_column());
|
EXPECT_EQ(0, bv.cursor_screen_column());
|
||||||
EXPECT_EQ(0, bv.cursor_virtual_column());
|
EXPECT_EQ(0, bv.cursor_virtual_column());
|
||||||
@ -120,15 +120,15 @@ TEST(BufferViewTest, fills_view_with_last_lines_of_buffer_when_cursor_warps_to_l
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
bv.resize(40, 3);
|
bv.resize(40, 3);
|
||||||
int times_called = 0;
|
int iter_count = 0;
|
||||||
int expected_row_offsets[] = {0, 1, 2};
|
int expected_row_offsets[] = {0, 1, 2};
|
||||||
bv.iter_lines([×_called, &expected_row_offsets](int row_offset, const Buffer::Iterator & iterator) -> bool {
|
for (auto it = bv.vert_iter(); it.is_valid(); it++)
|
||||||
EXPECT_EQ(10 + times_called, LineNumber(iterator));
|
{
|
||||||
EXPECT_EQ(expected_row_offsets[times_called], row_offset);
|
EXPECT_EQ(10 + iter_count, LineNumber(it.iterator()));
|
||||||
times_called++;
|
EXPECT_EQ(expected_row_offsets[iter_count], it.row_offset());
|
||||||
return true;
|
iter_count++;
|
||||||
});
|
}
|
||||||
EXPECT_EQ(3, times_called);
|
EXPECT_EQ(3, iter_count);
|
||||||
EXPECT_EQ(2, bv.cursor_screen_row());
|
EXPECT_EQ(2, bv.cursor_screen_row());
|
||||||
EXPECT_EQ(0, bv.cursor_screen_column());
|
EXPECT_EQ(0, bv.cursor_screen_column());
|
||||||
EXPECT_EQ(0, bv.cursor_virtual_column());
|
EXPECT_EQ(0, bv.cursor_virtual_column());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user