mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
Merge pull request #15972 from seandewar/vim-8.2.3487
vim-patch:8.2.{3416,3448,3470,3478,3480,3486,3487}
This commit is contained in:
commit
a9cd9de01d
@ -3017,11 +3017,12 @@ void ex_call(exarg_T *eap)
|
||||
}
|
||||
}
|
||||
|
||||
// When inside :try we need to check for following "| catch".
|
||||
if (!failed || eap->cstack->cs_trylevel > 0) {
|
||||
// When inside :try we need to check for following "| catch" or "| endtry".
|
||||
// Not when there was an error, but do check if an exception was thrown.
|
||||
if ((!aborting() || current_exception != NULL) && (!failed || eap->cstack->cs_trylevel > 0)) {
|
||||
// Check for trailing illegal characters and a following command.
|
||||
if (!ends_excmd(*arg)) {
|
||||
if (!failed) {
|
||||
if (!failed && !aborting()) {
|
||||
emsg_severe = true;
|
||||
emsg(_(e_trailing));
|
||||
}
|
||||
|
@ -1083,7 +1083,7 @@ void ex_endwhile(exarg_T *eap)
|
||||
if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) {
|
||||
eap->errmsg = err;
|
||||
} else {
|
||||
fl = cstack->cs_flags[cstack->cs_idx];
|
||||
fl = cstack->cs_flags[cstack->cs_idx];
|
||||
if (!(fl & csf)) {
|
||||
// If we are in a ":while" or ":for" but used the wrong endloop
|
||||
// command, do not rewind to the next enclosing ":for"/":while".
|
||||
@ -1575,6 +1575,7 @@ void ex_endtry(exarg_T *eap)
|
||||
|
||||
if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
|
||||
eap->errmsg = get_end_emsg(cstack);
|
||||
|
||||
// Find the matching ":try" and report what's missing.
|
||||
idx = cstack->cs_idx;
|
||||
do {
|
||||
@ -1594,6 +1595,9 @@ void ex_endtry(exarg_T *eap)
|
||||
if (current_exception) {
|
||||
discard_current_exception();
|
||||
}
|
||||
|
||||
// report eap->errmsg, also when there already was an error
|
||||
did_emsg = false;
|
||||
} else {
|
||||
idx = cstack->cs_idx;
|
||||
|
||||
@ -1664,8 +1668,10 @@ void ex_endtry(exarg_T *eap)
|
||||
*/
|
||||
(void)cleanup_conditionals(cstack, CSF_TRY | CSF_SILENT, TRUE);
|
||||
|
||||
--cstack->cs_idx;
|
||||
--cstack->cs_trylevel;
|
||||
if (cstack->cs_idx >= 0 && (cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
|
||||
cstack->cs_idx--;
|
||||
}
|
||||
cstack->cs_trylevel--;
|
||||
|
||||
if (!skip) {
|
||||
report_resume_pending(pending,
|
||||
@ -1913,7 +1919,7 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
|
||||
|
||||
default:
|
||||
if (cstack->cs_flags[idx] & CSF_FINALLY) {
|
||||
if (cstack->cs_pending[idx] & CSTP_THROW) {
|
||||
if ((cstack->cs_pending[idx] & CSTP_THROW) && cstack->cs_exception[idx] != NULL) {
|
||||
// Cancel the pending exception. This is in the
|
||||
// finally clause, so that the stack of the
|
||||
// caught exceptions is not involved.
|
||||
@ -1934,8 +1940,9 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
|
||||
*/
|
||||
if (!(cstack->cs_flags[idx] & CSF_FINALLY)) {
|
||||
if ((cstack->cs_flags[idx] & CSF_ACTIVE)
|
||||
&& (cstack->cs_flags[idx] & CSF_CAUGHT)) {
|
||||
&& (cstack->cs_flags[idx] & CSF_CAUGHT) && !(cstack->cs_flags[idx] & CSF_FINISHED)) {
|
||||
finish_exception((except_T *)cstack->cs_exception[idx]);
|
||||
cstack->cs_flags[idx] |= CSF_FINISHED;
|
||||
}
|
||||
// Stop at this try conditional - except the try block never
|
||||
// got active (because of an inactive surrounding conditional
|
||||
|
@ -14,9 +14,10 @@
|
||||
|
||||
#define CSF_TRY 0x0100 // is a ":try"
|
||||
#define CSF_FINALLY 0x0200 // ":finally" has been passed
|
||||
#define CSF_THROWN 0x0400 // exception thrown to this try conditional
|
||||
#define CSF_CAUGHT 0x0800 // exception caught by this try conditional
|
||||
#define CSF_SILENT 0x1000 // "emsg_silent" reset by ":try"
|
||||
#define CSF_THROWN 0x0800 // exception thrown to this try conditional
|
||||
#define CSF_CAUGHT 0x1000 // exception caught by this try conditional
|
||||
#define CSF_FINISHED 0x2000 // CSF_CAUGHT was handled by finish_exception()
|
||||
#define CSF_SILENT 0x4000 // "emsg_silent" reset by ":try"
|
||||
// Note that CSF_ELSE is only used when CSF_TRY and CSF_WHILE are unset
|
||||
// (an ":if"), and CSF_SILENT is only used when CSF_TRY is set.
|
||||
|
||||
|
@ -5173,19 +5173,19 @@ static void win_redr_status(win_T *wp)
|
||||
*(p + len++) = ' ';
|
||||
}
|
||||
if (bt_help(wp->w_buffer)) {
|
||||
STRCPY(p + len, _("[Help]"));
|
||||
snprintf((char *)p + len, MAXPATHL - len, "%s", _("[Help]"));
|
||||
len += (int)STRLEN(p + len);
|
||||
}
|
||||
if (wp->w_p_pvw) {
|
||||
STRCPY(p + len, _("[Preview]"));
|
||||
snprintf((char *)p + len, MAXPATHL - len, "%s", _("[Preview]"));
|
||||
len += (int)STRLEN(p + len);
|
||||
}
|
||||
if (bufIsChanged(wp->w_buffer)) {
|
||||
STRCPY(p + len, "[+]");
|
||||
len += 3;
|
||||
snprintf((char *)p + len, MAXPATHL - len, "%s", "[+]");
|
||||
len += (int)STRLEN(p + len);
|
||||
}
|
||||
if (wp->w_buffer->b_p_ro) {
|
||||
STRCPY(p + len, _("[RO]"));
|
||||
snprintf((char *)p + len, MAXPATHL - len, "%s", _("[RO]"));
|
||||
// len += (int)STRLEN(p + len); // dead assignment
|
||||
}
|
||||
|
||||
|
@ -523,4 +523,16 @@ func Test_statusline_mbyte_fillchar()
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Used to write beyond allocated memory. This assumes MAXPATHL is 4096 bytes.
|
||||
func Test_statusline_verylong_filename()
|
||||
let fname = repeat('x', 4090)
|
||||
" Nvim's swap file creation fails on Windows (E303) due to fname's length
|
||||
" exe "new " .. fname
|
||||
exe "noswapfile new " .. fname
|
||||
set buftype=help
|
||||
set previewwindow
|
||||
redraw
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -1996,5 +1996,97 @@ func Test_reload_in_try_catch()
|
||||
call delete('Xreload')
|
||||
endfunc
|
||||
|
||||
" Test for using throw in a called function with following error {{{1
|
||||
func Test_user_command_throw_in_function_call()
|
||||
let lines =<< trim END
|
||||
function s:get_dict() abort
|
||||
throw 'my_error'
|
||||
endfunction
|
||||
|
||||
try
|
||||
call s:get_dict().foo()
|
||||
catch /my_error/
|
||||
let caught = 'yes'
|
||||
catch
|
||||
let caught = v:exception
|
||||
endtry
|
||||
call assert_equal('yes', caught)
|
||||
END
|
||||
call writefile(lines, 'XtestThrow')
|
||||
source XtestThrow
|
||||
|
||||
call delete('XtestThrow')
|
||||
unlet g:caught
|
||||
endfunc
|
||||
|
||||
" Test for using throw in a called function with following endtry {{{1
|
||||
func Test_user_command_function_call_with_endtry()
|
||||
let lines =<< trim END
|
||||
funct s:throw(msg) abort
|
||||
throw a:msg
|
||||
endfunc
|
||||
func s:main() abort
|
||||
try
|
||||
try
|
||||
throw 'err1'
|
||||
catch
|
||||
call s:throw('err2') | endtry
|
||||
catch
|
||||
let s:caught = 'yes'
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
call s:main()
|
||||
call assert_equal('yes', s:caught)
|
||||
END
|
||||
call writefile(lines, 'XtestThrow')
|
||||
source XtestThrow
|
||||
|
||||
call delete('XtestThrow')
|
||||
endfunc
|
||||
|
||||
func ThisWillFail()
|
||||
|
||||
endfunc
|
||||
|
||||
" This was crashing prior to the fix in 8.2.3478.
|
||||
func Test_error_in_catch_and_finally()
|
||||
let lines =<< trim END
|
||||
try
|
||||
echo x
|
||||
catch
|
||||
for l in []
|
||||
finally
|
||||
END
|
||||
call writefile(lines, 'XtestCatchAndFinally')
|
||||
try
|
||||
source XtestCatchAndFinally
|
||||
catch /E600:/
|
||||
endtry
|
||||
|
||||
call delete('XtestCatchAndFinally')
|
||||
endfunc
|
||||
|
||||
" This was causing an illegal memory access
|
||||
func Test_leave_block_in_endtry_not_called()
|
||||
let lines =<< trim END
|
||||
" vim9script
|
||||
" try #
|
||||
try "
|
||||
for x in []
|
||||
if
|
||||
endwhile
|
||||
if
|
||||
endtry
|
||||
END
|
||||
call writefile(lines, 'XtestEndtry')
|
||||
try
|
||||
source XtestEndtry
|
||||
catch /E171:/
|
||||
endtry
|
||||
|
||||
call delete('XtestEndtry')
|
||||
endfunc
|
||||
|
||||
" Modeline {{{1
|
||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||
|
Loading…
Reference in New Issue
Block a user