parent
22d9ffa63a
commit
cb1b03c0db
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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;
|
||||
|
|
12
src/utils.hh
12
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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user