updated for version 7.3.052
Problem: When 'completefunc' opens a new window all kinds of errors follow.
(Xavier Deguillard)
Solution: When 'completefunc' goes to another window or buffer and when it
deletes text abort completion. Add a test for 'completefunc'.
diff --git a/src/edit.c b/src/edit.c
index 04a17eb..0bcc9db 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -58,6 +58,10 @@
};
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
/*
* Structure used to store one match for insert completion.
@@ -3833,6 +3837,8 @@
char_u *args[2];
char_u *funcname;
pos_T pos;
+ win_T *curwin_save;
+ buf_T *curbuf_save;
funcname = (type == CTRL_X_FUNCTION) ? curbuf->b_p_cfu : curbuf->b_p_ofu;
if (*funcname == NUL)
@@ -3843,13 +3849,27 @@
args[1] = base;
pos = curwin->w_cursor;
+ curwin_save = curwin;
+ curbuf_save = curbuf;
matchlist = call_func_retlist(funcname, 2, args, FALSE);
+ if (curwin_save != curwin || curbuf_save != curbuf)
+ {
+ EMSG(_(e_complwin));
+ goto theend;
+ }
curwin->w_cursor = pos; /* restore the cursor position */
- if (matchlist == NULL)
- return;
+ check_cursor();
+ if (!equalpos(curwin->w_cursor, pos))
+ {
+ EMSG(_(e_compldel));
+ goto theend;
+ }
+ if (matchlist != NULL)
+ ins_compl_add_list(matchlist);
- ins_compl_add_list(matchlist);
- list_unref(matchlist);
+theend:
+ if (matchlist != NULL)
+ list_unref(matchlist);
}
#endif /* FEAT_COMPL_FUNC */
@@ -4994,6 +5014,8 @@
int col;
char_u *funcname;
pos_T pos;
+ win_T *curwin_save;
+ buf_T *curbuf_save;
/* Call 'completefunc' or 'omnifunc' and get pattern length as a
* string */
@@ -5009,8 +5031,21 @@
args[0] = (char_u *)"1";
args[1] = NULL;
pos = curwin->w_cursor;
+ curwin_save = curwin;
+ curbuf_save = curbuf;
col = call_func_retnr(funcname, 2, args, FALSE);
+ if (curwin_save != curwin || curbuf_save != curbuf)
+ {
+ EMSG(_(e_complwin));
+ return FAIL;
+ }
curwin->w_cursor = pos; /* restore the cursor position */
+ check_cursor();
+ if (!equalpos(curwin->w_cursor, pos))
+ {
+ EMSG(_(e_compldel));
+ return FAIL;
+ }
if (col < 0)
col = curs_col;