ArkScript
A small, fast, functional and scripting language for video games
Utils.cpp
Go to the documentation of this file.
2#include <cstring>
3#include <regex>
4
5int utf8str_codepoint_len(char const* s, int utf8len)
6{
7 int codepointLen = 0;
8 unsigned char m4 = 128 + 64 + 32 + 16;
9 unsigned char m3 = 128 + 64 + 32;
10 unsigned char m2 = 128 + 64;
11
12 for (int i = 0; i < utf8len; ++i, ++codepointLen)
13 {
14 char c = s[i];
15
16 if ((c & m4) == m4)
17 i += 3;
18 else if ((c & m3) == m3)
19 i += 2;
20 else if ((c & m2) == m2)
21 i += 1;
22 }
23
24 return codepointLen;
25}
26
27int context_len(char const* prefix)
28{
29 char const wb[] = " \t\n\r\v\f-=+*&^%$#@!,./?<>;:`~'\"[]{}()\\|";
30 int i = std::strlen(prefix) - 1;
31 int cl = 0;
32
33 while (i >= 0)
34 {
35 if (std::strchr(wb, prefix[i]) != NULL)
36 break;
37
38 ++cl;
39 --i;
40 }
41
42 return cl;
43}
44
45Replxx::completions_t hook_completion(std::string const& context, int& contextLen, std::vector<std::string> const& examples)
46{
47 Replxx::completions_t completions;
48 int utf8ContextLen = context_len(context.c_str());
49 int prefixLen = context.length() - utf8ContextLen;
50
51 if ((prefixLen > 0) && (context[prefixLen - 1] == '\\'))
52 {
53 --prefixLen;
54 ++utf8ContextLen;
55 }
56
57 contextLen = utf8str_codepoint_len(context.c_str() + prefixLen, utf8ContextLen);
58
59 std::string prefix = context.substr(prefixLen);
60 for (auto const& e : examples)
61 {
62 if (e.compare(0, prefix.size(), prefix) == 0)
63 completions.emplace_back(e.c_str());
64 }
65
66 return completions;
67}
68
69void hook_color(std::string const& context, Replxx::colors_t& colors, std::vector<std::pair<std::string, Replxx::Color>> const& regex_color)
70{
71 // highlight matching regex sequences
72 for (auto const& e : regex_color)
73 {
74 std::size_t pos = 0;
75 std::string str = context;
76 std::smatch match;
77
78 while (std::regex_search(str, match, std::regex(e.first)))
79 {
80 std::string c = match[0];
81 std::string prefix = match.prefix().str();
82 pos += utf8str_codepoint_len(prefix.c_str(), static_cast<int>(prefix.length()));
83 int len = utf8str_codepoint_len(c.c_str(), static_cast<int>(c.length()));
84
85 for (int i = 0; i < len; ++i)
86 colors.at(pos + i) = e.second;
87
88 pos += len;
89 str = match.suffix();
90 }
91 }
92}
93
94Replxx::hints_t hook_hint(std::string const& context, int& contextLen, Replxx::Color& color, std::vector<std::string> const& examples)
95{
96 Replxx::hints_t hints;
97 // only show hint if prefix is at least 'n' chars long
98 // or if prefix begins with a specific character
99 int utf8ContextLen = context_len(context.c_str());
100 int prefixLen = context.length() - utf8ContextLen;
101 contextLen = utf8str_codepoint_len(context.c_str() + prefixLen, utf8ContextLen);
102 std::string prefix = context.substr(prefixLen);
103
104 if (prefix.size() >= 2 || (!prefix.empty() && prefix.at(0) == '.'))
105 {
106 for (auto const& e : examples)
107 {
108 if (e.compare(0, prefix.size(), prefix) == 0)
109 hints.emplace_back(e.c_str());
110 }
111 }
112
113 if (hints.size() == 1)
114 color = Replxx::Color::GREEN;
115
116 return hints;
117}
replxx utilities
int utf8str_codepoint_len(char const *s, int utf8len)
Definition: Utils.cpp:5
Replxx::completions_t hook_completion(std::string const &context, int &contextLen, std::vector< std::string > const &examples)
Definition: Utils.cpp:45
Replxx::hints_t hook_hint(std::string const &context, int &contextLen, Replxx::Color &color, std::vector< std::string > const &examples)
Definition: Utils.cpp:94
void hook_color(std::string const &context, Replxx::colors_t &colors, std::vector< std::pair< std::string, Replxx::Color > > const &regex_color)
Definition: Utils.cpp:69
int context_len(char const *prefix)
Definition: Utils.cpp:27