DisplayLine no longer map to a single buffer line, but to a buffer range
This commit is contained in:
parent
486ebed098
commit
c7e52a650d
|
@ -23,6 +23,12 @@ void AtomContent::trim_end(CharCount count)
|
||||||
m_text = m_text.substr(0, m_text.char_length() - count);
|
m_text = m_text.substr(0, m_text.char_length() - count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DisplayLine::DisplayLine(AtomList atoms)
|
||||||
|
: m_atoms(std::move(atoms))
|
||||||
|
{
|
||||||
|
compute_range();
|
||||||
|
}
|
||||||
|
|
||||||
DisplayLine::iterator DisplayLine::split(iterator it, BufferCoord pos)
|
DisplayLine::iterator DisplayLine::split(iterator it, BufferCoord pos)
|
||||||
{
|
{
|
||||||
kak_assert(it->content.type() == AtomContent::BufferRange);
|
kak_assert(it->content.type() == AtomContent::BufferRange);
|
||||||
|
@ -35,6 +41,26 @@ DisplayLine::iterator DisplayLine::split(iterator it, BufferCoord pos)
|
||||||
return m_atoms.insert(it, std::move(atom));
|
return m_atoms.insert(it, std::move(atom));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DisplayLine::iterator DisplayLine::insert(iterator it, DisplayAtom atom)
|
||||||
|
{
|
||||||
|
if (atom.content.has_buffer_range())
|
||||||
|
{
|
||||||
|
m_range.first = std::min(m_range.first, atom.content.begin());
|
||||||
|
m_range.second = std::max(m_range.second, atom.content.end());
|
||||||
|
}
|
||||||
|
return m_atoms.insert(it, std::move(atom));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayLine::push_back(DisplayAtom atom)
|
||||||
|
{
|
||||||
|
if (atom.content.has_buffer_range())
|
||||||
|
{
|
||||||
|
m_range.first = std::min(m_range.first, atom.content.begin());
|
||||||
|
m_range.second = std::max(m_range.second, atom.content.end());
|
||||||
|
}
|
||||||
|
m_atoms.push_back(std::move(atom));
|
||||||
|
}
|
||||||
|
|
||||||
void DisplayLine::optimize()
|
void DisplayLine::optimize()
|
||||||
{
|
{
|
||||||
if (m_atoms.empty())
|
if (m_atoms.empty())
|
||||||
|
@ -112,6 +138,20 @@ void DisplayLine::trim(CharCount first_char, CharCount char_count)
|
||||||
if (char_count < 0)
|
if (char_count < 0)
|
||||||
(it-1)->content.trim_end(-char_count);
|
(it-1)->content.trim_end(-char_count);
|
||||||
m_atoms.erase(it, end());
|
m_atoms.erase(it, end());
|
||||||
|
|
||||||
|
compute_range();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayLine::compute_range()
|
||||||
|
{
|
||||||
|
m_range = { {INT_MAX, INT_MAX}, {INT_MIN, INT_MIN} };
|
||||||
|
for (auto& atom : m_atoms)
|
||||||
|
{
|
||||||
|
if (not atom.content.has_buffer_range())
|
||||||
|
continue;
|
||||||
|
m_range.first = std::min(m_range.first, atom.content.begin());
|
||||||
|
m_range.second = std::max(m_range.second, atom.content.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayBuffer::compute_range()
|
void DisplayBuffer::compute_range()
|
||||||
|
@ -120,17 +160,8 @@ void DisplayBuffer::compute_range()
|
||||||
m_range.second = {0,0};
|
m_range.second = {0,0};
|
||||||
for (auto& line : m_lines)
|
for (auto& line : m_lines)
|
||||||
{
|
{
|
||||||
for (auto& atom : line)
|
m_range.first = std::min(line.range().first, m_range.first);
|
||||||
{
|
m_range.second = std::max(line.range().second, m_range.second);
|
||||||
if (not atom.content.has_buffer_range())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (m_range.first > atom.content.begin())
|
|
||||||
m_range.first = atom.content.begin();
|
|
||||||
|
|
||||||
if (m_range.second < atom.content.end())
|
|
||||||
m_range.second = atom.content.end();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
kak_assert(m_range.first <= m_range.second);
|
kak_assert(m_range.first <= m_range.second);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,6 @@ enum Attributes
|
||||||
Bold = 8
|
Bold = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
class DisplayLine;
|
|
||||||
|
|
||||||
struct AtomContent
|
struct AtomContent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -123,6 +121,8 @@ struct DisplayAtom
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using BufferRange = std::pair<BufferCoord, BufferCoord>;
|
||||||
|
|
||||||
class DisplayLine
|
class DisplayLine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -130,13 +130,10 @@ public:
|
||||||
using iterator = AtomList::iterator;
|
using iterator = AtomList::iterator;
|
||||||
using const_iterator = AtomList::const_iterator;
|
using const_iterator = AtomList::const_iterator;
|
||||||
|
|
||||||
explicit DisplayLine(LineCount buffer_line) : m_buffer_line(buffer_line) {}
|
DisplayLine() = default;
|
||||||
DisplayLine(LineCount buffer_line, AtomList atoms)
|
DisplayLine(AtomList atoms);
|
||||||
: m_buffer_line(buffer_line), m_atoms(std::move(atoms)) {}
|
|
||||||
DisplayLine(String str, ColorPair color)
|
DisplayLine(String str, ColorPair color)
|
||||||
: m_buffer_line(-1), m_atoms{ { std::move(str), color } } {}
|
{ push_back({ std::move(str), color }); }
|
||||||
|
|
||||||
LineCount buffer_line() const { return m_buffer_line; }
|
|
||||||
|
|
||||||
iterator begin() { return m_atoms.begin(); }
|
iterator begin() { return m_atoms.begin(); }
|
||||||
iterator end() { return m_atoms.end(); }
|
iterator end() { return m_atoms.end(); }
|
||||||
|
@ -147,12 +144,13 @@ public:
|
||||||
const AtomList& atoms() const { return m_atoms; }
|
const AtomList& atoms() const { return m_atoms; }
|
||||||
|
|
||||||
CharCount length() const;
|
CharCount length() const;
|
||||||
|
const BufferRange& range() const { return m_range; }
|
||||||
|
|
||||||
// Split atom pointed by it at pos, returns an iterator to the first atom
|
// Split atom pointed by it at pos, returns an iterator to the first atom
|
||||||
iterator split(iterator it, BufferCoord pos);
|
iterator split(iterator it, BufferCoord pos);
|
||||||
|
|
||||||
iterator insert(iterator it, DisplayAtom atom) { return m_atoms.insert(it, std::move(atom)); }
|
iterator insert(iterator it, DisplayAtom atom);
|
||||||
void push_back(DisplayAtom atom) { m_atoms.push_back(std::move(atom)); }
|
void push_back(DisplayAtom atom);
|
||||||
|
|
||||||
// remove first_char from the begining of the line, and make sure
|
// remove first_char from the begining of the line, and make sure
|
||||||
// the line is less that char_count character
|
// the line is less that char_count character
|
||||||
|
@ -160,12 +158,11 @@ public:
|
||||||
|
|
||||||
void optimize();
|
void optimize();
|
||||||
private:
|
private:
|
||||||
LineCount m_buffer_line;
|
void compute_range();
|
||||||
|
BufferRange m_range = { { INT_MAX, INT_MAX }, { INT_MIN, INT_MIN } };
|
||||||
AtomList m_atoms;
|
AtomList m_atoms;
|
||||||
};
|
};
|
||||||
|
|
||||||
using BufferRange = std::pair<BufferCoord, BufferCoord>;
|
|
||||||
|
|
||||||
class DisplayBuffer
|
class DisplayBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -31,7 +31,8 @@ void highlight_range(DisplayBuffer& display_buffer,
|
||||||
|
|
||||||
for (auto& line : display_buffer.lines())
|
for (auto& line : display_buffer.lines())
|
||||||
{
|
{
|
||||||
if (line.buffer_line() < begin.line or end.line < line.buffer_line())
|
auto& range = line.range();
|
||||||
|
if (range.second <= begin or end < range.first)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
|
for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
|
||||||
|
@ -235,7 +236,7 @@ void expand_tabulations(const Window& window, DisplayBuffer& display_buffer)
|
||||||
atom_it = line.split(atom_it, (it+1).coord());
|
atom_it = line.split(atom_it, (it+1).coord());
|
||||||
|
|
||||||
int column = 0;
|
int column = 0;
|
||||||
for (auto line_it = buffer.iterator_at(line.buffer_line());
|
for (auto line_it = buffer.iterator_at(it.coord().line);
|
||||||
line_it != it; ++line_it)
|
line_it != it; ++line_it)
|
||||||
{
|
{
|
||||||
kak_assert(*line_it != '\n');
|
kak_assert(*line_it != '\n');
|
||||||
|
@ -270,7 +271,7 @@ void show_line_numbers(const Window& window, DisplayBuffer& display_buffer)
|
||||||
for (auto& line : display_buffer.lines())
|
for (auto& line : display_buffer.lines())
|
||||||
{
|
{
|
||||||
char buffer[10];
|
char buffer[10];
|
||||||
snprintf(buffer, 10, format, (int)line.buffer_line() + 1);
|
snprintf(buffer, 10, format, (int)line.range().first.line + 1);
|
||||||
DisplayAtom atom = DisplayAtom(AtomContent(buffer));
|
DisplayAtom atom = DisplayAtom(AtomContent(buffer));
|
||||||
atom.colors = colors;
|
atom.colors = colors;
|
||||||
line.insert(line.begin(), std::move(atom));
|
line.insert(line.begin(), std::move(atom));
|
||||||
|
@ -358,7 +359,7 @@ public:
|
||||||
const String empty{' ', width};
|
const String empty{' ', width};
|
||||||
for (auto& line : display_buffer.lines())
|
for (auto& line : display_buffer.lines())
|
||||||
{
|
{
|
||||||
int line_num = (int)line.buffer_line() + 1;
|
int line_num = (int)line.range().first.line + 1;
|
||||||
auto it = find_if(lines, [&](const LineAndFlag& l) { return std::get<0>(l) == line_num; });
|
auto it = find_if(lines, [&](const LineAndFlag& l) { return std::get<0>(l) == line_num; });
|
||||||
String content = it != lines.end() ? std::get<2>(*it) : empty;
|
String content = it != lines.end() ? std::get<2>(*it) : empty;
|
||||||
content += String(' ', width - content.char_length());
|
content += String(' ', width - content.char_length());
|
||||||
|
|
|
@ -146,12 +146,12 @@ public:
|
||||||
{
|
{
|
||||||
kak_assert(m_cursor_pos <= m_line.char_length());
|
kak_assert(m_cursor_pos <= m_line.char_length());
|
||||||
if (m_cursor_pos == m_line.char_length())
|
if (m_cursor_pos == m_line.char_length())
|
||||||
return DisplayLine{-1, { {m_line, get_color("StatusLine")},
|
return DisplayLine{{ {m_line, get_color("StatusLine")},
|
||||||
{" "_str, get_color("StatusCursor")} }};
|
{" "_str, get_color("StatusCursor")} }};
|
||||||
else
|
else
|
||||||
return DisplayLine(-1, { DisplayAtom{ m_line.substr(0, m_cursor_pos), get_color("StatusLine") },
|
return DisplayLine({ { m_line.substr(0, m_cursor_pos), get_color("StatusLine") },
|
||||||
DisplayAtom{ m_line.substr(m_cursor_pos, 1), get_color("StatusCursor") },
|
{ m_line.substr(m_cursor_pos, 1), get_color("StatusCursor") },
|
||||||
DisplayAtom{ m_line.substr(m_cursor_pos+1), get_color("StatusLine") } });
|
{ m_line.substr(m_cursor_pos+1), get_color("StatusLine") } });
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
CharCount m_cursor_pos = 0;
|
CharCount m_cursor_pos = 0;
|
||||||
|
@ -181,7 +181,7 @@ public:
|
||||||
if (key == Key(Key::Modifiers::Control, 'm'))
|
if (key == Key(Key::Modifiers::Control, 'm'))
|
||||||
{
|
{
|
||||||
context().ui().menu_hide();
|
context().ui().menu_hide();
|
||||||
context().ui().print_status(DisplayLine{ -1 });
|
context().ui().print_status(DisplayLine{});
|
||||||
reset_normal_mode();
|
reset_normal_mode();
|
||||||
int selected = m_selected - m_choices.begin();
|
int selected = m_selected - m_choices.begin();
|
||||||
m_callback(selected, MenuEvent::Validate, context());
|
m_callback(selected, MenuEvent::Validate, context());
|
||||||
|
@ -194,7 +194,7 @@ public:
|
||||||
m_edit_filter = false;
|
m_edit_filter = false;
|
||||||
m_filter = boost::regex(".*");
|
m_filter = boost::regex(".*");
|
||||||
m_filter_editor.reset("");
|
m_filter_editor.reset("");
|
||||||
context().ui().print_status(DisplayLine{ -1 });
|
context().ui().print_status(DisplayLine{});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -319,7 +319,7 @@ public:
|
||||||
history.erase(it);
|
history.erase(it);
|
||||||
history.push_back(line);
|
history.push_back(line);
|
||||||
}
|
}
|
||||||
context().ui().print_status(DisplayLine{ -1 });
|
context().ui().print_status(DisplayLine{});
|
||||||
context().ui().menu_hide();
|
context().ui().menu_hide();
|
||||||
reset_normal_mode();
|
reset_normal_mode();
|
||||||
// call callback after reset_normal_mode so that callback
|
// call callback after reset_normal_mode so that callback
|
||||||
|
@ -329,7 +329,7 @@ public:
|
||||||
}
|
}
|
||||||
else if (key == Key::Escape or key == Key { Key::Modifiers::Control, 'c' })
|
else if (key == Key::Escape or key == Key { Key::Modifiers::Control, 'c' })
|
||||||
{
|
{
|
||||||
context().ui().print_status(DisplayLine{ -1 });
|
context().ui().print_status(DisplayLine{});
|
||||||
context().ui().menu_hide();
|
context().ui().menu_hide();
|
||||||
reset_normal_mode();
|
reset_normal_mode();
|
||||||
m_callback(line, PromptEvent::Abort, context());
|
m_callback(line, PromptEvent::Abort, context());
|
||||||
|
|
|
@ -142,8 +142,7 @@ void on_sigint(int)
|
||||||
}
|
}
|
||||||
|
|
||||||
NCursesUI::NCursesUI()
|
NCursesUI::NCursesUI()
|
||||||
: m_stdin_watcher{0, [this](FDWatcher&){ if (m_input_callback) m_input_callback(); }},
|
: m_stdin_watcher{0, [this](FDWatcher&){ if (m_input_callback) m_input_callback(); }}
|
||||||
m_status_line{-1}
|
|
||||||
{
|
{
|
||||||
initscr();
|
initscr();
|
||||||
cbreak();
|
cbreak();
|
||||||
|
|
|
@ -194,7 +194,7 @@ DisplayAtom read<DisplayAtom>(int socket)
|
||||||
template<>
|
template<>
|
||||||
DisplayLine read<DisplayLine>(int socket)
|
DisplayLine read<DisplayLine>(int socket)
|
||||||
{
|
{
|
||||||
return DisplayLine(0, read_vector<DisplayAtom>(socket));
|
return DisplayLine(read_vector<DisplayAtom>(socket));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -69,7 +69,7 @@ void Window::update_display_buffer()
|
||||||
LineCount buffer_line = m_position.line + line;
|
LineCount buffer_line = m_position.line + line;
|
||||||
if (buffer_line >= buffer().line_count())
|
if (buffer_line >= buffer().line_count())
|
||||||
break;
|
break;
|
||||||
lines.push_back(DisplayLine(buffer_line));
|
lines.emplace_back();
|
||||||
lines.back().push_back(DisplayAtom(AtomContent(buffer(), buffer_line, buffer_line+1)));
|
lines.back().push_back(DisplayAtom(AtomContent(buffer(), buffer_line, buffer_line+1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ void Window::scroll_to_keep_cursor_visible_ifn()
|
||||||
// highlight only the line containing the cursor
|
// highlight only the line containing the cursor
|
||||||
DisplayBuffer display_buffer;
|
DisplayBuffer display_buffer;
|
||||||
DisplayBuffer::LineList& lines = display_buffer.lines();
|
DisplayBuffer::LineList& lines = display_buffer.lines();
|
||||||
lines.push_back(DisplayLine(last.line));
|
lines.emplace_back();
|
||||||
|
|
||||||
lines.back().push_back(DisplayAtom(AtomContent(buffer(), last.line, last.line+1)));
|
lines.back().push_back(DisplayAtom(AtomContent(buffer(), last.line, last.line+1)));
|
||||||
|
|
||||||
|
@ -172,7 +172,6 @@ namespace
|
||||||
CharCount find_display_column(const DisplayLine& line, const Buffer& buffer,
|
CharCount find_display_column(const DisplayLine& line, const Buffer& buffer,
|
||||||
const BufferCoord& coord)
|
const BufferCoord& coord)
|
||||||
{
|
{
|
||||||
kak_assert(coord.line == line.buffer_line());
|
|
||||||
CharCount column = 0;
|
CharCount column = 0;
|
||||||
for (auto& atom : line)
|
for (auto& atom : line)
|
||||||
{
|
{
|
||||||
|
@ -193,7 +192,7 @@ CharCount find_display_column(const DisplayLine& line, const Buffer& buffer,
|
||||||
BufferCoord find_buffer_coord(const DisplayLine& line, const Buffer& buffer,
|
BufferCoord find_buffer_coord(const DisplayLine& line, const Buffer& buffer,
|
||||||
CharCount column)
|
CharCount column)
|
||||||
{
|
{
|
||||||
LineCount l = line.buffer_line();
|
auto& range = line.range();
|
||||||
for (auto& atom : line)
|
for (auto& atom : line)
|
||||||
{
|
{
|
||||||
auto& content = atom.content;
|
auto& content = atom.content;
|
||||||
|
@ -201,13 +200,13 @@ BufferCoord find_buffer_coord(const DisplayLine& line, const Buffer& buffer,
|
||||||
if (content.has_buffer_range() and column < len)
|
if (content.has_buffer_range() and column < len)
|
||||||
{
|
{
|
||||||
if (content.type() == AtomContent::BufferRange)
|
if (content.type() == AtomContent::BufferRange)
|
||||||
return utf8::advance(buffer.iterator_at(content.begin()), buffer.iterator_at(l+1),
|
return utf8::advance(buffer.iterator_at(content.begin()), buffer.iterator_at(range.second),
|
||||||
std::max(0_char, column)).coord();
|
std::max(0_char, column)).coord();
|
||||||
return content.begin();
|
return content.begin();
|
||||||
}
|
}
|
||||||
column -= len;
|
column -= len;
|
||||||
}
|
}
|
||||||
return buffer.clamp({l, buffer[l].length()});
|
return buffer.clamp(buffer.prev(range.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +215,8 @@ DisplayCoord Window::display_position(const BufferCoord& coord)
|
||||||
LineCount l = 0;
|
LineCount l = 0;
|
||||||
for (auto& line : m_display_buffer.lines())
|
for (auto& line : m_display_buffer.lines())
|
||||||
{
|
{
|
||||||
if (line.buffer_line() == coord.line)
|
auto& range = line.range();
|
||||||
|
if (range.first <= coord and coord < range.second)
|
||||||
return {l, find_display_column(line, buffer(), coord)};
|
return {l, find_display_column(line, buffer(), coord)};
|
||||||
++l;
|
++l;
|
||||||
}
|
}
|
||||||
|
@ -229,9 +229,9 @@ BufferCoord Window::offset_coord(const BufferCoord& coord, LineCount offset)
|
||||||
DisplayBuffer display_buffer;
|
DisplayBuffer display_buffer;
|
||||||
DisplayBuffer::LineList& lines = display_buffer.lines();
|
DisplayBuffer::LineList& lines = display_buffer.lines();
|
||||||
{
|
{
|
||||||
lines.emplace_back(coord.line);
|
lines.emplace_back();
|
||||||
lines.back().push_back({AtomContent(buffer(), coord.line, coord.line+1)});
|
lines.back().push_back({AtomContent(buffer(), coord.line, coord.line+1)});
|
||||||
lines.emplace_back(line);
|
lines.emplace_back();
|
||||||
lines.back().push_back({AtomContent(buffer(), line, line+1)});
|
lines.back().push_back({AtomContent(buffer(), line, line+1)});
|
||||||
}
|
}
|
||||||
display_buffer.compute_range();
|
display_buffer.compute_range();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user