diff --git a/src/display_buffer.cc b/src/display_buffer.cc index 55772b6b..8cda0c47 100644 --- a/src/display_buffer.cc +++ b/src/display_buffer.cc @@ -94,6 +94,19 @@ DisplayLine::iterator DisplayLine::split(iterator it, ByteCoord pos) 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) { if (atom.has_buffer_range()) diff --git a/src/display_buffer.hh b/src/display_buffer.hh index 35381058..8e543284 100644 --- a/src/display_buffer.hh +++ b/src/display_buffer.hh @@ -117,9 +117,14 @@ public: 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 buffer coord pos, + // returns an iterator to the first atom 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 erase(iterator beg, iterator end); void push_back(DisplayAtom atom); diff --git a/src/highlighters.cc b/src/highlighters.cc index 5ff6d6a2..905c5632 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -577,12 +577,54 @@ HighlighterAndId create_column_highlighter(HighlighterParameters params) } if (not found) { - CharCount col = get_column(buffer, tabstop, buffer.prev(line.range().end)); - if (col < column) + CharCount first_buffer_col = -1; + 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}); } + 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; + } + } } } };