diff --git a/src/apps/terminal/BasicTerminalBuffer.cpp b/src/apps/terminal/BasicTerminalBuffer.cpp index 28b5b40947..f21124de47 100644 --- a/src/apps/terminal/BasicTerminalBuffer.cpp +++ b/src/apps/terminal/BasicTerminalBuffer.cpp @@ -421,7 +421,7 @@ BasicTerminalBuffer::FindWord(const TermPos& pos, x--; // get the char type at the given position - int type = classifier->Classify(line->cells[x].character.bytes); + int type = classifier->Classify(line->cells[x].character); // check whether we are supposed to find words only if (type != CHAR_TYPE_WORD_CHAR && !findNonWords) @@ -444,7 +444,7 @@ BasicTerminalBuffer::FindWord(const TermPos& pos, if (x > 0 && IS_WIDTH(line->cells[x - 1].attributes)) x--; - if (classifier->Classify(line->cells[x].character.bytes) != type) + if (classifier->Classify(line->cells[x].character) != type) break; start.SetTo(x, y); @@ -467,7 +467,7 @@ BasicTerminalBuffer::FindWord(const TermPos& pos, break; } - if (classifier->Classify(line->cells[x].character.bytes) != type) + if (classifier->Classify(line->cells[x].character) != type) break; x += IS_WIDTH(line->cells[x].attributes) ? 2 : 1; diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp index 3488e41628..e6e3d4be01 100644 --- a/src/apps/terminal/TermView.cpp +++ b/src/apps/terminal/TermView.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -144,28 +145,34 @@ restrict_value(const Type& value, const Type& min, const Type& max) class TermView::CharClassifier : public TerminalCharClassifier { public: CharClassifier(const char* specialWordChars) - : - fSpecialWordChars(specialWordChars) { + const char* p = specialWordChars; + while (p != NULL && *p) { + int count = UTF8Char::ByteCount(*p); + if (count <= 0 || count > 4) + break; + fSpecialWordChars.push_back(UTF8Char(p, count)); + p += count; + } } - virtual int Classify(const char* character) + virtual int Classify(const UTF8Char& character) { - // TODO: Deal correctly with non-ASCII chars. - char c = *character; - if (UTF8Char::ByteCount(c) > 1) + if (character.IsSpace()) + return CHAR_TYPE_SPACE; + + if (character.IsAlNum()) return CHAR_TYPE_WORD_CHAR; - if (isspace(c)) - return CHAR_TYPE_SPACE; - if (isalnum(c) || strchr(fSpecialWordChars, c) != NULL) + if (std::find(fSpecialWordChars.begin(), fSpecialWordChars.end(), + character) != fSpecialWordChars.end()) return CHAR_TYPE_WORD_CHAR; return CHAR_TYPE_WORD_DELIMITER; } private: - const char* fSpecialWordChars; + std::vector fSpecialWordChars; }; diff --git a/src/apps/terminal/TerminalCharClassifier.h b/src/apps/terminal/TerminalCharClassifier.h index 2a8ebc017d..236f31c3aa 100644 --- a/src/apps/terminal/TerminalCharClassifier.h +++ b/src/apps/terminal/TerminalCharClassifier.h @@ -13,11 +13,13 @@ enum { }; +class UTF8Char; + class TerminalCharClassifier { public: virtual ~TerminalCharClassifier(); - virtual int Classify(const char* character) = 0; + virtual int Classify(const UTF8Char& character) = 0; }; diff --git a/src/apps/terminal/UTF8Char.h b/src/apps/terminal/UTF8Char.h index ef7c48fb51..e8b50d46a4 100644 --- a/src/apps/terminal/UTF8Char.h +++ b/src/apps/terminal/UTF8Char.h @@ -8,6 +8,8 @@ #include #include +#include + struct UTF8Char { char bytes[4]; @@ -63,17 +65,23 @@ struct UTF8Char { bool IsSpace() const { - // TODO: Support multi-byte chars! - return ByteCount() == 1 ? isspace(bytes[0]) : false; + return BUnicodeChar::IsSpace(BUnicodeChar::FromUTF8(bytes)); + } + + bool IsAlNum() const + { + return BUnicodeChar::IsAlNum(BUnicodeChar::FromUTF8(bytes)); } UTF8Char ToLower() const { - // TODO: Support multi-byte chars! - if (ByteCount() > 1) - return *this; + uint32 c = BUnicodeChar::ToLower(BUnicodeChar::FromUTF8(bytes)); - return UTF8Char((char)tolower(bytes[0])); + UTF8Char character; + char* utf8 = character.bytes; + BUnicodeChar::ToUTF8(c, &utf8); + + return character; } bool operator==(const UTF8Char& other) const