diff --git a/doc/arif_ctx_create.3 b/doc/arif_ctx_create.3 index 65d0814..ada77a8 100644 --- a/doc/arif_ctx_create.3 +++ b/doc/arif_ctx_create.3 @@ -53,10 +53,12 @@ type is defined as: .in +4n .EX typedef char *(arif_cand_disp_func) ( - char *text, - int len, - int idx, - int *display_len_ptr + char const *text, + int len, + char const *comment, + int comment_len, + int idx, + int *display_len_ptr ); .EE .in @@ -67,6 +69,13 @@ is the candidate's text to replace the original text, and .I len is its length in bytes. .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 .I idx is the candidate's index for the current page, starting at 1. diff --git a/doc/arif_set_engine.3 b/doc/arif_set_engine.3 index 29eca87..b34dff5 100644 --- a/doc/arif_set_engine.3 +++ b/doc/arif_set_engine.3 @@ -185,13 +185,19 @@ candidates are valid until the next call with non-NULL .IR line . .PP -Note that the engine is not responsible for specifying the display text for a -candidate. -The +The engine is not responsible for specifying the display text for a candidate, +however, it may reuse the .I display and .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 Both .I line @@ -230,6 +236,7 @@ You should have received a copy of the license along with this document. If not, see . . .SH SEE ALSO +.BR arif_ctx_create (3), .BR arif_ctx_destroy (3), .BR arif_fetch (3), .BR arif_query (3) diff --git a/examples/arif_rime.c b/examples/arif_rime.c index 7a60963..f8b245b 100644 --- a/examples/arif_rime.c +++ b/examples/arif_rime.c @@ -260,25 +260,45 @@ copy_candidate ( char const *prefix, int prefix_len ) { - RimeMenu *menu = &src->menu; - RimeComposition *composition = &src->composition; + RimeMenu *menu = &src->menu; int candidate_idx = menu->highlighted_candidate_index; if (candidate_idx >= menu->page_size) { return -1; } - char const *text = menu->candidates[candidate_idx].text; - int text_len = strlen(text); + RimeCandidate *candidate = &menu->candidates[candidate_idx]; + 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; 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); - memcpy(buf, text, text_len); - memcpy(buf + text_len, prefix, prefix_len); - memcpy(buf + text_len + prefix_len, line, line_len); + memcpy(buf, text, text_len); + memcpy(buf + text_len, prefix, prefix_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) { .text = buf, .len = text_len, @@ -286,6 +306,8 @@ copy_candidate ( .replace_len = composition->sel_end - composition->sel_start, .transform = buf + text_len, .transform_len = prefix_len + line_len, + .display = comment, + .display_len = comment_len, }; return menu->is_last_page && candidate_idx + 1 == menu->page_size; diff --git a/include/arif.h b/include/arif.h index f55c808..c7905ec 100644 --- a/include/arif.h +++ b/include/arif.h @@ -33,6 +33,8 @@ struct arif_ctx; typedef char *(arif_cand_disp_func) ( char const *text, int len, + char const *comment, + int comment_len, int idx, int *display_len_ptr ); diff --git a/src/arif.c b/src/arif.c index 48a3cca..40bdcf4 100644 --- a/src/arif.c +++ b/src/arif.c @@ -63,7 +63,8 @@ static struct cand_page * static int compare_text (char const *, int, char const *, int); static void copy_candidate (struct arif_cand *, struct arif_cand const *, 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 free_page (struct cand_page *); static void free_page_list (struct cand_page *); @@ -126,7 +127,8 @@ copy_candidate ( arif_cand_disp_func *disp_cand ) { 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) { .text = src->text, @@ -144,17 +146,31 @@ static char * disp_cand_default ( char const *text, int len, + char const *comment, + int comment_len, int idx, int *display_len_ptr ) { - char const *fmt = "[%d] %.*s"; - int display_len = snprintf(NULL, 0, fmt, idx, len, text); + char const *fmt; + 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); char *disp = malloc(sizeof(char) * (display_len + 1)); 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; return disp;