1 // Copyright (C) 2018 ycmd contributors 2 // 3 // This file is part of ycmd. 4 // 5 // ycmd is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // ycmd is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with ycmd. If not, see <http://www.gnu.org/licenses/>. 17 18 #ifndef CHARACTER_H_YTIET2HZ 19 #define CHARACTER_H_YTIET2HZ 20 21 #include <string> 22 #include <string_view> 23 #include <vector> 24 25 namespace YouCompleteMe { 26 27 // This class represents a UTF-8 character. It takes a UTF-8 encoded string 28 // corresponding to a grapheme cluster (see 29 // https://www.unicode.org/glossary/#grapheme_cluster), normalize it through NFD 30 // (see https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf#G49621), and 31 // compute the folded and swapped case versions of the normalized character. It 32 // also holds some properties like if the character is a letter or a 33 // punctuation, and if it is uppercase. 34 class Character { 35 public: 36 YCM_EXPORT explicit Character( std::string_view character ); 37 // Make class noncopyable 38 Character( const Character& ) = delete; 39 Character& operator=( const Character& ) = delete; 40 Character( Character&& ) = default; 41 Character& operator=( Character&& ) = default; 42 Normal()43 inline std::string Normal() const { 44 return normal_; 45 } 46 Base()47 inline std::string Base() const { 48 return base_; 49 } 50 FoldedCase()51 inline std::string FoldedCase() const { 52 return folded_case_; 53 } 54 SwappedCase()55 inline std::string SwappedCase() const { 56 return swapped_case_; 57 } 58 IsBase()59 inline bool IsBase() const { 60 return is_base_; 61 } 62 IsLetter()63 inline bool IsLetter() const { 64 return is_letter_; 65 } 66 IsPunctuation()67 inline bool IsPunctuation() const { 68 return is_punctuation_; 69 } 70 IsUppercase()71 inline bool IsUppercase() const { 72 return is_uppercase_; 73 } 74 75 inline bool operator== ( const Character &other ) const { 76 return normal_ == other.normal_; 77 } 78 EqualsBase(const Character & other)79 inline bool EqualsBase( const Character &other ) const { 80 return base_ == other.base_; 81 } 82 EqualsIgnoreCase(const Character & other)83 inline bool EqualsIgnoreCase( const Character &other ) const { 84 return folded_case_ == other.folded_case_; 85 } 86 87 // Smart base matching on top of smart case matching, e.g.: 88 // - e matches e, é, E, É; 89 // - E matches E, É but not e, é; 90 // - é matches é, É but not e, E; 91 // - É matches É but not e, é, E. MatchesSmart(const Character & other)92 inline bool MatchesSmart( const Character &other ) const { 93 return ( is_base_ && EqualsBase( other ) && 94 ( !is_uppercase_ || other.is_uppercase_ ) ) || 95 ( !is_uppercase_ && EqualsIgnoreCase( other ) ) || 96 normal_ == other.normal_; 97 } 98 99 private: 100 std::string normal_; 101 std::string base_; 102 std::string folded_case_; 103 std::string swapped_case_; 104 bool is_base_; 105 bool is_letter_; 106 bool is_punctuation_; 107 bool is_uppercase_; 108 }; 109 110 111 YCM_EXPORT std::string NormalizeInput( std::string_view text ); 112 113 using CharacterSequence = std::vector< const Character * >; 114 115 } // namespace YouCompleteMe 116 117 #endif /* end of include guard: CHARACTER_H_YTIET2HZ */ 118