diff --git a/src/rime/gear/chord_composer.cc b/src/rime/gear/chord_composer.cc index c26007f451..dc293a82f2 100644 --- a/src/rime/gear/chord_composer.cc +++ b/src/rime/gear/chord_composer.cc @@ -13,8 +13,7 @@ #include #include -// U+FEFF works better with MacType -static const char* kZeroWidthSpace = "\xef\xbb\xbf"; //"\xe2\x80\x8b"; +static const char* kZeroWidthSpace = "\xe2\x80\x8b"; // U+200B namespace rime { @@ -118,8 +117,9 @@ ProcessResult ChordComposer::ProcessChordingKey(const KeyEvent& key_event) { return kAccepted; } -inline static bool is_composing_text(Context* ctx) { - return ctx->IsComposing() && ctx->input() != kZeroWidthSpace; +inline static bool is_composing(Context* ctx) { + return !ctx->composition().empty() && + !ctx->composition().back().HasTag("phony"); } ProcessResult ChordComposer::ProcessKeyEvent(const KeyEvent& key_event) { @@ -133,7 +133,7 @@ ProcessResult ChordComposer::ProcessKeyEvent(const KeyEvent& key_event) { int ch = key_event.keycode(); if (!is_key_up && ch >= 0x20 && ch <= 0x7e) { // save raw input - if (!is_composing_text(engine_->context()) || !raw_sequence_.empty()) { + if (!is_composing(engine_->context()) || !raw_sequence_.empty()) { raw_sequence_.push_back(ch); DLOG(INFO) << "update raw sequence: " << raw_sequence_; } @@ -164,18 +164,17 @@ void ChordComposer::UpdateChord() { string code = SerializeChord(); prompt_format_.Apply(&code); if (comp.empty()) { - // add an invisbile place holder segment + // add a placeholder segment // 1. to cheat ctx->IsComposing() == true // 2. to attach chord prompt to while chording - ctx->PushInput(kZeroWidthSpace); - if (comp.empty()) { - LOG(ERROR) << "failed to update chord."; - return; - } - comp.back().tags.insert("phony"); - } - comp.back().tags.insert("chord_prompt"); - comp.back().prompt = code; + ctx->set_input(kZeroWidthSpace); + Segment placeholder(0, ctx->input().length()); + placeholder.tags.insert("phony"); + ctx->composition().AddSegment(placeholder); + } + auto& last_segment = comp.back(); + last_segment.tags.insert("chord_prompt"); + last_segment.prompt = code; } void ChordComposer::FinishChord() { @@ -207,20 +206,20 @@ void ChordComposer::ClearChord() { return; Context* ctx = engine_->context(); Composition& comp = ctx->composition(); - if (comp.empty()) { + if (comp.empty()) return; + auto& last_segment = comp.back(); + if (comp.size() == 1 && last_segment.HasTag("phony")) { + ctx->Clear(); } - if (comp.input().substr(comp.back().start) == kZeroWidthSpace) { - ctx->PopInput(ctx->caret_pos() - comp.back().start); - } - else if (comp.back().HasTag("chord_prompt")) { - comp.back().prompt.clear(); - comp.back().tags.erase("chord_prompt"); + else if (last_segment.HasTag("chord_prompt")) { + last_segment.prompt.clear(); + last_segment.tags.erase("chord_prompt"); } } void ChordComposer::OnContextUpdate(Context* ctx) { - if (is_composing_text(ctx)) { + if (is_composing(ctx)) { composing_ = true; } else if (composing_) {