Improve column highlighter to cooperate better with other highlighters

Fixes #268
This commit is contained in:
Maxime Coste 2015-07-23 13:58:23 +01:00
parent 654904f046
commit 2946504a17
3 changed files with 64 additions and 4 deletions

View File

@ -94,6 +94,19 @@ DisplayLine::iterator DisplayLine::split(iterator it, ByteCoord pos)
return m_atoms.insert(it, std::move(atom)); return m_atoms.insert(it, std::move(atom));
} }
DisplayLine::iterator DisplayLine::split(iterator it, CharCount pos)
{
kak_assert(it->type() == DisplayAtom::Text);
kak_assert(pos > 0);
kak_assert(pos < it->length());
DisplayAtom atom(it->m_text.substr(0, pos).str());
it->m_text = it->m_text.substr(pos).str();
atom.check_invariant();
it->check_invariant();
return m_atoms.insert(it, std::move(atom));
}
DisplayLine::iterator DisplayLine::insert(iterator it, DisplayAtom atom) DisplayLine::iterator DisplayLine::insert(iterator it, DisplayAtom atom)
{ {
if (atom.has_buffer_range()) if (atom.has_buffer_range())

View File

@ -117,9 +117,14 @@ public:
CharCount length() const; CharCount length() const;
const BufferRange& range() const { return m_range; } 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 buffer coord pos,
// returns an iterator to the first atom
iterator split(iterator it, ByteCoord pos); iterator split(iterator it, ByteCoord pos);
// Split atom pointed by it at its pos character,
// returns an iterator to the first atom
iterator split(iterator it, CharCount pos);
iterator insert(iterator it, DisplayAtom atom); iterator insert(iterator it, DisplayAtom atom);
iterator erase(iterator beg, iterator end); iterator erase(iterator beg, iterator end);
void push_back(DisplayAtom atom); void push_back(DisplayAtom atom);

View File

@ -577,12 +577,54 @@ HighlighterAndId create_column_highlighter(HighlighterParameters params)
} }
if (not found) if (not found)
{ {
CharCount col = get_column(buffer, tabstop, buffer.prev(line.range().end)); CharCount first_buffer_col = -1;
if (col < column) CharCount first_display_col = 0;
for (auto& atom : line)
{ {
line.push_back({String{' ', column - col - 1}}); if (atom.has_buffer_range())
{
first_buffer_col = get_column(buffer, tabstop, atom.begin());
break;
}
first_display_col += atom.length();
}
if (first_buffer_col == -1)
continue;
CharCount eol_col = line.length();
CharCount count = column + first_display_col - first_buffer_col - eol_col;
if (count >= 0)
{
if (count > 0)
line.push_back({String{' ', count}});
line.push_back({String{" "}, face}); line.push_back({String{" "}, face});
} }
else
{
for (auto atom_it = line.end(); atom_it != line.begin() and count < 0; --atom_it)
{
DisplayAtom& atom = *(atom_it-1);
const CharCount len = atom.length();
if (atom.type() == DisplayAtom::Text and -count <= len)
{
auto it = atom_it - 1;
CharCount pos = len + count;
if (pos > 0)
{
it = ++line.split(it, pos);
pos = 0;
}
if (pos+1 != it->length())
it = line.split(it, pos+1);
apply_face(face)(*it);
break;
}
count += len;
}
}
} }
} }
}; };