summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2019-11-22 21:48:26 +1100
committerMaxime Coste <mawww@kakoune.org>2019-11-22 21:50:51 +1100
commitcb1b03c0db91d85db3545a49f68d63fad0fe137c (patch)
treebf8ba71c18a74d8bc1ebb38df246a3b0d87ad256
parent22d9ffa63ac22d3823c41b4671e0565a92cf8619 (diff)
Add support for markup in info boxes
Fixes #2552
-rw-r--r--doc/json_ui.asciidoc2
-rw-r--r--doc/pages/changelog.asciidoc2
-rw-r--r--doc/pages/commands.asciidoc4
-rw-r--r--src/client.cc11
-rw-r--r--src/client.hh7
-rw-r--r--src/commands.cc12
-rw-r--r--src/display_buffer.hh8
-rw-r--r--src/highlighters.cc2
-rw-r--r--src/json_ui.cc2
-rw-r--r--src/json_ui.hh2
-rw-r--r--src/main.cc2
-rw-r--r--src/ncurses_ui.cc78
-rw-r--r--src/ncurses_ui.hh7
-rw-r--r--src/remote.cc8
-rw-r--r--src/user_interface.hh4
-rw-r--r--src/utils.hh12
-rw-r--r--src/window.cc2
17 files changed, 110 insertions, 55 deletions
diff --git a/doc/json_ui.asciidoc b/doc/json_ui.asciidoc
index 67ca3c27..e8dcad09 100644
--- a/doc/json_ui.asciidoc
+++ b/doc/json_ui.asciidoc
@@ -35,7 +35,7 @@ Here are the requests that can be written by the json ui on stdout:
- inline: display the menu next to (above or below) the anchor coordinate
* menu_select(int selected)
* menu_hide()
-* info_show(String title, String content, Coord anchor, Face face, String style)
+* info_show(Line title, Array<Line> content, Coord anchor, Face face, String style)
style can be:
- prompt: display the info as a prompt info (anchor is ignored)
- inline: display the info next to (above or below) the anchor coordinate
diff --git a/doc/pages/changelog.asciidoc b/doc/pages/changelog.asciidoc
index 3312bc97..25494519 100644
--- a/doc/pages/changelog.asciidoc
+++ b/doc/pages/changelog.asciidoc
@@ -17,6 +17,8 @@ released versions.
* `WrapMarker` face used by `wrap -marker` highlighter
+* `info` supports markup with the `-markup` switch
+
== Kakoune 2019.07.01
* Re-organized bundled script files directory hierarchy.
diff --git a/doc/pages/commands.asciidoc b/doc/pages/commands.asciidoc
index f9e239e4..f81c3268 100644
--- a/doc/pages/commands.asciidoc
+++ b/doc/pages/commands.asciidoc
@@ -323,6 +323,10 @@ but not really useful in that context.
*-title* <text>:::
set the title of the message box
+
+ *-markup*:::
+ parse markup in both title (if provided) and text. (See
+ <<faces#markup-strings,`:doc faces markup-strings`>>)
*try* <commands> [catch <on_error_commands>]...::
prevent an error in *commands* from aborting the whole command
diff --git a/src/client.cc b/src/client.cc
index f4a85ccb..c4312aca 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -411,7 +411,7 @@ void Client::menu_hide()
m_ui_pending &= ~(MenuShow | MenuSelect);
}
-void Client::info_show(String title, String content, BufferCoord anchor, InfoStyle style)
+void Client::info_show(DisplayLine title, DisplayLineList content, BufferCoord anchor, InfoStyle style)
{
if (m_info.style == InfoStyle::Modal) // We already have a modal info opened, do not touch it.
return;
@@ -421,6 +421,15 @@ void Client::info_show(String title, String content, BufferCoord anchor, InfoSty
m_ui_pending &= ~InfoHide;
}
+void Client::info_show(StringView title, StringView content, BufferCoord anchor, InfoStyle style)
+{
+ info_show({title.str(), Face{}},
+ content | split<StringView>('\n')
+ | transform([](StringView s) { return DisplayLine{s.str(), Face{}}; })
+ | gather<DisplayLineList>(),
+ anchor, style);
+}
+
void Client::info_hide(bool even_modal)
{
if (not even_modal and m_info.style == InfoStyle::Modal)
diff --git a/src/client.hh b/src/client.hh
index e9da7588..3fa27627 100644
--- a/src/client.hh
+++ b/src/client.hh
@@ -45,7 +45,8 @@ public:
void menu_select(int selected);
void menu_hide();
- void info_show(String title, String content, BufferCoord anchor, InfoStyle style);
+ void info_show(DisplayLine title, DisplayLineList content, BufferCoord anchor, InfoStyle style);
+ void info_show(StringView title, StringView content, BufferCoord anchor, InfoStyle style);
void info_hide(bool even_modal = false);
void print_status(DisplayLine status_line);
@@ -119,8 +120,8 @@ private:
struct Info
{
- String title;
- String content;
+ DisplayLine title;
+ DisplayLineList content;
BufferCoord anchor;
Optional<DisplayCoord> ui_anchor;
InfoStyle style;
diff --git a/src/commands.cc b/src/commands.cc
index dd105c69..728b4403 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -2144,6 +2144,7 @@ const CommandDesc info_cmd = {
ParameterDesc{
{ { "anchor", { true, "set info anchoring <line>.<column>" } },
{ "style", { true, "set info style (above, below, menu, modal)" } },
+ { "markup", { false, "parse markup" } },
{ "title", { true, "set info title" } } },
ParameterDesc::Flags::None, 0, 1
},
@@ -2179,7 +2180,16 @@ const CommandDesc info_cmd = {
}).value_or(BufferCoord{});
auto title = parser.get_switch("title").value_or(StringView{});
- context.client().info_show(title.str(), parser[0], pos, style);
+ if (parser.get_switch("markup"))
+ context.client().info_show(parse_display_line(title, context.faces()),
+ parser[0] | split<StringView>('\n')
+ | transform([&](StringView s) {
+ return parse_display_line(s, context.faces());
+ })
+ | gather<DisplayLineList>(),
+ pos, style);
+ else
+ context.client().info_show(title.str(), parser[0], pos, style);
}
};
diff --git a/src/display_buffer.hh b/src/display_buffer.hh
index 1c8fc53d..01310b26 100644
--- a/src/display_buffer.hh
+++ b/src/display_buffer.hh
@@ -135,6 +135,7 @@ private:
AtomList m_atoms;
};
+using DisplayLineList = Vector<DisplayLine>;
class FaceRegistry;
String fix_atom_text(StringView str);
@@ -143,11 +144,10 @@ DisplayLine parse_display_line(StringView line, const FaceRegistry& faces, const
class DisplayBuffer : public UseMemoryDomain<MemoryDomain::Display>
{
public:
- using LineList = Vector<DisplayLine>;
DisplayBuffer() {}
- LineList& lines() { return m_lines; }
- const LineList& lines() const { return m_lines; }
+ DisplayLineList& lines() { return m_lines; }
+ const DisplayLineList& lines() const { return m_lines; }
// returns the smallest BufferRange which contains every DisplayAtoms
const BufferRange& range() const { return m_range; }
@@ -160,7 +160,7 @@ public:
size_t timestamp() const { return m_timestamp; }
private:
- LineList m_lines;
+ DisplayLineList m_lines;
BufferRange m_range;
size_t m_timestamp = -1;
};
diff --git a/src/highlighters.cc b/src/highlighters.cc
index 000befef..a8f4c433 100644
--- a/src/highlighters.cc
+++ b/src/highlighters.cc
@@ -133,7 +133,7 @@ void apply_highlighter(HighlightContext context,
if (begin == end)
return;
- using LineIterator = DisplayBuffer::LineList::iterator;
+ using LineIterator = DisplayLineList::iterator;
LineIterator first_line;
Vector<size_t> insert_idx;
auto line_end = display_buffer.lines().end();
diff --git a/src/json_ui.cc b/src/json_ui.cc
index 51fde617..1182c221 100644
--- a/src/json_ui.cc
+++ b/src/json_ui.cc
@@ -217,7 +217,7 @@ void JsonUI::menu_hide()
rpc_call("menu_hide");
}
-void JsonUI::info_show(StringView title, StringView content,
+void JsonUI::info_show(const DisplayLine& title, const DisplayLineList& content,
DisplayCoord anchor, Face face,
InfoStyle style)
{
diff --git a/src/json_ui.hh b/src/json_ui.hh
index 5e53ab42..7b1abf44 100644
--- a/src/json_ui.hh
+++ b/src/json_ui.hh
@@ -35,7 +35,7 @@ public:
void menu_select(int selected) override;
void menu_hide() override;
- void info_show(StringView title, StringView content,
+ void info_show(const DisplayLine& title, const DisplayLineList& content,
DisplayCoord anchor, Face face,
InfoStyle style) override;
void info_hide() override;
diff --git a/src/main.cc b/src/main.cc
index a6283b46..8400fb1c 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -517,7 +517,7 @@ std::unique_ptr<UserInterface> make_ui(UIType ui_type)
void menu_select(int) override {}
void menu_hide() override {}
- void info_show(StringView, StringView, DisplayCoord, Face, InfoStyle) override {}
+ void info_show(const DisplayLine&, const DisplayLineList&, DisplayCoord, Face, InfoStyle) override {}
void info_hide() override {}
void draw(const DisplayBuffer&, const Face&, const Face&) override {}
diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc
index cd036b34..4e75d958 100644
--- a/src/ncurses_ui.cc
+++ b/src/ncurses_ui.cc
@@ -1032,11 +1032,26 @@ static DisplayCoord compute_pos(DisplayCoord anchor, DisplayCoord size,
struct InfoBox
{
DisplayCoord size;
- Vector<String> contents;
+ DisplayLineList contents;
};
-InfoBox make_info_box(StringView title, StringView message, ColumnCount max_width,
- ConstArrayView<StringView> assistant)
+template<typename... Args>
+void append_atoms(DisplayLine& line, Args&&... args)
+{
+ auto append = overload(
+ [](DisplayLine& line, String str) {
+ line.push_back(DisplayAtom{std::move(str)});
+ },
+ [](DisplayLine& line, const DisplayLine& atoms) {
+ for (auto& atom : atoms)
+ line.push_back(atom);
+ });
+
+ (append(line, args), ...);
+}
+
+InfoBox make_info_box(const DisplayLine& title, const DisplayLineList& content,
+ ColumnCount max_width, ConstArrayView<StringView> assistant)
{
DisplayCoord assistant_size;
if (not assistant.empty())
@@ -1048,71 +1063,70 @@ InfoBox make_info_box(StringView title, StringView message, ColumnCount max_widt
if (max_bubble_width < 4)
return result;
- Vector<StringView> lines = wrap_lines(message, max_bubble_width);
+ ColumnCount bubble_width = title.length() + 2;
+ for (auto& line : content)
+ bubble_width = max(bubble_width, line.length());
- ColumnCount bubble_width = title.column_length() + 2;
- for (auto& line : lines)
- bubble_width = max(bubble_width, line.column_length());
-
- auto line_count = max(assistant_size.line-1, LineCount{(int)lines.size()} + 2);
+ auto line_count = max(assistant_size.line-1, LineCount{(int)content.size()} + 2);
result.size = DisplayCoord{line_count, bubble_width + assistant_size.column + 4};
const auto assistant_top_margin = (line_count - assistant_size.line+1) / 2;
for (LineCount i = 0; i < line_count; ++i)
{
- String line;
constexpr Codepoint dash{L'─'};
+ DisplayLine line;
if (not assistant.empty())
{
- if (i >= assistant_top_margin)
- line += assistant[(int)min(i - assistant_top_margin, assistant_size.line-1)];
- else
- line += assistant[(int)assistant_size.line-1];
+ StringView assistant_line = (i >= assistant_top_margin) ?
+ assistant[(int)min(i - assistant_top_margin, assistant_size.line-1)]
+ : assistant[(int)assistant_size.line-1];
+
+ append_atoms(line, assistant_line.str());
}
if (i == 0)
{
- if (title.empty())
- line += "╭─" + String{dash, bubble_width} + "─╮";
+ if (title.atoms().empty())
+ append_atoms(line, "╭─" + String{dash, bubble_width} + "─╮");
else
{
- auto dash_count = bubble_width - title.column_length() - 2;
+ auto dash_count = bubble_width - title.length() - 2;
String left{dash, dash_count / 2};
String right{dash, dash_count - dash_count / 2};
- line += "╭─" + left + "┤" + title +"├" + right +"─╮";
+ append_atoms(line, "╭─" + left + "┤", title, "├" + right +"─╮");
}
}
- else if (i < lines.size() + 1)
+ else if (i < content.size() + 1)
{
- auto& info_line = lines[(int)i - 1];
- const ColumnCount padding = bubble_width - info_line.column_length();
- line += "│ " + info_line + String{' ', padding} + " │";
+ auto& info_line = content[(int)i - 1];
+ const ColumnCount padding = bubble_width - info_line.length();
+ append_atoms(line, "│ ", info_line, String{' ', padding} + " │");
}
- else if (i == lines.size() + 1)
- line += "╰─" + String(dash, bubble_width) + "─╯";
+ else if (i == content.size() + 1)
+ append_atoms(line, "╰─" + String(dash, bubble_width) + "─╯");
result.contents.push_back(std::move(line));
}
return result;
}
-InfoBox make_simple_info_box(StringView contents, ColumnCount max_width)
+InfoBox make_simple_info_box(const DisplayLineList& content, ColumnCount max_width)
{
InfoBox info_box{};
- for (auto& line : wrap_lines(contents, max_width))
+ for (auto& line : content)
{
++info_box.size.line;
- info_box.size.column = std::max(line.column_length(), info_box.size.column);
- info_box.contents.push_back(line.str());
+ info_box.size.column = std::max(line.length(), info_box.size.column);
+ info_box.contents.push_back(line);
}
return info_box;
}
-void NCursesUI::info_show(StringView title, StringView content,
+void NCursesUI::info_show(const DisplayLine& title, const DisplayLineList& content,
DisplayCoord anchor, Face face, InfoStyle style)
{
info_hide();
- m_info.title = title.str();
- m_info.content = content.str();
+ m_info.title = title;
+ m_info.content = content;
m_info.anchor = anchor;
m_info.face = face;
m_info.style = style;
@@ -1170,7 +1184,7 @@ void NCursesUI::info_show(StringView title, StringView content,
for (auto line = 0_line; line < info_box.size.line; ++line)
{
m_info.move_cursor(line);
- m_info.draw(m_palette, DisplayAtom(info_box.contents[(int)line]), face);
+ m_info.draw(m_palette, info_box.contents[(int)line].atoms(), face);
}
m_dirty = true;
}
diff --git a/src/ncurses_ui.hh b/src/ncurses_ui.hh
index d10470ec..7d51cdcb 100644
--- a/src/ncurses_ui.hh
+++ b/src/ncurses_ui.hh
@@ -3,6 +3,7 @@
#include "array_view.hh"
#include "coord.hh"
+#include "display_buffer.hh"
#include "event_manager.hh"
#include "face.hh"
#include "hash_map.hh"
@@ -44,7 +45,7 @@ public:
void menu_select(int selected) override;
void menu_hide() override;
- void info_show(StringView title, StringView content,
+ void info_show(const DisplayLine& title, const DisplayLineList& content,
DisplayCoord anchor, Face face,
InfoStyle style) override;
void info_hide() override;
@@ -135,8 +136,8 @@ private:
struct Info : Window
{
- String title;
- String content;
+ DisplayLine title;
+ DisplayLineList content;
Face face;
DisplayCoord anchor;
InfoStyle style;
diff --git a/src/remote.cc b/src/remote.cc
index 8d98533b..6b03edbd 100644
--- a/src/remote.cc
+++ b/src/remote.cc
@@ -356,7 +356,7 @@ public:
void menu_select(int selected) override;
void menu_hide() override;
- void info_show(StringView title, StringView content,
+ void info_show(const DisplayLine& title, const DisplayLineList& content,
DisplayCoord anchor, Face face,
InfoStyle style) override;
void info_hide() override;
@@ -483,7 +483,7 @@ void RemoteUI::menu_hide()
send_message(MessageType::MenuHide);
}
-void RemoteUI::info_show(StringView title, StringView content,
+void RemoteUI::info_show(const DisplayLine& title, const DisplayLineList& content,
DisplayCoord anchor, Face face,
InfoStyle style)
{
@@ -643,8 +643,8 @@ RemoteClient::RemoteClient(StringView session, StringView name, std::unique_ptr<
break;
case MessageType::InfoShow:
{
- auto title = reader.read<String>();
- auto content = reader.read<String>();
+ auto title = reader.read<DisplayLine>();
+ auto content = reader.read<DisplayLineList>();
auto anchor = reader.read<DisplayCoord>();
auto face = reader.read<Face>();
auto style = reader.read<InfoStyle>();
diff --git a/src/user_interface.hh b/src/user_interface.hh
index b216cbba..5bab3e89 100644
--- a/src/user_interface.hh
+++ b/src/user_interface.hh
@@ -12,6 +12,7 @@ namespace Kakoune
class String;
class DisplayBuffer;
class DisplayLine;
+using DisplayLineList = Vector<DisplayLine, MemoryDomain::Display>;
struct DisplayCoord;
struct Face;
struct Key;
@@ -56,7 +57,8 @@ public:
virtual void menu_select(int selected) = 0;
virtual void menu_hide() = 0;
- virtual void info_show(StringView title, StringView content,
+ virtual void info_show(const DisplayLine& title,
+ const DisplayLineList& content,
DisplayCoord anchor, Face face,
InfoStyle style) = 0;
virtual void info_hide() = 0;
diff --git a/src/utils.hh b/src/utils.hh
index f9c53509..0979aebe 100644
--- a/src/utils.hh
+++ b/src/utils.hh
@@ -186,6 +186,18 @@ private:
Invoker* m_invoker;
};
+template<typename... Funcs>
+struct Overload : Funcs...
+{
+ using Funcs::operator()...;
+};
+
+template<typename... Funcs>
+auto overload(Funcs&&... funcs)
+{
+ return Overload<std::decay_t<Funcs>...>{std::forward<Funcs>(funcs)...};
+}
+
}
#endif // utils_hh_INCLUDED
diff --git a/src/window.cc b/src/window.cc
index 0ef445ca..cbc4deab 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -135,7 +135,7 @@ const DisplayBuffer& Window::update_display_buffer(const Context& context)
}
}
- DisplayBuffer::LineList& lines = m_display_buffer.lines();
+ DisplayLineList& lines = m_display_buffer.lines();
m_display_buffer.set_timestamp(buffer().timestamp());
lines.clear();