feat: support candidate comments

This commit is contained in:
CismonX 2023-12-01 04:00:15 +08:00
parent 460e563d85
commit da1b6e3c69
Signed by: cismonx
GPG Key ID: 3094873E29A482FB
5 changed files with 77 additions and 21 deletions

View File

@ -53,10 +53,12 @@ type is defined as:
.in +4n .in +4n
.EX .EX
typedef char *(arif_cand_disp_func) ( typedef char *(arif_cand_disp_func) (
char *text, char const *text,
int len, int len,
int idx, char const *comment,
int *display_len_ptr int comment_len,
int idx,
int *display_len_ptr
); );
.EE .EE
.in .in
@ -67,6 +69,13 @@ is the candidate's text to replace the original text, and
.I len .I len
is its length in bytes. is its length in bytes.
.PP .PP
If
.I comment
is not NULL, it contains descriptive text regarding the candidate.
Argument
.I comment_len
is its length in bytes.
.PP
Argument Argument
.I idx .I idx
is the candidate's index for the current page, starting at 1. is the candidate's index for the current page, starting at 1.

View File

@ -185,13 +185,19 @@ candidates are valid until the next
call with non-NULL call with non-NULL
.IR line . .IR line .
.PP .PP
Note that the engine is not responsible for specifying the display text for a The engine is not responsible for specifying the display text for a candidate,
candidate. however, it may reuse the
The
.I display .I display
and and
.I display_len .I display_len
members of a candidate should be ignored by the caller. members to store descriptive information regarding the candidate.
This information will be passed to the display function of the input context
through the
.I comment
and
.I comment_len
arguments (see
.BR \%arif_ctx_create ()).
.PP .PP
Both Both
.I line .I line
@ -230,6 +236,7 @@ You should have received a copy of the license along with this document.
If not, see <https://www.gnu.org/licenses/fdl-1.3.html>. If not, see <https://www.gnu.org/licenses/fdl-1.3.html>.
. .
.SH SEE ALSO .SH SEE ALSO
.BR arif_ctx_create (3),
.BR arif_ctx_destroy (3), .BR arif_ctx_destroy (3),
.BR arif_fetch (3), .BR arif_fetch (3),
.BR arif_query (3) .BR arif_query (3)

View File

@ -260,25 +260,45 @@ copy_candidate (
char const *prefix, char const *prefix,
int prefix_len int prefix_len
) { ) {
RimeMenu *menu = &src->menu; RimeMenu *menu = &src->menu;
RimeComposition *composition = &src->composition;
int candidate_idx = menu->highlighted_candidate_index; int candidate_idx = menu->highlighted_candidate_index;
if (candidate_idx >= menu->page_size) { if (candidate_idx >= menu->page_size) {
return -1; return -1;
} }
char const *text = menu->candidates[candidate_idx].text; RimeCandidate *candidate = &menu->candidates[candidate_idx];
int text_len = strlen(text); RimeComposition *composition = &src->composition;
char const *text = candidate->text;
if (text == NULL) {
text = "";
}
int text_len = strlen(text);
char const *comment = candidate->comment;
if (comment == NULL) {
comment = "";
}
int comment_len = strlen(comment);
char const *line = composition->preedit; char const *line = composition->preedit;
int line_len = composition->length; int line_len = composition->length;
char *buf = malloc(text_len + prefix_len + line_len); char *buf = malloc(text_len + prefix_len + line_len + comment_len + 1);
assert(buf != NULL); assert(buf != NULL);
memcpy(buf, text, text_len); memcpy(buf, text, text_len);
memcpy(buf + text_len, prefix, prefix_len); memcpy(buf + text_len, prefix, prefix_len);
memcpy(buf + text_len + prefix_len, line, line_len); memcpy(buf + text_len + prefix_len, line, line_len);
memcpy(buf + text_len + prefix_len + line_len, comment, comment_len);
// Distinguish "no comment" from "empty comment",
// so that the frontend can handle them differently.
if (candidate->comment == NULL) {
comment = NULL;
} else {
comment = buf + text_len + line_len;
}
*dest = (struct arif_cand) { *dest = (struct arif_cand) {
.text = buf, .text = buf,
.len = text_len, .len = text_len,
@ -286,6 +306,8 @@ copy_candidate (
.replace_len = composition->sel_end - composition->sel_start, .replace_len = composition->sel_end - composition->sel_start,
.transform = buf + text_len, .transform = buf + text_len,
.transform_len = prefix_len + line_len, .transform_len = prefix_len + line_len,
.display = comment,
.display_len = comment_len,
}; };
return menu->is_last_page && candidate_idx + 1 == menu->page_size; return menu->is_last_page && candidate_idx + 1 == menu->page_size;

View File

@ -33,6 +33,8 @@ struct arif_ctx;
typedef char *(arif_cand_disp_func) ( typedef char *(arif_cand_disp_func) (
char const *text, char const *text,
int len, int len,
char const *comment,
int comment_len,
int idx, int idx,
int *display_len_ptr int *display_len_ptr
); );

View File

@ -63,7 +63,8 @@ static struct cand_page *
static int compare_text (char const *, int, char const *, int); static int compare_text (char const *, int, char const *, int);
static void copy_candidate (struct arif_cand *, struct arif_cand const *, static void copy_candidate (struct arif_cand *, struct arif_cand const *,
int, arif_cand_disp_func *); int, arif_cand_disp_func *);
static char * disp_cand_default (char const *, int, int, int *); static char * disp_cand_default (char const *, int, char const *, int,
int, int *);
static void first_candidates (struct arif_ctx *, char const *, int, int); static void first_candidates (struct arif_ctx *, char const *, int, int);
static void free_page (struct cand_page *); static void free_page (struct cand_page *);
static void free_page_list (struct cand_page *); static void free_page_list (struct cand_page *);
@ -126,7 +127,8 @@ copy_candidate (
arif_cand_disp_func *disp_cand arif_cand_disp_func *disp_cand
) { ) {
int display_len; int display_len;
char *display = disp_cand(src->text, src->len, idx + 1, &display_len); char *display = disp_cand(src->text, src->len,
src->display, src->display_len, idx + 1, &display_len);
*dest = (struct arif_cand) { *dest = (struct arif_cand) {
.text = src->text, .text = src->text,
@ -144,17 +146,31 @@ static char *
disp_cand_default ( disp_cand_default (
char const *text, char const *text,
int len, int len,
char const *comment,
int comment_len,
int idx, int idx,
int *display_len_ptr int *display_len_ptr
) { ) {
char const *fmt = "[%d] %.*s"; char const *fmt;
int display_len = snprintf(NULL, 0, fmt, idx, len, text); int display_len;
if (comment == NULL) {
fmt = "[%d] %.*s";
display_len = snprintf(NULL, 0, fmt, idx, len, text);
} else {
fmt = "[%d] %.*s (%.*s)";
display_len = snprintf(NULL, 0, fmt, idx, len, text,
comment_len, comment);
}
assert(display_len >= 0); assert(display_len >= 0);
char *disp = malloc(sizeof(char) * (display_len + 1)); char *disp = malloc(sizeof(char) * (display_len + 1));
assert(disp != NULL); assert(disp != NULL);
sprintf(disp, fmt, idx, len, text); if (comment == NULL) {
sprintf(disp, fmt, idx, len, text);
} else {
sprintf(disp, fmt, idx, len, text, comment_len, comment);
}
*display_len_ptr = display_len; *display_len_ptr = display_len;
return disp; return disp;