summaryrefslogtreecommitdiff
path: root/src
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
parent5a6922a0458c3eb19aa5a23e1050af2a1a027fcd (diff)
try to preserve display column rather than buffer column when moving line
Diffstat (limited to 'src')
-rw-r--r--src/editor.cc31
-rw-r--r--src/editor.hh3
-rw-r--r--src/window.cc82
-rw-r--r--src/window.hh2
4 files changed, 91 insertions, 27 deletions
diff --git a/src/editor.cc b/src/editor.cc
index 5d2e4a81..13253ae2 100644
--- a/src/editor.cc
+++ b/src/editor.cc
@@ -168,16 +168,20 @@ void sort_and_merge_overlapping(SelectionList& selections, size_t& main_selectio
merge_overlapping(selections, main_selection, overlaps);
}
+BufferCoord Editor::offset_coord(const BufferCoord& coord, CharCount offset)
+{
+ auto& line = buffer()[coord.line];
+ auto character = std::max(0_char, std::min(line.char_count_to(coord.column) + offset,
+ line.char_length() - 2));
+ return {coord.line, line.byte_count_to(character)};
+}
+
void Editor::move_selections(CharCount offset, SelectMode mode)
{
kak_assert(mode == SelectMode::Replace or mode == SelectMode::Extend);
for (auto& sel : m_selections)
{
- auto last = sel.last();
- auto& line = buffer()[last.line];
- auto character = std::max(0_char, std::min(line.char_count_to(last.column) + offset,
- line.char_length() - 2));
- last.column = line.byte_count_to(character);
+ auto last = offset_coord(sel.last(), offset);
sel.first() = mode == SelectMode::Extend ? sel.first() : last;
sel.last() = last;
avoid_eol(*m_buffer, sel);
@@ -185,17 +189,22 @@ void Editor::move_selections(CharCount offset, SelectMode mode)
sort_and_merge_overlapping(m_selections, m_main_sel);
}
+BufferCoord Editor::offset_coord(const BufferCoord& coord, LineCount offset)
+{
+ auto character = (*m_buffer)[coord.line].char_count_to(coord.column);
+ auto line = clamp(coord.line + offset, 0_line, m_buffer->line_count()-1);
+ auto& content = (*m_buffer)[line];
+
+ character = std::max(0_char, std::min(character, content.char_length() - 2));
+ return {line, content.byte_count_to(character)};
+}
+
void Editor::move_selections(LineCount offset, SelectMode mode)
{
kak_assert(mode == SelectMode::Replace or mode == SelectMode::Extend);
for (auto& sel : m_selections)
{
- auto character = (*m_buffer)[sel.last().line].char_count_to(sel.last().column);
- auto line = clamp(sel.last().line + offset, 0_line, m_buffer->line_count()-1);
- auto& content = (*m_buffer)[line];
-
- character = std::max(0_char, std::min(character, content.char_length() - 2));
- BufferCoord pos{line, content.byte_count_to(character)};
+ auto pos = offset_coord(sel.last(), offset);
sel.first() = mode == SelectMode::Extend ? sel.first() : pos;
sel.last() = pos;
avoid_eol(*m_buffer, sel);
diff --git a/src/editor.hh b/src/editor.hh
index d8785a87..95ddd2b1 100644
--- a/src/editor.hh
+++ b/src/editor.hh
@@ -91,6 +91,9 @@ private:
void begin_edition();
void end_edition();
+ virtual BufferCoord offset_coord(const BufferCoord& coord, LineCount move);
+ virtual BufferCoord offset_coord(const BufferCoord& coord, CharCount move);
+
int m_edition_level;
void check_invariant() const;
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();
diff --git a/src/window.hh b/src/window.hh
index 25890e81..08ee23f0 100644
--- a/src/window.hh
+++ b/src/window.hh
@@ -56,6 +56,8 @@ private:
void scroll_to_keep_cursor_visible_ifn();
+ BufferCoord offset_coord(const BufferCoord& coord, LineCount move) override;
+
DisplayCoord m_position;
DisplayCoord m_dimensions;
DisplayBuffer m_display_buffer;