Skip to content

Commit

Permalink
fix(context): tag selected segment after editing
Browse files Browse the repository at this point in the history
call Context::BeginEditing when input is edited after selection.
move cursor also counts as edit.

the tag is used to tell if BackSpace should delete the last input
character or revert a recent selection.

the information was previously denoted by kConfirmed status which caused
the side-effect of breaking a user phrase into individual segments.

fixed #746, fixed #830
  • Loading branch information
lotem committed Mar 2, 2024
1 parent 4ee471e commit 8b7f6b7
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 11 deletions.
18 changes: 14 additions & 4 deletions src/rime/context.cc
Expand Up @@ -12,6 +12,8 @@

namespace rime {

const string kSelectedBeforeEditing = "selected_before_editing";

bool Context::Commit() {
if (!IsComposing())
return false;
Expand Down Expand Up @@ -185,16 +187,20 @@ bool Context::ConfirmCurrentSelection() {
return true;
}

bool Context::ConfirmPreviousSelection() {
void Context::BeginEditing() {
for (auto it = composition_.rbegin(); it != composition_.rend(); ++it) {
if (it->status > Segment::kSelected) {
return false;
return;
}
if (it->status == Segment::kSelected) {
it->status = Segment::kConfirmed;
return true;
it->tags.insert(kSelectedBeforeEditing);
return;
}
}
}

bool Context::ConfirmPreviousSelection() {
BeginEditing();
return false;
}

Expand Down Expand Up @@ -225,6 +231,10 @@ bool Context::ReopenPreviousSelection() {
if (it->status > Segment::kSelected)
return false;
if (it->status == Segment::kSelected) {
// do not reopen the previous selection after editing input.
if (it->tags.count(kSelectedBeforeEditing) != 0) {
return false;
}
while (it != composition_.rbegin()) {
composition_.pop_back();
}
Expand Down
4 changes: 2 additions & 2 deletions src/rime/context.h
Expand Up @@ -50,8 +50,8 @@ class RIME_API Context {
// return false if there's no candidate for current segment
bool ConfirmCurrentSelection();
bool DeleteCurrentSelection();

bool ConfirmPreviousSelection();
void BeginEditing();
bool ConfirmPreviousSelection(); // deprecated
bool ReopenPreviousSegment();
bool ClearPreviousSegment();
bool ReopenPreviousSelection();
Expand Down
5 changes: 3 additions & 2 deletions src/rime/gear/editor.cc
Expand Up @@ -123,7 +123,8 @@ bool Editor::CommitComposition(Context* ctx) {
}

bool Editor::RevertLastEdit(Context* ctx) {
// different behavior in regard to previous operation type
// revert last selection or delete last input character
// depending on recent operation type
ctx->ReopenPreviousSelection() ||
(ctx->PopInput() && ctx->ReopenPreviousSegment());
return true;
Expand Down Expand Up @@ -181,7 +182,7 @@ ProcessResult Editor::DirectCommit(Context* ctx, int ch) {

ProcessResult Editor::AddToInput(Context* ctx, int ch) {
ctx->PushInput(ch);
ctx->ConfirmPreviousSelection();
ctx->BeginEditing();
return kAccepted;
}

Expand Down
2 changes: 1 addition & 1 deletion src/rime/gear/navigator.cc
Expand Up @@ -123,7 +123,7 @@ bool Navigator::End(Context* ctx) {
}

void Navigator::BeginMove(Context* ctx) {
ctx->ConfirmPreviousSelection();
ctx->BeginEditing();
// update spans
if (input_ != ctx->input() || ctx->caret_pos() > spans_.end()) {
input_ = ctx->input();
Expand Down
3 changes: 1 addition & 2 deletions src/rime/gear/speller.cc
Expand Up @@ -121,8 +121,7 @@ ProcessResult Speller::ProcessKeyEvent(const KeyEvent& key_event) {
}
DLOG(INFO) << "add to input: '" << (char)ch << "', " << key_event.repr();
ctx->PushInput(ch);
ctx->ConfirmPreviousSelection(); // so that next BackSpace won't revert
// previous selection
ctx->BeginEditing();
if (AutoSelectPreviousMatch(ctx, &previous_segment)) {
DLOG(INFO) << "auto-select previous match.";
// after auto-selecting, if only the current non-initial key is left,
Expand Down

0 comments on commit 8b7f6b7

Please sign in to comment.