aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2016-11-16 06:52:19 -0500
committerGitHub <noreply@github.com>2016-11-16 06:52:19 -0500
commit108d54bbd455635fc29541eb4bae4b9f3318aafb (patch)
treed5d829f41de3c7d151f62910f00c81bad873e47b
parentc66ca17ca1a2f396252bc554198f9e73c7073385 (diff)
parent34317846d6fa9c2d3b23742abc455eafca0e92e4 (diff)
downloadrneovim-108d54bbd455635fc29541eb4bae4b9f3318aafb.tar.gz
rneovim-108d54bbd455635fc29541eb4bae4b9f3318aafb.tar.bz2
rneovim-108d54bbd455635fc29541eb4bae4b9f3318aafb.zip
Merge pull request #5600 from jamessan/vim-7.4.1640
vim-patch:7.4.1640,7.4.1647,7.4.1650,7.4.1664
-rw-r--r--runtime/doc/eval.txt2
-rw-r--r--runtime/doc/options.txt2
-rw-r--r--runtime/doc/quickfix.txt4
-rw-r--r--src/nvim/eval/encode.c4
-rw-r--r--src/nvim/quickfix.c59
-rw-r--r--src/nvim/undo.c2
-rw-r--r--src/nvim/version.c10
-rw-r--r--test/functional/eval/msgpack_functions_spec.lua20
-rw-r--r--test/functional/legacy/quickfix_spec.lua70
-rw-r--r--test/functional/shada/errors_spec.lua4
-rw-r--r--test/functional/shada/variables_spec.lua4
11 files changed, 150 insertions, 31 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index eecf12c44e..64f58c5599 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -5069,7 +5069,7 @@ msgpackdump({list}) {Nvim} *msgpackdump()*
(dictionary with zero items is represented by 0x80 byte in
messagepack).
- Limitations: *E951* *E952* *E953*
+ Limitations: *E5004* *E5005*
1. |Funcref|s cannot be dumped.
2. Containers that reference themselves cannot be dumped.
3. Dictionary keys are always dumped as STR strings.
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 1789f73aa9..9d8d1f84c8 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -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' Removed. |vim-differences| {Nvim}
- *'undodir'* *'udir'* *E926*
+ *'undodir'* *'udir'* *E5003*
'undodir' 'udir' string (default "$XDG_DATA_HOME/nvim/undo")
global
{only when compiled with the |+persistent_undo| feature}
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
index 44d68c7b38..7c1fc30eba 100644
--- a/runtime/doc/quickfix.txt
+++ b/runtime/doc/quickfix.txt
@@ -53,6 +53,10 @@ command with 'l'.
If the current window was closed by an |autocommand| while processing a
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[!] [nr] Display error [nr]. If [nr] is omitted, the same
error is displayed again. Without [!] this doesn't
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index 670437ceda..f6c58d8562 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -836,7 +836,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
msgpack_pack_double(packer, (double) (flt))
#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"), \
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_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"), \
mpstack, objname)
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index d6697902ef..f0d77f9e2b 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -482,9 +482,11 @@ qf_init_ext (
p_str += len;
} else if (tv->v_type == VAR_LIST) {
- /* Get the next line from the supplied list */
- while (p_li && p_li->li_tv.v_type != VAR_STRING)
- p_li = p_li->li_next; /* Skip non-string items */
+ // Get the next line from the supplied list
+ while (p_li && (p_li->li_tv.v_type != VAR_STRING
+ || 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 */
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) {
/* first element in the list */
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 {
assert(*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
* if dir == FORWARD go "errornr" valid entries forward
@@ -1585,14 +1615,29 @@ win_found:
oldwin == curwin ? curwin : NULL);
}
} else {
+ int old_qf_curlist = qi->qf_curlist;
+ bool is_abort = false;
+
ok = buflist_getfile(qf_ptr->qf_fnum, (linenr_T)1,
GETF_SETMARK | GETF_SWITCH, forceit);
if (qi != &ql_info && !win_valid(oldwin)) {
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;
qi = 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
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_index = 1;
+ if (qi->qf_lists[qi->qf_curlist].qf_count > 0) {
+ qi->qf_lists[qi->qf_curlist].qf_index = 1;
+ }
qf_update_buffer(qi);
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index d6428d63f7..4d56046bc1 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -691,7 +691,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
int ret;
char *failed_dir;
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));
xfree(failed_dir);
} else {
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 10dbf97158..8f3619f1e8 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -747,7 +747,7 @@ static int included_patches[] = {
1700,
// 1699,
// 1698 NA
- // 1697,
+ 1697,
// 1696,
1695,
// 1694 NA
@@ -780,7 +780,7 @@ static int included_patches[] = {
// 1667 NA
// 1666 NA
// 1665 NA
- // 1664,
+ 1664,
1663,
// 1662 NA
// 1661 NA
@@ -794,17 +794,17 @@ static int included_patches[] = {
// 1653 NA
1652,
// 1651 NA
- // 1650,
+ 1650,
1649,
1648,
- // 1647,
+ 1647,
// 1646 NA
// 1645,
// 1644,
1643,
1642,
1641,
- // 1640,
+ 1640,
// 1639,
// 1638,
// 1637 NA
diff --git a/test/functional/eval/msgpack_functions_spec.lua b/test/functional/eval/msgpack_functions_spec.lua
index f11c08de05..ebe7c5492b 100644
--- a/test/functional/eval/msgpack_functions_spec.lua
+++ b/test/functional/eval/msgpack_functions_spec.lua
@@ -566,27 +566,27 @@ describe('msgpackdump() function', function()
it('fails to dump a function reference', function()
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])'))
end)
it('fails to dump a function reference in a list', function()
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])'))
end)
it('fails to dump a recursive list', function()
execute('let 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])'))
end)
it('fails to dump a recursive dict', function()
execute('let todump = {"d": {"d": {}}}')
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])'))
end)
@@ -605,35 +605,35 @@ describe('msgpackdump() function', function()
it('fails to dump a recursive list in a special dict', function()
execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
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])'))
end)
it('fails to dump a recursive (key) map in a special dict', function()
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
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])'))
end)
it('fails to dump a recursive (val) map in a special dict', function()
execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
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])'))
end)
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('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])'))
end)
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('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])'))
end)
@@ -641,7 +641,7 @@ describe('msgpackdump() function', function()
function()
execute('let todump = {"_TYPE": v:msgpack_types.array, "_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])'))
end)
diff --git a/test/functional/legacy/quickfix_spec.lua b/test/functional/legacy/quickfix_spec.lua
index b5a8e10a97..5787ff8ff3 100644
--- a/test/functional/legacy/quickfix_spec.lua
+++ b/test/functional/legacy/quickfix_spec.lua
@@ -265,7 +265,7 @@ describe('helpgrep', function()
autocmd BufReadCmd t call R(expand("<amatch>"))
augroup END
- function R(n)
+ function! R(n)
quit
endfunc
@@ -406,6 +406,56 @@ describe('helpgrep', function()
augroup END
augroup! QfBufWinEnter
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)
@@ -478,6 +528,24 @@ describe('helpgrep', function()
call('Test_locationlist')
expected_empty()
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)
describe('errorformat', function()
diff --git a/test/functional/shada/errors_spec.lua b/test/functional/shada/errors_spec.lua
index 98ead6cc3d..19f35571d7 100644
--- a/test/functional/shada/errors_spec.lua
+++ b/test/functional/shada/errors_spec.lua
@@ -497,7 +497,7 @@ $
it('errors when a funcref is stored in a variable', function()
nvim_command('let F = function("tr")')
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',
redir_exec('wshada'))
end)
@@ -506,7 +506,7 @@ $
nvim_command('let L = []')
nvim_command('call add(L, L)')
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',
redir_exec('wshada'))
end)
diff --git a/test/functional/shada/variables_spec.lua b/test/functional/shada/variables_spec.lua
index 15502f0b71..a420462437 100644
--- a/test/functional/shada/variables_spec.lua
+++ b/test/functional/shada/variables_spec.lua
@@ -132,7 +132,7 @@ describe('ShaDa support code', function()
meths.set_var('U', '10')
nvim_command('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'))
meths.set_option('shada', '')
reset()
@@ -145,7 +145,7 @@ describe('ShaDa support code', function()
nvim_command('call add(L, L)')
meths.set_var('U', '10')
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'))
meths.set_option('shada', '')
set_additional_cmd('set shada+=!')