diff options
-rw-r--r-- | runtime/filetype.vim | 2 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 131 | ||||
-rw-r--r-- | src/nvim/eval.c | 5 | ||||
-rw-r--r-- | src/nvim/file_search.c | 77 | ||||
-rw-r--r-- | src/nvim/move.c | 12 | ||||
-rw-r--r-- | src/nvim/normal.c | 5 | ||||
-rw-r--r-- | src/nvim/option.c | 165 | ||||
-rw-r--r-- | src/nvim/path.c | 13 | ||||
-rw-r--r-- | src/nvim/screen.c | 63 | ||||
-rw-r--r-- | src/nvim/search.c | 10 | ||||
-rw-r--r-- | src/nvim/testdir/test_listlbr.in | 33 | ||||
-rw-r--r-- | src/nvim/testdir/test_listlbr.ok | 14 | ||||
-rw-r--r-- | src/nvim/version.c | 30 | ||||
-rw-r--r-- | test/functional/legacy/comparators_spec.lua | 14 |
14 files changed, 341 insertions, 233 deletions
diff --git a/runtime/filetype.vim b/runtime/filetype.vim index c5b01f0c40..d60ab65ce7 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -868,7 +868,7 @@ func! s:FThtml() setf xhtml return endif - if getline(n) =~ '{%\s*\(extends\|block\|load\)\>' + if getline(n) =~ '{%\s*\(extends\|block\|load\)\>\|{#\s\+' setf htmldjango return endif diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 709ff3dd0d..bdea609820 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -592,71 +592,72 @@ struct file_buffer { int b_p_scriptID[BV_COUNT]; /* SIDs for buffer-local options */ - int b_p_ai; /* 'autoindent' */ - int b_p_ai_nopaste; /* b_p_ai saved for paste mode */ - char_u *b_p_bkc; ///< 'backupcopy' - unsigned int b_bkc_flags; ///< flags for 'backupcopy' - int b_p_ci; /* 'copyindent' */ - int b_p_bin; /* 'binary' */ - int b_p_bomb; /* 'bomb' */ - char_u *b_p_bh; /* 'bufhidden' */ - char_u *b_p_bt; /* 'buftype' */ - int b_p_bl; /* 'buflisted' */ - int b_p_cin; /* 'cindent' */ - char_u *b_p_cino; /* 'cinoptions' */ - char_u *b_p_cink; /* 'cinkeys' */ - char_u *b_p_cinw; /* 'cinwords' */ - char_u *b_p_com; /* 'comments' */ - char_u *b_p_cms; /* 'commentstring' */ - char_u *b_p_cpt; /* 'complete' */ - char_u *b_p_cfu; /* 'completefunc' */ - char_u *b_p_ofu; /* 'omnifunc' */ - int b_p_eol; /* 'endofline' */ - int b_p_fixeol; /* 'fixendofline' */ - int b_p_et; /* 'expandtab' */ - int b_p_et_nobin; /* b_p_et saved for binary mode */ - char_u *b_p_fenc; /* 'fileencoding' */ - char_u *b_p_ff; /* 'fileformat' */ - char_u *b_p_ft; /* 'filetype' */ - char_u *b_p_fo; /* 'formatoptions' */ - char_u *b_p_flp; /* 'formatlistpat' */ - int b_p_inf; /* 'infercase' */ - char_u *b_p_isk; /* 'iskeyword' */ - char_u *b_p_def; /* 'define' local value */ - char_u *b_p_inc; /* 'include' */ - char_u *b_p_inex; /* 'includeexpr' */ - uint32_t b_p_inex_flags; /* flags for 'includeexpr' */ - char_u *b_p_inde; /* 'indentexpr' */ - uint32_t b_p_inde_flags; /* flags for 'indentexpr' */ - char_u *b_p_indk; /* 'indentkeys' */ - char_u *b_p_fex; /* 'formatexpr' */ - uint32_t b_p_fex_flags; /* flags for 'formatexpr' */ - char_u *b_p_kp; /* 'keywordprg' */ - int b_p_lisp; /* 'lisp' */ - char_u *b_p_mps; /* 'matchpairs' */ - int b_p_ml; /* 'modeline' */ - int b_p_ml_nobin; /* b_p_ml saved for binary mode */ - int b_p_ma; /* 'modifiable' */ - char_u *b_p_nf; /* 'nrformats' */ - int b_p_pi; /* 'preserveindent' */ - char_u *b_p_qe; /* 'quoteescape' */ - int b_p_ro; /* 'readonly' */ - long b_p_sw; /* 'shiftwidth' */ - int b_p_si; /* 'smartindent' */ - long b_p_sts; /* 'softtabstop' */ - long b_p_sts_nopaste; /* b_p_sts saved for paste mode */ - char_u *b_p_sua; /* 'suffixesadd' */ - bool b_p_swf; /* 'swapfile' */ - long b_p_smc; /* 'synmaxcol' */ - char_u *b_p_syn; /* 'syntax' */ - long b_p_ts; /* 'tabstop' */ - long b_p_tw; /* 'textwidth' */ - long b_p_tw_nobin; /* b_p_tw saved for binary mode */ - long b_p_tw_nopaste; /* b_p_tw saved for paste mode */ - long b_p_wm; /* 'wrapmargin' */ - long b_p_wm_nobin; /* b_p_wm saved for binary mode */ - long b_p_wm_nopaste; /* b_p_wm saved for paste mode */ - char_u *b_p_keymap; /* 'keymap' */ + int b_p_ai; ///< 'autoindent' + int b_p_ai_nopaste; ///< b_p_ai saved for paste mode + char_u *b_p_bkc; ///< 'backupco + unsigned int b_bkc_flags; ///< flags for 'backupco + int b_p_ci; ///< 'copyindent' + int b_p_bin; ///< 'binary' + int b_p_bomb; ///< 'bomb' + char_u *b_p_bh; ///< 'bufhidden' + char_u *b_p_bt; ///< 'buftype' + int b_p_bl; ///< 'buflisted' + int b_p_cin; ///< 'cindent' + char_u *b_p_cino; ///< 'cinoptions' + char_u *b_p_cink; ///< 'cinkeys' + char_u *b_p_cinw; ///< 'cinwords' + char_u *b_p_com; ///< 'comments' + char_u *b_p_cms; ///< 'commentstring' + char_u *b_p_cpt; ///< 'complete' + char_u *b_p_cfu; ///< 'completefunc' + char_u *b_p_ofu; ///< 'omnifunc' + int b_p_eol; ///< 'endofline' + int b_p_fixeol; ///< 'fixendofline' + int b_p_et; ///< 'expandtab' + int b_p_et_nobin; ///< b_p_et saved for binary mode + int b_p_et_nopaste; ///< b_p_et saved for paste mode + char_u *b_p_fenc; ///< 'fileencoding' + char_u *b_p_ff; ///< 'fileformat' + char_u *b_p_ft; ///< 'filetype' + char_u *b_p_fo; ///< 'formatoptions' + char_u *b_p_flp; ///< 'formatlistpat' + int b_p_inf; ///< 'infercase' + char_u *b_p_isk; ///< 'iskeyword' + char_u *b_p_def; ///< 'define' local value + char_u *b_p_inc; ///< 'include' + char_u *b_p_inex; ///< 'includeexpr' + uint32_t b_p_inex_flags; ///< flags for 'includeexpr' + char_u *b_p_inde; ///< 'indentexpr' + uint32_t b_p_inde_flags; ///< flags for 'indentexpr' + char_u *b_p_indk; ///< 'indentkeys' + char_u *b_p_fex; ///< 'formatexpr' + uint32_t b_p_fex_flags; ///< flags for 'formatexpr' + char_u *b_p_kp; ///< 'keywordprg' + int b_p_lisp; ///< 'lisp' + char_u *b_p_mps; ///< 'matchpairs' + int b_p_ml; ///< 'modeline' + int b_p_ml_nobin; ///< b_p_ml saved for binary mode + int b_p_ma; ///< 'modifiable' + char_u *b_p_nf; ///< 'nrformats' + int b_p_pi; ///< 'preserveindent' + char_u *b_p_qe; ///< 'quoteescape' + int b_p_ro; ///< 'readonly' + long b_p_sw; ///< 'shiftwidth' + int b_p_si; ///< 'smartindent' + long b_p_sts; ///< 'softtabstop' + long b_p_sts_nopaste; ///< b_p_sts saved for paste mode + char_u *b_p_sua; ///< 'suffixesadd' + bool b_p_swf; ///< 'swapfile' + long b_p_smc; ///< 'synmaxcol' + char_u *b_p_syn; ///< 'syntax' + long b_p_ts; ///< 'tabstop' + long b_p_tw; ///< 'textwidth' + long b_p_tw_nobin; ///< b_p_tw saved for binary mode + long b_p_tw_nopaste; ///< b_p_tw saved for paste mode + long b_p_wm; ///< 'wrapmargin' + long b_p_wm_nobin; ///< b_p_wm saved for binary mode + long b_p_wm_nopaste; ///< b_p_wm saved for paste mode + char_u *b_p_keymap; ///< 'keymap' /* local values for options which are normally global */ char_u *b_p_gp; /* 'grepprg' local value */ diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 327d0bf637..ec085efc07 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -3580,9 +3580,10 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) type = TYPE_SEQUAL; break; case 'i': if (p[1] == 's') { - if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') + if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') { len = 5; - if (!vim_isIDc(p[len])) { + } + if (!isalnum(p[len]) && p[len] != '_') { type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; type_is = TRUE; } diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index b213a42c52..2929790ebf 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -484,28 +484,21 @@ vim_findfile_init ( len = (int)(p - search_ctx->ffsc_fix_path) - 1; STRNCAT(ff_expand_buffer, search_ctx->ffsc_fix_path, len); add_pathsep((char *)ff_expand_buffer); - } else + } else { len = (int)STRLEN(search_ctx->ffsc_fix_path); + } if (search_ctx->ffsc_wc_path != NULL) { wc_path = vim_strsave(search_ctx->ffsc_wc_path); temp = xmalloc(STRLEN(search_ctx->ffsc_wc_path) + STRLEN(search_ctx->ffsc_fix_path + len) + 1); - } - - if (temp == NULL || wc_path == NULL) { - xfree(buf); - xfree(temp); + STRCPY(temp, search_ctx->ffsc_fix_path + len); + STRCAT(temp, search_ctx->ffsc_wc_path); + xfree(search_ctx->ffsc_wc_path); xfree(wc_path); - goto error_return; + search_ctx->ffsc_wc_path = temp; } - - STRCPY(temp, search_ctx->ffsc_fix_path + len); - STRCAT(temp, search_ctx->ffsc_wc_path); - xfree(search_ctx->ffsc_wc_path); - xfree(wc_path); - search_ctx->ffsc_wc_path = temp; } xfree(buf); } @@ -1046,41 +1039,44 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_l return retptr; } -/* - * check if two wildcard paths are equal. Returns TRUE or FALSE. - * They are equal if: - * - both paths are NULL - * - they have the same length - * - char by char comparison is OK - * - the only differences are in the counters behind a '**', so - * '**\20' is equal to '**\24' - */ -static int ff_wc_equal(char_u *s1, char_u *s2) +// Check if two wildcard paths are equal. +// They are equal if: +// - both paths are NULL +// - they have the same length +// - char by char comparison is OK +// - the only differences are in the counters behind a '**', so +// '**\20' is equal to '**\24' +static bool ff_wc_equal(char_u *s1, char_u *s2) { - int i; + int i, j; + int c1 = NUL; + int c2 = NUL; int prev1 = NUL; int prev2 = NUL; - if (s1 == s2) - return TRUE; - - if (s1 == NULL || s2 == NULL) - return FALSE; + if (s1 == s2) { + return true; + } - if (STRLEN(s1) != STRLEN(s2)) - return FAIL; + if (s1 == NULL || s2 == NULL) { + return false; + } - for (i = 0; s1[i] != NUL && s2[i] != NUL; i += MB_PTR2LEN(s1 + i)) { - int c1 = PTR2CHAR(s1 + i); - int c2 = PTR2CHAR(s2 + i); + for (i = 0, j = 0; s1[i] != NUL && s2[j] != NUL;) { + c1 = PTR2CHAR(s1 + i); + c2 = PTR2CHAR(s2 + j); if ((p_fic ? vim_tolower(c1) != vim_tolower(c2) : c1 != c2) - && (prev1 != '*' || prev2 != '*')) - return FAIL; + && (prev1 != '*' || prev2 != '*')) { + return false; + } prev2 = prev1; prev1 = c1; + + i += MB_PTR2LEN(s1 + i); + j += MB_PTR2LEN(s2 + j); } - return TRUE; + return s1[i] == s2[j]; } /* @@ -1111,10 +1107,11 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u * if ((url && fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0) || (!url && vp->file_id_valid && os_fileid_equal(&(vp->file_id), &file_id))) { - /* are the wildcard parts equal */ - if (ff_wc_equal(vp->ffv_wc_path, wc_path) == TRUE) - /* already visited */ + // are the wildcard parts equal + if (ff_wc_equal(vp->ffv_wc_path, wc_path)) { + // already visited return FAIL; + } } } diff --git a/src/nvim/move.c b/src/nvim/move.c index eb55397511..ba79c0411a 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -1288,9 +1288,10 @@ void scroll_cursor_top(int min_scroll, int always) * - at least 'scrolloff' lines above and below the cursor */ validate_cheight(); - int used = curwin->w_cline_height; - if (curwin->w_cursor.lnum < curwin->w_topline) + int used = curwin->w_cline_height; // includes filler lines above + if (curwin->w_cursor.lnum < curwin->w_topline) { scrolled = used; + } if (hasFolding(curwin->w_cursor.lnum, &top, &bot)) { --top; @@ -1301,9 +1302,10 @@ void scroll_cursor_top(int min_scroll, int always) } new_topline = top + 1; - /* count filler lines of the cursor window as context */ + // "used" already contains the number of filler lines above, don't add it + // again. + // Hide filler lines above cursor line by adding them to "extra". int extra = diff_check_fill(curwin, curwin->w_cursor.lnum); - used += extra; /* * Check if the lines from "top" to "bot" fit in the window. If they do, @@ -1312,7 +1314,7 @@ void scroll_cursor_top(int min_scroll, int always) while (top > 0) { int i = hasFolding(top, &top, NULL) ? 1 // count one logical line for a sequence of folded lines - : plines(top); + : plines_nofill(top); used += i; if (extra + i <= off && bot < curbuf->b_ml.ml_line_count) { if (hasFolding(bot, NULL, &bot)) diff --git a/src/nvim/normal.c b/src/nvim/normal.c index e6c5354941..e064d34e09 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -7783,7 +7783,7 @@ static void nv_open(cmdarg_T *cap) n_opencmd(cap); } -// calculate start/end virtual columns for operating in block mode +// Calculate start/end virtual columns for operating in block mode. static void get_op_vcol( oparg_T *oap, colnr_T redo_VIsual_vcol, @@ -7793,7 +7793,8 @@ static void get_op_vcol( colnr_T start; colnr_T end; - if (VIsual_mode != Ctrl_V) { + if (VIsual_mode != Ctrl_V + || (!initial && oap->end.col < curwin->w_width)) { return; } diff --git a/src/nvim/option.c b/src/nvim/option.c index c11e22703e..4bf7ec5405 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -168,11 +168,12 @@ static int p_ml_nobin; static long p_tw_nobin; static long p_wm_nobin; -/* Saved values for when 'paste' is set */ +// Saved values for when 'paste' is set. +static int p_ai_nopaste; +static int p_et_nopaste; +static long p_sts_nopaste; static long p_tw_nopaste; static long p_wm_nopaste; -static long p_sts_nopaste; -static int p_ai_nopaste; typedef struct vimoption { char *fullname; /* full option name */ @@ -710,15 +711,11 @@ void set_init_1(void) /* Must be before option_expand(), because that one needs vim_isIDc() */ didset_options(); - /* Use the current chartab for the generic chartab. */ + // Use the current chartab for the generic chartab. This is not in + // didset_options() because it only depends on 'encoding'. init_spell_chartab(); /* - * initialize the table for 'breakat'. - */ - fill_breakat_flags(); - - /* * Expand environment variables and things like "~" for the defaults. * If option_expand() returns non-NULL the variable is expanded. This can * only happen for non-indirect options. @@ -750,14 +747,8 @@ void set_init_1(void) } } - /* Initialize the highlight_attr[] table. */ - highlight_changed(); - save_file_ff(curbuf); /* Buffer is unchanged */ - /* Parse default for 'wildmode' */ - check_opt_wim(); - /* Detect use of mlterm. * Mlterm is a terminal emulator akin to xterm that has some special * abilities (bidi namely). @@ -767,11 +758,7 @@ void set_init_1(void) if (os_env_exists("MLTERM")) set_option_value((char_u *)"tbidi", 1L, NULL, 0); - /* Parse default for 'fillchars'. */ - (void)set_chars_option(&p_fcs); - - /* Parse default for 'listchars'. */ - (void)set_chars_option(&p_lcs); + didset_options2(); // enc_locale() will try to find the encoding of the current locale. // This will be used when 'default' is used as encoding specifier @@ -1150,9 +1137,12 @@ do_set ( */ arg += 3; if (*arg == '&') { - ++arg; - /* Only for :set command set global value of local options. */ + arg++; + // Only for :set command set global value of local options. set_options_default(OPT_FREE | opt_flags); + didset_options(); + didset_options2(); + redraw_all_later(CLEAR); } else { showoptions(1, opt_flags); did_show = TRUE; @@ -2072,9 +2062,31 @@ static void didset_options(void) (void)spell_check_msm(); (void)spell_check_sps(); (void)compile_cap_prog(curwin->w_s); - /* set cedit_key */ + (void)did_set_spell_option(true); + // set cedit_key (void)check_cedit(); briopt_check(curwin); + // initialize the table for 'breakat'. + fill_breakat_flags(); +} + +// More side effects of setting options. +static void didset_options2(void) +{ + // Initialize the highlight_attr[] table. + (void)highlight_changed(); + + // Parse default for 'clipboard'. + opt_strings_flags(p_cb, p_cb_values, &cb_flags, true); + + // Parse default for 'fillchars'. + (void)set_chars_option(&p_fcs); + + // Parse default for 'listchars'. + (void)set_chars_option(&p_lcs); + + // Parse default for 'wildmode'. + check_opt_wim(); } /* @@ -2853,22 +2865,7 @@ did_set_string_option ( || varp == &(curwin->w_s->b_p_spf)) { // When 'spelllang' or 'spellfile' is set and there is a window for this // buffer in which 'spell' is set load the wordlists. - if (varp == &(curwin->w_s->b_p_spf)) { - int l = (int)STRLEN(curwin->w_s->b_p_spf); - if (l > 0 - && (l < 4 || STRCMP(curwin->w_s->b_p_spf + l - 4, ".add") != 0)) { - errmsg = e_invarg; - } - } - - if (errmsg == NULL) { - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_buffer == curbuf && wp->w_p_spell) { - errmsg = did_set_spelllang(wp); - break; - } - } - } + errmsg = did_set_spell_option(varp == &(curwin->w_s->b_p_spf)); } /* When 'spellcapcheck' is set compile the regexp program. */ else if (varp == &(curwin->w_s->b_p_spc)) { @@ -3424,6 +3421,30 @@ char_u *check_stl_option(char_u *s) return NULL; } +static char_u *did_set_spell_option(bool is_spellfile) +{ + char_u *errmsg = NULL; + + if (is_spellfile) { + int l = (int)STRLEN(curwin->w_s->b_p_spf); + if (l > 0 + && (l < 4 || STRCMP(curwin->w_s->b_p_spf + l - 4, ".add") != 0)) { + errmsg = e_invarg; + } + } + + if (errmsg == NULL) { + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if (wp->w_buffer == curbuf && wp->w_p_spell) { + errmsg = did_set_spelllang(wp); + break; + } + } + } + + return errmsg; +} + /* * Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'. * Return error message when failed, NULL when OK. @@ -5503,6 +5524,7 @@ void buf_copy_options(buf_T *buf, int flags) buf->b_p_et = p_et; buf->b_p_fixeol = p_fixeol; buf->b_p_et_nobin = p_et_nobin; + buf->b_p_et_nopaste = p_et_nopaste; buf->b_p_ml = p_ml; buf->b_p_ml_nobin = p_ml_nobin; buf->b_p_inf = p_inf; @@ -6160,6 +6182,7 @@ static void paste_option_changed(void) { static int old_p_paste = FALSE; static int save_sm = 0; + static int save_sta = 0; static int save_ru = 0; static int save_ri = 0; static int save_hkmap = 0; @@ -6176,40 +6199,44 @@ static void paste_option_changed(void) buf->b_p_wm_nopaste = buf->b_p_wm; buf->b_p_sts_nopaste = buf->b_p_sts; buf->b_p_ai_nopaste = buf->b_p_ai; + buf->b_p_et_nopaste = buf->b_p_et; } - /* save global options */ + // save global options save_sm = p_sm; + save_sta = p_sta; save_ru = p_ru; save_ri = p_ri; save_hkmap = p_hkmap; - /* save global values for local buffer options */ + // save global values for local buffer options + p_ai_nopaste = p_ai; + p_et_nopaste = p_et; + p_sts_nopaste = p_sts; p_tw_nopaste = p_tw; p_wm_nopaste = p_wm; - p_sts_nopaste = p_sts; - p_ai_nopaste = p_ai; } - /* - * Always set the option values, also when 'paste' is set when it is - * already on. - */ - /* set options for each buffer */ + // Always set the option values, also when 'paste' is set when it is + // already on. + // set options for each buffer FOR_ALL_BUFFERS(buf) { - buf->b_p_tw = 0; /* textwidth is 0 */ - buf->b_p_wm = 0; /* wrapmargin is 0 */ - buf->b_p_sts = 0; /* softtabstop is 0 */ - buf->b_p_ai = 0; /* no auto-indent */ - } - - /* set global options */ - p_sm = 0; /* no showmatch */ - if (p_ru) - status_redraw_all(); /* redraw to remove the ruler */ - p_ru = 0; /* no ruler */ - p_ri = 0; /* no reverse insert */ - p_hkmap = 0; /* no Hebrew keyboard */ - /* set global values for local buffer options */ + buf->b_p_tw = 0; // textwidth is 0 + buf->b_p_wm = 0; // wrapmargin is 0 + buf->b_p_sts = 0; // softtabstop is 0 + buf->b_p_ai = 0; // no auto-indent + buf->b_p_et = 0; // no expandtab + } + + // set global options + p_sm = 0; // no showmatch + p_sta = 0; // no smarttab + if (p_ru) { + status_redraw_all(); // redraw to remove the ruler + } + p_ru = 0; // no ruler + p_ri = 0; // no reverse insert + p_hkmap = 0; // no Hebrew keyboard + // set global values for local buffer options p_tw = 0; p_wm = 0; p_sts = 0; @@ -6225,20 +6252,24 @@ static void paste_option_changed(void) buf->b_p_wm = buf->b_p_wm_nopaste; buf->b_p_sts = buf->b_p_sts_nopaste; buf->b_p_ai = buf->b_p_ai_nopaste; + buf->b_p_et = buf->b_p_et_nopaste; } /* restore global options */ p_sm = save_sm; - if (p_ru != save_ru) - status_redraw_all(); /* redraw to draw the ruler */ + p_sta = save_sta; + if (p_ru != save_ru) { + status_redraw_all(); // redraw to draw the ruler + } p_ru = save_ru; p_ri = save_ri; p_hkmap = save_hkmap; - /* set global values for local buffer options */ + // set global values for local buffer options + p_ai = p_ai_nopaste; + p_et = p_et_nopaste; + p_sts = p_sts_nopaste; p_tw = p_tw_nopaste; p_wm = p_wm_nopaste; - p_sts = p_sts_nopaste; - p_ai = p_ai_nopaste; } old_p_paste = p_paste; diff --git a/src/nvim/path.c b/src/nvim/path.c index 8b9a49dfc0..e0e5f19911 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -1775,19 +1775,20 @@ bool same_directory(char_u *f1, char_u *f2) */ int pathcmp(const char *p, const char *q, int maxlen) { - int i; + int i, j; int c1, c2; const char *s = NULL; - for (i = 0; maxlen < 0 || i < maxlen; i += MB_PTR2LEN((char_u *)p + i)) { + for (i = 0, j = 0; maxlen < 0 || (i < maxlen && j < maxlen);) { c1 = PTR2CHAR((char_u *)p + i); - c2 = PTR2CHAR((char_u *)q + i); + c2 = PTR2CHAR((char_u *)q + j); /* End of "p": check if "q" also ends or just has a slash. */ if (c1 == NUL) { if (c2 == NUL) /* full match */ return 0; s = q; + i = j; break; } @@ -1811,9 +1812,13 @@ int pathcmp(const char *p, const char *q, int maxlen) return p_fic ? vim_toupper(c1) - vim_toupper(c2) : c1 - c2; /* no match */ } + + i += MB_PTR2LEN((char_u *)p + i); + j += MB_PTR2LEN((char_u *)q + j); } - if (s == NULL) /* "i" ran into "maxlen" */ + if (s == NULL) { // "i" or "j" ran into "maxlen" return 0; + } c1 = PTR2CHAR((char_u *)s + i); c2 = PTR2CHAR((char_u *)s + i + MB_PTR2LEN((char_u *)s + i)); diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 7495647ff2..3b5836f0b5 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2432,13 +2432,18 @@ win_line ( } } - /* find start of trailing whitespace */ - if (wp->w_p_list && lcs_trail) { - trailcol = (colnr_T)STRLEN(ptr); - while (trailcol > (colnr_T)0 && ascii_iswhite(ptr[trailcol - 1])) - --trailcol; - trailcol += (colnr_T) (ptr - line); - extra_check = TRUE; + if (wp->w_p_list) { + if (lcs_space || lcs_trail) { + extra_check = true; + } + // find start of trailing whitespace + if (lcs_trail) { + trailcol = (colnr_T)STRLEN(ptr); + while (trailcol > (colnr_T)0 && ascii_iswhite(ptr[trailcol - 1])) { + trailcol--; + } + trailcol += (colnr_T) (ptr - line); + } } /* @@ -3210,27 +3215,7 @@ win_line ( } } - ++ptr; - - // 'list': change char 160 to lcs_nbsp and space to lcs_space. - if (wp->w_p_list - && (((c == 160 || (mb_utf8 && (mb_c == 160 || mb_c == 0x202f))) - && lcs_nbsp) - || (c == ' ' && lcs_space && ptr - line <= trailcol))) { - c = (c == ' ') ? lcs_space : lcs_nbsp; - if (area_attr == 0 && search_attr == 0) { - n_attr = 1; - extra_attr = hl_attr(HLF_8); - saved_attr2 = char_attr; /* save current attr */ - } - mb_c = c; - if (enc_utf8 && (*mb_char2len)(c) > 1) { - mb_utf8 = TRUE; - u8cc[0] = 0; - c = 0xc0; - } else - mb_utf8 = FALSE; - } + ptr++; if (extra_check) { bool can_spell = true; @@ -3377,6 +3362,28 @@ win_line ( } } + // 'list': change char 160 to lcs_nbsp and space to lcs_space. + if (wp->w_p_list + && (((c == 160 + || (mb_utf8 && (mb_c == 160 || mb_c == 0x202f))) + && lcs_nbsp) + || (c == ' ' && lcs_space && ptr - line <= trailcol))) { + c = (c == ' ') ? lcs_space : lcs_nbsp; + if (area_attr == 0 && search_attr == 0) { + n_attr = 1; + extra_attr = hl_attr(HLF_8); + saved_attr2 = char_attr; // save current attr + } + mb_c = c; + if (enc_utf8 && (*mb_char2len)(c) > 1) { + mb_utf8 = true; + u8cc[0] = 0; + c = 0xc0; + } else { + mb_utf8 = false; + } + } + if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ') { c = lcs_trail; if (!attr_pri) { diff --git a/src/nvim/search.c b/src/nvim/search.c index 827473e55d..fffae1ecb2 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -3144,10 +3144,12 @@ current_block ( } if (VIsual_active) { - if (*p_sel == 'e') - ++curwin->w_cursor.col; - if (sol && gchar_cursor() != NUL) - inc(&curwin->w_cursor); /* include the line break */ + if (*p_sel == 'e') { + inc(&curwin->w_cursor); + } + if (sol && gchar_cursor() != NUL) { + inc(&curwin->w_cursor); // include the line break + } VIsual = start_pos; VIsual_mode = 'v'; redraw_curbuf_later(INVERTED); /* update the inversion */ diff --git a/src/nvim/testdir/test_listlbr.in b/src/nvim/testdir/test_listlbr.in index f13eee121e..6084711786 100644 --- a/src/nvim/testdir/test_listlbr.in +++ b/src/nvim/testdir/test_listlbr.in @@ -24,20 +24,24 @@ STARTTEST : $put =g:line : wincmd p :endfu +:" :let g:test="Test 1: set linebreak" :redraw! :let line=ScreenChar(winwidth(0)) :call DoRecordScreen() +:" :let g:test="Test 2: set linebreak + set list" :set linebreak list listchars= :redraw! :let line=ScreenChar(winwidth(0)) :call DoRecordScreen() +:" :let g:test ="Test 3: set linebreak nolist" :set nolist linebreak :redraw! :let line=ScreenChar(winwidth(0)) :call DoRecordScreen() +:" :let g:test ="Test 4: set linebreak with tab and 1 line as long as screen: should break!" :set nolist linebreak ts=8 :let line="1\t".repeat('a', winwidth(0)-2) @@ -51,6 +55,7 @@ STARTTEST :$put =line :$ :norm! zt +:" :let g:test ="Test 5: set linebreak with conceal and set list and tab displayed by different char (line may not be truncated)" :set cpo&vim list linebreak conceallevel=2 concealcursor=nv listchars=tab:ab :syn match ConcealVar contained /_/ conceal @@ -58,6 +63,7 @@ STARTTEST :let line=ScreenChar(winwidth(0)) :call DoRecordScreen() :set cpo&vim linebreak +:" :let g:test ="Test 6: set linebreak with visual block mode" :let line="REMOVE: this not" :$put =g:test @@ -67,20 +73,47 @@ STARTTEST :1/^REMOVE: 0jf x:$put :set cpo&vim linebreak +:" :let g:test ="Test 7: set linebreak with visual block mode and v_b_A" :$put =g:test Golong line: 40afoobar aTARGET at end :exe "norm! $3B\<C-v>eAx\<Esc>" :set cpo&vim linebreak sbr= +:" :let g:test ="Test 8: set linebreak with visual char mode and changing block" :$put =g:test Go1111-1111-1111-11-1111-1111-11110f-lv3lc2222bgj. +:" :let g:test ="Test 9: using redo after block visual mode" :$put =g:test Go aaa aaa a2k2j~e. +:" +:let g:test ="Test 10: using normal commands after block-visual" +:$put =g:test +:set linebreak +Go +abcd{ef +ghijklm +no}pqrs2k0f{c% +:" +:let g:test ="Test 11: using block replace mode after wrapping" +:$put =g:test +:set linebreak wrap +Go150aayypk147|jr0 +:" +:let g:test ="Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$" +:set list listchars=space:_,trail:-,tab:>-,eol:$ +:$put =g:test +:let line="a aaaaaaaaaaaaaaaaaaaaaa\ta " +:$put =line +:$ +:norm! zt +:redraw! +:let line=ScreenChar(winwidth(0)) +:call DoRecordScreen() :%w! test.out :qa! ENDTEST diff --git a/src/nvim/testdir/test_listlbr.ok b/src/nvim/testdir/test_listlbr.ok index 323bcdee08..b32a54969e 100644 --- a/src/nvim/testdir/test_listlbr.ok +++ b/src/nvim/testdir/test_listlbr.ok @@ -46,3 +46,17 @@ Test 9: using redo after block visual mode AaA AaA A +Test 10: using normal commands after block-visual + +abcdpqrs +Test 11: using block replace mode after wrapping +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0aaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0aaa +Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$ +a aaaaaaaaaaaaaaaaaaaaaa a + +Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$ +a_ +aaaaaaaaaaaaaaaaaaaa +aa>-----a-$ +~ diff --git a/src/nvim/version.c b/src/nvim/version.c index 4de63ebb10..39b8e3db84 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -311,7 +311,7 @@ static int included_patches[] = { 980, // 979 NA 978, - // 977, + 977, // 976 NA 975, // 974, @@ -403,15 +403,15 @@ static int included_patches[] = { // 888, 887, // 886 NA - // 885, + 885, // 884 NA - // 883, + 883, // 882, // 881, // 880 NA // 879, // 878, - // 877, + 877, // 876 NA // 875 NA // 874 NA @@ -420,7 +420,7 @@ static int included_patches[] = { // 871, // 870, // 869 NA - // 868, + 868, // 867 NA // 866 NA // 865 NA @@ -429,23 +429,23 @@ static int included_patches[] = { // 862 NA // 861 NA // 860 NA - // 859, + 859, 858, // 857, - // 856, + 856, // 855 NA // 854 NA - // 853, + 853, // 852 NA // 851 NA // 850 NA 849, 848, - // 847, + 847, // 846 NA // 845, - // 844, - // 843, + 844, + 843, // 842 NA // 841 NA // 840 NA @@ -453,12 +453,12 @@ static int included_patches[] = { // 838 NA // 837 NA 836, - // 835, + 835, 834, - // 833, + 833, // 832, // 831, - // 830, + 830, // 829 NA 828, // 827 NA @@ -470,7 +470,7 @@ static int included_patches[] = { // 821 NA 820, // 819, - // 818, + 818, 817, 816, 815, diff --git a/test/functional/legacy/comparators_spec.lua b/test/functional/legacy/comparators_spec.lua new file mode 100644 index 0000000000..e3fa3eea23 --- /dev/null +++ b/test/functional/legacy/comparators_spec.lua @@ -0,0 +1,14 @@ +-- " Test for expression comparators. + +local helpers = require('test.functional.helpers') +local clear, eq = helpers.clear, helpers.eq +local eval, execute = helpers.eval, helpers.execute + +describe('comparators', function() + before_each(clear) + + it('is working', function() + execute('set isident+=#') + eq(1, eval('1 is#1')) + end) +end) |