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 
5 int 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 
27 int 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 
45 Replxx::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 
69 void 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 
94 Replxx::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
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
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
int context_len(char const *prefix)
Definition: Utils.cpp:27
auto colors
Definition: Node.cpp:181