diff --git a/src/rime/gear/punctuator.cc b/src/rime/gear/punctuator.cc index ed439c3d7a..06b8ffcf55 100644 --- a/src/rime/gear/punctuator.cc +++ b/src/rime/gear/punctuator.cc @@ -49,9 +49,9 @@ Punctuator::Punctuator(const Ticket& ticket) : Processor(ticket) { config_.LoadConfig(engine_); } -static bool punctuation_is_translated(Context* ctx) { +static bool punctuation_is_translated(Context* ctx, const string& tag) { Composition& comp = ctx->composition(); - if (comp.empty() || !comp.back().HasTag("punct")) { + if (comp.empty() || !comp.back().HasTag(tag)) { return false; } auto cand = comp.back().GetSelectedCandidate(); @@ -79,7 +79,8 @@ static bool is_after_number(Context* ctx) { static bool is_after_digit_separator(Context* ctx) { const auto& comp = ctx->composition(); - return !comp.empty() && comp.back().HasTag("punct_number"); + return !comp.empty() && comp[0].HasTag("punct_number") && + comp[0].length == ctx->input().length(); } ProcessResult Punctuator::ProcessKeyEvent(const KeyEvent& key_event) { @@ -110,8 +111,8 @@ ProcessResult Punctuator::ProcessKeyEvent(const KeyEvent& key_event) { if (AlternatePunct(key, punct_definition)) { return kAccepted; } - if (ToggleNumberMode(key) || ctx->PushInput(ch)) { - if (punctuation_is_translated(ctx)) { + if (ToggleNumberMode(ch) || ctx->PushInput(ch)) { + if (punctuation_is_translated(ctx, "punct")) { ConfirmUniquePunct(punct_definition) || AutoCommitPunct(punct_definition) || PairPunct(punct_definition); } @@ -119,20 +120,24 @@ ProcessResult Punctuator::ProcessKeyEvent(const KeyEvent& key_event) { return kAccepted; } -bool Punctuator::ToggleNumberMode(const string& key) { +bool Punctuator::ToggleNumberMode(char ch) { Context* ctx = engine_->context(); - if (ctx->input() == key) { - Composition& comp = ctx->composition(); - if (!comp.empty()) { - Segment& segment(comp.back()); - if (segment.HasTag("punct_number")) { - segment.tags.erase("punct_number"); - segment.tags.insert("punct"); - segment.status = Segment::kVoid; - DLOG(INFO) << "exit number mode, key = " << key; - ctx->update_notifier()(ctx); - return true; - } + Composition& comp = ctx->composition(); + if (comp.empty()) { + if (is_digit_separator(ch) && is_after_number(ctx)) { + ctx->PushInput(ch) && punctuation_is_translated(ctx, "punct_number") && + comp.Forward(); + return true; + } + } else if (ctx->input() == string(1, ch)) { + Segment& segment = comp[0]; + if (segment.HasTag("punct_number")) { + segment.tags.erase("punct_number"); + segment.tags.insert("punct"); + segment.status = Segment::kVoid; + DLOG(INFO) << "exit number mode, key = " << ch; + ctx->ReopenPreviousSegment(); + return true; } } return false; @@ -234,7 +239,8 @@ bool PunctSegmentor::Proceed(Segmentation* segmentation) { return false; // exclusive } -PunctTranslator::PunctTranslator(const Ticket& ticket) : Translator(ticket) { +PunctTranslator::PunctTranslator(const Ticket& ticket) + : Translator(ticket), formatter_(ticket) { const bool load_symbols = true; config_.LoadConfig(engine_, load_symbols); } @@ -282,6 +288,14 @@ an CreatePunctCandidate(const string& punct, an PunctTranslator::Query(const string& input, const Segment& segment) { + if (segment.HasTag("punct_number")) { + if (input.length() == 1 && is_digit_separator(input[0])) { + string punct = input; + formatter_.Format(&punct); + return New(CreatePunctCandidate(punct, segment)); + } + return nullptr; + } if (!segment.HasTag("punct")) return nullptr; // sync with full_shape option diff --git a/src/rime/gear/punctuator.h b/src/rime/gear/punctuator.h index beb4d8dfac..aaf03d392a 100644 --- a/src/rime/gear/punctuator.h +++ b/src/rime/gear/punctuator.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace rime { @@ -35,7 +36,7 @@ class Punctuator : public Processor { virtual ProcessResult ProcessKeyEvent(const KeyEvent& key_event); protected: - bool ToggleNumberMode(const string& key); + bool ToggleNumberMode(char ch); bool AlternatePunct(const string& key, const an& definition); bool ConfirmUniquePunct(const an& definition); bool AutoCommitPunct(const an& definition); @@ -74,6 +75,7 @@ class PunctTranslator : public Translator { const Segment& segment, const an& definition); + ShapeFormatter formatter_; PunctConfig config_; };