Add the most important missing feature of Kakoune
This commit is contained in:
parent
dc8803e41b
commit
dc7227b983
|
@ -18,6 +18,7 @@
|
||||||
#include "color_registry.hh"
|
#include "color_registry.hh"
|
||||||
#include "client_manager.hh"
|
#include "client_manager.hh"
|
||||||
#include "parameters_parser.hh"
|
#include "parameters_parser.hh"
|
||||||
|
#include "utf8_iterator.hh"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -555,9 +556,83 @@ void menu(const CommandParameters& params, Context& context)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String assist(String message, CharCount maxWidth)
|
||||||
|
{
|
||||||
|
static const std::vector<String> assistant =
|
||||||
|
{ R"( __ )",
|
||||||
|
R"( / \ )",
|
||||||
|
R"( | | )",
|
||||||
|
R"( @ @ /)",
|
||||||
|
R"( || || / )",
|
||||||
|
R"( || || _/ )",
|
||||||
|
R"( |\_/| )",
|
||||||
|
R"( \___/ )",
|
||||||
|
R"( )" };
|
||||||
|
|
||||||
|
const CharCount maxBubbleWidth = maxWidth - assistant[0].char_length() - 6;
|
||||||
|
CharCount bubbleWidth = 0;
|
||||||
|
std::vector<String> lines;
|
||||||
|
{
|
||||||
|
using Utf8It = utf8::utf8_iterator<String::iterator>;
|
||||||
|
Utf8It word_begin{message.begin()};
|
||||||
|
Utf8It word_end{word_begin};
|
||||||
|
Utf8It end{message.end()};
|
||||||
|
CharCount col = 0;
|
||||||
|
String line;
|
||||||
|
while (word_begin != end)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
++word_end;
|
||||||
|
} while (word_end != end and not is_blank(*word_end) and not is_eol(*word_end));
|
||||||
|
|
||||||
|
col += word_end - word_begin;
|
||||||
|
if (col > maxBubbleWidth or *word_begin == '\n')
|
||||||
|
{
|
||||||
|
bubbleWidth = std::max(bubbleWidth, line.char_length());
|
||||||
|
lines.push_back(std::move(line));
|
||||||
|
line = "";
|
||||||
|
col = 0;
|
||||||
|
}
|
||||||
|
if (*word_begin != '\n')
|
||||||
|
line += String(word_begin.underlying_iterator(), word_end.underlying_iterator());
|
||||||
|
word_begin = word_end;
|
||||||
|
}
|
||||||
|
if (not line.empty())
|
||||||
|
{
|
||||||
|
bubbleWidth = std::max(bubbleWidth, line.char_length());
|
||||||
|
lines.push_back(std::move(line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String result;
|
||||||
|
LineCount lineCount{std::max<int>(8, lines.size() + 3)};
|
||||||
|
for (LineCount i = 0; i < lineCount; ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
result += assistant[std::min((int)i, (int)assistant.size()-1)];
|
||||||
|
if (i == 0)
|
||||||
|
result += " " + String('_', (int)bubbleWidth) + " ";
|
||||||
|
else if (i == 1)
|
||||||
|
result += "/ " + String(' ', (int)bubbleWidth) + " \\";
|
||||||
|
else if (i < lines.size() + 2)
|
||||||
|
{
|
||||||
|
auto& line = lines[(int)i - 2];
|
||||||
|
const CharCount padding = std::max(bubbleWidth - line.char_length(), 0_char);
|
||||||
|
result += "| " + line + String(' ', padding) + " |";
|
||||||
|
}
|
||||||
|
else if (i == lines.size() + 2)
|
||||||
|
result += "\\_" + String('_', (int)bubbleWidth) + "_/";
|
||||||
|
|
||||||
|
result += "\n";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void info(const CommandParameters& params, Context& context)
|
void info(const CommandParameters& params, Context& context)
|
||||||
{
|
{
|
||||||
ParametersParser parser(params, { { "anchor", true } });
|
ParametersParser parser(params, { { "anchor", true }, { "assist", false } });
|
||||||
|
|
||||||
if (parser.positional_count() > 1)
|
if (parser.positional_count() > 1)
|
||||||
throw wrong_argument_count();
|
throw wrong_argument_count();
|
||||||
|
@ -566,7 +641,8 @@ void info(const CommandParameters& params, Context& context)
|
||||||
if (parser.positional_count() > 0)
|
if (parser.positional_count() > 0)
|
||||||
{
|
{
|
||||||
MenuStyle style = MenuStyle::Prompt;
|
MenuStyle style = MenuStyle::Prompt;
|
||||||
DisplayCoord pos = { context.ui().dimensions().line, 0 };
|
DisplayCoord dimensions = context.ui().dimensions();
|
||||||
|
DisplayCoord pos = { dimensions.line, 0 };
|
||||||
if (parser.has_option("anchor"))
|
if (parser.has_option("anchor"))
|
||||||
{
|
{
|
||||||
style = MenuStyle::Inline;
|
style = MenuStyle::Inline;
|
||||||
|
@ -581,7 +657,8 @@ void info(const CommandParameters& params, Context& context)
|
||||||
throw runtime_error("anchor param must be one of [left, right, cursor]");
|
throw runtime_error("anchor param must be one of [left, right, cursor]");
|
||||||
pos = context.window().display_position(it);
|
pos = context.window().display_position(it);
|
||||||
}
|
}
|
||||||
context.ui().info_show(parser[0], pos, style);
|
const String& message = parser.has_option("assist") ? assist(parser[0], dimensions.column) : parser[0];
|
||||||
|
context.ui().info_show(message, pos, style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user