diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 9557281b50..e764ba6f0f 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3430,7 +3430,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'formatprg'* *'fp'* 'formatprg' 'fp' string (default "") - global + global or local to buffer |global-local| {not in Vi} The name of an external program that will be used to format the lines selected with the |gq| operator. The program must take the input on diff --git a/src/channel.c b/src/channel.c index b0af4e4669..340ee11f24 100644 --- a/src/channel.c +++ b/src/channel.c @@ -731,7 +731,14 @@ channel_open( channel_free(channel); return NULL; } - memcpy((char *)&server.sin_addr, host->h_addr, host->h_length); + { + char *p; + + /* When using host->h_addr directly ubsan warns for it to not be + * aligned. First copy the pointer to aviod that. */ + memcpy(&p, &host->h_addr, sizeof(p)); + memcpy((char *)&server.sin_addr, p, host->h_length); + } /* On Mac and Solaris a zero timeout almost never works. At least wait * one millisecond. Let's do it for all systems, because we don't know why diff --git a/src/eval.c b/src/eval.c index 5bed90b3b5..f70d03b369 100644 --- a/src/eval.c +++ b/src/eval.c @@ -9256,6 +9256,8 @@ fill_assert_error( { if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH) ga_concat(gap, (char_u *)"Pattern "); + else if (atype == ASSERT_NOTEQUAL) + ga_concat(gap, (char_u *)"Expected not equal to "); else ga_concat(gap, (char_u *)"Expected "); if (exp_str == NULL) @@ -9265,16 +9267,17 @@ fill_assert_error( } else ga_concat_esc(gap, exp_str); - if (atype == ASSERT_MATCH) - ga_concat(gap, (char_u *)" does not match "); - else if (atype == ASSERT_NOTMATCH) - ga_concat(gap, (char_u *)" does match "); - else if (atype == ASSERT_NOTEQUAL) - ga_concat(gap, (char_u *)" differs from "); - else - ga_concat(gap, (char_u *)" but got "); - ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); - vim_free(tofree); + if (atype != ASSERT_NOTEQUAL) + { + if (atype == ASSERT_MATCH) + ga_concat(gap, (char_u *)" does not match "); + else if (atype == ASSERT_NOTMATCH) + 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)); + vim_free(tofree); + } } } diff --git a/src/if_ruby.c b/src/if_ruby.c index 943112a3b2..0a655285fe 100644 --- a/src/if_ruby.c +++ b/src/if_ruby.c @@ -871,7 +871,11 @@ static int ensure_ruby_initialized(void) int argc = 1; char *argv[] = {"gvim.exe"}; char **argvp = argv; +# ifdef RUBY19_OR_LATER + ruby_sysinit(&argc, &argvp); +# else NtInitialize(&argc, &argvp); +# endif #endif { #if defined(RUBY19_OR_LATER) || defined(RUBY_INIT_STACK) diff --git a/src/json.c b/src/json.c index faaeab35cc..a9333cf076 100644 --- a/src/json.c +++ b/src/json.c @@ -936,7 +936,7 @@ item_end: && dict_find(top_item->jd_tv.vval.v_dict, top_item->jd_key, -1) != NULL) { - EMSG2(_("E937: Duplicate key in JSON: \"%s\""), + EMSG2(_("E938: Duplicate key in JSON: \"%s\""), top_item->jd_key); clear_tv(&top_item->jd_key_tv); clear_tv(cur_item); diff --git a/src/message.c b/src/message.c index 90b2b0a7c3..1c47fa82cd 100644 --- a/src/message.c +++ b/src/message.c @@ -578,8 +578,6 @@ emsg(char_u *s) return TRUE; called_emsg = TRUE; - if (emsg_silent == 0) - ex_exitval = 1; /* * If "emsg_severe" is TRUE: When an error exception is to be thrown, @@ -642,6 +640,8 @@ emsg(char_u *s) return TRUE; } + ex_exitval = 1; + /* Reset msg_silent, an error causes messages to be switched back on. */ msg_silent = 0; cmd_silent = FALSE; diff --git a/src/move.c b/src/move.c index 206f71a1be..86278a3cfe 100644 --- a/src/move.c +++ b/src/move.c @@ -2870,13 +2870,17 @@ do_check_cursorbind(void) restart_edit_save = restart_edit; restart_edit = TRUE; check_cursor(); +# ifdef FEAT_SYN_HL + if (curwin->w_p_cuc) + validate_cursor(); +# endif restart_edit = restart_edit_save; # ifdef FEAT_MBYTE /* Correct cursor for multi-byte character. */ if (has_mbyte) mb_adjust_cursor(); # endif - redraw_later(VALID); + redraw_later(curwin->w_p_cul ? NOT_VALID : VALID); /* Only scroll when 'scrollbind' hasn't done this. */ if (!curwin->w_p_scb) diff --git a/src/normal.c b/src/normal.c index b6fc3e2a2c..49c976cf3b 100644 --- a/src/normal.c +++ b/src/normal.c @@ -1984,7 +1984,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) op_formatexpr(oap); /* use expression */ else #endif - if (*p_fp != NUL) + if (*p_fp != NUL || *curbuf->b_p_fp != NUL) op_colon(oap); /* use external command */ else op_format(oap, FALSE); /* use internal function */ @@ -2197,10 +2197,12 @@ op_colon(oparg_T *oap) } else if (oap->op_type == OP_FORMAT) { - if (*p_fp == NUL) - stuffReadbuff((char_u *)"fmt"); - else + if (*curbuf->b_p_fp != NUL) + stuffReadbuff(curbuf->b_p_fp); + else if (*p_fp != NUL) stuffReadbuff(p_fp); + else + stuffReadbuff((char_u *)"fmt"); stuffReadbuff((char_u *)"\n']"); } diff --git a/src/option.c b/src/option.c index 45b05c5fe0..da48db9055 100644 --- a/src/option.c +++ b/src/option.c @@ -107,6 +107,7 @@ #if defined(FEAT_BEVAL) && defined(FEAT_EVAL) # define PV_BEXPR OPT_BOTH(OPT_BUF(BV_BEXPR)) #endif +#define PV_FP OPT_BOTH(OPT_BUF(BV_FP)) #ifdef FEAT_EVAL # define PV_FEX OPT_BUF(BV_FEX) #endif @@ -1270,7 +1271,7 @@ static struct vimoption options[] = {(char_u *)"^\\s*\\d\\+[\\]:.)}\\t ]\\s*", (char_u *)0L} SCRIPTID_INIT}, {"formatprg", "fp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, - (char_u *)&p_fp, PV_NONE, + (char_u *)&p_fp, PV_FP, {(char_u *)"", (char_u *)0L} SCRIPTID_INIT}, {"fsync", "fs", P_BOOL|P_SECURE|P_VI_DEF, #ifdef HAVE_FSYNC @@ -5574,6 +5575,7 @@ check_buf_options(buf_T *buf) #if defined(FEAT_CRYPT) check_string_option(&buf->b_p_cm); #endif + check_string_option(&buf->b_p_fp); #if defined(FEAT_EVAL) check_string_option(&buf->b_p_fex); #endif @@ -10358,6 +10360,9 @@ unset_global_local_option(char_u *name, void *from) clear_string_option(&buf->b_p_tsr); break; #endif + case PV_FP: + clear_string_option(&buf->b_p_fp); + break; #ifdef FEAT_QUICKFIX case PV_EFM: clear_string_option(&buf->b_p_efm); @@ -10411,6 +10416,7 @@ get_varp_scope(struct vimoption *p, int opt_flags) { switch ((int)p->indir) { + case PV_FP: return (char_u *)&(curbuf->b_p_fp); #ifdef FEAT_QUICKFIX case PV_EFM: return (char_u *)&(curbuf->b_p_efm); case PV_GP: return (char_u *)&(curbuf->b_p_gp); @@ -10491,6 +10497,8 @@ get_varp(struct vimoption *p) case PV_TSR: return *curbuf->b_p_tsr != NUL ? (char_u *)&(curbuf->b_p_tsr) : p->var; #endif + case PV_FP: return *curbuf->b_p_fp != NUL + ? (char_u *)&(curbuf->b_p_fp) : p->var; #ifdef FEAT_QUICKFIX case PV_EFM: return *curbuf->b_p_efm != NUL ? (char_u *)&(curbuf->b_p_efm) : p->var; @@ -11059,6 +11067,7 @@ buf_copy_options(buf_T *buf, int flags) buf->b_p_inde = vim_strsave(p_inde); buf->b_p_indk = vim_strsave(p_indk); #endif + buf->b_p_fp = empty_option; #if defined(FEAT_EVAL) buf->b_p_fex = vim_strsave(p_fex); #endif diff --git a/src/option.h b/src/option.h index 74c3d8be3f..3acc9667e1 100644 --- a/src/option.h +++ b/src/option.h @@ -1051,6 +1051,7 @@ enum , BV_EP , BV_ET , BV_FENC + , BV_FP #ifdef FEAT_EVAL , BV_BEXPR , BV_FEX diff --git a/src/structs.h b/src/structs.h index 512a77a168..fd43ba50b5 100644 --- a/src/structs.h +++ b/src/structs.h @@ -2100,6 +2100,7 @@ struct file_buffer long_u b_p_inde_flags; /* flags for 'indentexpr' */ char_u *b_p_indk; /* 'indentkeys' */ #endif + char_u *b_p_fp; /* 'formatprg' */ #if defined(FEAT_EVAL) char_u *b_p_fex; /* 'formatexpr' */ long_u b_p_fex_flags; /* flags for 'formatexpr' */ diff --git a/src/testdir/test_assert.vim b/src/testdir/test_assert.vim index 25630f2dbc..8c54bddb8a 100644 --- a/src/testdir/test_assert.vim +++ b/src/testdir/test_assert.vim @@ -32,7 +32,7 @@ func Test_assert_notequal() call assert_notequal([1, 2, 3], s) call assert_notequal('foo', s) - call assert_match("Expected 'foo' differs from 'foo'", v:errors[0]) + call assert_match("Expected not equal to 'foo'", v:errors[0]) call remove(v:errors, 0) endfunc diff --git a/src/testdir/test_json.vim b/src/testdir/test_json.vim index bd348fc42e..6616365134 100644 --- a/src/testdir/test_json.vim +++ b/src/testdir/test_json.vim @@ -152,7 +152,7 @@ func Test_json_decode() call assert_fails('call json_decode("blah")', "E474:") call assert_fails('call json_decode("true blah")', "E488:") call assert_fails('call json_decode("")', "E474:") - call assert_fails('call json_decode("{\"a\":1,\"a\":2}")', "E937:") + call assert_fails('call json_decode("{\"a\":1,\"a\":2}")', "E938:") call assert_fails('call json_decode("{")', "E474:") call assert_fails('call json_decode("{foobar}")', "E474:") diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim index 29bd783ebc..98177851ab 100644 --- a/src/testdir/test_normal.vim +++ b/src/testdir/test_normal.vim @@ -224,21 +224,33 @@ func! Test_normal06_formatprg() " only test on non windows platform if has('win32') return - else - " uses sed to number non-empty lines - call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh') - call system('chmod +x ./Xsed_format.sh') endif - call Setup_NewWindow() - %d - call setline(1, ['a', '', 'c', '', ' ', 'd', 'e']) + + " uses sed to number non-empty lines + call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh') + call system('chmod +x ./Xsed_format.sh') + let text = ['a', '', 'c', '', ' ', 'd', 'e'] + let expected = ['1 a', '', '3 c', '', '5 ', '6 d', '7 e'] + + 10new + call setline(1, text) set formatprg=./Xsed_format.sh norm! gggqG - call assert_equal(['1 a', '', '3 c', '', '5 ', '6 d', '7 e'], getline(1, '$')) + call assert_equal(expected, getline(1, '$')) + bw! + + 10new + call setline(1, text) + set formatprg=donothing + setlocal formatprg=./Xsed_format.sh + norm! gggqG + call assert_equal(expected, getline(1, '$')) + bw! + " clean up set formatprg= + setlocal formatprg= call delete('Xsed_format.sh') - bw! endfunc func! Test_normal07_internalfmt() @@ -251,7 +263,7 @@ func! Test_normal07_internalfmt() norm! gggqG call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$')) " clean up - set formatprg= tw=0 + set tw=0 bw! endfunc diff --git a/src/testdir/test_system.vim b/src/testdir/test_system.vim index 0446bd9105..a7de57aacc 100644 --- a/src/testdir/test_system.vim +++ b/src/testdir/test_system.vim @@ -46,3 +46,44 @@ function! Test_System() call assert_fails('call system("wc -l", 99999)', 'E86:') endfunction + +function! Test_system_exmode() + if !has('unix') + return + endif + + let cmd=" -es -u NONE -c 'source Xscript' +q; echo $?" + " Need to put this in a script, "catch" isn't found after an unknown + " function. + call writefile(['try', 'call doesnotexist()', 'catch', 'endtry'], 'Xscript') + let a = system(v:progpath . cmd) + call assert_equal('0', a[0]) + call assert_equal(0, v:shell_error) + + " Error before try does set error flag. + call writefile(['call nosuchfunction()', 'try', 'call doesnotexist()', 'catch', 'endtry'], 'Xscript') + let a = system(v:progpath . cmd) + call assert_notequal('0', a[0]) + + let cmd=" -es -u NONE -c 'source Xscript' +q" + let a = system(v:progpath . cmd) + call assert_notequal(0, v:shell_error) + + let cmd=" -es -u NONE -c 'call doesnotexist()' +q; echo $?" + let a = system(v:progpath. cmd) + call assert_notequal(0, a[0]) + + let cmd=" -es -u NONE -c 'call doesnotexist()' +q" + let a = system(v:progpath. cmd) + call assert_notequal(0, v:shell_error) + + let cmd=" -es -u NONE -c 'call doesnotexist()|let a=1' +q; echo $?" + let a = system(v:progpath. cmd) + call assert_notequal(0, a[0]) + + let cmd=" -es -u NONE -c 'call doesnotexist()|let a=1' +q" + let a = system(v:progpath. cmd) + call assert_notequal(0, v:shell_error) + + call delete('Xscript') +endfunc diff --git a/src/version.c b/src/version.c index e8b97ec325..a73ac3b608 100644 --- a/src/version.c +++ b/src/version.c @@ -779,6 +779,24 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 187, +/**/ + 186, +/**/ + 185, +/**/ + 184, +/**/ + 183, +/**/ + 182, +/**/ + 181, +/**/ + 180, +/**/ + 179, /**/ 178, /**/