diff --git a/src/source_base.cpp b/src/source_base.cpp index 1515f7f..0111acc 100644 --- a/src/source_base.cpp +++ b/src/source_base.cpp @@ -1151,7 +1151,8 @@ void Source::BaseView::insert_snippet(Gtk::TextIter iter, const std::string &sni if(snippet.at(i) != '}') throw std::logic_error("closing } not found"); ++i; - arguments_offsets[number].emplace_back(insert.size(), insert.size() + placeholder.size()); + auto insert_character_count = utf8_character_count(insert); + arguments_offsets[number].emplace_back(insert_character_count, insert_character_count + utf8_character_count(placeholder)); insert += placeholder; } else { @@ -1170,8 +1171,10 @@ void Source::BaseView::insert_snippet(Gtk::TextIter iter, const std::string &sni ++i; } } - else if(parse_number()) - arguments_offsets[number].emplace_back(insert.size(), insert.size()); + else if(parse_number()) { + auto insert_character_count = utf8_character_count(insert); + arguments_offsets[number].emplace_back(insert_character_count, insert_character_count); + } else parse_variable(); } diff --git a/src/utility.cpp b/src/utility.cpp index 8e1c894..1dc4bdd 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -6,6 +6,15 @@ ScopeGuard::~ScopeGuard() { on_exit(); } +size_t utf8_character_count(const std::string &text) noexcept { + size_t count = 0; + for(auto chr : text) { + if(static_cast(chr) <= 0b01111111 || static_cast(chr) >= 0b11000000) + ++count; + } + return count; +} + bool starts_with(const char *str, const std::string &test) noexcept { for(size_t i = 0; i < test.size(); ++i) { if(*str == '\0') diff --git a/src/utility.hpp b/src/utility.hpp index e143b8d..9d5a723 100644 --- a/src/utility.hpp +++ b/src/utility.hpp @@ -8,11 +8,16 @@ public: ~ScopeGuard(); }; +/// Returns number of utf8 characters in text argument +size_t utf8_character_count(const std::string &text) noexcept; + bool starts_with(const char *str, const std::string &test) noexcept; bool starts_with(const char *str, const char *test) noexcept; bool starts_with(const std::string &str, const std::string &test) noexcept; bool starts_with(const std::string &str, const char *test) noexcept; +/// Comparison starts from position pos in str bool starts_with(const std::string &str, size_t pos, const std::string &test) noexcept; +/// Comparison starts from position pos in str bool starts_with(const std::string &str, size_t pos, const char *test) noexcept; bool ends_with(const std::string &str, const std::string &test) noexcept; diff --git a/tests/utility_test.cpp b/tests/utility_test.cpp index ae0e319..b778612 100644 --- a/tests/utility_test.cpp +++ b/tests/utility_test.cpp @@ -11,6 +11,11 @@ int main() { } g_assert(scope_exit); + g_assert(utf8_character_count("") == 0); + g_assert(utf8_character_count("test") == 4); + g_assert(utf8_character_count("æøå") == 3); + g_assert(utf8_character_count("æøåtest") == 7); + std::string empty; std::string test("test"); std::string testtest("testtest");