aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/filetype.vim3
-rw-r--r--runtime/lua/vim/filetype.lua2
-rw-r--r--src/nvim/api/vim.c14
-rw-r--r--src/nvim/buffer.c49
-rw-r--r--src/nvim/eval.c34
-rw-r--r--src/nvim/eval/funcs.c4
-rw-r--r--src/nvim/ex_cmds.c10
-rw-r--r--src/nvim/globals.h2
-rw-r--r--src/nvim/lua/stdlib.c7
-rw-r--r--src/nvim/option.c100
-rw-r--r--src/nvim/pos.h4
-rw-r--r--src/nvim/screen.c2
-rw-r--r--src/nvim/testdir/test_assert.vim174
-rw-r--r--src/nvim/testdir/test_cdo.vim205
-rw-r--r--src/nvim/testdir/test_cursor_func.vim67
-rw-r--r--src/nvim/testdir/test_filetype.vim1
-rw-r--r--src/nvim/testdir/test_options.vim37
-rw-r--r--src/nvim/testdir/test_packadd.vim361
-rw-r--r--src/nvim/testdir/test_retab.vim21
-rw-r--r--src/nvim/testdir/test_winbuf_close.vim19
-rw-r--r--src/nvim/window.c14
-rw-r--r--test/functional/api/vim_spec.lua13
-rw-r--r--test/functional/legacy/assert_spec.lua233
-rw-r--r--test/functional/legacy/cdo_spec.lua228
-rw-r--r--test/functional/legacy/packadd_spec.lua507
-rw-r--r--test/functional/lua/vim_spec.lua17
26 files changed, 1107 insertions, 1021 deletions
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index 8b40b43a04..35f4b25120 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -1543,6 +1543,9 @@ au BufNewFile,BufRead *.r,*.R call dist#ft#FTr()
" Remind
au BufNewFile,BufRead .reminders,*.remind,*.rem setf remind
+" ReScript
+au BufNewFile,BufRead *.res,*.resi setf rescript
+
" Resolv.conf
au BufNewFile,BufRead resolv.conf setf resolv
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index e2cf408f3b..2fe4aa3d32 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -514,6 +514,8 @@ local extension = {
rego = "rego",
rem = "remind",
remind = "remind",
+ res = "rescript",
+ resi = "rescript",
frt = "reva",
testUnit = "rexx",
rex = "rexx",
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index f7c55344f5..f4909b0801 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -601,7 +601,19 @@ void nvim_del_current_line(Error *err)
Object nvim_get_var(String name, Error *err)
FUNC_API_SINCE(1)
{
- return dict_get_value(&globvardict, name, err);
+ dictitem_T *di = tv_dict_find(&globvardict, name.data, (ptrdiff_t)name.size);
+ if (di == NULL) { // try to autoload script
+ if (!script_autoload(name.data, name.size, false) || aborting()) {
+ api_set_error(err, kErrorTypeValidation, "Key not found: %s", name.data);
+ return (Object)OBJECT_INIT;
+ }
+ di = tv_dict_find(&globvardict, name.data, (ptrdiff_t)name.size);
+ }
+ if (di == NULL) {
+ api_set_error(err, kErrorTypeValidation, "Key not found: %s", name.data);
+ return (Object)OBJECT_INIT;
+ }
+ return vim_to_object(&di->di_tv);
}
/// Sets a global (g:) variable.
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index ee704bd1bd..38b045b31c 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -5455,30 +5455,43 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp)
return false;
}
-int buf_signcols(buf_T *buf)
+static int buf_signcols_inner(buf_T *buf, int maximum)
{
- if (!buf->b_signcols_valid) {
- sign_entry_T *sign; // a sign in the sign list
- int signcols = 0;
- int linesum = 0;
- linenr_T curline = 0;
-
- FOR_ALL_SIGNS_IN_BUF(buf, sign) {
- if (sign->se_lnum > curline) {
- if (linesum > signcols) {
- signcols = linesum;
+ sign_entry_T *sign; // a sign in the sign list
+ int signcols = 0;
+ int linesum = 0;
+ linenr_T curline = 0;
+
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
+ if (sign->se_lnum > curline) {
+ if (linesum > signcols) {
+ signcols = linesum;
+ if (signcols >= maximum) {
+ return maximum;
}
- curline = sign->se_lnum;
- linesum = 0;
- }
- if (sign->se_has_text_or_icon) {
- linesum++;
}
+ curline = sign->se_lnum;
+ linesum = 0;
+ }
+ if (sign->se_has_text_or_icon) {
+ linesum++;
}
- if (linesum > signcols) {
- signcols = linesum;
+ }
+
+ if (linesum > signcols) {
+ signcols = linesum;
+ if (signcols >= maximum) {
+ return maximum;
}
+ }
+
+ return signcols;
+}
+int buf_signcols(buf_T *buf, int maximum)
+{
+ if (!buf->b_signcols_valid) {
+ int signcols = buf_signcols_inner(buf, maximum);
// Check if we need to redraw
if (signcols != buf->b_signcols) {
buf->b_signcols = signcols;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 4b83bda804..07f0799bc4 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -8192,7 +8192,7 @@ char *save_tv_as_string(typval_T *tv, ptrdiff_t *const len, bool endnl)
/// Convert the specified byte index of line 'lnum' in buffer 'buf' to a
/// character index. Works only for loaded buffers. Returns -1 on failure.
-/// The index of the first character is one.
+/// The index of the first byte and the first character is zero.
int buf_byteidx_to_charidx(buf_T *buf, int lnum, int byteidx)
{
if (buf == NULL || buf->b_ml.ml_mfp == NULL) {
@@ -8206,15 +8206,29 @@ int buf_byteidx_to_charidx(buf_T *buf, int lnum, int byteidx)
char_u *str = ml_get_buf(buf, lnum, false);
if (*str == NUL) {
- return 1;
+ return 0;
+ }
+
+ // count the number of characters
+ char_u *t = str;
+ int count;
+ for (count = 0; *t != NUL && t <= str + byteidx; count++) {
+ t += utfc_ptr2len(t);
+ }
+
+ // In insert mode, when the cursor is at the end of a non-empty line,
+ // byteidx points to the NUL character immediately past the end of the
+ // string. In this case, add one to the character count.
+ if (*t == NUL && byteidx != 0 && t == str + byteidx) {
+ count++;
}
- return mb_charlen_len(str, byteidx + 1);
+ return count - 1;
}
/// Convert the specified character index of line 'lnum' in buffer 'buf' to a
-/// byte index. Works only for loaded buffers. Returns -1 on failure. The index
-/// of the first byte and the first character is one.
+/// byte index. Works only for loaded buffers. Returns -1 on failure.
+/// The index of the first byte and the first character is zero.
int buf_charidx_to_byteidx(buf_T *buf, int lnum, int charidx)
{
if (buf == NULL || buf->b_ml.ml_mfp == NULL) {
@@ -8233,7 +8247,7 @@ int buf_charidx_to_byteidx(buf_T *buf, int lnum, int charidx)
t += utfc_ptr2len(t);
}
- return t - str + 1;
+ return t - str;
}
/// Translate a VimL object into a position
@@ -8315,7 +8329,7 @@ pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret
if (name[0] == '.') { // Cursor.
pos = curwin->w_cursor;
if (charcol) {
- pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col) - 1;
+ pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col);
}
return &pos;
}
@@ -8326,7 +8340,7 @@ pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret
pos = curwin->w_cursor;
}
if (charcol) {
- pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col) - 1;
+ pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col);
}
return &pos;
}
@@ -8336,7 +8350,7 @@ pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret
return NULL;
}
if (charcol) {
- pp->col = buf_byteidx_to_charidx(curbuf, pp->lnum, pp->col) - 1;
+ pp->col = buf_byteidx_to_charidx(curbuf, pp->lnum, pp->col);
}
return pp;
}
@@ -8423,7 +8437,7 @@ int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp, bool c
if (buf == NULL || buf->b_ml.ml_mfp == NULL) {
return FAIL;
}
- n = buf_charidx_to_byteidx(buf, posp->lnum, n);
+ n = buf_charidx_to_byteidx(buf, posp->lnum, n) + 1;
}
posp->col = n;
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 8beacc9988..7772d9ffc2 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -1588,7 +1588,7 @@ static void set_cursorpos(typval_T *argvars, typval_T *rettv, bool charcol)
line = tv_get_lnum(argvars);
col = (long)tv_get_number_chk(&argvars[1], NULL);
if (charcol) {
- col = buf_charidx_to_byteidx(curbuf, line, col);
+ col = buf_charidx_to_byteidx(curbuf, line, col) + 1;
}
if (argvars[2].v_type != VAR_UNKNOWN) {
coladd = (long)tv_get_number_chk(&argvars[2], NULL);
@@ -3327,7 +3327,7 @@ static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos, bool
}
if (fp != NULL && charcol) {
pos = *fp;
- pos.col = buf_byteidx_to_charidx(wp->w_buffer, pos.lnum, pos.col) - 1;
+ pos.col = buf_byteidx_to_charidx(wp->w_buffer, pos.lnum, pos.col);
fp = &pos;
}
} else {
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index fd1e34803f..49bf9972b1 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -814,7 +814,11 @@ void ex_retab(exarg_T *eap)
// len is actual number of white characters used
len = num_spaces + num_tabs;
old_len = (long)STRLEN(ptr);
- long new_len = old_len - col + start_col + len + 1;
+ const long new_len = old_len - col + start_col + len + 1;
+ if (new_len <= 0 || new_len >= MAXCOL) {
+ emsg(_(e_resulting_text_too_long));
+ break;
+ }
new_line = xmalloc(new_len);
if (start_col > 0) {
@@ -847,6 +851,10 @@ void ex_retab(exarg_T *eap)
break;
}
vcol += win_chartabsize(curwin, ptr + col, (colnr_T)vcol);
+ if (vcol >= MAXCOL) {
+ emsg(_(e_resulting_text_too_long));
+ break;
+ }
col += utfc_ptr2len(ptr + col);
}
if (new_line == NULL) { // out of memory
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index f6fbe98ff0..98a38c5fe2 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -1000,6 +1000,8 @@ EXTERN char e_non_empty_string_required[] INIT(= N_("E1142: Non-empty string req
EXTERN char e_cannot_define_autocommands_for_all_events[] INIT(= N_("E1155: Cannot define autocommands for ALL events"));
+EXTERN char e_resulting_text_too_long[] INIT(= N_("E1240: Resulting text too long"));
+
EXTERN char e_highlight_group_name_too_long[] INIT(= N_("E1249: Highlight group name too long"));
EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c
index 18a579ed0f..55b23cf0c8 100644
--- a/src/nvim/lua/stdlib.c
+++ b/src/nvim/lua/stdlib.c
@@ -25,6 +25,7 @@
#include "nvim/func_attr.h"
#include "nvim/garray.h"
#include "nvim/getchar.h"
+#include "nvim/globals.h"
#include "nvim/lua/converter.h"
#include "nvim/lua/executor.h"
#include "nvim/lua/stdlib.h"
@@ -408,6 +409,12 @@ int nlua_getvar(lua_State *lstate)
const char *name = luaL_checklstring(lstate, 3, &len);
dictitem_T *di = tv_dict_find(dict, name, (ptrdiff_t)len);
+ if (di == NULL && dict == &globvardict) { // try to autoload script
+ if (!script_autoload(name, len, false) || aborting()) {
+ return 0; // nil
+ }
+ di = tv_dict_find(dict, name, (ptrdiff_t)len);
+ }
if (di == NULL) {
return 0; // nil
}
diff --git a/src/nvim/option.c b/src/nvim/option.c
index dddf926b9a..c8e50d4494 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -6232,6 +6232,9 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_fcs = vim_strsave(from->wo_fcs);
to->wo_lcs = vim_strsave(from->wo_lcs);
to->wo_winbl = from->wo_winbl;
+
+ // Copy the script context so that we know were the value was last set.
+ memmove(to->wo_script_ctx, from->wo_script_ctx, sizeof(to->wo_script_ctx));
check_winopt(to); // don't want NULL pointers
}
@@ -6304,11 +6307,30 @@ void didset_window_options(win_T *wp)
wp->w_grid_alloc.blending = wp->w_p_winbl > 0;
}
+/// Index into the options table for a buffer-local option enum.
+static int buf_opt_idx[BV_COUNT];
+#define COPY_OPT_SCTX(buf, bv) buf->b_p_script_ctx[bv] = options[buf_opt_idx[bv]].last_set
+
+/// Initialize buf_opt_idx[] if not done already.
+static void init_buf_opt_idx(void)
+{
+ static int did_init_buf_opt_idx = false;
+
+ if (did_init_buf_opt_idx) {
+ return;
+ }
+ did_init_buf_opt_idx = true;
+ for (int i = 0; options[i].fullname != NULL; i++) {
+ if (options[i].indir & PV_BUF) {
+ buf_opt_idx[options[i].indir & PV_MASK] = i;
+ }
+ }
+}
/// Copy global option values to local options for one buffer.
/// Used when creating a new buffer and sometimes when entering a buffer.
/// flags:
-/// BCO_ENTER We will enter the buf buffer.
+/// BCO_ENTER We will enter the buffer "buf".
/// BCO_ALWAYS Always copy the options, but only set b_p_initialized when
/// appropriate.
/// BCO_NOHELP Don't copy the values to a help buffer.
@@ -6344,11 +6366,12 @@ void buf_copy_options(buf_T *buf, int flags)
}
if (should_copy || (flags & BCO_ALWAYS)) {
- /* Don't copy the options specific to a help buffer when
- * BCO_NOHELP is given or the options were initialized already
- * (jumping back to a help file with CTRL-T or CTRL-O) */
- dont_do_help = ((flags & BCO_NOHELP) && buf->b_help)
- || buf->b_p_initialized;
+ memset(buf->b_p_script_ctx, 0, sizeof(buf->b_p_script_ctx));
+ init_buf_opt_idx();
+ // Don't copy the options specific to a help buffer when
+ // BCO_NOHELP is given or the options were initialized already
+ // (jumping back to a help file with CTRL-T or CTRL-O)
+ dont_do_help = ((flags & BCO_NOHELP) && buf->b_help) || buf->b_p_initialized;
if (dont_do_help) { // don't free b_p_isk
save_p_isk = buf->b_p_isk;
buf->b_p_isk = NULL;
@@ -6380,35 +6403,58 @@ void buf_copy_options(buf_T *buf, int flags)
}
buf->b_p_ai = p_ai;
+ COPY_OPT_SCTX(buf, BV_AI);
buf->b_p_ai_nopaste = p_ai_nopaste;
buf->b_p_sw = p_sw;
+ COPY_OPT_SCTX(buf, BV_SW);
buf->b_p_scbk = p_scbk;
+ COPY_OPT_SCTX(buf, BV_SCBK);
buf->b_p_tw = p_tw;
+ COPY_OPT_SCTX(buf, BV_TW);
buf->b_p_tw_nopaste = p_tw_nopaste;
buf->b_p_tw_nobin = p_tw_nobin;
buf->b_p_wm = p_wm;
+ COPY_OPT_SCTX(buf, BV_WM);
buf->b_p_wm_nopaste = p_wm_nopaste;
buf->b_p_wm_nobin = p_wm_nobin;
buf->b_p_bin = p_bin;
+ COPY_OPT_SCTX(buf, BV_BIN);
buf->b_p_bomb = p_bomb;
+ COPY_OPT_SCTX(buf, BV_BOMB);
buf->b_p_et = p_et;
+ COPY_OPT_SCTX(buf, BV_ET);
buf->b_p_fixeol = p_fixeol;
+ COPY_OPT_SCTX(buf, BV_FIXEOL);
buf->b_p_et_nobin = p_et_nobin;
buf->b_p_et_nopaste = p_et_nopaste;
buf->b_p_ml = p_ml;
+ COPY_OPT_SCTX(buf, BV_ML);
buf->b_p_ml_nobin = p_ml_nobin;
buf->b_p_inf = p_inf;
- buf->b_p_swf = cmdmod.noswapfile ? false : p_swf;
+ COPY_OPT_SCTX(buf, BV_INF);
+ if (cmdmod.noswapfile) {
+ buf->b_p_swf = false;
+ } else {
+ buf->b_p_swf = p_swf;
+ COPY_OPT_SCTX(buf, BV_SWF);
+ }
buf->b_p_cpt = vim_strsave(p_cpt);
+ COPY_OPT_SCTX(buf, BV_CPT);
#ifdef BACKSLASH_IN_FILENAME
buf->b_p_csl = vim_strsave(p_csl);
+ COPY_OPT_SCTX(buf, BV_CSL);
#endif
buf->b_p_cfu = vim_strsave(p_cfu);
+ COPY_OPT_SCTX(buf, BV_CFU);
buf->b_p_ofu = vim_strsave(p_ofu);
+ COPY_OPT_SCTX(buf, BV_OFU);
buf->b_p_tfu = vim_strsave(p_tfu);
+ COPY_OPT_SCTX(buf, BV_TFU);
buf->b_p_sts = p_sts;
+ COPY_OPT_SCTX(buf, BV_STS);
buf->b_p_sts_nopaste = p_sts_nopaste;
buf->b_p_vsts = vim_strsave(p_vsts);
+ COPY_OPT_SCTX(buf, BV_VSTS);
if (p_vsts && p_vsts != empty_option) {
(void)tabstop_set(p_vsts, &buf->b_p_vsts_array);
} else {
@@ -6418,42 +6464,68 @@ void buf_copy_options(buf_T *buf, int flags)
? vim_strsave(p_vsts_nopaste)
: NULL;
buf->b_p_com = vim_strsave(p_com);
+ COPY_OPT_SCTX(buf, BV_COM);
buf->b_p_cms = vim_strsave(p_cms);
+ COPY_OPT_SCTX(buf, BV_CMS);
buf->b_p_fo = vim_strsave(p_fo);
+ COPY_OPT_SCTX(buf, BV_FO);
buf->b_p_flp = vim_strsave(p_flp);
+ COPY_OPT_SCTX(buf, BV_FLP);
buf->b_p_nf = vim_strsave(p_nf);
+ COPY_OPT_SCTX(buf, BV_NF);
buf->b_p_mps = vim_strsave(p_mps);
+ COPY_OPT_SCTX(buf, BV_MPS);
buf->b_p_si = p_si;
+ COPY_OPT_SCTX(buf, BV_SI);
buf->b_p_channel = 0;
buf->b_p_ci = p_ci;
+ COPY_OPT_SCTX(buf, BV_CI);
buf->b_p_cin = p_cin;
+ COPY_OPT_SCTX(buf, BV_CIN);
buf->b_p_cink = vim_strsave(p_cink);
+ COPY_OPT_SCTX(buf, BV_CINK);
buf->b_p_cino = vim_strsave(p_cino);
+ COPY_OPT_SCTX(buf, BV_CINO);
// Don't copy 'filetype', it must be detected
buf->b_p_ft = empty_option;
buf->b_p_pi = p_pi;
+ COPY_OPT_SCTX(buf, BV_PI);
buf->b_p_cinw = vim_strsave(p_cinw);
+ COPY_OPT_SCTX(buf, BV_CINW);
buf->b_p_lisp = p_lisp;
+ COPY_OPT_SCTX(buf, BV_LISP);
// Don't copy 'syntax', it must be set
buf->b_p_syn = empty_option;
buf->b_p_smc = p_smc;
+ COPY_OPT_SCTX(buf, BV_SMC);
buf->b_s.b_syn_isk = empty_option;
buf->b_s.b_p_spc = vim_strsave(p_spc);
+ COPY_OPT_SCTX(buf, BV_SPC);
(void)compile_cap_prog(&buf->b_s);
buf->b_s.b_p_spf = vim_strsave(p_spf);
+ COPY_OPT_SCTX(buf, BV_SPF);
buf->b_s.b_p_spl = vim_strsave(p_spl);
+ COPY_OPT_SCTX(buf, BV_SPL);
buf->b_s.b_p_spo = vim_strsave(p_spo);
+ COPY_OPT_SCTX(buf, BV_SPO);
buf->b_p_inde = vim_strsave(p_inde);
+ COPY_OPT_SCTX(buf, BV_INDE);
buf->b_p_indk = vim_strsave(p_indk);
+ COPY_OPT_SCTX(buf, BV_INDK);
buf->b_p_fp = empty_option;
buf->b_p_fex = vim_strsave(p_fex);
+ COPY_OPT_SCTX(buf, BV_FEX);
buf->b_p_sua = vim_strsave(p_sua);
+ COPY_OPT_SCTX(buf, BV_SUA);
buf->b_p_keymap = vim_strsave(p_keymap);
+ COPY_OPT_SCTX(buf, BV_KMAP);
buf->b_kmap_state |= KEYMAP_INIT;
// This isn't really an option, but copying the langmap and IME
// state from the current buffer is better than resetting it.
buf->b_p_iminsert = p_iminsert;
+ COPY_OPT_SCTX(buf, BV_IMI);
buf->b_p_imsearch = p_imsearch;
+ COPY_OPT_SCTX(buf, BV_IMS);
// options that are normally global but also have a local value
// are not copied, start using the global value
@@ -6473,11 +6545,14 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_def = empty_option;
buf->b_p_inc = empty_option;
buf->b_p_inex = vim_strsave(p_inex);
+ COPY_OPT_SCTX(buf, BV_INEX);
buf->b_p_dict = empty_option;
buf->b_p_tsr = empty_option;
buf->b_p_tsrfu = empty_option;
buf->b_p_qe = vim_strsave(p_qe);
+ COPY_OPT_SCTX(buf, BV_QE);
buf->b_p_udf = p_udf;
+ COPY_OPT_SCTX(buf, BV_UDF);
buf->b_p_lw = empty_option;
buf->b_p_menc = empty_option;
@@ -6496,9 +6571,12 @@ void buf_copy_options(buf_T *buf, int flags)
}
} else {
buf->b_p_isk = vim_strsave(p_isk);
+ COPY_OPT_SCTX(buf, BV_ISK);
did_isk = true;
buf->b_p_ts = p_ts;
+ COPY_OPT_SCTX(buf, BV_TS);
buf->b_p_vts = vim_strsave(p_vts);
+ COPY_OPT_SCTX(buf, BV_VTS);
if (p_vts && p_vts != empty_option && !buf->b_p_vts_array) {
(void)tabstop_set(p_vts, &buf->b_p_vts_array);
} else {
@@ -6509,6 +6587,7 @@ void buf_copy_options(buf_T *buf, int flags)
clear_string_option(&buf->b_p_bt);
}
buf->b_p_ma = p_ma;
+ COPY_OPT_SCTX(buf, BV_MA);
}
}
@@ -8046,7 +8125,6 @@ int win_signcol_count(win_T *wp)
/// Return the number of requested sign columns, based on user / configuration.
int win_signcol_configured(win_T *wp, int *is_fixed)
{
- int minimum = 0, maximum = 1, needed_signcols;
const char *scl = (const char *)wp->w_p_scl;
if (is_fixed) {
@@ -8059,7 +8137,6 @@ int win_signcol_configured(win_T *wp, int *is_fixed)
&& (wp->w_p_nu || wp->w_p_rnu)))) {
return 0;
}
- needed_signcols = buf_signcols(wp->w_buffer);
// yes or yes
if (!strncmp(scl, "yes:", 4)) {
@@ -8075,6 +8152,8 @@ int win_signcol_configured(win_T *wp, int *is_fixed)
*is_fixed = 0;
}
+ int minimum = 0, maximum = 1;
+
if (!strncmp(scl, "auto:", 5)) {
// Variable depending on a configuration
maximum = scl[5] - '0';
@@ -8085,7 +8164,8 @@ int win_signcol_configured(win_T *wp, int *is_fixed)
}
}
- int ret = MAX(minimum, MIN(maximum, needed_signcols));
+ int needed_signcols = buf_signcols(wp->w_buffer, maximum);
+ int ret = MAX(minimum, needed_signcols);
assert(ret <= SIGN_SHOW_MAX);
return ret;
}
diff --git a/src/nvim/pos.h b/src/nvim/pos.h
index d17e27906e..51991ed314 100644
--- a/src/nvim/pos.h
+++ b/src/nvim/pos.h
@@ -16,7 +16,9 @@ typedef int colnr_T;
/// Maximal (invalid) line number
enum { MAXLNUM = 0x7fffffff, };
/// Maximal column number
-enum { MAXCOL = INT_MAX, };
+/// MAXCOL used to be INT_MAX, but with 64 bit ints that results in running
+/// out of memory when trying to allocate a very long line.
+enum { MAXCOL = 0x7fffffff, };
// Minimum line number
enum { MINLNUM = 1, };
// minimum column number
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 0644a08210..6dcabffb7d 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -794,7 +794,7 @@ static void win_update(win_T *wp, Providers *providers)
// If we can compute a change in the automatic sizing of the sign column
// under 'signcolumn=auto:X' and signs currently placed in the buffer, better
// figuring it out here so we can redraw the entire screen for it.
- buf_signcols(buf);
+ win_signcol_count(wp);
type = wp->w_redr_type;
diff --git a/src/nvim/testdir/test_assert.vim b/src/nvim/testdir/test_assert.vim
index 52f243aaea..28c5948142 100644
--- a/src/nvim/testdir/test_assert.vim
+++ b/src/nvim/testdir/test_assert.vim
@@ -1,5 +1,55 @@
" Test that the methods used for testing work.
+func Test_assert_false()
+ call assert_equal(0, assert_false(0))
+ call assert_equal(0, assert_false(v:false))
+ call assert_equal(0, v:false->assert_false())
+
+ call assert_equal(1, assert_false(123))
+ call assert_match("Expected False but got 123", v:errors[0])
+ call remove(v:errors, 0)
+
+ call assert_equal(1, 123->assert_false())
+ call assert_match("Expected False but got 123", v:errors[0])
+ call remove(v:errors, 0)
+endfunc
+
+func Test_assert_true()
+ call assert_equal(0, assert_true(1))
+ call assert_equal(0, assert_true(123))
+ call assert_equal(0, assert_true(v:true))
+ call assert_equal(0, v:true->assert_true())
+
+ call assert_equal(1, assert_true(0))
+ call assert_match("Expected True but got 0", v:errors[0])
+ call remove(v:errors, 0)
+
+ call assert_equal(1, 0->assert_true())
+ call assert_match("Expected True but got 0", v:errors[0])
+ call remove(v:errors, 0)
+endfunc
+
+func Test_assert_equal()
+ let s = 'foo'
+ call assert_equal(0, assert_equal('foo', s))
+ let n = 4
+ call assert_equal(0, assert_equal(4, n))
+ let l = [1, 2, 3]
+ call assert_equal(0, assert_equal([1, 2, 3], l))
+ call assert_equal(v:_null_list, v:_null_list)
+ call assert_equal(v:_null_list, [])
+ call assert_equal([], v:_null_list)
+
+ let s = 'foo'
+ call assert_equal(1, assert_equal('bar', s))
+ call assert_match("Expected 'bar' but got 'foo'", v:errors[0])
+ call remove(v:errors, 0)
+
+ call assert_equal('XxxxxxxxxxxxxxxxxxxxxxX', 'XyyyyyyyyyyyyyyyyyyyyyyyyyX')
+ call assert_match("Expected 'X\\\\\\[x occurs 21 times]X' but got 'X\\\\\\[y occurs 25 times]X'", v:errors[0])
+ call remove(v:errors, 0)
+endfunc
+
func Test_assert_equalfile()
call assert_equal(1, assert_equalfile('abcabc', 'xyzxyz'))
call assert_match("E485: Can't read file abcabc", v:errors[0])
@@ -46,17 +96,129 @@ func Test_assert_equalfile()
call delete('Xtwo')
endfunc
+func Test_assert_notequal()
+ let n = 4
+ call assert_equal(0, assert_notequal('foo', n))
+ let s = 'foo'
+ call assert_equal(0, assert_notequal([1, 2, 3], s))
+
+ call assert_equal(1, assert_notequal('foo', s))
+ call assert_match("Expected not equal to 'foo'", v:errors[0])
+ call remove(v:errors, 0)
+endfunc
+
+func Test_assert_report()
+ call assert_equal(1, assert_report('something is wrong'))
+ call assert_match('something is wrong', v:errors[0])
+ call remove(v:errors, 0)
+ call assert_equal(1, 'also wrong'->assert_report())
+ call assert_match('also wrong', v:errors[0])
+ call remove(v:errors, 0)
+endfunc
+
+func Test_assert_exception()
+ try
+ nocommand
+ catch
+ call assert_equal(0, assert_exception('E492:'))
+ endtry
+
+ try
+ nocommand
+ catch
+ try
+ " illegal argument, get NULL for error
+ call assert_equal(1, assert_exception([]))
+ catch
+ call assert_equal(0, assert_exception('E730:'))
+ endtry
+ endtry
+endfunc
+
+func Test_wrong_error_type()
+ let save_verrors = v:errors
+ let v:['errors'] = {'foo': 3}
+ call assert_equal('yes', 'no')
+ let verrors = v:errors
+ let v:errors = save_verrors
+ call assert_equal(type([]), type(verrors))
+endfunc
+
+func Test_match()
+ call assert_equal(0, assert_match('^f.*b.*r$', 'foobar'))
+
+ call assert_equal(1, assert_match('bar.*foo', 'foobar'))
+ call assert_match("Pattern 'bar.*foo' does not match 'foobar'", v:errors[0])
+ call remove(v:errors, 0)
+
+ call assert_equal(1, assert_match('bar.*foo', 'foobar', 'wrong'))
+ call assert_match('wrong', v:errors[0])
+ call remove(v:errors, 0)
+
+ call assert_equal(1, 'foobar'->assert_match('bar.*foo', 'wrong'))
+ call assert_match('wrong', v:errors[0])
+ call remove(v:errors, 0)
+endfunc
+
+func Test_notmatch()
+ call assert_equal(0, assert_notmatch('foo', 'bar'))
+ call assert_equal(0, assert_notmatch('^foobar$', 'foobars'))
+
+ call assert_equal(1, assert_notmatch('foo', 'foobar'))
+ call assert_match("Pattern 'foo' does match 'foobar'", v:errors[0])
+ call remove(v:errors, 0)
+
+ call assert_equal(1, 'foobar'->assert_notmatch('foo'))
+ call assert_match("Pattern 'foo' does match 'foobar'", v:errors[0])
+ call remove(v:errors, 0)
+endfunc
+
+func Test_assert_fail_fails()
+ call assert_equal(1, assert_fails('xxx', 'E12345'))
+ call assert_match("Expected 'E12345' but got 'E492:", v:errors[0])
+ call remove(v:errors, 0)
+
+ call assert_equal(1, assert_fails('xxx', 'E9876', 'stupid'))
+ call assert_match("stupid: Expected 'E9876' but got 'E492:", v:errors[0])
+ call remove(v:errors, 0)
+
+ call assert_equal(1, assert_fails('echo', '', 'echo command'))
+ call assert_match("command did not fail: echo command", v:errors[0])
+ call remove(v:errors, 0)
+
+ call assert_equal(1, 'echo'->assert_fails('', 'echo command'))
+ call assert_match("command did not fail: echo command", v:errors[0])
+ call remove(v:errors, 0)
+endfunc
+
func Test_assert_fails_in_try_block()
try
call assert_equal(0, assert_fails('throw "error"'))
endtry
endfunc
+func Test_assert_beeps()
+ new
+ call assert_equal(0, assert_beeps('normal h'))
+
+ call assert_equal(1, assert_beeps('normal 0'))
+ call assert_match("command did not beep: normal 0", v:errors[0])
+ call remove(v:errors, 0)
+
+ call assert_equal(0, 'normal h'->assert_beeps())
+ call assert_equal(1, 'normal 0'->assert_beeps())
+ call assert_match("command did not beep: normal 0", v:errors[0])
+ call remove(v:errors, 0)
+
+ bwipe
+endfunc
+
func Test_assert_inrange()
call assert_equal(0, assert_inrange(7, 7, 7))
call assert_equal(0, assert_inrange(5, 7, 5))
call assert_equal(0, assert_inrange(5, 7, 6))
call assert_equal(0, assert_inrange(5, 7, 7))
+
call assert_equal(1, assert_inrange(5, 7, 4))
call assert_match("Expected range 5 - 7, but got 4", v:errors[0])
call remove(v:errors, 0)
@@ -64,6 +226,12 @@ func Test_assert_inrange()
call assert_match("Expected range 5 - 7, but got 8", v:errors[0])
call remove(v:errors, 0)
+ call assert_equal(0, 5->assert_inrange(5, 7))
+ call assert_equal(0, 7->assert_inrange(5, 7))
+ call assert_equal(1, 8->assert_inrange(5, 7))
+ call assert_match("Expected range 5 - 7, but got 8", v:errors[0])
+ call remove(v:errors, 0)
+
call assert_fails('call assert_inrange(1, 1)', 'E119:')
if has('float')
@@ -83,6 +251,12 @@ func Test_assert_inrange()
endif
endfunc
+func Test_assert_with_msg()
+ call assert_equal('foo', 'bar', 'testing')
+ call assert_match("testing: Expected 'foo' but got 'bar'", v:errors[0])
+ call remove(v:errors, 0)
+endfunc
+
" Must be last.
func Test_zz_quit_detected()
" Verify that if a test function ends Vim the test script detects this.
diff --git a/src/nvim/testdir/test_cdo.vim b/src/nvim/testdir/test_cdo.vim
new file mode 100644
index 0000000000..aa2e4f1a8c
--- /dev/null
+++ b/src/nvim/testdir/test_cdo.vim
@@ -0,0 +1,205 @@
+" Tests for the :cdo, :cfdo, :ldo and :lfdo commands
+
+if !has('quickfix')
+ throw 'Skipped: quickfix feature missing'
+endif
+
+" Create the files used by the tests
+function SetUp()
+ call writefile(["Line1", "Line2", "Line3"], 'Xtestfile1')
+ call writefile(["Line1", "Line2", "Line3"], 'Xtestfile2')
+ call writefile(["Line1", "Line2", "Line3"], 'Xtestfile3')
+endfunction
+
+" Remove the files used by the tests
+function TearDown()
+ call delete('Xtestfile1')
+ call delete('Xtestfile2')
+ call delete('Xtestfile3')
+endfunction
+
+" Returns the current line in '<filename> <linenum>L <column>C' format
+function GetRuler()
+ return expand('%') . ' ' . line('.') . 'L' . ' ' . col('.') . 'C'
+endfunction
+
+" Tests for the :cdo and :ldo commands
+function XdoTests(cchar)
+ enew
+
+ " Shortcuts for calling the cdo and ldo commands
+ let Xdo = a:cchar . 'do'
+ let Xgetexpr = a:cchar . 'getexpr'
+ let Xprev = a:cchar. 'prev'
+ let XdoCmd = Xdo . ' call add(l, GetRuler())'
+
+ " Try with an empty list
+ let l = []
+ exe XdoCmd
+ call assert_equal([], l)
+
+ " Populate the list and then try
+ exe Xgetexpr . " ['non-error 1', 'Xtestfile1:1:3:Line1', 'non-error 2', 'Xtestfile2:2:2:Line2', 'non-error 3', 'Xtestfile3:3:1:Line3']"
+
+ let l = []
+ exe XdoCmd
+ call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 3L 1C'], l)
+
+ " Run command only on selected error lines
+ let l = []
+ enew
+ exe "2,3" . XdoCmd
+ call assert_equal(['Xtestfile2 2L 2C', 'Xtestfile3 3L 1C'], l)
+
+ " Boundary condition tests
+ let l = []
+ enew
+ exe "1,1" . XdoCmd
+ call assert_equal(['Xtestfile1 1L 3C'], l)
+
+ let l = []
+ enew
+ exe "3" . XdoCmd
+ call assert_equal(['Xtestfile3 3L 1C'], l)
+
+ " Range test commands
+ let l = []
+ enew
+ exe "%" . XdoCmd
+ call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 3L 1C'], l)
+
+ let l = []
+ enew
+ exe "1,$" . XdoCmd
+ call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 3L 1C'], l)
+
+ let l = []
+ enew
+ exe Xprev
+ exe "." . XdoCmd
+ call assert_equal(['Xtestfile2 2L 2C'], l)
+
+ let l = []
+ enew
+ exe "+" . XdoCmd
+ call assert_equal(['Xtestfile3 3L 1C'], l)
+
+ " Invalid error lines test
+ let l = []
+ enew
+ exe "silent! 27" . XdoCmd
+ exe "silent! 4,5" . XdoCmd
+ call assert_equal([], l)
+
+ " Run commands from an unsaved buffer
+ let v:errmsg=''
+ let l = []
+ enew
+ setlocal modified
+ exe "silent! 2,2" . XdoCmd
+ if v:errmsg !~# 'No write since last change'
+ call add(v:errors, 'Unsaved file change test failed')
+ endif
+
+ " If the executed command fails, then the operation should be aborted
+ enew!
+ let subst_count = 0
+ exe "silent!" . Xdo . " s/Line/xLine/ | let subst_count += 1"
+ if subst_count != 1 || getline('.') != 'xLine1'
+ call add(v:errors, 'Abort command on error test failed')
+ endif
+
+ let l = []
+ exe "2,2" . Xdo . "! call add(l, GetRuler())"
+ call assert_equal(['Xtestfile2 2L 2C'], l)
+
+ " List with no valid error entries
+ let l = []
+ edit! +2 Xtestfile1
+ exe Xgetexpr . " ['non-error 1', 'non-error 2', 'non-error 3']"
+ exe XdoCmd
+ call assert_equal([], l)
+ exe "silent! 2" . XdoCmd
+ call assert_equal([], l)
+ let v:errmsg=''
+ exe "%" . XdoCmd
+ exe "1,$" . XdoCmd
+ exe "." . XdoCmd
+ call assert_equal('', v:errmsg)
+
+ " List with only one valid entry
+ let l = []
+ exe Xgetexpr . " ['Xtestfile3:3:1:Line3']"
+ exe XdoCmd
+ call assert_equal(['Xtestfile3 3L 1C'], l)
+
+endfunction
+
+" Tests for the :cfdo and :lfdo commands
+function XfdoTests(cchar)
+ enew
+
+ " Shortcuts for calling the cfdo and lfdo commands
+ let Xfdo = a:cchar . 'fdo'
+ let Xgetexpr = a:cchar . 'getexpr'
+ let XfdoCmd = Xfdo . ' call add(l, GetRuler())'
+ let Xpfile = a:cchar. 'pfile'
+
+ " Clear the quickfix/location list
+ exe Xgetexpr . " []"
+
+ " Try with an empty list
+ let l = []
+ exe XfdoCmd
+ call assert_equal([], l)
+
+ " Populate the list and then try
+ exe Xgetexpr . " ['non-error 1', 'Xtestfile1:1:3:Line1', 'Xtestfile1:2:1:Line2', 'non-error 2', 'Xtestfile2:2:2:Line2', 'non-error 3', 'Xtestfile3:2:3:Line2', 'Xtestfile3:3:1:Line3']"
+
+ let l = []
+ exe XfdoCmd
+ call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 2L 3C'], l)
+
+ " Run command only on selected error lines
+ let l = []
+ exe "2,3" . XfdoCmd
+ call assert_equal(['Xtestfile2 2L 2C', 'Xtestfile3 2L 3C'], l)
+
+ " Boundary condition tests
+ let l = []
+ exe "3" . XfdoCmd
+ call assert_equal(['Xtestfile3 2L 3C'], l)
+
+ " Range test commands
+ let l = []
+ exe "%" . XfdoCmd
+ call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 2L 3C'], l)
+
+ let l = []
+ exe "1,$" . XfdoCmd
+ call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 2L 3C'], l)
+
+ let l = []
+ exe Xpfile
+ exe "." . XfdoCmd
+ call assert_equal(['Xtestfile2 2L 2C'], l)
+
+ " List with only one valid entry
+ let l = []
+ exe Xgetexpr . " ['Xtestfile2:2:5:Line2']"
+ exe XfdoCmd
+ call assert_equal(['Xtestfile2 2L 5C'], l)
+
+endfunction
+
+" Tests for cdo and cfdo
+function Test_cdo()
+ call XdoTests('c')
+ call XfdoTests('c')
+endfunction
+
+" Tests for ldo and lfdo
+function Test_ldo()
+ call XdoTests('l')
+ call XfdoTests('l')
+endfunction
diff --git a/src/nvim/testdir/test_cursor_func.vim b/src/nvim/testdir/test_cursor_func.vim
index 47e74a24d6..57825b4551 100644
--- a/src/nvim/testdir/test_cursor_func.vim
+++ b/src/nvim/testdir/test_cursor_func.vim
@@ -123,11 +123,18 @@ func Test_screenpos_number()
bwipe!
endfunc
+" Save the visual start character position
func SaveVisualStartCharPos()
call add(g:VisualStartPos, getcharpos('v'))
return ''
endfunc
+" Save the current cursor character position in insert mode
+func SaveInsertCurrentCharPos()
+ call add(g:InsertCurrentPos, getcharpos('.'))
+ return ''
+endfunc
+
" Test for the getcharpos() function
func Test_getcharpos()
call assert_fails('call getcharpos({})', 'E731:')
@@ -156,16 +163,29 @@ func Test_getcharpos()
vnoremap <expr> <F3> SaveVisualStartCharPos()
let g:VisualStartPos = []
exe "normal 2G6lv$\<F3>ohh\<F3>o\<F3>"
- call assert_equal([[0, 2, 7, 0], [0, 2, 9, 0], [0, 2, 5, 0]], g:VisualStartPos)
+ call assert_equal([[0, 2, 7, 0], [0, 2, 10, 0], [0, 2, 5, 0]], g:VisualStartPos)
call assert_equal([0, 2, 9, 0], getcharpos('v'))
let g:VisualStartPos = []
exe "normal 3Gv$\<F3>o\<F3>"
- call assert_equal([[0, 3, 1, 0], [0, 3, 1, 0]], g:VisualStartPos)
+ call assert_equal([[0, 3, 1, 0], [0, 3, 2, 0]], g:VisualStartPos)
let g:VisualStartPos = []
exe "normal 1Gv$\<F3>o\<F3>"
call assert_equal([[0, 1, 1, 0], [0, 1, 1, 0]], g:VisualStartPos)
vunmap <F3>
+ " Test for getting the position in insert mode with the cursor after the
+ " last character in a line
+ inoremap <expr> <F3> SaveInsertCurrentCharPos()
+ let g:InsertCurrentPos = []
+ exe "normal 1GA\<F3>"
+ exe "normal 2GA\<F3>"
+ exe "normal 3GA\<F3>"
+ exe "normal 4GA\<F3>"
+ exe "normal 2G6li\<F3>"
+ call assert_equal([[0, 1, 1, 0], [0, 2, 10, 0], [0, 3, 2, 0], [0, 4, 10, 0],
+ \ [0, 2, 7, 0]], g:InsertCurrentPos)
+ iunmap <F3>
+
%bw!
endfunc
@@ -192,6 +212,10 @@ func Test_setcharpos()
call setcharpos("'m", [0, 2, 9, 0])
normal `m
call assert_equal([2, 11], [line('.'), col('.')])
+ " unload the buffer and try to set the mark
+ let bnr = bufnr()
+ enew!
+ call assert_equal(-1, setcharpos("'m", [bnr, 2, 2, 0]))
%bw!
call assert_equal(-1, setcharpos('.', [10, 3, 1, 0]))
@@ -202,6 +226,11 @@ func SaveVisualStartCharCol()
return ''
endfunc
+func SaveInsertCurrentCharCol()
+ call add(g:InsertCurrentCol, charcol('.'))
+ return ''
+endfunc
+
" Test for the charcol() function
func Test_charcol()
call assert_fails('call charcol({})', 'E731:')
@@ -239,19 +268,36 @@ func Test_charcol()
vnoremap <expr> <F3> SaveVisualStartCharCol()
let g:VisualStartCol = []
exe "normal 2G6lv$\<F3>ohh\<F3>o\<F3>"
- call assert_equal([7, 9, 5], g:VisualStartCol)
+ call assert_equal([7, 10, 5], g:VisualStartCol)
call assert_equal(9, charcol('v'))
let g:VisualStartCol = []
exe "normal 3Gv$\<F3>o\<F3>"
- call assert_equal([1, 1], g:VisualStartCol)
+ call assert_equal([1, 2], g:VisualStartCol)
let g:VisualStartCol = []
exe "normal 1Gv$\<F3>o\<F3>"
call assert_equal([1, 1], g:VisualStartCol)
vunmap <F3>
+ " Test for getting the column number in insert mode with the cursor after
+ " the last character in a line
+ inoremap <expr> <F3> SaveInsertCurrentCharCol()
+ let g:InsertCurrentCol = []
+ exe "normal 1GA\<F3>"
+ exe "normal 2GA\<F3>"
+ exe "normal 3GA\<F3>"
+ exe "normal 4GA\<F3>"
+ exe "normal 2G6li\<F3>"
+ call assert_equal([1, 10, 2, 10, 7], g:InsertCurrentCol)
+ iunmap <F3>
+
%bw!
endfunc
+func SaveInsertCursorCharPos()
+ call add(g:InsertCursorPos, getcursorcharpos('.'))
+ return ''
+endfunc
+
" Test for getcursorcharpos()
func Test_getcursorcharpos()
call assert_equal(getcursorcharpos(), getcursorcharpos(0))
@@ -269,6 +315,19 @@ func Test_getcursorcharpos()
normal 4G9l
call assert_equal([0, 4, 9, 0, 9], getcursorcharpos())
+ " Test for getting the cursor position in insert mode with the cursor after
+ " the last character in a line
+ inoremap <expr> <F3> SaveInsertCursorCharPos()
+ let g:InsertCursorPos = []
+ exe "normal 1GA\<F3>"
+ exe "normal 2GA\<F3>"
+ exe "normal 3GA\<F3>"
+ exe "normal 4GA\<F3>"
+ exe "normal 2G6li\<F3>"
+ call assert_equal([[0, 1, 1, 0, 1], [0, 2, 10, 0, 15], [0, 3, 2, 0, 2],
+ \ [0, 4, 10, 0, 10], [0, 2, 7, 0, 12]], g:InsertCursorPos)
+ iunmap <F3>
+
let winid = win_getid()
normal 2G5l
wincmd w
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 4ef35b3a46..b663032c24 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -435,6 +435,7 @@ let s:filename_checks = {
\ 'readline': ['.inputrc', 'inputrc'],
\ 'remind': ['.reminders', 'file.remind', 'file.rem', '.reminders-file'],
\ 'rego': ['file.rego'],
+ \ 'rescript': ['file.res', 'file.resi'],
\ 'resolv': ['resolv.conf'],
\ 'reva': ['file.frt'],
\ 'rexx': ['file.rex', 'file.orx', 'file.rxo', 'file.rxj', 'file.jrexx', 'file.rexxj', 'file.rexx', 'file.testGroup', 'file.testUnit'],
diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim
index 7d1fed3b94..8612b7013b 100644
--- a/src/nvim/testdir/test_options.vim
+++ b/src/nvim/testdir/test_options.vim
@@ -314,21 +314,50 @@ func Test_set_errors()
set modifiable&
endfunc
+func CheckWasSet(name)
+ let verb_cm = execute('verbose set ' .. a:name .. '?')
+ call assert_match('Last set from.*test_options.vim', verb_cm)
+endfunc
+func CheckWasNotSet(name)
+ let verb_cm = execute('verbose set ' .. a:name .. '?')
+ call assert_notmatch('Last set from', verb_cm)
+endfunc
+
" Must be executed before other tests that set 'term'.
func Test_000_term_option_verbose()
if has('nvim') || has('gui_running')
return
endif
- let verb_cm = execute('verbose set t_cm')
- call assert_notmatch('Last set from', verb_cm)
+
+ call CheckWasNotSet('t_cm')
let term_save = &term
set term=ansi
- let verb_cm = execute('verbose set t_cm')
- call assert_match('Last set from.*test_options.vim', verb_cm)
+ call CheckWasSet('t_cm')
let &term = term_save
endfunc
+func Test_copy_context()
+ setlocal list
+ call CheckWasSet('list')
+ split
+ call CheckWasSet('list')
+ quit
+ setlocal nolist
+
+ set ai
+ call CheckWasSet('ai')
+ set filetype=perl
+ call CheckWasSet('filetype')
+ set fo=tcroq
+ call CheckWasSet('fo')
+
+ split Xsomebuf
+ call CheckWasSet('ai')
+ call CheckWasNotSet('filetype')
+ call CheckWasSet('fo')
+endfunc
+
func Test_set_ttytype()
" Nvim does not support 'ttytype'.
if !has('nvim') && !has('gui_running') && has('unix')
diff --git a/src/nvim/testdir/test_packadd.vim b/src/nvim/testdir/test_packadd.vim
new file mode 100644
index 0000000000..fcb8b8033b
--- /dev/null
+++ b/src/nvim/testdir/test_packadd.vim
@@ -0,0 +1,361 @@
+" Tests for 'packpath' and :packadd
+
+
+func SetUp()
+ let s:topdir = getcwd() . '/Xdir'
+ exe 'set packpath=' . s:topdir
+ let s:plugdir = s:topdir . '/pack/mine/opt/mytest'
+endfunc
+
+func TearDown()
+ call delete(s:topdir, 'rf')
+endfunc
+
+func Test_packadd()
+ if !exists('s:plugdir')
+ echomsg 'when running this test manually, call SetUp() first'
+ return
+ endif
+
+ call mkdir(s:plugdir . '/plugin/also', 'p')
+ call mkdir(s:plugdir . '/ftdetect', 'p')
+ call mkdir(s:plugdir . '/after', 'p')
+ set rtp&
+ let rtp = &rtp
+ filetype on
+
+ let rtp_entries = split(rtp, ',')
+ for entry in rtp_entries
+ if entry =~? '\<after\>'
+ let first_after_entry = entry
+ break
+ endif
+ endfor
+
+ exe 'split ' . s:plugdir . '/plugin/test.vim'
+ call setline(1, 'let g:plugin_works = 42')
+ wq
+
+ exe 'split ' . s:plugdir . '/plugin/also/loaded.vim'
+ call setline(1, 'let g:plugin_also_works = 77')
+ wq
+
+ exe 'split ' . s:plugdir . '/ftdetect/test.vim'
+ call setline(1, 'let g:ftdetect_works = 17')
+ wq
+
+ packadd mytest
+
+ call assert_equal(42, g:plugin_works)
+ call assert_equal(77, g:plugin_also_works)
+ call assert_equal(17, g:ftdetect_works)
+ call assert_true(len(&rtp) > len(rtp))
+ call assert_match('/testdir/Xdir/pack/mine/opt/mytest\($\|,\)', &rtp)
+
+ let new_after = match(&rtp, '/testdir/Xdir/pack/mine/opt/mytest/after,')
+ let forwarded = substitute(first_after_entry, '\\', '[/\\\\]', 'g')
+ let old_after = match(&rtp, ',' . forwarded . '\>')
+ call assert_true(new_after > 0, 'rtp is ' . &rtp)
+ call assert_true(old_after > 0, 'match ' . forwarded . ' in ' . &rtp)
+ call assert_true(new_after < old_after, 'rtp is ' . &rtp)
+
+ " NOTE: '/.../opt/myte' forwardly matches with '/.../opt/mytest'
+ call mkdir(fnamemodify(s:plugdir, ':h') . '/myte', 'p')
+ let rtp = &rtp
+ packadd myte
+
+ " Check the path of 'myte' is added
+ call assert_true(len(&rtp) > len(rtp))
+ call assert_match('/testdir/Xdir/pack/mine/opt/myte\($\|,\)', &rtp)
+
+ " Check exception
+ call assert_fails("packadd directorynotfound", 'E919:')
+ call assert_fails("packadd", 'E471:')
+endfunc
+
+func Test_packadd_start()
+ let plugdir = s:topdir . '/pack/mine/start/other'
+ call mkdir(plugdir . '/plugin', 'p')
+ set rtp&
+ let rtp = &rtp
+ filetype on
+
+ exe 'split ' . plugdir . '/plugin/test.vim'
+ call setline(1, 'let g:plugin_works = 24')
+ wq
+
+ packadd other
+
+ call assert_equal(24, g:plugin_works)
+ call assert_true(len(&rtp) > len(rtp))
+ call assert_match('/testdir/Xdir/pack/mine/start/other\($\|,\)', &rtp)
+endfunc
+
+func Test_packadd_noload()
+ call mkdir(s:plugdir . '/plugin', 'p')
+ call mkdir(s:plugdir . '/syntax', 'p')
+ set rtp&
+ let rtp = &rtp
+
+ exe 'split ' . s:plugdir . '/plugin/test.vim'
+ call setline(1, 'let g:plugin_works = 42')
+ wq
+ let g:plugin_works = 0
+
+ packadd! mytest
+
+ call assert_true(len(&rtp) > len(rtp))
+ call assert_match('testdir/Xdir/pack/mine/opt/mytest\($\|,\)', &rtp)
+ call assert_equal(0, g:plugin_works)
+
+ " check the path is not added twice
+ let new_rtp = &rtp
+ packadd! mytest
+ call assert_equal(new_rtp, &rtp)
+endfunc
+
+func Test_packadd_symlink_dir()
+ if !has('unix')
+ return
+ endif
+ let top2_dir = s:topdir . '/Xdir2'
+ let real_dir = s:topdir . '/Xsym'
+ call mkdir(real_dir, 'p')
+ exec "silent !ln -s Xsym" top2_dir
+ let &rtp = top2_dir . ',' . top2_dir . '/after'
+ let &packpath = &rtp
+
+ let s:plugdir = top2_dir . '/pack/mine/opt/mytest'
+ call mkdir(s:plugdir . '/plugin', 'p')
+
+ exe 'split ' . s:plugdir . '/plugin/test.vim'
+ call setline(1, 'let g:plugin_works = 44')
+ wq
+ let g:plugin_works = 0
+
+ packadd mytest
+
+ " Must have been inserted in the middle, not at the end
+ call assert_match('/pack/mine/opt/mytest,', &rtp)
+ call assert_equal(44, g:plugin_works)
+
+ " No change when doing it again.
+ let rtp_before = &rtp
+ packadd mytest
+ call assert_equal(rtp_before, &rtp)
+
+ set rtp&
+ let rtp = &rtp
+ exec "silent !rm" top2_dir
+endfunc
+
+func Test_packadd_symlink_dir2()
+ if !has('unix')
+ return
+ endif
+ let top2_dir = s:topdir . '/Xdir2'
+ let real_dir = s:topdir . '/Xsym/pack'
+ call mkdir(top2_dir, 'p')
+ call mkdir(real_dir, 'p')
+ let &rtp = top2_dir . ',' . top2_dir . '/after'
+ let &packpath = &rtp
+
+ exec "silent !ln -s ../Xsym/pack" top2_dir . '/pack'
+ let s:plugdir = top2_dir . '/pack/mine/opt/mytest'
+ call mkdir(s:plugdir . '/plugin', 'p')
+
+ exe 'split ' . s:plugdir . '/plugin/test.vim'
+ call setline(1, 'let g:plugin_works = 48')
+ wq
+ let g:plugin_works = 0
+
+ packadd mytest
+
+ " Must have been inserted in the middle, not at the end
+ call assert_match('/Xdir2/pack/mine/opt/mytest,', &rtp)
+ call assert_equal(48, g:plugin_works)
+
+ " No change when doing it again.
+ let rtp_before = &rtp
+ packadd mytest
+ call assert_equal(rtp_before, &rtp)
+
+ set rtp&
+ let rtp = &rtp
+ exec "silent !rm" top2_dir . '/pack'
+ exec "silent !rmdir" top2_dir
+endfunc
+
+" Check command-line completion for 'packadd'
+func Test_packadd_completion()
+ let optdir1 = &packpath . '/pack/mine/opt'
+ let optdir2 = &packpath . '/pack/candidate/opt'
+
+ call mkdir(optdir1 . '/pluginA', 'p')
+ call mkdir(optdir1 . '/pluginC', 'p')
+ call mkdir(optdir2 . '/pluginB', 'p')
+ call mkdir(optdir2 . '/pluginC', 'p')
+
+ let li = []
+ call feedkeys(":packadd \<Tab>')\<C-B>call add(li, '\<CR>", 't')
+ call feedkeys(":packadd " . repeat("\<Tab>", 2) . "')\<C-B>call add(li, '\<CR>", 't')
+ call feedkeys(":packadd " . repeat("\<Tab>", 3) . "')\<C-B>call add(li, '\<CR>", 't')
+ call feedkeys(":packadd " . repeat("\<Tab>", 4) . "')\<C-B>call add(li, '\<CR>", 'tx')
+ call assert_equal("packadd pluginA", li[0])
+ call assert_equal("packadd pluginB", li[1])
+ call assert_equal("packadd pluginC", li[2])
+ call assert_equal("packadd ", li[3])
+endfunc
+
+func Test_packloadall()
+ " plugin foo with an autoload directory
+ let fooplugindir = &packpath . '/pack/mine/start/foo/plugin'
+ call mkdir(fooplugindir, 'p')
+ call writefile(['let g:plugin_foo_number = 1234',
+ \ 'let g:plugin_foo_auto = bbb#value',
+ \ 'let g:plugin_extra_auto = extra#value'], fooplugindir . '/bar.vim')
+ let fooautodir = &packpath . '/pack/mine/start/foo/autoload'
+ call mkdir(fooautodir, 'p')
+ call writefile(['let bar#value = 77'], fooautodir . '/bar.vim')
+
+ " plugin aaa with an autoload directory
+ let aaaplugindir = &packpath . '/pack/mine/start/aaa/plugin'
+ call mkdir(aaaplugindir, 'p')
+ call writefile(['let g:plugin_aaa_number = 333',
+ \ 'let g:plugin_aaa_auto = bar#value'], aaaplugindir . '/bbb.vim')
+ let aaaautodir = &packpath . '/pack/mine/start/aaa/autoload'
+ call mkdir(aaaautodir, 'p')
+ call writefile(['let bbb#value = 55'], aaaautodir . '/bbb.vim')
+
+ " plugin extra with only an autoload directory
+ let extraautodir = &packpath . '/pack/mine/start/extra/autoload'
+ call mkdir(extraautodir, 'p')
+ call writefile(['let extra#value = 99'], extraautodir . '/extra.vim')
+
+ packloadall
+ call assert_equal(1234, g:plugin_foo_number)
+ call assert_equal(55, g:plugin_foo_auto)
+ call assert_equal(99, g:plugin_extra_auto)
+ call assert_equal(333, g:plugin_aaa_number)
+ call assert_equal(77, g:plugin_aaa_auto)
+
+ " only works once
+ call writefile(['let g:plugin_bar_number = 4321'], fooplugindir . '/bar2.vim')
+ packloadall
+ call assert_false(exists('g:plugin_bar_number'))
+
+ " works when ! used
+ packloadall!
+ call assert_equal(4321, g:plugin_bar_number)
+endfunc
+
+func Test_helptags()
+ let docdir1 = &packpath . '/pack/mine/start/foo/doc'
+ let docdir2 = &packpath . '/pack/mine/start/bar/doc'
+ call mkdir(docdir1, 'p')
+ call mkdir(docdir2, 'p')
+ call writefile(['look here: *look-here*'], docdir1 . '/bar.txt')
+ call writefile(['look away: *look-away*'], docdir2 . '/foo.txt')
+ exe 'set rtp=' . &packpath . '/pack/mine/start/foo,' . &packpath . '/pack/mine/start/bar'
+
+ helptags ALL
+
+ let tags1 = readfile(docdir1 . '/tags')
+ call assert_match('look-here', tags1[0])
+ let tags2 = readfile(docdir2 . '/tags')
+ call assert_match('look-away', tags2[0])
+
+ call assert_fails('helptags abcxyz', 'E150:')
+endfunc
+
+func Test_colorscheme()
+ let colordirrun = &packpath . '/runtime/colors'
+ let colordirstart = &packpath . '/pack/mine/start/foo/colors'
+ let colordiropt = &packpath . '/pack/mine/opt/bar/colors'
+ call mkdir(colordirrun, 'p')
+ call mkdir(colordirstart, 'p')
+ call mkdir(colordiropt, 'p')
+ call writefile(['let g:found_one = 1'], colordirrun . '/one.vim')
+ call writefile(['let g:found_two = 1'], colordirstart . '/two.vim')
+ call writefile(['let g:found_three = 1'], colordiropt . '/three.vim')
+ exe 'set rtp=' . &packpath . '/runtime'
+
+ colorscheme one
+ call assert_equal(1, g:found_one)
+ colorscheme two
+ call assert_equal(1, g:found_two)
+ colorscheme three
+ call assert_equal(1, g:found_three)
+endfunc
+
+func Test_colorscheme_completion()
+ let colordirrun = &packpath . '/runtime/colors'
+ let colordirstart = &packpath . '/pack/mine/start/foo/colors'
+ let colordiropt = &packpath . '/pack/mine/opt/bar/colors'
+ call mkdir(colordirrun, 'p')
+ call mkdir(colordirstart, 'p')
+ call mkdir(colordiropt, 'p')
+ call writefile(['let g:found_one = 1'], colordirrun . '/one.vim')
+ call writefile(['let g:found_two = 1'], colordirstart . '/two.vim')
+ call writefile(['let g:found_three = 1'], colordiropt . '/three.vim')
+ exe 'set rtp=' . &packpath . '/runtime'
+
+ let li=[]
+ call feedkeys(":colorscheme " . repeat("\<Tab>", 1) . "')\<C-B>call add(li, '\<CR>", 't')
+ call feedkeys(":colorscheme " . repeat("\<Tab>", 2) . "')\<C-B>call add(li, '\<CR>", 't')
+ call feedkeys(":colorscheme " . repeat("\<Tab>", 3) . "')\<C-B>call add(li, '\<CR>", 't')
+ call feedkeys(":colorscheme " . repeat("\<Tab>", 4) . "')\<C-B>call add(li, '\<CR>", 'tx')
+ call assert_equal("colorscheme one", li[0])
+ call assert_equal("colorscheme three", li[1])
+ call assert_equal("colorscheme two", li[2])
+ call assert_equal("colorscheme ", li[3])
+endfunc
+
+func Test_runtime()
+ let rundir = &packpath . '/runtime/extra'
+ let startdir = &packpath . '/pack/mine/start/foo/extra'
+ let optdir = &packpath . '/pack/mine/opt/bar/extra'
+ call mkdir(rundir, 'p')
+ call mkdir(startdir, 'p')
+ call mkdir(optdir, 'p')
+ call writefile(['let g:sequence .= "run"'], rundir . '/bar.vim')
+ call writefile(['let g:sequence .= "start"'], startdir . '/bar.vim')
+ call writefile(['let g:sequence .= "foostart"'], startdir . '/foo.vim')
+ call writefile(['let g:sequence .= "opt"'], optdir . '/bar.vim')
+ call writefile(['let g:sequence .= "xxxopt"'], optdir . '/xxx.vim')
+ exe 'set rtp=' . &packpath . '/runtime'
+
+ let g:sequence = ''
+ runtime extra/bar.vim
+ call assert_equal('run', g:sequence)
+ let g:sequence = ''
+ runtime START extra/bar.vim
+ call assert_equal('start', g:sequence)
+ let g:sequence = ''
+ runtime OPT extra/bar.vim
+ call assert_equal('opt', g:sequence)
+ let g:sequence = ''
+ runtime PACK extra/bar.vim
+ call assert_equal('start', g:sequence)
+ let g:sequence = ''
+ runtime! PACK extra/bar.vim
+ call assert_equal('startopt', g:sequence)
+ let g:sequence = ''
+ runtime PACK extra/xxx.vim
+ call assert_equal('xxxopt', g:sequence)
+
+ let g:sequence = ''
+ runtime ALL extra/bar.vim
+ call assert_equal('run', g:sequence)
+ let g:sequence = ''
+ runtime ALL extra/foo.vim
+ call assert_equal('foostart', g:sequence)
+ let g:sequence = ''
+ runtime! ALL extra/xxx.vim
+ call assert_equal('xxxopt', g:sequence)
+ let g:sequence = ''
+ runtime! ALL extra/bar.vim
+ call assert_equal('runstartopt', g:sequence)
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_retab.vim b/src/nvim/testdir/test_retab.vim
index e7b8946ccf..1650a03876 100644
--- a/src/nvim/testdir/test_retab.vim
+++ b/src/nvim/testdir/test_retab.vim
@@ -69,6 +69,8 @@ func Test_retab()
call assert_equal(" a b c ", Retab('!', 3))
call assert_equal(" a b c ", Retab('', 5))
call assert_equal(" a b c ", Retab('!', 5))
+
+ set tabstop& expandtab&
endfunc
func Test_retab_error()
@@ -78,3 +80,22 @@ func Test_retab_error()
call assert_fails('ret 10000', 'E475:')
call assert_fails('ret 80000000000000000000', 'E475:')
endfunc
+
+func Test_retab_endless()
+ new
+ call setline(1, "\t0\t")
+ let caught = 'no'
+ try
+ while 1
+ set ts=4000
+ retab 4
+ endwhile
+ catch /E1240/
+ let caught = 'yes'
+ endtry
+ bwipe!
+ set tabstop&
+endfunc
+
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_winbuf_close.vim b/src/nvim/testdir/test_winbuf_close.vim
index 7f5b80e8d3..f4878c2397 100644
--- a/src/nvim/testdir/test_winbuf_close.vim
+++ b/src/nvim/testdir/test_winbuf_close.vim
@@ -194,3 +194,22 @@ func Test_tabwin_close()
call assert_true(v:true)
%bwipe!
endfunc
+
+" Test when closing a split window (above/below) restores space to the window
+" below when 'noequalalways' and 'splitright' are set.
+func Test_window_close_splitright_noequalalways()
+ set noequalalways
+ set splitright
+ new
+ let w1 = win_getid()
+ new
+ let w2 = win_getid()
+ execute "normal \<c-w>b"
+ let h = winheight(0)
+ let w = win_getid()
+ new
+ q
+ call assert_equal(h, winheight(0), "Window height does not match eight before opening and closing another window")
+ call assert_equal(w, win_getid(), "Did not return to original window after opening and closing a window")
+endfunc
+
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 4861b71995..e09af7a7bb 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -3079,9 +3079,21 @@ static frame_T *win_altframe(win_T *win, tabpage_T *tp)
return frp->fr_prev;
}
+ // By default the next window will get the space that was abandoned by this
+ // window
frame_T *target_fr = frp->fr_next;
frame_T *other_fr = frp->fr_prev;
- if (p_spr || p_sb) {
+
+ // If this is part of a column of windows and 'splitbelow' is true then the
+ // previous window will get the space.
+ if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_COL && p_sb) {
+ target_fr = frp->fr_prev;
+ other_fr = frp->fr_next;
+ }
+
+ // If this is part of a row of windows, and 'splitright' is true then the
+ // previous window will get the space.
+ if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_ROW && p_spr) {
target_fr = frp->fr_prev;
other_fr = frp->fr_next;
}
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index ccf3e81b22..5a387f3deb 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -898,6 +898,19 @@ describe('API', function()
command('lockvar lua')
eq('Key is locked: lua', pcall_err(meths.del_var, 'lua'))
eq('Key is locked: lua', pcall_err(meths.set_var, 'lua', 1))
+
+ -- Check if autoload works properly
+ local pathsep = helpers.get_pathsep()
+ local xconfig = 'Xhome' .. pathsep .. 'Xconfig'
+ local xdata = 'Xhome' .. pathsep .. 'Xdata'
+ local autoload_folder = table.concat({xconfig, 'nvim', 'autoload'}, pathsep)
+ local autoload_file = table.concat({autoload_folder , 'testload.vim'}, pathsep)
+ mkdir_p(autoload_folder)
+ write_file(autoload_file , [[let testload#value = 2]])
+
+ clear{ args_rm={'-u'}, env={ XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata } }
+ eq(2, meths.get_var('testload#value'))
+ rmdir('Xhome')
end)
it('nvim_get_vvar, nvim_set_vvar', function()
diff --git a/test/functional/legacy/assert_spec.lua b/test/functional/legacy/assert_spec.lua
index c2b22472bf..dd6a9d0bde 100644
--- a/test/functional/legacy/assert_spec.lua
+++ b/test/functional/legacy/assert_spec.lua
@@ -19,36 +19,10 @@ describe('assert function:', function()
clear()
end)
- describe('assert_beeps', function()
- it('works', function()
- call('assert_beeps', 'normal h')
- expected_empty()
- call('assert_beeps', 'normal 0')
- expected_errors({'command did not beep: normal 0'})
- end)
-
- it('can be used as a method', function()
- local tmpname = source [[
- call assert_equal(0, 'normal h'->assert_beeps())
- call assert_equal(1, 'normal 0'->assert_beeps())
- ]]
- expected_errors({tmpname .. ' line 2: command did not beep: normal 0'})
- end)
- end)
-
-- assert_equal({expected}, {actual}, [, {msg}])
describe('assert_equal', function()
it('should not change v:errors when expected is equal to actual', function()
source([[
- let s = 'foo'
- call assert_equal('foo', s)
- let n = 4
- call assert_equal(4, n)
- let l = [1, 2, 3]
- call assert_equal([1, 2, 3], l)
- call assert_equal(v:_null_list, v:_null_list)
- call assert_equal(v:_null_list, [])
- call assert_equal([], v:_null_list)
fu Func()
endfu
let F1 = function('Func')
@@ -98,30 +72,6 @@ describe('assert function:', function()
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
exc_exec('call CheckAssert()'))
end)
-
- it('can specify a message and get a message about what failed', function()
- call('assert_equal', 'foo', 'bar', 'testing')
- expected_errors({"testing: Expected 'foo' but got 'bar'"})
- end)
-
- it('should shorten a long message', function()
- call ('assert_equal', 'XxxxxxxxxxxxxxxxxxxxxxX', 'XyyyyyyyyyyyyyyyyyyyyyyyyyX')
- expected_errors({"Expected 'X\\[x occurs 21 times]X' but got 'X\\[y occurs 25 times]X'"})
- end)
- end)
-
- -- assert_notequal({expected}, {actual}[, {msg}])
- describe('assert_notequal', function()
- it('should not change v:errors when expected differs from actual', function()
- eq(0, call('assert_notequal', 'foo', 4))
- eq(0, call('assert_notequal', {1, 2, 3}, 'foo'))
- expected_empty()
- end)
-
- it('should change v:errors when expected is equal to actual', function()
- eq(1, call('assert_notequal', 'foo', 'foo'))
- expected_errors({"Expected not equal to 'foo'"})
- end)
end)
-- assert_false({actual}, [, {msg}])
@@ -141,14 +91,6 @@ describe('assert function:', function()
call('assert_false', {})
expected_errors({'Expected False but got []'})
end)
-
- it('can be used as a method', function()
- local tmpname = source [[
- call assert_equal(0, v:false->assert_false())
- call assert_equal(1, 123->assert_false())
- ]]
- expected_errors({tmpname .. ' line 2: Expected False but got 123'})
- end)
end)
-- assert_true({actual}, [, {msg}])
@@ -164,14 +106,6 @@ describe('assert function:', function()
eq(1, call('assert_true', 1.5))
expected_errors({'Expected True but got 1.5'})
end)
-
- it('can be used as a method', function()
- local tmpname = source [[
- call assert_equal(0, v:true->assert_true())
- call assert_equal(1, 0->assert_true())
- ]]
- expected_errors({tmpname .. ' line 2: Expected True but got 0'})
- end)
end)
describe('v:errors', function()
@@ -217,76 +151,10 @@ describe('assert function:', function()
tmpname_two .. " line 1: file two: Expected True but got ''",
})
end)
-
- it('is reset to a list by assert functions', function()
- source([[
- let save_verrors = v:errors
- let v:['errors'] = {'foo': 3}
- call assert_equal('yes', 'no')
- let verrors = v:errors
- let v:errors = save_verrors
- call assert_equal(type([]), type(verrors))
- ]])
- expected_empty()
- end)
- end)
-
- -- assert_match({pat}, {text}[, {msg}])
- describe('assert_match', function()
- it('should not change v:errors when pat matches text', function()
- call('assert_match', '^f.*b.*r$', 'foobar')
- expected_empty()
- end)
-
- it('should change v:errors when pat does not match text', function()
- call('assert_match', 'bar.*foo', 'foobar')
- expected_errors({"Pattern 'bar.*foo' does not match 'foobar'"})
- end)
-
- it('should set v:errors to msg when given and match fails', function()
- call('assert_match', 'bar.*foo', 'foobar', 'wrong')
- expected_errors({"wrong: Pattern 'bar.*foo' does not match 'foobar'"})
- end)
-
- it('can be used as a method', function()
- local tmpname = source [[
- call assert_equal(1, 'foobar'->assert_match('bar.*foo', 'wrong'))
- ]]
- expected_errors({
- tmpname .. " line 1: wrong: Pattern 'bar.*foo' does not match 'foobar'"
- })
- end)
- end)
-
- -- assert_notmatch({pat}, {text}[, {msg}])
- describe('assert_notmatch', function()
- it('should not change v:errors when pat does not match text', function()
- call('assert_notmatch', 'foo', 'bar')
- call('assert_notmatch', '^foobar$', 'foobars')
- expected_empty()
- end)
-
- it('should change v:errors when pat matches text', function()
- call('assert_notmatch', 'foo', 'foobar')
- expected_errors({"Pattern 'foo' does match 'foobar'"})
- end)
-
- it('can be used as a method', function()
- local tmpname = source [[
- call assert_equal(1, 'foobar'->assert_notmatch('foo'))
- ]]
- expected_errors({tmpname .. " line 1: Pattern 'foo' does match 'foobar'"})
- end)
end)
-- assert_fails({cmd}, [, {error}])
describe('assert_fails', function()
- it('should change v:errors when error does not match v:errmsg', function()
- eq(1, eval([[assert_fails('xxx', 'E12345')]]))
- command([[call assert_match("Expected 'E12345' but got 'E492:", v:errors[0])]])
- expected_errors({"Expected 'E12345' but got 'E492: Not an editor command: xxx': xxx"})
- end)
-
it('should not change v:errors when cmd errors', function()
eq(0, eval([[assert_fails('NonexistentCmd')]]))
expected_empty()
@@ -296,106 +164,5 @@ describe('assert function:', function()
eq(1, eval([[assert_fails('call empty("")', '')]]))
expected_errors({'command did not fail: call empty("")'})
end)
-
- it('can specify and get a message about what failed', function()
- eq(1, eval([[assert_fails('xxx', 'E9876', 'stupid')]]))
- command([[call assert_match("stupid: Expected 'E9876' but got 'E492:", v:errors[0])]])
- expected_errors({"stupid: Expected 'E9876' but got 'E492: Not an editor command: xxx': stupid"})
- end)
-
- it('can specify and get a message even when cmd succeeds', function()
- eq(1, eval([[assert_fails('echo', '', 'echo command')]]))
- expected_errors({'command did not fail: echo command'})
- end)
-
- it('can be used as a method', function()
- local tmpname = source [[
- call assert_equal(1, 'echo'->assert_fails('', 'echo command'))
- ]]
- expected_errors({
- tmpname .. ' line 1: command did not fail: echo command'
- })
- end)
- end)
-
- -- assert_inrange({lower}, {upper}, {actual}[, {msg}])
- describe('assert_inrange()', function()
- it('should not change v:errors when actual is in range', function()
- call('assert_inrange', 7, 7, 7)
- call('assert_inrange', 5, 7, 5)
- call('assert_inrange', 5, 7, 6)
- call('assert_inrange', 5, 7, 7)
- expected_empty()
- end)
-
- it('should change v:errors when actual is not in range', function()
- call('assert_inrange', 5, 7, 4)
- call('assert_inrange', 5, 7, 8)
- expected_errors({
- "Expected range 5 - 7, but got 4",
- "Expected range 5 - 7, but got 8",
- })
- end)
-
- it('assert_inrange(1, 1) returns E119', function()
- eq('Vim(call):E119: Not enough arguments for function: assert_inrange',
- exc_exec("call assert_inrange(1, 1)"))
- end)
-
- it('can be used as a method', function()
- local tmpname = source [[
- call assert_equal(0, 5->assert_inrange(5, 7))
- call assert_equal(0, 7->assert_inrange(5, 7))
- call assert_equal(1, 8->assert_inrange(5, 7))
- ]]
- expected_errors({tmpname .. ' line 3: Expected range 5 - 7, but got 8'})
- end)
- end)
-
- -- assert_report({msg})
- describe('assert_report()', function()
- it('should add a message to v:errors', function()
- eq(1, call('assert_report', 'something is wrong'))
- command("call assert_match('something is wrong', v:errors[0])")
- command('call remove(v:errors, 0)')
- expected_empty()
- end)
-
- it('can be used as a method', function()
- local tmpname = source [[
- call assert_equal(1, 'also wrong'->assert_report())
- ]]
- expected_errors({tmpname .. ' line 1: also wrong'})
- end)
- end)
-
- -- assert_exception({cmd}, [, {error}])
- describe('assert_exception()', function()
- it('should assert thrown exceptions properly', function()
- source([[
- try
- nocommand
- catch
- call assert_equal(0, assert_exception('E492'))
- endtry
- ]])
- expected_empty()
- end)
-
- it('should work properly when nested', function()
- source([[
- try
- nocommand
- catch
- try
- " illegal argument, get NULL for error
- call assert_equal(1, assert_exception([]))
- catch
- call assert_equal(0, assert_exception('E730'))
- endtry
- endtry
- ]])
- expected_empty()
- end)
end)
end)
diff --git a/test/functional/legacy/cdo_spec.lua b/test/functional/legacy/cdo_spec.lua
deleted file mode 100644
index 8b3216cbfd..0000000000
--- a/test/functional/legacy/cdo_spec.lua
+++ /dev/null
@@ -1,228 +0,0 @@
--- Tests for the :cdo, :cfdo, :ldo and :lfdo commands
-
-local helpers = require('test.functional.helpers')(after_each)
-local nvim, clear = helpers.meths, helpers.clear
-local call, feed = helpers.call, helpers.feed
-local source, eq = helpers.source, helpers.eq
-
-local function expected_empty()
- eq({}, nvim.get_vvar('errors'))
-end
-
-describe('cdo', function()
- before_each(function()
- clear()
-
- call('writefile', {'Line1', 'Line2', 'Line3'}, 'Xtestfile1')
- call('writefile', {'Line1', 'Line2', 'Line3'}, 'Xtestfile2')
- call('writefile', {'Line1', 'Line2', 'Line3'}, 'Xtestfile3')
-
- source([=[
- " Returns the current line in '<filename> <linenum>L <column>C' format
- function GetRuler()
- return expand('%') . ' ' . line('.') . 'L' . ' ' . col('.') . 'C'
- endfunction
-
- " Tests for the :cdo and :ldo commands
- function XdoTests(cchar)
- enew
-
- " Shortcuts for calling the cdo and ldo commands
- let Xdo = a:cchar . 'do'
- let Xgetexpr = a:cchar . 'getexpr'
- let Xprev = a:cchar. 'prev'
- let XdoCmd = Xdo . ' call add(l, GetRuler())'
-
- " Try with an empty list
- let l = []
- exe XdoCmd
- call assert_equal([], l)
-
- " Populate the list and then try
- exe Xgetexpr . " ['non-error 1', 'Xtestfile1:1:3:Line1', 'non-error 2', 'Xtestfile2:2:2:Line2', 'non-error 3', 'Xtestfile3:3:1:Line3']"
-
- let l = []
- exe XdoCmd
- call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 3L 1C'], l)
-
- " Run command only on selected error lines
- let l = []
- enew
- exe "2,3" . XdoCmd
- call assert_equal(['Xtestfile2 2L 2C', 'Xtestfile3 3L 1C'], l)
-
- " Boundary condition tests
- let l = []
- enew
- exe "1,1" . XdoCmd
- call assert_equal(['Xtestfile1 1L 3C'], l)
-
- let l = []
- enew
- exe "3" . XdoCmd
- call assert_equal(['Xtestfile3 3L 1C'], l)
-
- " Range test commands
- let l = []
- enew
- exe "%" . XdoCmd
- call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 3L 1C'], l)
-
- let l = []
- enew
- exe "1,$" . XdoCmd
- call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 3L 1C'], l)
-
- let l = []
- enew
- exe Xprev
- exe "." . XdoCmd
- call assert_equal(['Xtestfile2 2L 2C'], l)
-
- let l = []
- enew
- exe "+" . XdoCmd
- call assert_equal(['Xtestfile3 3L 1C'], l)
-
- " Invalid error lines test
- let l = []
- enew
- exe "silent! 27" . XdoCmd
- exe "silent! 4,5" . XdoCmd
- call assert_equal([], l)
-
- " Run commands from an unsaved buffer when 'hidden' is unset
- set nohidden
- let v:errmsg=''
- let l = []
- enew
- setlocal modified
- exe "silent! 2,2" . XdoCmd
- if v:errmsg !~# 'No write since last change'
- call add(v:errors, 'Unsaved file change test failed')
- endif
-
- " If the executed command fails, then the operation should be aborted
- enew!
- let subst_count = 0
- exe "silent!" . Xdo . " s/Line/xLine/ | let subst_count += 1"
- if subst_count != 1 || getline('.') != 'xLine1'
- call add(v:errors, 'Abort command on error test failed')
- endif
- set hidden
-
- let l = []
- exe "2,2" . Xdo . "! call add(l, GetRuler())"
- call assert_equal(['Xtestfile2 2L 2C'], l)
-
- " List with no valid error entries
- let l = []
- edit! +2 Xtestfile1
- exe Xgetexpr . " ['non-error 1', 'non-error 2', 'non-error 3']"
- exe XdoCmd
- call assert_equal([], l)
- exe "silent! 2" . XdoCmd
- call assert_equal([], l)
- let v:errmsg=''
- exe "%" . XdoCmd
- exe "1,$" . XdoCmd
- exe "." . XdoCmd
- call assert_equal('', v:errmsg)
-
- " List with only one valid entry
- let l = []
- exe Xgetexpr . " ['Xtestfile3:3:1:Line3']"
- exe XdoCmd
- call assert_equal(['Xtestfile3 3L 1C'], l)
-
- endfunction
-
- " Tests for the :cfdo and :lfdo commands
- function XfdoTests(cchar)
- enew
-
- " Shortcuts for calling the cfdo and lfdo commands
- let Xfdo = a:cchar . 'fdo'
- let Xgetexpr = a:cchar . 'getexpr'
- let XfdoCmd = Xfdo . ' call add(l, GetRuler())'
- let Xpfile = a:cchar. 'pfile'
-
- " Clear the quickfix/location list
- exe Xgetexpr . " []"
-
- " Try with an empty list
- let l = []
- exe XfdoCmd
- call assert_equal([], l)
-
- " Populate the list and then try
- exe Xgetexpr . " ['non-error 1', 'Xtestfile1:1:3:Line1', 'Xtestfile1:2:1:Line2', 'non-error 2', 'Xtestfile2:2:2:Line2', 'non-error 3', 'Xtestfile3:2:3:Line2', 'Xtestfile3:3:1:Line3']"
-
- let l = []
- exe XfdoCmd
- call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 2L 3C'], l)
-
- " Run command only on selected error lines
- let l = []
- exe "2,3" . XfdoCmd
- call assert_equal(['Xtestfile2 2L 2C', 'Xtestfile3 2L 3C'], l)
-
- " Boundary condition tests
- let l = []
- exe "3" . XfdoCmd
- call assert_equal(['Xtestfile3 2L 3C'], l)
-
- " Range test commands
- let l = []
- exe "%" . XfdoCmd
- call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 2L 3C'], l)
-
- let l = []
- exe "1,$" . XfdoCmd
- call assert_equal(['Xtestfile1 1L 3C', 'Xtestfile2 2L 2C', 'Xtestfile3 2L 3C'], l)
-
- let l = []
- exe Xpfile
- exe "." . XfdoCmd
- call assert_equal(['Xtestfile2 2L 2C'], l)
-
- " List with only one valid entry
- let l = []
- exe Xgetexpr . " ['Xtestfile2:2:5:Line2']"
- exe XfdoCmd
- call assert_equal(['Xtestfile2 2L 5C'], l)
-
- endfunction
- ]=])
- end)
-
- after_each(function()
- os.remove('Xtestfile1')
- os.remove('Xtestfile2')
- os.remove('Xtestfile3')
- end)
-
- it('works for :cdo', function()
- -- call('XdoTests', 'c')
- feed(":call XdoTests('c')<CR><C-l>")
- expected_empty()
- end)
-
- it('works for :cfdo', function()
- -- call('XfdoTests', 'c')
- feed(":call XfdoTests('c')<CR><C-l>")
- expected_empty()
- end)
-
- it('works for :ldo', function()
- -- call('XdoTests', 'l')
- feed(":call XdoTests('l')<CR><C-l>")
- expected_empty()
- end)
-
- it('works for :lfdo', function()
- -- call('XfdoTests', 'l')
- feed(":call XfdoTests('l')<CR><C-l>")
- expected_empty()
- end)
-end)
diff --git a/test/functional/legacy/packadd_spec.lua b/test/functional/legacy/packadd_spec.lua
deleted file mode 100644
index 4f9f5a0237..0000000000
--- a/test/functional/legacy/packadd_spec.lua
+++ /dev/null
@@ -1,507 +0,0 @@
--- Tests for 'packpath' and :packadd
-
-local helpers = require('test.functional.helpers')(after_each)
-local clear, source, command = helpers.clear, helpers.source, helpers.command
-local call, eq, nvim = helpers.call, helpers.eq, helpers.meths
-local feed = helpers.feed
-
-local function expected_empty()
- eq({}, nvim.get_vvar('errors'))
-end
-
-describe('packadd', function()
- before_each(function()
- clear()
-
- source([=[
- func Escape(s)
- return escape(a:s, '\~')
- endfunc
-
- func SetUp()
- let s:topdir = expand(getcwd() . '/Xdir')
- if isdirectory(s:topdir)
- call delete(s:topdir, 'rf')
- endif
- exe 'set packpath=' . s:topdir
- let s:plugdir = expand(s:topdir . '/pack/mine/opt/mytest')
- endfunc
-
- func TearDown()
- call delete(s:topdir, 'rf')
- endfunc
-
- func Test_packadd()
- if !exists('s:plugdir')
- echomsg 'when running this test manually, call SetUp() first'
- return
- endif
-
- call mkdir(s:plugdir . '/plugin/also', 'p')
- call mkdir(s:plugdir . '/ftdetect', 'p')
- call mkdir(s:plugdir . '/after', 'p')
- set rtp&
- let rtp = &rtp
- filetype on
-
- let rtp_entries = split(rtp, ',')
- for entry in rtp_entries
- if entry =~? '\<after\>'
- let first_after_entry = entry
- break
- endif
- endfor
-
- exe 'split ' . s:plugdir . '/plugin/test.vim'
- call setline(1, 'let g:plugin_works = 42')
- wq
-
- exe 'split ' . s:plugdir . '/plugin/also/loaded.vim'
- call setline(1, 'let g:plugin_also_works = 77')
- wq
-
- exe 'split ' . s:plugdir . '/ftdetect/test.vim'
- call setline(1, 'let g:ftdetect_works = 17')
- wq
-
- packadd mytest
-
- call assert_true(42, g:plugin_works)
- call assert_equal(77, g:plugin_also_works)
- call assert_true(17, g:ftdetect_works)
- call assert_true(len(&rtp) > len(rtp))
- call assert_match(Escape(s:plugdir) . '\($\|,\)', &rtp)
-
- let new_after = match(&rtp, Escape(expand(s:plugdir . '/after') . ','))
- let forwarded = substitute(first_after_entry, '\\', '[/\\\\]', 'g')
- let old_after = match(&rtp, ',' . escape(forwarded, '~') . '\>')
- call assert_true(new_after > 0, 'rtp is ' . &rtp)
- call assert_true(old_after > 0, 'match ' . forwarded . ' in ' . &rtp)
- call assert_true(new_after < old_after, 'rtp is ' . &rtp)
-
- " NOTE: '/.../opt/myte' forwardly matches with '/.../opt/mytest'
- call mkdir(fnamemodify(s:plugdir, ':h') . '/myte', 'p')
- let rtp = &rtp
- packadd myte
-
- " Check the path of 'myte' is added
- call assert_true(len(&rtp) > len(rtp))
- call assert_match(Escape(s:plugdir) . '\($\|,\)', &rtp)
-
- " Check exception
- call assert_fails("packadd directorynotfound", 'E919:')
- call assert_fails("packadd", 'E471:')
- endfunc
-
- func Test_packadd_start()
- let plugdir = expand(s:topdir . '/pack/mine/start/other')
- call mkdir(plugdir . '/plugin', 'p')
- set rtp&
- let rtp = &rtp
- filetype on
-
- exe 'split ' . plugdir . '/plugin/test.vim'
- call setline(1, 'let g:plugin_works = 24')
- wq
-
- exe 'split ' . plugdir . '/plugin/test.lua'
- call setline(1, 'vim.g.plugin_lua_works = 24')
- wq
-
- packadd other
-
- call assert_equal(24, g:plugin_works)
- call assert_equal(24, g:plugin_lua_works)
- call assert_true(len(&rtp) > len(rtp))
- call assert_match(Escape(plugdir) . '\($\|,\)', &rtp)
- endfunc
-
- func Test_packadd_noload()
- call mkdir(s:plugdir . '/plugin', 'p')
- call mkdir(s:plugdir . '/syntax', 'p')
- set rtp&
- let rtp = &rtp
-
- exe 'split ' . s:plugdir . '/plugin/test.vim'
- call setline(1, 'let g:plugin_works = 42')
- wq
- exe 'split ' . s:plugdir . '/plugin/test.lua'
- call setline(1, 'let g:plugin_lua_works = 42')
- wq
- let g:plugin_works = 0
- let g:plugin_lua_works = 0
-
- packadd! mytest
-
- call assert_true(len(&rtp) > len(rtp))
- call assert_match(Escape(s:plugdir) . '\($\|,\)', &rtp)
- call assert_equal(0, g:plugin_works)
- call assert_equal(0, g:plugin_lua_works)
-
- " check the path is not added twice
- let new_rtp = &rtp
- packadd! mytest
- call assert_equal(new_rtp, &rtp)
- endfunc
-
- func Test_packadd_symlink_dir()
- let top2_dir = expand(s:topdir . '/Xdir2')
- let real_dir = expand(s:topdir . '/Xsym')
- call mkdir(real_dir, 'p')
- if has('win32')
- exec "silent! !mklink /d" top2_dir "Xsym"
- else
- exec "silent! !ln -s Xsym" top2_dir
- endif
- let &rtp = top2_dir . ',' . expand(top2_dir . '/after')
- let &packpath = &rtp
-
- let s:plugdir = expand(top2_dir . '/pack/mine/opt/mytest')
- call mkdir(s:plugdir . '/plugin', 'p')
-
- exe 'split ' . s:plugdir . '/plugin/test.vim'
- call setline(1, 'let g:plugin_works = 44')
- wq
- let g:plugin_works = 0
-
- packadd mytest
-
- " Must have been inserted in the middle, not at the end
- call assert_match(Escape(expand('/pack/mine/opt/mytest').','), &rtp)
- call assert_equal(44, g:plugin_works)
-
- " No change when doing it again.
- let rtp_before = &rtp
- packadd mytest
- call assert_equal(rtp_before, &rtp)
-
- set rtp&
- let rtp = &rtp
- exec "silent !" (has('win32') ? "rd /q/s" : "rm") top2_dir
- endfunc
-
- func Test_packadd_symlink_dir2()
- let top2_dir = expand(s:topdir . '/Xdir2')
- let real_dir = expand(s:topdir . '/Xsym/pack')
- call mkdir(top2_dir, 'p')
- call mkdir(real_dir, 'p')
- let &rtp = top2_dir . ',' . top2_dir . '/after'
- let &packpath = &rtp
-
- if has('win32')
- exec "silent! !mklink /d" top2_dir "Xsym"
- else
- exec "silent !ln -s ../Xsym/pack" top2_dir . '/pack'
- endif
- let s:plugdir = expand(top2_dir . '/pack/mine/opt/mytest')
- call mkdir(s:plugdir . '/plugin', 'p')
-
- exe 'split ' . s:plugdir . '/plugin/test.vim'
- call setline(1, 'let g:plugin_works = 48')
- wq
- let g:plugin_works = 0
-
- packadd mytest
-
- " Must have been inserted in the middle, not at the end
- call assert_match(Escape(expand('/Xdir2/pack/mine/opt/mytest').','), &rtp)
- call assert_equal(48, g:plugin_works)
-
- " No change when doing it again.
- let rtp_before = &rtp
- packadd mytest
- call assert_equal(rtp_before, &rtp)
-
- set rtp&
- let rtp = &rtp
- if has('win32')
- exec "silent !rd /q/s" top2_dir
- else
- exec "silent !rm" top2_dir . '/pack'
- exec "silent !rmdir" top2_dir
- endif
- endfunc
-
- func Test_packloadall()
- " plugin foo with an autoload directory
- let fooplugindir = &packpath . '/pack/mine/start/foo/plugin'
- call mkdir(fooplugindir, 'p')
- call writefile(['let g:plugin_foo_number = 1234',
- \ 'let g:plugin_foo_auto = bbb#value',
- \ 'let g:plugin_extra_auto = extra#value'], fooplugindir . '/bar.vim')
- let fooautodir = &packpath . '/pack/mine/start/foo/autoload'
- call mkdir(fooautodir, 'p')
- call writefile(['let bar#value = 77'], fooautodir . '/bar.vim')
-
- " plugin aaa with an autoload directory
- let aaaplugindir = &packpath . '/pack/mine/start/aaa/plugin'
- call mkdir(aaaplugindir, 'p')
- call writefile(['let g:plugin_aaa_number = 333',
- \ 'let g:plugin_aaa_auto = bar#value'], aaaplugindir . '/bbb.vim')
- let aaaautodir = &packpath . '/pack/mine/start/aaa/autoload'
- call mkdir(aaaautodir, 'p')
- call writefile(['let bbb#value = 55'], aaaautodir . '/bbb.vim')
-
- " plugin extra with only an autoload directory
- let extraautodir = &packpath . '/pack/mine/start/extra/autoload'
- call mkdir(extraautodir, 'p')
- call writefile(['let extra#value = 99'], extraautodir . '/extra.vim')
-
- packloadall
- call assert_equal(1234, g:plugin_foo_number)
- call assert_equal(55, g:plugin_foo_auto)
- call assert_equal(99, g:plugin_extra_auto)
- call assert_equal(333, g:plugin_aaa_number)
- call assert_equal(77, g:plugin_aaa_auto)
-
- " only works once
- call writefile(['let g:plugin_bar_number = 4321'],
- \ fooplugindir . '/bar2.vim')
- packloadall
- call assert_false(exists('g:plugin_bar_number'))
-
- " works when ! used
- packloadall!
- call assert_equal(4321, g:plugin_bar_number)
- endfunc
-
- func Test_helptags()
- let docdir1 = &packpath . '/pack/mine/start/foo/doc'
- let docdir2 = &packpath . '/pack/mine/start/bar/doc'
- call mkdir(docdir1, 'p')
- call mkdir(docdir2, 'p')
- call writefile(['look here: *look-here*'], docdir1 . '/bar.txt')
- call writefile(['look away: *look-away*'], docdir2 . '/foo.txt')
- exe 'set rtp=' . &packpath . '/pack/mine/start/foo,' . &packpath . '/pack/mine/start/bar'
-
- helptags ALL
-
- let tags1 = readfile(docdir1 . '/tags')
- call assert_match('look-here', tags1[0])
- let tags2 = readfile(docdir2 . '/tags')
- call assert_match('look-away', tags2[0])
-
- call assert_fails('helptags abcxyz', 'E150:')
- endfunc
-
- func Test_colorscheme()
- let colordirrun = &packpath . '/runtime/colors'
- let colordirstart = &packpath . '/pack/mine/start/foo/colors'
- let colordiropt = &packpath . '/pack/mine/opt/bar/colors'
- call mkdir(colordirrun, 'p')
- call mkdir(colordirstart, 'p')
- call mkdir(colordiropt, 'p')
- call writefile(['let g:found_one = 1'], colordirrun . '/one.vim')
- call writefile(['let g:found_two = 1'], colordirstart . '/two.vim')
- call writefile(['let g:found_three = 1'], colordiropt . '/three.vim')
- exe 'set rtp=' . &packpath . '/runtime'
-
- colorscheme one
- call assert_equal(1, g:found_one)
- colorscheme two
- call assert_equal(1, g:found_two)
- colorscheme three
- call assert_equal(1, g:found_three)
- endfunc
-
- func Test_runtime()
- let rundir = &packpath . '/runtime/extra'
- let startdir = &packpath . '/pack/mine/start/foo/extra'
- let optdir = &packpath . '/pack/mine/opt/bar/extra'
- call mkdir(rundir, 'p')
- call mkdir(startdir, 'p')
- call mkdir(optdir, 'p')
- call writefile(['let g:sequence .= "run"'], rundir . '/bar.vim')
- call writefile(['let g:sequence .= "start"'], startdir . '/bar.vim')
- call writefile(['let g:sequence .= "foostart"'], startdir . '/foo.vim')
- call writefile(['let g:sequence .= "opt"'], optdir . '/bar.vim')
- call writefile(['let g:sequence .= "xxxopt"'], optdir . '/xxx.vim')
- exe 'set rtp=' . &packpath . '/runtime'
-
- let g:sequence = ''
- runtime extra/bar.vim
- call assert_equal('run', g:sequence)
- let g:sequence = ''
- runtime START extra/bar.vim
- call assert_equal('start', g:sequence)
- let g:sequence = ''
- runtime OPT extra/bar.vim
- call assert_equal('opt', g:sequence)
- let g:sequence = ''
- runtime PACK extra/bar.vim
- call assert_equal('start', g:sequence)
- let g:sequence = ''
- runtime! PACK extra/bar.vim
- call assert_equal('startopt', g:sequence)
- let g:sequence = ''
- runtime PACK extra/xxx.vim
- call assert_equal('xxxopt', g:sequence)
-
- let g:sequence = ''
- runtime ALL extra/bar.vim
- call assert_equal('run', g:sequence)
- let g:sequence = ''
- runtime ALL extra/foo.vim
- call assert_equal('foostart', g:sequence)
- let g:sequence = ''
- runtime! ALL extra/xxx.vim
- call assert_equal('xxxopt', g:sequence)
- let g:sequence = ''
- runtime! ALL extra/bar.vim
- call assert_equal('runstartopt', g:sequence)
- endfunc
- ]=])
- call('SetUp')
- end)
-
- after_each(function()
- call('TearDown')
- end)
-
- it('is working', function()
- call('Test_packadd')
- expected_empty()
- end)
-
- it('works with packadd!', function()
- call('Test_packadd_noload')
- expected_empty()
- end)
-
- it('works with symlinks', function()
- call('Test_packadd_symlink_dir')
- expected_empty()
- end)
-
- it('works with :packloadall', function()
- call('Test_packloadall')
- expected_empty()
- end)
-
- it('works with helptags', function()
- call('Test_helptags')
- expected_empty()
- end)
-
- it('works with colorschemes', function()
- call('Test_colorscheme')
- expected_empty()
- end)
-
- it('works with :runtime [what]', function()
- call('Test_runtime')
- expected_empty()
- end)
-
- it('loads packages from "start" directory', function()
- call('Test_packadd_start')
- expected_empty()
- end)
-
- describe('command line completion', function()
- local Screen = require('test.functional.ui.screen')
- local screen
-
- before_each(function()
- screen = Screen.new(30, 5)
- screen:attach()
- screen:set_default_attr_ids({
- [0] = {bold=true, foreground=Screen.colors.Blue},
- [1] = {
- foreground = Screen.colors.Black,
- background = Screen.colors.Yellow,
- },
- [2] = {bold = true, reverse = true}
- })
-
- command([[let optdir1 = &packpath . '/pack/mine/opt']])
- command([[let optdir2 = &packpath . '/pack/candidate/opt']])
- command([[call mkdir(optdir1 . '/pluginA', 'p')]])
- command([[call mkdir(optdir1 . '/pluginC', 'p')]])
- command([[call mkdir(optdir2 . '/pluginB', 'p')]])
- command([[call mkdir(optdir2 . '/pluginC', 'p')]])
- end)
-
- it('works', function()
- feed(':packadd <Tab>')
- screen:expect([=[
- |
- {0:~ }|
- {0:~ }|
- {1:pluginA}{2: pluginB pluginC }|
- :packadd pluginA^ |
- ]=])
- feed('<Tab>')
- screen:expect([=[
- |
- {0:~ }|
- {0:~ }|
- {2:pluginA }{1:pluginB}{2: pluginC }|
- :packadd pluginB^ |
- ]=])
- feed('<Tab>')
- screen:expect([=[
- |
- {0:~ }|
- {0:~ }|
- {2:pluginA pluginB }{1:pluginC}{2: }|
- :packadd pluginC^ |
- ]=])
- feed('<Tab>')
- screen:expect([=[
- |
- {0:~ }|
- {0:~ }|
- {2:pluginA pluginB pluginC }|
- :packadd ^ |
- ]=])
- end)
-
- it('works for colorschemes', function()
- source([[
- let colordirrun = &packpath . '/runtime/colors'
- let colordirstart = &packpath . '/pack/mine/start/foo/colors'
- let colordiropt = &packpath . '/pack/mine/opt/bar/colors'
- call mkdir(colordirrun, 'p')
- call mkdir(colordirstart, 'p')
- call mkdir(colordiropt, 'p')
- call writefile(['let g:found_one = 1'], colordirrun . '/one.vim')
- call writefile(['let g:found_two = 1'], colordirstart . '/two.vim')
- call writefile(['let g:found_three = 1'], colordiropt . '/three.vim')
- exe 'set rtp=' . &packpath . '/runtime']])
-
- feed(':colorscheme <Tab>')
- screen:expect([=[
- |
- {0:~ }|
- {0:~ }|
- {1:one}{2: three two }|
- :colorscheme one^ |
- ]=])
- feed('<Tab>')
- screen:expect([=[
- |
- {0:~ }|
- {0:~ }|
- {2:one }{1:three}{2: two }|
- :colorscheme three^ |
- ]=])
- feed('<Tab>')
- screen:expect([=[
- |
- {0:~ }|
- {0:~ }|
- {2:one three }{1:two}{2: }|
- :colorscheme two^ |
- ]=])
- feed('<Tab>')
- screen:expect([=[
- |
- {0:~ }|
- {0:~ }|
- {2:one three two }|
- :colorscheme ^ |
- ]=])
- end)
- end)
-end)
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 17f7a04db6..7ec986acdd 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -19,6 +19,9 @@ local NIL = helpers.NIL
local retry = helpers.retry
local next_msg = helpers.next_msg
local remove_trace = helpers.remove_trace
+local mkdir_p = helpers.mkdir_p
+local rmdir = helpers.rmdir
+local write_file = helpers.write_file
before_each(clear)
@@ -1019,6 +1022,20 @@ describe('lua stdlib', function()
eq(3, exec_lua([[return vim.g.GetCounter()]]))
exec_lua([[vim.api.nvim_get_var('AddCounter')()]])
eq(4, exec_lua([[return vim.api.nvim_get_var('GetCounter')()]]))
+
+ -- Check if autoload works properly
+ local pathsep = helpers.get_pathsep()
+ local xconfig = 'Xhome' .. pathsep .. 'Xconfig'
+ local xdata = 'Xhome' .. pathsep .. 'Xdata'
+ local autoload_folder = table.concat({xconfig, 'nvim', 'autoload'}, pathsep)
+ local autoload_file = table.concat({autoload_folder , 'testload.vim'}, pathsep)
+ mkdir_p(autoload_folder)
+ write_file(autoload_file , [[let testload#value = 2]])
+
+ clear{ args_rm={'-u'}, env={ XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata } }
+
+ eq(2, exec_lua("return vim.g['testload#value']"))
+ rmdir('Xhome')
end)
it('vim.b', function()