-
Notifications
You must be signed in to change notification settings - Fork 574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: delete selected candidate #556
feat: delete selected candidate #556
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the pull request.
The struct RimeApi
can only be extended from the end for backward compatibility.
Sync the repo, and then add new API functions as the last members of the struct.
I also added a few suggestions about code style.
src/rime_api.cc
Outdated
@@ -1083,6 +1083,34 @@ const char* RimeGetVersion() { | |||
return RIME_VERSION; | |||
} | |||
|
|||
Bool RimeDeleteCandidate(RimeSessionId session_id, size_t index) { | |||
an<Session> session(Service::instance().GetSession(session_id)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
avoid repeated code.
extract the common code to helper functions:
static bool do_with_candidate(RimeSessionId session_id, size_t index, bool (Context::* verb)(size_t index)) {
// ...
return (ctx->*verb)(index);
}
static bool do_with_candidate_on_current_page(RimeSessionId session_id, size_t index, bool (Context::* verb)(size_t index)) {
// ...
return (ctx->*verb)(page_start + index);
}
Then call the helper functions with &Context::Select
or &Context::Delete
in each version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry but it turns out I have trouble using this syntax. It first throw error message with
/home/runner/work/trime/trime/app/src/main/jni/librime/src/rime_api.cc:1061:25: error: called object type 'bool
(rime::Context::*)(size_t)' is not a function or function pointer
return Bool(ctx->*verb(index));
~~~~^
/home/runner/work/trime/trime/app/src/main/jni/librime/src/rime_api.cc:1083:53: error: use of undeclared identifier 'Select'; did you mean 'rime::Context::Select'?
return Bool(do_with_candidate(session_id, index, &Select));
^~~~~~
rime::Context::Select
/home/runner/work/trime/trime/app/src/main/jni/librime/src/rime/context.h:47:8: note: 'rime::Context::Select' declared here
bool Select(size_t index);
^
and then after I change &Select
to &rime::Context::Select
it throw error message:
home/runner/work/trime/trime/app/src/main/jni/librime/src/rime_api.cc:1061:25: error: called object type 'bool (rime::Context::*)(size_t)' is not a function or function pointer
return Bool(ctx->*verb(index));
~~~~^
1 error generated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pointer to member function, if I recall correctly, need to be qualified by class name, try &Context::Select
as in the original comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pointer to member function, if I recall correctly, need to be qualified by class name, try
&Context::Select
as in the original comment.
it not works either.
I have changed to
Bool RimeSelectCandidate(RimeSessionId session_id, size_t index) {
return Bool(do_with_candidate(session_id, index, &Context::Select));
}
and got error message:
home/runner/work/trime/trime/app/src/main/jni/librime/src/rime_api.cc:1061:25: error: called object type 'bool (rime::Context::*)(size_t)' is not a function or function pointer
return Bool(ctx->*verb(index));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry. It didn't work because .*
or ->*
has lower precedence than function call. So it should be written with parentheses around the expression ctx->*verb
. See also my inline comments.
src/rime_api.h
Outdated
@@ -520,6 +520,9 @@ typedef struct rime_api_t { | |||
//! select a candidate at the given index in candidate list. | |||
Bool (*select_candidate)(RimeSessionId session_id, size_t index); | |||
|
|||
//! delete a candidate at the given index in candidate list. | |||
Bool (*delete_candidate)(RimeSessionId session_id, size_t index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New API functions must be appended to the struct RimeApi
.
src/rime/context.cc
Outdated
@@ -123,6 +123,19 @@ bool Context::Select(size_t index) { | |||
return false; | |||
} | |||
|
|||
bool Context::Delete(size_t index) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name is unclear; it can be confused with deleting characters from the input.
Rename it DeleteCandidate
.
Avoid repeated code.
Introduce a private member function (overloaded)
bool Context::DeleteCandidate(function<an<Candidate> (Segment& seg)> get_candidate) {
// ...
if (auto cand = get_candidate(seg)) {
// ...
}
Then call it in each version:
bool Context::DeleteCandidate(size_t index) {
return DeleteCandidate(
[index](Segment& seg) {
return seg.GetCandidateAt(index);
});
}
bool Context::DeleteCurrentSelection() {
return DeleteCandidate(
[](Segment& seg) {
return seg.GetSelectedCandidate();
});
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, PTAL
@@ -1170,9 +1186,11 @@ RIME_API RimeApi* rime_get_api() { | |||
s_api.get_input = &RimeGetInput; | |||
s_api.get_caret_pos = &RimeGetCaretPos; | |||
s_api.select_candidate = &RimeSelectCandidate; | |||
s_api.delete_candidate = &RimeDeleteCandidate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional: reorder these to match definition in RimeApi
.
@@ -550,6 +550,11 @@ typedef struct rime_api_t { | |||
void (*commit_proto)(RimeSessionId session_id, RIME_PROTO_BUILDER* commit_builder); | |||
void (*context_proto)(RimeSessionId session_id, RIME_PROTO_BUILDER* context_builder); | |||
void (*status_proto)(RimeSessionId session_id, RIME_PROTO_BUILDER* status_builder); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge conflict. Sync the repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sync to latest code.
@@ -123,19 +123,32 @@ bool Context::Select(size_t index) { | |||
return false; | |||
} | |||
|
|||
bool Context::DeleteCurrentSelection() { | |||
bool Context::DeleteCandidate(function<an<Candidate> (Segment& seg)> get_candidate) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This memeber function should have a definition in context.h
, in the private:
or pretected:
section.
} | ||
|
||
Bool RimeSelectCandidate(RimeSessionId session_id, size_t index) { | ||
return do_with_candidate(session_id, index, Select); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer explicit conversion to the returned C type (Bool
=int
):
return Bool(do_with_candidate(...));
Prefer &Select
to make it obvious we are passing a function pointer.
an<Session> session(Service::instance().GetSession(session_id)); | ||
if (!session) | ||
return False; | ||
Context *ctx = session->context(); | ||
if (!ctx) | ||
return False; | ||
return Bool(ctx->Select(index)); | ||
return Bool(ctx->*verb(index)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a pair of parentheses around the function part (ctx->*verb)(index)
.
Remove the Bool( )
, because the return type is not Bool
.
@@ -1076,13 +1076,29 @@ Bool RimeSelectCandidateOnCurrentPage(RimeSessionId session_id, size_t index) { | |||
return False; | |||
const auto& seg(ctx->composition().back()); | |||
size_t page_start = seg.selected_index / page_size * page_size; | |||
return Bool(ctx->Select(page_start + index)); | |||
return (ctx->*verb)(page_start + index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used correctly here.
@@ -550,6 +550,11 @@ typedef struct rime_api_t { | |||
void (*commit_proto)(RimeSessionId session_id, RIME_PROTO_BUILDER* commit_builder); | |||
void (*context_proto)(RimeSessionId session_id, RIME_PROTO_BUILDER* context_builder); | |||
void (*status_proto)(RimeSessionId session_id, RIME_PROTO_BUILDER* status_builder); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sync to latest code.
src/rime_api.cc
Outdated
@@ -1083,6 +1083,34 @@ const char* RimeGetVersion() { | |||
return RIME_VERSION; | |||
} | |||
|
|||
Bool RimeDeleteCandidate(RimeSessionId session_id, size_t index) { | |||
an<Session> session(Service::instance().GetSession(session_id)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry. It didn't work because .*
or ->*
has lower precedence than function call. So it should be written with parentheses around the expression ctx->*verb
. See also my inline comments.
Ok so it turns out lacking an build environment made a mess of everything. After I managed to fix the environment, the IDE immediately pointed the mistake and fix it, and everything is working well now. This PR will be closed, and a new PR will be open to make commit tree clean. Thanks for your patience these days. |
Pull request
Issue tracker
Fixes will automatically close the related issue
Fixes #
Feature
This feature supports deleting candidate at arbitrary index, which is useful for quick deleting.
Unit test
Manual test
Code Review
Additional Info