Add simple markup support to generate display lines from strings
The syntax is simply {face} to enable the given face, use \{ to escape a {, and \\ to escape a \.
This commit is contained in:
parent
db8c12fd2a
commit
6bc5f8c3a3
|
@ -891,6 +891,7 @@ const CommandDesc echo_cmd = {
|
||||||
"echo <params>...: display given parameters in the status line",
|
"echo <params>...: display given parameters in the status line",
|
||||||
ParameterDesc{
|
ParameterDesc{
|
||||||
{ { "color", { true, "set message color" } },
|
{ { "color", { true, "set message color" } },
|
||||||
|
{ "markup", { false, "parse markup" } },
|
||||||
{ "debug", { false, "write to debug buffer instead of status line" } } },
|
{ "debug", { false, "write to debug buffer instead of status line" } } },
|
||||||
ParameterDesc::Flags::SwitchesOnlyAtStart
|
ParameterDesc::Flags::SwitchesOnlyAtStart
|
||||||
},
|
},
|
||||||
|
@ -902,6 +903,8 @@ const CommandDesc echo_cmd = {
|
||||||
String message = join(parser, ' ', false);
|
String message = join(parser, ' ', false);
|
||||||
if (parser.get_switch("debug"))
|
if (parser.get_switch("debug"))
|
||||||
write_to_debug_buffer(message);
|
write_to_debug_buffer(message);
|
||||||
|
else if (parser.get_switch("markup"))
|
||||||
|
context.print_status(parse_display_line(message, get_face("StatusLine")));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto face = get_face(parser.get_switch("color").value_or("StatusLine").str());
|
auto face = get_face(parser.get_switch("color").value_or("StatusLine").str());
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "buffer.hh"
|
#include "buffer.hh"
|
||||||
#include "utf8.hh"
|
#include "utf8.hh"
|
||||||
|
|
||||||
|
#include "face_registry.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -250,4 +252,55 @@ void DisplayBuffer::optimize()
|
||||||
for (auto& line : m_lines)
|
for (auto& line : m_lines)
|
||||||
line.optimize();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,8 @@ private:
|
||||||
AtomList m_atoms;
|
AtomList m_atoms;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DisplayLine parse_display_line(StringView line, Face default_face);
|
||||||
|
|
||||||
class DisplayBuffer : public UseMemoryDomain<MemoryDomain::Display>
|
class DisplayBuffer : public UseMemoryDomain<MemoryDomain::Display>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -118,6 +118,8 @@ public:
|
||||||
[[gnu::always_inline]]
|
[[gnu::always_inline]]
|
||||||
void append(const char* data, ByteCount count) { m_data.append(data, (size_t)(int)count); }
|
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 push_back(char c) { m_data.push_back(c); }
|
||||||
void resize(ByteCount size) { m_data.resize((size_t)(int)size); }
|
void resize(ByteCount size) { m_data.resize((size_t)(int)size); }
|
||||||
void reserve(ByteCount size) { m_data.reserve((size_t)(int)size); }
|
void reserve(ByteCount size) { m_data.reserve((size_t)(int)size); }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user