mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
vim-patch:9.1.0491: Cmdline pum doesn't work properly with 'rightleft' (#29355)
Problem: Cmdline pum doesn't work properly with 'rightleft'.
Solution: Don't use curwin->w_p_rl in cmdline mode in pum_redraw(). Use
a static variable since pum_may_redraw() may be called in any
mode. Also correct position of other popups with 'rightleft'.
(zeertzjq)
closes: vim/vim#15005
883018feff
This commit is contained in:
@@ -143,7 +143,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
|
||||
|| (State == MODE_CMDLINE && ui_has(kUIWildmenu));
|
||||
}
|
||||
|
||||
pum_rl = (curwin->w_p_rl && State != MODE_CMDLINE);
|
||||
pum_rl = State != MODE_CMDLINE && curwin->w_p_rl;
|
||||
|
||||
do {
|
||||
// Mark the pum as visible already here,
|
||||
@@ -450,7 +450,7 @@ static void pum_puts_with_attr(int col, char *text, hlf_T hlf)
|
||||
}
|
||||
|
||||
char *rt_leader = NULL;
|
||||
if (curwin->w_p_rl) {
|
||||
if (pum_rl) {
|
||||
rt_leader = reverse_text(leader);
|
||||
}
|
||||
char *match_leader = rt_leader != NULL ? rt_leader : leader;
|
||||
@@ -1212,12 +1212,14 @@ void pum_set_event_info(dict_T *dict)
|
||||
static void pum_position_at_mouse(int min_width)
|
||||
{
|
||||
int min_row = 0;
|
||||
int min_col = 0;
|
||||
int max_row = Rows;
|
||||
int max_col = Columns;
|
||||
if (mouse_grid > 1) {
|
||||
win_T *wp = get_win_by_grid_handle(mouse_grid);
|
||||
if (wp != NULL) {
|
||||
min_row = -wp->w_winrow;
|
||||
min_col = -wp->w_wincol;
|
||||
max_row = MAX(Rows - wp->w_winrow, wp->w_grid.rows);
|
||||
max_col = MAX(Columns - wp->w_wincol, wp->w_grid.cols);
|
||||
}
|
||||
@@ -1230,6 +1232,7 @@ static void pum_position_at_mouse(int min_width)
|
||||
} else {
|
||||
pum_anchor_grid = mouse_grid;
|
||||
}
|
||||
|
||||
if (max_row - mouse_row > pum_size) {
|
||||
// Enough space below the mouse row.
|
||||
pum_above = false;
|
||||
@@ -1246,16 +1249,29 @@ static void pum_position_at_mouse(int min_width)
|
||||
pum_row = min_row;
|
||||
}
|
||||
}
|
||||
if (max_col - mouse_col >= pum_base_width
|
||||
|| max_col - mouse_col > min_width) {
|
||||
// Enough space to show at mouse column.
|
||||
pum_col = mouse_col;
|
||||
|
||||
if (pum_rl) {
|
||||
if (mouse_col - min_col + 1 >= pum_base_width
|
||||
|| mouse_col - min_col + 1 > min_width) {
|
||||
// Enough space to show at mouse column.
|
||||
pum_col = mouse_col;
|
||||
} else {
|
||||
// Not enough space, left align with window.
|
||||
pum_col = min_col + MIN(pum_base_width, min_width) - 1;
|
||||
}
|
||||
pum_width = pum_col - min_col + 1;
|
||||
} else {
|
||||
// Not enough space, right align with window.
|
||||
pum_col = max_col - (pum_base_width > min_width ? min_width : pum_base_width);
|
||||
if (max_col - mouse_col >= pum_base_width
|
||||
|| max_col - mouse_col > min_width) {
|
||||
// Enough space to show at mouse column.
|
||||
pum_col = mouse_col;
|
||||
} else {
|
||||
// Not enough space, right align with window.
|
||||
pum_col = max_col - MIN(pum_base_width, min_width);
|
||||
}
|
||||
pum_width = max_col - pum_col;
|
||||
}
|
||||
|
||||
pum_width = max_col - pum_col;
|
||||
if (pum_width > pum_base_width + 1) {
|
||||
pum_width = pum_base_width + 1;
|
||||
}
|
||||
@@ -1337,6 +1353,7 @@ void pum_show_popupmenu(vimmenu_T *menu)
|
||||
pum_compute_size();
|
||||
pum_scrollbar = 0;
|
||||
pum_height = pum_size;
|
||||
pum_rl = curwin->w_p_rl;
|
||||
pum_position_at_mouse(20);
|
||||
|
||||
pum_selected = -1;
|
||||
@@ -1416,7 +1433,9 @@ void pum_make_popup(const char *path_name, int use_mouse_pos)
|
||||
// Hack: set mouse position at the cursor so that the menu pops up
|
||||
// around there.
|
||||
mouse_row = curwin->w_grid.row_offset + curwin->w_wrow;
|
||||
mouse_col = curwin->w_grid.col_offset + curwin->w_wcol;
|
||||
mouse_col = curwin->w_grid.col_offset
|
||||
+ (curwin->w_p_rl ? curwin->w_width_inner - curwin->w_wcol - 1
|
||||
: curwin->w_wcol);
|
||||
if (ui_has(kUIMultigrid)) {
|
||||
mouse_grid = curwin->w_grid.target->handle;
|
||||
} else if (curwin->w_grid.target != &default_grid) {
|
||||
|
@@ -2530,6 +2530,7 @@ describe('builtin popupmenu', function()
|
||||
]],
|
||||
}
|
||||
|
||||
-- oldtest: Test_wildmenu_pum_rightleft()
|
||||
feed('<tab>')
|
||||
screen:expect {
|
||||
grid = [[
|
||||
@@ -4479,6 +4480,27 @@ describe('builtin popupmenu', function()
|
||||
|
||||
feed('<Esc>')
|
||||
|
||||
command('set rightleft')
|
||||
feed('/X<CR>:popup PopUp<CR>')
|
||||
screen:expect([[
|
||||
evif ruof eerht owt eno|
|
||||
evif ruof eerht{7:^X} owt eno dna|
|
||||
{n: odnU }wt erom eno|
|
||||
{1: }{n: }{1: ~}|
|
||||
{1: }{n: etsaP }{1: ~}|
|
||||
{1: }{n: }{1: ~}|
|
||||
{1: }{n: droW tceleS }{1: ~}|
|
||||
{1: }{n: ecnetneS tceleS }{1: ~}|
|
||||
{1: }{n: hpargaraP tceleS }{1: ~}|
|
||||
{1: }{n: eniL tceleS }{1: ~}|
|
||||
{1: }{n: kcolB tceleS }{1: ~}|
|
||||
{1: }{n: llA tceleS }{1: ~}|
|
||||
{1: ~}|*7
|
||||
:popup PopUp |
|
||||
]])
|
||||
feed('<Esc>')
|
||||
command('set norightleft')
|
||||
|
||||
-- Set an <expr> mapping to change a menu entry while it's displayed.
|
||||
-- The text should not change but the command does.
|
||||
-- Also verify that "changed" shows up, which means the mapping triggered.
|
||||
@@ -4535,6 +4557,55 @@ describe('builtin popupmenu', function()
|
||||
feed('<Esc>')
|
||||
end)
|
||||
|
||||
-- oldtest: Test_mouse_popup_position()
|
||||
it('position of right-click menu when clicking near edge', function()
|
||||
screen:try_resize(50, 20)
|
||||
exec([[
|
||||
set mousemodel=popup_setpos
|
||||
aunmenu *
|
||||
source $VIMRUNTIME/menu.vim
|
||||
call setline(1, join(range(20)))
|
||||
]])
|
||||
|
||||
api.nvim_input_mouse('right', 'press', '', 0, 0, 45 - 1)
|
||||
screen:expect([[
|
||||
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ^18 19 |
|
||||
{1:~ }{n: Undo }|
|
||||
{1:~ }{n: }|
|
||||
{1:~ }{n: Paste }|
|
||||
{1:~ }{n: }|
|
||||
{1:~ }{n: Select Word }|
|
||||
{1:~ }{n: Select Sentence }|
|
||||
{1:~ }{n: Select Paragraph}|
|
||||
{1:~ }{n: Select Line }|
|
||||
{1:~ }{n: Select Block }|
|
||||
{1:~ }{n: Select All }|
|
||||
{1:~ }|*8
|
||||
|
|
||||
]])
|
||||
feed('<Esc>')
|
||||
|
||||
command('set rightleft')
|
||||
api.nvim_input_mouse('right', 'press', '', 0, 0, 50 - 45)
|
||||
screen:expect([[
|
||||
91 8^1 71 61 51 41 31 21 11 01 9 8 7 6 5 4 3 2 1 0|
|
||||
{n: odnU }{1: ~}|
|
||||
{n: }{1: ~}|
|
||||
{n: etsaP }{1: ~}|
|
||||
{n: }{1: ~}|
|
||||
{n: droW tceleS }{1: ~}|
|
||||
{n: ecnetneS tceleS }{1: ~}|
|
||||
{n:hpargaraP tceleS }{1: ~}|
|
||||
{n: eniL tceleS }{1: ~}|
|
||||
{n: kcolB tceleS }{1: ~}|
|
||||
{n: llA tceleS }{1: ~}|
|
||||
{1: ~}|*8
|
||||
|
|
||||
]])
|
||||
feed('<Esc>')
|
||||
command('set norightleft')
|
||||
end)
|
||||
|
||||
describe('"kind" and "menu"', function()
|
||||
before_each(function()
|
||||
screen:try_resize(30, 8)
|
||||
|
@@ -2905,6 +2905,24 @@ func Test_wildmenu_pum_odd_wildchar()
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
" Test that 'rightleft' should not affect cmdline completion popup menu.
|
||||
func Test_wildmenu_pum_rightleft()
|
||||
CheckFeature rightleft
|
||||
CheckScreendump
|
||||
|
||||
let lines =<< trim END
|
||||
set wildoptions=pum
|
||||
set rightleft
|
||||
END
|
||||
call writefile(lines, 'Xwildmenu_pum_rl', 'D')
|
||||
let buf = RunVimInTerminal('-S Xwildmenu_pum_rl', #{rows: 10, cols: 50})
|
||||
|
||||
call term_sendkeys(buf, ":sign \<Tab>")
|
||||
call VerifyScreenDump(buf, 'Test_wildmenu_pum_rl', {})
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
" Test for completion after a :substitute command followed by a pipe (|)
|
||||
" character
|
||||
func Test_cmdline_complete_substitute()
|
||||
|
@@ -910,6 +910,13 @@ func Test_popup_command_dump()
|
||||
|
||||
call term_sendkeys(buf, "\<Esc>")
|
||||
|
||||
if has('rightleft')
|
||||
call term_sendkeys(buf, ":set rightleft\<CR>")
|
||||
call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>")
|
||||
call VerifyScreenDump(buf, 'Test_popup_command_rl', {})
|
||||
call term_sendkeys(buf, "\<Esc>:set norightleft\<CR>")
|
||||
endif
|
||||
|
||||
" Set a timer to change a menu entry while it's displayed. The text should
|
||||
" not change but the command does. Making the screendump also verifies that
|
||||
" "changed" shows up, which means the timer triggered.
|
||||
@@ -932,6 +939,37 @@ func Test_popup_command_dump()
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
" Test position of right-click menu when clicking near window edge.
|
||||
func Test_mouse_popup_position()
|
||||
CheckFeature menu
|
||||
CheckScreendump
|
||||
|
||||
let script =<< trim END
|
||||
set mousemodel=popup_setpos
|
||||
source $VIMRUNTIME/menu.vim
|
||||
call setline(1, join(range(20)))
|
||||
func Trigger(col)
|
||||
call test_setmouse(1, a:col)
|
||||
call feedkeys("\<RightMouse>", 't')
|
||||
endfunc
|
||||
END
|
||||
call writefile(script, 'XmousePopupPosition', 'D')
|
||||
let buf = RunVimInTerminal('-S XmousePopupPosition', #{rows: 20, cols: 50})
|
||||
|
||||
call term_sendkeys(buf, ":call Trigger(45)\<CR>")
|
||||
call VerifyScreenDump(buf, 'Test_mouse_popup_position_01', {})
|
||||
call term_sendkeys(buf, "\<Esc>")
|
||||
|
||||
if has('rightleft')
|
||||
call term_sendkeys(buf, ":set rightleft\<CR>")
|
||||
call term_sendkeys(buf, ":call Trigger(50 + 1 - 45)\<CR>")
|
||||
call VerifyScreenDump(buf, 'Test_mouse_popup_position_02', {})
|
||||
call term_sendkeys(buf, "\<Esc>:set norightleft\<CR>")
|
||||
endif
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_popup_complete_backwards()
|
||||
new
|
||||
call setline(1, ['Post', 'Port', 'Po'])
|
||||
|
Reference in New Issue
Block a user