Fixes this bug: When 'rightleft' is set the completion menu is positioned wrong. (Baha-Eddine MOKADEM) Additionally, the menu is changed such that the completion suggestions are shown in 'rightleft' style when 'rightleft' is set. This makes it more user-friendly, because the suggestions look like they do in the window. The patch is rather big, as a lot of corner cases wrt. positioning needs to be taken care of and because the 'rightleft' menu style is completely new functionality. Created by Martin Toft during Google Summer of Code 2007. Index: src/popupmnu.c =================================================================== RCS file: /cvsroot/vim/vim7/src/popupmnu.c,v retrieving revision 1.8 diff -c -r1.8 popupmnu.c *** src/popupmnu.c 28 Jun 2007 19:33:43 -0000 1.8 --- src/popupmnu.c 31 Jul 2007 20:24:41 -0000 *************** *** 75,81 **** row = curwin->w_cline_row + W_WINROW(curwin); height = curwin->w_cline_height; - col = curwin->w_wcol + W_WINCOL(curwin) - curwin->w_leftcol; if (firstwin->w_p_pvw) top_clear = firstwin->w_height; --- 75,80 ---- *************** *** 167,172 **** --- 166,180 ---- pum_base_width = max_width; pum_kind_width = kind_width; + /* Calculate column */ + #ifdef FEAT_RIGHTLEFT + if (curwin->w_p_rl) + col = W_WINCOL(curwin) + W_WIDTH(curwin) - curwin->w_wcol - + curwin->w_leftcol - 1; + else + #endif + col = W_WINCOL(curwin) + curwin->w_wcol - curwin->w_leftcol; + /* if there are more items than room we need a scrollbar */ if (pum_height < size) { *************** *** 179,189 **** if (def_width < max_width) def_width = max_width; ! if (col < Columns - PUM_DEF_WIDTH || col < Columns - max_width) { /* align pum column with "col" */ pum_col = col; ! pum_width = Columns - pum_col - pum_scrollbar; if (pum_width > max_width + kind_width + extra_width + 1 && pum_width > PUM_DEF_WIDTH) { --- 187,209 ---- if (def_width < max_width) def_width = max_width; ! if ((col < Columns - PUM_DEF_WIDTH || col < Columns - max_width) ! #ifdef FEAT_RIGHTLEFT ! && !curwin->w_p_rl ! || (curwin->w_p_rl && (col > PUM_DEF_WIDTH || col > max_width)) ! #endif ! ) { /* align pum column with "col" */ pum_col = col; ! ! #ifdef FEAT_RIGHTLEFT ! if (curwin->w_p_rl) ! pum_width = pum_col - pum_scrollbar + 1; ! else ! #endif ! pum_width = Columns - pum_col - pum_scrollbar; ! if (pum_width > max_width + kind_width + extra_width + 1 && pum_width > PUM_DEF_WIDTH) { *************** *** 195,208 **** else if (Columns < def_width) { /* not enough room, will use what we have */ ! pum_col = 0; pum_width = Columns - 1; } else { if (max_width > PUM_DEF_WIDTH) max_width = PUM_DEF_WIDTH; /* truncate */ ! pum_col = Columns - max_width; pum_width = max_width - pum_scrollbar; } --- 215,238 ---- else if (Columns < def_width) { /* not enough room, will use what we have */ ! #ifdef FEAT_RIGHTLEFT ! if (curwin->w_p_rl) ! pum_col = Columns - 1; ! else ! #endif ! pum_col = 0; pum_width = Columns - 1; } else { if (max_width > PUM_DEF_WIDTH) max_width = PUM_DEF_WIDTH; /* truncate */ ! #ifdef FEAT_RIGHTLEFT ! if (curwin->w_p_rl) ! pum_col = max_width - 1; ! else ! #endif ! pum_col = Columns - max_width; pum_width = max_width - pum_scrollbar; } *************** *** 255,262 **** attr = (idx == pum_selected) ? attr_select : attr_norm; /* prepend a space if there is room */ ! if (pum_col > 0) ! screen_putchar(' ', row, pum_col - 1, attr); /* Display each entry, use two spaces for a Tab. * Do this 3 times: For the main text, kind and extra info */ --- 285,300 ---- attr = (idx == pum_selected) ? attr_select : attr_norm; /* prepend a space if there is room */ ! #ifdef FEAT_RIGHTLEFT ! if (curwin->w_p_rl) ! { ! if (pum_col < W_WINCOL(curwin) + W_WIDTH(curwin) - 1) ! screen_putchar(' ', row, pum_col + 1, attr); ! } ! else ! #endif ! if (pum_col > 0) ! screen_putchar(' ', row, pum_col - 1, attr); /* Display each entry, use two spaces for a Tab. * Do this 3 times: For the main text, kind and extra info */ *************** *** 282,307 **** { /* Display the text that fits or comes before a Tab. * First convert it to printable characters. */ ! char_u *st; ! int saved = *p; *p = NUL; st = transstr(s); *p = saved; ! if (st != NULL) { ! screen_puts_len(st, (int)STRLEN(st), row, col, attr); ! vim_free(st); } - col += width; if (*p != TAB) break; /* Display two spaces for a Tab. */ ! screen_puts_len((char_u *)" ", 2, row, col, attr); ! col += 2; totwidth += 2; s = NULL; /* start text at next char */ width = 0; --- 320,385 ---- { /* Display the text that fits or comes before a Tab. * First convert it to printable characters. */ ! char_u *st, *rt, *rt_saved; ! int len, j; ! int saved = *p; *p = NUL; st = transstr(s); *p = saved; ! #ifdef FEAT_RIGHTLEFT ! if (curwin->w_p_rl) ! { ! if (st != NULL) ! { ! rt = (char_u *)reverse_text(st); ! rt_saved = rt; ! if (rt != NULL) ! { ! len = STRLEN(rt); ! if (len > pum_width) ! { ! for (j = pum_width; j < len; ++j) ! mb_ptr_adv(rt); ! len = pum_width; ! } ! screen_puts_len(rt, len, row, ! col - len + 1, attr); ! vim_free(rt_saved); ! } ! vim_free(st); ! } ! col -= width; ! } ! else ! #endif { ! if (st != NULL) ! { ! screen_puts_len(st, (int)STRLEN(st), row, col, attr); ! vim_free(st); ! } ! col += width; } if (*p != TAB) break; /* Display two spaces for a Tab. */ ! #ifdef FEAT_RIGHTLEFT ! if (curwin->w_p_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; *************** *** 322,337 **** && pum_array[idx].pum_extra == NULL) || pum_base_width + n >= pum_width) break; ! screen_fill(row, row + 1, col, pum_col + pum_base_width + n, ' ', ' ', attr); ! col = pum_col + pum_base_width + n; totwidth = pum_base_width + n; } ! screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ', attr); if (pum_scrollbar > 0) ! screen_putchar(' ', row, pum_col + pum_width, ! i >= thumb_pos && i < thumb_pos + thumb_heigth ? attr_thumb : attr_scroll); ++row; --- 400,440 ---- && pum_array[idx].pum_extra == NULL) || pum_base_width + n >= pum_width) break; ! #ifdef FEAT_RIGHTLEFT ! if (curwin->w_p_rl) ! { ! screen_fill(row, row + 1, pum_col - pum_base_width - n + 1, ! col + 1, ' ', ' ', attr); ! col = pum_col - pum_base_width - n + 1; ! } ! else ! #endif ! { ! screen_fill(row, row + 1, col, pum_col + pum_base_width + n, ' ', ' ', attr); ! col = pum_col + pum_base_width + n; ! } totwidth = pum_base_width + n; } ! #ifdef FEAT_RIGHTLEFT ! if (curwin->w_p_rl) ! screen_fill(row, row + 1, pum_col - pum_width + 1, col + 1, ' ', ! ' ', attr); ! else ! #endif ! screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ', ! attr); if (pum_scrollbar > 0) ! #ifdef FEAT_RIGHTLEFT ! if (curwin->w_p_rl) ! screen_putchar(' ', row, pum_col - pum_width, ! i >= thumb_pos && i < thumb_pos + thumb_heigth ! ? attr_thumb : attr_scroll); ! else ! #endif ! screen_putchar(' ', row, pum_col + pum_width, ! i >= thumb_pos && i < thumb_pos + thumb_heigth ? attr_thumb : attr_scroll); ++row; Index: src/search.c =================================================================== RCS file: /cvsroot/vim/vim7/src/search.c,v retrieving revision 1.59 diff -c -r1.59 search.c *** src/search.c 10 Jul 2007 11:28:36 -0000 1.59 --- src/search.c 31 Jul 2007 20:24:46 -0000 *************** *** 101,107 **** static char_u *mr_pattern = NULL; /* pattern used by search_regcomp() */ #ifdef FEAT_RIGHTLEFT static int mr_pattern_alloced = FALSE; /* mr_pattern was allocated */ ! static char_u *reverse_text __ARGS((char_u *s)); #endif #ifdef FEAT_FIND_ID --- 101,107 ---- static char_u *mr_pattern = NULL; /* pattern used by search_regcomp() */ #ifdef FEAT_RIGHTLEFT static int mr_pattern_alloced = FALSE; /* mr_pattern was allocated */ ! char_u *reverse_text __ARGS((char_u *s)); #endif #ifdef FEAT_FIND_ID *************** *** 233,239 **** * Reverse text into allocated memory. * Returns the allocated string, NULL when out of memory. */ ! static char_u * reverse_text(s) char_u *s; { --- 233,239 ---- * Reverse text into allocated memory. * Returns the allocated string, NULL when out of memory. */ ! char_u * reverse_text(s) char_u *s; { *************** *** 1898,1904 **** } #ifdef FEAT_RIGHTLEFT ! /* This is just guessing: when 'rightleft' is set, search for a maching * paren/brace in the other direction. */ if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL) backwards = !backwards; --- 1898,1904 ---- } #ifdef FEAT_RIGHTLEFT ! /* This is just guessing: when 'rightleft' is set, search for a matching * paren/brace in the other direction. */ if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL) backwards = !backwards;