summaryrefslogtreecommitdiff
path: root/src/window.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2013-07-17 21:17:32 +0200
committerMaxime Coste <frrrwww@gmail.com>2013-07-23 20:46:15 +0200
commit486ebed098a687bb58b4740db14eaf77f51ef874 (patch)
tree2c45a2de10d7562fe1812e932dbea6ed5f723d70 /src/window.cc
parent5a6922a0458c3eb19aa5a23e1050af2a1a027fcd (diff)
try to preserve display column rather than buffer column when moving line
Diffstat (limited to 'src/window.cc')
-rw-r--r--src/window.cc82
1 files changed, 66 insertions, 16 deletions
diff --git a/src/window.cc b/src/window.cc
index 8e8f2ee8..6c73e11f 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -167,31 +167,81 @@ void Window::scroll_to_keep_cursor_visible_ifn()
}
}
+namespace
+{
+CharCount find_display_column(const DisplayLine& line, const Buffer& buffer,
+ const BufferCoord& coord)
+{
+ kak_assert(coord.line == line.buffer_line());
+ CharCount column = 0;
+ for (auto& atom : line)
+ {
+ auto& content = atom.content;
+ if (content.has_buffer_range() and
+ coord >= content.begin() and coord < content.end())
+ {
+ if (content.type() == AtomContent::BufferRange)
+ column += utf8::distance(buffer.iterator_at(content.begin()),
+ buffer.iterator_at(coord));
+ return column;
+ }
+ column += content.length();
+ }
+ return column;
+}
+
+BufferCoord find_buffer_coord(const DisplayLine& line, const Buffer& buffer,
+ CharCount column)
+{
+ LineCount l = line.buffer_line();
+ for (auto& atom : line)
+ {
+ auto& content = atom.content;
+ CharCount len = content.length();
+ if (content.has_buffer_range() and column < len)
+ {
+ if (content.type() == AtomContent::BufferRange)
+ return utf8::advance(buffer.iterator_at(content.begin()), buffer.iterator_at(l+1),
+ std::max(0_char, column)).coord();
+ return content.begin();
+ }
+ column -= len;
+ }
+ return buffer.clamp({l, buffer[l].length()});
+}
+}
+
DisplayCoord Window::display_position(const BufferCoord& coord)
{
- DisplayCoord res{0,0};
+ LineCount l = 0;
for (auto& line : m_display_buffer.lines())
{
if (line.buffer_line() == coord.line)
- {
- for (auto& atom : line)
- {
- auto& content = atom.content;
- if (content.has_buffer_range() and
- coord >= content.begin() and coord < content.end())
- {
- res.column += utf8::distance(buffer().iterator_at(content.begin()),
- buffer().iterator_at(coord));
- return res;
- }
- res.column += content.length();
- }
- }
- ++res.line;
+ return {l, find_display_column(line, buffer(), coord)};
+ ++l;
}
return { 0, 0 };
}
+BufferCoord Window::offset_coord(const BufferCoord& coord, LineCount offset)
+{
+ auto line = clamp(coord.line + offset, 0_line, buffer().line_count()-1);
+ DisplayBuffer display_buffer;
+ DisplayBuffer::LineList& lines = display_buffer.lines();
+ {
+ lines.emplace_back(coord.line);
+ lines.back().push_back({AtomContent(buffer(), coord.line, coord.line+1)});
+ lines.emplace_back(line);
+ lines.back().push_back({AtomContent(buffer(), line, line+1)});
+ }
+ display_buffer.compute_range();
+ m_highlighters(*this, display_buffer);
+ m_builtin_highlighters(*this, display_buffer);
+
+ CharCount column = find_display_column(lines[0], buffer(), coord);
+ return find_buffer_coord(lines[1], buffer(), column);
+}
+
void Window::on_option_changed(const Option& option)
{
String desc = option.name() + "=" + option.get_as_string();