Compare commits

...

19 Commits

Author SHA1 Message Date
Bram Moolenaar
5459129af2 patch 8.0.1489: there is no easy way to get the global directory
Problem:    There is no easy way to get the global directory, esp. if some
            windows have a local directory.
Solution:   Make getcwd(-1) return the global directory. (Andy Massimino,
            closes #2606)
2018-02-09 20:53:59 +01:00
Bram Moolenaar
0d20737732 patch 8.0.1488: emacs tags no longer work
Problem:    Emacs tags no longer work. (zdohnal)
Solution:   Do not skip over end of line.
2018-02-09 19:25:29 +01:00
Bram Moolenaar
8846ac5aed patch 8.0.1487: test 14 fails
Problem:    Test 14 fails.
Solution:   Fix of-by-one error.
2018-02-09 19:24:01 +01:00
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
28 changed files with 398 additions and 154 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,14 +480,12 @@ 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
InstallOptions::dialog "$PLUGINSDIR\vimrc.ini"
Pop $3
FunctionEnd

View File

@@ -4484,10 +4484,13 @@ getcwd([{winnr} [, {tabnr}]])
Without arguments, for the current window.
With {winnr} return the local current directory of this window
in the current tab page.
in the current tab page. {winnr} can be the window number or
the |window-ID|.
If {winnr} is -1 return the name of the global working
directory. See also |haslocaldir()|.
With {winnr} and {tabnr} return the local current directory of
the window in the specified tab page.
{winnr} can be the window number or the |window-ID|.
Return an empty string if the arguments are invalid.
getfsize({fname}) *getfsize()*

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;
@@ -1563,8 +1569,8 @@ normalchar:
/* If typed something may trigger CursorHoldI again. */
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
/* but not in CTRL-X mode, a script can't restore the state */
&& 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;
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,8 +5188,9 @@ 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
|| ctrl_x_mode == CTRL_X_PATH_DEFINES)
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

@@ -4613,16 +4613,21 @@ f_getcwd(typval_T *argvars, typval_T *rettv)
{
win_T *wp = NULL;
char_u *cwd;
int global = FALSE;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
wp = find_tabwin(&argvars[0], &argvars[1]);
if (wp != NULL)
if (argvars[0].v_type == VAR_NUMBER && argvars[0].vval.v_number == -1)
global = TRUE;
else
wp = find_tabwin(&argvars[0], &argvars[1]);
if (wp != NULL && wp->w_localdir != NULL)
rettv->vval.v_string = vim_strsave(wp->w_localdir);
else if (wp != NULL || global)
{
if (wp->w_localdir != NULL)
rettv->vval.v_string = vim_strsave(wp->w_localdir);
else if (globaldir != NULL)
if (globaldir != NULL)
rettv->vval.v_string = vim_strsave(globaldir);
else
{
@@ -7977,7 +7982,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

@@ -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)
@@ -5173,8 +5186,8 @@ ff_wc_equal(char_u *s1, char_u *s2)
prev2 = prev1;
prev1 = c1;
i += MB_PTR2LEN(s1 + i);
j += MB_PTR2LEN(s2 + j);
i += MB_PTR2LEN(s1 + i);
j += MB_PTR2LEN(s2 + j);
}
return s1[i] == s2[j];
}
@@ -5892,7 +5905,7 @@ pathcmp(const char *p, const char *q, int maxlen)
if (c2 == NUL) /* full match */
return 0;
s = q;
i = j;
i = j;
break;
}

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
@@ -6370,7 +6379,7 @@ write_viminfo_registers(FILE *fp)
* |{bartype},{flags},{name},{type},
* {linecount},{width},{timestamp},"line1","line2"
* flags: REG_PREVIOUS - register is y_previous
* REG_EXEC - used for @@
* REG_EXEC - used for @@
*/
if (y_previous == &y_regs[i])
flags |= REG_PREVIOUS;

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

@@ -6183,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;
}
@@ -2795,7 +2794,7 @@ fold_line(
{
ScreenLinesUC[off + col] = fill_fold;
ScreenLinesC[0][off + col] = 0;
ScreenLines[off + col] = 0x80; /* avoid storing zero */
ScreenLines[off + col] = 0x80; /* avoid storing zero */
}
else
{

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

@@ -2958,12 +2958,9 @@ matching_line_len(char_u *lbuf)
char_u *p = lbuf + 1;
/* does the same thing as parse_match() */
p += STRLEN(p) + 2;
p += STRLEN(p) + 1;
#ifdef FEAT_EMACS_TAGS
if (*p)
p += STRLEN(p);
else
++p;
p += STRLEN(p) + 1;
#endif
return (p - lbuf) + STRLEN(p);
}

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;
@@ -630,7 +640,7 @@ free_terminal(buf_T *buf)
{
if (term->tl_job->jv_status != JOB_ENDED
&& term->tl_job->jv_status != JOB_FINISHED
&& term->tl_job->jv_status != JOB_FAILED)
&& term->tl_job->jv_status != JOB_FAILED)
job_stop(term->tl_job, NULL, "kill");
job_unref(term->tl_job);
}
@@ -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
@@ -3292,7 +3334,7 @@ term_send_eof(channel_T *ch)
#define WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN 1ul
#define WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN 2ull
#define WINPTY_MOUSE_MODE_FORCE 2
#define WINPTY_MOUSE_MODE_FORCE 2
void* (*winpty_config_new)(UINT64, void*);
void* (*winpty_open)(void*, void*);

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

@@ -37,6 +37,7 @@ function SetUp()
new
call mkdir('Xtopdir')
cd Xtopdir
let g:topdir = getcwd()
call mkdir('Xdir1')
call mkdir('Xdir2')
call mkdir('Xdir3')
@@ -56,36 +57,44 @@ function Test_GetCwd()
3wincmd w
lcd Xdir1
call assert_equal("a Xdir1 1", GetCwdInfo(0, 0))
call assert_equal(g:topdir, getcwd(-1))
wincmd W
call assert_equal("b Xtopdir 0", GetCwdInfo(0, 0))
call assert_equal(g:topdir, getcwd(-1))
wincmd W
lcd Xdir3
call assert_equal("c Xdir3 1", GetCwdInfo(0, 0))
call assert_equal("a Xdir1 1", GetCwdInfo(bufwinnr("a"), 0))
call assert_equal("b Xtopdir 0", GetCwdInfo(bufwinnr("b"), 0))
call assert_equal("c Xdir3 1", GetCwdInfo(bufwinnr("c"), 0))
call assert_equal(g:topdir, getcwd(-1))
wincmd W
call assert_equal("a Xdir1 1", GetCwdInfo(bufwinnr("a"), tabpagenr()))
call assert_equal("b Xtopdir 0", GetCwdInfo(bufwinnr("b"), tabpagenr()))
call assert_equal("c Xdir3 1", GetCwdInfo(bufwinnr("c"), tabpagenr()))
call assert_equal(g:topdir, getcwd(-1))
tabnew x
new y
new z
3wincmd w
call assert_equal("x Xtopdir 0", GetCwdInfo(0, 0))
call assert_equal(g:topdir, getcwd(-1))
wincmd W
lcd Xdir2
call assert_equal("y Xdir2 1", GetCwdInfo(0, 0))
call assert_equal(g:topdir, getcwd(-1))
wincmd W
lcd Xdir3
call assert_equal("z Xdir3 1", GetCwdInfo(0, 0))
call assert_equal("x Xtopdir 0", GetCwdInfo(bufwinnr("x"), 0))
call assert_equal("y Xdir2 1", GetCwdInfo(bufwinnr("y"), 0))
call assert_equal("z Xdir3 1", GetCwdInfo(bufwinnr("z"), 0))
call assert_equal(g:topdir, getcwd(-1))
let tp_nr = tabpagenr()
tabrewind
call assert_equal("x Xtopdir 0", GetCwdInfo(3, tp_nr))
call assert_equal("y Xdir2 1", GetCwdInfo(2, tp_nr))
call assert_equal("z Xdir3 1", GetCwdInfo(1, tp_nr))
call assert_equal(g:topdir, getcwd(-1))
endfunc

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

@@ -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

@@ -229,4 +229,32 @@ func Test_tag_file_encoding()
call delete('Xtags1')
endfunc
func Test_tagjump_etags()
if !has('emacs_tags')
return
endif
call writefile([
\ "void foo() {}",
\ "int main(int argc, char **argv)",
\ "{",
\ "\tfoo();",
\ "\treturn 0;",
\ "}",
\ ], 'Xmain.c')
call writefile([
\ "\x0c",
\ "Xmain.c,64",
\ "void foo() {}\x7ffoo\x011,0",
\ "int main(int argc, char **argv)\x7fmain\x012,14",
\ ], 'Xtags')
set tags=Xtags
ta foo
call assert_equal('void foo() {}', getline('.'))
call delete('Xtags')
call delete('Xmain.c')
bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

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,44 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1489,
/**/
1488,
/**/
1487,
/**/
1486,
/**/
1485,
/**/
1484,
/**/
1483,
/**/
1482,
/**/
1481,
/**/
1480,
/**/
1479,
/**/
1478,
/**/
1477,
/**/
1476,
/**/
1475,
/**/
1474,
/**/
1473,
/**/
1472,
/**/
1471,
/**/
1470,
/**/

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 */