From 0cfaa3b88f2421f040b4b4e76a16b9905d0c87c3 Mon Sep 17 00:00:00 2001 From: handa Date: Thu, 16 Nov 2006 12:07:00 +0000 Subject: [PATCH] (parse_action_list): Allow (undo 0). (adjust_markers): New function. (preedit_insert, preedit_delete): Call adjust_markers. (preedit_replace): New function. (update_candidate): Call preedit_replace instead of preedit_insert and preedit_delete. (filter): When ic_info->commit_key_head is nonzero, shift input event keys even if there's no committed text. --- src/input.c | 105 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 35 deletions(-) diff --git a/src/input.c b/src/input.c index cc07d78..7edb1f7 100644 --- a/src/input.c +++ b/src/input.c @@ -855,8 +855,7 @@ parse_action_list (MPlist *plist, MPlist *macros) if (! MPLIST_TAIL_P (pl)) { if (! MPLIST_SYMBOL_P (pl) - && (! MPLIST_INTEGER_P (pl) - || MPLIST_INTEGER (pl) == 0)) + && ! MPLIST_INTEGER_P (pl)) MERROR (MERROR_IM, -1); } } @@ -2388,22 +2387,53 @@ find_candidates_group (MPlist *plist, int index, return NULL; } +/* Adjust markers for the change of preedit text. + If FROM == TO, the change is insertion of INS chars. + If FROM < TO and INS == 0, the change is deletion of the range. + If FROM < TO and INS > 0, the change is replacement. */ + static void -preedit_insert (MInputContext *ic, int pos, MText *mt, int c) +adjust_markers (MInputContext *ic, int from, int to, int ins) { MInputContextInfo *ic_info = ((MInputContext *) ic)->info; MPlist *markers; + + if (from == to) + { + MPLIST_DO (markers, ic_info->markers) + if (MPLIST_INTEGER (markers) > from) + MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + ins); + if (ic->cursor_pos >= from) + ic->cursor_pos += ins; + } + else + { + MPLIST_DO (markers, ic_info->markers) + { + if (MPLIST_INTEGER (markers) >= to) + MPLIST_VAL (markers) + = (void *) (MPLIST_INTEGER (markers) + ins - (to - from)); + else if (MPLIST_INTEGER (markers) > from) + MPLIST_VAL (markers) = (void *) from; + } + if (ic->cursor_pos >= to) + ic->cursor_pos += ins - (to - from); + else if (ic->cursor_pos > from) + ic->cursor_pos = from; + } +} + + +static void +preedit_insert (MInputContext *ic, int pos, MText *mt, int c) +{ int nchars = mt ? mtext_nchars (mt) : 1; if (mt) mtext_ins (ic->preedit, pos, mt); else mtext_ins_char (ic->preedit, pos, c, 1); - MPLIST_DO (markers, ic_info->markers) - if (MPLIST_INTEGER (markers) > pos) - MPLIST_VAL (markers) = (void *) (MPLIST_INTEGER (markers) + nchars); - if (ic->cursor_pos >= pos) - ic->cursor_pos += nchars; + adjust_markers (ic, pos, pos, nchars); ic->preedit_changed = 1; } @@ -2411,25 +2441,32 @@ preedit_insert (MInputContext *ic, int pos, MText *mt, int c) static void preedit_delete (MInputContext *ic, int from, int to) { - MInputContextInfo *ic_info = ((MInputContext *) ic)->info; - MPlist *markers; + mtext_del (ic->preedit, from, to); + adjust_markers (ic, from, to, 0); + ic->preedit_changed = 1; +} + +static void +preedit_replace (MInputContext *ic, int from, int to, MText *mt, int c) +{ + int ins; mtext_del (ic->preedit, from, to); - MPLIST_DO (markers, ic_info->markers) - { - if (MPLIST_INTEGER (markers) > to) - MPLIST_VAL (markers) - = (void *) (MPLIST_INTEGER (markers) - (to - from)); - else if (MPLIST_INTEGER (markers) > from) - MPLIST_VAL (markers) = (void *) from; - } - if (ic->cursor_pos >= to) - ic->cursor_pos -= to - from; - else if (ic->cursor_pos > from) - ic->cursor_pos = from; + if (mt) + { + mtext_ins (ic->preedit, from, mt); + ins = mtext_nchars (mt); + } + else + { + mtext_ins_char (ic->preedit, from, c, 1); + ins = 1; + } + adjust_markers (ic, from, to, ins); ic->preedit_changed = 1; } + static void preedit_commit (MInputContext *ic) { @@ -2513,11 +2550,10 @@ update_candidate (MInputContext *ic, MTextProperty *prop, int idx) int ingroup_index = idx - start; MText *mt; - preedit_delete (ic, from, to); if (MPLIST_MTEXT_P (group)) { mt = MPLIST_MTEXT (group); - preedit_insert (ic, from, NULL, mtext_ref_char (mt, ingroup_index)); + preedit_replace (ic, from, to, NULL, mtext_ref_char (mt, ingroup_index)); to = from + 1; } else @@ -2528,7 +2564,7 @@ update_candidate (MInputContext *ic, MTextProperty *prop, int idx) for (i = 0, plist = MPLIST_PLIST (group); i < ingroup_index; i++, plist = MPLIST_NEXT (plist)); mt = MPLIST_MTEXT (plist); - preedit_insert (ic, from, mt, 0); + preedit_replace (ic, from, to, mt, 0); to = from + mtext_nchars (mt); } mtext_put_prop (ic->preedit, from, to, Mcandidate_list, candidate_list); @@ -3737,17 +3773,16 @@ filter (MInputContext *ic, MSymbol key, void *arg) if (lang != Mnil) mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced), Mlanguage, ic->im->language); - if (ic_info->commit_key_head > 0) - { - memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head, - sizeof (int) * (ic_info->used - ic_info->commit_key_head)); - ic_info->used -= ic_info->commit_key_head; - ic_info->key_head -= ic_info->commit_key_head; - ic_info->state_key_head -= ic_info->commit_key_head; - ic_info->commit_key_head = 0; - } } - + if (ic_info->commit_key_head > 0) + { + memmove (ic_info->keys, ic_info->keys + ic_info->commit_key_head, + sizeof (int) * (ic_info->used - ic_info->commit_key_head)); + ic_info->used -= ic_info->commit_key_head; + ic_info->key_head -= ic_info->commit_key_head; + ic_info->state_key_head -= ic_info->commit_key_head; + ic_info->commit_key_head = 0; + } if (ic_info->key_unhandled) { ic_info->used = 0; -- 1.7.10.4