Compare commits

...

18 Commits

Author SHA1 Message Date
Bram Moolenaar
82846a00ac patch 8.0.1486: accessing invalid memory with "it"
Problem:    Accessing invalid memory with "it". (Dominique Pelle)
Solution:   Avoid going over the end of the line. (Christian Brabandt,
            closes #2532)
2018-02-09 18:09:54 +01:00
Bram Moolenaar
9e33efd152 patch 8.0.1485: weird autocmd may cause arglist to be changed recursively
Problem:    Weird autocmd may cause arglist to be changed recursively.
Solution:   Prevent recursively changing the argument list. (Christian
            Brabandt, closes #2472)
2018-02-09 17:50:28 +01:00
Bram Moolenaar
a15ef4588c patch 8.0.1484: reduntant conditions
Problem:    Reduntant conditions.
Solution:   Remove them. (Dominique Pelle)
2018-02-09 16:46:00 +01:00
Bram Moolenaar
9d32276b52 patch 8.0.1483: searchpair() might return an invalid value on timeout
Problem:    Searchpair() might return an invalid value on timeout.
Solution:   When the second search times out, do not accept a match from the
            first search. (Daniel Hahler, closes #2552)
2018-02-09 16:04:25 +01:00
Bram Moolenaar
02ae9b4a93 patch 8.0.1482: using feedkeys() does not work to test completion
Problem:    Using feedkeys() does not work to test Insert mode completion.
            (Lifepillar)
Solution:   Do not check for typed keys when executing :normal or feedkeys().
            Fix thesaurus completion not working when 'complete' is empty.
2018-02-09 15:06:02 +01:00
Bram Moolenaar
1567558b20 patch 8.0.1481: clearing a pointer takes two lines
Problem:    Clearing a pointer takes two lines.
Solution:   Add vim_clear() to free and clear the pointer.
2018-02-09 12:29:56 +01:00
Bram Moolenaar
0562532c2e patch 8.0.1480: patch missing change
Problem:    Patch missing change.
Solution:   Add missing change.
2018-02-09 12:28:00 +01:00
Bram Moolenaar
bc0e9adae9 patch 8.0.1479: insert mode completion state is confusing
Problem:    Insert mode completion state is confusing.
Solution:   Move ctrl_x_mode into edit.c.  Add CTRL_X_NORMAL for zero.
2018-02-09 12:13:34 +01:00
Bram Moolenaar
dff72ba445 patch 8.0.1478: unnecessary condition
Problem:    Unnecessary condition for "len" being zero.
Solution:   Remove the condition. (Dominique Pelle)
2018-02-08 22:45:17 +01:00
Bram Moolenaar
d317b38a4d patch 8.0.1477: redraw flicker when moving the mouse outside of terminal window
Problem:    Redraw flicker when moving the mouse outside of terminal window.
Solution:   Instead of updating the cursor color and shape every time leaving
            and entering a terminal window, only update when different from
            the previously used cursor.
2018-02-08 22:33:31 +01:00
Bram Moolenaar
acda04f5c6 patch 8.0.1476: screen isn't always updated right away
Problem:    Screen isn't always updated right away.
Solution:   Adjust #ifdef: Call out_flush() when not running the GUI.
2018-02-08 09:57:28 +01:00
Bram Moolenaar
f12519dec8 patch 8.0.1475: invalid memory access in read_redo()
Problem:    Invalid memory access in read_redo(). (gy741)
Solution:   Convert the replacement character back from a negative number to
            CR or NL. (hint by Dominique Pelle, closes #2616)
2018-02-06 22:52:49 +01:00
Bram Moolenaar
dd08b6a32b patch 8.0.1474: Visual C 2017 has multiple MSVCVER numbers
Problem:    Visual C 2017 has multiple MSVCVER numbers.
Solution:   Assume the 2017 version if MSVCVER >= 1910. (Leonardo Valeri
            Manera, closes #2619)
2018-02-06 22:02:43 +01:00
Bram Moolenaar
511ffdd65d patch 8.0.1473: MS-Windows: D&D fails between 32 and 64 bit apps
Problem:    MS-Windows: D&D fails between 32 and 64 bit apps.
Solution:   Add the /HIGHENTROPYVA:NO linker option. (Ken Takata, closes #2504)
2018-02-04 19:37:40 +01:00
Bram Moolenaar
5d4247402b patch 8.0.1472: MS-Windows: nsis installer is a bit slow
Problem:    MS-Windows: nsis installer is a bit slow.
Solution:   Use ReserveFile for vimrc.ini. (closes #2522)
2018-02-04 19:11:30 +01:00
Bram Moolenaar
28944fecff patch 8.0.1471: on MS-Windows CursorIM highlighting no longer works
Problem:    On MS-Windows CursorIM highlighting no longer works.
Solution:   Adjust #if statements. (Ken Takata)
2018-02-04 19:01:31 +01:00
Bram Moolenaar
2c7b906afb patch 8.0.1470: integer overflow when using regexp pattern
Problem:    Integer overflow when using regexp pattern. (geeknik)
Solution:   Use a long instead of int. (Christian Brabandt, closes #2251)
2018-02-04 18:22:46 +01:00
Bram Moolenaar
2374faae11 patch 8.0.1469: when package path is a symlink 'runtimepath' is wrong
Problem:    When package path is a symlink adding it to 'runtimepath' happens
            at the end.
Solution:   Do not resolve symlinks before locating the position in
            'runtimepath'. (Ozaki Kiichi, closes #2604)
2018-02-04 17:47:42 +01:00
26 changed files with 539 additions and 268 deletions

View File

@@ -89,6 +89,11 @@ Page instfiles
UninstPage uninstConfirm
UninstPage instfiles
# Reserve files
# Needed for showing the _vimrc setting page faster.
ReserveFile /plugin InstallOptions.dll
ReserveFile vimrc.ini
##########################################################
# Functions
@@ -475,15 +480,13 @@ Function SetCustom
# Display the InstallOptions dialog
# Check if a _vimrc should be created
SectionGetFlags ${sec_vimrc_id} $0
IntOp $0 $0 & 1
StrCmp $0 "1" +2 0
SectionGetFlags ${sec_vimrc_id} $3
IntOp $3 $3 & 1
StrCmp $3 "1" +2 0
Abort
Push $3
InstallOptions::dialog "$PLUGINSDIR\vimrc.ini"
Pop $3
Pop $3
FunctionEnd
Function ValidateCustom

View File

@@ -289,7 +289,8 @@ MSVC_MAJOR = ($(MSVCVER) / 100 - 6)
MSVCRT_VER = ($(MSVCVER) / 10 - 60)
# Visual C++ 2017 needs special handling
# it has an _MSC_VER of 1910->14.1, but is actually v15 with runtime v140
!elseif $(MSVCVER) == 1910
# TODO: what's the maximum value?
!elseif $(MSVCVER) >= 1910
MSVC_MAJOR = 15
MSVCRT_VER = 140
!else
@@ -1179,6 +1180,13 @@ LINKARGS1 = $(LINKARGS1) /LTCG:STATUS
!endif
!endif
!if $(MSVC_MAJOR) >= 11 && "$(CPU)" == "AMD64" && "$(GUI)" == "yes"
# This option is required for VC2012 or later so that 64-bit gvim can
# accept D&D from 32-bit applications. NOTE: This disables 64-bit ASLR,
# therefore the security level becomes as same as VC2010.
LINKARGS1 = $(LINKARGS1) /HIGHENTROPYVA:NO
!endif
all: $(VIM).exe \
vimrun.exe \
install.exe \

View File

@@ -17,39 +17,41 @@
/*
* definitions used for CTRL-X submode
*/
#define CTRL_X_WANT_IDENT 0x100
# define CTRL_X_WANT_IDENT 0x100
#define CTRL_X_NOT_DEFINED_YET 1
#define CTRL_X_SCROLL 2
#define CTRL_X_WHOLE_LINE 3
#define CTRL_X_FILES 4
#define CTRL_X_TAGS (5 + CTRL_X_WANT_IDENT)
#define CTRL_X_PATH_PATTERNS (6 + CTRL_X_WANT_IDENT)
#define CTRL_X_PATH_DEFINES (7 + CTRL_X_WANT_IDENT)
#define CTRL_X_FINISHED 8
#define CTRL_X_DICTIONARY (9 + CTRL_X_WANT_IDENT)
#define CTRL_X_THESAURUS (10 + CTRL_X_WANT_IDENT)
#define CTRL_X_CMDLINE 11
#define CTRL_X_FUNCTION 12
#define CTRL_X_OMNI 13
#define CTRL_X_SPELL 14
#define CTRL_X_LOCAL_MSG 15 /* only used in "ctrl_x_msgs" */
#define CTRL_X_EVAL 16 /* for builtin function complete() */
# define CTRL_X_NORMAL 0 /* CTRL-N CTRL-P completion, default */
# define CTRL_X_NOT_DEFINED_YET 1
# define CTRL_X_SCROLL 2
# define CTRL_X_WHOLE_LINE 3
# define CTRL_X_FILES 4
# define CTRL_X_TAGS (5 + CTRL_X_WANT_IDENT)
# define CTRL_X_PATH_PATTERNS (6 + CTRL_X_WANT_IDENT)
# define CTRL_X_PATH_DEFINES (7 + CTRL_X_WANT_IDENT)
# define CTRL_X_FINISHED 8
# define CTRL_X_DICTIONARY (9 + CTRL_X_WANT_IDENT)
# define CTRL_X_THESAURUS (10 + CTRL_X_WANT_IDENT)
# define CTRL_X_CMDLINE 11
# define CTRL_X_FUNCTION 12
# define CTRL_X_OMNI 13
# define CTRL_X_SPELL 14
# define CTRL_X_LOCAL_MSG 15 /* only used in "ctrl_x_msgs" */
# define CTRL_X_EVAL 16 /* for builtin function complete() */
#define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT]
#define CTRL_X_MODE_LINE_OR_EVAL(m) (m == CTRL_X_WHOLE_LINE || m == CTRL_X_EVAL)
# define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT]
# define CTRL_X_MODE_LINE_OR_EVAL(m) ((m) == CTRL_X_WHOLE_LINE || (m) == CTRL_X_EVAL)
/* Message for CTRL-X mode, index is ctrl_x_mode. */
static char *ctrl_x_msgs[] =
{
N_(" Keyword completion (^N^P)"), /* ctrl_x_mode == 0, ^P/^N compl. */
N_(" Keyword completion (^N^P)"), /* CTRL_X_NORMAL, ^P/^N compl. */
N_(" ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"),
NULL,
NULL, /* CTRL_X_SCROLL: depends on state */
N_(" Whole line completion (^L^N^P)"),
N_(" File name completion (^F^N^P)"),
N_(" Tag completion (^]^N^P)"),
N_(" Path pattern completion (^N^P)"),
N_(" Definition completion (^D^N^P)"),
NULL,
NULL, /* CTRL_X_FINISHED */
N_(" Dictionary completion (^K^N^P)"),
N_(" Thesaurus completion (^T^N^P)"),
N_(" Command-line completion (^V^N^P)"),
@@ -61,10 +63,10 @@ static char *ctrl_x_msgs[] =
};
static char e_hitend[] = N_("Hit end of paragraph");
#ifdef FEAT_COMPL_FUNC
# 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
# endif
/*
* Structure used to store one match for insert completion.
@@ -83,8 +85,8 @@ struct compl_S
int cp_number; /* sequence number */
};
#define ORIGINAL_TEXT (1) /* the original text when the expansion begun */
#define FREE_FNAME (2)
# define ORIGINAL_TEXT (1) /* the original text when the expansion begun */
# define FREE_FNAME (2)
/*
* All the current matches are stored in a list.
@@ -127,6 +129,9 @@ static int compl_restarting = FALSE; /* don't insert match */
* FALSE the word to be completed must be located. */
static int compl_started = FALSE;
/* Which Ctrl-X mode are we in? */
static int ctrl_x_mode = CTRL_X_NORMAL;
/* Set when doing something for completion that may call edit() recursively,
* which is not allowed. */
static int compl_busy = FALSE;
@@ -174,10 +179,10 @@ static void ins_compl_addfrommatch(void);
static int ins_compl_prep(int c);
static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg);
static buf_T *ins_compl_next_buf(buf_T *buf, int flag);
#if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL)
# if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL)
static void ins_compl_add_list(list_T *list);
static void ins_compl_add_dict(dict_T *dict);
#endif
# endif
static int ins_compl_get_exp(pos_T *ini);
static void ins_compl_delete(void);
static void ins_compl_insert(int in_compl_func);
@@ -1449,7 +1454,8 @@ doESCkey:
/* if 'complete' is empty then plain ^P is no longer special,
* but it is under other ^X modes */
if (*curbuf->b_p_cpt == NUL
&& ctrl_x_mode != 0
&& (ctrl_x_mode == CTRL_X_NORMAL
|| ctrl_x_mode == CTRL_X_WHOLE_LINE)
&& !(compl_cont_status & CONT_LOCAL))
goto normalchar;
@@ -1564,7 +1570,7 @@ normalchar:
if (c != K_CURSORHOLD
# ifdef FEAT_COMPL_FUNC
/* but not in CTRL-X mode, a script can't restore the state */
&& ctrl_x_mode == 0
&& ctrl_x_mode == CTRL_X_NORMAL
# endif
)
did_cursorhold = FALSE;
@@ -1577,7 +1583,7 @@ normalchar:
#ifdef FEAT_CINDENT
if (can_cindent && cindent_on()
# ifdef FEAT_INS_EXPAND
&& ctrl_x_mode == 0
&& ctrl_x_mode == CTRL_X_NORMAL
# endif
)
{
@@ -2241,6 +2247,24 @@ ins_ctrl_x(void)
}
}
/*
* Whether other than default completion has been selected.
*/
int
ctrl_x_mode_not_default(void)
{
return ctrl_x_mode != CTRL_X_NORMAL;
}
/*
* Whether CTRL-X was typed without a following character.
*/
int
ctrl_x_mode_not_defined_yet(void)
{
return ctrl_x_mode == CTRL_X_NOT_DEFINED_YET;
}
/*
* Return TRUE if the 'dict' or 'tsr' option can be used.
*/
@@ -2254,7 +2278,7 @@ has_compl_option(int dict_opt)
)
: (*curbuf->b_p_tsr == NUL && *p_tsr == NUL))
{
ctrl_x_mode = 0;
ctrl_x_mode = CTRL_X_NORMAL;
edit_submode = NULL;
msg_attr(dict_opt ? (char_u *)_("'dictionary' option is empty")
: (char_u *)_("'thesaurus' option is empty"),
@@ -2830,7 +2854,7 @@ set_completion(colnr_T startcol, list_T *list)
int save_w_leftcol = curwin->w_leftcol;
/* If already doing completions stop it. */
if (ctrl_x_mode != 0)
if (ctrl_x_mode != CTRL_X_NORMAL)
ins_compl_prep(' ');
ins_compl_clear();
ins_compl_free();
@@ -2904,8 +2928,7 @@ ins_compl_del_pum(void)
if (compl_match_array != NULL)
{
pum_undisplay();
vim_free(compl_match_array);
compl_match_array = NULL;
vim_clear((void **)&compl_match_array);
}
}
@@ -3407,10 +3430,8 @@ ins_compl_free(void)
compl_T *match;
int i;
vim_free(compl_pattern);
compl_pattern = NULL;
vim_free(compl_leader);
compl_leader = NULL;
vim_clear((void **)&compl_pattern);
vim_clear((void **)&compl_leader);
if (compl_first_match == NULL)
return;
@@ -3442,13 +3463,10 @@ ins_compl_clear(void)
compl_cont_status = 0;
compl_started = FALSE;
compl_matches = 0;
vim_free(compl_pattern);
compl_pattern = NULL;
vim_free(compl_leader);
compl_leader = NULL;
vim_clear((void **)&compl_pattern);
vim_clear((void **)&compl_leader);
edit_submode_extra = NULL;
vim_free(compl_orig_text);
compl_orig_text = NULL;
vim_clear((void **)&compl_orig_text);
compl_enter_selects = FALSE;
/* clear v:completed_item */
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
@@ -3736,7 +3754,7 @@ ins_compl_prep(int c)
/* Set "compl_get_longest" when finding the first matches. */
if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET
|| (ctrl_x_mode == 0 && !compl_started))
|| (ctrl_x_mode == CTRL_X_NORMAL && !compl_started))
{
compl_get_longest = (strstr((char *)p_cot, "longest") != NULL);
compl_used_match = TRUE;
@@ -3841,19 +3859,19 @@ ins_compl_prep(int c)
else
compl_cont_mode = CTRL_X_NOT_DEFINED_YET;
}
ctrl_x_mode = 0;
ctrl_x_mode = CTRL_X_NORMAL;
edit_submode = NULL;
showmode();
break;
}
}
else if (ctrl_x_mode != 0)
else if (ctrl_x_mode != CTRL_X_NORMAL)
{
/* We're already in CTRL-X mode, do we stay in it? */
if (!vim_is_ctrl_x_key(c))
{
if (ctrl_x_mode == CTRL_X_SCROLL)
ctrl_x_mode = 0;
ctrl_x_mode = CTRL_X_NORMAL;
else
ctrl_x_mode = CTRL_X_FINISHED;
edit_submode = NULL;
@@ -3867,8 +3885,8 @@ ins_compl_prep(int c)
* 'Pattern not found') until another key is hit, then go back to
* showing what mode we are in. */
showmode();
if ((ctrl_x_mode == 0 && c != Ctrl_N && c != Ctrl_P && c != Ctrl_R
&& !ins_compl_pum_key(c))
if ((ctrl_x_mode == CTRL_X_NORMAL && c != Ctrl_N && c != Ctrl_P
&& c != Ctrl_R && !ins_compl_pum_key(c))
|| ctrl_x_mode == CTRL_X_FINISHED)
{
/* Get here when we have finished typing a sequence of ^N and
@@ -3951,7 +3969,7 @@ ins_compl_prep(int c)
compl_matches = 0;
if (!shortmess(SHM_COMPLETIONMENU))
msg_clr_cmdline(); /* necessary for "noshowmode" */
ctrl_x_mode = 0;
ctrl_x_mode = CTRL_X_NORMAL;
compl_enter_selects = FALSE;
if (edit_submode != NULL)
{
@@ -4292,7 +4310,8 @@ ins_compl_get_exp(pos_T *ini)
/* For ^N/^P pick a new entry from e_cpt if compl_started is off,
* or if found_all says this entry is done. For ^X^L only use the
* entries from 'complete' that look in loaded buffers. */
if ((ctrl_x_mode == 0 || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
if ((ctrl_x_mode == CTRL_X_NORMAL
|| CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
&& (!compl_started || found_all))
{
found_all = FALSE;
@@ -4304,7 +4323,7 @@ ins_compl_get_exp(pos_T *ini)
first_match_pos = *ini;
/* Move the cursor back one character so that ^N can match the
* word immediately after the cursor. */
if (ctrl_x_mode == 0 && dec(&first_match_pos) < 0)
if (ctrl_x_mode == CTRL_X_NORMAL && dec(&first_match_pos) < 0)
{
/* Move the cursor to after the last character in the
* buffer, so that word at start of buffer is found
@@ -4437,8 +4456,8 @@ ins_compl_get_exp(pos_T *ini)
/* Find up to TAG_MANY matches. Avoids that an enormous number
* of matches is found when compl_pattern is empty */
if (find_tags(compl_pattern, &num_matches, &matches,
TAG_REGEXP | TAG_NAMES | TAG_NOIC |
TAG_INS_COMP | (ctrl_x_mode ? TAG_VERBOSE : 0),
TAG_REGEXP | TAG_NAMES | TAG_NOIC | TAG_INS_COMP
| (ctrl_x_mode != CTRL_X_NORMAL ? TAG_VERBOSE : 0),
TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0)
{
ins_compl_add_matches(num_matches, matches, p_ic);
@@ -4633,8 +4652,10 @@ ins_compl_get_exp(pos_T *ini)
found_new_match = OK;
/* break the loop for specialized modes (use 'complete' just for the
* generic ctrl_x_mode == 0) or when we've found a new match */
if ((ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
* generic ctrl_x_mode == CTRL_X_NORMAL) or when we've found a new
* match */
if ((ctrl_x_mode != CTRL_X_NORMAL
&& !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
|| found_new_match != FAIL)
{
if (got_int)
@@ -4643,7 +4664,8 @@ ins_compl_get_exp(pos_T *ini)
if (type != -1)
ins_compl_check_keys(0, FALSE);
if ((ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
if ((ctrl_x_mode != CTRL_X_NORMAL
&& !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
|| compl_interrupted)
break;
compl_started = TRUE;
@@ -4659,13 +4681,13 @@ ins_compl_get_exp(pos_T *ini)
}
compl_started = TRUE;
if ((ctrl_x_mode == 0 || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
if ((ctrl_x_mode == CTRL_X_NORMAL || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
&& *e_cpt == NUL) /* Got to end of 'complete' */
found_new_match = FAIL;
i = -1; /* total of matches, unknown */
if (found_new_match == FAIL
|| (ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)))
if (found_new_match == FAIL || (ctrl_x_mode != CTRL_X_NORMAL
&& !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)))
i = ins_compl_make_cyclic();
if (compl_old_match != NULL)
@@ -4999,12 +5021,12 @@ ins_compl_next(
ins_compl_check_keys(int frequency, int in_compl_func)
{
static int count = 0;
int c;
/* Don't check when reading keys from a script. That would break the test
* scripts */
if (using_script())
/* Don't check when reading keys from a script, :normal or feedkeys().
* That would break the test scripts. But do check for keys when called
* from complete_check(). */
if (!in_compl_func && (using_script() || ex_normal_busy))
return;
/* Only do this at regular intervals */
@@ -5166,7 +5188,8 @@ ins_complete(int c, int enable_pum)
* it is a continued search
*/
compl_cont_status &= ~CONT_INTRPT; /* remove INTRPT */
if (ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_PATH_PATTERNS
if (ctrl_x_mode == CTRL_X_NORMAL
|| ctrl_x_mode == CTRL_X_PATH_PATTERNS
|| ctrl_x_mode == CTRL_X_PATH_DEFINES)
{
if (compl_startpos.lnum != curwin->w_cursor.lnum)
@@ -5219,7 +5242,8 @@ ins_complete(int c, int enable_pum)
if (!(compl_cont_status & CONT_ADDING)) /* normal expansion */
{
compl_cont_mode = ctrl_x_mode;
if (ctrl_x_mode != 0) /* Remove LOCAL if ctrl_x_mode != 0 */
if (ctrl_x_mode != CTRL_X_NORMAL)
/* Remove LOCAL if ctrl_x_mode != CTRL_X_NORMAL */
compl_cont_status = 0;
compl_cont_status |= CONT_N_ADDS;
compl_startpos = curwin->w_cursor;
@@ -5228,7 +5252,7 @@ ins_complete(int c, int enable_pum)
}
/* Work out completion pattern and original text -- webb */
if (ctrl_x_mode == 0 || (ctrl_x_mode & CTRL_X_WANT_IDENT))
if (ctrl_x_mode == CTRL_X_NORMAL || (ctrl_x_mode & CTRL_X_WANT_IDENT))
{
if ((compl_cont_status & CONT_SOL)
|| ctrl_x_mode == CTRL_X_PATH_DEFINES)
@@ -5445,7 +5469,7 @@ ins_complete(int c, int enable_pum)
return FAIL;
if (col == -3)
{
ctrl_x_mode = 0;
ctrl_x_mode = CTRL_X_NORMAL;
edit_submode = NULL;
if (!shortmess(SHM_COMPLETIONMENU))
msg_clr_cmdline();
@@ -5545,10 +5569,8 @@ ins_complete(int c, int enable_pum)
if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
{
vim_free(compl_pattern);
compl_pattern = NULL;
vim_free(compl_orig_text);
compl_orig_text = NULL;
vim_clear((void **)&compl_pattern);
vim_clear((void **)&compl_orig_text);
return FAIL;
}
@@ -5604,7 +5626,7 @@ ins_complete(int c, int enable_pum)
* (such as M in M'exico) if not tried already. -- Acevedo */
if ( compl_length > 1
|| (compl_cont_status & CONT_ADDING)
|| (ctrl_x_mode != 0
|| (ctrl_x_mode != CTRL_X_NORMAL
&& ctrl_x_mode != CTRL_X_PATH_PATTERNS
&& ctrl_x_mode != CTRL_X_PATH_DEFINES))
compl_cont_status &= ~CONT_N_ADDS;
@@ -7177,11 +7199,9 @@ set_last_insert(int c)
void
free_last_insert(void)
{
vim_free(last_insert);
last_insert = NULL;
vim_clear((void **)&last_insert);
# ifdef FEAT_INS_EXPAND
vim_free(compl_orig_text);
compl_orig_text = NULL;
vim_clear((void **)&compl_orig_text);
# endif
}
#endif
@@ -7809,8 +7829,7 @@ mb_replace_pop_ins(int cc)
static void
replace_flush(void)
{
vim_free(replace_stack);
replace_stack = NULL;
vim_clear((void **)&replace_stack);
replace_stack_len = 0;
replace_stack_nr = 0;
}

View File

@@ -7977,7 +7977,7 @@ f_mode(typval_T *argvars, typval_T *rettv)
#ifdef FEAT_INS_EXPAND
if (ins_compl_active())
buf[1] = 'c';
else if (ctrl_x_mode == 1)
else if (ctrl_x_mode_not_defined_yet())
buf[1] = 'x';
#endif
}

View File

@@ -3567,13 +3567,11 @@ source_all_matches(char_u *pat)
}
}
/* used for "cookie" of add_pack_plugin() */
static int APP_ADD_DIR;
static int APP_LOAD;
static int APP_BOTH;
static void
add_pack_plugin(char_u *fname, void *cookie)
/*
* Add the package directory to 'runtimepath'.
*/
static int
add_pack_dir_to_rtp(char_u *fname)
{
char_u *p4, *p3, *p2, *p1, *p;
char_u *insp;
@@ -3582,20 +3580,16 @@ add_pack_plugin(char_u *fname, void *cookie)
int keep;
size_t oldlen;
size_t addlen;
char_u *afterdir;
char_u *afterdir = NULL;
size_t afterlen = 0;
char_u *ffname = fix_fname(fname);
char_u *ffname = NULL;
size_t fname_len;
char_u *buf = NULL;
char_u *rtp_ffname;
int match;
int retval = FAIL;
if (ffname == NULL)
return;
if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)ffname) == NULL)
{
/* directory is not yet in 'runtimepath', add it */
p4 = p3 = p2 = p1 = get_past_head(ffname);
p4 = p3 = p2 = p1 = get_past_head(fname);
for (p = p1; *p; MB_PTR_ADV(p))
if (vim_ispathsep_nocolon(*p))
{
@@ -3607,8 +3601,12 @@ add_pack_plugin(char_u *fname, void *cookie)
* p4 p3 p2 p1
*
* find the part up to "pack" in 'runtimepath' */
c = *p4;
c = *++p4; /* append pathsep in order to expand symlink */
*p4 = NUL;
ffname = fix_fname(fname);
*p4 = c;
if (ffname == NULL)
return FAIL;
/* Find "ffname" in "p_rtp", ignoring '/' vs '\' differences. */
fname_len = STRLEN(ffname);
@@ -3635,15 +3633,14 @@ add_pack_plugin(char_u *fname, void *cookie)
else
/* append after the matching directory. */
--insp;
*p4 = c;
/* check if rtp/pack/name/start/name/after exists */
afterdir = concat_fnames(ffname, (char_u *)"after", TRUE);
afterdir = concat_fnames(fname, (char_u *)"after", TRUE);
if (afterdir != NULL && mch_isdir(afterdir))
afterlen = STRLEN(afterdir) + 1; /* add one for comma */
oldlen = STRLEN(p_rtp);
addlen = STRLEN(ffname) + 1; /* add one for comma */
addlen = STRLEN(fname) + 1; /* add one for comma */
new_rtp = alloc((int)(oldlen + addlen + afterlen + 1));
/* add one for NUL */
if (new_rtp == NULL)
@@ -3651,10 +3648,9 @@ add_pack_plugin(char_u *fname, void *cookie)
keep = (int)(insp - p_rtp);
mch_memmove(new_rtp, p_rtp, keep);
new_rtp[keep] = ',';
mch_memmove(new_rtp + keep + 1, ffname, addlen);
mch_memmove(new_rtp + keep + 1, fname, addlen);
if (p_rtp[keep] != NUL)
mch_memmove(new_rtp + keep + addlen, p_rtp + keep,
oldlen - keep + 1);
mch_memmove(new_rtp + keep + addlen, p_rtp + keep, oldlen - keep + 1);
if (afterlen > 0)
{
STRCAT(new_rtp, ",");
@@ -3662,16 +3658,30 @@ add_pack_plugin(char_u *fname, void *cookie)
}
set_option_value((char_u *)"rtp", 0L, new_rtp, 0);
vim_free(new_rtp);
vim_free(afterdir);
}
retval = OK;
if (cookie != &APP_ADD_DIR)
{
theend:
vim_free(buf);
vim_free(ffname);
vim_free(afterdir);
return retval;
}
/*
* Load scripts in "plugin" and "ftdetect" directories of the package.
*/
static int
load_pack_plugin(char_u *fname)
{
static char *plugpat = "%s/plugin/**/*.vim";
static char *ftpat = "%s/ftdetect/*.vim";
int len;
char_u *pat;
char_u *ffname = fix_fname(fname);
char_u *pat = NULL;
int retval = FAIL;
if (ffname == NULL)
return FAIL;
len = (int)STRLEN(ffname) + (int)STRLEN(ftpat);
pat = alloc(len);
if (pat == NULL)
@@ -3696,11 +3706,28 @@ add_pack_plugin(char_u *fname, void *cookie)
}
#endif
vim_free(pat);
}
retval = OK;
theend:
vim_free(buf);
vim_free(ffname);
return retval;
}
/* used for "cookie" of add_pack_plugin() */
static int APP_ADD_DIR;
static int APP_LOAD;
static int APP_BOTH;
static void
add_pack_plugin(char_u *fname, void *cookie)
{
if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)fname) == NULL)
/* directory is not yet in 'runtimepath', add it */
if (add_pack_dir_to_rtp(fname) == FAIL)
return;
if (cookie != &APP_ADD_DIR)
load_pack_plugin(fname);
}
/*

View File

@@ -8058,6 +8058,16 @@ alist_set(
int fnum_len)
{
int i;
static int recursive = 0;
if (recursive)
{
#ifdef FEAT_AUTOCMD
EMSG(_(e_au_recursive));
#endif
return;
}
++recursive;
alist_clear(al);
if (ga_grow(&al->al_ga, count) == OK)
@@ -8087,6 +8097,8 @@ alist_set(
FreeWild(count, files);
if (al == &global_alist)
arg_had_last = FALSE;
--recursive;
}
/*

View File

@@ -2115,7 +2115,8 @@ vgetorpeek(int advance)
&& State != ASKMORE
&& State != CONFIRM
#ifdef FEAT_INS_EXPAND
&& !((ctrl_x_mode != 0 && vim_is_ctrl_x_key(c1))
&& !((ctrl_x_mode_not_default()
&& vim_is_ctrl_x_key(c1))
|| ((compl_cont_status & CONT_LOCAL)
&& (c1 == Ctrl_N || c1 == Ctrl_P)))
#endif

View File

@@ -964,7 +964,6 @@ EXTERN char_u *edit_submode INIT(= NULL); /* msg for CTRL-X submode */
EXTERN char_u *edit_submode_pre INIT(= NULL); /* prepended to edit_submode */
EXTERN char_u *edit_submode_extra INIT(= NULL);/* appended to edit_submode */
EXTERN hlf_T edit_submode_highl; /* highl. method for extra info */
EXTERN int ctrl_x_mode INIT(= 0); /* Which Ctrl-X mode are we in? */
#endif
EXTERN int no_abbr INIT(= TRUE); /* TRUE when no abbreviations loaded */
@@ -1595,6 +1594,9 @@ EXTERN char_u e_notset[] INIT(= N_("E764: Option '%s' is not set"));
EXTERN char_u e_invalidreg[] INIT(= N_("E850: Invalid register name"));
#endif
EXTERN char_u e_dirnotf[] INIT(= N_("E919: Directory not found in '%s': \"%s\""));
#ifdef FEAT_AUTOCMD
EXTERN char_u e_au_recursive[] INIT(= N_("E952: Autocommand caused recursive behavior"));
#endif
#ifdef FEAT_GUI_MAC
EXTERN short disallow_gui INIT(= FALSE);

View File

@@ -1137,13 +1137,13 @@ gui_update_cursor(
if (id > 0)
{
cattr = syn_id2colors(id, &cfg, &cbg);
#if defined(FEAT_XIM) || defined(FEAT_HANGULIN)
#if defined(FEAT_MBYTE) || defined(FEAT_HANGULIN)
{
static int iid;
guicolor_T fg, bg;
if (
# if defined(FEAT_GUI_GTK) && !defined(FEAT_HANGULIN)
# if defined(FEAT_GUI_GTK) && defined(FEAT_XIM) && !defined(FEAT_HANGULIN)
preedit_get_status()
# else
im_get_status()

View File

@@ -1836,6 +1836,19 @@ vim_free(void *x)
}
}
/*
* Like vim_free(), and also set the pointer to NULL.
*/
void
vim_clear(void **x)
{
if (*x != NULL)
{
vim_free(*x);
*x = NULL;
}
}
#ifndef HAVE_MEMSET
void *
vim_memset(void *ptr, int c, size_t size)

View File

@@ -1685,11 +1685,19 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
get_op_char(oap->op_type), get_extra_op_char(oap->op_type),
oap->motion_force, cap->cmdchar, cap->nchar);
else if (cap->cmdchar != ':')
{
int nchar = oap->op_type == OP_REPLACE ? cap->nchar : NUL;
/* reverse what nv_replace() did */
if (nchar == REPLACE_CR_NCHAR)
nchar = CAR;
else if (nchar == REPLACE_NL_NCHAR)
nchar = NL;
prep_redo(oap->regname, 0L, NUL, 'v',
get_op_char(oap->op_type),
get_extra_op_char(oap->op_type),
oap->op_type == OP_REPLACE
? cap->nchar : NUL);
nchar);
}
if (!redo_VIsual_busy)
{
redo_VIsual_mode = resel_VIsual_mode;
@@ -7023,10 +7031,12 @@ nv_replace(cmdarg_T *cap)
reset_VIsual();
if (had_ctrl_v)
{
if (cap->nchar == '\r')
cap->nchar = -1;
else if (cap->nchar == '\n')
cap->nchar = -2;
/* Use a special (negative) number to make a difference between a
* literal CR or NL and a line break. */
if (cap->nchar == CAR)
cap->nchar = REPLACE_CR_NCHAR;
else if (cap->nchar == NL)
cap->nchar = REPLACE_NL_NCHAR;
}
nv_operator(cap);
return;

View File

@@ -2113,13 +2113,21 @@ op_replace(oparg_T *oap, int c)
size_t oldlen;
struct block_def bd;
char_u *after_p = NULL;
int had_ctrl_v_cr = (c == -1 || c == -2);
int had_ctrl_v_cr = FALSE;
if ((curbuf->b_ml.ml_flags & ML_EMPTY ) || oap->empty)
return OK; /* nothing to do */
if (had_ctrl_v_cr)
c = (c == -1 ? '\r' : '\n');
if (c == REPLACE_CR_NCHAR)
{
had_ctrl_v_cr = TRUE;
c = CAR;
}
else if (c == REPLACE_NL_NCHAR)
{
had_ctrl_v_cr = TRUE;
c = NL;
}
#ifdef FEAT_MBYTE
if (has_mbyte)
@@ -2207,7 +2215,8 @@ op_replace(oparg_T *oap, int c)
/* insert pre-spaces */
vim_memset(newp + bd.textcol, ' ', (size_t)bd.startspaces);
/* insert replacement chars CHECK FOR ALLOCATED SPACE */
/* -1/-2 is used for entering CR literally. */
/* REPLACE_CR_NCHAR/REPLACE_NL_NCHAR is used for entering CR
* literally. */
if (had_ctrl_v_cr || (c != '\r' && c != '\n'))
{
#ifdef FEAT_MBYTE

View File

@@ -6,6 +6,8 @@ void display_dollar(colnr_T col);
void change_indent(int type, int amount, int round, int replaced, int call_changed_bytes);
void truncate_spaces(char_u *line);
void backspace_until_column(int col);
int ctrl_x_mode_not_default(void);
int ctrl_x_mode_not_defined_yet(void);
int vim_is_ctrl_x_key(int c);
int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int dir, int flags);
void completeopt_was_set(void);

View File

@@ -46,6 +46,7 @@ void vim_strncpy(char_u *to, char_u *from, size_t len);
void vim_strcat(char_u *to, char_u *from, size_t tosize);
int copy_option_part(char_u **option, char_u *buf, int maxlen, char *sep_chars);
void vim_free(void *x);
void vim_clear(void **x);
int vim_stricmp(char *s1, char *s2);
int vim_strnicmp(char *s1, char *s2, size_t len);
char_u *vim_strchr(char_u *string, int c);

View File

@@ -1600,7 +1600,7 @@ nfa_regatom(void)
default:
{
int n = 0;
long n = 0;
int cmp = c;
if (c == '<' || c == '>')
@@ -1628,7 +1628,14 @@ nfa_regatom(void)
/* \%{n}v \%{n}<v \%{n}>v */
EMIT(cmp == '<' ? NFA_VCOL_LT :
cmp == '>' ? NFA_VCOL_GT : NFA_VCOL);
EMIT(n);
#if VIM_SIZEOF_INT < VIM_SIZEOF_LONG
if (n > INT_MAX)
{
EMSG(_("E951: \\% value too large"));
return FAIL;
}
#endif
EMIT((int)n);
break;
}
else if (c == '\'' && n == 0)
@@ -6176,7 +6183,7 @@ nfa_regmatch(
{
/* If \Z was present, then ignore composing characters.
* When ignoring the base character this always matches. */
if (len == 0 && sta->c != curc)
if (sta->c != curc)
result = FAIL;
else
result = OK;

View File

@@ -474,9 +474,8 @@ redraw_after_callback(int call_update_screen)
* flicker. */
out_flush_cursor(FALSE, FALSE);
else
#else
out_flush();
#endif
out_flush();
--redrawing_for_callback;
}

View File

@@ -421,7 +421,7 @@ ignorecase_opt(char_u *pat, int ic_in, int scs)
if (ic && !no_smartcase && scs
#ifdef FEAT_INS_EXPAND
&& !(ctrl_x_mode && curbuf->b_p_inf)
&& !(ctrl_x_mode_not_default() && curbuf->b_p_inf)
#endif
)
ic = !pat_has_uppercase(pat);
@@ -684,11 +684,11 @@ searchit(
&& pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count
&& pos->col < MAXCOL - 2)
{
ptr = ml_get_buf(buf, pos->lnum, FALSE) + pos->col;
if (*ptr == NUL)
ptr = ml_get_buf(buf, pos->lnum, FALSE);
if ((int)STRLEN(ptr) < pos->col)
start_char_len = 1;
else
start_char_len = (*mb_ptr2len)(ptr);
start_char_len = (*mb_ptr2len)(ptr + pos->col);
}
#endif
else
@@ -973,7 +973,16 @@ searchit(
NULL, NULL
#endif
)) == 0)
{
#ifdef FEAT_RELTIME
/* If the search timed out, we did find a match
* but it might be the wrong one, so that's not
* OK. */
if (timed_out != NULL && *timed_out)
match_ok = FALSE;
#endif
break;
}
/* Need to get the line pointer again, a
* multi-line search may have made it invalid. */

View File

@@ -193,6 +193,16 @@ static int term_backspace_char = BS;
static int term_default_cterm_fg = -1;
static int term_default_cterm_bg = -1;
/* Store the last set and the desired cursor properties, so that we only update
* them when needed. Doing it unnecessary may result in flicker. */
static char_u *last_set_cursor_color = (char_u *)"";
static char_u *desired_cursor_color = (char_u *)"";
static int last_set_cursor_shape = -1;
static int desired_cursor_shape = -1;
static int last_set_cursor_blink = -1;
static int desired_cursor_blink = -1;
/**************************************
* 1. Generic code for all systems.
*/
@@ -513,7 +523,7 @@ ex_terminal(exarg_T *eap)
init_job_options(&opt);
cmd = eap->arg;
while (*cmd && *cmd == '+' && *(cmd + 1) == '+')
while (*cmd == '+' && *(cmd + 1) == '+')
{
char_u *p, *ep;
@@ -642,6 +652,8 @@ free_terminal(buf_T *buf)
vim_free(term->tl_status_text);
vim_free(term->tl_opencmd);
vim_free(term->tl_eof_chars);
if (desired_cursor_color == term->tl_cursor_color)
desired_cursor_color = (char_u *)"";
vim_free(term->tl_cursor_color);
vim_free(term);
buf->b_term = NULL;
@@ -1472,8 +1484,28 @@ term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg)
}
#endif
static int did_change_cursor = FALSE;
static void
may_output_cursor_props(void)
{
if (STRCMP(last_set_cursor_color, desired_cursor_color) != 0
|| last_set_cursor_shape != desired_cursor_shape
|| last_set_cursor_blink != desired_cursor_blink)
{
last_set_cursor_color = desired_cursor_color;
last_set_cursor_shape = desired_cursor_shape;
last_set_cursor_blink = desired_cursor_blink;
term_cursor_color(desired_cursor_color);
if (desired_cursor_shape == -1 || desired_cursor_blink == -1)
/* this will restore the initial cursor style, if possible */
ui_cursor_shape_forced(TRUE);
else
term_cursor_shape(desired_cursor_shape, desired_cursor_blink);
}
}
/*
* Set the cursor color and shape, if not last set to these.
*/
static void
may_set_cursor_props(term_T *term)
{
@@ -1485,29 +1517,30 @@ may_set_cursor_props(term_T *term)
#endif
if (in_terminal_loop == term)
{
did_change_cursor = TRUE;
if (term->tl_cursor_color != NULL)
term_cursor_color(term->tl_cursor_color);
desired_cursor_color = term->tl_cursor_color;
else
term_cursor_color((char_u *)"");
term_cursor_shape(term->tl_cursor_shape, term->tl_cursor_blink);
desired_cursor_color = (char_u *)"";
desired_cursor_shape = term->tl_cursor_shape;
desired_cursor_blink = term->tl_cursor_blink;
may_output_cursor_props();
}
}
/*
* Reset the desired cursor properties and restore them when needed.
*/
static void
may_restore_cursor_props(void)
prepare_restore_cursor_props(void)
{
#ifdef FEAT_GUI
if (gui.in_use)
return;
#endif
if (did_change_cursor)
{
did_change_cursor = FALSE;
term_cursor_color((char_u *)"");
/* this will restore the initial cursor style, if possible */
ui_cursor_shape_forced(TRUE);
}
desired_cursor_color = (char_u *)"";
desired_cursor_shape = -1;
desired_cursor_blink = -1;
may_output_cursor_props();
}
/*
@@ -1544,6 +1577,7 @@ terminal_loop(int blocking)
int tty_fd = curbuf->b_term->tl_job->jv_channel
->ch_part[get_tty_part(curbuf->b_term)].ch_fd;
#endif
int restore_cursor;
/* Remember the terminal we are sending keys to. However, the terminal
* might be closed while waiting for a character, e.g. typing "exit" in a
@@ -1564,6 +1598,7 @@ terminal_loop(int blocking)
if (update_screen(0) == FAIL)
break;
update_cursor(curbuf->b_term, FALSE);
restore_cursor = TRUE;
c = term_vgetc();
if (!term_use_loop())
@@ -1672,6 +1707,11 @@ terminal_loop(int blocking)
# endif
if (send_keys_to_term(curbuf->b_term, c, TRUE) != OK)
{
if (c == K_MOUSEMOVE)
/* We are sure to come back here, don't reset the cursor color
* and shape to avoid flickering. */
restore_cursor = FALSE;
ret = OK;
goto theend;
}
@@ -1680,7 +1720,8 @@ terminal_loop(int blocking)
theend:
in_terminal_loop = NULL;
may_restore_cursor_props();
if (restore_cursor)
prepare_restore_cursor_props();
return ret;
}
@@ -2005,6 +2046,8 @@ handle_settermprop(
break;
case VTERM_PROP_CURSORCOLOR:
if (desired_cursor_color == term->tl_cursor_color)
desired_cursor_color = (char_u *)"";
vim_free(term->tl_cursor_color);
if (*value->string == NUL)
term->tl_cursor_color = NULL;
@@ -3216,8 +3259,7 @@ f_term_wait(typval_T *argvars, typval_T *rettv UNUSED)
return;
/* Get the job status, this will detect a job that finished. */
if ((buf->b_term->tl_job->jv_channel == NULL
|| !buf->b_term->tl_job->jv_channel->ch_keep_open)
if (!buf->b_term->tl_job->jv_channel->ch_keep_open
&& STRCMP(job_status(buf->b_term->tl_job), "dead") == 0)
{
/* The job is dead, keep reading channel I/O until the channel is

View File

@@ -631,11 +631,11 @@ func! Test_edit_CTRL_L()
call feedkeys("cct\<c-x>\<c-l>\<c-n>\<esc>", 'tnix')
call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<esc>", 'tnix')
call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
call feedkeys("cct\<c-x>\<c-l>\<c-p>\<esc>", 'tnix')
call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<esc>", 'tnix')
@@ -1357,7 +1357,6 @@ func Test_edit_complete_very_long_name()
let save_columns = &columns
" Need at least about 1100 columns to reproduce the problem.
set columns=2000
call assert_equal(2000, &columns)
set noswapfile
let longfilename = longdirname . '/' . repeat('a', 255)

View File

@@ -116,3 +116,14 @@ func Test_omni_dash()
delfunc Omni
set omnifunc=
endfunc
" Check that when using feedkeys() typeahead does not interrupt searching for
" completions.
func Test_compl_feedkeys()
new
set completeopt=menuone,noselect
call feedkeys("ajump ju\<C-X>\<C-N>\<C-P>\<ESC>", "tx")
call assert_equal("jump jump", getline(1))
bwipe!
set completeopt&
endfunc

View File

@@ -37,8 +37,8 @@ func Test_packadd()
call assert_equal(77, g:plugin_also_works)
call assert_equal(17, g:ftdetect_works)
call assert_true(len(&rtp) > len(rtp))
call assert_true(&rtp =~ '/testdir/Xdir/pack/mine/opt/mytest\($\|,\)')
call assert_true(&rtp =~ '/testdir/Xdir/pack/mine/opt/mytest/after$')
call assert_match('/testdir/Xdir/pack/mine/opt/mytest\($\|,\)', &rtp)
call assert_match('/testdir/Xdir/pack/mine/opt/mytest/after$', &rtp)
" Check exception
call assert_fails("packadd directorynotfound", 'E919:')
@@ -60,7 +60,7 @@ func Test_packadd_start()
call assert_equal(24, g:plugin_works)
call assert_true(len(&rtp) > len(rtp))
call assert_true(&rtp =~ '/testdir/Xdir/pack/mine/start/other\($\|,\)')
call assert_match('/testdir/Xdir/pack/mine/start/other\($\|,\)', &rtp)
endfunc
func Test_packadd_noload()
@@ -77,7 +77,7 @@ func Test_packadd_noload()
packadd! mytest
call assert_true(len(&rtp) > len(rtp))
call assert_true(&rtp =~ 'testdir/Xdir/pack/mine/opt/mytest\($\|,\)')
call assert_match('testdir/Xdir/pack/mine/opt/mytest\($\|,\)', &rtp)
call assert_equal(0, g:plugin_works)
" check the path is not added twice
@@ -108,7 +108,7 @@ func Test_packadd_symlink_dir()
packadd mytest
" Must have been inserted in the middle, not at the end
call assert_true(&rtp =~ '/pack/mine/opt/mytest,')
call assert_match('/pack/mine/opt/mytest,', &rtp)
call assert_equal(44, g:plugin_works)
" No change when doing it again.
@@ -121,6 +121,43 @@ func Test_packadd_symlink_dir()
exec "silent !rm" top2_dir
endfunc
func Test_packadd_symlink_dir2()
if !has('unix')
return
endif
let top2_dir = s:topdir . '/Xdir2'
let real_dir = s:topdir . '/Xsym/pack'
call mkdir(top2_dir, 'p')
call mkdir(real_dir, 'p')
let &rtp = top2_dir . ',' . top2_dir . '/after'
let &packpath = &rtp
exec "silent !ln -s ../Xsym/pack" top2_dir . '/pack'
let s:plugdir = top2_dir . '/pack/mine/opt/mytest'
call mkdir(s:plugdir . '/plugin', 'p')
exe 'split ' . s:plugdir . '/plugin/test.vim'
call setline(1, 'let g:plugin_works = 48')
wq
let g:plugin_works = 0
packadd mytest
" Must have been inserted in the middle, not at the end
call assert_match('/Xdir2/pack/mine/opt/mytest,', &rtp)
call assert_equal(48, g:plugin_works)
" No change when doing it again.
let rtp_before = &rtp
packadd mytest
call assert_equal(rtp_before, &rtp)
set rtp&
let rtp = &rtp
exec "silent !rm" top2_dir . '/pack'
exec "silent !rmdir" top2_dir
endfunc
" Check command-line completion for 'packadd'
func Test_packadd_completion()
let optdir1 = &packpath . '/pack/mine/opt'
@@ -196,9 +233,9 @@ func Test_helptags()
helptags ALL
let tags1 = readfile(docdir1 . '/tags')
call assert_true(tags1[0] =~ 'look-here')
call assert_match('look-here', tags1[0])
let tags2 = readfile(docdir2 . '/tags')
call assert_true(tags2[0] =~ 'look-away')
call assert_match('look-away', tags2[0])
endfunc
func Test_colorscheme()

View File

@@ -693,7 +693,7 @@ func Test_popup_and_preview_autocommand()
norm! gt
call assert_equal(0, &previewwindow)
norm! gT
call assert_equal(12, tabpagenr('$'))
call assert_equal(10, tabpagenr('$'))
tabonly
pclose
augroup MyBufAdd

View File

@@ -152,3 +152,16 @@ func Test_match()
call assert_equal(3 , match('abc', '\zs', 3, 1))
call assert_equal(-1, match('abc', '\zs', 4, 1))
endfunc
" This was causing an illegal memory access
func Test_inner_tag()
new
norm ixxx
call feedkeys("v", 'xt')
insert
x
x
.
norm it
q!
endfunc

View File

@@ -403,3 +403,10 @@ func Test_undo_0()
bwipe!
endfunc
func Test_redo_empty_line()
new
exe "norm\x16r\x160"
exe "norm."
bwipe!
endfunc

View File

@@ -771,6 +771,42 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1486,
/**/
1485,
/**/
1484,
/**/
1483,
/**/
1482,
/**/
1481,
/**/
1480,
/**/
1479,
/**/
1478,
/**/
1477,
/**/
1476,
/**/
1475,
/**/
1474,
/**/
1473,
/**/
1472,
/**/
1471,
/**/
1470,
/**/
1469,
/**/
1468,
/**/

View File

@@ -2515,4 +2515,8 @@ typedef enum {
# endif
#endif
/* Replacement for nchar used by nv_replace(). */
#define REPLACE_CR_NCHAR -1
#define REPLACE_NL_NCHAR -2
#endif /* VIM__H */