Merge pull request #5600 from jamessan/vim-7.4.1640

vim-patch:7.4.1640,7.4.1647,7.4.1650,7.4.1664
This commit is contained in:
James McCoy 2016-11-16 06:52:19 -05:00 committed by GitHub
commit 108d54bbd4
11 changed files with 150 additions and 31 deletions

View File

@ -5069,7 +5069,7 @@ msgpackdump({list}) {Nvim} *msgpackdump()*
(dictionary with zero items is represented by 0x80 byte in (dictionary with zero items is represented by 0x80 byte in
messagepack). messagepack).
Limitations: *E951* *E952* *E953* Limitations: *E5004* *E5005*
1. |Funcref|s cannot be dumped. 1. |Funcref|s cannot be dumped.
2. Containers that reference themselves cannot be dumped. 2. Containers that reference themselves cannot be dumped.
3. Dictionary keys are always dumped as STR strings. 3. Dictionary keys are always dumped as STR strings.

View File

@ -6512,7 +6512,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'ttyfast'* *'tf'* *'nottyfast'* *'notf'* *'ttyfast'* *'tf'* *'nottyfast'* *'notf'*
'ttyfast' 'tf' Removed. |vim-differences| {Nvim} 'ttyfast' 'tf' Removed. |vim-differences| {Nvim}
*'undodir'* *'udir'* *E926* *'undodir'* *'udir'* *E5003*
'undodir' 'udir' string (default "$XDG_DATA_HOME/nvim/undo") 'undodir' 'udir' string (default "$XDG_DATA_HOME/nvim/undo")
global global
{only when compiled with the |+persistent_undo| feature} {only when compiled with the |+persistent_undo| feature}

View File

@ -53,6 +53,10 @@ command with 'l'.
If the current window was closed by an |autocommand| while processing a If the current window was closed by an |autocommand| while processing a
location list command, it will be aborted. location list command, it will be aborted.
*E925* *E926*
If the current quickfix or location list was changed by an |autocommand| while
processing a quickfix or location list command, it will be aborted.
*:cc* *:cc*
:cc[!] [nr] Display error [nr]. If [nr] is omitted, the same :cc[!] [nr] Display error [nr]. If [nr] is omitted, the same
error is displayed again. Without [!] this doesn't error is displayed again. Without [!] this doesn't

View File

@ -836,7 +836,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
msgpack_pack_double(packer, (double) (flt)) msgpack_pack_double(packer, (double) (flt))
#define TYPVAL_ENCODE_CONV_FUNC(fun) \ #define TYPVAL_ENCODE_CONV_FUNC(fun) \
return conv_error(_("E951: Error while dumping %s, %s: " \ return conv_error(_("E5004: Error while dumping %s, %s: " \
"attempt to dump function reference"), \ "attempt to dump function reference"), \
mpstack, objname) mpstack, objname)
@ -880,7 +880,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS() #define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS()
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \ #define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
return conv_error(_("E952: Unable to dump %s: " \ return conv_error(_("E5005: Unable to dump %s: " \
"container references itself in %s"), \ "container references itself in %s"), \
mpstack, objname) mpstack, objname)

View File

@ -482,9 +482,11 @@ qf_init_ext (
p_str += len; p_str += len;
} else if (tv->v_type == VAR_LIST) { } else if (tv->v_type == VAR_LIST) {
/* Get the next line from the supplied list */ // Get the next line from the supplied list
while (p_li && p_li->li_tv.v_type != VAR_STRING) while (p_li && (p_li->li_tv.v_type != VAR_STRING
p_li = p_li->li_next; /* Skip non-string items */ || p_li->li_tv.vval.v_string == NULL)) {
p_li = p_li->li_next; // Skip non-string items
}
if (!p_li) /* End of the list */ if (!p_li) /* End of the list */
break; break;
@ -910,7 +912,9 @@ static int qf_add_entry(qf_info_T *qi, qfline_T **prevp, char_u *dir,
if (qi->qf_lists[qi->qf_curlist].qf_count == 0) { if (qi->qf_lists[qi->qf_curlist].qf_count == 0) {
/* first element in the list */ /* first element in the list */
qi->qf_lists[qi->qf_curlist].qf_start = qfp; qi->qf_lists[qi->qf_curlist].qf_start = qfp;
qfp->qf_prev = qfp; /* first element points to itself */ qi->qf_lists[qi->qf_curlist].qf_ptr = qfp;
qi->qf_lists[qi->qf_curlist].qf_index = 0;
qfp->qf_prev = qfp; // first element points to itself
} else { } else {
assert(*prevp); assert(*prevp);
qfp->qf_prev = *prevp; qfp->qf_prev = *prevp;
@ -1254,6 +1258,32 @@ static char_u *qf_guess_filepath(char_u *filename)
} }
/// When loading a file from the quickfix, the auto commands may modify it.
/// This may invalidate the current quickfix entry. This function checks
/// whether a entry is still present in the quickfix.
/// Similar to location list.
static bool is_qf_entry_present(qf_info_T *qi, qfline_T *qf_ptr)
{
qf_list_T *qfl;
qfline_T *qfp;
int i;
qfl = &qi->qf_lists[qi->qf_curlist];
// Search for the entry in the current list
for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count; i++, qfp = qfp->qf_next) {
if (qfp == qf_ptr) {
break;
}
}
if (i == qfl->qf_count) { // Entry is not found
return false;
}
return true;
}
/* /*
* jump to a quickfix line * jump to a quickfix line
* if dir == FORWARD go "errornr" valid entries forward * if dir == FORWARD go "errornr" valid entries forward
@ -1585,14 +1615,29 @@ win_found:
oldwin == curwin ? curwin : NULL); oldwin == curwin ? curwin : NULL);
} }
} else { } else {
int old_qf_curlist = qi->qf_curlist;
bool is_abort = false;
ok = buflist_getfile(qf_ptr->qf_fnum, (linenr_T)1, ok = buflist_getfile(qf_ptr->qf_fnum, (linenr_T)1,
GETF_SETMARK | GETF_SWITCH, forceit); GETF_SETMARK | GETF_SWITCH, forceit);
if (qi != &ql_info && !win_valid(oldwin)) { if (qi != &ql_info && !win_valid(oldwin)) {
EMSG(_("E924: Current window was closed")); EMSG(_("E924: Current window was closed"));
is_abort = true;
opened_window = false;
} else if (old_qf_curlist != qi->qf_curlist
|| !is_qf_entry_present(qi, qf_ptr)) {
if (qi == &ql_info) {
EMSG(_("E925: Current quickfix was changed"));
} else {
EMSG(_("E926: Current location list was changed"));
}
is_abort = true;
}
if (is_abort) {
ok = false; ok = false;
qi = NULL; qi = NULL;
qf_ptr = NULL; qf_ptr = NULL;
opened_window = false;
} }
} }
} }
@ -3580,7 +3625,9 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
else else
qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE; qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start; qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start;
if (qi->qf_lists[qi->qf_curlist].qf_count > 0) {
qi->qf_lists[qi->qf_curlist].qf_index = 1; qi->qf_lists[qi->qf_curlist].qf_index = 1;
}
qf_update_buffer(qi); qf_update_buffer(qi);

View File

@ -691,7 +691,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
int ret; int ret;
char *failed_dir; char *failed_dir;
if ((ret = os_mkdir_recurse(dir_name, 0755, &failed_dir)) != 0) { if ((ret = os_mkdir_recurse(dir_name, 0755, &failed_dir)) != 0) {
EMSG3(_("E926: Unable to create directory \"%s\" for undo file: %s"), EMSG3(_("E5003: Unable to create directory \"%s\" for undo file: %s"),
failed_dir, os_strerror(ret)); failed_dir, os_strerror(ret));
xfree(failed_dir); xfree(failed_dir);
} else { } else {

View File

@ -747,7 +747,7 @@ static int included_patches[] = {
1700, 1700,
// 1699, // 1699,
// 1698 NA // 1698 NA
// 1697, 1697,
// 1696, // 1696,
1695, 1695,
// 1694 NA // 1694 NA
@ -780,7 +780,7 @@ static int included_patches[] = {
// 1667 NA // 1667 NA
// 1666 NA // 1666 NA
// 1665 NA // 1665 NA
// 1664, 1664,
1663, 1663,
// 1662 NA // 1662 NA
// 1661 NA // 1661 NA
@ -794,17 +794,17 @@ static int included_patches[] = {
// 1653 NA // 1653 NA
1652, 1652,
// 1651 NA // 1651 NA
// 1650, 1650,
1649, 1649,
1648, 1648,
// 1647, 1647,
// 1646 NA // 1646 NA
// 1645, // 1645,
// 1644, // 1644,
1643, 1643,
1642, 1642,
1641, 1641,
// 1640, 1640,
// 1639, // 1639,
// 1638, // 1638,
// 1637 NA // 1637 NA

View File

@ -566,27 +566,27 @@ describe('msgpackdump() function', function()
it('fails to dump a function reference', function() it('fails to dump a function reference', function()
execute('let Todump = function("tr")') execute('let Todump = function("tr")')
eq('Vim(call):E951: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference', eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference',
exc_exec('call msgpackdump([Todump])')) exc_exec('call msgpackdump([Todump])'))
end) end)
it('fails to dump a function reference in a list', function() it('fails to dump a function reference in a list', function()
execute('let todump = [function("tr")]') execute('let todump = [function("tr")]')
eq('Vim(call):E951: Error while dumping msgpackdump() argument, index 0, index 0: attempt to dump function reference', eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, index 0: attempt to dump function reference',
exc_exec('call msgpackdump([todump])')) exc_exec('call msgpackdump([todump])'))
end) end)
it('fails to dump a recursive list', function() it('fails to dump a recursive list', function()
execute('let todump = [[[]]]') execute('let todump = [[[]]]')
execute('call add(todump[0][0], todump)') execute('call add(todump[0][0], todump)')
eq('Vim(call):E952: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 0, index 0', eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 0, index 0',
exc_exec('call msgpackdump([todump])')) exc_exec('call msgpackdump([todump])'))
end) end)
it('fails to dump a recursive dict', function() it('fails to dump a recursive dict', function()
execute('let todump = {"d": {"d": {}}}') execute('let todump = {"d": {"d": {}}}')
execute('call extend(todump.d.d, {"d": todump})') execute('call extend(todump.d.d, {"d": todump})')
eq('Vim(call):E952: Unable to dump msgpackdump() argument, index 0: container references itself in key \'d\', key \'d\', key \'d\'', eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key \'d\', key \'d\', key \'d\'',
exc_exec('call msgpackdump([todump])')) exc_exec('call msgpackdump([todump])'))
end) end)
@ -605,35 +605,35 @@ describe('msgpackdump() function', function()
it('fails to dump a recursive list in a special dict', function() it('fails to dump a recursive list in a special dict', function()
execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}') execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
execute('call add(todump._VAL, todump)') execute('call add(todump._VAL, todump)')
eq('Vim(call):E952: Unable to dump msgpackdump() argument, index 0: container references itself in index 0', eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0',
exc_exec('call msgpackdump([todump])')) exc_exec('call msgpackdump([todump])'))
end) end)
it('fails to dump a recursive (key) map in a special dict', function() it('fails to dump a recursive (key) map in a special dict', function()
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}') execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
execute('call add(todump._VAL, [todump, 0])') execute('call add(todump._VAL, [todump, 0])')
eq('Vim(call):E952: Unable to dump msgpackdump() argument, index 0: container references itself in index 1', eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 1',
exc_exec('call msgpackdump([todump])')) exc_exec('call msgpackdump([todump])'))
end) end)
it('fails to dump a recursive (val) map in a special dict', function() it('fails to dump a recursive (val) map in a special dict', function()
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}') execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
execute('call add(todump._VAL, [0, todump])') execute('call add(todump._VAL, [0, todump])')
eq('Vim(call):E952: Unable to dump msgpackdump() argument, index 0: container references itself in key 0 at index 0 from special map', eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key 0 at index 0 from special map',
exc_exec('call msgpackdump([todump])')) exc_exec('call msgpackdump([todump])'))
end) end)
it('fails to dump a recursive (key) map in a special dict, _VAL reference', function() it('fails to dump a recursive (key) map in a special dict, _VAL reference', function()
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}') execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}')
execute('call add(todump._VAL[0][0], todump._VAL)') execute('call add(todump._VAL[0][0], todump._VAL)')
eq('Vim(call):E952: Unable to dump msgpackdump() argument, index 0: container references itself in key [[[[...@0], []]]] at index 0 from special map, index 0', eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [[[[...@0], []]]] at index 0 from special map, index 0',
exc_exec('call msgpackdump([todump])')) exc_exec('call msgpackdump([todump])'))
end) end)
it('fails to dump a recursive (val) map in a special dict, _VAL reference', function() it('fails to dump a recursive (val) map in a special dict, _VAL reference', function()
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}') execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}')
execute('call add(todump._VAL[0][1], todump._VAL)') execute('call add(todump._VAL[0][1], todump._VAL)')
eq('Vim(call):E952: Unable to dump msgpackdump() argument, index 0: container references itself in key [] at index 0 from special map, index 0', eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [] at index 0 from special map, index 0',
exc_exec('call msgpackdump([todump])')) exc_exec('call msgpackdump([todump])'))
end) end)
@ -641,7 +641,7 @@ describe('msgpackdump() function', function()
function() function()
execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}') execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
execute('call add(todump._VAL, [0, todump._VAL])') execute('call add(todump._VAL, [0, todump._VAL])')
eq('Vim(call):E952: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 1', eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 1',
exc_exec('call msgpackdump([todump])')) exc_exec('call msgpackdump([todump])'))
end) end)

View File

@ -265,7 +265,7 @@ describe('helpgrep', function()
autocmd BufReadCmd t call R(expand("<amatch>")) autocmd BufReadCmd t call R(expand("<amatch>"))
augroup END augroup END
function R(n) function! R(n)
quit quit
endfunc endfunc
@ -406,6 +406,56 @@ describe('helpgrep', function()
augroup END augroup END
augroup! QfBufWinEnter augroup! QfBufWinEnter
endfunc endfunc
function XquickfixChangedByAutocmd(cchar)
let Xolder = a:cchar . 'older'
let Xgetexpr = a:cchar . 'getexpr'
let Xrewind = a:cchar . 'rewind'
if a:cchar == 'c'
let Xsetlist = 'setqflist('
let ErrorNr = 'E925'
function! ReadFunc()
colder
cgetexpr []
endfunc
else
let Xsetlist = 'setloclist(0,'
let ErrorNr = 'E926'
function! ReadFunc()
lolder
lgetexpr []
endfunc
endif
augroup testgroup
au!
autocmd BufReadCmd t call ReadFunc()
augroup END
bwipe!
let words = [ "a", "b" ]
let qflist = []
for word in words
call add(qflist, {'filename': 't'})
exec "call " . Xsetlist . "qflist, '')"
endfor
exec "call assert_fails('" . Xrewind . "', '" . ErrorNr . ":')"
augroup! testgroup
endfunc
func Test_caddbuffer_to_empty()
helpgr quickfix
call setqflist([], 'r')
cad
try
silent cn
catch
" number of matches is unknown
call assert_true(v:exception =~ 'E553:')
endtry
quit!
endfunc
]]) ]])
end) end)
@ -478,6 +528,24 @@ describe('helpgrep', function()
call('Test_locationlist') call('Test_locationlist')
expected_empty() expected_empty()
end) end)
it('is changed by autocmd', function()
call('XquickfixChangedByAutocmd', 'c')
expected_empty()
call('XquickfixChangedByAutocmd', 'l')
expected_empty()
end)
it('does not crash after using caddbuffer with an empty qf list', function()
call('Test_caddbuffer_to_empty')
expected_empty()
end)
it('cgetexpr does not crash with a NULL element in a list', function()
execute('cgetexpr [$x]')
-- Still alive?
eq(2, eval('1+1'))
end)
end) end)
describe('errorformat', function() describe('errorformat', function()

View File

@ -497,7 +497,7 @@ $
it('errors when a funcref is stored in a variable', function() it('errors when a funcref is stored in a variable', function()
nvim_command('let F = function("tr")') nvim_command('let F = function("tr")')
nvim_command('set shada+=!') nvim_command('set shada+=!')
eq('\nE951: Error while dumping variable g:F, itself: attempt to dump function reference' eq('\nE5004: Error while dumping variable g:F, itself: attempt to dump function reference'
.. '\nE574: Failed to write variable F', .. '\nE574: Failed to write variable F',
redir_exec('wshada')) redir_exec('wshada'))
end) end)
@ -506,7 +506,7 @@ $
nvim_command('let L = []') nvim_command('let L = []')
nvim_command('call add(L, L)') nvim_command('call add(L, L)')
nvim_command('set shada+=!') nvim_command('set shada+=!')
eq('\nE952: Unable to dump variable g:L: container references itself in index 0' eq('\nE5005: Unable to dump variable g:L: container references itself in index 0'
.. '\nE574: Failed to write variable L', .. '\nE574: Failed to write variable L',
redir_exec('wshada')) redir_exec('wshada'))
end) end)

View File

@ -132,7 +132,7 @@ describe('ShaDa support code', function()
meths.set_var('U', '10') meths.set_var('U', '10')
nvim_command('set shada+=!') nvim_command('set shada+=!')
set_additional_cmd('set shada+=!') set_additional_cmd('set shada+=!')
eq('Vim(wshada):E951: Error while dumping variable g:F, itself: attempt to dump function reference', eq('Vim(wshada):E5004: Error while dumping variable g:F, itself: attempt to dump function reference',
exc_exec('wshada')) exc_exec('wshada'))
meths.set_option('shada', '') meths.set_option('shada', '')
reset() reset()
@ -145,7 +145,7 @@ describe('ShaDa support code', function()
nvim_command('call add(L, L)') nvim_command('call add(L, L)')
meths.set_var('U', '10') meths.set_var('U', '10')
nvim_command('set shada+=!') nvim_command('set shada+=!')
eq('Vim(wshada):E952: Unable to dump variable g:L: container references itself in index 0', eq('Vim(wshada):E5005: Unable to dump variable g:L: container references itself in index 0',
exc_exec('wshada')) exc_exec('wshada'))
meths.set_option('shada', '') meths.set_option('shada', '')
set_additional_cmd('set shada+=!') set_additional_cmd('set shada+=!')