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