summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/commands.cc3
-rw-r--r--src/display_buffer.cc53
-rw-r--r--src/display_buffer.hh2
-rw-r--r--src/string.hh2
4 files changed, 60 insertions, 0 deletions
diff --git a/src/commands.cc b/src/commands.cc
index b93114a8..0c35cb26 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -891,6 +891,7 @@ const CommandDesc echo_cmd = {
"echo <params>...: display given parameters in the status line",
ParameterDesc{
{ { "color", { true, "set message color" } },
+ { "markup", { false, "parse markup" } },
{ "debug", { false, "write to debug buffer instead of status line" } } },
ParameterDesc::Flags::SwitchesOnlyAtStart
},
@@ -902,6 +903,8 @@ const CommandDesc echo_cmd = {
String message = join(parser, ' ', false);
if (parser.get_switch("debug"))
write_to_debug_buffer(message);
+ else if (parser.get_switch("markup"))
+ context.print_status(parse_display_line(message, get_face("StatusLine")));
else
{
auto face = get_face(parser.get_switch("color").value_or("StatusLine").str());
diff --git a/src/display_buffer.cc b/src/display_buffer.cc
index 8cda0c47..0a1b3503 100644
--- a/src/display_buffer.cc
+++ b/src/display_buffer.cc
@@ -4,6 +4,8 @@
#include "buffer.hh"
#include "utf8.hh"
+#include "face_registry.hh"
+
namespace Kakoune
{
@@ -250,4 +252,55 @@ void DisplayBuffer::optimize()
for (auto& line : m_lines)
line.optimize();
}
+
+DisplayLine parse_display_line(StringView line, Face default_face)
+{
+ DisplayLine res;
+ bool was_antislash = false;
+ auto pos = line.begin();
+ String content;
+ Face face = default_face;
+ for (auto it = line.begin(), end = line.end(); it != end; ++it)
+ {
+ const char c = *it;
+ if (c == '{')
+ {
+ if (was_antislash)
+ {
+ content += StringView{pos, it};
+ content.back() = '{';
+ pos = it + 1;
+ }
+ else
+ {
+ content += StringView{pos, it};
+ res.push_back({std::move(content), face});
+ content.clear();
+ auto closing = std::find(it+1, end, '}');
+ if (closing == end)
+ throw runtime_error("unclosed face definition");
+ face = merge_faces(default_face, get_face({it+1, closing}));
+ it = closing;
+ pos = closing + 1;
+ }
+ was_antislash = false;
+ }
+ if (c == '\\')
+ {
+ if (was_antislash)
+ {
+ content += StringView{pos, it};
+ pos = it + 1;
+ was_antislash = false;
+ }
+ else
+ was_antislash = true;
+ }
+ }
+ content += StringView{pos, line.end()};
+ if (not content.empty())
+ res.push_back({std::move(content), face});
+ return res;
+}
+
}
diff --git a/src/display_buffer.hh b/src/display_buffer.hh
index 97b717b1..9670325a 100644
--- a/src/display_buffer.hh
+++ b/src/display_buffer.hh
@@ -140,6 +140,8 @@ private:
AtomList m_atoms;
};
+DisplayLine parse_display_line(StringView line, Face default_face);
+
class DisplayBuffer : public UseMemoryDomain<MemoryDomain::Display>
{
public:
diff --git a/src/string.hh b/src/string.hh
index 6970e74a..d15baa34 100644
--- a/src/string.hh
+++ b/src/string.hh
@@ -118,6 +118,8 @@ public:
[[gnu::always_inline]]
void append(const char* data, ByteCount count) { m_data.append(data, (size_t)(int)count); }
+ void clear() { m_data.clear(); }
+
void push_back(char c) { m_data.push_back(c); }
void resize(ByteCount size) { m_data.resize((size_t)(int)size); }
void reserve(ByteCount size) { m_data.reserve((size_t)(int)size); }