ArkScript
A small, fast, functional and scripting language for video games
Utils.cpp
Go to the documentation of this file.
1#include <CLI/REPL/Utils.hpp>
2
3#include <regex>
4#include <algorithm>
5
6namespace Ark::internal
7{
8 long countOpenEnclosures(const std::string& line, const char open, const char close)
9 {
10 return std::ranges::count(line, open) - std::ranges::count(line, close);
11 }
12
13 void trimWhitespace(std::string& line)
14 {
15 const std::size_t string_begin = line.find_first_not_of(" \t");
16 if (std::string::npos != string_begin)
17 {
18 const std::size_t string_end = line.find_last_not_of(" \t");
19 line = line.substr(string_begin, string_end - string_begin + 1);
20 }
21 }
22
23 std::size_t codepointLength(const std::string& str)
24 {
25 std::size_t len = 0;
26 for (const auto c : str)
27 len += (c & 0xc0) != 0x80;
28 return len;
29 }
30
31 std::size_t contextLen(const std::string& prefix)
32 {
33 const std::string word_break = " \t\n\r\v\f=+*&^%$#@!,./?<>;`~'\"[]{}()\\|";
34 long i = static_cast<long>(prefix.size()) - 1;
35 std::size_t count = 0;
36
37 while (i >= 0)
38 {
39 if (word_break.find(prefix[static_cast<std::size_t>(i)]) != std::string::npos)
40 break;
41
42 ++count;
43 --i;
44 }
45
46 return count;
47 }
48
49 replxx::Replxx::completions_t hookCompletion(const std::vector<std::string>& words, const std::string& context, int& length)
50 {
51 replxx::Replxx::completions_t completions;
52 std::size_t utf8_context_len = contextLen(context);
53 std::size_t prefix_len = context.size() - utf8_context_len;
54
55 if (prefix_len > 0 && context[prefix_len - 1] == '\\')
56 {
57 --prefix_len;
58 ++utf8_context_len;
59 }
60
61 length = static_cast<int>(codepointLength(context.substr(prefix_len, utf8_context_len)));
62
63 const std::string prefix = context.substr(prefix_len);
64 for (const auto& e : words)
65 {
66 if (e.starts_with(prefix) == 0)
67 completions.emplace_back(e.c_str());
68 }
69
70 return completions;
71 }
72
73 void hookColor(const std::vector<std::pair<std::string, replxx::Replxx::Color>>& words_colors, const std::string& context, replxx::Replxx::colors_t& colors)
74 {
75 // highlight matching regex sequences
76 for (const auto& [regex, color] : words_colors)
77 {
78 std::size_t pos = 0;
79 std::string str = context;
80 std::smatch match;
81
82 while (std::regex_search(str, match, std::regex(regex)))
83 {
84 std::string c = match[0];
85 std::string prefix = match.prefix().str();
86 const std::size_t len = codepointLength(c);
87
88 pos += codepointLength(prefix);
89 for (std::size_t i = 0; i < len; ++i)
90 colors.at(pos + i) = color;
91
92 pos += len;
93 str = match.suffix();
94 }
95 }
96 }
97
98 replxx::Replxx::hints_t hookHint(const std::vector<std::string>& words, const std::string& context, int& length, replxx::Replxx::Color& color)
99 {
100 replxx::Replxx::hints_t hints;
101 // only show hint if prefix is at least 'n' chars long
102 // or if prefix begins with a specific character
103 const std::size_t utf8_context_len = contextLen(context);
104 const std::size_t prefix_len = context.size() - utf8_context_len;
105 length = static_cast<int>(codepointLength(context.substr(prefix_len, utf8_context_len)));
106 const std::string prefix = context.substr(prefix_len);
107
108 if (prefix.size() >= 2 || (!prefix.empty() && prefix.at(0) == '.'))
109 {
110 for (const auto& e : words)
111 {
112 if (e.compare(0, prefix.size(), prefix) == 0)
113 hints.emplace_back(e.c_str());
114 }
115 }
116
117 if (hints.size() == 1)
118 color = replxx::Replxx::Color::GREEN;
119
120 return hints;
121 }
122}
replxx utilities
std::size_t codepointLength(const std::string &str)
Definition Utils.cpp:23
std::size_t contextLen(const std::string &prefix)
Definition Utils.cpp:31
long countOpenEnclosures(const std::string &line, char open, char close)
Count the open enclosure and its counterpart: (), {}, [].
Definition Utils.cpp:8
void hookColor(const std::vector< std::pair< std::string, replxx::Replxx::Color > > &words_colors, const std::string &context, replxx::Replxx::colors_t &colors)
Definition Utils.cpp:73
constexpr std::array colors
Definition Logger.cpp:8
replxx::Replxx::completions_t hookCompletion(const std::vector< std::string > &words, const std::string &context, int &length)
Definition Utils.cpp:49
replxx::Replxx::hints_t hookHint(const std::vector< std::string > &words, const std::string &context, int &length, replxx::Replxx::Color &color)
Definition Utils.cpp:98
void trimWhitespace(std::string &line)
Remove whitespaces at the start and end of a string.
Definition Utils.cpp:13