feat: support candidate comments
This commit is contained in:
parent
460e563d85
commit
da1b6e3c69
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
26
src/arif.c
26
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;
|
||||
|
|
Loading…
Reference in New Issue