From 77af7d7f264fb6054bed09b353fbf71d64ce2f67 Mon Sep 17 00:00:00 2001 From: fanlusky <1730976608@qq.com> Date: Mon, 22 Jun 2026 00:56:59 +0800 Subject: [PATCH] Do not trigger cloud prediction when the full-pinyin auxiliary code is active. --- server/src/session/engine_input_session.cpp | 38 ++++++++++++++-- .../src/session/shuangpin_input_session.cpp | 45 +++++++++++++++++-- .../src/test_engine_shuangpin_session.cpp | 33 ++++++++++++++ server/tests/src/test_quanpin_scheme.cpp | 2 +- 4 files changed, 110 insertions(+), 8 deletions(-) diff --git a/server/src/session/engine_input_session.cpp b/server/src/session/engine_input_session.cpp index 83974c52..a2785ca3 100644 --- a/server/src/session/engine_input_session.cpp +++ b/server/src/session/engine_input_session.cpp @@ -3,6 +3,7 @@ #include #include "config/ime_config.h" #include "MetasequoiaImeEngine/common/helpcode_utils.h" +#include "MetasequoiaImeEngine/quanpin/quanpin_query.h" #include "MetasequoiaImeEngine/shuangpin/shuangpin_query.h" #include "MetasequoiaImeEngine/shuangpin/shuangpin_utils.h" @@ -43,6 +44,27 @@ ShuangpinCompositionBase ResolveShuangpinCompositionBase(const QueryRequest &req return base; } + +bool HasActiveQuanpinHelpcode(const QueryRequest &request) +{ + if (!request.enable_shuangpin_helpcode || request.raw_input.empty()) + { + return false; + } + + const auto &raw_input_with_cases = request.raw_input_with_cases.empty() ? request.raw_input : request.raw_input_with_cases; + if (HelpcodeUtils::is_quanpin_double_help_mode(raw_input_with_cases) && request.raw_input.size() >= 2) + { + return quanpin::is_complete_pinyin_input(request.raw_input.substr(0, request.raw_input.size() - 2)); + } + + if (HelpcodeUtils::is_quanpin_single_help_mode(raw_input_with_cases) && !request.raw_input.empty()) + { + return quanpin::is_complete_pinyin_input(request.raw_input.substr(0, request.raw_input.size() - 1)); + } + + return false; +} } // namespace EngineInputSession::EngineInputSession(SchemeType scheme_type) : session_(scheme_type) @@ -264,8 +286,16 @@ IInputSession::SelectionTransition EngineInputSession::advance_composition_after IInputSession::CloudQueryState EngineInputSession::get_cloud_query_state() const { CloudQueryState state; + state.cache_key = request().raw_input; + state.committed_pinyin = request().normalized_input; + if (is_shuangpin()) { + if (ResolveShuangpinCompositionBase(request()).helpcode_length > 0) + { + return state; + } + const auto &pinyin_with_cases = get_pinyin_sequence_with_cases(); if (!pinyin_with_cases.empty() && pinyin_with_cases.size() % 2 == 0) { @@ -277,16 +307,16 @@ IInputSession::CloudQueryState EngineInputSession::get_cloud_query_state() const { state.query_text = request().normalized_input; } + return state; + } - state.cache_key = request().raw_input; - state.committed_pinyin = request().normalized_input; + if (HasActiveQuanpinHelpcode(request())) + { return state; } state.should_query = !request().normalized_input.empty(); state.query_text = request().normalized_input; - state.cache_key = request().raw_input; - state.committed_pinyin = request().normalized_input; return state; } diff --git a/server/src/session/shuangpin_input_session.cpp b/server/src/session/shuangpin_input_session.cpp index 941dd4b5..ff022543 100644 --- a/server/src/session/shuangpin_input_session.cpp +++ b/server/src/session/shuangpin_input_session.cpp @@ -1,7 +1,41 @@ #include "shuangpin_input_session.h" +#include "config/ime_config.h" #include "MetasequoiaImeEngine/common/helpcode_utils.h" +#include "MetasequoiaImeEngine/shuangpin/shuangpin_utils.h" #include +namespace +{ +bool HasActiveShuangpinHelpcode(const ShuangpinInputSession &session) +{ + if (!GetConfiguredShuangpinHelpcodeEnabled()) + { + return false; + } + + const auto &raw_input = session.get_pinyin_sequence(); + const auto &raw_input_with_cases = session.get_pinyin_sequence_with_cases(); + if (raw_input.empty()) + { + return false; + } + + if (ShuangpinUtil::IsFullHelpMode(raw_input_with_cases) && raw_input.size() >= 2) + { + return true; + } + + if (raw_input.size() % 2 == 1 && raw_input.size() > 1) + { + const std::string pure_raw_input = raw_input.substr(0, raw_input.size() - 1); + const std::string pure_segmentation = ShuangpinUtil::pinyin_segmentation(pure_raw_input); + return ShuangpinUtil::is_all_complete_pinyin(pure_raw_input, pure_segmentation); + } + + return false; +} +} // namespace + ShuangpinInputSession::ShuangpinInputSession() : dictionary_(std::make_unique()) { } @@ -142,6 +176,14 @@ ShuangpinInputSession::advance_composition_after_selection(const std::string &se IInputSession::CloudQueryState ShuangpinInputSession::get_cloud_query_state() const { CloudQueryState state; + state.cache_key = dictionary_->get_pinyin_sequence(); + state.committed_pinyin = dictionary_->get_pure_pinyin_sequence(); + + if (HasActiveShuangpinHelpcode(*this)) + { + return state; + } + const auto &pinyin_with_cases = dictionary_->get_pinyin_sequence_with_cases(); if (!pinyin_with_cases.empty() && pinyin_with_cases.size() % 2 == 0) { @@ -153,9 +195,6 @@ IInputSession::CloudQueryState ShuangpinInputSession::get_cloud_query_state() co { state.query_text = dictionary_->get_quanpin(); } - - state.cache_key = dictionary_->get_pinyin_sequence(); - state.committed_pinyin = dictionary_->get_pure_pinyin_sequence(); return state; } diff --git a/server/tests/src/test_engine_shuangpin_session.cpp b/server/tests/src/test_engine_shuangpin_session.cpp index bcf40563..868fc36c 100644 --- a/server/tests/src/test_engine_shuangpin_session.cpp +++ b/server/tests/src/test_engine_shuangpin_session.cpp @@ -67,3 +67,36 @@ TEST_CASE(EngineShuangpinSessionCloudQueryMatchesLegacyTiming) state = session.get_cloud_query_state(); REQUIRE(!state.should_query); } + +TEST_CASE(EngineShuangpinSessionCloudQueryDoesNotTriggerWhenHelpcodesApply) +{ + EngineInputSession session(SchemeType::Shuangpin); + + InputLetters(session, "xitelea"); + auto state = session.get_cloud_query_state(); + REQUIRE(!state.should_query); + + session.reset_state(); + InputLetters(session, "xiteleaA"); + state = session.get_cloud_query_state(); + REQUIRE(!state.should_query); +} + +TEST_CASE(EngineQuanpinSessionCloudQueryDoesNotTriggerWhenHelpcodesApply) +{ + EngineInputSession session(SchemeType::Quanpin); + + InputLetters(session, "xiteleA"); + auto state = session.get_cloud_query_state(); + REQUIRE(!state.should_query); + + session.reset_state(); + InputLetters(session, "xiteleAA"); + state = session.get_cloud_query_state(); + REQUIRE(!state.should_query); + + session.reset_state(); + InputLetters(session, "xitelR"); + state = session.get_cloud_query_state(); + REQUIRE(state.should_query); +} diff --git a/server/tests/src/test_quanpin_scheme.cpp b/server/tests/src/test_quanpin_scheme.cpp index 20aa0640..c011de4a 100644 --- a/server/tests/src/test_quanpin_scheme.cpp +++ b/server/tests/src/test_quanpin_scheme.cpp @@ -105,7 +105,7 @@ TEST_CASE(QuanpinHelpcodeRequiresCompleteBasePinyin) REQUIRE_EQ(request.raw_input_with_cases, std::string("xitelA")); REQUIRE_EQ(request.raw_input, std::string("xitela")); REQUIRE_EQ(request.normalized_input, std::string("xitela")); - REQUIRE_EQ(request.raw_segmentation, std::string("xi'te'la")); + REQUIRE_EQ(request.raw_segmentation, std::string("xi'te'lA")); } TEST_CASE(QuanpinCompletePinyinInputDetectionMatchesHelpcodesRequirement)