diff --git a/src/string.cc b/src/string.cc index 2c6bb140..dcfc1037 100644 --- a/src/string.cc +++ b/src/string.cc @@ -5,7 +5,7 @@ namespace Kakoune { -std::vector split(const String& str, char separator) +std::vector split(const String& str, char separator, char escape) { auto begin = str.begin(); auto end = str.begin(); @@ -13,12 +13,40 @@ std::vector split(const String& str, char separator) std::vector res; while (end != str.end()) { - while (end != str.end() and *end != separator) - ++end; - res.push_back(String(begin, end)); - if (end == str.end()) - break; - begin = ++end; + res.emplace_back(); + String& element = res.back(); + while (end != str.end()) + { + auto c = *end; + if (c == escape and end + 1 != end and *(end+1) == separator) + { + element += separator; + end += 2; + } + else if (c == separator) + { + ++end; + break; + } + else + { + element += c; + ++end; + } + } + begin = end; + } + return res; +} + +String escape(const String& str, char character, char escape) +{ + String res; + for (auto& c : str) + { + if (c == character) + res += escape; + res += c; } return res; } diff --git a/src/string.hh b/src/string.hh index a64bf180..f4a93309 100644 --- a/src/string.hh +++ b/src/string.hh @@ -84,7 +84,8 @@ inline String operator+(Codepoint lhs, const String& rhs) return String(lhs) + rhs; } -std::vector split(const String& str, char separator); +std::vector split(const String& str, char separator, char escape = 0); +String escape(const String& str, char character, char escape); inline String operator"" _str(const char* str, size_t) { diff --git a/src/unit_tests.cc b/src/unit_tests.cc index e0537123..5058bb91 100644 --- a/src/unit_tests.cc +++ b/src/unit_tests.cc @@ -120,11 +120,15 @@ void test_string() { kak_assert(String("youpi ") + "matin" == "youpi matin"); - std::vector splited = split("youpi:matin::tchou", ':'); + std::vector splited = split("youpi:matin::tchou\\:kanaky:hihi\\:", ':', '\\'); kak_assert(splited[0] == "youpi"); kak_assert(splited[1] == "matin"); kak_assert(splited[2] == ""); - kak_assert(splited[3] == "tchou"); + kak_assert(splited[3] == "tchou:kanaky"); + kak_assert(splited[4] == "hihi:"); + + String escaped = escape("youpi:matin:tchou:", ':', '\\'); + kak_assert(escaped == "youpi\\:matin\\:tchou\\:"); } void test_keys()