13
13
#include < rime/schema.h>
14
14
#include < rime/gear/chord_composer.h>
15
15
16
- // U+FEFF works better with MacType
17
- static const char * kZeroWidthSpace = " \xef\xbb\xbf " ; // "\xe2\x80\x8b";
16
+ static const char * kZeroWidthSpace = " \xe2\x80\x8b " ; // U+200B
18
17
19
18
namespace rime {
20
19
@@ -118,8 +117,9 @@ ProcessResult ChordComposer::ProcessChordingKey(const KeyEvent& key_event) {
118
117
return kAccepted ;
119
118
}
120
119
121
- inline static bool is_composing_text (Context* ctx) {
122
- return ctx->IsComposing () && ctx->input () != kZeroWidthSpace ;
120
+ inline static bool is_composing (Context* ctx) {
121
+ return !ctx->composition ().empty () &&
122
+ !ctx->composition ().back ().HasTag (" phony" );
123
123
}
124
124
125
125
ProcessResult ChordComposer::ProcessKeyEvent (const KeyEvent& key_event) {
@@ -133,7 +133,7 @@ ProcessResult ChordComposer::ProcessKeyEvent(const KeyEvent& key_event) {
133
133
int ch = key_event.keycode ();
134
134
if (!is_key_up && ch >= 0x20 && ch <= 0x7e ) {
135
135
// save raw input
136
- if (!is_composing_text (engine_->context ()) || !raw_sequence_.empty ()) {
136
+ if (!is_composing (engine_->context ()) || !raw_sequence_.empty ()) {
137
137
raw_sequence_.push_back (ch);
138
138
DLOG (INFO) << " update raw sequence: " << raw_sequence_;
139
139
}
@@ -164,18 +164,17 @@ void ChordComposer::UpdateChord() {
164
164
string code = SerializeChord ();
165
165
prompt_format_.Apply (&code);
166
166
if (comp.empty ()) {
167
- // add an invisbile place holder segment
167
+ // add a placeholder segment
168
168
// 1. to cheat ctx->IsComposing() == true
169
169
// 2. to attach chord prompt to while chording
170
- ctx->PushInput (kZeroWidthSpace );
171
- if (comp.empty ()) {
172
- LOG (ERROR) << " failed to update chord." ;
173
- return ;
174
- }
175
- comp.back ().tags .insert (" phony" );
176
- }
177
- comp.back ().tags .insert (" chord_prompt" );
178
- comp.back ().prompt = code;
170
+ ctx->set_input (kZeroWidthSpace );
171
+ Segment placeholder (0 , ctx->input ().length ());
172
+ placeholder.tags .insert (" phony" );
173
+ ctx->composition ().AddSegment (placeholder);
174
+ }
175
+ auto & last_segment = comp.back ();
176
+ last_segment.tags .insert (" chord_prompt" );
177
+ last_segment.prompt = code;
179
178
}
180
179
181
180
void ChordComposer::FinishChord () {
@@ -207,20 +206,20 @@ void ChordComposer::ClearChord() {
207
206
return ;
208
207
Context* ctx = engine_->context ();
209
208
Composition& comp = ctx->composition ();
210
- if (comp.empty ()) {
209
+ if (comp.empty ())
211
210
return ;
211
+ auto & last_segment = comp.back ();
212
+ if (comp.size () == 1 && last_segment.HasTag (" phony" )) {
213
+ ctx->Clear ();
212
214
}
213
- if (comp.input ().substr (comp.back ().start ) == kZeroWidthSpace ) {
214
- ctx->PopInput (ctx->caret_pos () - comp.back ().start );
215
- }
216
- else if (comp.back ().HasTag (" chord_prompt" )) {
217
- comp.back ().prompt .clear ();
218
- comp.back ().tags .erase (" chord_prompt" );
215
+ else if (last_segment.HasTag (" chord_prompt" )) {
216
+ last_segment.prompt .clear ();
217
+ last_segment.tags .erase (" chord_prompt" );
219
218
}
220
219
}
221
220
222
221
void ChordComposer::OnContextUpdate (Context* ctx) {
223
- if (is_composing_text (ctx)) {
222
+ if (is_composing (ctx)) {
224
223
composing_ = true ;
225
224
}
226
225
else if (composing_) {
0 commit comments