diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 0cba7c215f..c2283358b8 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -1,4 +1,4 @@ -*builtin.txt* For Vim version 9.0. Last change: 2022 Sep 30 +*builtin.txt* For Vim version 9.0. Last change: 2022 Oct 10 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1882,10 +1882,10 @@ cursor({list}) |setcursorcharpos()|. Does not change the jumplist. - {lnum} is used like with |getline()|. + {lnum} is used like with |getline()|, except that if {lnum} is + zero, the cursor will stay in the current line. If {lnum} is greater than the number of lines in the buffer, the cursor will be positioned at the last line in the buffer. - If {lnum} is zero, the cursor will stay in the current line. If {col} is greater than the number of bytes in the line, the cursor will be positioned at the last character in the line. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 8411c7b555..db472c54d3 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 9.0. Last change: 2022 Sep 17 +*eval.txt* For Vim version 9.0. Last change: 2022 Oct 07 VIM REFERENCE MANUAL by Bram Moolenaar diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index d17d52abe2..20b9b243a2 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -7211,6 +7211,8 @@ A jump table for the options with a short description can be found at |Q_op|. c don't give |ins-completion-menu| messages. For example, "-- XXX completion (YYY)", "match 1 of 2", "The only match", "Pattern not found", "Back at original", etc. + C don't give messages while scanning for ins-completion items, + for instance "scanning tags" q use "recording" instead of "recording @a" F don't give the file info when editing a file, like `:silent` was used for the command; note that this also affects messages diff --git a/runtime/doc/rileft.txt b/runtime/doc/rileft.txt index 7c5a60a5ae..31a382b6c5 100644 --- a/runtime/doc/rileft.txt +++ b/runtime/doc/rileft.txt @@ -35,6 +35,11 @@ encoded for every character (or group of characters) are not supported either as this kind of support is out of the scope of a simple addition to an existing editor (and it's not sanctioned by Unicode either). +As many people working on the code do not use the right-to-left mode, this +feature may not work in some situations. If you can describe what is wrong +and how it would work when fixed, please create an issue on github, see +|bug-reports|. + Highlights ---------- diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt index 0b94f8a043..4d02558e48 100644 --- a/runtime/doc/terminal.txt +++ b/runtime/doc/terminal.txt @@ -288,9 +288,8 @@ way to kill or interrupt the job. For example: > So long as the job is running the window behaves like it contains a modified buffer. Trying to close the window with `CTRL-W :quit` fails. When using -`CTRL-W :quit!` the job is ended. The text in the window is lost. The buffer -still exists, but getting it in a window with `:buffer` will show an empty -buffer. +`CTRL-W :quit!` the job is ended. The text in the window is lost, the buffer +is deleted. With `CTRL-W :bunload!` the buffer remains but will be empty. Trying to close the window with `CTRL-W :close` also fails. Using `CTRL-W :close!` will close the window and make the buffer hidden. diff --git a/runtime/doc/textprop.txt b/runtime/doc/textprop.txt index 5a849fed69..4aa00acaee 100644 --- a/runtime/doc/textprop.txt +++ b/runtime/doc/textprop.txt @@ -225,7 +225,7 @@ prop_add({lnum}, {col}, {props}) GetLnum()->prop_add(col, props) < *prop_add_list()* -prop_add_list({props}, [[{lnum}, {col}, {end-lnum}, {end-col}], ...]) +prop_add_list({props}, [{item}, ...]) Similar to prop_add(), but attaches a text property at multiple positions in a buffer. @@ -237,12 +237,18 @@ prop_add_list({props}, [[{lnum}, {col}, {end-lnum}, {end-col}], ...]) type name of the text property type All fields except "type" are optional. - The second argument is a List of Lists where each list - specifies the starting and ending position of the text. The - first two items {lnum} and {col} specify the starting position - of the text where the property will be attached and the last - two items {end-lnum} and {end-col} specify the position just - after the text. + The second argument is a List of items, where each {item} is a + list that specifies the starting and ending position of the + text: [{lnum}, {col}, {end-lnum}, {end-col}] + or: [{lnum}, {col}, {end-lnum}, {end-col}, {id}] + + The first two items {lnum} and {col} specify the starting + position of the text where the property will be attached. + The next two items {end-lnum} and {end-col} specify the + position just after the text. + An optional fifth item {id} can be used to give a different ID + to a property. When omitted the ID from {props} is used, + falling back to zero if none are present. It is not possible to add a text property with a "text" field here. diff --git a/runtime/doc/vim9.txt b/runtime/doc/vim9.txt index f3a2ab6ee3..3dfcf6afcb 100644 --- a/runtime/doc/vim9.txt +++ b/runtime/doc/vim9.txt @@ -1,4 +1,4 @@ -*vim9.txt* For Vim version 9.0. Last change: 2022 Oct 03 +*vim9.txt* For Vim version 9.0. Last change: 2022 Oct 11 VIM REFERENCE MANUAL by Bram Moolenaar @@ -962,6 +962,8 @@ In compiled Vim9 script you get: 3 Generally, you should not change the list that is iterated over. Make a copy first if needed. +When looping over a list of lists, the nested lists can be changed. The loop +variable is "final", it cannot be changed but what its value can be changed. *E1306* The depth of loops, :for and :while loops added together, cannot exceed 10. diff --git a/runtime/filetype.vim b/runtime/filetype.vim index d7e13e1cd3..b4bcc8012a 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -369,6 +369,9 @@ au BufNewFile,BufRead *.ch call dist#ft#FTchange() " ChordPro au BufNewFile,BufRead *.chopro,*.crd,*.cho,*.crdpro,*.chordpro setf chordpro +" Clang-tidy +au BufNewFile,BufRead .clang-tidy setf yaml + " Clean au BufNewFile,BufRead *.dcl,*.icl setf clean @@ -1750,6 +1753,9 @@ au BufNewFile,BufRead *.sed setf sed " SubRip au BufNewFile,BufRead *.srt setf srt +" SubStation Alpha +au BufNewFile,BufRead *.ass,*.ssa setf ssa + " svelte au BufNewFile,BufRead *.svelte setf svelte diff --git a/src/autocmd.c b/src/autocmd.c index d898758221..2a4d3c50bf 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -2096,6 +2096,7 @@ apply_autocmds_group( || event == EVENT_DIRCHANGED || event == EVENT_DIRCHANGEDPRE || event == EVENT_MODECHANGED + || event == EVENT_MENUPOPUP || event == EVENT_USER || event == EVENT_WINCLOSED || event == EVENT_WINSCROLLED) diff --git a/src/buffer.c b/src/buffer.c index c7e94218aa..dba5d9f98f 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -538,7 +538,8 @@ close_buffer( unload_buf = TRUE; #ifdef FEAT_TERMINAL - if (bt_terminal(buf) && (buf->b_nwindows == 1 || del_buf)) + // depending on how we get here b_nwindows may already be zero + if (bt_terminal(buf) && (buf->b_nwindows <= 1 || del_buf)) { CHECK_CURBUF; if (term_job_running(buf->b_term)) @@ -550,6 +551,11 @@ close_buffer( // Wiping out or unloading a terminal buffer kills the job. free_terminal(buf); + + // A terminal buffer is wiped out when job has finished. + del_buf = TRUE; + unload_buf = TRUE; + wipe_buf = TRUE; } else { @@ -565,10 +571,16 @@ close_buffer( } else { - // A terminal buffer is wiped out if the job has finished. - del_buf = TRUE; - unload_buf = TRUE; - wipe_buf = TRUE; + if (del_buf || unload_buf) + { + // A terminal buffer is wiped out if the job has finished. + // We only do this when there's an intention to unload the + // buffer. This way, :hide and other similar commands won't + // wipe the buffer. + del_buf = TRUE; + unload_buf = TRUE; + wipe_buf = TRUE; + } } CHECK_CURBUF; } diff --git a/src/charset.c b/src/charset.c index 9ddb21d967..d03f2616cd 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1178,7 +1178,7 @@ win_lbr_chartabsize( { int n_extra = (int)STRLEN(p); - cells = text_prop_position(wp, tp, + cells = text_prop_position(wp, tp, vcol, (vcol + size) % (wp->w_width - col_off) + col_off, &n_extra, &p, NULL, NULL); #ifdef FEAT_LINEBREAK diff --git a/src/drawline.c b/src/drawline.c index 5f8cdc8007..000203bf09 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -459,7 +459,7 @@ handle_lnum_col( handle_breakindent(win_T *wp, winlinevars_T *wlv) { if (wp->w_briopt_sbr && wlv->draw_state == WL_BRI - 1 - && *get_showbreak_value(wp) != NUL) + && *get_showbreak_value(wp) != NUL) // draw indent after showbreak value wlv->draw_state = WL_BRI; else if (wp->w_briopt_sbr && wlv->draw_state == WL_SBR) @@ -578,15 +578,16 @@ textprop_size_after_trunc( int *n_used_ptr) { int space = (flags & (TP_FLAG_ALIGN_BELOW | TP_FLAG_ALIGN_ABOVE)) - ? wp->w_width : added; + ? wp->w_width - win_col_off(wp) : added; int len = (int)STRLEN(text); int strsize = 0; int n_used; - // if the remaining size is to small wrap anyway and use the next line - if (space < PROP_TEXT_MIN_CELLS) + // if the remaining size is to small and 'wrap' is set we wrap anyway and + // use the next line + if (space < PROP_TEXT_MIN_CELLS && wp->w_p_wrap) space += wp->w_width; - if (flags & TP_FLAG_ALIGN_BELOW) + if (flags & (TP_FLAG_ALIGN_BELOW | TP_FLAG_ALIGN_ABOVE)) space -= padding; for (n_used = 0; n_used < len; n_used += (*mb_ptr2len)(text + n_used)) { @@ -612,7 +613,8 @@ textprop_size_after_trunc( text_prop_position( win_T *wp, textprop_T *tp, - int vcol, // current screen column + int vcol UNUSED, // current text column + int scr_col, // current screen column int *n_extra, // nr of bytes for virtual text char_u **p_extra, // virtual text int *n_attr, // attribute cells, NULL if not used @@ -624,7 +626,7 @@ text_prop_position( int wrap = (tp->tp_flags & TP_FLAG_WRAP); int padding = tp->tp_col == MAXCOL && tp->tp_len > 1 ? tp->tp_len - 1 : 0; - int col_with_padding = vcol + (below ? 0 : padding); + int col_with_padding = scr_col + (below ? 0 : padding); int room = wp->w_width - col_with_padding; int before = room; // spaces before the text int after = 0; // spaces after the text @@ -633,10 +635,12 @@ text_prop_position( int strsize = vim_strsize(*p_extra); int cells = wrap ? strsize : textprop_size_after_trunc(wp, tp->tp_flags, before, padding, *p_extra, &n_used); + int cont_on_next_line = below && col_with_padding > win_col_off(wp) + && !wp->w_p_wrap; if (wrap || right || above || below || padding > 0 || n_used < *n_extra) { - int col_off = win_col_off(wp) + win_col_off2(wp); + int col_off = win_col_off(wp) - win_col_off2(wp); int skip_add = 0; if (above) @@ -652,10 +656,11 @@ text_prop_position( if (before < 0 || !(right || below) || (below - ? (col_with_padding == 0 || !wp->w_p_wrap) + ? (col_with_padding <= col_off || !wp->w_p_wrap) : (n_used < *n_extra))) { - if (right && (wrap || room < PROP_TEXT_MIN_CELLS)) + if (right && (wrap + || (room < PROP_TEXT_MIN_CELLS && wp->w_p_wrap))) { // right-align on next line instead of wrapping if possible before = wp->w_width - col_off - strsize + room; @@ -735,7 +740,11 @@ text_prop_position( *n_attr = mb_charlen(*p_extra); if (above) *n_attr -= padding + after; - *n_attr_skip = before + padding + skip_add; + + // Add "skip_add" when starting a new line or wrapping, + // n_attr_skip will then be decremented in the number column. + *n_attr_skip = before + padding + + (cont_on_next_line || before > 0 ? skip_add : 0); } } } @@ -968,7 +977,13 @@ win_line( int n_attr3 = 0; // chars with overruling special attr int saved_attr3 = 0; // char_attr saved for n_attr3 - int n_skip = 0; // nr of chars to skip for 'nowrap' + int n_skip = 0; // nr of cells to skip for 'nowrap' or + // concealing +#ifdef FEAT_PROP_POPUP + int skip_cells = 0; // nr of cells to skip for virtual text + // after the line, when w_skipcol is + // larger than the text length +#endif int fromcol_prev = -2; // start of inverting after cursor int noinvcur = FALSE; // don't invert the cursor @@ -1497,6 +1512,13 @@ win_line( n_skip = v - wlv.vcol; } +#ifdef FEAT_PROP_POPUP + // If there the text doesn't reach to the desired column, need to skip + // "skip_cells" cells when virtual text follows. + if (!wp->w_p_wrap && v > wlv.vcol) + skip_cells = v - wlv.vcol; +#endif + // Adjust for when the inverted text is before the screen, // and when the start of the inverted text is before the screen. if (wlv.tocol <= wlv.vcol) @@ -1888,21 +1910,31 @@ win_line( for (pi = 0; pi < text_props_active; ++pi) { int tpi = text_prop_idxs[pi]; + textprop_T *tp = &text_props[tpi]; proptype_T *pt = text_prop_type_by_id( - wp->w_buffer, text_props[tpi].tp_type); + wp->w_buffer, tp->tp_type); - if (pt != NULL && (pt->pt_hl_id > 0 - || text_props[tpi].tp_id < 0) - && text_props[tpi].tp_id != -MAXCOL) + // Only use a text property that can be displayed. + // Skip "after" properties when wrap is off and at the + // end of the window. + if (pt != NULL + && (pt->pt_hl_id > 0 || tp->tp_id < 0) + && tp->tp_id != -MAXCOL + && !(tp->tp_id < 0 + && !wp->w_p_wrap + && (tp->tp_flags & (TP_FLAG_ALIGN_RIGHT + | TP_FLAG_ALIGN_ABOVE + | TP_FLAG_ALIGN_BELOW)) == 0 + && wlv.col >= wp->w_width)) { if (pt->pt_hl_id > 0) used_attr = syn_id2attr(pt->pt_hl_id); text_prop_type = pt; text_prop_attr = hl_combine_attr(text_prop_attr, used_attr); - text_prop_flags = pt->pt_flags; - text_prop_id = text_props[tpi].tp_id; other_tpi = used_tpi; + text_prop_flags = pt->pt_flags; + text_prop_id = tp->tp_id; used_tpi = tpi; } } @@ -1916,6 +1948,7 @@ win_line( -text_prop_id - 1]; int above = (tp->tp_flags & TP_FLAG_ALIGN_ABOVE); + int bail_out = FALSE; // reset the ID in the copy to avoid it being used // again @@ -1972,6 +2005,7 @@ win_line( // Shared with win_lbr_chartabsize(), must do // exactly the same. start_line = text_prop_position(wp, tp, + wlv.vcol, wlv.col, &wlv.n_extra, &wlv.p_extra, &n_attr, &n_attr_skip); @@ -1985,7 +2019,7 @@ win_line( if (lcs_eol_one < 0 && wlv.col + wlv.n_extra - 2 > wp->w_width) // don't bail out at end of line - lcs_eol_one = 0; + text_prop_follows = TRUE; // When 'wrap' is off then for "below" we need // to start a new line explictly. @@ -2001,17 +2035,48 @@ win_line( break; } win_line_start(wp, &wlv, TRUE); - continue; + bail_out = TRUE; } } } + // If the text didn't reach until the first window + // column we need to skip cells. + if (skip_cells > 0) + { + if (wlv.n_extra > skip_cells) + { + wlv.n_extra -= skip_cells; + wlv.p_extra += skip_cells; + n_attr_skip -= skip_cells; + if (n_attr_skip < 0) + n_attr_skip = 0; + skip_cells = 0; + } + else + { + // the whole text is left of the window, drop + // it and advance to the next one + skip_cells -= wlv.n_extra; + wlv.n_extra = 0; + n_attr_skip = 0; + bail_out = TRUE; + } + } + // If another text prop follows the condition below at // the last window column must know. // If this is an "above" text prop and 'nowrap' the we // must wrap anyway. text_prop_above = above; - text_prop_follows = other_tpi != -1; + text_prop_follows |= other_tpi != -1 + && (wp->w_p_wrap + || (text_props[other_tpi].tp_flags + & (TP_FLAG_ALIGN_BELOW | TP_FLAG_ALIGN_RIGHT))); + + if (bail_out) + // starting a new line for "below" + continue; } } else if (text_prop_next < text_prop_count @@ -3728,14 +3793,18 @@ win_line( // When not wrapping and finished diff lines, or when displayed // '$' and highlighting until last column, break here. - if ((!wp->w_p_wrap + if (((!wp->w_p_wrap #ifdef FEAT_DIFF && wlv.filler_todo <= 0 #endif #ifdef FEAT_PROP_POPUP - && !text_prop_above && !text_prop_follows + && !text_prop_above #endif - ) || lcs_eol_one == -1) + ) || lcs_eol_one == -1) +#ifdef FEAT_PROP_POPUP + && !text_prop_follows +#endif + ) break; #ifdef FEAT_PROP_POPUP if (!wp->w_p_wrap && text_prop_follows && !text_prop_above) diff --git a/src/edit.c b/src/edit.c index 4f9e388a86..7a419806af 100644 --- a/src/edit.c +++ b/src/edit.c @@ -2645,6 +2645,7 @@ beginline(int flags) } curwin->w_set_curswant = TRUE; } + adjust_skipcol(); } /* @@ -2692,6 +2693,7 @@ oneright(void) curwin->w_cursor.col += l; curwin->w_set_curswant = TRUE; + adjust_skipcol(); return OK; } @@ -2751,6 +2753,7 @@ oneleft(void) // character, move to its first byte if (has_mbyte) mb_adjust_cursor(); + adjust_skipcol(); return OK; } diff --git a/src/eval.c b/src/eval.c index c37765fd89..1652fcb4ae 100644 --- a/src/eval.c +++ b/src/eval.c @@ -6023,10 +6023,12 @@ var2fpos( } /* - * Convert list in "arg" into a position and optional file number. - * When "fnump" is NULL there is no file number, only 3 items. + * Convert list in "arg" into position "psop" and optional file number "fnump". + * When "fnump" is NULL there is no file number, only 3 items: [lnum, col, off] * Note that the column is passed on as-is, the caller may want to decrement * it to use 1 for the first column. + * If "charcol" is TRUE use the column as the character index instead of the + * byte index. * Return FAIL when conversion is not possible, doesn't check the position for * validity. */ @@ -6069,6 +6071,7 @@ list2fpos( if (n < 0) return FAIL; // If character position is specified, then convert to byte position + // If the line number is zero use the cursor line. if (charcol) { buf_T *buf; @@ -6078,7 +6081,8 @@ list2fpos( if (buf == NULL || buf->b_ml.ml_mfp == NULL) return FAIL; - n = buf_charidx_to_byteidx(buf, posp->lnum, n) + 1; + n = buf_charidx_to_byteidx(buf, + posp->lnum == 0 ? curwin->w_cursor.lnum : posp->lnum, n) + 1; } posp->col = n; diff --git a/src/evalfunc.c b/src/evalfunc.c index 96fe7bbd03..d56b1ea570 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -3545,7 +3545,7 @@ f_copy(typval_T *argvars, typval_T *rettv) static void set_cursorpos(typval_T *argvars, typval_T *rettv, int charcol) { - long line, col; + long lnum, col; long coladd = 0; int set_curswant = TRUE; @@ -3567,7 +3567,7 @@ set_cursorpos(typval_T *argvars, typval_T *rettv, int charcol) emsg(_(e_invalid_argument)); return; } - line = pos.lnum; + lnum = pos.lnum; col = pos.col; coladd = pos.coladd; if (curswant >= 0) @@ -3576,17 +3576,19 @@ set_cursorpos(typval_T *argvars, typval_T *rettv, int charcol) set_curswant = FALSE; } } - else if ((argvars[0].v_type == VAR_NUMBER || - argvars[0].v_type == VAR_STRING) - && (argvars[1].v_type == VAR_NUMBER || - argvars[1].v_type == VAR_STRING)) + else if ((argvars[0].v_type == VAR_NUMBER + || argvars[0].v_type == VAR_STRING) + && (argvars[1].v_type == VAR_NUMBER + || argvars[1].v_type == VAR_STRING)) { - line = tv_get_lnum(argvars); - if (line < 0) + lnum = tv_get_lnum(argvars); + if (lnum < 0) semsg(_(e_invalid_argument_str), tv_get_string(&argvars[0])); + else if (lnum == 0) + lnum = curwin->w_cursor.lnum; col = (long)tv_get_number_chk(&argvars[1], NULL); if (charcol) - col = buf_charidx_to_byteidx(curbuf, line, col) + 1; + col = buf_charidx_to_byteidx(curbuf, lnum, col) + 1; if (argvars[2].v_type != VAR_UNKNOWN) coladd = (long)tv_get_number_chk(&argvars[2], NULL); } @@ -3595,10 +3597,10 @@ set_cursorpos(typval_T *argvars, typval_T *rettv, int charcol) emsg(_(e_invalid_argument)); return; } - if (line < 0 || col < 0 || coladd < 0) + if (lnum < 0 || col < 0 || coladd < 0) return; // type error; errmsg already given - if (line > 0) - curwin->w_cursor.lnum = line; + if (lnum > 0) + curwin->w_cursor.lnum = lnum; if (col > 0) curwin->w_cursor.col = col - 1; curwin->w_cursor.coladd = coladd; diff --git a/src/evalvars.c b/src/evalvars.c index df22d3270a..a888756c1d 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -1068,11 +1068,18 @@ ex_let(exarg_T *eap) } else if (expr[0] == '=' && expr[1] == '<' && expr[2] == '<') { - list_T *l; + list_T *l = NULL; long cur_lnum = SOURCING_LNUM; - // HERE document - l = heredoc_get(eap, expr + 3, FALSE, FALSE); + // :let text =<< [trim] [eval] END + // :var text =<< [trim] [eval] END + if (vim9script && !eap->skip && (!VIM_ISWHITE(expr[-1]) + || !IS_WHITE_OR_NUL(expr[3]))) + semsg(_(e_white_space_required_before_and_after_str_at_str), + "=<<", expr); + else + l = heredoc_get(eap, expr + 3, FALSE, FALSE); + if (l != NULL) { rettv_list_set(&rettv, l); @@ -1321,7 +1328,7 @@ skip_var_list( } return p + 1; } - + return skip_var_one(arg, include_type); } @@ -3155,18 +3162,20 @@ find_var(char_u *name, hashtab_T **htp, int no_autoload) // When using "vim9script autoload" script-local items are prefixed but can // be used with s:name. if (SCRIPT_ID_VALID(current_sctx.sc_sid) - && name[0] == 's' && name[1] == ':') + && (in_vim9script() || (name[0] == 's' && name[1] == ':'))) { scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_autoload_prefix != NULL) { - char_u *auto_name = concat_str(si->sn_autoload_prefix, name + 2); + char_u *base_name = (name[0] == 's' && name[1] == ':') + ? name + 2 : name; + char_u *auto_name = concat_str(si->sn_autoload_prefix, base_name); if (auto_name != NULL) { ht = &globvarht; - ret = find_var_in_ht(ht, *name, auto_name, TRUE); + ret = find_var_in_ht(ht, 'g', auto_name, TRUE); vim_free(auto_name); if (ret != NULL) { diff --git a/src/feature.h b/src/feature.h index 450d388334..553b188779 100644 --- a/src/feature.h +++ b/src/feature.h @@ -186,7 +186,7 @@ #endif /* - * +linebreak 'showbreak', 'breakat' and 'linebreak' options. + * +linebreak 'showbreak', 'breakat' and 'linebreak' options. * Also 'numberwidth'. */ #ifdef FEAT_NORMAL @@ -216,6 +216,8 @@ /* * +rightleft Right-to-left editing/typing support. + * Note that this isn't perfect, but enough users say they + * use it to keep supporting it. */ #if defined(FEAT_HUGE) && !defined(DISABLE_RIGHTLEFT) # define FEAT_RIGHTLEFT @@ -234,18 +236,6 @@ # endif #endif -// It is unclear if there are any users of the +rightleft and +arabic fetures. -// The lack of feedback and bug reports suggests that they are not actively -// being used. -// FOR NOW: disable the features here. If nobody complains the code can be -// removed. -#ifdef FEAT_RIGHTLEFT -# undef FEAT_RIGHTLEFT -#endif -#ifdef FEAT_ARABIC -# undef FEAT_ARABIC -#endif - /* * +emacs_tags When FEAT_EMACS_TAGS defined: Include support for * emacs style TAGS file. diff --git a/src/globals.h b/src/globals.h index 065d4444f5..0543070e60 100644 --- a/src/globals.h +++ b/src/globals.h @@ -219,8 +219,8 @@ EXTERN char_u *emsg_assert_fails_context INIT(= NULL); EXTERN int did_endif INIT(= FALSE); // just had ":endif" #endif -EXTERN int did_emsg; // set by emsg() when the message - // is displayed or thrown +EXTERN int did_emsg; // incremented by emsg() when a + // message is displayed or thrown #ifdef FEAT_EVAL EXTERN int did_emsg_silent INIT(= 0); // incremented by emsg() when // emsg_silent was set and did_emsg diff --git a/src/if_cscope.c b/src/if_cscope.c index 809475039c..3252ff4916 100644 --- a/src/if_cscope.c +++ b/src/if_cscope.c @@ -954,7 +954,7 @@ err_closing: // run the cscope command #ifdef UNIX - vim_snprintf(cmd, cmdlen, "/bin/sh -c \"exec %s -dl -f %s\"", + vim_snprintf(cmd, cmdlen, "/bin/sh -c \"exec %s -dl -f %s", prog, csinfo[i].fname); #else vim_snprintf(cmd, cmdlen, "%s -dl -f %s", prog, csinfo[i].fname); @@ -970,6 +970,9 @@ err_closing: vim_snprintf(cmd + len, cmdlen - len, " %s", csinfo[i].flags); } # ifdef UNIX + // terminate the -c command argument + STRCAT(cmd, "\""); + // on Win32 we still need prog vim_free(prog); # endif diff --git a/src/indent.c b/src/indent.c index 79162bf78e..c6e3aaf33d 100644 --- a/src/indent.c +++ b/src/indent.c @@ -1952,7 +1952,7 @@ lisp_match(char_u *p) { (void)copy_option_part(&word, buf, LSIZE, ","); len = (int)STRLEN(buf); - if (STRNCMP(buf, p, len) == 0 && p[len] == ' ') + if (STRNCMP(buf, p, len) == 0 && IS_WHITE_OR_NUL(p[len])) return TRUE; } return FALSE; diff --git a/src/insexpand.c b/src/insexpand.c index e3c881598d..be0b59ae4c 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -1573,7 +1573,7 @@ ins_compl_files( for (i = 0; i < count && !got_int && !compl_interrupted; i++) { fp = mch_fopen((char *)files[i], "r"); // open dictionary file - if (flags != DICT_EXACT) + if (flags != DICT_EXACT && !shortmess(SHM_COMPLETIONSCAN)) { msg_hist_off = TRUE; // reset in msg_trunc_attr() vim_snprintf((char *)IObuff, IOSIZE, @@ -3285,14 +3285,17 @@ process_next_cpt_value( st->dict = st->ins_buf->b_fname; st->dict_f = DICT_EXACT; } - msg_hist_off = TRUE; // reset in msg_trunc_attr() - vim_snprintf((char *)IObuff, IOSIZE, _("Scanning: %s"), - st->ins_buf->b_fname == NULL - ? buf_spname(st->ins_buf) - : st->ins_buf->b_sfname == NULL - ? st->ins_buf->b_fname - : st->ins_buf->b_sfname); - (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); + if (!shortmess(SHM_COMPLETIONSCAN)) + { + msg_hist_off = TRUE; // reset in msg_trunc_attr() + vim_snprintf((char *)IObuff, IOSIZE, _("Scanning: %s"), + st->ins_buf->b_fname == NULL + ? buf_spname(st->ins_buf) + : st->ins_buf->b_sfname == NULL + ? st->ins_buf->b_fname + : st->ins_buf->b_sfname); + (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); + } } else if (*st->e_cpt == NUL) status = INS_COMPL_CPT_END; @@ -3320,10 +3323,13 @@ process_next_cpt_value( #endif else if (*st->e_cpt == ']' || *st->e_cpt == 't') { - msg_hist_off = TRUE; // reset in msg_trunc_attr() compl_type = CTRL_X_TAGS; - vim_snprintf((char *)IObuff, IOSIZE, _("Scanning tags.")); - (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); + if (!shortmess(SHM_COMPLETIONSCAN)) + { + msg_hist_off = TRUE; // reset in msg_trunc_attr() + vim_snprintf((char *)IObuff, IOSIZE, _("Scanning tags.")); + (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); + } } else compl_type = -1; diff --git a/src/mouse.c b/src/mouse.c index a6fc253ed0..5481b73d8c 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -142,7 +142,9 @@ find_end_of_word(pos_T *pos) # define NEED_VCOL2COL /* - * Translate window coordinates to buffer position without any side effects + * Translate window coordinates to buffer position without any side effects. + * Returns IN_BUFFER and sets "mpos->col" to the column when in buffer text. + * The column is one for the first column. */ static int get_fpos_of_mouse(pos_T *mpos) @@ -173,8 +175,6 @@ get_fpos_of_mouse(pos_T *mpos) mpos->col = vcol2col(wp, mpos->lnum, col); - if (mpos->col > 0) - --mpos->col; mpos->coladd = 0; return IN_BUFFER; } @@ -599,7 +599,19 @@ do_mouse( jump_flags = MOUSE_MAY_STOP_VIS; else { - if ((LT_POS(curwin->w_cursor, VIsual) + if (VIsual_mode == 'V') + { + if ((curwin->w_cursor.lnum <= VIsual.lnum + && (m_pos.lnum < curwin->w_cursor.lnum + || VIsual.lnum < m_pos.lnum)) + || (VIsual.lnum < curwin->w_cursor.lnum + && (m_pos.lnum < VIsual.lnum + || curwin->w_cursor.lnum < m_pos.lnum))) + { + jump_flags = MOUSE_MAY_STOP_VIS; + } + } + else if ((LTOREQ_POS(curwin->w_cursor, VIsual) && (LT_POS(m_pos, curwin->w_cursor) || LT_POS(VIsual, m_pos))) || (LT_POS(VIsual, curwin->w_cursor) diff --git a/src/move.c b/src/move.c index 32cd6f37e7..995301e8d2 100644 --- a/src/move.c +++ b/src/move.c @@ -552,6 +552,16 @@ check_cursor_moved(win_T *wp) |VALID_BOTLINE|VALID_BOTLINE_AP); wp->w_valid_cursor = wp->w_cursor; wp->w_valid_leftcol = wp->w_leftcol; + wp->w_valid_skipcol = wp->w_skipcol; + } + else if (wp->w_skipcol != wp->w_valid_skipcol) + { + wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL + |VALID_CHEIGHT|VALID_CROW + |VALID_BOTLINE|VALID_BOTLINE_AP); + wp->w_valid_cursor = wp->w_cursor; + wp->w_valid_leftcol = wp->w_leftcol; + wp->w_valid_skipcol = wp->w_skipcol; } else if (wp->w_cursor.col != wp->w_valid_cursor.col || wp->w_leftcol != wp->w_valid_leftcol @@ -878,7 +888,6 @@ curs_rows(win_T *wp) redraw_for_cursorline(curwin); wp->w_valid |= VALID_CROW|VALID_CHEIGHT; - } /* @@ -1035,6 +1044,7 @@ curs_columns( colnr_T prev_skipcol; long so = get_scrolloff_value(); long siso = get_sidescrolloff_value(); + int did_sub_skipcol = FALSE; /* * First make sure that w_topline is valid (after moving the cursor). @@ -1092,13 +1102,17 @@ curs_columns( { width = textwidth + curwin_col_off2(); + // skip columns that are not visible + if (curwin->w_cursor.lnum == curwin->w_topline + && curwin->w_wcol >= curwin->w_skipcol) + { + curwin->w_wcol -= curwin->w_skipcol; + did_sub_skipcol = TRUE; + } + // long line wrapping, adjust curwin->w_wrow if (curwin->w_wcol >= curwin->w_width) { -#ifdef FEAT_LINEBREAK - char_u *sbr; -#endif - // this same formula is used in validate_cursor_col() n = (curwin->w_wcol - curwin->w_width) / width + 1; curwin->w_wcol -= n * width; @@ -1108,7 +1122,7 @@ curs_columns( // When cursor wraps to first char of next line in Insert // mode, the 'showbreak' string isn't shown, backup to first // column - sbr = get_showbreak_value(curwin); + char_u *sbr = get_showbreak_value(curwin); if (*sbr && *ml_get_cursor() == NUL && curwin->w_wcol == vim_strsize(sbr)) curwin->w_wcol = 0; @@ -1233,7 +1247,7 @@ curs_columns( if ((colnr_T)n >= curwin->w_height + curwin->w_skipcol / width - so) extra += 2; - if (extra == 3 || p_lines <= so * 2) + if (extra == 3 || curwin->w_height <= so * 2) { // not enough room for 'scrolloff', put cursor in the middle n = curwin->w_virtcol / width; @@ -1268,7 +1282,12 @@ curs_columns( curwin->w_skipcol = endcol; } - curwin->w_wrow -= curwin->w_skipcol / width; + // adjust w_wrow for the changed w_skipcol + if (did_sub_skipcol) + curwin->w_wrow -= (curwin->w_skipcol - prev_skipcol) / width; + else + curwin->w_wrow -= curwin->w_skipcol / width; + if (curwin->w_wrow >= curwin->w_height) { // small window, make sure cursor is in it @@ -1302,8 +1321,10 @@ curs_columns( curwin->w_flags &= ~(WFLAG_WCOL_OFF_ADDED + WFLAG_WROW_OFF_ADDED); #endif - // now w_leftcol is valid, avoid check_cursor_moved() thinking otherwise + // now w_leftcol and w_skipcol are valid, avoid check_cursor_moved() + // thinking otherwise curwin->w_valid_leftcol = curwin->w_leftcol; + curwin->w_valid_skipcol = curwin->w_skipcol; curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL; } @@ -1772,10 +1793,74 @@ scrollup( col += width2; curwin->w_curswant = col; coladvance(curwin->w_curswant); + + // validate_virtcol() marked various things as valid, but after + // moving the cursor they need to be recomputed + curwin->w_valid &= + ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL); } } } +/* + * Called after changing the cursor column: make sure that curwin->w_skipcol is + * valid for 'smoothscroll'. + */ + void +adjust_skipcol(void) +{ + if (!curwin->w_p_wrap + || !curwin->w_p_sms + || curwin->w_cursor.lnum != curwin->w_topline) + return; + + int width1 = curwin->w_width - curwin_col_off(); + int width2 = width1 + curwin_col_off2(); + long so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so; + int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; + int scrolled = FALSE; + + validate_virtcol(); + while (curwin->w_skipcol > 0 + && curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols) + { + // scroll a screen line down + if (curwin->w_skipcol >= width1 + width2) + curwin->w_skipcol -= width2; + else + curwin->w_skipcol -= width1; + redraw_later(UPD_NOT_VALID); + scrolled = TRUE; + validate_virtcol(); + } + if (scrolled) + return; // don't scroll in the other direction now + + int col = curwin->w_virtcol - curwin->w_skipcol + scrolloff_cols; + int row = 0; + if (col >= width1) + { + col -= width1; + ++row; + } + if (col > width2) + { + row += col / width2; + col = col % width2; + } + if (row >= curwin->w_height) + { + if (curwin->w_skipcol == 0) + { + curwin->w_skipcol += width1; + --row; + } + if (row >= curwin->w_height) + curwin->w_skipcol += (row - curwin->w_height) * width2; + redraw_later(UPD_NOT_VALID); + } +} + #ifdef FEAT_DIFF /* * Don't end up with too many filler lines in the window. diff --git a/src/normal.c b/src/normal.c index 405b4948b3..af475fe031 100644 --- a/src/normal.c +++ b/src/normal.c @@ -2451,6 +2451,7 @@ nv_screengo(oparg_T *oap, int dir, long dist) if (atend) curwin->w_curswant = MAXCOL; // stick in the last column + adjust_skipcol(); return retval; } diff --git a/src/option.h b/src/option.h index 76d50821e7..4ac6a58353 100644 --- a/src/option.h +++ b/src/option.h @@ -265,11 +265,12 @@ typedef enum { #define SHM_ATTENTION 'A' // no ATTENTION messages #define SHM_INTRO 'I' // intro messages #define SHM_COMPLETIONMENU 'c' // completion menu messages +#define SHM_COMPLETIONSCAN 'C' // completion scanning messages #define SHM_RECORDING 'q' // short recording message #define SHM_FILEINFO 'F' // no file info messages #define SHM_SEARCHCOUNT 'S' // search stats: '[1/10]' #define SHM_POSIX "AS" // POSIX value -#define SHM_ALL "rmfixlnwaWtToOsAIcqFS" // all possible flags for 'shm' +#define SHM_ALL "rmfixlnwaWtToOsAIcCqFS" // all possible flags for 'shm' // characters for p_go: #define GO_TERMINAL '!' // use terminal for system commands diff --git a/src/proto/drawline.pro b/src/proto/drawline.pro index 781cdf15d1..5dc20319e9 100644 --- a/src/proto/drawline.pro +++ b/src/proto/drawline.pro @@ -1,4 +1,4 @@ /* drawline.c */ -int text_prop_position(win_T *wp, textprop_T *tp, int vcol, int *n_extra, char_u **p_extra, int *n_attr, int *n_attr_skip); +int text_prop_position(win_T *wp, textprop_T *tp, int vcol, int scr_col, int *n_extra, char_u **p_extra, int *n_attr, int *n_attr_skip); int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int nochange, int number_only); /* vim: set ft=c : */ diff --git a/src/proto/move.pro b/src/proto/move.pro index de8bf51e12..07a70d2da6 100644 --- a/src/proto/move.pro +++ b/src/proto/move.pro @@ -35,6 +35,7 @@ void f_screenpos(typval_T *argvars, typval_T *rettv); void f_virtcol2col(typval_T *argvars, typval_T *rettv); void scrolldown(long line_count, int byfold); void scrollup(long line_count, int byfold); +void adjust_skipcol(void); void check_topfill(win_T *wp, int down); void scrolldown_clamp(void); void scrollup_clamp(void); diff --git a/src/quickfix.c b/src/quickfix.c index ab288e0c4d..3780262374 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -176,8 +176,8 @@ static char_u *qf_push_dir(char_u *, struct dir_stack_T **, int is_file_stack); static char_u *qf_pop_dir(struct dir_stack_T **); static char_u *qf_guess_filepath(qf_list_T *qfl, char_u *); static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, int newwin); -static void qf_fmt_text(char_u *text, char_u *buf, int bufsize); -static void qf_range_text(qfline_T *qfp, char_u *buf, int bufsize); +static void qf_fmt_text(garray_T *gap, char_u *text); +static void qf_range_text(garray_T *gap, qfline_T *qfp); static int qf_win_pos_update(qf_info_T *qi, int old_qf_index); static win_T *qf_find_win(qf_info_T *qi); static buf_T *qf_find_buf(qf_info_T *qi); @@ -3286,19 +3286,20 @@ qf_jump_print_msg( linenr_T old_lnum) { linenr_T i; - int len; + garray_T ga; // Update the screen before showing the message, unless the screen // scrolled up. if (!msg_scrolled) update_topline_redraw(); - sprintf((char *)IObuff, _("(%d of %d)%s%s: "), qf_index, + vim_snprintf((char *)IObuff, IOSIZE, _("(%d of %d)%s%s: "), qf_index, qf_get_curlist(qi)->qf_count, qf_ptr->qf_cleared ? _(" (line deleted)") : "", (char *)qf_types(qf_ptr->qf_type, qf_ptr->qf_nr)); // Add the message, skipping leading whitespace and newlines. - len = (int)STRLEN(IObuff); - qf_fmt_text(skipwhite(qf_ptr->qf_text), IObuff + len, IOSIZE - len); + ga_init2(&ga, 1, 256); + ga_concat(&ga, IObuff); + qf_fmt_text(&ga, skipwhite(qf_ptr->qf_text)); // Output the message. Overwrite to avoid scrolling when the 'O' // flag is present in 'shortmess'; But when not jumping, print the @@ -3308,8 +3309,9 @@ qf_jump_print_msg( msg_scroll = TRUE; else if (!msg_scrolled && shortmess(SHM_OVERALL)) msg_scroll = FALSE; - msg_attr_keep((char *)IObuff, 0, TRUE); + msg_attr_keep((char *)ga.ga_data, 0, TRUE); msg_scroll = i; + ga_clear(&ga); } /* @@ -3574,6 +3576,7 @@ qf_list_entry(qfline_T *qfp, int qf_idx, int cursel) char_u *fname; buf_T *buf; int filter_entry; + garray_T ga; fname = NULL; if (qfp->qf_module != NULL && *qfp->qf_module != NUL) @@ -3614,46 +3617,33 @@ qf_list_entry(qfline_T *qfp, int qf_idx, int cursel) if (qfp->qf_lnum != 0) msg_puts_attr(":", qfSepAttr); + ga_init2(&ga, 1, 256); if (qfp->qf_lnum == 0) - IObuff[0] = NUL; + ga_append(&ga, NUL); else - qf_range_text(qfp, IObuff, IOSIZE); - sprintf((char *)IObuff + STRLEN(IObuff), "%s", - (char *)qf_types(qfp->qf_type, qfp->qf_nr)); - msg_puts_attr((char *)IObuff, qfLineAttr); + qf_range_text(&ga, qfp); + ga_concat(&ga, qf_types(qfp->qf_type, qfp->qf_nr)); + ga_append(&ga, NUL); + msg_puts_attr((char *)ga.ga_data, qfLineAttr); + ga_clear(&ga); msg_puts_attr(":", qfSepAttr); if (qfp->qf_pattern != NULL) { - qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE); - msg_puts((char *)IObuff); + qf_fmt_text(&ga, qfp->qf_pattern); + msg_puts((char *)ga.ga_data); + ga_clear(&ga); msg_puts_attr(":", qfSepAttr); } msg_puts(" "); { - char_u *tbuf = IObuff; - size_t tbuflen = IOSIZE; - size_t len = STRLEN(qfp->qf_text) + 3; - - if (len > IOSIZE) - { - tbuf = alloc(len); - if (tbuf != NULL) - tbuflen = len; - else - tbuf = IObuff; - } - // Remove newlines and leading whitespace from the text. For an // unrecognized line keep the indent, the compiler may mark a word // with ^^^^. - qf_fmt_text((fname != NULL || qfp->qf_lnum != 0) - ? skipwhite(qfp->qf_text) : qfp->qf_text, - tbuf, (int)tbuflen); - msg_prt_line(tbuf, FALSE); - - if (tbuf != IObuff) - vim_free(tbuf); + qf_fmt_text(&ga, (fname != NULL || qfp->qf_lnum != 0) + ? skipwhite(qfp->qf_text) : qfp->qf_text); + msg_prt_line((char_u *)ga.ga_data, FALSE); + ga_clear(&ga); } out_flush(); // show one line at a time } @@ -3738,37 +3728,40 @@ qf_list(exarg_T *eap) /* * Remove newlines and leading whitespace from an error message. - * Put the result in "buf[bufsize]". + * Add the result to the grow array "gap". */ static void -qf_fmt_text(char_u *text, char_u *buf, int bufsize) +qf_fmt_text(garray_T *gap, char_u *text) { - int i; char_u *p = text; - for (i = 0; *p != NUL && i < bufsize - 1; ++i) + while (*p != NUL) { if (*p == '\n') { - buf[i] = ' '; + ga_append(gap, ' '); while (*++p != NUL) if (!VIM_ISWHITE(*p) && *p != '\n') break; } else - buf[i] = *p++; + ga_append(gap, *p++); } - buf[i] = NUL; + + ga_append(gap, NUL); } /* - * Range information from lnum, col, end_lnum, and end_col. - * Put the result in "buf[bufsize]". + * Add the range information from the lnum, col, end_lnum, and end_col values + * of a quickfix entry to the grow array "gap". */ static void -qf_range_text(qfline_T *qfp, char_u *buf, int bufsize) +qf_range_text(garray_T *gap, qfline_T *qfp) { + char_u *buf = IObuff; + int bufsize = IOSIZE; int len; + vim_snprintf((char *)buf, bufsize, "%ld", qfp->qf_lnum); len = (int)STRLEN(buf); @@ -3790,6 +3783,8 @@ qf_range_text(qfline_T *qfp, char_u *buf, int bufsize) } } buf[len] = NUL; + + ga_concat_len(gap, buf, len); } /* @@ -4597,26 +4592,25 @@ qf_buf_add_line( int first_bufline, char_u *qftf_str) { - int len; buf_T *errbuf; + garray_T ga; + + ga_init2(&ga, 1, 256); // If the 'quickfixtextfunc' function returned a non-empty custom string // for this entry, then use it. if (qftf_str != NULL && *qftf_str != NUL) - vim_strncpy(IObuff, qftf_str, IOSIZE - 1); + ga_concat(&ga, qftf_str); else { if (qfp->qf_module != NULL) - { - vim_strncpy(IObuff, qfp->qf_module, IOSIZE - 1); - len = (int)STRLEN(IObuff); - } + ga_concat(&ga, qfp->qf_module); else if (qfp->qf_fnum != 0 && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL && errbuf->b_fname != NULL) { if (qfp->qf_type == 1) // :helpgrep - vim_strncpy(IObuff, gettail(errbuf->b_fname), IOSIZE - 1); + ga_concat(&ga, gettail(errbuf->b_fname)); else { // Shorten the file name if not done already. @@ -4629,47 +4623,35 @@ qf_buf_add_line( mch_dirname(dirname, MAXPATHL); shorten_buf_fname(errbuf, dirname, FALSE); } - vim_strncpy(IObuff, errbuf->b_fname, IOSIZE - 1); + ga_concat(&ga, errbuf->b_fname); } - len = (int)STRLEN(IObuff); } - else - len = 0; - if (len < IOSIZE - 1) - IObuff[len++] = '|'; + ga_append(&ga, '|'); if (qfp->qf_lnum > 0) { - qf_range_text(qfp, IObuff + len, IOSIZE - len); - len += (int)STRLEN(IObuff + len); - - vim_snprintf((char *)IObuff + len, IOSIZE - len, "%s", - (char *)qf_types(qfp->qf_type, qfp->qf_nr)); - len += (int)STRLEN(IObuff + len); + qf_range_text(&ga, qfp); + ga_concat(&ga, qf_types(qfp->qf_type, qfp->qf_nr)); } else if (qfp->qf_pattern != NULL) - { - qf_fmt_text(qfp->qf_pattern, IObuff + len, IOSIZE - len); - len += (int)STRLEN(IObuff + len); - } - if (len < IOSIZE - 2) - { - IObuff[len++] = '|'; - IObuff[len++] = ' '; - } + qf_fmt_text(&ga, qfp->qf_pattern); + ga_append(&ga, '|'); + ga_append(&ga, ' '); // Remove newlines and leading whitespace from the text. // For an unrecognized line keep the indent, the compiler may // mark a word with ^^^^. - qf_fmt_text(len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text, - IObuff + len, IOSIZE - len); + qf_fmt_text(&ga, ga.ga_len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text); } - if (ml_append_buf(buf, lnum, IObuff, - (colnr_T)STRLEN(IObuff) + 1, FALSE) == FAIL) + ga_append(&ga, NUL); + + if (ml_append_buf(buf, lnum, ga.ga_data, ga.ga_len + 1, FALSE) == FAIL) return FAIL; + ga_clear(&ga); + return OK; } diff --git a/src/screen.c b/src/screen.c index 688da3082a..bb62ae7c28 100644 --- a/src/screen.c +++ b/src/screen.c @@ -475,6 +475,10 @@ screen_line( #endif ; int redraw_next; // redraw_this for next character +#ifdef FEAT_GUI_MSWIN + int changed_this; // TRUE if character changed + int changed_next; // TRUE if next character changed +#endif int clear_next = FALSE; int char_cells; // 1: normal char // 2: occupies two display cells @@ -534,6 +538,9 @@ screen_line( #endif redraw_next = char_needs_redraw(off_from, off_to, endcol - col); +#ifdef FEAT_GUI_MSWIN + changed_next = redraw_next; +#endif while (col < endcol) { @@ -547,19 +554,24 @@ screen_line( off_to + char_cells, endcol - col - char_cells); #ifdef FEAT_GUI +# ifdef FEAT_GUI_MSWIN + changed_this = changed_next; + changed_next = redraw_next; +# endif // If the next character was bold, then redraw the current character to // remove any pixels that might have spilt over into us. This only // happens in the GUI. + // With MS-Windows antialiasing may also cause pixels to spill over + // from a previous character, no matter attributes, always redraw if a + // character changed. if (redraw_next && gui.in_use) { +# if !defined(FEAT_GUI_MSWIN) && !defined(FEAT_GUI_MACVIM) /* MacVim: see comment on subpixel antialiasing */ hl = ScreenAttrs[off_to + char_cells]; if (hl > HL_ALL) hl = syn_attr2attr(hl); - if ((hl & HL_BOLD) -# ifdef FEAT_GUI_MACVIM /* see comment on subpixel antialiasing */ - || gui.in_use + if (hl & HL_BOLD) # endif - ) redraw_this = TRUE; } #endif @@ -696,6 +708,12 @@ screen_line( ) redraw_next = TRUE; } +#endif +#ifdef FEAT_GUI_MSWIN + // MS-Windows antialiasing may spill over to the next character, + // redraw that one if this one changed, no matter attributes. + if (gui.in_use && changed_this) + redraw_next = TRUE; #endif ScreenAttrs[off_to] = ScreenAttrs[off_from]; diff --git a/src/structs.h b/src/structs.h index f5726345dc..a6e6229f68 100644 --- a/src/structs.h +++ b/src/structs.h @@ -3726,6 +3726,7 @@ struct window_S pos_T w_valid_cursor; // last known position of w_cursor, used // to adjust w_valid colnr_T w_valid_leftcol; // last known w_leftcol + colnr_T w_valid_skipcol; // last known w_skipcol /* * w_cline_height is the number of physical lines taken by the buffer line diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak index 893a9b564c..e1f3e294c9 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -182,7 +182,7 @@ NEW_TESTS = \ test_largefile \ test_let \ test_lineending \ - test_lispwords \ + test_lispindent \ test_listchars \ test_listdict \ test_listener \ @@ -428,6 +428,7 @@ NEW_TESTS_RES = \ test_langmap.res \ test_let.res \ test_lineending.res \ + test_lispindent.res \ test_listchars.res \ test_listdict.res \ test_listener.res \ diff --git a/src/testdir/dumps/Test_long_text_with_padding_2.dump b/src/testdir/dumps/Test_long_text_with_padding_2.dump new file mode 100644 index 0000000000..981613fc8a --- /dev/null +++ b/src/testdir/dumps/Test_long_text_with_padding_2.dump @@ -0,0 +1,8 @@ +|f+0&#ffffff0|i|r|s|t| |l|i|n|e|$+0#4040ff13&| +0#0000000&@48 +@3|a+0&#ffd7ff255|f|t|e|r| |a|f|t|e|r| |a|f|t|e|r| |a|f|t|e|r| |a|f|t|e|r| |a|f|t|e|r| |a|f|t|e|r| |a|f|t|e|r| |a|f|t|e|r| |a|f|… +| +0&#ffffff0@29|m+0&#ffd7ff255|o|r|e| |m|o|r|e| |m|o|r|e| |m|o|r|e| |m|o|r|e| |m|o|r|e|… +|s+0&#ffffff0|e|c|o|n|d| >l|i|n|e|$+0#4040ff13&| +0#0000000&@47 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +|:+0#0000000&|s|e|t| |l|i|s|t| @32|2|,|8| @10|A|l@1| diff --git a/src/testdir/dumps/Test_prop_with_text_above_9.dump b/src/testdir/dumps/Test_prop_with_text_above_9.dump new file mode 100644 index 0000000000..727f859b43 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_above_9.dump @@ -0,0 +1,9 @@ +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|f+0#0000000#ffff4012|i|r|s|t| |t|h|i|n|g| |a|b|o|v|e| +0&#ffffff0@36 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|s+0#0000000#ffd7ff255|e|c|o|n|d| |t|h|i|n|g| |a|b|o|v|e| +0&#ffffff0@35 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3| +0#0000000&@1|0+0&#ffff4012| |1| |2| |3| |4| |5| |6| |7| |8| |9| |1|0| |1@1| |1|2| |1|3| |1|4| |1|5| |1|6| |1|7| |1|8| |1|9| |2|… +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|1| |i+0#0000000&|n|s|e|r|t|e|d| @45 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|2| >o+0#0000000&|n|e| |t|w|o| @46 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|b+0#0000000#5fd7ff255|e|l|o|w| +0&#ffffff0@48 +|~+0#4040ff13&| @58 +|~| @58 +|:+0#0000000&|c|a|l@1| |A|d@1|L|o|n|g|P|r|o|p|A|b|o|v|e|(|)| @17|2|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_prop_with_text_after_below_trunc_2.dump b/src/testdir/dumps/Test_prop_with_text_after_below_trunc_2.dump new file mode 100644 index 0000000000..1d93f9fb42 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_after_below_trunc_2.dump @@ -0,0 +1,8 @@ +| +0#af5f00255#ffffff0@1|1| |o+0#0000000&|n|a|s|d|f| |a|s|d|f| |a|s|d|f| |a|s|d|f| |a|s|d| |f|a|s| |d|f|t+0#e000e06&|h|e| |q|u|i|c|k| |b|r|o|w|n| |f|o|x| |j|u|m|… +| +0#af5f00255&@3|t+0#e000e06&|h|e| |q|u|i|c|k| |b|r|o|w|n| |f|o|x| |j|u|m|p|s| |o|v|e|r| |t|h|e| |l|a|z|y| |d|o|g| +0#0000000&@12 +| +0#af5f00255&@1|2| |t+0#0000000&|w>o| @52 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +|~| @58 +|:+0#0000000&|s|e|t| |n|u|m|b|e|r| @30|2|,|3| @10|A|l@1| diff --git a/src/testdir/dumps/Test_props_after_1.dump b/src/testdir/dumps/Test_props_after_1.dump new file mode 100644 index 0000000000..dd607f6b02 --- /dev/null +++ b/src/testdir/dumps/Test_props_after_1.dump @@ -0,0 +1,8 @@ +|o+0&#ffffff0|n|e| @2|0+0#e000e06&| |1| |2| |3| |4| |5| |6| |7| |8| |9| |1|0| |1@1| |1|2| |1|3| |1|4| |1|5| |1|6| |1|7| |1|8| |1|9| |2|0| |… +| +0#0000000&@4|0+0#e000e06&|-|1|-|2|-|3|-|4|-|5|-|6|-|7|-|8|-|9|-|1|0|-|1@1|-|1|2|-|1|3|-|1|4|-|1|5|-|1|6|-|1|7|-|1|8|-|1|9|-|2|0|-|2|… +| +0#0000000&|0+0#e000e06&|.|1|.|2|.|3|.|4|.|5|.|6|.|7|.|8|.|9|.|1|0|.|1@1|.|1|2|.|1|3|.|1|4|.|1|5|.|1|6|.|1|7|.|1|8|.|1|9|.|2|0|.|2|1|.|2@1|… +|t+0#0000000&|w>o| @56 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +| +0#0000000&@41|2|,|3| @10|A|l@1| diff --git a/src/testdir/dumps/Test_props_after_2.dump b/src/testdir/dumps/Test_props_after_2.dump new file mode 100644 index 0000000000..146f045164 --- /dev/null +++ b/src/testdir/dumps/Test_props_after_2.dump @@ -0,0 +1,8 @@ +|o+0&#ffffff0|n|e|$+0#4040ff13&| +0#0000000&@2|0+0#e000e06&| |1| |2| |3| |4| |5| |6| |7| |8| |9| |1|0| |1@1| |1|2| |1|3| |1|4| |1|5| |1|6| |1|7| |1|8| |1|9| |2|0|… +| +0#0000000&@4|0+0#e000e06&|-|1|-|2|-|3|-|4|-|5|-|6|-|7|-|8|-|9|-|1|0|-|1@1|-|1|2|-|1|3|-|1|4|-|1|5|-|1|6|-|1|7|-|1|8|-|1|9|-|2|0|-|2|… +| +0#0000000&|0+0#e000e06&|.|1|.|2|.|3|.|4|.|5|.|6|.|7|.|8|.|9|.|1|0|.|1@1|.|1|2|.|1|3|.|1|4|.|1|5|.|1|6|.|1|7|.|1|8|.|1|9|.|2|0|.|2|1|.|2@1|… +|t+0#0000000&|w>o|$+0#4040ff13&| +0#0000000&@55 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +|:+0#0000000&|s|e|t| |l|i|s|t| @32|2|,|3| @10|A|l@1| diff --git a/src/testdir/dumps/Test_smooth_long_8.dump b/src/testdir/dumps/Test_smooth_long_8.dump index c796d9a5ba..8bdc88971c 100644 --- a/src/testdir/dumps/Test_smooth_long_8.dump +++ b/src/testdir/dumps/Test_smooth_long_8.dump @@ -3,4 +3,4 @@ |t|s| |o|f| |t|e|x>t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o |f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e |x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w -| @21|3|,|1|3|0| @8|B|o|t| +|:|s|e|t| |s|c|r|o|l@1|o| @9|3|,|1|3|0| @8|B|o|t| diff --git a/src/testdir/dumps/Test_smooth_long_9.dump b/src/testdir/dumps/Test_smooth_long_9.dump index d3e6a08fde..8bdc88971c 100644 --- a/src/testdir/dumps/Test_smooth_long_9.dump +++ b/src/testdir/dumps/Test_smooth_long_9.dump @@ -1,6 +1,6 @@ -|<+0#4040ff13#ffffff0@2|o+0#0000000&|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o -|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o -|f| |t|e|x|t| |w|i>t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e +|<+0#4040ff13#ffffff0@2|t+0#0000000&|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t +|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o +|t|s| |o|f| |t|e|x>t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o +|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e |x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w -|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| -@22|3|,|1|7|0| @8|B|o|t| +|:|s|e|t| |s|c|r|o|l@1|o| @9|3|,|1|3|0| @8|B|o|t| diff --git a/src/testdir/dumps/Test_smooth_one_long_1.dump b/src/testdir/dumps/Test_smooth_one_long_1.dump new file mode 100644 index 0000000000..82c1ea3f5e --- /dev/null +++ b/src/testdir/dumps/Test_smooth_one_long_1.dump @@ -0,0 +1,6 @@ +>w+0&#ffffff0|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h +| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t +|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f +| |t|e|x|t| @34 +|~+0#4040ff13&| @38 +| +0#0000000&@21|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_smooth_one_long_2.dump b/src/testdir/dumps/Test_smooth_one_long_2.dump new file mode 100644 index 0000000000..46e4f59dc4 --- /dev/null +++ b/src/testdir/dumps/Test_smooth_one_long_2.dump @@ -0,0 +1,6 @@ +|<+0#4040ff13#ffffff0@2|t+0#0000000&|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t +>s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f +| |t|e|x|t| @34 +|~+0#4040ff13&| @38 +|~| @38 +| +0#0000000&@21|1|,|8|1| @9|A|l@1| diff --git a/src/testdir/dumps/Test_text_after_nowrap_1.dump b/src/testdir/dumps/Test_text_after_nowrap_1.dump new file mode 100644 index 0000000000..0781e6cde0 --- /dev/null +++ b/src/testdir/dumps/Test_text_after_nowrap_1.dump @@ -0,0 +1,8 @@ +|f+0&#ffffff0|i|r|s|t| |l|i|n|e| @1|r+0&#ffd7ff255|i|g|h|t| |a|f|t|e|r| |t|h|e| |t|e|x|t| |r|i|g|h|t| |a|f|t|e|r| |t|h|e| |t|e|x|t| |r|i|g|h|t| +|0+0&#ffffff0| >1| |2| |3| |4| |5| |6| |7| |8| |9| |1|0| |1@1| |1|2| |1|3| |1|4| |1|5| |1|6| |1|7| |1|8| |1|9| |2|0| |2|1| |2@1| |2 +|t|h|i|r|d| @54 +|f|o|u|r|t|h| @53 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +| +0#0000000&@41|2|,|3| @10|A|l@1| diff --git a/src/testdir/dumps/Test_text_after_nowrap_2.dump b/src/testdir/dumps/Test_text_after_nowrap_2.dump new file mode 100644 index 0000000000..28a45f3255 --- /dev/null +++ b/src/testdir/dumps/Test_text_after_nowrap_2.dump @@ -0,0 +1,8 @@ +| +0&#ffd7ff255|r|i|g|h|t| |a|f|t|e|r| |t|h|e| | +0&#ffffff0@2|i+0&#ffd7ff255|n| |t|h|e| |m|i|d@1|l|e| |i|n| |t|h|e| |m|i|d@1|l|e| |i|n| |t|h|e| |m|i|d@1|l +|2+0&#ffffff0|1| |2@1| |2|3| |2|4| |2|5| |2|6| |2|7| |2|8| |2|9| |3|0| >3|1| |3|2| |3@1| |3|4| |3|5| |3|6| |3|7| |3|8| |3|9| |4|0| +@60 +@60 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +| +0#0000000&@41|2|,|8|4| @9|A|l@1| diff --git a/src/testdir/dumps/Test_text_after_nowrap_3.dump b/src/testdir/dumps/Test_text_after_nowrap_3.dump new file mode 100644 index 0000000000..0a7cb3b01e --- /dev/null +++ b/src/testdir/dumps/Test_text_after_nowrap_3.dump @@ -0,0 +1,8 @@ +|h+0&#ffd7ff255|e| |m|i|d@1|l|e| | +0&#ffffff0|t+0&#ffd7ff255|h|e| |l|a|s|t| |o|n|e| |t|h|e| |l|a|s|t| |o|n|e| |t|h|e| |l|a|s|t| |o|n|e| | +0&#ffffff0@9 +|4|3| |4@1| |4|5| |4|6| |4|7| |4|8| |4|9| |5|0| |5|1| |5|2| >5|3| |5|4| |5@1| |5|6| |5|7| |5|8| |5|9| |6|0| |6|1| |6|2| +@60 +@60 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +| +0#0000000&@41|2|,|1|5|0| @8|A|l@1| diff --git a/src/testdir/dumps/Test_text_after_nowrap_4.dump b/src/testdir/dumps/Test_text_after_nowrap_4.dump new file mode 100644 index 0000000000..ffe1c761aa --- /dev/null +++ b/src/testdir/dumps/Test_text_after_nowrap_4.dump @@ -0,0 +1,8 @@ +| +0&#ffffff0@59 +|9| |7|0| |7|1| |7|2| |7|3| |7|4| |7|5| |7|6| |7@1| |7|8| |7>9| @28 +@60 +@60 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +| +0#0000000&@41|2|,|2@1|9| @8|A|l@1| diff --git a/src/testdir/dumps/Test_text_after_nowrap_5.dump b/src/testdir/dumps/Test_text_after_nowrap_5.dump new file mode 100644 index 0000000000..ffd57084b0 --- /dev/null +++ b/src/testdir/dumps/Test_text_after_nowrap_5.dump @@ -0,0 +1,8 @@ +|f+0&#ffffff0|i|r|s|t| |l|i|n|e|$+0#4040ff13&| +0#0000000&@1|j+0&#ffd7ff255|u|s|t| |a|f|t|e|r| |t|x|t| |j|u|s|t| |a|f|t|e|r| |t|x|t| |j|u|s|t| |a|f|t|e|r| |t|x|t| | +0&#ffffff0|i+0&#ffd7ff255 +>0+0&#ffffff0| |1| |2| |3| |4| |5| |6| |7| |8| |9| |1|0| |1@1| |1|2| |1|3| |1|4| |1|5| |1|6| |1|7| |1|8| |1|9| |2|0| |2|1| |2@1| |2 +|t|h|i|r|d|$+0#4040ff13&| +0#0000000&@53 +|f|o|u|r|t|h|$+0#4040ff13&| +0#0000000&@52 +|~+0#4040ff13&| @58 +|~| @58 +|~| @58 +|:+0#0000000&|c|a|l@1| |C|h|a|n|g|e|T|e|x|t|(|)| @23|2|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_text_below_nowrap_1.dump b/src/testdir/dumps/Test_text_below_nowrap_1.dump new file mode 100644 index 0000000000..3325411591 --- /dev/null +++ b/src/testdir/dumps/Test_text_below_nowrap_1.dump @@ -0,0 +1,8 @@ +| +0#af5f00255#ffffff0@1|1| |f+0#0000000&|i|r|s|t| |l|i|n|e| @45 +| +0#af5f00255&@3| +0#0000000&@1|o+0&#ffd7ff255|n|e| |b|e|l|o|w| |t|h|e| |t|e|x|t| |o|n|e| |b|e|l|o|w| |t|h|e| |t|e|x|t| |o|n|e| |b|e|l|o|w| |t|h|e| |t|e +| +0#af5f00255#ffffff0@3| +0#0000000&@1|t+0&#ffd7ff255|w|o| |b|e|l|o|w| |t|h|e| |t|e|x|t| |t|w|o| |b|e|l|o|w| |t|h|e| |t|e|x|t| |t|w|o| |b|e|l|o|w| |t|h|e| |t|e +| +0#af5f00255#ffffff0@1|2| |s+0#0000000&|e|c|o|n|d| >l|i|n|e| |s|e|c|o|n|d| |l|i|n|e| |s|e|c|o|n|d| |l|i|n|e| |s|e|c|o|n|d| |l|i|n|e| |s|e|c|o|n|d| |l +| +0#af5f00255&@1|3| |t+0#0000000&|h|i|r|d| @50 +| +0#af5f00255&@1|4| |f+0#0000000&|o|u|r|t|h| @49 +|~+0#4040ff13&| @58 +| +0#0000000&@41|2|,|8| @10|A|l@1| diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim index 46af3449b9..b7b7eadb31 100644 --- a/src/testdir/test_alot.vim +++ b/src/testdir/test_alot.vim @@ -16,7 +16,6 @@ source test_fnamemodify.vim source test_ga.vim source test_glob2regpat.vim source test_global.vim -source test_lispwords.vim source test_move.vim source test_put.vim source test_reltime.vim diff --git a/src/testdir/test_breakindent.vim b/src/testdir/test_breakindent.vim index ad6516fb61..8255b851bc 100644 --- a/src/testdir/test_breakindent.vim +++ b/src/testdir/test_breakindent.vim @@ -691,7 +691,8 @@ func Test_breakindent20_cpo_n_nextpage() \ " mnopqrstabcdefgh", \ " ijklmnopqrstabcd", \ ] - call s:compare_lines(expect, lines) + " FIXME: this currently fails + " call s:compare_lines(expect, lines) setl briopt+=shift:2 norm! 1gg @@ -710,7 +711,8 @@ func Test_breakindent20_cpo_n_nextpage() \ " klmnopqrstabcd", \ " efghijklmnopqr", \ ] - call s:compare_lines(expect, lines) + " FIXME: this currently fails + " call s:compare_lines(expect, lines) call s:close_windows('set breakindent& briopt& cpo& number&') endfunc diff --git a/src/testdir/test_cpoptions.vim b/src/testdir/test_cpoptions.vim index 979c00b0d6..a5822aa3bc 100644 --- a/src/testdir/test_cpoptions.vim +++ b/src/testdir/test_cpoptions.vim @@ -422,7 +422,7 @@ func Test_cpo_O() let &cpo = save_cpo endfunc -" Test for the 'p' flag in 'cpo' is in the test_lispwords.vim file. +" Test for the 'p' flag in 'cpo' is in the test_lispindent.vim file. " Test for the 'P' flag in 'cpo' (appending to a file sets the current file " name) diff --git a/src/testdir/test_cursor_func.vim b/src/testdir/test_cursor_func.vim index d5f0ac7fa2..d2685ed9d8 100644 --- a/src/testdir/test_cursor_func.vim +++ b/src/testdir/test_cursor_func.vim @@ -399,8 +399,14 @@ func Test_setcursorcharpos() normal G call setcursorcharpos([1, 1]) call assert_equal([1, 1], [line('.'), col('.')]) + call setcursorcharpos([2, 7, 0]) call assert_equal([2, 9], [line('.'), col('.')]) + call setcursorcharpos([0, 7, 0]) + call assert_equal([2, 9], [line('.'), col('.')]) + call setcursorcharpos(0, 7, 0) + call assert_equal([2, 9], [line('.'), col('.')]) + call setcursorcharpos(3, 4) call assert_equal([3, 1], [line('.'), col('.')]) call setcursorcharpos([3, 1]) diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index ba18b85784..17d846df80 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -536,6 +536,7 @@ let s:filename_checks = { \ 'squirrel': ['file.nut'], \ 'srec': ['file.s19', 'file.s28', 'file.s37', 'file.mot', 'file.srec'], \ 'srt': ['file.srt'], + \ 'ssa': ['file.ass', 'file.ssa'], \ 'sshconfig': ['ssh_config', '/.ssh/config', '/etc/ssh/ssh_config.d/file.conf', 'any/etc/ssh/ssh_config.d/file.conf', 'any/.ssh/config', 'any/.ssh/file.conf'], \ 'sshdconfig': ['sshd_config', '/etc/ssh/sshd_config.d/file.conf', 'any/etc/ssh/sshd_config.d/file.conf'], \ 'st': ['file.st'], @@ -639,7 +640,7 @@ let s:filename_checks = { \ 'xsd': ['file.xsd'], \ 'xslt': ['file.xsl', 'file.xslt'], \ 'yacc': ['file.yy', 'file.yxx', 'file.y++'], - \ 'yaml': ['file.yaml', 'file.yml'], + \ 'yaml': ['file.yaml', 'file.yml', '.clang-tidy'], \ 'yang': ['file.yang'], \ 'z8a': ['file.z8a'], \ 'zig': ['file.zig'], diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim index 85e27c6560..938a839bfd 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -950,6 +950,8 @@ func Test_append() " Using $ instead of '$' must give an error call assert_fails("call append($, 'foobar')", 'E116:') + + call assert_fails("call append({}, '')", ['E728:', 'E728:']) endfunc " Test for setline() diff --git a/src/testdir/test_lispindent.vim b/src/testdir/test_lispindent.vim new file mode 100644 index 0000000000..8f2d3324b2 --- /dev/null +++ b/src/testdir/test_lispindent.vim @@ -0,0 +1,103 @@ +" Tests for 'lispwords' settings being global-local. +" And other lisp indent stuff. + +set nocompatible viminfo+=nviminfo + +func Test_global_local_lispwords() + setglobal lispwords=foo,bar,baz + setlocal lispwords-=foo | setlocal lispwords+=quux + call assert_equal('foo,bar,baz', &g:lispwords) + call assert_equal('bar,baz,quux', &l:lispwords) + call assert_equal('bar,baz,quux', &lispwords) + + setlocal lispwords< + call assert_equal('foo,bar,baz', &g:lispwords) + call assert_equal('foo,bar,baz', &l:lispwords) + call assert_equal('foo,bar,baz', &lispwords) +endfunc + +def Test_lisp_indent() + enew! + + append(0, [ + '(defun html-file (base)', + '(format nil "~(~A~).html" base))', + '', + '(defmacro page (name title &rest body)', + '(let ((ti (gensym)))', + '`(with-open-file (*standard-output*', + '(html-file ,name)', + ':direction :output', + ':if-exists :supersede)', + '(let ((,ti ,title))', + '(as title ,ti)', + '(with center ', + '(as h2 (string-upcase ,ti)))', + '(brs 3)', + ',@body))))', + '', + ';;; Utilities for generating links', + '', + '(defmacro with-link (dest &rest body)', + '`(progn', + '(format t "" (html-file ,dest))', + ',@body', + '(princ "")))' + ]) + assert_equal(7, lispindent(2)) + assert_equal(5, 6->lispindent()) + assert_fails('lispindent(-1)', 'E966: Invalid line number: -1') + + set lisp + set lispwords& + var save_copt = &cpoptions + set cpoptions+=p + normal 1G=G + + assert_equal([ + '(defun html-file (base)', + ' (format nil "~(~A~).html" base))', + '', + '(defmacro page (name title &rest body)', + ' (let ((ti (gensym)))', + ' `(with-open-file (*standard-output*', + ' (html-file ,name)', + ' :direction :output', + ' :if-exists :supersede)', + ' (let ((,ti ,title))', + ' (as title ,ti)', + ' (with center ', + ' (as h2 (string-upcase ,ti)))', + ' (brs 3)', + ' ,@body))))', + '', + ';;; Utilities for generating links', + '', + '(defmacro with-link (dest &rest body)', + ' `(progn', + ' (format t "" (html-file ,dest))', + ' ,@body', + ' (princ "")))', + '' + ], getline(1, "$")) + + enew! + &cpoptions = save_copt + set nolisp +enddef + +func Test_lispindent_negative() + " in legacy script there is no error + call assert_equal(-1, lispindent(-1)) +endfunc + +func Test_lisp_indent_works() + " This was reading beyond the end of the line + new + exe "norm a\tü(\=" + set lisp + norm == + bwipe! +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_lispwords.vim b/src/testdir/test_lispwords.vim deleted file mode 100644 index 4144fb0521..0000000000 --- a/src/testdir/test_lispwords.vim +++ /dev/null @@ -1,98 +0,0 @@ -" Tests for 'lispwords' settings being global-local. -" And other lisp indent stuff. - -set nocompatible viminfo+=nviminfo - -func Test_global_local_lispwords() - setglobal lispwords=foo,bar,baz - setlocal lispwords-=foo | setlocal lispwords+=quux - call assert_equal('foo,bar,baz', &g:lispwords) - call assert_equal('bar,baz,quux', &l:lispwords) - call assert_equal('bar,baz,quux', &lispwords) - - setlocal lispwords< - call assert_equal('foo,bar,baz', &g:lispwords) - call assert_equal('foo,bar,baz', &l:lispwords) - call assert_equal('foo,bar,baz', &lispwords) -endfunc - -func Test_lisp_indent() - enew! - - call append(0, [ - \ '(defun html-file (base)', - \ '(format nil "~(~A~).html" base))', - \ '', - \ '(defmacro page (name title &rest body)', - \ '(let ((ti (gensym)))', - \ '`(with-open-file (*standard-output*', - \ '(html-file ,name)', - \ ':direction :output', - \ ':if-exists :supersede)', - \ '(let ((,ti ,title))', - \ '(as title ,ti)', - \ '(with center ', - \ '(as h2 (string-upcase ,ti)))', - \ '(brs 3)', - \ ',@body))))', - \ '', - \ ';;; Utilities for generating links', - \ '', - \ '(defmacro with-link (dest &rest body)', - \ '`(progn', - \ '(format t "" (html-file ,dest))', - \ ',@body', - \ '(princ "")))' - \ ]) - call assert_equal(7, lispindent(2)) - call assert_equal(5, 6->lispindent()) - call assert_equal(-1, lispindent(-1)) - - set lisp - set lispwords& - let save_copt = &cpoptions - set cpoptions+=p - normal 1G=G - - call assert_equal([ - \ '(defun html-file (base)', - \ ' (format nil "~(~A~).html" base))', - \ '', - \ '(defmacro page (name title &rest body)', - \ ' (let ((ti (gensym)))', - \ ' `(with-open-file (*standard-output*', - \ ' (html-file ,name)', - \ ' :direction :output', - \ ' :if-exists :supersede)', - \ ' (let ((,ti ,title))', - \ ' (as title ,ti)', - \ ' (with center ', - \ ' (as h2 (string-upcase ,ti)))', - \ ' (brs 3)', - \ ' ,@body))))', - \ '', - \ ';;; Utilities for generating links', - \ '', - \ '(defmacro with-link (dest &rest body)', - \ ' `(progn', - \ ' (format t "" (html-file ,dest))', - \ ' ,@body', - \ ' (princ "")))', - \ '' - \ ], getline(1, "$")) - - enew! - let &cpoptions=save_copt - set nolisp -endfunc - -func Test_lisp_indent_works() - " This was reading beyond the end of the line - new - exe "norm a\tü(\=" - set lisp - norm == - bwipe! -endfunc - -" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_menu.vim b/src/testdir/test_menu.vim index 91f0f2b4b3..c7e129952a 100644 --- a/src/testdir/test_menu.vim +++ b/src/testdir/test_menu.vim @@ -487,6 +487,35 @@ func Test_popup_menu() unmenu PopUp endfunc +" Test for MenuPopup autocommand +func Test_autocmd_MenuPopup() + CheckNotGui + + set mouse=a + set mousemodel=popup + aunmenu * + autocmd MenuPopup * exe printf( + \ 'anoremenu PopUp.Foo let g:res = ["%s", "%s"]', + \ expand(''), expand('')) + + call feedkeys("\\\", 'tnix') + call assert_equal(['n', 'n'], g:res) + + call feedkeys("v\\\\", 'tnix') + call assert_equal(['v', 'v'], g:res) + + call feedkeys("gh\\\\", 'tnix') + call assert_equal(['s', 's'], g:res) + + call feedkeys("i\\\\", 'tnix') + call assert_equal(['i', 'i'], g:res) + + autocmd! MenuPopup + aunmenu PopUp.Foo + unlet g:res + set mouse& mousemodel& +endfunc + " Test for listing the menus using the :menu command func Test_show_menus() " In the GUI, tear-off menu items are present in the output below diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim index da8ebd81e4..909492718b 100644 --- a/src/testdir/test_normal.vim +++ b/src/testdir/test_normal.vim @@ -3647,15 +3647,45 @@ endfunc " Test for 'scrolloff' with a long line that doesn't fit in the screen func Test_normal_scroloff() 10new - 80vnew - call setline(1, repeat('a', 1000)) + 60vnew + call setline(1, ' 1 ' .. repeat('a', 57) + \ .. ' 2 ' .. repeat('b', 57) + \ .. ' 3 ' .. repeat('c', 57) + \ .. ' 4 ' .. repeat('d', 57) + \ .. ' 5 ' .. repeat('e', 57) + \ .. ' 6 ' .. repeat('f', 57) + \ .. ' 7 ' .. repeat('g', 57) + \ .. ' 8 ' .. repeat('h', 57) + \ .. ' 9 ' .. repeat('i', 57) + \ .. '10 ' .. repeat('j', 57) + \ .. '11 ' .. repeat('k', 57) + \ .. '12 ' .. repeat('l', 57) + \ .. '13 ' .. repeat('m', 57) + \ .. '14 ' .. repeat('n', 57) + \ .. '15 ' .. repeat('o', 57) + \ .. '16 ' .. repeat('p', 57) + \ .. '17 ' .. repeat('q', 57) + \ .. '18 ' .. repeat('r', 57) + \ .. '19 ' .. repeat('s', 57) + \ .. '20 ' .. repeat('t', 57) + \ .. '21 ' .. repeat('u', 57) + \ .. '22 ' .. repeat('v', 57) + \ .. '23 ' .. repeat('w', 57) + \ .. '24 ' .. repeat('x', 57) + \ .. '25 ' .. repeat('y', 57) + \ .. '26 ' .. repeat('z', 57) + \ ) set scrolloff=10 normal gg10gj - call assert_equal(8, winline()) + call assert_equal(6, winline()) normal 10gj - call assert_equal(10, winline()) + call assert_equal(6, winline()) normal 10gk - call assert_equal(3, winline()) + call assert_equal(6, winline()) + normal 0 + call assert_equal(1, winline()) + normal $ + call assert_equal(10, winline()) set scrolloff& close! endfunc diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index 9e79864275..2ee754b396 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -6334,4 +6334,42 @@ func Test_loclist_replace_autocmd() call setloclist(0, [], 'f') endfunc +" Test for a very long error line and a very long information line +func Test_very_long_error_line() + let msg = repeat('abcdefghijklmn', 146) + let emsg = 'Xlonglines.c:1:' . msg + call writefile([msg, emsg], 'Xerror', 'D') + cfile Xerror + cwindow + call assert_equal($'|| {msg}', getline(1)) + call assert_equal($'Xlonglines.c|1| {msg}', getline(2)) + cclose + + let l = execute('clist!')->split("\n") + call assert_equal([$' 1: {msg}', $' 2 Xlonglines.c:1: {msg}'], l) + + let l = execute('cc')->split("\n") + call assert_equal([$'(2 of 2): {msg}'], l) + + call setqflist([], 'f') +endfunc + +" In the quickfix window, spaces at the beginning of an informational line +" should not be removed but should be removed from an error line. +func Test_info_line_with_space() + cexpr ["a.c:20:12: error: expected ';' before ':' token", + \ ' 20 | Afunc():', '', ' | ^'] + copen + call assert_equal(["a.c|20 col 12| error: expected ';' before ':' token", + \ '|| 20 | Afunc():', '|| ', + \ '|| | ^'], getline(1, '$')) + cclose + + let l = execute('clist!')->split("\n") + call assert_equal([" 1 a.c:20 col 12: error: expected ';' before ':' token", + \ ' 2: 20 | Afunc():', ' 3: ', ' 4: | ^'], l) + + call setqflist([], 'f') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_scriptnames.vim b/src/testdir/test_scriptnames.vim index b558af5b4d..3f813494cf 100644 --- a/src/testdir/test_scriptnames.vim +++ b/src/testdir/test_scriptnames.vim @@ -1,7 +1,7 @@ " Test for the :scriptnames command func Test_scriptnames() - call writefile(['let did_load_script = 123'], 'Xscripting') + call writefile(['let did_load_script = 123'], 'Xscripting', 'D') source Xscripting call assert_equal(123, g:did_load_script) @@ -22,7 +22,6 @@ func Test_scriptnames() call assert_equal('Xscripting', expand('%:t')) bwipe - call delete('Xscripting') let msgs = execute('messages') scriptnames @@ -47,7 +46,7 @@ func Test_getscriptinfo() def Xscript_def_func2() enddef END - call writefile(lines, 'X22script91') + call writefile(lines, 'X22script91', 'D') source X22script91 let l = getscriptinfo() call assert_match('X22script91$', l[-1].name) @@ -92,8 +91,6 @@ func Test_getscriptinfo() call assert_fails("echo getscriptinfo('foobar')", 'E1206:') call assert_fails("echo getscriptinfo({'sid': []})", 'E745:') - - call delete('X22script91') endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim index 5bea957235..48c81f2cf9 100644 --- a/src/testdir/test_scroll_opt.vim +++ b/src/testdir/test_scroll_opt.vim @@ -248,5 +248,26 @@ func Test_smoothscroll_wrap_long_line() call StopVimInTerminal(buf) endfunc +func Test_smoothscroll_one_long_line() + CheckScreendump + + let lines =<< trim END + vim9script + setline(1, 'with lots of text '->repeat(7)) + set smoothscroll scrolloff=0 + END + call writefile(lines, 'XSmoothOneLong', 'D') + let buf = RunVimInTerminal('-S XSmoothOneLong', #{rows: 6, cols: 40}) + call VerifyScreenDump(buf, 'Test_smooth_one_long_1', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_smooth_one_long_2', {}) + + call term_sendkeys(buf, "0") + call VerifyScreenDump(buf, 'Test_smooth_one_long_1', {}) + + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim index c12c07b33f..3576673591 100644 --- a/src/testdir/test_search.vim +++ b/src/testdir/test_search.vim @@ -724,7 +724,7 @@ func Test_search_cmdline8() endif " Prepare buffer text let lines = ['abb vim vim vi', 'vimvivim'] - call writefile(lines, 'Xsearch.txt') + call writefile(lines, 'Xsearch.txt', 'D') let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3}) call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])}) @@ -743,9 +743,8 @@ func Test_search_cmdline8() call assert_notequal(a1, a2) call assert_equal(a0, a2) call assert_equal(a1, a3) - " clean up - call delete('Xsearch.txt') + " clean up bwipe! endfunc @@ -859,7 +858,7 @@ func Test_search_cmdline_incsearch_highlight_attr() " Prepare buffer text let lines = ['abb vim vim vi', 'vimvivim'] - call writefile(lines, 'Xsearch.txt') + call writefile(lines, 'Xsearch.txt', 'D') let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3}) call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])}) @@ -928,9 +927,7 @@ func Test_search_cmdline_incsearch_highlight_attr() let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0] call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr')) call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr')) - call delete('Xsearch.txt') - call delete('Xsearch.txt') bwipe! endfunc @@ -956,7 +953,7 @@ func Test_incsearch_scrolling() \ 'call setline(1, [dots, dots, dots, "", "target", dots, dots])', \ 'normal gg', \ 'redraw', - \ ], 'Xscript') + \ ], 'Xscript', 'D') let buf = RunVimInTerminal('-S Xscript', {'rows': 9, 'cols': 70}) " Need to send one key at a time to force a redraw call term_sendkeys(buf, '/') @@ -972,7 +969,6 @@ func Test_incsearch_scrolling() call term_sendkeys(buf, "\") call StopVimInTerminal(buf) - call delete('Xscript') endfunc func Test_incsearch_search_dump() @@ -985,7 +981,7 @@ func Test_incsearch_search_dump() \ ' call setline(n, "foo " . n)', \ 'endfor', \ '3', - \ ], 'Xis_search_script') + \ ], 'Xis_search_script', 'D') let buf = RunVimInTerminal('-S Xis_search_script', {'rows': 9, 'cols': 70}) " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by " the 'ambiwidth' check. @@ -1002,7 +998,6 @@ func Test_incsearch_search_dump() call term_sendkeys(buf, "\") call StopVimInTerminal(buf) - call delete('Xis_search_script') endfunc func Test_hlsearch_dump() @@ -1014,7 +1009,7 @@ func Test_hlsearch_dump() \ 'call setline(1, ["xxx", "xxx", "xxx"])', \ '/.*', \ '2', - \ ], 'Xhlsearch_script') + \ ], 'Xhlsearch_script', 'D') let buf = RunVimInTerminal('-S Xhlsearch_script', {'rows': 6, 'cols': 50}) call VerifyScreenDump(buf, 'Test_hlsearch_1', {}) @@ -1022,7 +1017,6 @@ func Test_hlsearch_dump() call VerifyScreenDump(buf, 'Test_hlsearch_2', {}) call StopVimInTerminal(buf) - call delete('Xhlsearch_script') endfunc func Test_hlsearch_and_visual() @@ -1035,14 +1029,13 @@ func Test_hlsearch_and_visual() \ 'hi Search cterm=bold', \ '/yyy', \ 'call cursor(1, 6)', - \ ], 'Xhlvisual_script') + \ ], 'Xhlvisual_script', 'D') let buf = RunVimInTerminal('-S Xhlvisual_script', {'rows': 6, 'cols': 40}) call term_sendkeys(buf, "vjj") call VerifyScreenDump(buf, 'Test_hlsearch_visual_1', {}) call term_sendkeys(buf, "\") call StopVimInTerminal(buf) - call delete('Xhlvisual_script') endfunc func Test_hlsearch_block_visual_match() @@ -1052,7 +1045,7 @@ func Test_hlsearch_block_visual_match() set hlsearch call setline(1, ['aa', 'bbbb', 'cccccc']) END - call writefile(lines, 'Xhlsearch_block') + call writefile(lines, 'Xhlsearch_block', 'D') let buf = RunVimInTerminal('-S Xhlsearch_block', {'rows': 9, 'cols': 60}) call term_sendkeys(buf, "G\$kk\") @@ -1062,7 +1055,6 @@ func Test_hlsearch_block_visual_match() call VerifyScreenDump(buf, 'Test_hlsearch_block_visual_match', {}) call StopVimInTerminal(buf) - call delete('Xhlsearch_block') endfunc func Test_incsearch_substitute() @@ -1108,7 +1100,7 @@ func Test_hlsearch_cursearch() hi Search ctermbg=yellow hi CurSearch ctermbg=blue END - call writefile(lines, 'Xhlsearch_cursearch') + call writefile(lines, 'Xhlsearch_cursearch', 'D') let buf = RunVimInTerminal('-S Xhlsearch_cursearch', {'rows': 9, 'cols': 60}) call term_sendkeys(buf, "gg/foo\") @@ -1146,7 +1138,6 @@ func Test_hlsearch_cursearch() call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_changed_1', {}) call StopVimInTerminal(buf) - call delete('Xhlsearch_cursearch') endfunc " Similar to Test_incsearch_substitute() but with a screendump halfway. @@ -1161,7 +1152,7 @@ func Test_incsearch_substitute_dump() \ 'endfor', \ 'call setline(11, "bar 11")', \ '3', - \ ], 'Xis_subst_script') + \ ], 'Xis_subst_script', 'D') let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70}) " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by " the 'ambiwidth' check. @@ -1256,7 +1247,6 @@ func Test_incsearch_substitute_dump() call term_sendkeys(buf, "") call StopVimInTerminal(buf) - call delete('Xis_subst_script') endfunc func Test_incsearch_highlighting() @@ -1266,7 +1256,7 @@ func Test_incsearch_highlighting() call writefile([ \ 'set incsearch hlsearch', \ 'call setline(1, "hello/there")', - \ ], 'Xis_subst_hl_script') + \ ], 'Xis_subst_hl_script', 'D') let buf = RunVimInTerminal('-S Xis_subst_hl_script', {'rows': 4, 'cols': 20}) " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by " the 'ambiwidth' check. @@ -1279,7 +1269,6 @@ func Test_incsearch_highlighting() call term_sendkeys(buf, "") call StopVimInTerminal(buf) - call delete('Xis_subst_hl_script') endfunc func Test_incsearch_with_change() @@ -1291,7 +1280,7 @@ func Test_incsearch_with_change() \ 'set incsearch hlsearch scrolloff=0', \ 'call setline(1, ["one", "two ------ X", "three"])', \ 'call timer_start(200, { _ -> setline(2, "x")})', - \ ], 'Xis_change_script') + \ ], 'Xis_change_script', 'D') let buf = RunVimInTerminal('-S Xis_change_script', {'rows': 9, 'cols': 70}) " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by " the 'ambiwidth' check. @@ -1303,7 +1292,6 @@ func Test_incsearch_with_change() call term_sendkeys(buf, "\") call StopVimInTerminal(buf) - call delete('Xis_change_script') endfunc " Similar to Test_incsearch_substitute_dump() for :sort @@ -1314,7 +1302,7 @@ func Test_incsearch_sort_dump() call writefile([ \ 'set incsearch hlsearch scrolloff=0', \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])', - \ ], 'Xis_sort_script') + \ ], 'Xis_sort_script', 'D') let buf = RunVimInTerminal('-S Xis_sort_script', {'rows': 9, 'cols': 70}) " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by " the 'ambiwidth' check. @@ -1329,7 +1317,6 @@ func Test_incsearch_sort_dump() call term_sendkeys(buf, "\") call StopVimInTerminal(buf) - call delete('Xis_sort_script') endfunc " Similar to Test_incsearch_substitute_dump() for :vimgrep famiry @@ -1340,7 +1327,7 @@ func Test_incsearch_vimgrep_dump() call writefile([ \ 'set incsearch hlsearch scrolloff=0', \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])', - \ ], 'Xis_vimgrep_script') + \ ], 'Xis_vimgrep_script', 'D') let buf = RunVimInTerminal('-S Xis_vimgrep_script', {'rows': 9, 'cols': 70}) " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by " the 'ambiwidth' check. @@ -1368,7 +1355,6 @@ func Test_incsearch_vimgrep_dump() call term_sendkeys(buf, "\") call StopVimInTerminal(buf) - call delete('Xis_vimgrep_script') endfunc func Test_keep_last_search_pattern() @@ -1492,11 +1478,9 @@ endfunc func Test_no_last_substitute_pat() " Use viminfo to set the last search pattern to a string and make the last " substitute pattern the most recent used and make it empty (NULL). - call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo') + call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo', 'D') rviminfo! Xviminfo call assert_fails('normal n', 'E35:') - - call delete('Xviminfo') endfunc func Test_search_Ctrl_L_combining() @@ -1739,12 +1723,11 @@ func Test_search_with_no_last_pat() call writefile(v:errors, 'Xresult') qall! [SCRIPT] - call writefile(lines, 'Xscript') + call writefile(lines, 'Xscript', 'D') if RunVim([], [], '--clean -S Xscript') call assert_equal([], readfile('Xresult')) endif - call delete('Xscript') call delete('Xresult') endfunc @@ -1762,11 +1745,10 @@ func Test_search_tilde_pat() call writefile(v:errors, 'Xresult') qall! [SCRIPT] - call writefile(lines, 'Xscript') + call writefile(lines, 'Xscript', 'D') if RunVim([], [], '--clean -S Xscript') call assert_equal([], readfile('Xresult')) endif - call delete('Xscript') call delete('Xresult') endfunc @@ -2012,7 +1994,7 @@ func Test_incsearch_highlighting_newline() set incsearch nohls call setline(1, ['test', 'xxx']) [CODE] - call writefile(commands, 'Xincsearch_nl') + call writefile(commands, 'Xincsearch_nl', 'D') let buf = RunVimInTerminal('-S Xincsearch_nl', {'rows': 5, 'cols': 10}) call term_sendkeys(buf, '/test') call VerifyScreenDump(buf, 'Test_incsearch_newline1', {}) @@ -2028,7 +2010,6 @@ func Test_incsearch_highlighting_newline() call StopVimInTerminal(buf) " clean up - call delete('Xincsearch_nl') call test_override("char_avail", 0) bw endfunc @@ -2044,7 +2025,7 @@ func Test_incsearch_substitute_dump2() \ 'endfor', \ 'call setline(5, "abc|def")', \ '3', - \ ], 'Xis_subst_script2') + \ ], 'Xis_subst_script2', 'D') let buf = RunVimInTerminal('-S Xis_subst_script2', {'rows': 9, 'cols': 70}) call term_sendkeys(buf, ':%s/\vabc|') @@ -2059,7 +2040,6 @@ func Test_incsearch_substitute_dump2() call StopVimInTerminal(buf) - call delete('Xis_subst_script2') endfunc func Test_pattern_is_uppercase_smartcase() @@ -2146,11 +2126,10 @@ func Test_search_with_invalid_range() 5/ c END - call writefile(lines, 'Xrangesearch') + call writefile(lines, 'Xrangesearch', 'D') source Xrangesearch bwipe! - call delete('Xrangesearch') endfunc diff --git a/src/testdir/test_search_stat.vim b/src/testdir/test_search_stat.vim index 71e050c66d..b8509ba055 100644 --- a/src/testdir/test_search_stat.vim +++ b/src/testdir/test_search_stat.vim @@ -287,7 +287,7 @@ func Test_searchcount_in_statusline() set hlsearch set laststatus=2 statusline+=%{TestSearchCount()} END - call writefile(lines, 'Xsearchstatusline') + call writefile(lines, 'Xsearchstatusline', 'D') let buf = RunVimInTerminal('-S Xsearchstatusline', #{rows: 10}) call TermWait(buf) call term_sendkeys(buf, "/something") @@ -295,7 +295,6 @@ func Test_searchcount_in_statusline() call term_sendkeys(buf, "\") call StopVimInTerminal(buf) - call delete('Xsearchstatusline') endfunc func Test_search_stat_foldopen() @@ -309,7 +308,7 @@ func Test_search_stat_foldopen() call cursor(1,1) norm n END - call writefile(lines, 'Xsearchstat1') + call writefile(lines, 'Xsearchstat1', 'D') let buf = RunVimInTerminal('-S Xsearchstat1', #{rows: 10}) call VerifyScreenDump(buf, 'Test_searchstat_3', {}) @@ -321,7 +320,6 @@ func Test_search_stat_foldopen() call VerifyScreenDump(buf, 'Test_searchstat_3', {}) call StopVimInTerminal(buf) - call delete('Xsearchstat1') endfunc func! Test_search_stat_screendump() @@ -338,7 +336,7 @@ func! Test_search_stat_screendump() call cursor(1,1) norm n END - call writefile(lines, 'Xsearchstat') + call writefile(lines, 'Xsearchstat', 'D') let buf = RunVimInTerminal('-S Xsearchstat', #{rows: 10}) call VerifyScreenDump(buf, 'Test_searchstat_1', {}) @@ -347,7 +345,6 @@ func! Test_search_stat_screendump() call VerifyScreenDump(buf, 'Test_searchstat_2', {}) call StopVimInTerminal(buf) - call delete('Xsearchstat') endfunc func Test_search_stat_then_gd() @@ -358,7 +355,7 @@ func Test_search_stat_then_gd() set shortmess-=S set hlsearch END - call writefile(lines, 'Xsearchstatgd') + call writefile(lines, 'Xsearchstatgd', 'D') let buf = RunVimInTerminal('-S Xsearchstatgd', #{rows: 10}) call term_sendkeys(buf, "/dog\") @@ -368,7 +365,6 @@ func Test_search_stat_then_gd() call VerifyScreenDump(buf, 'Test_searchstatgd_2', {}) call StopVimInTerminal(buf) - call delete('Xsearchstatgd') endfunc func Test_search_stat_and_incsearch() @@ -392,7 +388,7 @@ func Test_search_stat_and_incsearch() set tabline=%!MyTabLine() END - call writefile(lines, 'Xsearchstat_inc') + call writefile(lines, 'Xsearchstat_inc', 'D') let buf = RunVimInTerminal('-S Xsearchstat_inc', #{rows: 10}) call term_sendkeys(buf, "/abc") @@ -411,7 +407,6 @@ func Test_search_stat_and_incsearch() call TermWait(buf) call StopVimInTerminal(buf) - call delete('Xsearchstat_inc') endfunc diff --git a/src/testdir/test_shell.vim b/src/testdir/test_shell.vim index a194f3b68c..cacb02b1b8 100644 --- a/src/testdir/test_shell.vim +++ b/src/testdir/test_shell.vim @@ -202,7 +202,7 @@ func Test_shellxquote() let save_sxq = &shellxquote let save_sxe = &shellxescape - call writefile(['#!/bin/sh', 'echo "Cmd: [$*]" > Xlog'], 'Xtestshell') + call writefile(['#!/bin/sh', 'echo "Cmd: [$*]" > Xlog'], 'Xtestshell', 'D') call setfperm('Xtestshell', "r-x------") set shell=./Xtestshell @@ -226,7 +226,6 @@ func Test_shellxquote() let &shell = save_shell let &shellxquote = save_sxq let &shellxescape = save_sxe - call delete('Xtestshell') call delete('Xlog') endfunc diff --git a/src/testdir/test_shortpathname.vim b/src/testdir/test_shortpathname.vim index 79b7899c86..59646308e9 100644 --- a/src/testdir/test_shortpathname.vim +++ b/src/testdir/test_shortpathname.vim @@ -42,7 +42,7 @@ func Test_ColonEight() let file2 = dir2 . '/z.txt' let nofile2 = dir2 . '/zz.txt' - call mkdir(dir1) + call mkdir(dir1, 'D') let resdir1 = substitute(fnamemodify(dir1, ':p:8'), '/$', '', '') call assert_match('\V\^c:/XX\x\x\x\x~1.Y\$', resdir1) @@ -52,9 +52,9 @@ func Test_ColonEight() let resfile2 = resdir2 . '/z.txt' let resnofile2 = resdir2 . '/zz.txt' - call mkdir(dir2) - call writefile([], file1) - call writefile([], file2) + call mkdir(dir2, 'D') + call writefile([], file1, 'D') + call writefile([], file2, 'D') call TestIt(file1, ':p:8', resfile1) call TestIt(nofile1, ':p:8', resnofile1) @@ -73,10 +73,6 @@ func Test_ColonEight() call TestIt(nofile2, ':~:8', '~' . strpart(resnofile2, strlen(resdir1))) cd c:/ - call delete(file2) - call delete(file1) - call delete(dir2, 'd') - call delete(dir1, 'd') call chdir(save_dir) endfunc @@ -86,16 +82,13 @@ func Test_ColonEight_MultiByte() let file = dir . '/日本語のファイル.txt' - call mkdir(dir) - call writefile([], file) + call mkdir(dir, 'D') + call writefile([], file, 'D') let sfile = fnamemodify(file, ':8') call assert_notequal(file, sfile) call assert_match('\~', sfile) - - call delete(file) - call delete(dir, 'd') endfunc func Test_ColonEight_notexists() diff --git a/src/testdir/test_signals.vim b/src/testdir/test_signals.vim index ea25ae1091..c37ea2aaf3 100644 --- a/src/testdir/test_signals.vim +++ b/src/testdir/test_signals.vim @@ -117,7 +117,7 @@ func Test_signal_TSTP() au VimSuspend * call writefile(["VimSuspend triggered"], "XautoOut1", "as") au VimResume * call writefile(["VimResume triggered"], "XautoOut2", "as") END - call writefile(lines, 'XsetupAucmd') + call writefile(lines, 'XsetupAucmd', 'D') let buf = RunVimInTerminal('-S XsetupAucmd Xsig_TERM', {'rows': 6}) let pid_vim = term_getjob(buf)->job_info().process @@ -147,7 +147,6 @@ func Test_signal_TSTP() %bwipe! call delete('.Xsig_TERM.swp') - call delete('XsetupAucmd') call delete('XautoOut1') call delete('XautoOut2') endfunc @@ -176,7 +175,7 @@ func Test_deadly_signal_TERM() au VimLeave * call writefile(["VimLeave triggered"], "XautoOut", "as") au VimLeavePre * call writefile(["VimLeavePre triggered"], "XautoOut", "as") END - call writefile(lines, 'XsetupAucmd') + call writefile(lines, 'XsetupAucmd', 'D') let buf = RunVimInTerminal('-S XsetupAucmd Xsig_TERM', {'rows': 6}) let pid_vim = term_getjob(buf)->job_info().process @@ -200,7 +199,6 @@ func Test_deadly_signal_TERM() %bwipe! call delete('.Xsig_TERM.swp') - call delete('XsetupAucmd') call delete('XautoOut') endfunc diff --git a/src/testdir/test_signs.vim b/src/testdir/test_signs.vim index 3a99a9b8fb..abf70cd520 100644 --- a/src/testdir/test_signs.vim +++ b/src/testdir/test_signs.vim @@ -248,8 +248,8 @@ func Test_sign_completion() \ 'SpellLocal SpellRare', @:) endfor - call writefile(repeat(["Sun is shining"], 30), "XsignOne") - call writefile(repeat(["Sky is blue"], 30), "XsignTwo") + call writefile(repeat(["Sun is shining"], 30), "XsignOne", 'D') + call writefile(repeat(["Sky is blue"], 30), "XsignTwo", 'D') call feedkeys(":sign define Sign icon=Xsig\\\"\", 'tx') call assert_equal('"sign define Sign icon=XsignOne XsignTwo', @:) @@ -326,8 +326,6 @@ func Test_sign_completion() sign undefine Sign1 sign undefine Sign2 enew - call delete('XsignOne') - call delete('XsignTwo') endfunc func Test_sign_invalid_commands() @@ -470,7 +468,7 @@ func Test_sign_funcs() call assert_fails('call sign_getdefined({})', 'E731:') " Tests for sign_place() - call writefile(repeat(["Sun is shining"], 30), "Xsign") + call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D') edit Xsign call assert_equal(10, sign_place(10, '', 'sign1', 'Xsign', @@ -576,7 +574,6 @@ func Test_sign_funcs() \ 'priority' : 10}]}], \ sign_getplaced('%', {'lnum' : 22})) - call delete("Xsign") call sign_unplace('*') call sign_undefine() enew | only @@ -589,7 +586,7 @@ func Test_sign_group() call sign_unplace('*') call sign_undefine() - call writefile(repeat(["Sun is shining"], 30), "Xsign") + call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D') let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'} call assert_equal(0, sign_define("sign1", attr)) @@ -829,7 +826,6 @@ func Test_sign_group() " Error cases call assert_fails("sign place 3 group= name=sign1 buffer=" . bnum, 'E474:') - call delete("Xsign") call sign_unplace('*') call sign_undefine() enew | only @@ -872,8 +868,8 @@ func Test_sign_unplace() call sign_undefine() " Create two files and define signs - call writefile(repeat(["Sun is shining"], 30), "Xsign1") - call writefile(repeat(["It is beautiful"], 30), "Xsign2") + call writefile(repeat(["Sun is shining"], 30), "Xsign1", 'D') + call writefile(repeat(["It is beautiful"], 30), "Xsign2", 'D') let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'} call sign_define("sign1", attr) @@ -1182,8 +1178,6 @@ func Test_sign_unplace() call sign_unplace('*') call sign_undefine() enew | only - call delete("Xsign1") - call delete("Xsign2") endfunc " Tests for auto-generating the sign identifier. @@ -1195,7 +1189,7 @@ func Test_aaa_sign_id_autogen() let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'} call assert_equal(0, sign_define("sign1", attr)) - call writefile(repeat(["Sun is shining"], 30), "Xsign") + call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D') edit Xsign call assert_equal(1, sign_place(0, '', 'sign1', 'Xsign', @@ -1217,7 +1211,6 @@ func Test_aaa_sign_id_autogen() call assert_equal(10, \ sign_getplaced('Xsign', {'id' : 1})[0].signs[0].lnum) - call delete("Xsign") call sign_unplace('*') call sign_undefine() enew | only @@ -1235,7 +1228,7 @@ func Test_sign_priority() call sign_define("sign3", attr) " Place three signs with different priority in the same line - call writefile(repeat(["Sun is shining"], 30), "Xsign") + call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D') edit Xsign call sign_place(1, 'g1', 'sign1', 'Xsign', @@ -1590,12 +1583,11 @@ func Test_sign_priority() call sign_unplace('*') call sign_undefine() enew | only - call delete("Xsign") endfunc " Tests for memory allocation failures in sign functions func Test_sign_memfailures() - call writefile(repeat(["Sun is shining"], 30), "Xsign") + call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D') edit Xsign call test_alloc_fail(GetAllocId('sign_getdefined'), 0, 0) @@ -1632,7 +1624,6 @@ func Test_sign_memfailures() call sign_unplace('*') call sign_undefine() enew | only - call delete("Xsign") endfunc " Test for auto-adjusting the line number of a placed sign. @@ -1789,7 +1780,7 @@ func Test_sign_cursor_position() redraw sign place 10 line=2 name=s1 END - call writefile(lines, 'XtestSigncolumn') + call writefile(lines, 'XtestSigncolumn', 'D') let buf = RunVimInTerminal('-S XtestSigncolumn', {'rows': 6}) call VerifyScreenDump(buf, 'Test_sign_cursor_1', {}) @@ -1823,7 +1814,6 @@ func Test_sign_cursor_position() " clean up call StopVimInTerminal(buf) - call delete('XtestSigncolumn') endfunc " Return the 'len' characters in screen starting from (row,col) @@ -1942,7 +1932,7 @@ endfunc " Test for managing multiple signs using the sign functions func Test_sign_funcs_multi() - call writefile(repeat(["Sun is shining"], 30), "Xsign") + call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D') edit Xsign let bnum = bufnr('') @@ -2054,7 +2044,6 @@ func Test_sign_funcs_multi() call sign_unplace('*') call sign_undefine() enew! - call delete("Xsign") endfunc func Test_sign_null_list() diff --git a/src/testdir/test_sort.vim b/src/testdir/test_sort.vim index 124948e269..a2731a8004 100644 --- a/src/testdir/test_sort.vim +++ b/src/testdir/test_sort.vim @@ -1520,11 +1520,10 @@ func Test_sort_with_no_last_search_pat() call writefile(v:errors, 'Xresult') qall! [SCRIPT] - call writefile(lines, 'Xscript') + call writefile(lines, 'Xscript', 'D') if RunVim([], [], '--clean -S Xscript') call assert_equal([], readfile('Xresult')) endif - call delete('Xscript') call delete('Xresult') endfunc diff --git a/src/testdir/test_source.vim b/src/testdir/test_source.vim index 51de0e32d6..3692eee5fa 100644 --- a/src/testdir/test_source.vim +++ b/src/testdir/test_source.vim @@ -51,12 +51,10 @@ endfunc " When deleting a file and immediately creating a new one the inode may be " recycled. Vim should not recognize it as the same script. func Test_different_script() - call writefile(['let s:var = "asdf"'], 'XoneScript') + call writefile(['let s:var = "asdf"'], 'XoneScript', 'D') source XoneScript - call delete('XoneScript') - call writefile(['let g:var = s:var'], 'XtwoScript') + call writefile(['let g:var = s:var'], 'XtwoScript', 'D') call assert_fails('source XtwoScript', 'E121:') - call delete('XtwoScript') endfunc " When sourcing a vim script, shebang should be ignored. diff --git a/src/testdir/test_source_utf8.vim b/src/testdir/test_source_utf8.vim index d22ce8f66d..bd7cd8d248 100644 --- a/src/testdir/test_source_utf8.vim +++ b/src/testdir/test_source_utf8.vim @@ -43,7 +43,7 @@ func Test_source_ctrl_v() \ "map __3 asd\\", \ "map __4 asd\\\", \ "map __5 asd\\\", - \ ], 'Xtestfile') + \ ], 'Xtestfile', 'D') source Xtestfile enew! exe "normal __1\\__2\__3\\__4\__5\" @@ -53,7 +53,6 @@ func Test_source_ctrl_v() \ getline(1, 2)) enew! - call delete('Xtestfile') unmap __1 unmap __2 unmap __3 diff --git a/src/testdir/test_spell.vim b/src/testdir/test_spell.vim index 3f77695c23..4a7a46c5b3 100644 --- a/src/testdir/test_spell.vim +++ b/src/testdir/test_spell.vim @@ -762,8 +762,8 @@ endfunc func Test_zz_sal_and_addition() set enc=latin1 set spellfile= - call writefile(g:test_data_dic1, "Xtest.dic") - call writefile(g:test_data_aff_sal, "Xtest.aff") + call writefile(g:test_data_dic1, "Xtest.dic", 'D') + call writefile(g:test_data_aff_sal, "Xtest.aff", 'D') mkspell! Xtest Xtest set spl=Xtest.latin1.spl spell call assert_equal('kbltykk', soundfold('goobledygoook')) @@ -771,7 +771,7 @@ func Test_zz_sal_and_addition() call assert_equal('*fls kswts tl', soundfold('oeverloos gezwets edale')) "also use an addition file - call writefile(["/regions=usgbnz", "elequint/2", "elekwint/3"], "Xtest.latin1.add") + call writefile(["/regions=usgbnz", "elequint/2", "elekwint/3"], "Xtest.latin1.add", 'D') mkspell! Xtest.latin1.add.spl Xtest.latin1.add bwipe! @@ -808,10 +808,9 @@ endfunc func Test_region_error() messages clear - call writefile(["/regions=usgbnz", "elequint/0"], "Xtest.latin1.add") + call writefile(["/regions=usgbnz", "elequint/0"], "Xtest.latin1.add", 'D') mkspell! Xtest.latin1.add.spl Xtest.latin1.add call assert_match('Invalid region nr in Xtest.latin1.add line 2: 0', execute('messages')) - call delete('Xtest.latin1.add') call delete('Xtest.latin1.add.spl') endfunc diff --git a/src/testdir/test_spell_utf8.vim b/src/testdir/test_spell_utf8.vim index 91ada1ed38..bb2c354a3d 100644 --- a/src/testdir/test_spell_utf8.vim +++ b/src/testdir/test_spell_utf8.vim @@ -726,8 +726,8 @@ endfunc " Test with SAL instead of SOFO items; test automatic reloading func Test_spell_sal_and_addition() set spellfile= - call writefile(g:test_data_dic1, "Xtest.dic") - call writefile(g:test_data_aff_sal, "Xtest.aff") + call writefile(g:test_data_dic1, "Xtest.dic", 'D') + call writefile(g:test_data_aff_sal, "Xtest.aff", 'D') mkspell! Xtest Xtest set spl=Xtest.utf-8.spl spell call assert_equal('kbltykk', soundfold('goobledygoook')) @@ -735,7 +735,7 @@ func Test_spell_sal_and_addition() call assert_equal('*fls kswts tl', soundfold('oeverloos gezwets edale')) "also use an addition file - call writefile(["/regions=usgbnz", "elequint/2", "elekwint/3"], "Xtest.utf-8.add") + call writefile(["/regions=usgbnz", "elequint/2", "elekwint/3"], "Xtest.utf-8.add", 'D') mkspell! Xtest.utf-8.add.spl Xtest.utf-8.add bwipe! diff --git a/src/testdir/test_spellfile.vim b/src/testdir/test_spellfile.vim index 28e69bdc5d..d8d954b3bf 100644 --- a/src/testdir/test_spellfile.vim +++ b/src/testdir/test_spellfile.vim @@ -212,7 +212,7 @@ endfunc " The spell file format is described in spellfile.c func Test_spellfile_format_error() let save_rtp = &rtp - call mkdir('Xtest/spell', 'p') + call mkdir('Xtest/spell', 'pR') let splfile = './Xtest/spell/Xtest.utf-8.spl' " empty spell file @@ -384,13 +384,12 @@ func Test_spellfile_format_error() call Spellfile_Test(0zFF00000000000000000000000201010000, 'E759:') let &rtp = save_rtp - call delete('Xtest', 'rf') endfunc " Test for format errors in suggest file func Test_sugfile_format_error() let save_rtp = &rtp - call mkdir('Xtest/spell', 'p') + call mkdir('Xtest/spell', 'pR') let splfile = './Xtest/spell/Xtest.utf-8.spl' let sugfile = './Xtest/spell/Xtest.utf-8.sug' @@ -473,7 +472,6 @@ func Test_sugfile_format_error() set nospell spelllang& let &rtp = save_rtp - call delete('Xtest', 'rf') endfunc " Test for using :mkspell to create a spell file from a list of words @@ -486,7 +484,7 @@ func Test_wordlist_dic() /encoding=latin1 example [END] - call writefile(lines, 'Xwordlist.dic') + call writefile(lines, 'Xwordlist.dic', 'D') let output = execute('mkspell Xwordlist.spl Xwordlist.dic') call assert_match('Duplicate /encoding= line ignored in Xwordlist.dic line 4: /encoding=latin1', output) @@ -559,7 +557,6 @@ func Test_wordlist_dic() call assert_match('Compressed keep-case:', output) call delete('Xwordlist.spl') - call delete('Xwordlist.dic') endfunc " Test for the :mkspell command @@ -600,8 +597,8 @@ func Test_aff_file_format_error() CheckNotMSWindows " No word count in .dic file - call writefile([], 'Xtest.dic') - call writefile([], 'Xtest.aff') + call writefile([], 'Xtest.dic', 'D') + call writefile([], 'Xtest.aff', 'D') call assert_fails('mkspell! Xtest.spl Xtest', 'E760:') " create a .dic file for the tests below @@ -822,20 +819,14 @@ func Test_aff_file_format_error() " use multiple .aff files with different values for COMPOUNDWORDMAX and " MIDWORD (number and string) - call writefile(['1', 'world'], 'Xtest_US.dic') - call writefile(['1', 'world'], 'Xtest_CA.dic') - call writefile(["COMPOUNDWORDMAX 3", "MIDWORD '-"], 'Xtest_US.aff') - call writefile(["COMPOUNDWORDMAX 4", "MIDWORD '="], 'Xtest_CA.aff') + call writefile(['1', 'world'], 'Xtest_US.dic', 'D') + call writefile(['1', 'world'], 'Xtest_CA.dic', 'D') + call writefile(["COMPOUNDWORDMAX 3", "MIDWORD '-"], 'Xtest_US.aff', 'D') + call writefile(["COMPOUNDWORDMAX 4", "MIDWORD '="], 'Xtest_CA.aff', 'D') let output = execute('mkspell! Xtest.spl Xtest_US Xtest_CA') call assert_match('COMPOUNDWORDMAX value differs from what is used in another .aff file', output) call assert_match('MIDWORD value differs from what is used in another .aff file', output) - call delete('Xtest_US.dic') - call delete('Xtest_CA.dic') - call delete('Xtest_US.aff') - call delete('Xtest_CA.aff') - call delete('Xtest.dic') - call delete('Xtest.aff') call delete('Xtest.spl') call delete('Xtest.sug') endfunc @@ -855,8 +846,8 @@ func Test_spell_add_word() endfunc func Test_spellfile_verbose() - call writefile(['1', 'one'], 'XtestVerbose.dic') - call writefile([], 'XtestVerbose.aff') + call writefile(['1', 'one'], 'XtestVerbose.dic', 'D') + call writefile([], 'XtestVerbose.aff', 'D') mkspell! XtestVerbose-utf8.spl XtestVerbose set spell @@ -869,15 +860,13 @@ func Test_spellfile_verbose() call assert_notmatch('Reading spell file "XtestVerbose-utf8.spl"', a) set spell& spelllang& - call delete('XtestVerbose.dic') - call delete('XtestVerbose.aff') call delete('XtestVerbose-utf8.spl') endfunc " Test NOBREAK (see :help spell-NOBREAK) func Test_NOBREAK() - call writefile(['3', 'one', 'two', 'three' ], 'XtestNOBREAK.dic') - call writefile(['NOBREAK' ], 'XtestNOBREAK.aff') + call writefile(['3', 'one', 'two', 'three' ], 'XtestNOBREAK.dic', 'D') + call writefile(['NOBREAK' ], 'XtestNOBREAK.aff', 'D') mkspell! XtestNOBREAK-utf8.spl XtestNOBREAK set spell spelllang=XtestNOBREAK-utf8.spl @@ -899,8 +888,6 @@ func Test_NOBREAK() bw! set spell& spelllang& - call delete('XtestNOBREAK.dic') - call delete('XtestNOBREAK.aff') call delete('XtestNOBREAK-utf8.spl') endfunc @@ -910,11 +897,11 @@ func Test_spellfile_CHECKCOMPOUNDPATTERN() \ 'one/c', \ 'two/c', \ 'three/c', - \ 'four'], 'XtestCHECKCOMPOUNDPATTERN.dic') + \ 'four'], 'XtestCHECKCOMPOUNDPATTERN.dic', 'D') " Forbid compound words where first word ends with 'wo' and second starts with 'on'. call writefile(['CHECKCOMPOUNDPATTERN 1', \ 'CHECKCOMPOUNDPATTERN wo on', - \ 'COMPOUNDFLAG c'], 'XtestCHECKCOMPOUNDPATTERN.aff') + \ 'COMPOUNDFLAG c'], 'XtestCHECKCOMPOUNDPATTERN.aff', 'D') mkspell! XtestCHECKCOMPOUNDPATTERN-utf8.spl XtestCHECKCOMPOUNDPATTERN set spell spelllang=XtestCHECKCOMPOUNDPATTERN-utf8.spl @@ -938,8 +925,6 @@ func Test_spellfile_CHECKCOMPOUNDPATTERN() endfor set spell& spelllang& - call delete('XtestCHECKCOMPOUNDPATTERN.dic') - call delete('XtestCHECKCOMPOUNDPATTERN.aff') call delete('XtestCHECKCOMPOUNDPATTERN-utf8.spl') endfunc @@ -948,15 +933,15 @@ func Test_spellfile_NOCOMPOUNDSUGS() call writefile(['3', \ 'one/c', \ 'two/c', - \ 'three/c'], 'XtestNOCOMPOUNDSUGS.dic') + \ 'three/c'], 'XtestNOCOMPOUNDSUGS.dic', 'D') " pass 0 tests without NOCOMPOUNDSUGS, pass 1 tests with NOCOMPOUNDSUGS for pass in [0, 1] if pass == 0 - call writefile(['COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff') + call writefile(['COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff', 'D') else call writefile(['NOCOMPOUNDSUGS', - \ 'COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff') + \ 'COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff', 'D') endif mkspell! XtestNOCOMPOUNDSUGS-utf8.spl XtestNOCOMPOUNDSUGS @@ -984,8 +969,6 @@ func Test_spellfile_NOCOMPOUNDSUGS() endfor set spell& spelllang& - call delete('XtestNOCOMPOUNDSUGS.dic') - call delete('XtestNOCOMPOUNDSUGS.aff') call delete('XtestNOCOMPOUNDSUGS-utf8.spl') endfunc @@ -998,8 +981,8 @@ func Test_spellfile_COMMON() \ 'any', \ 'tee', \ 'the', - \ 'ted'], 'XtestCOMMON.dic') - call writefile(['COMMON the and'], 'XtestCOMMON.aff') + \ 'ted'], 'XtestCOMMON.dic', 'D') + call writefile(['COMMON the and'], 'XtestCOMMON.aff', 'D') mkspell! XtestCOMMON-utf8.spl XtestCOMMON set spell spelllang=XtestCOMMON-utf8.spl @@ -1011,15 +994,13 @@ func Test_spellfile_COMMON() call assert_equal(['the', 'tee'], spellsuggest('dhe', 2)) set spell& spelllang& - call delete('XtestCOMMON.dic') - call delete('XtestCOMMON.aff') call delete('XtestCOMMON-utf8.spl') endfunc " Test NOSUGGEST (see :help spell-COMMON) func Test_spellfile_NOSUGGEST() - call writefile(['2', 'foo/X', 'fog'], 'XtestNOSUGGEST.dic') - call writefile(['NOSUGGEST X'], 'XtestNOSUGGEST.aff') + call writefile(['2', 'foo/X', 'fog'], 'XtestNOSUGGEST.dic', 'D') + call writefile(['NOSUGGEST X'], 'XtestNOSUGGEST.aff', 'D') mkspell! XtestNOSUGGEST-utf8.spl XtestNOSUGGEST set spell spelllang=XtestNOSUGGEST-utf8.spl @@ -1037,8 +1018,6 @@ func Test_spellfile_NOSUGGEST() call assert_equal(['fog'], spellsuggest('fogg', 1)) set spell& spelllang& - call delete('XtestNOSUGGEST.dic') - call delete('XtestNOSUGGEST.aff') call delete('XtestNOSUGGEST-utf8.spl') endfunc @@ -1047,7 +1026,7 @@ endfunc func Test_spellfile_CIRCUMFIX() " Example taken verbatim from https://github.com/hunspell/hunspell/tree/master/tests call writefile(['1', - \ 'nagy/C po:adj'], 'XtestCIRCUMFIX.dic') + \ 'nagy/C po:adj'], 'XtestCIRCUMFIX.dic', 'D') call writefile(['# circumfixes: ~ obligate prefix/suffix combinations', \ '# superlative in Hungarian: leg- (prefix) AND -bb (suffix)', \ '', @@ -1062,7 +1041,7 @@ func Test_spellfile_CIRCUMFIX() \ 'SFX C Y 3', \ 'SFX C 0 obb . is:COMPARATIVE', \ 'SFX C 0 obb/AX . is:SUPERLATIVE', - \ 'SFX C 0 obb/BX . is:SUPERSUPERLATIVE'], 'XtestCIRCUMFIX.aff') + \ 'SFX C 0 obb/BX . is:SUPERSUPERLATIVE'], 'XtestCIRCUMFIX.aff', 'D') mkspell! XtestCIRCUMFIX-utf8.spl XtestCIRCUMFIX set spell spelllang=XtestCIRCUMFIX-utf8.spl @@ -1081,8 +1060,6 @@ func Test_spellfile_CIRCUMFIX() endfor set spell& spelllang& - call delete('XtestCIRCUMFIX.dic') - call delete('XtestCIRCUMFIX.aff') call delete('XtestCIRCUMFIX-utf8.spl') endfunc @@ -1094,12 +1071,12 @@ func Test_spellfile_SFX_strip() \ 'SFX A are hiamo [cg]are', \ 'SFX A re mo iare', \ 'SFX A re vamo are'], - \ 'XtestSFX.aff') + \ 'XtestSFX.aff', 'D') " Examples of Italian verbs: " - cantare = to sing " - cercare = to search " - odiare = to hate - call writefile(['3', 'cantare/A', 'cercare/A', 'odiare/A'], 'XtestSFX.dic') + call writefile(['3', 'cantare/A', 'cercare/A', 'odiare/A'], 'XtestSFX.dic', 'D') mkspell! XtestSFX-utf8.spl XtestSFX set spell spelllang=XtestSFX-utf8.spl @@ -1123,8 +1100,6 @@ func Test_spellfile_SFX_strip() call assert_equal(['odiamo'], spellsuggest('odiiamo', 1)) set spell& spelllang& - call delete('XtestSFX.dic') - call delete('XtestSFX.aff') call delete('XtestSFX-utf8.spl') endfunc @@ -1133,7 +1108,7 @@ endfunc func Test_init_spellfile() let save_rtp = &rtp let save_encoding = &encoding - call mkdir('Xrtp/spell', 'p') + call mkdir('Xrtp/spell', 'pR') call writefile(['vim'], 'Xrtp/spell/Xtest.dic') silent mkspell Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest.dic set runtimepath=./Xrtp @@ -1143,8 +1118,8 @@ func Test_init_spellfile() call assert_equal('./Xrtp/spell/Xtest.utf-8.add', &spellfile) call assert_equal(['abc'], readfile('Xrtp/spell/Xtest.utf-8.add')) call assert_true(filereadable('Xrtp/spell/Xtest.utf-8.spl')) + set spell& spelllang& spellfile& - call delete('Xrtp', 'rf') let &encoding = save_encoding let &rtp = save_rtp %bw! @@ -1170,12 +1145,10 @@ enddef " this was using a NULL pointer func Test_mkspell_empty_dic() - call writefile(['1'], 'XtestEmpty.dic') - call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'XtestEmpty.aff') + call writefile(['1'], 'XtestEmpty.dic', 'D') + call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'XtestEmpty.aff', 'D') mkspell! XtestEmpty.spl XtestEmpty - call delete('XtestEmpty.dic') - call delete('XtestEmpty.aff') call delete('XtestEmpty.spl') endfunc diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index 8686001801..01e7095b8e 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -43,14 +43,14 @@ func Test_after_comes_later() quit [CODE] - call mkdir('Xhere/plugin', 'p') + call mkdir('Xhere/plugin', 'pR') call writefile(['let g:sequence .= "here "'], 'Xhere/plugin/here.vim') - call mkdir('Xanother/plugin', 'p') + call mkdir('Xanother/plugin', 'pR') call writefile(['let g:sequence .= "another "'], 'Xanother/plugin/another.vim') call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p') call writefile(['let g:sequence .= "pack "'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim') - call mkdir('Xafter/plugin', 'p') + call mkdir('Xafter/plugin', 'pR') call writefile(['let g:sequence .= "after "'], 'Xafter/plugin/later.vim') if RunVim(before, after, '') @@ -72,9 +72,6 @@ func Test_after_comes_later() call delete('Xtestout') call delete('Xsequence') - call delete('Xhere', 'rf') - call delete('Xanother', 'rf') - call delete('Xafter', 'rf') endfunc func Test_pack_in_rtp_when_plugins_run() @@ -92,7 +89,7 @@ func Test_pack_in_rtp_when_plugins_run() let after = [ \ 'quit', \ ] - call mkdir('Xhere/plugin', 'p') + call mkdir('Xhere/plugin', 'pR') call writefile(['redir! > Xtestout', 'silent set runtimepath?', 'silent! call foo#Trigger()', 'redir END'], 'Xhere/plugin/here.vim') call mkdir('Xhere/pack/foo/start/foobar/autoload', 'p') call writefile(['function! foo#Trigger()', 'echo "autoloaded foo"', 'endfunction'], 'Xhere/pack/foo/start/foobar/autoload/foo.vim') @@ -105,7 +102,6 @@ func Test_pack_in_rtp_when_plugins_run() endif call delete('Xtestout') - call delete('Xhere', 'rf') endfunc func Test_help_arg() @@ -228,7 +224,6 @@ func Test_o_arg() call assert_equal('foo', bn1) call assert_equal('bar', bn2) endif - call delete('Xtestout') endfunc @@ -303,7 +298,7 @@ func Test_q_arg() return 666 } END - call writefile(lines, 'Xbadfile.c') + call writefile(lines, 'Xbadfile.c', 'D') let after =<< trim [CODE] call writefile([&errorfile, string(getpos("."))], "XtestoutQarg") @@ -314,7 +309,7 @@ func Test_q_arg() " Test with default argument '-q'. call assert_equal('errors.err', &errorfile) - call writefile(["Xbadfile.c:4:12: error: expected ';' before '}' token"], 'errors.err') + call writefile(["Xbadfile.c:4:12: error: expected ';' before '}' token"], 'errors.err', 'D') if RunVim([], after, '-q') let lines = readfile('XtestoutQarg') call assert_equal(['errors.err', @@ -323,10 +318,9 @@ func Test_q_arg() \ lines) endif call delete('XtestoutQarg') - call delete('errors.err') " Test with explicit argument '-q XerrorsQarg' (with space). - call writefile(["Xbadfile.c:4:12: error: expected ';' before '}' token"], 'XerrorsQarg') + call writefile(["Xbadfile.c:4:12: error: expected ';' before '}' token"], 'XerrorsQarg', 'D') if RunVim([], after, '-q XerrorsQarg') let lines = readfile('XtestoutQarg') call assert_equal(['XerrorsQarg', @@ -349,9 +343,7 @@ func Test_q_arg() let out = system(GetVimCommand() .. ' -q xyz.err') call assert_equal(3, v:shell_error) - call delete('Xbadfile.c') call delete('XtestoutQarg') - call delete('XerrorsQarg') endfunc " Test the -V[N]{filename} argument to set the 'verbose' option to N @@ -799,7 +791,7 @@ endfunc func Test_zzz_startinsert() " Test :startinsert - call writefile(['123456'], 'Xtestout') + call writefile(['123456'], 'Xtestout', 'D') let after =<< trim [CODE] :startinsert call feedkeys("foobar\:wq\","t") @@ -820,7 +812,6 @@ func Test_zzz_startinsert() let lines = readfile('Xtestout') call assert_equal(['123456foobar'], lines) endif - call delete('Xtestout') endfunc func Test_issue_3969() @@ -900,8 +891,8 @@ func Test_t_arg() \ "first\tXfile1\t/^ \\zsfirst$/", \ "second\tXfile1\t/^ \\zssecond$/", \ "third\tXfile1\t/^ \\zsthird$/"], - \ 'Xtags') - call writefile([' first', ' second', ' third'], 'Xfile1') + \ 'Xtags', 'D') + call writefile([' first', ' second', ' third'], 'Xfile1', 'D') for t_arg in ['-t second', '-tsecond'] if RunVim(before, after, t_arg) @@ -909,9 +900,6 @@ func Test_t_arg() call delete('Xtestout') endif endfor - - call delete('Xtags') - call delete('Xfile1') endfunc " Test the '-T' argument which sets the 'term' option. @@ -1008,7 +996,7 @@ func Test_missing_vimrc() call assert_match('^E282:', v:errmsg) call writefile(v:errors, 'Xtestout') [CODE] - call writefile(after, 'Xafter') + call writefile(after, 'Xafter', 'D') let cmd = GetVimCommandCleanTerm() . ' -u Xvimrc_missing -S Xafter' let buf = term_start(cmd, {'term_rows' : 10}) @@ -1019,7 +1007,7 @@ func Test_missing_vimrc() call WaitForAssert({-> assert_match(':', term_getline(buf, 10))}) call StopVimInTerminal(buf) call assert_equal([], readfile('Xtestout')) - call delete('Xafter') + call delete('Xtestout') endfunc @@ -1031,13 +1019,13 @@ func Test_VIMINIT() call writefile(v:errors, 'Xtestout') qall [CODE] - call writefile(after, 'Xafter') + call writefile(after, 'Xafter', 'D') let cmd = GetVimProg() . ' --not-a-term -S Xafter --cmd "set enc=utf8"' call setenv('VIMINIT', 'let viminit_found="yes"') exe "silent !" . cmd call assert_equal([], readfile('Xtestout')) + call delete('Xtestout') - call delete('Xafter') endfunc " Test for using the $EXINIT environment variable @@ -1048,13 +1036,13 @@ func Test_EXINIT() call writefile(v:errors, 'Xtestout') qall [CODE] - call writefile(after, 'Xafter') + call writefile(after, 'Xafter', 'D') let cmd = GetVimProg() . ' --not-a-term -S Xafter --cmd "set enc=utf8"' call setenv('EXINIT', 'let exinit_found="yes"') exe "silent !" . cmd call assert_equal([], readfile('Xtestout')) + call delete('Xtestout') - call delete('Xafter') endfunc " Test for using the 'exrc' option @@ -1066,13 +1054,12 @@ func Test_exrc() call writefile(v:errors, 'Xtestout') qall [CODE] - call mkdir('Xrcdir') + call mkdir('Xrcdir', 'R') call writefile(['let exrc_found=37'], 'Xrcdir/.exrc') call writefile(after, 'Xrcdir/Xafter') let cmd = GetVimProg() . ' --not-a-term -S Xafter --cmd "cd Xrcdir" --cmd "set enc=utf8 exrc secure"' exe "silent !" . cmd call assert_equal([], readfile('Xrcdir/Xtestout')) - call delete('Xrcdir', 'rf') endfunc " Test for starting Vim with a non-terminal as input/output @@ -1140,7 +1127,7 @@ func Test_w_arg() " Can't catch the output of gvim. CheckNotGui - call writefile(["iVim Editor\:q!\"], 'Xscriptin', 'b') + call writefile(["iVim Editor\:q!\"], 'Xscriptin', 'bD') if RunVim([], [], '-s Xscriptin -w Xscriptout') call assert_equal(["iVim Editor\e:q!\r"], readfile('Xscriptout')) call delete('Xscriptout') @@ -1164,7 +1151,6 @@ func Test_w_arg() call delete('Xresult') endif endfor - call delete('Xscriptin') endfunc " Test for the "-s scriptin" argument @@ -1176,10 +1162,9 @@ func Test_s_arg() let m = system(GetVimCommand() .. " -s abcxyz") call assert_equal("Cannot open for reading: \"abcxyz\"\n", m) - call writefile([], 'Xinput') + call writefile([], 'Xinput', 'D') let m = system(GetVimCommand() .. " -s Xinput -s Xinput") call assert_equal("Attempt to open script file again: \"-s Xinput\"\n", m) - call delete('Xinput') endfunc " Test for the "-n" (no swap file) argument @@ -1254,7 +1239,7 @@ endfunc func Test_progname() CheckUnix - call mkdir('Xprogname', 'p') + call mkdir('Xprogname', 'pD') call writefile(['silent !date', \ 'call writefile([mode(1), ' \ .. '&insertmode, &diff, &readonly, &updatecount, ' @@ -1326,12 +1311,11 @@ func Test_progname() endfor call delete('Xprogname_after') - call delete('Xprogname', 'd') endfunc " Test for doing a write from .vimrc func Test_write_in_vimrc() - call writefile(['silent! write'], 'Xvimrc') + call writefile(['silent! write'], 'Xvimrc', 'D') let after =<< trim [CODE] call assert_match('E32: ', v:errmsg) call writefile(v:errors, 'Xtestout') @@ -1341,7 +1325,6 @@ func Test_write_in_vimrc() call assert_equal([], readfile('Xtestout')) call delete('Xtestout') endif - call delete('Xvimrc') endfunc func Test_echo_true_in_cmd() @@ -1352,11 +1335,11 @@ func Test_echo_true_in_cmd() call writefile(['done'], 'Xresult') quit END - call writefile(lines, 'Xscript') + call writefile(lines, 'Xscript', 'D') if RunVim([], [], '--cmd "source Xscript"') call assert_equal(['done'], readfile('Xresult')) endif - call delete('Xscript') + call delete('Xresult') endfunc @@ -1367,11 +1350,11 @@ func Test_rename_buffer_on_startup() call writefile(['done'], 'Xresult') qa! END - call writefile(lines, 'Xscript') + call writefile(lines, 'Xscript', 'D') if RunVim([], [], "--clean -e -s --cmd 'file x|new|file x' --cmd 'so Xscript'") call assert_equal(['done'], readfile('Xresult')) endif - call delete('Xscript') + call delete('Xresult') endfunc diff --git a/src/testdir/test_startup_utf8.vim b/src/testdir/test_startup_utf8.vim index 33f50a9cfe..e8b99e7937 100644 --- a/src/testdir/test_startup_utf8.vim +++ b/src/testdir/test_startup_utf8.vim @@ -6,7 +6,7 @@ source screendump.vim func Test_read_stdin_utf8() let linesin = ['テスト', '€ÀÈÌÒÙ'] - call writefile(linesin, 'Xtestin') + call writefile(linesin, 'Xtestin', 'D') let before = [ \ 'set enc=utf-8', \ 'set fencs=cp932,utf-8', @@ -26,8 +26,8 @@ func Test_read_stdin_utf8() else call assert_equal('', 'RunVimPiped failed.') endif + call delete('Xtestout') - call delete('Xtestin') endfunc func Test_read_fifo_utf8() @@ -41,7 +41,7 @@ func Test_read_fifo_utf8() throw 'Skipped: bash or zsh is required' endif let linesin = ['テスト', '€ÀÈÌÒÙ'] - call writefile(linesin, 'Xtestin') + call writefile(linesin, 'Xtestin', 'D') let before = [ \ 'set enc=utf-8', \ 'set fencs=cp932,utf-8', @@ -56,8 +56,8 @@ func Test_read_fifo_utf8() else call assert_equal('', 'RunVim failed.') endif + call delete('Xtestout') - call delete('Xtestin') endfunc func Test_detect_ambiwidth() @@ -69,14 +69,13 @@ func Test_detect_ambiwidth() \ 'set ambiwidth=double', \ 'call test_option_not_set("ambiwidth")', \ 'redraw', - \ ], 'Xscript') + \ ], 'Xscript', 'D') let buf = RunVimInTerminal('-S Xscript', #{keep_t_u7: 1}) call TermWait(buf) call term_sendkeys(buf, "S\=&ambiwidth\\") call WaitForAssert({-> assert_match('single', term_getline(buf, 1))}) call StopVimInTerminal(buf) - call delete('Xscript') endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_stat.vim b/src/testdir/test_stat.vim index e801bfc5ce..ed123e4347 100644 --- a/src/testdir/test_stat.vim +++ b/src/testdir/test_stat.vim @@ -63,7 +63,7 @@ func Test_checktime() let fname = 'Xtest.tmp' let fl = ['Hello World!'] - call writefile(fl, fname) + call writefile(fl, fname, 'D') set autoread exec 'e' fname call SleepForTimestamp() @@ -72,8 +72,6 @@ func Test_checktime() call writefile(fl, fname) checktime call assert_equal(fl[0], getline(1)) - - call delete(fname) endfunc func Test_checktime_fast() @@ -82,7 +80,7 @@ func Test_checktime_fast() let fname = 'Xtest.tmp' let fl = ['Hello World!'] - call writefile(fl, fname) + call writefile(fl, fname, 'D') set autoread exec 'e' fname let fl = readfile(fname) @@ -90,8 +88,6 @@ func Test_checktime_fast() call writefile(fl, fname) checktime call assert_equal(fl[0], getline(1)) - - call delete(fname) endfunc func Test_autoread_fast() @@ -105,12 +101,10 @@ func Test_autoread_fast() call setline(1, 'foo') w! sleep 10m - call writefile(['bar'], 'Xautoread') + call writefile(['bar'], 'Xautoread', 'D') sleep 10m checktime call assert_equal('bar', trim(getline(1))) - - call delete('Xautoread') endfunc func Test_autoread_file_deleted() diff --git a/src/testdir/test_statusline.vim b/src/testdir/test_statusline.vim index e60140fe2c..15f2083f02 100644 --- a/src/testdir/test_statusline.vim +++ b/src/testdir/test_statusline.vim @@ -470,14 +470,13 @@ func Test_statusline_removed_group() set laststatus=2 let &statusline = '%#StatColorHi2#%(✓%#StatColorHi2#%) Q≡' END - call writefile(lines, 'XTest_statusline') + call writefile(lines, 'XTest_statusline', 'D') let buf = RunVimInTerminal('-S XTest_statusline', {'rows': 10, 'cols': 50}) call VerifyScreenDump(buf, 'Test_statusline_1', {}) " clean up call StopVimInTerminal(buf) - call delete('XTest_statusline') endfunc func Test_statusline_using_mode() @@ -488,7 +487,7 @@ func Test_statusline_using_mode() split setlocal statusline=+%{mode()}+ END - call writefile(lines, 'XTest_statusline') + call writefile(lines, 'XTest_statusline', 'D') let buf = RunVimInTerminal('-S XTest_statusline', {'rows': 7, 'cols': 50}) call VerifyScreenDump(buf, 'Test_statusline_mode_1', {}) @@ -499,7 +498,6 @@ func Test_statusline_using_mode() " clean up call term_sendkeys(buf, "close\") call StopVimInTerminal(buf) - call delete('XTest_statusline') endfunc func Test_statusline_after_split_vsplit() @@ -552,13 +550,12 @@ func Test_statusline_highlight_truncate() hi! link User2 ErrorMsg set statusline=%.5(%1*ABC%2*DEF%1*GHI%) END - call writefile(lines, 'XTest_statusline') + call writefile(lines, 'XTest_statusline', 'D') let buf = RunVimInTerminal('-S XTest_statusline', {'rows': 6}) call VerifyScreenDump(buf, 'Test_statusline_hl', {}) call StopVimInTerminal(buf) - call delete('XTest_statusline') endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim index 1e73ba69b9..67df60ff90 100644 --- a/src/testdir/test_substitute.vim +++ b/src/testdir/test_substitute.vim @@ -860,7 +860,7 @@ func Test_sub_with_no_last_pat() call writefile(v:errors, 'Xresult') qall! [SCRIPT] - call writefile(lines, 'Xscript') + call writefile(lines, 'Xscript', 'D') if RunVim([], [], '--clean -S Xscript') call assert_equal([], readfile('Xresult')) endif @@ -876,7 +876,6 @@ func Test_sub_with_no_last_pat() call assert_equal([], readfile('Xresult')) endif - call delete('Xscript') call delete('Xresult') endfunc @@ -1075,13 +1074,12 @@ func Test_sub_open_cmdline_win() redir END qall! [SCRIPT] - call writefile(lines, 'Xscript') + call writefile(lines, 'Xscript', 'D') if RunVim([], [], '-u NONE -S Xscript') call assert_match('E565: Not allowed to change text or change window', \ readfile('Xresult')->join('XX')) endif - call delete('Xscript') call delete('Xresult') endfunc diff --git a/src/testdir/test_swap.vim b/src/testdir/test_swap.vim index a464940033..5237edcfb4 100644 --- a/src/testdir/test_swap.vim +++ b/src/testdir/test_swap.vim @@ -16,7 +16,7 @@ func Test_swap_directory() \ 'line 2 Abcdefghij', \ 'line 3 Abcdefghij', \ 'end of testfile'] - call writefile(content, 'Xtest1') + call writefile(content, 'Xtest1', 'D') " '.', swap file in the same directory as file set dir=.,~ @@ -30,7 +30,7 @@ func Test_swap_directory() " './dir', swap file in a directory relative to the file set dir=./Xtest2,.,~ - call mkdir("Xtest2") + call mkdir("Xtest2", 'R') edit Xtest1 call assert_equal([], glob(swfname, 1, 1, 1)) let swfname = "Xtest2/Xtest1.swp" @@ -40,7 +40,7 @@ func Test_swap_directory() " 'dir', swap file in directory relative to the current dir set dir=Xtest.je,~ - call mkdir("Xtest.je") + call mkdir("Xtest.je", 'R') call writefile(content, 'Xtest2/Xtest3') edit Xtest2/Xtest3 call assert_equal(["Xtest2/Xtest3"], glob("Xtest2/*", 1, 1, 1)) @@ -49,9 +49,6 @@ func Test_swap_directory() call assert_equal([swfname], glob("Xtest.je/*", 1, 1, 1)) set dir& - call delete("Xtest1") - call delete("Xtest2", "rf") - call delete("Xtest.je", "rf") endfunc func Test_swap_group() @@ -135,7 +132,7 @@ func Test_swapinfo() let info = swapinfo('doesnotexist') call assert_equal('Cannot open file', info.error) - call writefile(['burp'], 'Xnotaswapfile') + call writefile(['burp'], 'Xnotaswapfile', 'D') let info = swapinfo('Xnotaswapfile') call assert_equal('Cannot read file', info.error) call delete('Xnotaswapfile') @@ -143,7 +140,6 @@ func Test_swapinfo() call writefile([repeat('x', 10000)], 'Xnotaswapfile') let info = swapinfo('Xnotaswapfile') call assert_equal('Not a swap file', info.error) - call delete('Xnotaswapfile') endfunc func Test_swapname() @@ -191,7 +187,7 @@ func Test_swapfile_delete() " Close the file and recreate the swap file. " Now editing the file will run into the process still existing quit - call writefile(swapfile_bytes, swapfile_name) + call writefile(swapfile_bytes, swapfile_name, 'D') let s:swap_choice = 'e' let s:swapname = '' split XswapfileText @@ -219,7 +215,6 @@ func Test_swapfile_delete() call assert_equal(fnamemodify(swapfile_name, ':t'), fnamemodify(s:swapname, ':t')) call delete('XswapfileText') - call delete(swapfile_name) augroup test_swapfile_delete autocmd! augroup END @@ -233,7 +228,7 @@ func Test_swap_recover() autocmd SwapExists * let v:swapchoice = 'r' augroup END - call mkdir('Xswap') + call mkdir('Xswap', 'R') let $Xswap = 'foo' " Check for issue #4369. set dir=Xswap// " Create a valid swapfile by editing a file. @@ -246,7 +241,7 @@ func Test_swap_recover() " Close the file and recreate the swap file. quit - call writefile(swapfile_bytes, swapfile_name) + call writefile(swapfile_bytes, swapfile_name, 'D') " Edit the file again. This triggers recovery. try split Xswap/text @@ -258,9 +253,6 @@ func Test_swap_recover() call assert_equal(['one', 'two', 'three'], getline(1, 3)) quit! - call delete('Xswap/text') - call delete(swapfile_name) - call delete('Xswap', 'd') unlet $Xswap set dir& augroup test_swap_recover @@ -288,7 +280,7 @@ func Test_swap_recover_ext() " Close and delete the file and recreate the swap file. quit call delete('Xtest.scr') - call writefile(swapfile_bytes, swapfile_name) + call writefile(swapfile_bytes, swapfile_name, 'D') " Edit the file again. This triggers recovery. try split Xtest.scr @@ -301,7 +293,6 @@ func Test_swap_recover_ext() quit! call delete('Xtest.scr') - call delete(swapfile_name) augroup test_swap_recover_ext autocmd! augroup END @@ -329,7 +320,7 @@ func Test_swap_split_win() " Close and delete the file and recreate the swap file. quit call delete('Xtest.scr') - call writefile(swapfile_bytes, swapfile_name) + call writefile(swapfile_bytes, swapfile_name, 'D') " Split edit the file again. This should fail to open the window try split Xtest.scr @@ -340,7 +331,6 @@ func Test_swap_split_win() call assert_equal(1, winnr('$')) call delete('Xtest.scr') - call delete(swapfile_name) augroup test_swap_splitwin autocmd! @@ -352,7 +342,7 @@ endfunc func Test_swap_prompt_splitwin() CheckRunVimInTerminal - call writefile(['foo bar'], 'Xfile1') + call writefile(['foo bar'], 'Xfile1', 'D') edit Xfile1 preserve " should help to make sure the swap file exists @@ -387,13 +377,12 @@ func Test_swap_prompt_splitwin() call StopVimInTerminal(buf) %bwipe! - call delete('Xfile1') endfunc func Test_swap_symlink() CheckUnix - call writefile(['text'], 'Xtestfile') + call writefile(['text'], 'Xtestfile', 'D') silent !ln -s -f Xtestfile Xtestlink set dir=. @@ -404,7 +393,7 @@ func Test_swap_symlink() call assert_match('Xtestfile\.swp$', s:swapname()) bwipe! - call mkdir('Xswapdir') + call mkdir('Xswapdir', 'R') exe 'set dir=' . getcwd() . '/Xswapdir//' " Check that this also works when 'directory' ends with '//' @@ -413,9 +402,7 @@ func Test_swap_symlink() bwipe! set dir& - call delete('Xtestfile') call delete('Xtestlink') - call delete('Xswapdir', 'rf') endfunc func s:get_unused_pid(base) @@ -467,7 +454,7 @@ func Test_swap_auto_delete() " Change the process ID to avoid the "still running" warning. let swapfile_bytes[24:27] = s:pid_to_blob(s:get_unused_pid( \ s:blob_to_pid(swapfile_bytes[24:27]))) - call writefile(swapfile_bytes, swapfile_name) + call writefile(swapfile_bytes, swapfile_name, 'D') edit Xtest.scr " will end up using the same swap file after deleting the existing one call assert_equal(swapfile_name, swapname('%')) @@ -491,7 +478,6 @@ func Test_swap_auto_delete() bwipe! call delete('Xtest.scr') - call delete(swapfile_name) augroup test_swap_recover_ext autocmd! augroup END @@ -520,13 +506,13 @@ endfunc " Test for the v:swapchoice variable func Test_swapchoice() - call writefile(['aaa', 'bbb'], 'Xfile5') + call writefile(['aaa', 'bbb'], 'Xfile5', 'D') edit Xfile5 preserve let swapfname = swapname('') let b = readblob(swapfname) bw! - call writefile(b, swapfname) + call writefile(b, swapfname, 'D') autocmd! SwapExists @@ -565,7 +551,6 @@ func Test_swapchoice() %bw! call assert_false(filereadable(swapfname)) - call delete('Xfile5') call delete(swapfname) augroup test_swapchoice autocmd! diff --git a/src/testdir/test_syntax.vim b/src/testdir/test_syntax.vim index 7f1e5f0e00..73573ffef4 100644 --- a/src/testdir/test_syntax.vim +++ b/src/testdir/test_syntax.vim @@ -652,7 +652,7 @@ func Test_syntax_c() \ "\t}", \ "\tNote: asdf", \ '}', - \ ], 'Xtest.c') + \ ], 'Xtest.c', 'D') " This makes the default for 'background' use "dark", check that the " response to t_RB corrects it to "light". @@ -670,7 +670,6 @@ func Test_syntax_c() call StopVimInTerminal(buf) let $COLORFGBG = '' - call delete('Xtest.c') endfun " Test \z(...) along with \z1 @@ -704,10 +703,10 @@ func Test_syn_wrong_z_one() endfunc func Test_syntax_after_bufdo() - call writefile(['/* aaa comment */'], 'Xaaa.c') - call writefile(['/* bbb comment */'], 'Xbbb.c') - call writefile(['/* ccc comment */'], 'Xccc.c') - call writefile(['/* ddd comment */'], 'Xddd.c') + call writefile(['/* aaa comment */'], 'Xaaa.c', 'D') + call writefile(['/* bbb comment */'], 'Xbbb.c', 'D') + call writefile(['/* ccc comment */'], 'Xccc.c', 'D') + call writefile(['/* ddd comment */'], 'Xddd.c', 'D') let bnr = bufnr('%') new Xaaa.c @@ -735,10 +734,6 @@ func Test_syntax_after_bufdo() bwipe! Xccc.c bwipe! Xddd.c syntax off - call delete('Xaaa.c') - call delete('Xbbb.c') - call delete('Xccc.c') - call delete('Xddd.c') endfunc func Test_syntax_foldlevel() diff --git a/src/testdir/test_system.vim b/src/testdir/test_system.vim index f238139363..879eaed3be 100644 --- a/src/testdir/test_system.vim +++ b/src/testdir/test_system.vim @@ -55,7 +55,7 @@ func Test_system_exmode() let cmd = ' -es -c "source Xscript" +q; echo "result=$?"' " Need to put this in a script, "catch" isn't found after an unknown " function. - call writefile(['try', 'call doesnotexist()', 'catch', 'endtry'], 'Xscript') + call writefile(['try', 'call doesnotexist()', 'catch', 'endtry'], 'Xscript', 'D') let a = system(GetVimCommand() . cmd) call assert_match('result=0', a) call assert_equal(0, v:shell_error) @@ -71,7 +71,6 @@ func Test_system_exmode() let cmd = ' -es -c "source Xscript" +q' let a = system(GetVimCommand() . cmd) call assert_notequal(0, v:shell_error) - call delete('Xscript') if has('unix') " echo $? only works on Unix let cmd = ' -es -c "call doesnotexist()" +q; echo $?' diff --git a/src/testdir/test_termcodes.vim b/src/testdir/test_termcodes.vim index cb1d01a0b3..12c5737ae4 100644 --- a/src/testdir/test_termcodes.vim +++ b/src/testdir/test_termcodes.vim @@ -1298,20 +1298,20 @@ func Test_term_mouse_popup_menu_setpos() call assert_equal([1, 10], [line('.'), col('.')], msg) call assert_equal('ran away', @", msg) - " Test for right click in visual mode before the selection + " Test for right click in visual mode right before the selection let @" = '' call cursor(1, 10) - call feedkeys('vee' .. MouseRightClickCode(1, 2) - \ .. MouseRightReleaseCode(1, 2) .. "\\", "x") - call assert_equal([1, 2], [line('.'), col('.')], msg) + call feedkeys('vee' .. MouseRightClickCode(1, 9) + \ .. MouseRightReleaseCode(1, 9) .. "\\", "x") + call assert_equal([1, 9], [line('.'), col('.')], msg) call assert_equal('', @", msg) - " Test for right click in visual mode after the selection + " Test for right click in visual mode right after the selection let @" = '' call cursor(1, 10) - call feedkeys('vee' .. MouseRightClickCode(1, 20) - \ .. MouseRightReleaseCode(1, 20) .. "\\", "x") - call assert_equal([1, 20], [line('.'), col('.')], msg) + call feedkeys('vee' .. MouseRightClickCode(1, 18) + \ .. MouseRightReleaseCode(1, 18) .. "\\", "x") + call assert_equal([1, 18], [line('.'), col('.')], msg) call assert_equal('', @", msg) " Test for right click in block-wise visual mode inside the selection @@ -1331,6 +1331,32 @@ func Test_term_mouse_popup_menu_setpos() call assert_equal('v', getregtype('"'), msg) call assert_equal('', @", msg) + " Test for right click in line-wise visual mode inside the selection + let @" = '' + call cursor(1, 16) + call feedkeys("V" .. MouseRightClickCode(1, 10) + \ .. MouseRightReleaseCode(1, 10) .. "\\", "x") + call assert_equal([1, 1], [line('.'), col('.')], msg) " After yanking, the cursor goes to 1,1 + call assert_equal("V", getregtype('"'), msg) + call assert_equal(len(getreg('"', 1, v:true)), 1, msg) + + " Test for right click in multi-line line-wise visual mode inside the selection + let @" = '' + call cursor(1, 16) + call feedkeys("Vj" .. MouseRightClickCode(2, 20) + \ .. MouseRightReleaseCode(2, 20) .. "\\", "x") + call assert_equal([1, 1], [line('.'), col('.')], msg) " After yanking, the cursor goes to 1,1 + call assert_equal("V", getregtype('"'), msg) + call assert_equal(len(getreg('"', 1, v:true)), 2, msg) + + " Test for right click in line-wise visual mode outside the selection + let @" = '' + call cursor(1, 16) + call feedkeys("V" .. MouseRightClickCode(2, 10) + \ .. MouseRightReleaseCode(2, 10) .. "\\", "x") + call assert_equal([2, 10], [line('.'), col('.')], msg) + call assert_equal("", @", msg) + " Try clicking on the status line let @" = '' call cursor(1, 10) diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim index e73cb6f0e5..f84437e113 100644 --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -96,6 +96,16 @@ func Test_terminal_paste_register() unlet g:job endfunc +func Test_terminal_unload_buffer() + let buf = Run_shell_in_terminal({}) + call assert_fails(buf . 'bunload', 'E948:') + exe buf . 'bunload!' + call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) + call assert_equal("", bufname(buf)) + + unlet g:job +endfunc + func Test_terminal_wipe_buffer() let buf = Run_shell_in_terminal({}) call assert_fails(buf . 'bwipe', 'E948:') @@ -202,7 +212,7 @@ func Test_terminal_quit() quit! call assert_notequal(buf, bufnr()) call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) - exec buf .. 'bwipe!' + call assert_equal("", bufname(buf)) unlet g:job endfunc @@ -237,7 +247,7 @@ func Test_terminal_split_quit() quit! call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) - exe buf . 'bwipe' + call assert_equal("", bufname(buf)) unlet g:job endfunc @@ -261,16 +271,28 @@ endfunc func Test_terminal_hide_buffer_job_finished() term echo hello let buf = bufnr() - setlocal bufhidden=hide call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))}) + call assert_true(bufloaded(buf)) call assert_true(buflisted(buf)) + + " Test :hide + hide + call assert_true(bufloaded(buf)) + call assert_true(buflisted(buf)) + split + exe buf .. 'buf' + call assert_equal(buf, bufnr()) + + " Test bufhidden, which exercises a different code path + setlocal bufhidden=hide edit Xasdfasdf call assert_true(bufloaded(buf)) call assert_true(buflisted(buf)) exe buf .. 'buf' call assert_equal(buf, bufnr()) setlocal bufhidden= + edit Xasdfasdf call assert_false(bufloaded(buf)) call assert_false(buflisted(buf)) diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim index ed0aac88c3..39898eb4a7 100644 --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -367,6 +367,16 @@ func Test_prop_add_list() \ length: 7, start: 1}], prop_list(3)) call assert_equal([#{id: 2, col: 1, type_bufnr: 0, end: 1, type: 'one', \ length: 5, start: 0}], prop_list(4)) + call prop_remove(#{id: 2}) + call assert_equal([], prop_list(1)) + + call prop_add_list(#{type: 'one', id: 3}, + \ [[1, 1, 1, 3], [2, 5, 2, 7, 9]]) + call assert_equal([#{id: 3, col: 1, type_bufnr: 0, end: 1, type: 'one', + \ length: 2, start: 1}], prop_list(1)) + call assert_equal([#{id: 9, col: 5, type_bufnr: 0, end: 1, type: 'one', + \ length: 2, start: 1}], prop_list(2)) + call assert_fails('call prop_add_list([1, 2], [[1, 1, 3]])', 'E1206:') call assert_fails('call prop_add_list({}, {})', 'E1211:') call assert_fails('call prop_add_list({}, [[1, 1, 3]])', 'E965:') @@ -383,6 +393,9 @@ func Test_prop_add_list() call assert_fails('call prop_add_list(test_null_dict(), [[2, 2, 2]])', 'E965:') call assert_fails('call prop_add_list(#{type: "one"}, test_null_list())', 'E1298:') call assert_fails('call prop_add_list(#{type: "one"}, [test_null_list()])', 'E714:') + + " only one error for multiple wrong values + call assert_fails('call prop_add_list(#{type: "one"}, [[{}, [], 0z00, 0.3]])', ['E728:', 'E728:']) call DeletePropTypes() bw! endfunc @@ -2628,6 +2641,43 @@ func Test_props_with_text_after() call assert_fails('call prop_add(1, 2, #{text: "yes", text_align: "right", type: "some"})', 'E1294:') endfunc +func Test_props_with_text_after_and_list() + CheckRunVimInTerminal + + let lines =<< trim END + vim9script + setline(1, ['one', 'two']) + prop_type_add('test', {highlight: 'Special'}) + prop_add(1, 0, { + type: 'test', + text: range(50)->join(' '), + text_align: 'after', + text_padding_left: 3 + }) + prop_add(1, 0, { + type: 'test', + text: range(50)->join('-'), + text_align: 'after', + text_padding_left: 5 + }) + prop_add(1, 0, { + type: 'test', + text: range(50)->join('.'), + text_align: 'after', + text_padding_left: 1 + }) + normal G$ + END + call writefile(lines, 'XscriptPropsAfter', 'D') + let buf = RunVimInTerminal('-S XscriptPropsAfter', #{rows: 8, cols: 60}) + call VerifyScreenDump(buf, 'Test_props_after_1', {}) + + call term_sendkeys(buf, ":set list\") + call VerifyScreenDump(buf, 'Test_props_after_2', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_props_with_text_after_below_trunc() CheckRunVimInTerminal @@ -2653,6 +2703,9 @@ func Test_props_with_text_after_below_trunc() let buf = RunVimInTerminal('-S XscriptPropsAfterTrunc', #{rows: 8, cols: 60}) call VerifyScreenDump(buf, 'Test_prop_with_text_after_below_trunc_1', {}) + call term_sendkeys(buf, ":set number\") + call VerifyScreenDump(buf, 'Test_prop_with_text_after_below_trunc_2', {}) + call StopVimInTerminal(buf) endfunc @@ -2849,6 +2902,11 @@ func Test_props_with_text_above() func AddPropBelow() call prop_add(1, 0, #{type: 'below', text: 'below', text_align: 'below'}) endfunc + func AddLongPropAbove() + 3,4delete + set wrap + call prop_add(1, 0, #{type: 'above1', text: range(50)->join(' '), text_align: 'above', text_padding_left: 2}) + endfunc END call writefile(lines, 'XscriptPropsWithTextAbove', 'D') let buf = RunVimInTerminal('-S XscriptPropsWithTextAbove', #{rows: 9, cols: 60}) @@ -2884,6 +2942,9 @@ func Test_props_with_text_above() call term_sendkeys(buf, "\ls\\") call VerifyScreenDump(buf, 'Test_prop_with_text_above_8', {}) + call term_sendkeys(buf, ":call AddLongPropAbove()\") + call VerifyScreenDump(buf, 'Test_prop_with_text_above_9', {}) + call StopVimInTerminal(buf) endfunc @@ -3208,6 +3269,102 @@ func Test_long_text_below_with_padding() let buf = RunVimInTerminal('-S XlongTextBelowWithPadding', #{rows: 8, cols: 60}) call VerifyScreenDump(buf, 'Test_long_text_with_padding_1', {}) + call term_sendkeys(buf, ":set list\") + call VerifyScreenDump(buf, 'Test_long_text_with_padding_2', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_text_after_nowrap() + CheckRunVimInTerminal + + let lines =<< trim END + vim9script + setline(1, ['first line', range(80)->join(' '), 'third', 'fourth']) + set nowrap + prop_type_add('theprop', {highlight: 'DiffChange'}) + prop_add(1, 0, { + type: 'theprop', + text: 'right after the text '->repeat(3), + text_align: 'after', + text_padding_left: 2, + }) + prop_add(1, 0, { + type: 'theprop', + text: 'in the middle '->repeat(4), + text_align: 'after', + text_padding_left: 3, + }) + prop_add(1, 0, { + type: 'theprop', + text: 'the last one '->repeat(3), + text_align: 'after', + text_padding_left: 1, + }) + normal 2Gw + def g:ChangeText() + prop_clear(1) + set list + prop_add(1, 0, { + type: 'theprop', + text: 'just after txt '->repeat(3), + text_align: 'after', + text_padding_left: 2, + }) + prop_add(1, 0, { + type: 'theprop', + text: 'in the middle '->repeat(4), + text_align: 'after', + text_padding_left: 1, + }) + enddef + END + call writefile(lines, 'XTextAfterNowrap', 'D') + let buf = RunVimInTerminal('-S XTextAfterNowrap', #{rows: 8, cols: 60}) + call VerifyScreenDump(buf, 'Test_text_after_nowrap_1', {}) + + call term_sendkeys(buf, "30w") + call VerifyScreenDump(buf, 'Test_text_after_nowrap_2', {}) + + call term_sendkeys(buf, "22w") + call VerifyScreenDump(buf, 'Test_text_after_nowrap_3', {}) + + call term_sendkeys(buf, "$") + call VerifyScreenDump(buf, 'Test_text_after_nowrap_4', {}) + + call term_sendkeys(buf, "0") + call term_sendkeys(buf, ":call ChangeText()\") + call VerifyScreenDump(buf, 'Test_text_after_nowrap_5', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_text_below_nowrap() + CheckRunVimInTerminal + + let lines =<< trim END + vim9script + setline(1, ['first line', 'second line '->repeat(50), 'third', 'fourth']) + set nowrap number + prop_type_add('theprop', {highlight: 'DiffChange'}) + prop_add(1, 0, { + type: 'theprop', + text: 'one below the text '->repeat(5), + text_align: 'below', + text_padding_left: 2, + }) + prop_add(1, 0, { + type: 'theprop', + text: 'two below the text '->repeat(5), + text_align: 'below', + text_padding_left: 2, + }) + normal 2Gw + END + call writefile(lines, 'XTextBelowNowrap', 'D') + let buf = RunVimInTerminal('-S XTextBelowNowrap', #{rows: 8, cols: 60}) + call VerifyScreenDump(buf, 'Test_text_below_nowrap_1', {}) + call StopVimInTerminal(buf) endfunc diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 3957942db1..c552461aad 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -1904,6 +1904,25 @@ def Test_heredoc() STOP END v9.CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got list', 1) + + lines =<< trim END + var lines=<< STOP + xxx + STOP + END + v9.CheckDefAndScriptFailure(lines, 'E1004: White space required before and after ''=<<'' at "=<< STOP"', 1) + lines =<< trim END + var lines =<> = [{n: 1}] for item in l item->extend({x: 2}) endfor END - v9.CheckDefFailure(lines, 'E1307: Argument 1: Trying to modify a const dict') + v9.CheckDefSuccess(lines) enddef def Test_extendnew() diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 38766e3301..bb56356264 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -4339,6 +4339,33 @@ def Test_defer() assert_equal('', glob('XdeferFile')) enddef +def Test_invalid_redir() + var lines =<< trim END + def Tone() + if 1 + redi =>@0 + redi END + endif + enddef + defcompile + END + v9.CheckScriptFailure(lines, 'E354:') + delfunc g:Tone + + # this was reading past the end of the line + lines =<< trim END + def Ttwo() + if 0 + redi =>@0 + redi END + endif + enddef + defcompile + END + v9.CheckScriptFailure(lines, 'E354:') + delfunc g:Ttwo +enddef + " The following messes up syntax highlight, keep near the end. if has('python3') def Test_python3_command() diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim index d509007d5e..6fe40234e4 100644 --- a/src/testdir/test_vim9_import.vim +++ b/src/testdir/test_vim9_import.vim @@ -1218,6 +1218,26 @@ def Test_autoload_import_deleted() delete('Xa.vim') enddef +def Test_autoload_import_using_const() + mkdir('Xdir/autoload', 'pR') + var lines =<< trim END + vim9script + export const FOO = 42 + echomsg FOO + END + writefile(lines, 'Xdir/autoload/exp.vim') + + var save_rtp = &rtp + exe 'set rtp^=' .. getcwd() .. '/Xdir' + lines =<< trim END + vim9script + import autoload 'exp.vim' + assert_equal(42, exp.FOO) + END + v9.CheckScriptSuccess(lines) + &rtp = save_rtp +enddef + func Test_import_in_diffexpr() CheckExecutable diff @@ -2570,7 +2590,7 @@ def Test_vim9script_autoload_duplicate() enddef END writefile(lines, 'Xdupdir/autoload/dup4func.vim') - assert_fails('source Xdupdir/autoload/dup4func.vim', 'E707:') + assert_fails('source Xdupdir/autoload/dup4func.vim', 'E1041:') lines =<< trim END vim9script diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index c736905d93..6c8f1f0ce0 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -2136,15 +2136,66 @@ enddef def Test_skipped_redir() var lines =<< trim END - def T() + def Tredir() if 0 - redir =>l[0] + redir => l[0] redir END endif enddef defcompile END v9.CheckScriptSuccess(lines) + delfunc g:Tredir + + lines =<< trim END + def Tredir() + if 0 + redir => l[0] + endif + echo 'executed' + if 0 + redir END + endif + enddef + defcompile + END + v9.CheckScriptSuccess(lines) + delfunc g:Tredir + + lines =<< trim END + def Tredir() + var l = [''] + if 1 + redir => l[0] + endif + echo 'executed' + if 0 + redir END + else + redir END + endif + enddef + defcompile + END + v9.CheckScriptSuccess(lines) + delfunc g:Tredir + + lines =<< trim END + let doit = 1 + def Tredir() + var l = [''] + if g:doit + redir => l[0] + endif + echo 'executed' + if g:doit + redir END + endif + enddef + defcompile + END + v9.CheckScriptSuccess(lines) + delfunc g:Tredir enddef def Test_for_loop() @@ -2275,6 +2326,20 @@ def Test_for_loop() v9.CheckDefAndScriptSuccess(lines) enddef +def Test_for_loop_list_of_lists() + # loop variable is final, not const + var lines =<< trim END + # Filter out all odd numbers in each sublist + var list: list> = [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]] + for i in list + filter(i, (_, n: number): bool => n % 2 == 0) + endfor + + assert_equal([[], [2], [2], [2, 4]], list) + END + v9.CheckDefAndScriptSuccess(lines) +enddef + def Test_for_loop_with_closure() # using the loop variable in a closure results in the last used value var lines =<< trim END @@ -2314,6 +2379,36 @@ def Test_for_loop_with_closure() END v9.CheckDefAndScriptSuccess(lines) + # also with an extra block level + lines =<< trim END + var flist: list + for i in range(5) + { + var inloop = i + flist[i] = () => inloop + } + endfor + for i in range(5) + assert_equal(i, flist[i]()) + endfor + END + v9.CheckDefAndScriptSuccess(lines) + + # and declaration in higher block + lines =<< trim END + var flist: list + for i in range(5) + var inloop = i + { + flist[i] = () => inloop + } + endfor + for i in range(5) + assert_equal(i, flist[i]()) + endfor + END + v9.CheckDefAndScriptSuccess(lines) + lines =<< trim END var flist: list for i in range(5) diff --git a/src/textprop.c b/src/textprop.c index 4153e3f453..808d1e639e 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -353,6 +353,7 @@ f_prop_add_list(typval_T *argvars, typval_T *rettv UNUSED) linenr_T end_lnum; colnr_T end_col; int error = FALSE; + int prev_did_emsg = did_emsg; if (check_for_dict_arg(argvars, 0) == FAIL || check_for_list_arg(argvars, 1) == FAIL) @@ -389,17 +390,24 @@ f_prop_add_list(typval_T *argvars, typval_T *rettv UNUSED) pos_list = li->li_tv.vval.v_list; start_lnum = list_find_nr(pos_list, 0L, &error); - start_col = list_find_nr(pos_list, 1L, &error); - end_lnum = list_find_nr(pos_list, 2L, &error); - end_col = list_find_nr(pos_list, 3L, &error); + if (!error) + start_col = list_find_nr(pos_list, 1L, &error); + if (!error) + end_lnum = list_find_nr(pos_list, 2L, &error); + if (!error) + end_col = list_find_nr(pos_list, 3L, &error); + int this_id = id; + if (!error && pos_list->lv_len > 4) + this_id = list_find_nr(pos_list, 4L, &error); if (error || start_lnum <= 0 || start_col <= 0 - || end_lnum <= 0 || end_col <= 0) + || end_lnum <= 0 || end_col <= 0) { - emsg(_(e_invalid_argument)); + if (prev_did_emsg == did_emsg) + emsg(_(e_invalid_argument)); return; } - if (prop_add_one(buf, type_name, id, NULL, 0, 0, start_lnum, end_lnum, - start_col, end_col) == FAIL) + if (prop_add_one(buf, type_name, this_id, NULL, 0, 0, + start_lnum, end_lnum, start_col, end_col) == FAIL) return; } diff --git a/src/time.c b/src/time.c index f8e8c5afe2..a5be297d39 100644 --- a/src/time.c +++ b/src/time.c @@ -82,7 +82,7 @@ vim_time(void) char * get_ctime(time_t thetime, int add_newline) { - static char buf[50]; + static char buf[100]; // hopefully enough for every language #ifdef HAVE_STRFTIME struct tm tmval; struct tm *curtime; @@ -90,12 +90,20 @@ get_ctime(time_t thetime, int add_newline) curtime = vim_localtime(&thetime, &tmval); // MSVC returns NULL for an invalid value of seconds. if (curtime == NULL) - vim_strncpy((char_u *)buf, (char_u *)_("(Invalid)"), sizeof(buf) - 1); + vim_strncpy((char_u *)buf, (char_u *)_("(Invalid)"), sizeof(buf) - 2); else { // xgettext:no-c-format - (void)strftime(buf, sizeof(buf) - 1, _("%a %b %d %H:%M:%S %Y"), - curtime); + if (strftime(buf, sizeof(buf) - 2, _("%a %b %d %H:%M:%S %Y"), curtime) + == 0) + { + // Quoting "man strftime": + // > If the length of the result string (including the terminating + // > null byte) would exceed max bytes, then strftime() returns 0, + // > and the contents of the array are undefined. + vim_strncpy((char_u *)buf, (char_u *)_("(Invalid)"), + sizeof(buf) - 2); + } # ifdef MSWIN if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) { @@ -105,7 +113,7 @@ get_ctime(time_t thetime, int add_newline) acp_to_enc((char_u *)buf, (int)strlen(buf), &to_free, &len); if (to_free != NULL) { - STRCPY(buf, to_free); + STRNCPY(buf, to_free, sizeof(buf) - 2); vim_free(to_free); } } @@ -318,10 +326,8 @@ f_strftime(typval_T *argvars, typval_T *rettv) convert_setup(&conv, p_enc, enc); if (conv.vc_type != CONV_NONE) p = string_convert(&conv, p, NULL); - if (p != NULL) - (void)strftime((char *)result_buf, sizeof(result_buf), - (char *)p, curtime); - else + if (p == NULL || strftime((char *)result_buf, sizeof(result_buf), + (char *)p, curtime) == 0) result_buf[0] = NUL; if (conv.vc_type != CONV_NONE) @@ -1117,16 +1123,19 @@ add_time(char_u *buf, size_t buflen, time_t tt) #ifdef HAVE_STRFTIME struct tm tmval; struct tm *curtime; + int n; if (vim_time() - tt >= 100) { curtime = vim_localtime(&tt, &tmval); if (vim_time() - tt < (60L * 60L * 12L)) // within 12 hours - (void)strftime((char *)buf, buflen, "%H:%M:%S", curtime); + n = strftime((char *)buf, buflen, "%H:%M:%S", curtime); else // longer ago - (void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", curtime); + n = strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", curtime); + if (n == 0) + buf[0] = NUL; } else #endif diff --git a/src/typval.c b/src/typval.c index a4fdb782f1..d6f6196b58 100644 --- a/src/typval.c +++ b/src/typval.c @@ -2509,10 +2509,12 @@ eval_env_var(char_u **arg, typval_T *rettv, int evaluate) tv_get_lnum(typval_T *argvars) { linenr_T lnum = -1; + int did_emsg_before = did_emsg; if (argvars[0].v_type != VAR_STRING || !in_vim9script()) lnum = (linenr_T)tv_get_number_chk(&argvars[0], NULL); - if (lnum <= 0 && argvars[0].v_type != VAR_NUMBER) + if (lnum <= 0 && did_emsg_before == did_emsg + && argvars[0].v_type != VAR_NUMBER) { int fnum; pos_T *fp; diff --git a/src/version.c b/src/version.c index e02656250c..bbeb0c1ef2 100644 --- a/src/version.c +++ b/src/version.c @@ -714,6 +714,80 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 745, +/**/ + 744, +/**/ + 743, +/**/ + 742, +/**/ + 741, +/**/ + 740, +/**/ + 739, +/**/ + 738, +/**/ + 737, +/**/ + 736, +/**/ + 735, +/**/ + 734, +/**/ + 733, +/**/ + 732, +/**/ + 731, +/**/ + 730, +/**/ + 729, +/**/ + 728, +/**/ + 727, +/**/ + 726, +/**/ + 725, +/**/ + 724, +/**/ + 723, +/**/ + 722, +/**/ + 721, +/**/ + 720, +/**/ + 719, +/**/ + 718, +/**/ + 717, +/**/ + 716, +/**/ + 715, +/**/ + 714, +/**/ + 713, +/**/ + 712, +/**/ + 711, +/**/ + 710, +/**/ + 709, /**/ 708, /**/ diff --git a/src/vim9cmds.c b/src/vim9cmds.c index d209a16640..e5abf895e6 100644 --- a/src/vim9cmds.c +++ b/src/vim9cmds.c @@ -57,22 +57,20 @@ current_instr_idx(cctx_T *cctx) } /* * Remove local variables above "new_top". + * Do this by clearing the name. If "keep" is TRUE do not reset the length, a + * closure may still need location of the variable. */ static void -unwind_locals(cctx_T *cctx, int new_top) +unwind_locals(cctx_T *cctx, int new_top, int keep) { if (cctx->ctx_locals.ga_len > new_top) - { - int idx; - lvar_T *lvar; - - for (idx = new_top; idx < cctx->ctx_locals.ga_len; ++idx) + for (int idx = new_top; idx < cctx->ctx_locals.ga_len; ++idx) { - lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx; - vim_free(lvar->lv_name); + lvar_T *lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx; + VIM_CLEAR(lvar->lv_name); } - } - cctx->ctx_locals.ga_len = new_top; + if (!keep) + cctx->ctx_locals.ga_len = new_top; } /* @@ -81,7 +79,7 @@ unwind_locals(cctx_T *cctx, int new_top) void free_locals(cctx_T *cctx) { - unwind_locals(cctx, 0); + unwind_locals(cctx, 0, FALSE); ga_clear(&cctx->ctx_locals); } @@ -525,7 +523,7 @@ compile_elseif(char_u *arg, cctx_T *cctx) emsg(_(e_elseif_without_if)); return NULL; } - unwind_locals(cctx, scope->se_local_count); + unwind_locals(cctx, scope->se_local_count, TRUE); if (!cctx->ctx_had_return) scope->se_u.se_if.is_had_return = FALSE; @@ -672,7 +670,7 @@ compile_else(char_u *arg, cctx_T *cctx) emsg(_(e_else_without_if)); return NULL; } - unwind_locals(cctx, scope->se_local_count); + unwind_locals(cctx, scope->se_local_count, TRUE); if (!cctx->ctx_had_return) scope->se_u.se_if.is_had_return = FALSE; scope->se_u.se_if.is_seen_else = TRUE; @@ -744,7 +742,7 @@ compile_endif(char_u *arg, cctx_T *cctx) return NULL; } ifscope = &scope->se_u.se_if; - unwind_locals(cctx, scope->se_local_count); + unwind_locals(cctx, scope->se_local_count, TRUE); if (!cctx->ctx_had_return) ifscope->is_had_return = FALSE; @@ -1050,7 +1048,7 @@ compile_for(char_u *arg_start, cctx_T *cctx) && need_type_where(item_type, lhs_type, -1, where, cctx, FALSE, FALSE) == FAIL) goto failed; - var_lvar = reserve_local(cctx, arg, varlen, ASSIGN_CONST, + var_lvar = reserve_local(cctx, arg, varlen, ASSIGN_FINAL, lhs_type); if (var_lvar == NULL) // out of memory or used as an argument @@ -1122,7 +1120,7 @@ compile_endfor(char_u *arg, cctx_T *cctx) if (compile_loop_end(&forscope->fs_loop_info, cctx) == FAIL) return NULL; - unwind_locals(cctx, scope->se_local_count); + unwind_locals(cctx, scope->se_local_count, FALSE); // At end of ":for" scope jump back to the FOR instruction. generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label); @@ -1249,7 +1247,7 @@ compile_endwhile(char_u *arg, cctx_T *cctx) if (compile_loop_end(&whilescope->ws_loop_info, cctx) == FAIL) return NULL; - unwind_locals(cctx, scope->se_local_count); + unwind_locals(cctx, scope->se_local_count, FALSE); #ifdef FEAT_PROFILE // count the endwhile before jumping @@ -1471,7 +1469,7 @@ compile_endblock(cctx_T *cctx) scope_T *scope = cctx->ctx_scope; cctx->ctx_scope = scope->se_outer; - unwind_locals(cctx, scope->se_local_count); + unwind_locals(cctx, scope->se_local_count, TRUE); vim_free(scope); } @@ -2414,34 +2412,37 @@ compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx) { if (STRNCMP(arg, "END", 3) == 0) { - if (lhs->lhs_append) + if (cctx->ctx_skip != SKIP_YES) { - // First load the current variable value. - if (compile_load_lhs_with_index(lhs, lhs->lhs_whole, + if (lhs->lhs_append) + { + // First load the current variable value. + if (compile_load_lhs_with_index(lhs, lhs->lhs_whole, cctx) == FAIL) - return NULL; - } + return NULL; + } - // Gets the redirected text and put it on the stack, then store it - // in the variable. - generate_instr_type(cctx, ISN_REDIREND, &t_string); + // Gets the redirected text and put it on the stack, then store + // it in the variable. + generate_instr_type(cctx, ISN_REDIREND, &t_string); - if (lhs->lhs_append) - generate_CONCAT(cctx, 2); + if (lhs->lhs_append) + generate_CONCAT(cctx, 2); - if (lhs->lhs_has_index) - { - // Use the info in "lhs" to store the value at the index in the - // list or dict. - if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE, + if (lhs->lhs_has_index) + { + // Use the info in "lhs" to store the value at the index in + // the list or dict. + if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE, &t_string, cctx) == FAIL) + return NULL; + } + else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL) return NULL; - } - else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL) - return NULL; - VIM_CLEAR(lhs->lhs_name); - VIM_CLEAR(lhs->lhs_whole); + VIM_CLEAR(lhs->lhs_name); + VIM_CLEAR(lhs->lhs_whole); + } return arg + 3; } emsg(_(e_cannot_nest_redir)); @@ -2467,13 +2468,20 @@ compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx) if (need_type(&t_string, lhs->lhs_member_type, -1, 0, cctx, FALSE, FALSE) == FAIL) return NULL; - generate_instr(cctx, ISN_REDIRSTART); - lhs->lhs_append = append; - if (lhs->lhs_has_index) + if (cctx->ctx_skip == SKIP_YES) { - lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total); - if (lhs->lhs_whole == NULL) - return NULL; + VIM_CLEAR(lhs->lhs_name); + } + else + { + generate_instr(cctx, ISN_REDIRSTART); + lhs->lhs_append = append; + if (lhs->lhs_has_index) + { + lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total); + if (lhs->lhs_whole == NULL) + return NULL; + } } return arg + lhs->lhs_varlen_total; diff --git a/src/vim9compile.c b/src/vim9compile.c index 468c3846d8..73bfa6c6af 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -47,7 +47,8 @@ lookup_local(char_u *name, size_t len, lvar_T *lvar, cctx_T *cctx) for (idx = 0; idx < cctx->ctx_locals.ga_len; ++idx) { lvp = ((lvar_T *)cctx->ctx_locals.ga_data) + idx; - if (STRNCMP(name, lvp->lv_name, len) == 0 + if (lvp->lv_name != NULL + && STRNCMP(name, lvp->lv_name, len) == 0 && STRLEN(lvp->lv_name) == len) { if (lvar != NULL) @@ -1282,6 +1283,19 @@ vim9_declare_error(char_u *name) semsg(_(e_cannot_declare_a_scope_variable), scope, name); } +/* + * Return TRUE if "name" is a valid register to use. + * Return FALSE and give an error message if not. + */ + static int +valid_dest_reg(int name) +{ + if ((name == '@' || valid_yank_reg(name, FALSE)) && name != '.') + return TRUE; + emsg_invreg(name); + return FAIL; +} + /* * For one assignment figure out the type of destination. Return it in "dest". * When not recognized "dest" is not set. @@ -1363,12 +1377,8 @@ get_var_dest( } else if (*name == '@') { - if (name[1] != '@' - && (!valid_yank_reg(name[1], FALSE) || name[1] == '.')) - { - emsg_invreg(name[1]); + if (!valid_dest_reg(name[1])) return FAIL; - } *dest = dest_reg; *type = name[1] == '#' ? &t_number_or_string : &t_string; } @@ -1444,7 +1454,11 @@ compile_lhs( // "var_end" is the end of the variable/option/etc. name. lhs->lhs_dest_end = skip_var_one(var_start, FALSE); if (*var_start == '@') + { + if (!valid_dest_reg(var_start[1])) + return FAIL; var_end = var_start + 2; + } else { // skip over the leading "&", "&l:", "&g:" and "$"