diff --git a/src/rime/gear/single_char_filter.cc b/src/rime/gear/single_char_filter.cc index f7164aff46..6aa00d6698 100644 --- a/src/rime/gear/single_char_filter.cc +++ b/src/rime/gear/single_char_filter.cc @@ -6,6 +6,9 @@ // #include #include +#include +#include +#include #include #include #include @@ -55,11 +58,75 @@ bool SingleCharFirstTranslation::Rearrange() { return !cache_.empty(); } -SingleCharFilter::SingleCharFilter(const Ticket& ticket) : Filter(ticket) {} +class SingleCharOnlyTranslation : public Translation { + public: + SingleCharOnlyTranslation(an translation); + + bool Next() override; + an Peek() override; + + private: + bool SkipToNextChar(); + + an translation_; + an current_; +}; + +SingleCharOnlyTranslation::SingleCharOnlyTranslation( + an translation) + : translation_(translation) { + SkipToNextChar(); +} + +bool SingleCharOnlyTranslation::SkipToNextChar() { + while (true) { + if (translation_->exhausted() || !translation_->Next()) { + set_exhausted(true); + current_.reset(); + return false; + } + current_ = translation_->Peek(); + if (unistrlen(current_->text()) == 1) + return true; + } +} + +an SingleCharOnlyTranslation::Peek() { + return current_; +} + +bool SingleCharOnlyTranslation::Next() { + if (exhausted()) + return false; + return SkipToNextChar(); +} + +SingleCharFilter::SingleCharFilter(const Ticket& ticket) : Filter(ticket) { + if (name_space_ == "") { + name_space_ = "single_char_filter"; + } + if (Config* config = engine_->schema()->config()) { + string type; + if (config->GetString(name_space_ + "/type", &type)) { + type_ = (type == "char_only") ? kCharOnly : kCharFirst; + } else { + type_ = kCharFirst; + } + config->GetString(name_space_ + "/option_name", &option_name_); + } +} an SingleCharFilter::Apply(an translation, CandidateList* candidates) { - return New(translation); + // for backward compatibility, always enable filter if no option_name is given + if (option_name_ != "" && !engine_->context()->get_option(option_name_)) { + return translation; + } + if (type_ == kCharFirst) { + return New(translation); + } else { + return New(translation); + } } } // namespace rime diff --git a/src/rime/gear/single_char_filter.h b/src/rime/gear/single_char_filter.h index 2e6c04d534..976f821cc0 100644 --- a/src/rime/gear/single_char_filter.h +++ b/src/rime/gear/single_char_filter.h @@ -17,6 +17,13 @@ class SingleCharFilter : public Filter { virtual an Apply(an translation, CandidateList* candidates); + + protected: + enum FilterType { kCharOnly, kCharFirst }; + + std::string name_space_; + std::string option_name_ = ""; + FilterType type_ = kCharFirst; }; } // namespace rime