diff options
-rw-r--r-- | runtime/autoload/dist/ft.vim | 2 | ||||
-rw-r--r-- | src/nvim/buffer.c | 9 | ||||
-rw-r--r-- | src/nvim/eval.c | 71 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 4 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 15 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_eval.c | 34 | ||||
-rw-r--r-- | src/nvim/fileio.c | 7 | ||||
-rw-r--r-- | src/nvim/globals.h | 2 | ||||
-rw-r--r-- | src/nvim/message.c | 9 | ||||
-rw-r--r-- | src/nvim/ops.c | 24 | ||||
-rw-r--r-- | src/nvim/testdir/test_arglist.vim | 10 | ||||
-rw-r--r-- | src/nvim/testdir/test_filetype.vim | 1 | ||||
-rw-r--r-- | src/nvim/testdir/test_visual.vim | 11 | ||||
-rw-r--r-- | test/functional/legacy/arglist_spec.lua | 13 |
16 files changed, 132 insertions, 84 deletions
diff --git a/runtime/autoload/dist/ft.vim b/runtime/autoload/dist/ft.vim index e85ffc763b..b6297472c3 100644 --- a/runtime/autoload/dist/ft.vim +++ b/runtime/autoload/dist/ft.vim @@ -575,7 +575,7 @@ endfunc let s:ft_rules_udev_rules_pattern = '^\s*\cudev_rules\s*=\s*"\([^"]\{-1,}\)/*".*' func dist#ft#FTRules() let path = expand('<amatch>:p') - if path =~ '^/\(etc/udev/\%(rules\.d/\)\=.*\.rules\|lib/udev/\%(rules\.d/\)\=.*\.rules\)$' + if path =~ '/\(etc/udev/\%(rules\.d/\)\=.*\.rules\|\%(usr/\)\=lib/udev/\%(rules\.d/\)\=.*\.rules\)$' setf udevrules return endif diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index b3bbdce9d9..4648631ebe 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2650,7 +2650,7 @@ void buflist_list(exarg_T *eap) int i; garray_T buflist; - buf_T **buflist_data = NULL, **p; + buf_T **buflist_data = NULL; if (vim_strchr(eap->arg, 't')) { ga_init(&buflist, sizeof(buf_T *), 50); @@ -2662,13 +2662,14 @@ void buflist_list(exarg_T *eap) qsort(buflist.ga_data, (size_t)buflist.ga_len, sizeof(buf_T *), buf_time_compare); - p = buflist_data = (buf_T **)buflist.ga_data; - buf = *p; + buflist_data = (buf_T **)buflist.ga_data; + buf = *buflist_data; } + buf_T **p = buflist_data; for (; buf != NULL && !got_int; - buf = buflist_data + buf = buflist_data != NULL ? (++p < buflist_data + buflist.ga_len ? *p : NULL) : buf->b_next) { const bool is_terminal = buf->terminal; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8e3109b8be..5aeb6fa746 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1679,7 +1679,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) arg = (const char *)find_name_end((char_u *)arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); if (!ascii_iswhite(*arg) && !ends_excmd(*arg)) { - emsg_severe = TRUE; + emsg_severe = true; EMSG(_(e_trailing)); break; } @@ -1692,7 +1692,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) /* This is mainly to keep test 49 working: when expanding * curly braces fails overrule the exception error message. */ if (len < 0 && !aborting()) { - emsg_severe = TRUE; + emsg_severe = true; EMSG2(_(e_invarg2), arg); break; } @@ -2007,7 +2007,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, * expression evaluation has been cancelled due to an * aborting error, an interrupt, or an exception. */ if (!aborting() && !quiet) { - emsg_severe = TRUE; + emsg_severe = true; EMSG2(_(e_invarg2), name); return NULL; } @@ -2675,6 +2675,7 @@ void ex_lockvar(exarg_T *eap) static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep) { char_u *arg = argstart; + char_u *name_end; bool error = false; lval_T lv; @@ -2687,43 +2688,43 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep) return; } os_unsetenv(name); - arg = skipwhite(arg); - continue; - } - - // Parse the name and find the end. - char_u *const name_end = (char_u *)get_lval(arg, NULL, &lv, true, - eap->skip || error, - 0, FNE_CHECK_START); - if (lv.ll_name == NULL) { - error = true; // error, but continue parsing. - } - if (name_end == NULL || (!ascii_iswhite(*name_end) - && !ends_excmd(*name_end))) { - if (name_end != NULL) { - emsg_severe = TRUE; - EMSG(_(e_trailing)); + name_end = arg; + } else { + // Parse the name and find the end. + name_end = get_lval(arg, NULL, &lv, true, eap->skip || error, + 0, FNE_CHECK_START); + if (lv.ll_name == NULL) { + error = true; // error, but continue parsing. + } + if (name_end == NULL + || (!ascii_iswhite(*name_end) && !ends_excmd(*name_end))) { + if (name_end != NULL) { + emsg_severe = true; + EMSG(_(e_trailing)); + } + if (!(eap->skip || error)) { + clear_lval(&lv); + } + break; } - if (!(eap->skip || error)) - clear_lval(&lv); - break; - } - if (!error && !eap->skip) { - if (eap->cmdidx == CMD_unlet) { - if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) - error = TRUE; - } else { - if (do_lock_var(&lv, name_end, deep, - eap->cmdidx == CMD_lockvar) == FAIL) { - error = true; + if (!error && !eap->skip) { + if (eap->cmdidx == CMD_unlet) { + if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) { + error = true; + } + } else { + if (do_lock_var(&lv, name_end, deep, + eap->cmdidx == CMD_lockvar) == FAIL) { + error = true; + } } } - } - - if (!eap->skip) - clear_lval(&lv); + if (!eap->skip) { + clear_lval(&lv); + } + } arg = skipwhite(name_end); } while (!ends_excmd(*arg)); diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index a81f789f0f..18e514b9a0 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -2407,9 +2407,9 @@ static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) float_T f; if (tv_get_float_chk(argvars, &f)) { - if (f <= -VARNUMBER_MAX + DBL_EPSILON) { + if (f <= (float_T)-VARNUMBER_MAX + DBL_EPSILON) { rettv->vval.v_number = -VARNUMBER_MAX; - } else if (f >= VARNUMBER_MAX - DBL_EPSILON) { + } else if (f >= (float_T)VARNUMBER_MAX - DBL_EPSILON) { rettv->vval.v_number = VARNUMBER_MAX; } else { rettv->vval.v_number = (varnumber_T)f; diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 46eccd5181..c4a7a210f1 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -2886,7 +2886,7 @@ void ex_call(exarg_T *eap) if (!failed || eap->cstack->cs_trylevel > 0) { // Check for trailing illegal characters and a following command. if (!ends_excmd(*arg)) { - emsg_severe = TRUE; + emsg_severe = true; EMSG(_(e_trailing)); } else { eap->nextcmd = check_nextcmd(arg); diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 7f4b01e306..7a06cb7ca6 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -1984,9 +1984,16 @@ void ex_argadd(exarg_T *eap) /// ":argdelete" void ex_argdelete(exarg_T *eap) { - if (eap->addr_count > 0) { - // ":1,4argdel": Delete all arguments in the range. - if (eap->line2 > ARGCOUNT) { + if (eap->addr_count > 0 || *eap->arg == NUL) { + // ":argdel" works like ":.argdel" + if (eap->addr_count == 0) { + if (curwin->w_arg_idx >= ARGCOUNT) { + EMSG(_("E610: No argument to delete")); + return; + } + eap->line1 = eap->line2 = curwin->w_arg_idx + 1; + } else if (eap->line2 > ARGCOUNT) { + // ":1,4argdel": Delete all arguments in the range. eap->line2 = ARGCOUNT; } linenr_T n = eap->line2 - eap->line1 + 1; @@ -2016,8 +2023,6 @@ void ex_argdelete(exarg_T *eap) curwin->w_arg_idx = ARGCOUNT - 1; } } - } else if (*eap->arg == NUL) { - EMSG(_(e_argreq)); } else { do_arglist(eap->arg, AL_DEL, 0); } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 064cebe016..1160ab835b 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -4949,7 +4949,7 @@ check_more( int n = ARGCOUNT - curwin->w_arg_idx - 1; if (!forceit && only_one_window() - && ARGCOUNT > 1 && !arg_had_last && n >= 0 && quitmore == 0) { + && ARGCOUNT > 1 && !arg_had_last && n > 0 && quitmore == 0) { if (message) { if ((p_confirm || cmdmod.confirm) && curbuf->b_fname != NULL) { char_u buff[DIALOG_MSG_SIZE]; diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index e99e5b01cd..0c7562980a 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -138,16 +138,15 @@ int aborted_in_try(void) return force_abort; } -/* - * cause_errthrow(): Cause a throw of an error exception if appropriate. - * Return TRUE if the error message should not be displayed by emsg(). - * Sets "ignore", if the emsg() call should be ignored completely. - * - * When several messages appear in the same command, the first is usually the - * most specific one and used as the exception value. The "severe" flag can be - * set to TRUE, if a later but severer message should be used instead. - */ -int cause_errthrow(char_u *mesg, int severe, int *ignore) +// cause_errthrow(): Cause a throw of an error exception if appropriate. +// Return true if the error message should not be displayed by emsg(). +// Sets "ignore", if the emsg() call should be ignored completely. +// +// When several messages appear in the same command, the first is usually the +// most specific one and used as the exception value. The "severe" flag can be +// set to true, if a later but severer message should be used instead. +bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore) + FUNC_ATTR_NONNULL_ALL { struct msglist *elem; struct msglist **plist; @@ -158,8 +157,9 @@ int cause_errthrow(char_u *mesg, int severe, int *ignore) * level. Also when no exception can be thrown. The message will be * displayed by emsg(). */ - if (suppress_errthrow) - return FALSE; + if (suppress_errthrow) { + return false; + } /* * If emsg() has not been called previously, temporarily reset @@ -195,8 +195,8 @@ int cause_errthrow(char_u *mesg, int severe, int *ignore) * not replaced by an interrupt message error exception. */ if (mesg == (char_u *)_(e_interr)) { - *ignore = TRUE; - return TRUE; + *ignore = true; + return true; } /* @@ -231,8 +231,8 @@ int cause_errthrow(char_u *mesg, int severe, int *ignore) * catch clause; just finally clauses are executed before the script * is terminated. */ - return FALSE; - } else + return false; + } else // NOLINT(readability/braces) #endif { /* @@ -271,7 +271,7 @@ int cause_errthrow(char_u *mesg, int severe, int *ignore) (*msg_list)->throw_msg = tmsg; } } - return TRUE; + return true; } } diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index f922591d0b..7740673bbe 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -5553,7 +5553,6 @@ static void au_del_cmd(AutoCmd *ac) static void au_cleanup(void) { AutoPat *ap, **prev_ap; - AutoCmd *ac, **prev_ac; event_T event; if (autocmd_busy || !au_need_clean) { @@ -5566,11 +5565,11 @@ static void au_cleanup(void) // Loop over all autocommand patterns. prev_ap = &(first_autopat[(int)event]); for (ap = *prev_ap; ap != NULL; ap = *prev_ap) { - // Loop over all commands for this pattern. - prev_ac = &(ap->cmds); bool has_cmd = false; - for (ac = *prev_ac; ac != NULL; ac = *prev_ac) { + // Loop over all commands for this pattern. + AutoCmd **prev_ac = &(ap->cmds); + for (AutoCmd *ac = *prev_ac; ac != NULL; ac = *prev_ac) { // Remove the command if the pattern is to be deleted or when // the command has been marked for deletion. if (ap->pat == NULL || ac->cmd == NULL) { diff --git a/src/nvim/globals.h b/src/nvim/globals.h index d6d00d6e83..91a0eab947 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -208,7 +208,7 @@ EXTERN int need_clr_eos INIT(= false); // need to clear text before // displaying a message. EXTERN int emsg_skip INIT(= 0); // don't display errors for // expression that is skipped -EXTERN int emsg_severe INIT(= false); // use message of next of several +EXTERN bool emsg_severe INIT(= false); // use message of next of several // emsg() calls for throw EXTERN int did_endif INIT(= false); // just had ":endif" EXTERN dict_T vimvardict; // Dictionary with v: variables diff --git a/src/nvim/message.c b/src/nvim/message.c index 8999365d32..e4f47917ec 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -607,8 +607,7 @@ int emsg_not_now(void) static bool emsg_multiline(const char *s, bool multiline) { int attr; - int ignore = false; - int severe; + bool ignore = false; // Skip this if not giving error messages at the moment. if (emsg_not_now()) { @@ -617,9 +616,9 @@ static bool emsg_multiline(const char *s, bool multiline) called_emsg = true; - // If "emsg_severe" is TRUE: When an error exception is to be thrown, + // If "emsg_severe" is true: When an error exception is to be thrown, // prefer this message over previous messages for the same command. - severe = emsg_severe; + bool severe = emsg_severe; emsg_severe = false; if (!emsg_off || vim_strchr(p_debug, 't') != NULL) { @@ -630,7 +629,7 @@ static bool emsg_multiline(const char *s, bool multiline) * when the message should be ignored completely (used for the * interrupt message). */ - if (cause_errthrow((char_u *)s, severe, &ignore) == true) { + if (cause_errthrow((char_u *)s, severe, &ignore)) { if (!ignore) { did_emsg++; } diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 595a699563..d31328219f 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3238,21 +3238,43 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) --lnum; new_cursor = curwin->w_cursor; - // simple case: insert into current line + // simple case: insert into one line at a time if (y_type == kMTCharWise && y_size == 1) { linenr_T end_lnum = 0; // init for gcc + linenr_T start_lnum = lnum; if (VIsual_active) { end_lnum = curbuf->b_visual.vi_end.lnum; if (end_lnum < curbuf->b_visual.vi_start.lnum) { end_lnum = curbuf->b_visual.vi_start.lnum; } + if (end_lnum > start_lnum) { + // "col" is valid for the first line, in following lines + // the virtual column needs to be used. Matters for + // multi-byte characters. + pos_T pos = { + .lnum = lnum, + .col = col, + .coladd = 0, + }; + getvcol(curwin, &pos, NULL, &vcol, NULL); + } } do { totlen = (size_t)(count * yanklen); if (totlen > 0) { oldp = ml_get(lnum); + if (lnum > start_lnum) { + pos_T pos = { + .lnum = lnum, + }; + if (getvpos(&pos, vcol) == OK) { + col = pos.col; + } else { + col = MAXCOL; + } + } if (VIsual_active && col > (int)STRLEN(oldp)) { lnum++; continue; diff --git a/src/nvim/testdir/test_arglist.vim b/src/nvim/testdir/test_arglist.vim index 6e7583ade3..92fedf9bfb 100644 --- a/src/nvim/testdir/test_arglist.vim +++ b/src/nvim/testdir/test_arglist.vim @@ -397,9 +397,15 @@ func Test_argdelete() last argdelete % call assert_equal(['b'], argv()) - call assert_fails('argdelete', 'E471:') + call assert_fails('argdelete', 'E610:') call assert_fails('1,100argdelete', 'E16:') - %argd + + call Reset_arglist() + args a b c d + next + argdel + call Assert_argc(['a', 'c', 'd']) + %argdel endfunc func Test_argdelete_completion() diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 8cf7400f7a..529f237a97 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -471,6 +471,7 @@ let s:filename_checks = { \ 'uc': ['file.uc'], \ 'udevconf': ['/etc/udev/udev.conf'], \ 'udevperm': ['/etc/udev/permissions.d/file.permissions'], + \ 'udevrules': ['/etc/udev/rules.d/file.rules', '/usr/lib/udev/rules.d/file.rules', '/lib/udev/rules.d/file.rules'], \ 'uil': ['file.uit', 'file.uil'], \ 'updatedb': ['/etc/updatedb.conf'], \ 'upstart': ['/usr/share/upstart/file.conf', '/usr/share/upstart/file.override', '/etc/init/file.conf', '/etc/init/file.override', '/.init/file.conf', '/.init/file.override', '/.config/upstart/file.conf', '/.config/upstart/file.override'], diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim index 7fc8cdd7f4..734f264672 100644 --- a/src/nvim/testdir/test_visual.vim +++ b/src/nvim/testdir/test_visual.vim @@ -432,3 +432,14 @@ func Test_Visual_Block() close! endfunc + +func Test_visual_put_in_block() + new + call setline(1, ['xxxx', 'y∞yy', 'zzzz']) + normal 1G2yl + exe "normal 1G2l\<C-V>jjlp" + call assert_equal(['xxxx', 'y∞xx', 'zzxx'], getline(1, 3)) + bwipe! +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/test/functional/legacy/arglist_spec.lua b/test/functional/legacy/arglist_spec.lua index 241a19d940..67c5750033 100644 --- a/test/functional/legacy/arglist_spec.lua +++ b/test/functional/legacy/arglist_spec.lua @@ -42,9 +42,7 @@ describe('argument list commands', function() end) it('test that argadd() works', function() - -- Fails with “E474: Invalid argument”. Not sure whether it is how it is - -- supposed to behave. - -- command('%argdelete') + command('%argdelete') command('argadd a b c') eq(0, eval('argidx()')) @@ -176,9 +174,14 @@ describe('argument list commands', function() command('last') command('argdelete %') eq({'b'}, eval('argv()')) - assert_fails('argdelete', 'E471:') + assert_fails('argdelete', 'E610:') assert_fails('1,100argdelete', 'E16:') - command('%argd') + reset_arglist() + command('args a b c d') + command('next') + command('argdel') + eq({'a', 'c', 'd'}, eval('argv()')) + command('%argdel') end) it('test for the :next, :prev, :first, :last, :rewind commands', function() |