Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions src/rime/gear/navigator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ Navigator::Navigator(const Ticket& ticket)
Config* config = engine_->schema()->config();
LoadConfig(config, "navigator", Horizontal);
LoadConfig(config, "navigator/vertical", Vertical);
config->GetBool("navigator/stop_before_delimiter", &stop_before_delimiter_);
if (stop_before_delimiter_) {
config->GetString("speller/delimiter", &delimiters_);
}

select_connection_ = engine_->context()->select_notifier().connect(
[this](Context* ctx) { OnSelect(ctx); });
Expand Down Expand Up @@ -120,8 +124,11 @@ bool Navigator::LeftByCharNoLoop(Context* ctx) {
bool Navigator::Rewind(Context* ctx) {
BeginMove(ctx);
// take a jump leftwards when there are multiple spans,
// but not from the middle of a span.
if (spans_.Count() > 1 && spans_.HasVertex(ctx->caret_pos())) {
// but not from the middle of a span
size_t caret_pos = ctx->caret_pos();
if (stop_before_delimiter_)
caret_pos = SkipDelimiterForward(caret_pos);
if (spans_.Count() > 1 && spans_.HasVertex(caret_pos)) {
size_t confirmed_pos = ctx->composition().GetConfirmedPosition();
JumpLeft(ctx, confirmed_pos, true);
} else {
Expand All @@ -132,7 +139,10 @@ bool Navigator::Rewind(Context* ctx) {

bool Navigator::Forward(Context* ctx) {
BeginMove(ctx);
if (spans_.Count() > 1 && spans_.HasVertex(ctx->caret_pos())) {
size_t caret_pos = SkipDelimiterForward(ctx->caret_pos());
if (stop_before_delimiter_)
caret_pos = SkipDelimiterForward(caret_pos);
if (spans_.Count() > 1 && spans_.HasVertex(caret_pos)) {
size_t confirmed_pos = ctx->composition().GetConfirmedPosition();
JumpRight(ctx, confirmed_pos, true);
} else {
Expand Down Expand Up @@ -197,6 +207,8 @@ void Navigator::BeginMove(Context* ctx) {
bool Navigator::JumpLeft(Context* ctx, size_t start_pos, bool loop) {
DLOG(INFO) << "jump left.";
size_t caret_pos = ctx->caret_pos();
if (stop_before_delimiter_)
caret_pos = SkipDelimiterForward(caret_pos);
size_t end_of_translation = spans_.end();
size_t end_of_input = ctx->input().length();
size_t new_pos =
Expand All @@ -212,6 +224,8 @@ bool Navigator::JumpLeft(Context* ctx, size_t start_pos, bool loop) {
: (std::max)(start_pos, spans_.PreviousStop(end_of_input))
// 跳至前一個切分點
: (std::max)(start_pos, spans_.PreviousStop(caret_pos));
if (stop_before_delimiter_)
new_pos = SkipDelimiterBackward(new_pos);
if (new_pos != caret_pos) {
ctx->set_caret_pos(new_pos);
return true;
Expand All @@ -222,6 +236,8 @@ bool Navigator::JumpLeft(Context* ctx, size_t start_pos, bool loop) {
bool Navigator::JumpRight(Context* ctx, size_t start_pos, bool loop) {
DLOG(INFO) << "jump right.";
size_t caret_pos = ctx->caret_pos();
if (stop_before_delimiter_)
caret_pos = SkipDelimiterForward(caret_pos);
size_t end_of_translation = spans_.end();
size_t end_of_input = ctx->input().length();
size_t new_pos =
Expand All @@ -231,6 +247,8 @@ bool Navigator::JumpRight(Context* ctx, size_t start_pos, bool loop) {
: (caret_pos >= end_of_translation) ? end_of_input
// 跳至後一個切分點
: spans_.NextStop(caret_pos);
if (stop_before_delimiter_)
new_pos = SkipDelimiterBackward(new_pos);
if (new_pos != caret_pos) {
ctx->set_caret_pos(new_pos);
return true;
Expand Down Expand Up @@ -290,4 +308,17 @@ bool Navigator::GoToEnd(Context* ctx) {
return false;
}

size_t Navigator::SkipDelimiterBackward(size_t pos) {
while (pos > 0 && delimiters_.find(input_[pos - 1]) != string::npos)
pos--;
return pos;
}

size_t Navigator::SkipDelimiterForward(size_t pos) {
while (pos < input_.length() - 1 &&
delimiters_.find(input_[pos]) != string::npos)
pos++;
return pos;
}

} // namespace rime
6 changes: 6 additions & 0 deletions src/rime/gear/navigator.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ class Navigator : public Processor, public KeyBindingProcessor<Navigator, 2> {
Spans spans_;

connection select_connection_;

private:
string delimiters_;
bool stop_before_delimiter_ = false;
size_t SkipDelimiterBackward(size_t pos);
size_t SkipDelimiterForward(size_t pos);
};

} // namespace rime
Expand Down
Loading