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
.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.

View File

@ -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 <https://www.gnu.org/licenses/fdl-1.3.html>.
.
.SH SEE ALSO
.BR arif_ctx_create (3),
.BR arif_ctx_destroy (3),
.BR arif_fetch (3),
.BR arif_query (3)

View File

@ -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;

View File

@ -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
);

View File

@ -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;