From 6ad84ab3e48d9490e4139df04f2c55b136f5501d Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Fri, 31 Dec 2021 12:59:53 +0000 Subject: [PATCH] patch 8.2.3953: insert completion code is too complicated Problem: Insert completion code is too complicated. Solution: More refactoring. Move function arguments into a struct. (Yegappan Lakshmanan, closes #9437) --- src/insexpand.c | 196 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 107 insertions(+), 89 deletions(-) diff --git a/src/insexpand.c b/src/insexpand.c index 66a836e..3b4d530 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -407,6 +407,111 @@ ins_compl_accept_char(int c) } /* + * Get the completed text by inferring the case of the originally typed text. + */ + static char_u * +ins_compl_infercase_gettext( + char_u *str, + int actual_len, + int actual_compl_length, + int min_len) +{ + int *wca; // Wide character array. + char_u *p; + int i, c; + int has_lower = FALSE; + int was_letter = FALSE; + + IObuff[0] = NUL; + + // Allocate wide character array for the completion and fill it. + wca = ALLOC_MULT(int, actual_len); + if (wca == NULL) + return IObuff; + + p = str; + for (i = 0; i < actual_len; ++i) + if (has_mbyte) + wca[i] = mb_ptr2char_adv(&p); + else + wca[i] = *(p++); + + // Rule 1: Were any chars converted to lower? + p = compl_orig_text; + for (i = 0; i < min_len; ++i) + { + if (has_mbyte) + c = mb_ptr2char_adv(&p); + else + c = *(p++); + if (MB_ISLOWER(c)) + { + has_lower = TRUE; + if (MB_ISUPPER(wca[i])) + { + // Rule 1 is satisfied. + for (i = actual_compl_length; i < actual_len; ++i) + wca[i] = MB_TOLOWER(wca[i]); + break; + } + } + } + + // Rule 2: No lower case, 2nd consecutive letter converted to + // upper case. + if (!has_lower) + { + p = compl_orig_text; + for (i = 0; i < min_len; ++i) + { + if (has_mbyte) + c = mb_ptr2char_adv(&p); + else + c = *(p++); + if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i])) + { + // Rule 2 is satisfied. + for (i = actual_compl_length; i < actual_len; ++i) + wca[i] = MB_TOUPPER(wca[i]); + break; + } + was_letter = MB_ISLOWER(c) || MB_ISUPPER(c); + } + } + + // Copy the original case of the part we typed. + p = compl_orig_text; + for (i = 0; i < min_len; ++i) + { + if (has_mbyte) + c = mb_ptr2char_adv(&p); + else + c = *(p++); + if (MB_ISLOWER(c)) + wca[i] = MB_TOLOWER(wca[i]); + else if (MB_ISUPPER(c)) + wca[i] = MB_TOUPPER(wca[i]); + } + + // Generate encoding specific output from wide character array. + // Multi-byte characters can occupy up to five bytes more than + // ASCII characters, and we also need one byte for NUL, so stay + // six bytes away from the edge of IObuff. + p = IObuff; + i = 0; + while (i < actual_len && (p - IObuff + 6) < IOSIZE) + if (has_mbyte) + p += (*mb_char2bytes)(wca[i++], p); + else + *(p++) = wca[i++]; + *p = NUL; + + vim_free(wca); + + return IObuff; +} + +/* * This is like ins_compl_add(), but if 'ic' and 'inf' are set, then the * case of the originally typed text is used, and the case of the completed * text is inferred, ie this tries to work out what case you probably wanted @@ -423,13 +528,9 @@ ins_compl_add_infercase( { char_u *str = str_arg; char_u *p; - int i, c; int actual_len; // Take multi-byte characters int actual_compl_length; // into account. int min_len; - int *wca; // Wide character array. - int has_lower = FALSE; - int was_letter = FALSE; int flags = 0; if (p_ic && curbuf->b_p_inf && len > 0) @@ -469,91 +570,8 @@ ins_compl_add_infercase( min_len = actual_len < actual_compl_length ? actual_len : actual_compl_length; - // Allocate wide character array for the completion and fill it. - wca = ALLOC_MULT(int, actual_len); - if (wca != NULL) - { - p = str; - for (i = 0; i < actual_len; ++i) - if (has_mbyte) - wca[i] = mb_ptr2char_adv(&p); - else - wca[i] = *(p++); - - // Rule 1: Were any chars converted to lower? - p = compl_orig_text; - for (i = 0; i < min_len; ++i) - { - if (has_mbyte) - c = mb_ptr2char_adv(&p); - else - c = *(p++); - if (MB_ISLOWER(c)) - { - has_lower = TRUE; - if (MB_ISUPPER(wca[i])) - { - // Rule 1 is satisfied. - for (i = actual_compl_length; i < actual_len; ++i) - wca[i] = MB_TOLOWER(wca[i]); - break; - } - } - } - - // Rule 2: No lower case, 2nd consecutive letter converted to - // upper case. - if (!has_lower) - { - p = compl_orig_text; - for (i = 0; i < min_len; ++i) - { - if (has_mbyte) - c = mb_ptr2char_adv(&p); - else - c = *(p++); - if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i])) - { - // Rule 2 is satisfied. - for (i = actual_compl_length; i < actual_len; ++i) - wca[i] = MB_TOUPPER(wca[i]); - break; - } - was_letter = MB_ISLOWER(c) || MB_ISUPPER(c); - } - } - - // Copy the original case of the part we typed. - p = compl_orig_text; - for (i = 0; i < min_len; ++i) - { - if (has_mbyte) - c = mb_ptr2char_adv(&p); - else - c = *(p++); - if (MB_ISLOWER(c)) - wca[i] = MB_TOLOWER(wca[i]); - else if (MB_ISUPPER(c)) - wca[i] = MB_TOUPPER(wca[i]); - } - - // Generate encoding specific output from wide character array. - // Multi-byte characters can occupy up to five bytes more than - // ASCII characters, and we also need one byte for NUL, so stay - // six bytes away from the edge of IObuff. - p = IObuff; - i = 0; - while (i < actual_len && (p - IObuff + 6) < IOSIZE) - if (has_mbyte) - p += (*mb_char2bytes)(wca[i++], p); - else - *(p++) = wca[i++]; - *p = NUL; - - vim_free(wca); - } - - str = IObuff; + str = ins_compl_infercase_gettext(str, actual_len, actual_compl_length, + min_len); } if (cont_s_ipos) flags |= CP_CONT_S_IPOS; -- 1.8.3.1