Restore diff based terminal output optimization when synchronized
terminal_synchronized ui_option now also controls this behaviour, update out of date documentation for ui_options as well. As discussed in #4317
This commit is contained in:
parent
1456431951
commit
3acf85f267
|
@ -349,10 +349,6 @@ are exclusively available to built-in options.
|
|||
*terminal_enable_mouse*:::
|
||||
boolean option that enables mouse support
|
||||
|
||||
*terminal_change_colors*:::
|
||||
boolean option that can disable color palette changing if the
|
||||
terminfo enables it but the terminal does not support it.
|
||||
|
||||
*terminal_shift_function_key*:::
|
||||
Function key from which shifted function key start, if the
|
||||
terminal sends F13 for <s-F1>, this should be set to 12.
|
||||
|
@ -367,8 +363,9 @@ are exclusively available to built-in options.
|
|||
padding line (defaults to *false*)
|
||||
|
||||
*terminal_synchronized*:::
|
||||
if *yes* or *true*, emit iterm2 synchronized output escape sequences
|
||||
during redraw to reduce flickering (defaults to *false*)
|
||||
if *yes* or *true*, emit synchronized output escape sequences and
|
||||
reduce terminal output with sequences that could trigger flickering
|
||||
if unsynchronized (defaults to *false*)
|
||||
|
||||
[[startup-info]]
|
||||
*startup_info_version* `int`::
|
||||
|
|
|
@ -545,9 +545,11 @@ void register_options()
|
|||
" terminal_status_on_top bool\n"
|
||||
" terminal_set_title bool\n"
|
||||
" terminal_enable_mouse bool\n"
|
||||
" terminal_change_colors bool\n"
|
||||
" terminal_synchronized bool\n"
|
||||
" terminal_wheel_scroll_amount int\n"
|
||||
" terminal_shift_function_key int\n",
|
||||
" terminal_shift_function_key int\n"
|
||||
" terminal_padding_char codepoint\n"
|
||||
" terminal_padding_fill bool\n",
|
||||
UserInterface::Options{});
|
||||
reg.declare_option("modelinefmt", "format string used to generate the modeline",
|
||||
"%val{bufname} %val{cursor_line}:%val{cursor_char_column} {{context_info}} {{mode_info}} - %val{client}@[%val{session}]"_str);
|
||||
|
|
|
@ -284,10 +284,6 @@ void TerminalUI::Screen::output(bool force, bool synchronized, Writer& writer)
|
|||
if (not lines)
|
||||
return;
|
||||
|
||||
// iTerm2 "begin synchronized update" sequence
|
||||
if (synchronized)
|
||||
writer.write("\033[?2026h");
|
||||
|
||||
if (force)
|
||||
{
|
||||
std::fill_n(hashes.get(), (size_t)size.line, 0);
|
||||
|
@ -299,17 +295,9 @@ void TerminalUI::Screen::output(bool force, bool synchronized, Writer& writer)
|
|||
return (hash_value(line.atoms) << 1) | 1; // ensure non-zero
|
||||
};
|
||||
|
||||
for (int line = 0; line < (int)size.line; ++line)
|
||||
{
|
||||
auto hash = hash_line(lines[line]);
|
||||
if (hash == hashes[line])
|
||||
continue;
|
||||
hashes[line] = hash;
|
||||
|
||||
format_with(writer, "\033[{}H", line + 1);
|
||||
|
||||
auto output_line = [&](const Line& line) {
|
||||
ColumnCount pending_move = 0;
|
||||
for (auto& [text, skip, face] : lines[line].atoms)
|
||||
for (auto& [text, skip, face] : line.atoms)
|
||||
{
|
||||
if (text.empty() and skip == 0)
|
||||
continue;
|
||||
|
@ -329,11 +317,75 @@ void TerminalUI::Screen::output(bool force, bool synchronized, Writer& writer)
|
|||
else if (skip > 0)
|
||||
writer.write(String{' ', skip});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// iTerm2 "end synchronized update" sequence
|
||||
if (synchronized)
|
||||
writer.write("\033[?2026l");
|
||||
{
|
||||
writer.write("\033[?2026h"); // begin synchronized update
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
line = 0;
|
||||
for (auto& change : changes)
|
||||
{
|
||||
line += change.keep;
|
||||
for (int i = 0; i < change.add; ++i)
|
||||
{
|
||||
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);
|
||||
|
||||
output_line(lines[line++]);
|
||||
}
|
||||
}
|
||||
|
||||
writer.write("\033[?2026l"); // end synchronized update
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int line = 0; line < (int)size.line; ++line)
|
||||
{
|
||||
auto hash = hash_line(lines[line]);
|
||||
if (hash == hashes[line])
|
||||
continue;
|
||||
hashes[line] = hash;
|
||||
|
||||
format_with(writer, "\033[{}H", line + 1);
|
||||
output_line(lines[line]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int TerminalUI::default_shift_function_key;
|
||||
|
|
Loading…
Reference in New Issue
Block a user