mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:7.4.1640
Problem: Crash when an autocommand changes a quickfix list. (Dominique)
Solution: Check wether an entry is still valid. (Yegappan Lakshmanan,
Hirohito Higashi)
ffec3c5349
This commit is contained in:
parent
aba853a156
commit
7231438f12
@ -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
|
||||||
|
@ -1254,6 +1254,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 +1611,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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -804,7 +804,7 @@ static int included_patches[] = {
|
|||||||
1643,
|
1643,
|
||||||
1642,
|
1642,
|
||||||
1641,
|
1641,
|
||||||
// 1640,
|
1640,
|
||||||
// 1639,
|
// 1639,
|
||||||
// 1638,
|
// 1638,
|
||||||
// 1637 NA
|
// 1637 NA
|
||||||
|
@ -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,43 @@ 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
|
||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -478,6 +515,13 @@ 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)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('errorformat', function()
|
describe('errorformat', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user