summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2021-09-09 08:59:26 +1000
committerMaxime Coste <mawww@kakoune.org>2021-09-09 09:01:42 +1000
commitb3a1017a264cfea7e9ae1a374208e9b02efbda5a (patch)
tree3136c155c3b54d60a345dd4dd67c946a90b3e108 /src
parent3d8061b975e39a9bd9963777174be4bd823eebfa (diff)
Remove scrolling detection/optimization in terminal output
Just validate if line changed or not. This should avoid flickering on terminals such as the linux console that eagerly redraw on line deletions. Unfortunately this means drawing will use more data and might add a bit of latency on slow links. Fixes #4317 Fixes #4320
Diffstat (limited to 'src')
-rw-r--r--src/terminal_ui.cc86
1 files changed, 25 insertions, 61 deletions
diff --git a/src/terminal_ui.cc b/src/terminal_ui.cc
index 67b21e7f..e9519cce 100644
--- a/src/terminal_ui.cc
+++ b/src/terminal_ui.cc
@@ -286,7 +286,7 @@ void TerminalUI::Screen::output(bool force, bool synchronized, Writer& writer)
// iTerm2 "begin synchronized update" sequence
if (synchronized)
- writer.write("\033P=1s\033\\");
+ writer.write("\033[?2026h");
if (force)
{
@@ -299,77 +299,41 @@ void TerminalUI::Screen::output(bool force, bool synchronized, Writer& writer)
return (hash_value(line.atoms) << 1) | 1; // ensure non-zero
};
- struct Change { int keep; int add; int del; };
- Vector<Change> changes{Change{}};
- auto new_hashes = ArrayView{lines.get(), (size_t)size.line} | transform(hash_line);
- for_each_diff(hashes.get(), (int)size.line,
- new_hashes.begin(), (int)size.line,
- [&changes](DiffOp op, int len) mutable {
- switch (op)
- {
- case DiffOp::Keep:
- changes.push_back({len, 0, 0});
- break;
- case DiffOp::Add:
- changes.back().add += len;
- break;
- case DiffOp::Remove:
- changes.back().del += len;
- break;
- }
- });
- std::copy(new_hashes.begin(), new_hashes.end(), hashes.get());
-
- int line = 0;
- for (auto& change : changes)
+ for (int line = 0; line < (int)size.line; ++line)
{
- line += change.keep;
- if (int del = change.del - change.add; del > 0)
- {
- format_with(writer, "\033[{}H\033[{}M", line + 1, del);
- line -= del;
- }
- line += change.del;
- }
+ auto hash = hash_line(lines[line]);
+ if (hash == hashes[line])
+ continue;
+ hashes[line] = hash;
- line = 0;
- for (auto& change : changes)
- {
- line += change.keep;
- for (int i = 0; i < change.add; ++i)
+ format_with(writer, "\033[{}H", line + 1);
+
+ ColumnCount pending_move = 0;
+ for (auto& [text, skip, face] : lines[line].atoms)
{
- if (int add = change.add - change.del; i == 0 and add > 0)
- format_with(writer, "\033[{}H\033[{}L", line + 1, add);
- else
- format_with(writer, "\033[{}H", line + 1);
+ if (text.empty() and skip == 0)
+ continue;
- ColumnCount pending_move = 0;
- for (auto& [text, skip, face] : lines[line++].atoms)
+ if (pending_move != 0)
+ {
+ format_with(writer, "\033[{}C", (int)pending_move);
+ pending_move = 0;
+ }
+ set_face(face, writer);
+ writer.write(text);
+ if (skip > 3 and face.attributes == Attribute{})
{
- if (text.empty() and skip == 0)
- continue;
-
- if (pending_move != 0)
- {
- format_with(writer, "\033[{}C", (int)pending_move);
- pending_move = 0;
- }
- set_face(face, writer);
- writer.write(text);
- if (skip > 3 and face.attributes == Attribute{})
- {
- writer.write("\033[K");
- pending_move = skip;
- }
- else if (skip > 0)
- writer.write(String{' ', skip});
+ writer.write("\033[K");
+ pending_move = skip;
}
+ else if (skip > 0)
+ writer.write(String{' ', skip});
}
}
// iTerm2 "end synchronized update" sequence
if (synchronized)
- writer.write("\033P=2s\033\\");
+ writer.write("\033[?2026l");
}
constexpr int TerminalUI::default_shift_function_key;