int_u char_pos = 0;
int is_select = FALSE;
- if ((hlf != HLF_PSI && hlf != HLF_PNI)
+ if (*text == NUL || (hlf != HLF_PSI && hlf != HLF_PNI)
|| (highlight_attr[HLF_PMSI] == highlight_attr[HLF_PSI]
&& highlight_attr[HLF_PMNI] == highlight_attr[HLF_PNI]))
return NULL;
if (s == NULL)
s = p;
w = ptr2cells(p);
- if (*p == NUL || *p == TAB || totwidth + w > pum_width)
+ if (*p != NUL && *p != TAB && totwidth + w <= pum_width)
{
- // Display the text that fits or comes before a Tab.
- // First convert it to printable characters.
- char_u *st;
- int *attrs = NULL;
- int saved = *p;
-
- if (saved != NUL)
- *p = NUL;
- st = transstr(s);
- if (saved != NUL)
- *p = saved;
-
- if (item_type == CPT_ABBR)
- attrs = pum_compute_text_attrs(st, hlf,
- pum_array[idx].pum_user_abbr_hlattr);
+ width += w;
+ continue;
+ }
+
+ // Display the text that fits or comes before a Tab.
+ // First convert it to printable characters.
+ char_u *st;
+ int *attrs = NULL;
+ int saved = *p;
+
+ if (saved != NUL)
+ *p = NUL;
+ st = transstr(s);
+ if (saved != NUL)
+ *p = saved;
+
+ if (item_type == CPT_ABBR)
+ attrs = pum_compute_text_attrs(st, hlf,
+ pum_array[idx].pum_user_abbr_hlattr);
#ifdef FEAT_RIGHTLEFT
- if (pum_rl)
+ if (pum_rl)
+ {
+ if (st != NULL)
{
- if (st != NULL)
+ char_u *rt = reverse_text(st);
+
+ if (rt != NULL)
{
- char_u *rt = reverse_text(st);
+ char_u *rt_start = rt;
+ int cells;
- if (rt != NULL)
+ cells = vim_strsize(rt);
+ if (cells > pum_width)
{
- char_u *rt_start = rt;
- int cells;
-
- cells = vim_strsize(rt);
- if (cells > pum_width)
+ do
{
- do
- {
- cells -= has_mbyte
+ cells -= has_mbyte
? (*mb_ptr2cells)(rt) : 1;
- MB_PTR_ADV(rt);
- } while (cells > pum_width);
-
- if (cells < pum_width)
- {
- // Most left character requires
- // 2-cells but only 1 cell is
- // available on screen. Put a
- // '<' on the left of the pum
- // item
- *(--rt) = '<';
- cells++;
- }
+ MB_PTR_ADV(rt);
+ } while (cells > pum_width);
+
+ if (cells < pum_width)
+ {
+ // Most left character requires 2-cells
+ // but only 1 cell is available on
+ // screen. Put a '<' on the left of
+ // the pum item.
+ *(--rt) = '<';
+ cells++;
}
+ }
- if (attrs == NULL)
- screen_puts_len(rt, (int)STRLEN(rt),
- row, col - cells + 1, attr);
- else
- pum_screen_puts_with_attrs(row,
+ if (attrs == NULL)
+ screen_puts_len(rt, (int)STRLEN(rt), row,
+ col - cells + 1, attr);
+ else
+ pum_screen_puts_with_attrs(row,
col - cells + 1, cells, rt,
- (int)STRLEN(rt), attrs);
+ (int)STRLEN(rt), attrs);
- vim_free(rt_start);
- }
- vim_free(st);
+ vim_free(rt_start);
}
- col -= width;
+ vim_free(st);
}
- else
+ col -= width;
+ }
+ else
#endif
+ {
+ if (st != NULL)
{
- if (st != NULL)
- {
- int size = (int)STRLEN(st);
- int cells = (*mb_string2cells)(st, size);
+ int size = (int)STRLEN(st);
+ int cells = (*mb_string2cells)(st, size);
- // only draw the text that fits
- while (size > 0
+ // only draw the text that fits
+ while (size > 0
&& col + cells > pum_width + pum_col)
+ {
+ --size;
+ if (has_mbyte)
{
- --size;
- if (has_mbyte)
- {
- size -= (*mb_head_off)(st, st + size);
- cells -= (*mb_ptr2cells)(st + size);
- }
- else
- --cells;
+ size -= (*mb_head_off)(st, st + size);
+ cells -= (*mb_ptr2cells)(st + size);
}
-
- if (attrs == NULL)
- screen_puts_len(st, size, row, col, attr);
else
- pum_screen_puts_with_attrs(row, col, cells,
+ --cells;
+ }
+
+ if (attrs == NULL)
+ screen_puts_len(st, size, row, col, attr);
+ else
+ pum_screen_puts_with_attrs(row, col, cells,
st, size, attrs);
- vim_free(st);
- }
- col += width;
+ vim_free(st);
}
+ col += width;
+ }
- if (attrs != NULL)
- VIM_CLEAR(attrs);
+ if (attrs != NULL)
+ VIM_CLEAR(attrs);
- if (*p != TAB)
- break;
+ if (*p != TAB)
+ break;
- // Display two spaces for a Tab.
+ // Display two spaces for a Tab.
#ifdef FEAT_RIGHTLEFT
- if (pum_rl)
- {
- screen_puts_len((char_u *)" ", 2, row, col - 1,
- attr);
- col -= 2;
- }
- else
-#endif
- {
- screen_puts_len((char_u *)" ", 2, row, col,
- attr);
- col += 2;
- }
- totwidth += 2;
- s = NULL; // start text at next char
- width = 0;
+ if (pum_rl)
+ {
+ screen_puts_len((char_u *)" ", 2, row, col - 1, attr);
+ col -= 2;
}
else
- width += w;
+#endif
+ {
+ screen_puts_len((char_u *)" ", 2, row, col, attr);
+ col += 2;
+ }
+ totwidth += 2;
+ s = NULL; // start text at next char
+ width = 0;
}
if (j > 0)
call StopVimInTerminal(buf)
endfunc
+func Test_pum_highlights_match_with_abbr()
+ CheckScreendump
+ let lines =<< trim END
+ func Omni_test(findstart, base)
+ if a:findstart
+ return col(".")
+ endif
+ return {
+ \ 'words': [
+ \ { 'word': 'foobar', 'abbr': "foobar\t\t!" },
+ \ { 'word': 'foobaz', 'abbr': "foobaz\t\t!" },
+ \]}
+ endfunc
+
+ set omnifunc=Omni_test
+ set completeopt=menuone,noinsert
+ hi PmenuMatchSel ctermfg=6 ctermbg=7
+ hi PmenuMatch ctermfg=4 ctermbg=225
+ END
+ call writefile(lines, 'Xscript', 'D')
+ let buf = RunVimInTerminal('-S Xscript', {})
+ call TermWait(buf)
+ call term_sendkeys(buf, "i\<C-X>\<C-O>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "foo")
+ call VerifyScreenDump(buf, 'Test_pum_highlights_19', {})
+
+ call term_sendkeys(buf, "\<C-E>\<Esc>")
+ call TermWait(buf)
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_pum_user_abbr_hlgroup()
CheckScreendump
let lines =<< trim END