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*:::
|
*terminal_enable_mouse*:::
|
||||||
boolean option that enables mouse support
|
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*:::
|
*terminal_shift_function_key*:::
|
||||||
Function key from which shifted function key start, if the
|
Function key from which shifted function key start, if the
|
||||||
terminal sends F13 for <s-F1>, this should be set to 12.
|
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*)
|
padding line (defaults to *false*)
|
||||||
|
|
||||||
*terminal_synchronized*:::
|
*terminal_synchronized*:::
|
||||||
if *yes* or *true*, emit iterm2 synchronized output escape sequences
|
if *yes* or *true*, emit synchronized output escape sequences and
|
||||||
during redraw to reduce flickering (defaults to *false*)
|
reduce terminal output with sequences that could trigger flickering
|
||||||
|
if unsynchronized (defaults to *false*)
|
||||||
|
|
||||||
[[startup-info]]
|
[[startup-info]]
|
||||||
*startup_info_version* `int`::
|
*startup_info_version* `int`::
|
||||||
|
|
|
@ -545,9 +545,11 @@ void register_options()
|
||||||
" terminal_status_on_top bool\n"
|
" terminal_status_on_top bool\n"
|
||||||
" terminal_set_title bool\n"
|
" terminal_set_title bool\n"
|
||||||
" terminal_enable_mouse bool\n"
|
" terminal_enable_mouse bool\n"
|
||||||
" terminal_change_colors bool\n"
|
" terminal_synchronized bool\n"
|
||||||
" terminal_wheel_scroll_amount int\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{});
|
UserInterface::Options{});
|
||||||
reg.declare_option("modelinefmt", "format string used to generate the modeline",
|
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);
|
"%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)
|
if (not lines)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// iTerm2 "begin synchronized update" sequence
|
|
||||||
if (synchronized)
|
|
||||||
writer.write("\033[?2026h");
|
|
||||||
|
|
||||||
if (force)
|
if (force)
|
||||||
{
|
{
|
||||||
std::fill_n(hashes.get(), (size_t)size.line, 0);
|
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
|
return (hash_value(line.atoms) << 1) | 1; // ensure non-zero
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int line = 0; line < (int)size.line; ++line)
|
auto output_line = [&](const Line& line) {
|
||||||
{
|
|
||||||
auto hash = hash_line(lines[line]);
|
|
||||||
if (hash == hashes[line])
|
|
||||||
continue;
|
|
||||||
hashes[line] = hash;
|
|
||||||
|
|
||||||
format_with(writer, "\033[{}H", line + 1);
|
|
||||||
|
|
||||||
ColumnCount pending_move = 0;
|
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)
|
if (text.empty() and skip == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -329,11 +317,75 @@ void TerminalUI::Screen::output(bool force, bool synchronized, Writer& writer)
|
||||||
else if (skip > 0)
|
else if (skip > 0)
|
||||||
writer.write(String{' ', skip});
|
writer.write(String{' ', skip});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// iTerm2 "end synchronized update" sequence
|
|
||||||
if (synchronized)
|
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;
|
constexpr int TerminalUI::default_shift_function_key;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user