diff options
| author | Maxime Coste <mawww@kakoune.org> | 2020-02-18 22:54:46 +1100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2021-07-12 10:25:58 +1000 |
| commit | 5466f63eebad4e7957b611919ca3d74dc6bad187 (patch) | |
| tree | 1a3071d9fb6fda20db4aaa97d2778e915a11c509 /src | |
| parent | 9e8f555a828286768c07df6753b64e08e7af952e (diff) | |
Use insert/remove lines escapes to reduce terminal traffic
Diff against known state and insert/erase relevant lines.
Erase everything first to avoid insertion invalidating lines that
get out of the terminal at bottom.
Diffstat (limited to 'src')
| -rw-r--r-- | src/terminal_ui.cc | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/src/terminal_ui.cc b/src/terminal_ui.cc index 45a89cda..de6d1576 100644 --- a/src/terminal_ui.cc +++ b/src/terminal_ui.cc @@ -7,6 +7,7 @@ #include "keys.hh" #include "ranges.hh" #include "string_utils.hh" +#include "diff.hh" #include <algorithm> @@ -187,29 +188,46 @@ void TerminalUI::Screen::output(bool force) } }; - DisplayCoord cursor_pos = pos; - for (auto& line : lines) + struct Add { int pos; int len; }; + Vector<Add> adds; + auto new_hashes = lines | transform([](auto& line) { return hash_value(line.atoms); }) | gather<Vector>(); + for_each_diff(hashes.begin(), hashes.size(), + new_hashes.begin(), new_hashes.size(), + [&, line=0, posB=0](DiffOp op, int len) mutable { + switch (op) + { + case DiffOp::Keep: + line += len; + posB += len; + break; + case DiffOp::Add: + adds.push_back({posB, len}); + posB += len; + break; + case DiffOp::Remove: + printf("\033[%dH\033[%dM", line+1, len); + break; + } + }); + hashes = std::move(new_hashes); + + for (auto& add : adds) { - auto line_hash = hash_value(line.atoms); - if (force or cursor_pos.line >= hashes.size() or - line_hash != hashes[(size_t)cursor_pos.line]) + printf("\033[%dH\033[%dL", add.pos + 1, add.len); + for (int i = 0; i < add.len; ++i) { - set_cursor_pos(cursor_pos); - for (auto& atom : line.atoms) + if (i != 0) + printf("\033[%dH", add.pos + i + 1); + for (auto& atom : lines[add.pos + i].atoms) { - printf("\033["); + fputs("\033[", stdout); set_attributes(atom.face.attributes); set_color(true, atom.face.fg); set_color(false, atom.face.bg); - printf("m"); + fputs("m", stdout); fputs(atom.text.c_str(), stdout); } } - if (hashes.size() <= cursor_pos.line) - hashes.push_back(line_hash); - else - hashes[(size_t)cursor_pos.line] = line_hash; - ++cursor_pos.line; } } |
