Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2016-10-15 21:31:00 -07:00
31 changed files with 415 additions and 141 deletions
+2
View File
@@ -4287,7 +4287,9 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
locale locale names (as output of locale -a)
mapping mapping name
menu menus
messages |:messages| suboptions
option options
packadd optional package |pack-add| names
shellcmd Shell command
sign |:sign| suboptions
syntax syntax file names |'syntax'|
+1
View File
@@ -1280,6 +1280,7 @@ completion can be enabled:
-complete=locale locale names (as output of locale -a)
-complete=mapping mapping name
-complete=menu menus
-complete=messages |:messages| suboptions
-complete=option options
-complete=packadd optional package |pack-add| names
-complete=shellcmd Shell command
+1 -1
View File
@@ -2064,7 +2064,7 @@ test1 \
test40 test41 test42 test43 test44 test45 test48 test49 \
test50 test51 test52 test53 test54 test55 test56 test57 test58 test59 \
test60 test64 test65 test66 test67 test68 test69 \
test70 test72 test73 test74 test75 test76 test77 test78 test79 \
test70 test72 test73 test74 test75 test77 test78 test79 \
test80 test82 test83 test84 test85 test86 test87 test88 test89 \
test90 test91 test92 test93 test94 test95 test97 test98 test99 \
test100 test101 test103 test104 test107 test108:
+59 -49
View File
@@ -4453,6 +4453,39 @@ job_free(job_T *job)
}
}
static void
job_cleanup(job_T *job)
{
if (job->jv_status != JOB_ENDED)
return;
if (job->jv_exit_cb != NULL)
{
typval_T argv[3];
typval_T rettv;
int dummy;
/* invoke the exit callback; make sure the refcount is > 0 */
++job->jv_refcount;
argv[0].v_type = VAR_JOB;
argv[0].vval.v_job = job;
argv[1].v_type = VAR_NUMBER;
argv[1].vval.v_number = job->jv_exitval;
call_func(job->jv_exit_cb, (int)STRLEN(job->jv_exit_cb),
&rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE,
job->jv_exit_partial, NULL);
clear_tv(&rettv);
--job->jv_refcount;
channel_need_redraw = TRUE;
}
if (job->jv_refcount == 0)
{
/* The job was already unreferenced, now that it ended it can be
* freed. Careful: caller must not use "job" after this! */
job_free(job);
}
}
#if defined(EXITFREE) || defined(PROTO)
void
job_free_all(void)
@@ -4470,10 +4503,15 @@ job_free_all(void)
static int
job_still_useful(job_T *job)
{
return job->jv_status == JOB_STARTED
&& (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL
|| (job->jv_channel != NULL
&& channel_still_useful(job->jv_channel)));
return (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL
|| (job->jv_channel != NULL
&& channel_still_useful(job->jv_channel)));
}
static int
job_still_alive(job_T *job)
{
return (job->jv_status == JOB_STARTED) && job_still_useful(job);
}
/*
@@ -4487,7 +4525,7 @@ set_ref_in_job(int copyID)
typval_T tv;
for (job = first_job; job != NULL; job = job->jv_next)
if (job_still_useful(job))
if (job_still_alive(job))
{
tv.v_type = VAR_JOB;
tv.vval.v_job = job;
@@ -4503,7 +4541,7 @@ job_unref(job_T *job)
{
/* Do not free the job when it has not ended yet and there is a
* "stoponexit" flag or an exit callback. */
if (!job_still_useful(job))
if (!job_still_alive(job))
{
job_free(job);
}
@@ -4528,7 +4566,7 @@ free_unused_jobs_contents(int copyID, int mask)
for (job = first_job; job != NULL; job = job->jv_next)
if ((job->jv_copyID & mask) != (copyID & mask)
&& !job_still_useful(job))
&& !job_still_alive(job))
{
/* Free the channel and ordinary items it contains, but don't
* recurse into Lists, Dictionaries etc. */
@@ -4548,7 +4586,7 @@ free_unused_jobs(int copyID, int mask)
{
job_next = job->jv_next;
if ((job->jv_copyID & mask) != (copyID & mask)
&& !job_still_useful(job))
&& !job_still_alive(job))
{
/* Free the job struct itself. */
job_free_job(job);
@@ -4639,34 +4677,31 @@ has_pending_job(void)
job_T *job;
for (job = first_job; job != NULL; job = job->jv_next)
if (job->jv_status == JOB_STARTED && job_still_useful(job))
if (job_still_alive(job))
return TRUE;
return FALSE;
}
#define MAX_CHECK_ENDED 8
/*
* Called once in a while: check if any jobs that seem useful have ended.
*/
void
job_check_ended(void)
{
static time_t last_check = 0;
time_t now;
job_T *job;
job_T *next;
int i;
/* Only do this once in 10 seconds. */
now = time(NULL);
if (last_check + 10 < now)
for (i = 0; i < MAX_CHECK_ENDED; ++i)
{
last_check = now;
for (job = first_job; job != NULL; job = next)
{
next = job->jv_next;
if (job->jv_status == JOB_STARTED && job_still_useful(job))
job_status(job); /* may free "job" */
}
job_T *job = mch_detect_ended_job(first_job);
if (job == NULL)
break;
if (job_still_useful(job))
job_cleanup(job); /* may free "job" */
}
if (channel_need_redraw)
{
channel_need_redraw = FALSE;
@@ -4887,32 +4922,7 @@ job_status(job_T *job)
{
result = mch_job_status(job);
if (job->jv_status == JOB_ENDED)
ch_log(job->jv_channel, "Job ended");
if (job->jv_status == JOB_ENDED && job->jv_exit_cb != NULL)
{
typval_T argv[3];
typval_T rettv;
int dummy;
/* invoke the exit callback; make sure the refcount is > 0 */
++job->jv_refcount;
argv[0].v_type = VAR_JOB;
argv[0].vval.v_job = job;
argv[1].v_type = VAR_NUMBER;
argv[1].vval.v_number = job->jv_exitval;
call_func(job->jv_exit_cb, (int)STRLEN(job->jv_exit_cb),
&rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE,
job->jv_exit_partial, NULL);
clear_tv(&rettv);
--job->jv_refcount;
channel_need_redraw = TRUE;
}
if (job->jv_status == JOB_ENDED && job->jv_refcount == 0)
{
/* The job was already unreferenced, now that it ended it can be
* freed. Careful: caller must not use "job" after this! */
job_free(job);
}
job_cleanup(job);
}
return result;
}
+22 -16
View File
@@ -179,8 +179,8 @@ static void ins_compl_add_dict(dict_T *dict);
#endif
static int ins_compl_get_exp(pos_T *ini);
static void ins_compl_delete(void);
static void ins_compl_insert(void);
static int ins_compl_next(int allow_get_expansion, int count, int insert_match);
static void ins_compl_insert(int in_compl_func);
static int ins_compl_next(int allow_get_expansion, int count, int insert_match, int in_compl_func);
static int ins_compl_key2dir(int c);
static int ins_compl_pum_key(int c);
static int ins_compl_key2count(int c);
@@ -861,7 +861,7 @@ edit(
&& (c == CAR || c == K_KENTER || c == NL)))
{
ins_compl_delete();
ins_compl_insert();
ins_compl_insert(FALSE);
}
}
}
@@ -3306,7 +3306,7 @@ ins_compl_files(
break;
}
line_breakcheck();
ins_compl_check_keys(50);
ins_compl_check_keys(50, FALSE);
}
fclose(fp);
}
@@ -4050,8 +4050,6 @@ ins_compl_next_buf(buf_T *buf, int flag)
}
#ifdef FEAT_COMPL_FUNC
static void expand_by_function(int type, char_u *base);
/*
* Execute user defined complete function 'completefunc' or 'omnifunc', and
* get matches in "matches".
@@ -4610,7 +4608,7 @@ ins_compl_get_exp(pos_T *ini)
break;
/* Fill the popup menu as soon as possible. */
if (type != -1)
ins_compl_check_keys(0);
ins_compl_check_keys(0, FALSE);
if ((ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
|| compl_interrupted)
@@ -4667,9 +4665,12 @@ ins_compl_delete(void)
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
}
/* Insert the new text being completed. */
/*
* Insert the new text being completed.
* "in_compl_func" is TRUE when called from complete_check().
*/
static void
ins_compl_insert(void)
ins_compl_insert(int in_compl_func)
{
dict_T *dict;
@@ -4696,7 +4697,8 @@ ins_compl_insert(void)
EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_INFO]));
}
set_vim_var_dict(VV_COMPLETED_ITEM, dict);
compl_curr_match = compl_shown_match;
if (!in_compl_func)
compl_curr_match = compl_shown_match;
}
/*
@@ -4720,7 +4722,8 @@ ins_compl_next(
int allow_get_expansion,
int count, /* repeat completion this many times; should
be at least 1 */
int insert_match) /* Insert the newly selected match */
int insert_match, /* Insert the newly selected match */
int in_compl_func) /* called from complete_check() */
{
int num_matches = -1;
int i;
@@ -4870,7 +4873,7 @@ ins_compl_next(
else if (insert_match)
{
if (!compl_get_longest || compl_used_match)
ins_compl_insert();
ins_compl_insert(in_compl_func);
else
ins_bytes(compl_leader + ins_compl_len());
}
@@ -4935,9 +4938,11 @@ ins_compl_next(
* mode. Also, when compl_pending is not zero, show a completion as soon as
* possible. -- webb
* "frequency" specifies out of how many calls we actually check.
* "in_compl_func" is TRUE when called from complete_check(), don't set
* compl_curr_match.
*/
void
ins_compl_check_keys(int frequency)
ins_compl_check_keys(int frequency, int in_compl_func)
{
static int count = 0;
@@ -4963,7 +4968,7 @@ ins_compl_check_keys(int frequency)
c = safe_vgetc(); /* Eat the character */
compl_shows_dir = ins_compl_key2dir(c);
(void)ins_compl_next(FALSE, ins_compl_key2count(c),
c != K_UP && c != K_DOWN);
c != K_UP && c != K_DOWN, in_compl_func);
}
else
{
@@ -4986,7 +4991,7 @@ ins_compl_check_keys(int frequency)
int todo = compl_pending > 0 ? compl_pending : -compl_pending;
compl_pending = 0;
(void)ins_compl_next(FALSE, todo, TRUE);
(void)ins_compl_next(FALSE, todo, TRUE, in_compl_func);
}
}
@@ -5504,7 +5509,8 @@ ins_complete(int c, int enable_pum)
* Find next match (and following matches).
*/
save_w_wrow = curwin->w_wrow;
n = ins_compl_next(TRUE, ins_compl_key2count(c), ins_compl_use_match(c));
n = ins_compl_next(TRUE, ins_compl_key2count(c),
ins_compl_use_match(c), FALSE);
/* may undisplay the popup menu */
ins_compl_upd_pum();
+1 -1
View File
@@ -2175,7 +2175,7 @@ f_complete_check(typval_T *argvars UNUSED, typval_T *rettv)
int saved = RedrawingDisabled;
RedrawingDisabled = 0;
ins_compl_check_keys(0);
ins_compl_check_keys(0, TRUE);
rettv->vval.v_number = compl_interrupted;
RedrawingDisabled = saved;
}
+18
View File
@@ -4291,6 +4291,11 @@ set_one_cmd_context(
xp->xp_pattern = arg;
break;
case CMD_messages:
xp->xp_context = EXPAND_MESSAGES;
xp->xp_pattern = arg;
break;
#if defined(FEAT_CMDHIST)
case CMD_history:
xp->xp_context = EXPAND_HISTORY;
@@ -5910,6 +5915,7 @@ static struct
#endif
{EXPAND_MAPPINGS, "mapping"},
{EXPAND_MENUS, "menu"},
{EXPAND_MESSAGES, "messages"},
{EXPAND_OWNSYNTAX, "syntax"},
#if defined(FEAT_PROFILE)
{EXPAND_SYNTIME, "syntime"},
@@ -11936,6 +11942,18 @@ get_behave_arg(expand_T *xp UNUSED, int idx)
return (char_u *)"xterm";
return NULL;
}
/*
* Function given to ExpandGeneric() to obtain the possible arguments of the
* ":messages {clear}" command.
*/
char_u *
get_messages_arg(expand_T *xp UNUSED, int idx)
{
if (idx == 0)
return (char_u *)"clear";
return NULL;
}
#endif
#ifdef FEAT_AUTOCMD
+1
View File
@@ -4843,6 +4843,7 @@ ExpandFromContext(
{
{EXPAND_COMMANDS, get_command_name, FALSE, TRUE},
{EXPAND_BEHAVE, get_behave_arg, TRUE, TRUE},
{EXPAND_MESSAGES, get_messages_arg, TRUE, TRUE},
#ifdef FEAT_CMDHIST
{EXPAND_HISTORY, get_history_arg, TRUE, TRUE},
#endif
+2 -1
View File
@@ -1597,7 +1597,8 @@ handle_viminfo_mark(garray_T *values, int force)
if (fm != NULL)
{
if (vi_namedfm != NULL || fm->time_set < timestamp || force)
if (vi_namedfm != NULL || fm->fmark.mark.lnum == 0
|| fm->time_set < timestamp || force)
{
fm->fmark.mark.lnum = lnum;
fm->fmark.mark.col = col;
+51 -6
View File
@@ -5316,8 +5316,7 @@ mch_job_status(job_T *job)
if (wait_pid == -1)
{
/* process must have exited */
job->jv_status = JOB_ENDED;
return "dead";
goto return_dead;
}
if (wait_pid == 0)
return "run";
@@ -5325,16 +5324,62 @@ mch_job_status(job_T *job)
{
/* LINTED avoid "bitwise operation on signed value" */
job->jv_exitval = WEXITSTATUS(status);
job->jv_status = JOB_ENDED;
return "dead";
goto return_dead;
}
if (WIFSIGNALED(status))
{
job->jv_exitval = -1;
job->jv_status = JOB_ENDED;
return "dead";
goto return_dead;
}
return "run";
return_dead:
if (job->jv_status != JOB_ENDED)
{
ch_log(job->jv_channel, "Job ended");
job->jv_status = JOB_ENDED;
}
return "dead";
}
job_T *
mch_detect_ended_job(job_T *job_list)
{
# ifdef HAVE_UNION_WAIT
union wait status;
# else
int status = -1;
# endif
pid_t wait_pid = 0;
job_T *job;
# ifdef __NeXT__
wait_pid = wait4(-1, &status, WNOHANG, (struct rusage *)0);
# else
wait_pid = waitpid(-1, &status, WNOHANG);
# endif
if (wait_pid <= 0)
/* no process ended */
return NULL;
for (job = job_list; job != NULL; job = job->jv_next)
{
if (job->jv_pid == wait_pid)
{
if (WIFEXITED(status))
/* LINTED avoid "bitwise operation on signed value" */
job->jv_exitval = WEXITSTATUS(status);
else if (WIFSIGNALED(status))
job->jv_exitval = -1;
if (job->jv_status != JOB_ENDED)
{
ch_log(job->jv_channel, "Job ended");
job->jv_status = JOB_ENDED;
}
return job;
}
}
return NULL;
}
int
+41 -1
View File
@@ -4973,13 +4973,53 @@ mch_job_status(job_T *job)
if (!GetExitCodeProcess(job->jv_proc_info.hProcess, &dwExitCode)
|| dwExitCode != STILL_ACTIVE)
{
job->jv_status = JOB_ENDED;
job->jv_exitval = (int)dwExitCode;
if (job->jv_status != JOB_ENDED)
{
ch_log(job->jv_channel, "Job ended");
job->jv_status = JOB_ENDED;
}
return "dead";
}
return "run";
}
job_T *
mch_detect_ended_job(job_T *job_list)
{
HANDLE jobHandles[MAXIMUM_WAIT_OBJECTS];
job_T *jobArray[MAXIMUM_WAIT_OBJECTS];
job_T *job = job_list;
while (job != NULL)
{
DWORD n;
DWORD result;
for (n = 0; n < MAXIMUM_WAIT_OBJECTS
&& job != NULL; job = job->jv_next)
{
if (job->jv_status == JOB_STARTED)
{
jobHandles[n] = job->jv_proc_info.hProcess;
jobArray[n] = job;
++n;
}
}
if (n == 0)
continue;
result = WaitForMultipleObjects(n, jobHandles, FALSE, 0);
if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + n)
{
job_T *wait_job = jobArray[result - WAIT_OBJECT_0];
if (STRCMP(mch_job_status(wait_job), "dead") == 0)
return wait_job;
}
}
return NULL;
}
int
mch_stop_job(job_T *job, char_u *how)
{
+1 -1
View File
@@ -15,7 +15,7 @@ char_u *find_word_start(char_u *ptr);
char_u *find_word_end(char_u *ptr);
int ins_compl_active(void);
int ins_compl_add_tv(typval_T *tv, int dir);
void ins_compl_check_keys(int frequency);
void ins_compl_check_keys(int frequency, int in_compl_func);
int get_literal(void);
void insertchar(int c, int flags, int second_indent);
void auto_format(int trailblank, int prev_line);
+1
View File
@@ -61,4 +61,5 @@ int put_eol(FILE *fd);
int put_line(FILE *fd, char *s);
void dialog_msg(char_u *buff, char *format, char_u *fname);
char_u *get_behave_arg(expand_T *xp, int idx);
char_u *get_messages_arg(expand_T *xp, int idx);
/* vim: set ft=c : */
+1
View File
@@ -59,6 +59,7 @@ int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc);
int mch_call_shell(char_u *cmd, int options);
void mch_start_job(char **argv, job_T *job, jobopt_T *options);
char *mch_job_status(job_T *job);
job_T *mch_detect_ended_job(job_T *job_list);
int mch_stop_job(job_T *job, char_u *how);
void mch_clear_job(job_T *job);
void mch_breakcheck(int force);
+1
View File
@@ -41,6 +41,7 @@ void mch_set_winsize_now(void);
int mch_call_shell(char_u *cmd, int options);
void mch_start_job(char *cmd, job_T *job, jobopt_T *options);
char *mch_job_status(job_T *job);
job_T *mch_detect_ended_job(job_T *job_list);
int mch_stop_job(job_T *job, char_u *how);
void mch_clear_job(job_T *job);
void mch_set_normal_colors(void);
+1 -1
View File
@@ -2266,7 +2266,7 @@ win_found:
ok = buflist_getfile(qf_ptr->qf_fnum,
(linenr_T)1, GETF_SETMARK | GETF_SWITCH, forceit);
if (qi != &ql_info && !win_valid(oldwin))
if (qi != &ql_info && !win_valid_any_tab(oldwin))
{
EMSG(_("E924: Current window was closed"));
is_abort = TRUE;
+8 -6
View File
@@ -7799,21 +7799,23 @@ next_search_hl_pos(
shl->lnum = 0;
for (i = posmatch->cur; i < MAXPOSMATCH; i++)
{
if (posmatch->pos[i].lnum == 0)
llpos_T *pos = &posmatch->pos[i];
if (pos->lnum == 0)
break;
if (posmatch->pos[i].col < mincol)
if (pos->col + pos->len - 1 <= mincol)
continue;
if (posmatch->pos[i].lnum == lnum)
if (pos->lnum == lnum)
{
if (shl->lnum == lnum)
{
/* partially sort positions by column numbers
* on the same line */
if (posmatch->pos[i].col < posmatch->pos[bot].col)
if (pos->col < posmatch->pos[bot].col)
{
llpos_T tmp = posmatch->pos[i];
llpos_T tmp = *pos;
posmatch->pos[i] = posmatch->pos[bot];
*pos = posmatch->pos[bot];
posmatch->pos[bot] = tmp;
}
}
+1 -1
View File
@@ -5444,7 +5444,7 @@ exit_matched:
#endif
#ifdef FEAT_INS_EXPAND
if (action == ACTION_EXPAND)
ins_compl_check_keys(30);
ins_compl_check_keys(30, FALSE);
if (got_int || compl_interrupted)
#else
if (got_int)
+1 -1
View File
@@ -8694,7 +8694,7 @@ spell_dump_compl(
/* Done all bytes at this node, go up one level. */
--depth;
line_breakcheck();
ins_compl_check_keys(50);
ins_compl_check_keys(50, FALSE);
}
else
{
+1 -1
View File
@@ -1587,7 +1587,7 @@ find_tags(
fast_breakcheck();
#ifdef FEAT_INS_EXPAND
if ((flags & TAG_INS_COMP)) /* Double brackets for gcc */
ins_compl_check_keys(30);
ins_compl_check_keys(30, FALSE);
if (got_int || compl_interrupted)
#else
if (got_int)
-1
View File
@@ -55,7 +55,6 @@ SCRIPTS_ALL = \
test70.out \
test73.out \
test75.out \
test76.out \
test77.out \
test79.out \
test80.out \
-46
View File
@@ -1,46 +0,0 @@
Tests for completefunc/omnifunc. vim: set ft=vim :
STARTTEST
:"Test that nothing happens if the 'completefunc' opens
:"a new window (no completion, no crash)
:so small.vim
:function! DummyCompleteOne(findstart, base)
: if a:findstart
: return 0
: else
: wincmd n
: return ['onedef', 'oneDEF']
: endif
:endfunction
:setlocal completefunc=DummyCompleteOne
/^one
A:q!
:function! DummyCompleteTwo(findstart, base)
: if a:findstart
: wincmd n
: return 0
: else
: return ['twodef', 'twoDEF']
: endif
:endfunction
:setlocal completefunc=DummyCompleteTwo
/^two
A:q!
:"Test that 'completefunc' works when it's OK.
:function! DummyCompleteThree(findstart, base)
: if a:findstart
: return 0
: else
: return ['threedef', 'threeDEF']
: endif
:endfunction
:setlocal completefunc=DummyCompleteThree
/^three
A:/^+++/,/^three/w! test.out
:qa!
ENDTEST
+++
one
two
three
-4
View File
@@ -1,4 +0,0 @@
+++
two
threeDEF
+18
View File
@@ -1362,6 +1362,24 @@ func Test_exit_callback()
endif
endfunc
let g:exit_cb_time = {'start': 0, 'end': 0}
function MyExitTimeCb(job, status)
let g:exit_cb_time.end = reltime(g:exit_cb_time.start)
endfunction
func Test_exit_callback_interval()
if !has('job')
return
endif
let g:exit_cb_time.start = reltime()
let job = job_start([s:python, '-c', 'import time;time.sleep(0.5)'], {'exit_cb': 'MyExitTimeCb'})
call WaitFor('g:exit_cb_time.end != 0')
let elapsed = reltimefloat(g:exit_cb_time.end)
call assert_true(elapsed > 0.3)
call assert_true(elapsed < 1.0)
endfunc
"""""""""
let g:Ch_close_ret = 'alive'
+5
View File
@@ -129,6 +129,11 @@ func Test_getcompletion()
let l = getcompletion('dark', 'highlight')
call assert_equal([], l)
let l = getcompletion('', 'messages')
call assert_true(index(l, 'clear') >= 0)
let l = getcompletion('not', 'messages')
call assert_equal([], l)
if has('cscope')
let l = getcompletion('', 'cscope')
let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show']
+10
View File
@@ -181,6 +181,16 @@ func Test_matchaddpos()
redraw!
call assert_equal(screenattr(2,2), screenattr(1,6))
" Check overlapping pos
call clearmatches()
call setline(1, ['1234567890', 'NH'])
call matchaddpos('Error', [[1,1,5], [1,3,5], [2,2]])
redraw!
call assert_notequal(screenattr(2,2), 0)
call assert_equal(screenattr(2,2), screenattr(1,5))
call assert_equal(screenattr(2,2), screenattr(1,7))
call assert_notequal(screenattr(2,2), screenattr(1,8))
nohl
syntax off
set hlsearch&
+111
View File
@@ -289,4 +289,115 @@ func Test_compl_vim_cmds_after_register_expr()
bwipe!
endfunc
func DummyCompleteOne(findstart, base)
if a:findstart
return 0
else
wincmd n
return ['onedef', 'oneDEF']
endif
endfunc
" Test that nothing happens if the 'completefunc' opens
" a new window (no completion, no crash)
func Test_completefunc_opens_new_window_one()
new
let winid = win_getid()
setlocal completefunc=DummyCompleteOne
call setline(1, 'one')
/^one
call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E839:')
call assert_notequal(winid, win_getid())
q!
call assert_equal(winid, win_getid())
call assert_equal('', getline(1))
q!
endfunc
" Test that nothing happens if the 'completefunc' opens
" a new window (no completion, no crash)
func DummyCompleteTwo(findstart, base)
if a:findstart
wincmd n
return 0
else
return ['twodef', 'twoDEF']
endif
endfunction
" Test that nothing happens if the 'completefunc' opens
" a new window (no completion, no crash)
func Test_completefunc_opens_new_window_two()
new
let winid = win_getid()
setlocal completefunc=DummyCompleteTwo
call setline(1, 'two')
/^two
call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E764:')
call assert_notequal(winid, win_getid())
q!
call assert_equal(winid, win_getid())
call assert_equal('two', getline(1))
q!
endfunc
func DummyCompleteThree(findstart, base)
if a:findstart
return 0
else
return ['threedef', 'threeDEF']
endif
endfunc
:"Test that 'completefunc' works when it's OK.
func Test_completefunc_works()
new
let winid = win_getid()
setlocal completefunc=DummyCompleteThree
call setline(1, 'three')
/^three
call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")
call assert_equal(winid, win_getid())
call assert_equal('threeDEF', getline(1))
q!
endfunc
func DummyCompleteFour(findstart, base)
if a:findstart
return 0
else
call complete_add('four1')
call complete_add('four2')
call complete_check()
call complete_add('four3')
call complete_add('four4')
call complete_check()
call complete_add('four5')
call complete_add('four6')
return []
endif
endfunc
:"Test that 'completefunc' works when it's OK.
func Test_omnifunc_with_check()
new
setlocal omnifunc=DummyCompleteFour
call setline(1, 'four')
/^four
call feedkeys("A\<C-X>\<C-O>\<C-N>\<Esc>", "x")
call assert_equal('four2', getline(1))
call setline(1, 'four')
/^four
call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<Esc>", "x")
call assert_equal('four3', getline(1))
call setline(1, 'four')
/^four
call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<C-N>\<Esc>", "x")
call assert_equal('four5', getline(1))
q!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+16
View File
@@ -617,6 +617,22 @@ function Test_locationlist_curwin_was_closed()
augroup! testgroup
endfunction
function Test_locationlist_cross_tab_jump()
call writefile(['loclistfoo'], 'loclistfoo')
call writefile(['loclistbar'], 'loclistbar')
set switchbuf=usetab
edit loclistfoo
tabedit loclistbar
silent lgrep loclistfoo loclist*
call assert_equal(1, tabpagenr())
enew | only | tabonly
set switchbuf&vim
call delete('loclistfoo')
call delete('loclistbar')
endfunction
" More tests for 'errorformat'
function! Test_efm1()
if !has('unix')
+23 -3
View File
@@ -1,6 +1,6 @@
" Test for reading and writing .viminfo
function Test_read_and_write()
function Test_viminfo_read_and_write()
call histdel(':')
let lines = [
\ '# comment line',
@@ -17,7 +17,7 @@ function Test_read_and_write()
let lines = readfile('Xviminfo')
let done = 0
for line in lines
if line[0] == '|' && line !~ '^|[234],'
if line[0] == '|' && line !~ '^|[234],' && line !~ '^|<'
if done == 0
call assert_equal('|1,4', line)
elseif done == 1
@@ -469,7 +469,27 @@ func Test_viminfo_file_mark_tabclose()
silent! bwipe Xtestfileintab
endfunc
func Test_oldfiles()
func Test_viminfo_file_mark_zero_time()
let lines = [
\ '# Viminfo version',
\ '|1,4',
\ '',
\ '*encoding=utf-8',
\ '',
\ '# File marks:',
\ "'B 1 0 /tmp/nothing",
\ '|4,66,1,0,0,"/tmp/nothing"',
\ "",
\ ]
call writefile(lines, 'Xviminfo')
delmark B
rviminfo Xviminfo
call delete('Xviminfo')
call assert_equal(1, line("'B"))
delmark B
endfunc
func Test_viminfo_oldfiles()
let v:oldfiles = []
let lines = [
\ '# comment line',
+14
View File
@@ -779,6 +779,20 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
39,
/**/
38,
/**/
37,
/**/
36,
/**/
35,
/**/
34,
/**/
33,
/**/
32,
/**/
+3 -1
View File
@@ -795,6 +795,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
#define EXPAND_SYNTIME 43
#define EXPAND_USER_ADDR_TYPE 44
#define EXPAND_PACKADD 45
#define EXPAND_MESSAGES 46
#define EXPAND_MACACTION 46
/* Values for exmode_active (0 is no exmode) */
@@ -2497,7 +2498,8 @@ typedef enum
#define FNE_INCL_BR 1 /* include [] in name */
#define FNE_CHECK_START 2 /* check name starts with valid character */
#if (defined(sun) || defined(__FreeBSD__)) && defined(S_ISCHR)
#if (defined(sun) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) \
&& defined(S_ISCHR)
# define OPEN_CHR_FILES
#endif