diff --git a/src/rime/composition.cc b/src/rime/composition.cc index 500d7b8dd..d23436502 100644 --- a/src/rime/composition.cc +++ b/src/rime/composition.cc @@ -5,6 +5,7 @@ // 2011-06-19 GONG Chen // #include +#include #include #include #include @@ -167,4 +168,16 @@ string Composition::GetDebugText() const { return result; } +string Composition::GetTextBefore(size_t pos) const { + if (empty()) return string(); + for (const auto& seg : boost::adaptors::reverse(*this)) { + if (seg.end <= pos) { + if (auto cand = seg.GetSelectedCandidate()) { + return cand->text(); + } + } + } + return string(); +} + } // namespace rime diff --git a/src/rime/composition.h b/src/rime/composition.h index 5502947fe..7bbb2bdfc 100644 --- a/src/rime/composition.h +++ b/src/rime/composition.h @@ -29,6 +29,8 @@ class Composition : public Segmentation { string GetCommitText() const; string GetScriptText() const; string GetDebugText() const; + // Returns text of the last segment before the given position. + string GetTextBefore(size_t pos) const; }; } // namespace rime diff --git a/src/rime/gear/poet.h b/src/rime/gear/poet.h index 1b1dd44df..ff55ed55f 100644 --- a/src/rime/gear/poet.h +++ b/src/rime/gear/poet.h @@ -44,14 +44,17 @@ class Poet { template an ContextualWeighted(an translation, const string& input, + size_t start, TranslatorT* translator) { if (!translator->contextual_suggestions() || !grammar_) { return translation; } - return New(translation, - input, - translator->GetPrecedingText(), - grammar_.get()); + auto preceding_text = translator->GetPrecedingText(start); + if (preceding_text.empty()) { + return translation; + } + return New( + translation, input, preceding_text, grammar_.get()); } private: diff --git a/src/rime/gear/script_translator.cc b/src/rime/gear/script_translator.cc index 33c36c16a..7ca3a2ac3 100644 --- a/src/rime/gear/script_translator.cc +++ b/src/rime/gear/script_translator.cc @@ -196,7 +196,7 @@ an ScriptTranslator::Query(const string& input, } auto deduped = New(result); if (contextual_suggestions_) { - return poet_->ContextualWeighted(deduped, input, this); + return poet_->ContextualWeighted(deduped, input, segment.start, this); } return deduped; } @@ -218,9 +218,10 @@ string ScriptTranslator::Spell(const Code& code) { return result; } -string ScriptTranslator::GetPrecedingText() const { - return contextual_suggestions_ ? - engine_->context()->commit_history().latest_text() : string(); +string ScriptTranslator::GetPrecedingText(size_t start) const { + return !contextual_suggestions_ ? string() : + start > 0 ? engine_->context()->composition().GetTextBefore(start) : + engine_->context()->commit_history().latest_text(); } bool ScriptTranslator::Memorize(const CommitEntry& commit_entry) { @@ -547,9 +548,10 @@ an ScriptTranslation::MakeSentence(Dictionary* dict, } } } - if (auto sentence = poet_->MakeSentence(graph, - syllable_graph.interpreted_length, - translator_->GetPrecedingText())) { + if (auto sentence = + poet_->MakeSentence(graph, + syllable_graph.interpreted_length, + translator_->GetPrecedingText(start_))) { sentence->Offset(start_); sentence->set_syllabifier(syllabifier_); return sentence; diff --git a/src/rime/gear/script_translator.h b/src/rime/gear/script_translator.h index 139a4be33..66f60a2ca 100644 --- a/src/rime/gear/script_translator.h +++ b/src/rime/gear/script_translator.h @@ -37,7 +37,7 @@ class ScriptTranslator : public Translator, string FormatPreedit(const string& preedit); string Spell(const Code& code); - string GetPrecedingText() const; + string GetPrecedingText(size_t start) const; // options int max_homophones() const { return max_homophones_; } diff --git a/src/rime/gear/table_translator.cc b/src/rime/gear/table_translator.cc index e21236e7a..2dcc4524c 100644 --- a/src/rime/gear/table_translator.cc +++ b/src/rime/gear/table_translator.cc @@ -312,7 +312,7 @@ an TableTranslator::Query(const string& input, } translation = New(translation); if (contextual_suggestions_) { - return poet_->ContextualWeighted(translation, input, this); + return poet_->ContextualWeighted(translation, input, segment.start, this); } return translation; } @@ -366,9 +366,10 @@ bool TableTranslator::Memorize(const CommitEntry& commit_entry) { return true; } -string TableTranslator::GetPrecedingText() const { - return contextual_suggestions_ ? - engine_->context()->commit_history().latest_text() : string(); +string TableTranslator::GetPrecedingText(size_t start) const { + return !contextual_suggestions_ ? string() : + start > 0 ? engine_->context()->composition().GetTextBefore(start) : + engine_->context()->commit_history().latest_text(); } // SentenceSyllabifier @@ -691,7 +692,7 @@ TableTranslator::MakeSentence(const string& input, size_t start, } if (auto sentence = poet_->MakeSentence(graph, input.length(), - GetPrecedingText())) { + GetPrecedingText(start))) { auto result = Cached( this, std::move(sentence), diff --git a/src/rime/gear/table_translator.h b/src/rime/gear/table_translator.h index 1977f5942..ae1d46424 100644 --- a/src/rime/gear/table_translator.h +++ b/src/rime/gear/table_translator.h @@ -29,13 +29,13 @@ class TableTranslator : public Translator, TableTranslator(const Ticket& ticket); virtual an Query(const string& input, - const Segment& segment); + const Segment& segment); virtual bool Memorize(const CommitEntry& commit_entry); an MakeSentence(const string& input, - size_t start, - bool include_prefix_phrases = false); - string GetPrecedingText() const; + size_t start, + bool include_prefix_phrases = false); + string GetPrecedingText(size_t start) const; UnityTableEncoder* encoder() const { return encoder_.get(); } protected: