diff options
Diffstat (limited to 'src/popupmenu.c')
-rw-r--r-- | src/popupmenu.c | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/src/popupmenu.c b/src/popupmenu.c index 01b6ab1e95..00b0006181 100644 --- a/src/popupmenu.c +++ b/src/popupmenu.c @@ -417,6 +417,88 @@ pum_under_menu(int row, int col, int only_redrawing) } /* + * displays text on the popup menu with specific attributes. + */ + static void +pum_screen_put_with_attr(int row, int col, char_u *text, int textlen, int attr) +{ + int i; + int leader_len; + int char_len; + int cells; + int new_attr; + char_u *rt_leader = NULL; + char_u *match_leader = NULL; + char_u *ptr = text; + garray_T *ga = NULL; + char_u *leader = ins_compl_leader(); + int in_fuzzy = (get_cot_flags() & COT_FUZZY) != 0; + + if ((highlight_attr[HLF_PMSI] == highlight_attr[HLF_PSI] && + highlight_attr[HLF_PMNI] == highlight_attr[HLF_PNI])) + { + screen_puts_len(text, textlen, row, col, attr); + return; + } + +#ifdef FEAT_RIGHTLEFT + if (leader != NULL && curwin->w_p_rl) + rt_leader = reverse_text(leader); +#endif + match_leader = rt_leader != NULL ? rt_leader : leader; + leader_len = match_leader ? (int)STRLEN(match_leader) : 0; + + if (match_leader != NULL && leader_len > 0 && in_fuzzy) + ga = fuzzy_match_str_with_pos(text, match_leader); + + // Render text with proper attributes + while (*ptr != NUL && ptr < text + textlen) + { + char_len = mb_ptr2len(ptr); + cells = mb_ptr2cells(ptr); + new_attr = attr; + + if (ga != NULL) + { + // Handle fuzzy matching + for (i = 0; i < ga->ga_len; i++) + { + int *match_pos = ((int *)ga->ga_data) + i; + int actual_char_pos = 0; + char_u *temp_ptr = text; + while (temp_ptr < ptr) + { + temp_ptr += mb_ptr2len(temp_ptr); + actual_char_pos++; + } + if (actual_char_pos == match_pos[0]) + { + new_attr = highlight_attr[(attr == highlight_attr[HLF_PSI] + ? HLF_PMSI : HLF_PMNI)]; + break; + } + } + } + else if (!in_fuzzy && (ptr - text < leader_len) && + (STRNCMP(text, match_leader, leader_len) == 0)) + new_attr = highlight_attr[(attr == highlight_attr[HLF_PSI] + ? HLF_PMSI : HLF_PMNI)]; + + screen_puts_len(ptr, char_len, row, col, new_attr); + col += cells; + ptr += char_len; + } + + if (ga != NULL) + { + ga_clear(ga); + vim_free(ga); + } + if (rt_leader) + vim_free(rt_leader); +} + +/* * Redraw the popup menu, using "pum_first" and "pum_selected". */ void @@ -567,8 +649,7 @@ pum_redraw(void) size++; } } - screen_puts_len(rt, (int)STRLEN(rt), - row, col - size + 1, attr); + pum_screen_put_with_attr(row, col -size + 1, rt, (int)STRLEN(rt), attr); vim_free(rt_start); } vim_free(st); @@ -596,7 +677,7 @@ pum_redraw(void) else --cells; } - screen_puts_len(st, size, row, col, attr); + pum_screen_put_with_attr(row, col, st, size, attr); vim_free(st); } col += width; |