Merge remote-tracking branch 'vim/master'

This commit is contained in:
Yee Cheng Chin
2019-01-25 21:30:00 -08:00
11 changed files with 210 additions and 95 deletions
+1 -1
View File
@@ -8737,7 +8737,7 @@ ins_esc(
*/
if (reg_recording != 0 || restart_edit != NUL)
showmode();
else if (p_smd)
else if (p_smd && !skip_showmode())
msg("");
return TRUE; /* exit Insert mode */
+65 -21
View File
@@ -9494,15 +9494,55 @@ assert_fails(typval_T *argvars)
return ret;
}
/*
* Append "p[clen]" to "gap", escaping unprintable characters.
* Changes NL to \n, CR to \r, etc.
*/
static void
ga_concat_esc(garray_T *gap, char_u *p, int clen)
{
char_u buf[NUMBUFLEN];
if (clen > 1)
{
mch_memmove(buf, p, clen);
buf[clen] = NUL;
ga_concat(gap, buf);
}
else switch (*p)
{
case BS: ga_concat(gap, (char_u *)"\\b"); break;
case ESC: ga_concat(gap, (char_u *)"\\e"); break;
case FF: ga_concat(gap, (char_u *)"\\f"); break;
case NL: ga_concat(gap, (char_u *)"\\n"); break;
case TAB: ga_concat(gap, (char_u *)"\\t"); break;
case CAR: ga_concat(gap, (char_u *)"\\r"); break;
case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
default:
if (*p < ' ')
{
vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
ga_concat(gap, buf);
}
else
ga_append(gap, *p);
break;
}
}
/*
* Append "str" to "gap", escaping unprintable characters.
* Changes NL to \n, CR to \r, etc.
*/
static void
ga_concat_esc(garray_T *gap, char_u *str)
ga_concat_shorten_esc(garray_T *gap, char_u *str)
{
char_u *p;
char_u *s;
int c;
int clen;
char_u buf[NUMBUFLEN];
int same_len;
if (str == NULL)
{
@@ -9511,25 +9551,29 @@ ga_concat_esc(garray_T *gap, char_u *str)
}
for (p = str; *p != NUL; ++p)
switch (*p)
{
same_len = 1;
s = p;
c = mb_ptr2char_adv(&s);
clen = s - p;
while (*s != NUL && c == mb_ptr2char(s))
{
case BS: ga_concat(gap, (char_u *)"\\b"); break;
case ESC: ga_concat(gap, (char_u *)"\\e"); break;
case FF: ga_concat(gap, (char_u *)"\\f"); break;
case NL: ga_concat(gap, (char_u *)"\\n"); break;
case TAB: ga_concat(gap, (char_u *)"\\t"); break;
case CAR: ga_concat(gap, (char_u *)"\\r"); break;
case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
default:
if (*p < ' ')
{
vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
ga_concat(gap, buf);
}
else
ga_append(gap, *p);
break;
++same_len;
s += clen;
}
if (same_len > 20)
{
ga_concat(gap, (char_u *)"\\[");
ga_concat_esc(gap, p, clen);
ga_concat(gap, (char_u *)" occurs ");
vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len);
ga_concat(gap, buf);
ga_concat(gap, (char_u *)" times]");
p = s - 1;
}
else
ga_concat_esc(gap, p, clen);
}
}
/*
@@ -9562,11 +9606,11 @@ fill_assert_error(
ga_concat(gap, (char_u *)"Expected ");
if (exp_str == NULL)
{
ga_concat_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
ga_concat_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
vim_free(tofree);
}
else
ga_concat_esc(gap, exp_str);
ga_concat_shorten_esc(gap, exp_str);
if (atype != ASSERT_NOTEQUAL)
{
if (atype == ASSERT_MATCH)
@@ -9575,7 +9619,7 @@ fill_assert_error(
ga_concat(gap, (char_u *)" does match ");
else
ga_concat(gap, (char_u *)" but got ");
ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
vim_free(tofree);
}
}
+3 -2
View File
@@ -3039,9 +3039,10 @@ inchar(
/*
* Always flush the output characters when getting input characters
* from the user.
* from the user and not just peeking.
*/
out_flush();
if (wait_time == -1L || wait_time > 10L)
out_flush();
/*
* Fill up to a third of the buffer, because each character may be
+1
View File
@@ -49,6 +49,7 @@ int win_ins_lines(win_T *wp, int row, int line_count, int invalid, int mayclear)
int win_del_lines(win_T *wp, int row, int line_count, int invalid, int mayclear, int clear_attr);
int screen_ins_lines(int off, int row, int line_count, int end, int clear_attr, win_T *wp);
int screen_del_lines(int off, int row, int line_count, int end, int force, int clear_attr, win_T *wp);
int skip_showmode(void);
int showmode(void);
void unshowmode(int force);
void clearmode(void);
+22 -10
View File
@@ -10158,6 +10158,26 @@ screen_del_lines(
return OK;
}
/*
* Return TRUE when postponing displaying the mode message: when not redrawing
* or inside a mapping.
*/
int
skip_showmode()
{
// Call char_avail() only when we are going to show something, because it
// takes a bit of time. redrawing() may also call char_avail_avail().
if (global_busy
|| msg_silent != 0
|| !redrawing()
|| (char_avail() && !KeyTyped))
{
redraw_cmdline = TRUE; // show mode later
return TRUE;
}
return FALSE;
}
/*
* Show the current mode and ruler.
*
@@ -10184,16 +10204,8 @@ showmode(void)
|| VIsual_active));
if (do_mode || reg_recording != 0)
{
/*
* Don't show mode right now, when not redrawing or inside a mapping.
* Call char_avail() only when we are going to show something, because
* it takes a bit of time.
*/
if (!redrawing() || (char_avail() && !KeyTyped) || msg_silent != 0)
{
redraw_cmdline = TRUE; /* show mode later */
return 0;
}
if (skip_showmode())
return 0; // show mode later
nwr_save = need_wait_return;
+4
View File
@@ -31,6 +31,10 @@ func Test_assert_equal()
call assert_equal(1, assert_equal('bar', s))
call assert_match("Expected 'bar' but got 'foo'", v:errors[0])
call remove(v:errors, 0)
call assert_equal('XxxxxxxxxxxxxxxxxxxxxxX', 'XyyyyyyyyyyyyyyyyyyyyyyyyyX')
call assert_match("Expected 'X\\\\\\[x occurs 21 times]X' but got 'X\\\\\\[y occurs 25 times]X'", v:errors[0])
call remove(v:errors, 0)
endfunc
func Test_assert_equalfile()
+41 -37
View File
@@ -885,19 +885,19 @@ endfunc
func Test_pipe_err_to_buffer_name()
call Run_test_pipe_err_to_buffer(1, 0, 1)
endfunc
func Test_pipe_err_to_buffer_nr()
call Run_test_pipe_err_to_buffer(0, 0, 1)
endfunc
func Test_pipe_err_to_buffer_name_nomod()
call Run_test_pipe_err_to_buffer(1, 1, 1)
endfunc
func Test_pipe_err_to_buffer_name_nomsg()
call Run_test_pipe_err_to_buffer(1, 0, 0)
endfunc
func Test_pipe_both_to_buffer()
if !has('job')
return
@@ -972,15 +972,15 @@ func Run_pipe_through_sort(all, use_buffer)
let options.in_top = 2
let options.in_bot = 4
endif
let g:job = job_start('sort', options)
let job = job_start('sort', options)
if !a:use_buffer
call assert_equal("run", job_status(g:job))
call ch_sendraw(g:job, "ccc\naaa\nddd\nbbb\neee\n")
call ch_close_in(g:job)
call assert_equal("run", job_status(job))
call ch_sendraw(job, "ccc\naaa\nddd\nbbb\neee\n")
call ch_close_in(job)
endif
call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
call WaitForAssert({-> assert_equal("dead", job_status(job))})
sp sortout
call WaitFor('line("$") > 3')
@@ -991,8 +991,7 @@ func Run_pipe_through_sort(all, use_buffer)
call assert_equal(['aaa', 'bbb', 'ddd'], getline(2, 4))
endif
call job_stop(g:job)
unlet g:job
call job_stop(job)
if a:use_buffer
bwipe! sortin
endif
@@ -1192,7 +1191,8 @@ func Test_pipe_to_buffer_raw()
split testout
let job = job_start([s:python, '-c',
\ 'import sys; [sys.stdout.write(".") and sys.stdout.flush() for _ in range(10000)]'], options)
call assert_equal("run", job_status(job))
" the job may be done quickly, also accept "dead"
call assert_match('^\%(dead\|run\)$', job_status(job))
call WaitFor('len(join(getline(1, "$"), "")) >= 10000')
try
let totlen = 0
@@ -1253,9 +1253,9 @@ func Test_out_cb()
endfunc
let job = job_start(s:python . " test_channel_pipe.py",
\ {'out_cb': dict.outHandler,
\ 'out_mode': 'json',
\ 'err_cb': dict.errHandler,
\ 'err_mode': 'json'})
\ 'out_mode': 'json',
\ 'err_cb': dict.errHandler,
\ 'err_mode': 'json'})
call assert_equal("run", job_status(job))
try
let g:Ch_outmsg = ''
@@ -1296,8 +1296,9 @@ func Test_out_close_cb()
endfunc
let job = job_start(s:python . " test_channel_pipe.py quit now",
\ {'out_cb': 'OutHandler',
\ 'close_cb': 'CloseHandler'})
call assert_equal("run", job_status(job))
\ 'close_cb': 'CloseHandler'})
" the job may be done quickly, also accept "dead"
call assert_match('^\%(dead\|run\)$', job_status(job))
try
call WaitForAssert({-> assert_equal('quit', g:Ch_msg1)})
call WaitForAssert({-> assert_equal(2, g:Ch_closemsg)})
@@ -1320,7 +1321,8 @@ func Test_read_in_close_cb()
endfunc
let job = job_start(s:python . " test_channel_pipe.py quit now",
\ {'close_cb': 'CloseHandler'})
call assert_equal("run", job_status(job))
" the job may be done quickly, also accept "dead"
call assert_match('^\%(dead\|run\)$', job_status(job))
try
call WaitForAssert({-> assert_equal('quit', g:Ch_received)})
finally
@@ -1344,7 +1346,8 @@ func Test_read_in_close_cb_incomplete()
endfunc
let job = job_start(s:python . " test_channel_pipe.py incomplete",
\ {'close_cb': 'CloseHandler'})
call assert_equal("run", job_status(job))
" the job may be done quickly, also accept "dead"
call assert_match('^\%(dead\|run\)$', job_status(job))
try
call WaitForAssert({-> assert_equal('incomplete', g:Ch_received)})
finally
@@ -1360,10 +1363,10 @@ func Test_out_cb_lambda()
call ch_log('Test_out_cb_lambda()')
let job = job_start(s:python . " test_channel_pipe.py",
\ {'out_cb': {ch, msg -> execute("let g:Ch_outmsg = 'lambda: ' . msg")},
\ 'out_mode': 'json',
\ 'err_cb': {ch, msg -> execute(":let g:Ch_errmsg = 'lambda: ' . msg")},
\ 'err_mode': 'json'})
\ {'out_cb': {ch, msg -> execute("let g:Ch_outmsg = 'lambda: ' . msg")},
\ 'out_mode': 'json',
\ 'err_cb': {ch, msg -> execute(":let g:Ch_errmsg = 'lambda: ' . msg")},
\ 'err_mode': 'json'})
call assert_equal("run", job_status(job))
try
let g:Ch_outmsg = ''
@@ -1391,14 +1394,13 @@ func Test_close_and_exit_cb()
let self.ret['exit_cb'] = job_status(a:job)
endfunc
let g:job = job_start(has('win32') ? 'cmd /c echo:' : 'echo', {
\ 'close_cb': g:retdict.close_cb,
\ 'exit_cb': g:retdict.exit_cb,
\ })
call assert_equal('run', job_status(g:job))
unlet g:job
let job = job_start([&shell, &shellcmdflag, 'echo'],
\ {'close_cb': g:retdict.close_cb,
\ 'exit_cb': g:retdict.exit_cb})
" the job may be done quickly, also accept "dead"
call assert_match('^\%(dead\|run\)$', job_status(job))
call WaitForAssert({-> assert_equal(2, len(g:retdict.ret))})
call assert_match('^\%(dead\|run\)', g:retdict.ret['close_cb'])
call assert_match('^\%(dead\|run\)$', g:retdict.ret['close_cb'])
call assert_equal('dead', g:retdict.ret['exit_cb'])
unlet g:retdict
endfunc
@@ -1421,7 +1423,7 @@ func Test_exit_cb_wipes_buf()
let g:wipe_buf = bufnr('')
let job = job_start(has('win32') ? 'cmd /c echo:' : ['true'],
\ {'exit_cb': 'ExitCbWipe'})
\ {'exit_cb': 'ExitCbWipe'})
let timer = timer_start(300, {-> feedkeys("\<Esc>", 'nt')}, {'repeat': 5})
call feedkeys(repeat('g', 1000) . 'o', 'ntx!')
call WaitForAssert({-> assert_equal("dead", job_status(job))})
@@ -1939,7 +1941,8 @@ func Test_keep_pty_open()
return
endif
let job = job_start(s:python . ' -c "import time;time.sleep(0.2)"', {'out_io': 'null', 'err_io': 'null', 'pty': 1})
let job = job_start(s:python . ' -c "import time;time.sleep(0.2)"',
\ {'out_io': 'null', 'err_io': 'null', 'pty': 1})
let elapsed = WaitFor({-> job_status(job) ==# 'dead'})
call assert_inrange(200, 1000, elapsed)
call job_stop(job)
@@ -1991,13 +1994,14 @@ func Test_raw_large_data()
try
let g:out = ''
let job = job_start(s:python . " test_channel_pipe.py",
\ {'mode': 'raw', 'drop': 'never', 'noblock': 1,
\ 'callback': {ch, msg -> execute('let g:out .= msg')}})
\ {'mode': 'raw', 'drop': 'never', 'noblock': 1,
\ 'callback': {ch, msg -> execute('let g:out .= msg')}})
let want = repeat('X', 79999) . "\n"
let outlen = 79999
let want = repeat('X', outlen) . "\n"
call ch_sendraw(job, want)
let g:Ch_job = job
call WaitForAssert({-> assert_equal("dead", job_status(g:Ch_job))})
call WaitFor({-> len(g:out) >= outlen}, 10000)
call WaitForAssert({-> assert_equal("dead", job_status(job))})
call assert_equal(want, substitute(g:out, '\r', '', 'g'))
finally
call job_stop(job)
+1 -1
View File
@@ -96,7 +96,7 @@ func Test_FileChangedShell_reload()
endfunc
func Test_file_changed_dialog()
if !has('unix')
if !has('unix') || has('gui_running')
return
endif
au! FileChangedShell
+60 -19
View File
@@ -20,7 +20,7 @@ endfunc
func Test_xxd()
call PrepareBuffer(range(1,30))
set ff=unix
w XXDfile
w! XXDfile
" Test 1: simple, filter the result through xxd
let s:test = 1
@@ -39,15 +39,19 @@ func Test_xxd()
exe '%!' . s:xxd_cmd . ' -r'
call assert_equal(map(range(1,30), {v,c -> string(c)}), getline(1,'$'), s:Mess(s:test))
" Test 3: Skip the first 30 bytes
" Test 3: Skip the first 0x30 bytes
let s:test += 1
exe '%!' . s:xxd_cmd . ' -s 0x30 %'
call assert_equal(expected[3:], getline(1,'$'), s:Mess(s:test))
for arg in ['-s 0x30', '-s0x30', '-s+0x30', '-skip 0x030', '-seek 0x30', '-seek +0x30 --']
exe '%!' . s:xxd_cmd . ' ' . arg . ' %'
call assert_equal(expected[3:], getline(1,'$'), s:Mess(s:test))
endfor
" Test 4: Skip the first 30 bytes
let s:test += 1
exe '%!' . s:xxd_cmd . ' -s -0x31 %'
call assert_equal(expected[2:], getline(1,'$'), s:Mess(s:test))
for arg in ['-s -0x31', '-s-0x31']
exe '%!' . s:xxd_cmd . ' ' . arg . ' %'
call assert_equal(expected[2:], getline(1,'$'), s:Mess(s:test))
endfor
" Test 5: Print 120 bytes as continuous hexdump with 20 octets per line
let s:test += 1
@@ -56,7 +60,7 @@ func Test_xxd()
if has('win32') && !filereadable(fname)
let fname = '../../doc/xxd.1'
endif
exe '0r! ' . s:xxd_cmd . ' -l 120 -ps -c 20 ' . fname
exe '0r! ' . s:xxd_cmd . ' -l 120 -ps -c20 ' . fname
$d
let expected = [
\ '2e54482058584420312022417567757374203139',
@@ -69,10 +73,12 @@ func Test_xxd()
" Test 6: Print the date from xxd.1
let s:test += 1
%d
exe '0r! ' . s:xxd_cmd . ' -s 0x36 -l 13 -c 13 ' . fname
$d
call assert_equal('00000036: 3231 7374 204d 6179 2031 3939 36 21st May 1996', getline(1), s:Mess(s:test))
for arg in ['-l 13', '-l13', '-len 13']
%d
exe '0r! ' . s:xxd_cmd . ' -s 0x36 -l 13 -cols 13 ' . fname
$d
call assert_equal('00000036: 3231 7374 204d 6179 2031 3939 36 21st May 1996', getline(1), s:Mess(s:test))
endfor
" Test 7: Print C include
let s:test += 1
@@ -87,14 +93,16 @@ func Test_xxd()
" Test 8: Print C include capitalized
let s:test += 1
call writefile(['TESTabcd09'], 'XXDfile')
%d
exe '0r! ' . s:xxd_cmd . ' -i -C XXDfile'
$d
let expected = ['unsigned char XXDFILE[] = {',
\ ' 0x54, 0x45, 0x53, 0x54, 0x61, 0x62, 0x63, 0x64, 0x30, 0x39, 0x0a', '};',
\ 'unsigned int XXDFILE_LEN = 11;']
call assert_equal(expected, getline(1,'$'), s:Mess(s:test))
for arg in ['-C', '-capitalize']
call writefile(['TESTabcd09'], 'XXDfile')
%d
exe '0r! ' . s:xxd_cmd . ' -i ' . arg . ' XXDfile'
$d
let expected = ['unsigned char XXDFILE[] = {',
\ ' 0x54, 0x45, 0x53, 0x54, 0x61, 0x62, 0x63, 0x64, 0x30, 0x39, 0x0a', '};',
\ 'unsigned int XXDFILE_LEN = 11;']
call assert_equal(expected, getline(1,'$'), s:Mess(s:test))
endfor
" Test 9: Create a file with containing a single 'A'
let s:test += 1
@@ -110,6 +118,39 @@ func Test_xxd()
call PrepareBuffer(readfile('XXDfile')[0])
call assert_equal('A', getline(1), s:Mess(s:test))
call delete('XXDfile')
" Test 10: group with 4 octets
let s:test += 1
for arg in ['-g 4', '-group 4', '-g4']
call writefile(['TESTabcd09'], 'XXDfile')
%d
exe '0r! ' . s:xxd_cmd . ' ' . arg . ' XXDfile'
$d
let expected = ['00000000: 54455354 61626364 30390a TESTabcd09.']
call assert_equal(expected, getline(1,'$'), s:Mess(s:test))
call delete('XXDfile')
endfor
" TODO:
" -o -offset
%d
bw!
endfunc
" Various ways with wrong arguments that trigger the usage output.
func Test_xxd_usage()
for arg in ['-c', '-g', '-o', '-s', '-l', '-X', 'one two three']
new
exe 'r! ' . s:xxd_cmd . ' ' . arg
call assert_match("Usage:", join(getline(1, 3)))
bwipe!
endfor
endfunc
func Test_xxd_version()
new
exe 'r! ' . s:xxd_cmd . ' -v'
call assert_match("xxd V1.10 .* by Juergen Weigert", join(getline(1, 3)))
bwipe!
endfunc
+8
View File
@@ -802,6 +802,14 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
822,
/**/
821,
/**/
820,
/**/
819,
/**/
818,
/**/
+4 -4
View File
@@ -508,10 +508,10 @@ main(int argc, char *argv[])
}
else if (!STRNCMP(pp, "-c", 2))
{
if (pp[2] && STRNCMP("ols", pp + 2, 3))
cols = (int)strtol(pp + 2, NULL, 0);
else if (pp[2] && STRNCMP("apitalize", pp + 2, 9))
if (pp[2] && !STRNCMP("apitalize", pp + 2, 9))
capitalize = 1;
else if (pp[2] && STRNCMP("ols", pp + 2, 3))
cols = (int)strtol(pp + 2, NULL, 0);
else
{
if (!argv[2])
@@ -523,7 +523,7 @@ main(int argc, char *argv[])
}
else if (!STRNCMP(pp, "-g", 2))
{
if (pp[2] && STRNCMP("group", pp + 2, 5))
if (pp[2] && STRNCMP("roup", pp + 2, 4))
octspergrp = (int)strtol(pp + 2, NULL, 0);
else
{