Compare commits

...

3 Commits

Author SHA1 Message Date
Bram Moolenaar
92e5df8047 patch 8.2.2428: FocusGained does not work when 'ttymouse' is empty
Problem:    FocusGained does not work when 'ttymouse' is empty.
Solution:   Don't use the short mouse code if there is a longer matching code.
            (closes #7755)  Add a test.
2021-01-30 15:39:47 +01:00
Bram Moolenaar
3eb6bd9c2b patch 8.2.2427: can still switch windows for 'completefunc'
Problem:    Can still switch windows for 'completefunc'.
Solution:   Also disallow switching windows for other completions.
2021-01-29 21:47:24 +01:00
Bram Moolenaar
28976e2acc patch 8.2.2426: allowing 'completefunc' to switch windows causes trouble
Problem:    Allowing 'completefunc' to switch windows causes trouble.
Solution:   use "textwinlock" instead of "textlock".
2021-01-29 21:07:07 +01:00
6 changed files with 81 additions and 50 deletions

View File

@@ -121,7 +121,6 @@ struct compl_S
static char e_hitend[] = N_("Hit end of paragraph");
# ifdef FEAT_COMPL_FUNC
static char e_complwin[] = N_("E839: Completion function changed window");
static char e_compldel[] = N_("E840: Completion function deleted text");
# endif
@@ -2199,8 +2198,6 @@ expand_by_function(
typval_T args[3];
char_u *funcname;
pos_T pos;
win_T *curwin_save;
buf_T *curbuf_save;
typval_T rettv;
int save_State = State;
@@ -2216,11 +2213,10 @@ expand_by_function(
args[2].v_type = VAR_UNKNOWN;
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
// Lock the text to avoid weird things from happening. Do allow switching
// to another window temporarily.
++textlock;
// Lock the text to avoid weird things from happening. Also disallow
// switching to another window, it should not be needed and may end up in
// Insert mode in another buffer.
++textwinlock;
// Call a function, which returns a list or dict.
if (call_vim_function(funcname, 2, args, &rettv) == OK)
@@ -2243,13 +2239,8 @@ expand_by_function(
break;
}
}
--textlock;
--textwinlock;
if (curwin_save != curwin || curbuf_save != curbuf)
{
emsg(_(e_complwin));
goto theend;
}
curwin->w_cursor = pos; // restore the cursor position
validate_cursor();
if (!EQUAL_POS(curwin->w_cursor, pos))
@@ -3226,7 +3217,7 @@ ins_compl_next(
return -1;
if (compl_leader != NULL
&& (compl_shown_match->cp_flags & CP_ORIGINAL_TEXT) == 0)
&& (compl_shown_match->cp_flags & CP_ORIGINAL_TEXT) == 0)
{
// Set "compl_shown_match" to the actually shown match, it may differ
// when "compl_leader" is used to omit some of the matches.
@@ -3842,8 +3833,6 @@ ins_complete(int c, int enable_pum)
int col;
char_u *funcname;
pos_T pos;
win_T *curwin_save;
buf_T *curbuf_save;
int save_State = State;
// Call 'completefunc' or 'omnifunc' and get pattern length as a
@@ -3865,16 +3854,11 @@ ins_complete(int c, int enable_pum)
args[1].vval.v_string = (char_u *)"";
args[2].v_type = VAR_UNKNOWN;
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
++textwinlock;
col = call_func_retnr(funcname, 2, args);
--textwinlock;
State = save_State;
if (curwin_save != curwin || curbuf_save != curbuf)
{
emsg(_(e_complwin));
return FAIL;
}
curwin->w_cursor = pos; // restore the cursor position
validate_cursor();
if (!EQUAL_POS(curwin->w_cursor, pos))

View File

@@ -5339,6 +5339,8 @@ check_termcode(
else
#endif // FEAT_GUI
{
int mouse_index_found = -1;
for (idx = 0; idx < tc_len; ++idx)
{
/*
@@ -5376,9 +5378,24 @@ check_termcode(
}
}
key_name[0] = termcodes[idx].name[0];
key_name[1] = termcodes[idx].name[1];
break;
// The mouse termcode "ESC [" is also the prefix of
// "ESC [ I" (focus gained). Only use it when there is
// no other match. Do use it when a digit is following to
// avoid waiting for more bytes.
if (slen == 2 && len > 2
&& termcodes[idx].code[0] == ESC
&& termcodes[idx].code[1] == '['
&& !isdigit(tp[2]))
{
if (mouse_index_found < 0)
mouse_index_found = idx;
}
else
{
key_name[0] = termcodes[idx].name[0];
key_name[1] = termcodes[idx].name[1];
break;
}
}
/*
@@ -5389,7 +5406,7 @@ check_termcode(
* When there is a modifier the * matches a number.
* When there is no modifier the ;* or * is omitted.
*/
if (termcodes[idx].modlen > 0)
if (termcodes[idx].modlen > 0 && mouse_index_found < 0)
{
int at_code;
@@ -5442,6 +5459,11 @@ check_termcode(
}
}
}
if (idx == tc_len && mouse_index_found >= 0)
{
key_name[0] = termcodes[mouse_index_found].name[0];
key_name[1] = termcodes[mouse_index_found].name[1];
}
}
#ifdef FEAT_TERMRESPONSE

View File

@@ -548,7 +548,7 @@ func Test_completefunc_error()
endfunc
set completefunc=CompleteFunc
call setline(1, ['', 'abcd', ''])
call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E840:')
call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E578:')
" delete text when called for the second time
func CompleteFunc2(findstart, base)
@@ -562,31 +562,24 @@ func Test_completefunc_error()
call setline(1, ['', 'abcd', ''])
call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E578:')
set completefunc&
delfunc CompleteFunc
delfunc CompleteFunc2
close!
endfunc
func Test_completefunc_error_not_asan()
" The following test causes an ASAN failure.
CheckNotAsan
" Jump to a different window from the complete function
func! CompleteFunc(findstart, base)
func CompleteFunc3(findstart, base)
if a:findstart == 1
return col('.') - 1
endif
wincmd p
return ['a', 'b']
endfunc
set completefunc=CompleteFunc
set completefunc=CompleteFunc3
new
call assert_fails('exe "normal a\<C-X>\<C-U>"', 'E839:')
call assert_fails('exe "normal a\<C-X>\<C-U>"', 'E565:')
close!
set completefunc&
delfunc CompleteFunc
delfunc CompleteFunc2
delfunc CompleteFunc3
close!
endfunc
" Test for returning non-string values from 'completefunc'

View File

@@ -342,7 +342,7 @@ func Test_completefunc_opens_new_window_one()
setlocal completefunc=DummyCompleteOne
call setline(1, 'one')
/^one
call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E578:')
call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:')
call assert_equal(winid, win_getid())
call assert_equal('onedef', getline(1))
q!
@@ -367,11 +367,9 @@ func Test_completefunc_opens_new_window_two()
setlocal completefunc=DummyCompleteTwo
call setline(1, 'two')
/^two
call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E839:')
call assert_notequal(winid, win_getid())
q!
call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:')
call assert_equal(winid, win_getid())
call assert_equal('two', getline(1))
call assert_equal('twodef', getline(1))
q!
endfunc
@@ -642,8 +640,8 @@ func Test_complete_func_mess()
set completefunc=MessComplete
new
call setline(1, 'Ju')
call feedkeys("A\<c-x>\<c-u>/\<esc>", 'tx')
call assert_equal('Oct/Oct', getline(1))
call assert_fails('call feedkeys("A\<c-x>\<c-u>/\<esc>", "tx")', 'E578:')
call assert_equal('Jan/', getline(1))
bwipe!
set completefunc=
endfunc

View File

@@ -1868,6 +1868,34 @@ func Test_xx07_xterm_response()
call test_override('term_props', 0)
endfunc
func Test_focus_events()
let save_term = &term
let save_ttymouse = &ttymouse
set term=xterm ttymouse=xterm2
au FocusGained * let g:focus_gained += 1
au FocusLost * let g:focus_lost += 1
let g:focus_gained = 0
let g:focus_lost = 0
call feedkeys("\<Esc>[O", "Lx!")
call assert_equal(1, g:focus_lost)
call feedkeys("\<Esc>[I", "Lx!")
call assert_equal(1, g:focus_gained)
" still works when 'ttymouse' is empty
set ttymouse=
call feedkeys("\<Esc>[O", "Lx!")
call assert_equal(2, g:focus_lost)
call feedkeys("\<Esc>[I", "Lx!")
call assert_equal(2, g:focus_gained)
au! FocusGained
au! FocusLost
let &term = save_term
let &ttymouse = save_ttymouse
endfunc
func Test_get_termcode()
try
let k1 = &t_k1
@@ -2261,7 +2289,7 @@ func Test_cmdline_literal()
endfunc
" Test for translation of special key codes (<xF1>, <xF2>, etc.)
func Test_Keycode_Tranlsation()
func Test_Keycode_Translation()
let keycodes = [
\ ["<xUp>", "<Up>"],
\ ["<xDown>", "<Down>"],

View File

@@ -750,6 +750,12 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2428,
/**/
2427,
/**/
2426,
/**/
2425,
/**/