summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2020-03-29 13:35:42 +1100
committerMaxime Coste <mawww@kakoune.org>2021-07-12 10:25:58 +1000
commitb0dcb07540a54b3ea132d43e4ae796878fad8ed8 (patch)
tree24c2736c63e801ad765ebc17b1b0b2924779767a /src
parent63310370f80121c804766a528a3ca450b21d59d7 (diff)
Reduce amount of SGR escapes emitted by tracking the active face
Diffstat (limited to 'src')
-rw-r--r--src/terminal_ui.cc50
-rw-r--r--src/terminal_ui.hh3
2 files changed, 38 insertions, 15 deletions
diff --git a/src/terminal_ui.cc b/src/terminal_ui.cc
index c08d1f70..cfea7b9d 100644
--- a/src/terminal_ui.cc
+++ b/src/terminal_ui.cc
@@ -179,28 +179,52 @@ void TerminalUI::Window::draw(DisplayCoord pos,
lines[(int)pos.line].append({}, size.column - pos.column, default_face);
}
-void TerminalUI::Screen::output(bool force)
+void TerminalUI::Screen::set_face(const Face& face)
{
- if (lines.empty())
- return;
-
static constexpr int fg_table[]{ 39, 30, 31, 32, 33, 34, 35, 36, 37, 90, 91, 92, 93, 94, 95, 96, 97 };
static constexpr int bg_table[]{ 49, 40, 41, 42, 43, 44, 45, 46, 47, 100, 101, 102, 103, 104, 105, 106, 107 };
static constexpr int attr_table[]{ 0, 4, 7, 5, 1, 2, 3 };
- auto set_color = [](bool fg, const Color& color) {
+
+ auto set_color = [](bool fg, const Color& color, bool join) {
+ if (join)
+ fputs(";", stdout);
if (color.isRGB())
- printf(";%d;2;%d;%d;%d", fg ? 38 : 48, color.r, color.g, color.b);
+ printf("%d;2;%d;%d;%d", fg ? 38 : 48, color.r, color.g, color.b);
else
- printf(";%d", (fg ? fg_table : bg_table)[(int)(char)color.color]);
+ printf("%d", (fg ? fg_table : bg_table)[(int)(char)color.color]);
};
- auto set_attributes = [](const Attribute& attributes) {
+ if (m_active_face == face)
+ return;
+
+ fputs("\033[", stdout);
+ bool join = false;
+ if (face.attributes != m_active_face.attributes)
+ {
for (int i = 0; i < sizeof(attr_table) / sizeof(int); ++i)
{
- if (attributes & (Attribute)(1 << i))
+ if (face.attributes & (Attribute)(1 << i))
printf(";%d", attr_table[i]);
}
- };
+ m_active_face = Face{{}, {}, face.attributes};
+ join = true;
+ }
+ if (m_active_face.fg != face.fg)
+ {
+ set_color(true, face.fg, join);
+ join = true;
+ }
+ if (m_active_face.bg != face.bg)
+ set_color(false, face.bg, join);
+ fputs("m", stdout);
+
+ m_active_face = face;
+}
+
+void TerminalUI::Screen::output(bool force)
+{
+ if (lines.empty())
+ return;
struct Change { int keep; int add; int del; };
Vector<Change> changes{Change{}};
@@ -254,11 +278,7 @@ void TerminalUI::Screen::output(bool force)
printf("\033[%dC", (int)pending_move);
pending_move = 0;
}
- fputs("\033[", stdout);
- set_attributes(atom.face.attributes);
- set_color(true, atom.face.fg);
- set_color(false, atom.face.bg);
- fputs("m", stdout);
+ set_face(atom.face);
fputs(atom.text.c_str(), stdout);
if (atom.skip > 0)
{
diff --git a/src/terminal_ui.hh b/src/terminal_ui.hh
index 85a5081f..fbdba862 100644
--- a/src/terminal_ui.hh
+++ b/src/terminal_ui.hh
@@ -89,7 +89,10 @@ private:
struct Screen : Window
{
void output(bool force);
+ void set_face(const Face& face);
+
Vector<size_t> hashes;
+ Face m_active_face;
};
Window m_window;