aboutsummaryrefslogtreecommitdiff
path: root/src/nvim
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim')
-rw-r--r--src/nvim/api/private/helpers.h5
-rw-r--r--src/nvim/api/vim.c41
-rw-r--r--src/nvim/buffer.c17
-rw-r--r--src/nvim/edit.c117
-rw-r--r--src/nvim/eval.c135
-rw-r--r--src/nvim/eval.h2
-rw-r--r--src/nvim/eval/funcs.c3
-rw-r--r--src/nvim/ex_cmds.c7
-rw-r--r--src/nvim/ex_cmds2.c8
-rw-r--r--src/nvim/ex_getln.c5
-rw-r--r--src/nvim/lua/executor.c31
-rw-r--r--src/nvim/main.c34
-rw-r--r--src/nvim/message.c7
-rw-r--r--src/nvim/option.c95
-rw-r--r--src/nvim/option_defs.h1
-rw-r--r--src/nvim/path.c7
-rw-r--r--src/nvim/quickfix.c7
-rw-r--r--src/nvim/search.c15
-rw-r--r--src/nvim/spell.c9
-rw-r--r--src/nvim/spell.h1
-rw-r--r--src/nvim/testdir/test49.vim14
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_assign.vim47
-rw-r--r--src/nvim/testdir/test_autocmd.vim2
-rw-r--r--src/nvim/testdir/test_charsearch.vim8
-rw-r--r--src/nvim/testdir/test_charsearch_utf8.vim2
-rw-r--r--src/nvim/testdir/test_edit.vim74
-rw-r--r--src/nvim/testdir/test_filetype.vim18
-rw-r--r--src/nvim/testdir/test_fnameescape.vim4
-rw-r--r--src/nvim/testdir/test_getcwd.vim188
-rw-r--r--src/nvim/testdir/test_highlight.vim16
-rw-r--r--src/nvim/testdir/test_hlsearch.vim4
-rw-r--r--src/nvim/testdir/test_ins_complete.vim18
-rw-r--r--src/nvim/testdir/test_let.vim53
-rw-r--r--src/nvim/testdir/test_listlbr.vim4
-rw-r--r--src/nvim/testdir/test_listlbr_utf8.vim20
-rw-r--r--src/nvim/testdir/test_matchadd_conceal.vim32
-rw-r--r--src/nvim/testdir/test_matchadd_conceal_utf8.vim2
-rw-r--r--src/nvim/testdir/test_number.vim10
-rw-r--r--src/nvim/testdir/test_options.vim2
-rw-r--r--src/nvim/testdir/test_partial.vim8
-rw-r--r--src/nvim/testdir/test_quickfix.vim58
-rw-r--r--src/nvim/testdir/test_smartindent.vim18
-rw-r--r--src/nvim/testdir/test_substitute.vim10
-rw-r--r--src/nvim/testdir/test_textobjects.vim2
-rw-r--r--src/nvim/testdir/test_utf8.vim23
-rw-r--r--src/nvim/testdir/test_utf8_comparisons.vim26
-rw-r--r--src/nvim/testdir/test_vimscript.vim118
48 files changed, 843 insertions, 486 deletions
diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h
index 271fd5b485..055abb797f 100644
--- a/src/nvim/api/private/helpers.h
+++ b/src/nvim/api/private/helpers.h
@@ -16,6 +16,7 @@
#define BOOLEAN_OBJ(b) ((Object) { \
.type = kObjectTypeBoolean, \
.data.boolean = b })
+#define BOOL(b) BOOLEAN_OBJ(b)
#define INTEGER_OBJ(i) ((Object) { \
.type = kObjectTypeInteger, \
@@ -29,6 +30,8 @@
.type = kObjectTypeString, \
.data.string = s })
+#define CSTR_TO_OBJ(s) STRING_OBJ(cstr_to_string(s))
+
#define BUFFER_OBJ(s) ((Object) { \
.type = kObjectTypeBuffer, \
.data.integer = s })
@@ -59,6 +62,8 @@
#define PUT(dict, k, v) \
kv_push(dict, ((KeyValuePair) { .key = cstr_to_string(k), .value = v }))
+#define PUT_BOOL(dict, name, condition) PUT(dict, name, BOOLEAN_OBJ(condition));
+
#define ADD(array, item) \
kv_push(array, item)
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 77002697fe..8ac820abd9 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -970,6 +970,47 @@ Object nvim_get_option(String name, Error *err)
return get_option_from(NULL, SREQ_GLOBAL, name, err);
}
+/// Gets the option information for all options.
+///
+/// The dictionary has the full option names as keys and option metadata
+/// dictionaries as detailed at |nvim_get_option_info|.
+///
+/// @return dictionary of all options
+Dictionary nvim_get_all_options_info(Error *err)
+ FUNC_API_SINCE(7)
+{
+ return get_all_vimoptions();
+}
+
+/// Gets the option information for one option
+///
+/// Resulting dictionary has keys:
+/// - name: Name of the option (like 'filetype')
+/// - shortname: Shortened name of the option (like 'ft')
+/// - type: type of option ("string", "integer" or "boolean")
+/// - default: The default value for the option
+/// - was_set: Whether the option was set.
+///
+/// - last_set_sid: Last set script id (if any)
+/// - last_set_linenr: line number where option was set
+/// - last_set_chan: Channel where option was set (0 for local)
+///
+/// - scope: one of "global", "win", or "buf"
+/// - global_local: whether win or buf option has a global value
+///
+/// - commalist: List of comma separated values
+/// - flaglist: List of single char flags
+///
+///
+/// @param name Option name
+/// @param[out] err Error details, if any
+/// @return Option Information
+Dictionary nvim_get_option_info(String name, Error *err)
+ FUNC_API_SINCE(7)
+{
+ return get_vimoption(name, err);
+}
+
/// Sets an option value.
///
/// @param channel_id
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index ffa44c33cd..839d61cd2e 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1637,12 +1637,23 @@ void do_autochdir(void)
void no_write_message(void)
{
- EMSG(_("E37: No write since last change (add ! to override)"));
+ if (curbuf->terminal
+ && channel_job_running((uint64_t)curbuf->b_p_channel)) {
+ EMSG(_("E948: Job still running (add ! to end the job)"));
+ } else {
+ EMSG(_("E37: No write since last change (add ! to override)"));
+ }
}
-void no_write_message_nobang(void)
+void no_write_message_nobang(const buf_T *const buf)
+ FUNC_ATTR_NONNULL_ALL
{
- EMSG(_("E37: No write since last change"));
+ if (buf->terminal
+ && channel_job_running((uint64_t)buf->b_p_channel)) {
+ EMSG(_("E948: Job still running"));
+ } else {
+ EMSG(_("E37: No write since last change"));
+ }
}
//
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 5d44c3274e..7fefa8520a 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -196,8 +196,8 @@ static int ctrl_x_mode = CTRL_X_NORMAL;
static int compl_matches = 0;
static char_u *compl_pattern = NULL;
-static int compl_direction = FORWARD;
-static int compl_shows_dir = FORWARD;
+static Direction compl_direction = FORWARD;
+static Direction compl_shows_dir = FORWARD;
static int compl_pending = 0; // > 1 for postponed CTRL-N
static pos_T compl_startpos;
static colnr_T compl_col = 0; /* column where the text starts
@@ -2156,7 +2156,7 @@ static bool ins_compl_accept_char(int c)
///
/// @param[in] cont_s_ipos next ^X<> will set initial_pos
int ins_compl_add_infercase(char_u *str_arg, int len, bool icase, char_u *fname,
- int dir, bool cont_s_ipos)
+ Direction dir, bool cont_s_ipos)
FUNC_ATTR_NONNULL_ARG(1)
{
char_u *str = str_arg;
@@ -2308,7 +2308,7 @@ static int ins_compl_add(char_u *const str, int len,
FUNC_ATTR_NONNULL_ARG(1)
{
compl_T *match;
- int dir = (cdir == kDirectionNotSet ? compl_direction : cdir);
+ const Direction dir = (cdir == kDirectionNotSet ? compl_direction : cdir);
int flags = flags_arg;
os_breakcheck();
@@ -2511,7 +2511,7 @@ static void ins_compl_add_matches(int num_matches, char_u **matches, int icase)
FUNC_ATTR_NONNULL_ALL
{
int add_r = OK;
- int dir = compl_direction;
+ Direction dir = compl_direction;
for (int i = 0; i < num_matches && add_r != FAIL; i++) {
if ((add_r = ins_compl_add(matches[i], -1, NULL, NULL, false, NULL, dir,
@@ -2864,7 +2864,7 @@ ins_compl_dictionaries (
char_u **files;
int count;
int save_p_scs;
- int dir = compl_direction;
+ Direction dir = compl_direction;
if (*dict == NUL) {
/* When 'dictionary' is empty and spell checking is enabled use
@@ -2945,7 +2945,10 @@ theend:
xfree(buf);
}
-static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir)
+static void ins_compl_files(int count, char_u **files, int thesaurus,
+ int flags, regmatch_T *regmatch, char_u *buf,
+ Direction *dir)
+ FUNC_ATTR_NONNULL_ARG(2, 7)
{
char_u *ptr;
int i;
@@ -3137,6 +3140,56 @@ bool ins_compl_active(void)
return compl_started;
}
+static void ins_compl_update_sequence_numbers(void)
+{
+ int number = 0;
+ compl_T *match;
+
+ if (compl_direction == FORWARD) {
+ // search backwards for the first valid (!= -1) number.
+ // This should normally succeed already at the first loop
+ // cycle, so it's fast!
+ for (match = compl_curr_match->cp_prev;
+ match != NULL && match != compl_first_match;
+ match = match->cp_prev) {
+ if (match->cp_number != -1) {
+ number = match->cp_number;
+ break;
+ }
+ }
+ if (match != NULL) {
+ // go up and assign all numbers which are not assigned yet
+ for (match = match->cp_next;
+ match != NULL && match->cp_number == -1;
+ match = match->cp_next) {
+ match->cp_number = ++number;
+ }
+ }
+ } else { // BACKWARD
+ assert(compl_direction == BACKWARD);
+ // search forwards (upwards) for the first valid (!= -1)
+ // number. This should normally succeed already at the
+ // first loop cycle, so it's fast!
+ for (match = compl_curr_match->cp_next;
+ match != NULL && match != compl_first_match;
+ match = match->cp_next) {
+ if (match->cp_number != -1) {
+ number = match->cp_number;
+ break;
+ }
+ }
+ if (match != NULL) {
+ // go down and assign all numbers which are not
+ // assigned yet
+ for (match = match->cp_prev;
+ match && match->cp_number == -1;
+ match = match->cp_prev) {
+ match->cp_number = ++number;
+ }
+ }
+ }
+}
+
// Get complete information
void get_complete_info(list_T *what_list, dict_T *retdict)
{
@@ -3214,6 +3267,9 @@ void get_complete_info(list_T *what_list, dict_T *retdict)
}
if (ret == OK && (what_flag & CI_WHAT_SELECTED)) {
+ if (compl_curr_match != NULL && compl_curr_match->cp_number == -1) {
+ ins_compl_update_sequence_numbers();
+ }
ret = tv_dict_add_nr(retdict, S_LEN("selected"),
(compl_curr_match != NULL)
? compl_curr_match->cp_number - 1 : -1);
@@ -3865,7 +3921,7 @@ theend:
*/
static void ins_compl_add_list(list_T *const list)
{
- int dir = compl_direction;
+ Direction dir = compl_direction;
// Go through the List with matches and add each of them.
TV_LIST_ITER(list, li, {
@@ -5242,52 +5298,11 @@ static int ins_complete(int c, bool enable_pum)
} else if (compl_curr_match->cp_next == compl_curr_match->cp_prev) {
edit_submode_extra = (char_u *)_("The only match");
edit_submode_highl = HLF_COUNT;
+ compl_curr_match->cp_number = 1;
} else {
// Update completion sequence number when needed.
if (compl_curr_match->cp_number == -1) {
- int number = 0;
- compl_T *match;
-
- if (compl_direction == FORWARD) {
- /* search backwards for the first valid (!= -1) number.
- * This should normally succeed already at the first loop
- * cycle, so it's fast! */
- for (match = compl_curr_match->cp_prev; match != NULL
- && match != compl_first_match;
- match = match->cp_prev)
- if (match->cp_number != -1) {
- number = match->cp_number;
- break;
- }
- if (match != NULL)
- /* go up and assign all numbers which are not assigned
- * yet */
- for (match = match->cp_next;
- match != NULL && match->cp_number == -1;
- match = match->cp_next)
- match->cp_number = ++number;
- } else { // BACKWARD
- // search forwards (upwards) for the first valid (!= -1)
- // number. This should normally succeed already at the
- // first loop cycle, so it's fast!
- for (match = compl_curr_match->cp_next;
- match != NULL && match != compl_first_match;
- match = match->cp_next) {
- if (match->cp_number != -1) {
- number = match->cp_number;
- break;
- }
- }
- if (match != NULL) {
- // go down and assign all numbers which are not
- // assigned yet
- for (match = match->cp_prev;
- match && match->cp_number == -1;
- match = match->cp_prev) {
- match->cp_number = ++number;
- }
- }
- }
+ ins_compl_update_sequence_numbers();
}
/* The match should always have a sequence number now, this is
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 054b788940..fa037b59d7 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -64,6 +64,7 @@ static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary");
static char *e_illvar = N_("E461: Illegal variable name: %s");
static char *e_cannot_mod = N_("E995: Cannot modify existing variable");
static char *e_invalwindow = N_("E957: Invalid window number");
+static char *e_lock_unlock = N_("E940: Cannot lock or unlock variable %s");
// TODO(ZyX-I): move to eval/executor
static char *e_letwrong = N_("E734: Wrong variable type for %s=");
@@ -2638,22 +2639,18 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
xp->xp_pattern = arg;
}
-/*
- * ":unlet[!] var1 ... " command.
- */
+/// ":unlet[!] var1 ... " command.
void ex_unlet(exarg_T *eap)
{
- ex_unletlock(eap, eap->arg, 0);
+ ex_unletlock(eap, eap->arg, 0, do_unlet_var);
}
// TODO(ZyX-I): move to eval/ex_cmds
-/*
- * ":lockvar" and ":unlockvar" commands
- */
+/// ":lockvar" and ":unlockvar" commands
void ex_lockvar(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = eap->arg;
int deep = 2;
if (eap->forceit) {
@@ -2663,30 +2660,41 @@ void ex_lockvar(exarg_T *eap)
arg = skipwhite(arg);
}
- ex_unletlock(eap, arg, deep);
+ ex_unletlock(eap, arg, deep, do_lock_var);
}
// TODO(ZyX-I): move to eval/ex_cmds
-/*
- * ":unlet", ":lockvar" and ":unlockvar" are quite similar.
- */
-static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep)
+/// Common parsing logic for :unlet, :lockvar and :unlockvar.
+///
+/// Invokes `callback` afterwards if successful and `eap->skip == false`.
+///
+/// @param[in] eap Ex command arguments for the command.
+/// @param[in] argstart Start of the string argument for the command.
+/// @param[in] deep Levels to (un)lock for :(un)lockvar, -1 to (un)lock
+/// everything.
+/// @param[in] callback Appropriate handler for the command.
+static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep,
+ ex_unletlock_callback callback)
+ FUNC_ATTR_NONNULL_ALL
{
- char_u *arg = argstart;
+ char_u *arg = argstart;
char_u *name_end;
bool error = false;
lval_T lv;
do {
if (*arg == '$') {
- const char *name = (char *)++arg;
-
+ lv.ll_name = (const char *)arg;
+ lv.ll_tv = NULL;
+ arg++;
if (get_env_len((const char_u **)&arg) == 0) {
- EMSG2(_(e_invarg2), name - 1);
+ EMSG2(_(e_invarg2), arg - 1);
return;
}
- os_unsetenv(name);
+ if (!error && !eap->skip && callback(&lv, arg, eap, deep) == FAIL) {
+ error = true;
+ }
name_end = arg;
} else {
// Parse the name and find the end.
@@ -2707,17 +2715,8 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep)
break;
}
- if (!error && !eap->skip) {
- if (eap->cmdidx == CMD_unlet) {
- if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) {
- error = true;
- }
- } else {
- if (do_lock_var(&lv, name_end, deep,
- eap->cmdidx == CMD_lockvar) == FAIL) {
- error = true;
- }
- }
+ if (!error && !eap->skip && callback(&lv, name_end, eap, deep) == FAIL) {
+ error = true;
}
if (!eap->skip) {
@@ -2732,8 +2731,19 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep)
// TODO(ZyX-I): move to eval/ex_cmds
-static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit)
+/// Unlet a variable indicated by `lp`.
+///
+/// @param[in] lp The lvalue.
+/// @param[in] name_end End of the string argument for the command.
+/// @param[in] eap Ex command arguments for :unlet.
+/// @param[in] deep Unused.
+///
+/// @return OK on success, or FAIL on failure.
+static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap,
+ int deep FUNC_ATTR_UNUSED)
+ FUNC_ATTR_NONNULL_ALL
{
+ int forceit = eap->forceit;
int ret = OK;
int cc;
@@ -2741,8 +2751,10 @@ static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit)
cc = *name_end;
*name_end = NUL;
- // Normal name or expanded name.
- if (do_unlet(lp->ll_name, lp->ll_name_len, forceit) == FAIL) {
+ // Environment variable, normal name or expanded name.
+ if (*lp->ll_name == '$') {
+ os_unsetenv(lp->ll_name + 1);
+ } else if (do_unlet(lp->ll_name, lp->ll_name_len, forceit) == FAIL) {
ret = FAIL;
}
*name_end = cc;
@@ -2816,7 +2828,7 @@ static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit)
///
/// @param[in] name Variable name to unlet.
/// @param[in] name_len Variable name length.
-/// @param[in] fonceit If true, do not complain if variable doesn’t exist.
+/// @param[in] forceit If true, do not complain if variable doesn’t exist.
///
/// @return OK if it existed, FAIL otherwise.
int do_unlet(const char *const name, const size_t name_len, const bool forceit)
@@ -2883,14 +2895,21 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit)
// TODO(ZyX-I): move to eval/ex_cmds
-/*
- * Lock or unlock variable indicated by "lp".
- * "deep" is the levels to go (-1 for unlimited);
- * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar".
- */
-static int do_lock_var(lval_T *lp, char_u *const name_end, const int deep,
- const bool lock)
+/// Lock or unlock variable indicated by `lp`.
+///
+/// Locks if `eap->cmdidx == CMD_lockvar`, unlocks otherwise.
+///
+/// @param[in] lp The lvalue.
+/// @param[in] name_end Unused.
+/// @param[in] eap Ex command arguments for :(un)lockvar.
+/// @param[in] deep Levels to (un)lock, -1 to (un)lock everything.
+///
+/// @return OK on success, or FAIL on failure.
+static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED,
+ exarg_T *eap, int deep)
+ FUNC_ATTR_NONNULL_ARG(1, 3)
{
+ bool lock = eap->cmdidx == CMD_lockvar;
int ret = OK;
if (deep == 0) { // Nothing to do.
@@ -2898,25 +2917,31 @@ static int do_lock_var(lval_T *lp, char_u *const name_end, const int deep,
}
if (lp->ll_tv == NULL) {
- // Normal name or expanded name.
- dictitem_T *const di = find_var(
- (const char *)lp->ll_name, lp->ll_name_len, NULL,
- true);
- if (di == NULL) {
+ if (*lp->ll_name == '$') {
+ EMSG2(_(e_lock_unlock), lp->ll_name);
ret = FAIL;
- } else if ((di->di_flags & DI_FLAGS_FIX)
- && di->di_tv.v_type != VAR_DICT
- && di->di_tv.v_type != VAR_LIST) {
- // For historical reasons this error is not given for Lists and
- // Dictionaries. E.g. b: dictionary may be locked/unlocked.
- emsgf(_("E940: Cannot lock or unlock variable %s"), lp->ll_name);
} else {
- if (lock) {
- di->di_flags |= DI_FLAGS_LOCK;
+ // Normal name or expanded name.
+ dictitem_T *const di = find_var(
+ (const char *)lp->ll_name, lp->ll_name_len, NULL,
+ true);
+ if (di == NULL) {
+ ret = FAIL;
+ } else if ((di->di_flags & DI_FLAGS_FIX)
+ && di->di_tv.v_type != VAR_DICT
+ && di->di_tv.v_type != VAR_LIST) {
+ // For historical reasons this error is not given for Lists and
+ // Dictionaries. E.g. b: dictionary may be locked/unlocked.
+ EMSG2(_(e_lock_unlock), lp->ll_name);
+ ret = FAIL;
} else {
- di->di_flags &= ~DI_FLAGS_LOCK;
+ if (lock) {
+ di->di_flags |= DI_FLAGS_LOCK;
+ } else {
+ di->di_flags &= ~DI_FLAGS_LOCK;
+ }
+ tv_item_lock(&di->di_tv, deep, lock);
}
- tv_item_lock(&di->di_tv, deep, lock);
}
} else if (lp->ll_range) {
listitem_T *li = lp->ll_li;
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index 0b4cbb3b4d..06b7f9e21d 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -233,6 +233,8 @@ typedef enum {
kDictListItems, ///< List dictionary contents: [keys, values].
} DictListType;
+typedef int (*ex_unletlock_callback)(lval_T *, char_u *, exarg_T *, int);
+
// Used for checking if local variables or arguments used in a lambda.
extern bool *eval_lavars_used;
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index b08ee3794d..4df935469a 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -7044,7 +7044,8 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(buf);
}
# else
- rettv->vval.v_string = (char_u *)xstrdup(p);
+ char *v = os_realpath(fname, NULL);
+ rettv->vval.v_string = (char_u *)(v == NULL ? xstrdup(fname) : v);
# endif
#endif
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index d2ccbe3e6d..b0a51eaefd 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -1965,7 +1965,12 @@ void do_wqall(exarg_T *eap)
}
FOR_ALL_BUFFERS(buf) {
- if (!bufIsChanged(buf) || bt_dontwrite(buf)) {
+ if (exiting
+ && buf->terminal
+ && channel_job_running((uint64_t)buf->b_p_channel)) {
+ no_write_message_nobang(buf);
+ error++;
+ } else if (!bufIsChanged(buf) || bt_dontwrite(buf)) {
continue;
}
/*
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 6b03117ff3..3b9c44c3cd 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -1297,7 +1297,7 @@ bool check_changed(buf_T *buf, int flags)
if (flags & CCGD_EXCMD) {
no_write_message();
} else {
- no_write_message_nobang();
+ no_write_message_nobang(curbuf);
}
return true;
}
@@ -1503,8 +1503,10 @@ bool check_changed_any(bool hidden, bool unload)
msg_col = 0;
msg_didout = false;
}
- if (EMSG2(_("E162: No write since last change for buffer \"%s\""),
- buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname)) {
+ if ((buf->terminal && channel_job_running((uint64_t)buf->b_p_channel))
+ ? EMSG2(_("E947: Job still running in buffer \"%s\""), buf->b_fname)
+ : EMSG2(_("E162: No write since last change for buffer \"%s\""),
+ buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname)) {
save = no_wait_return;
no_wait_return = false;
wait_return(false);
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 0100be15bc..ed408c28e5 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1024,7 +1024,7 @@ static int command_line_execute(VimState *state, int key)
}
// free expanded names when finished walking through matches
- if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm
+ if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm && s->c != Ctrl_Z
&& s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A
&& s->c != Ctrl_L) {
if (compl_match_array) {
@@ -1328,7 +1328,8 @@ static int command_line_execute(VimState *state, int key)
// - hitting <ESC> twice means: abandon command line.
// - wildcard expansion is only done when the 'wildchar' key is really
// typed, not when it comes from a macro
- if ((s->c == p_wc && !s->gotesc && KeyTyped) || s->c == p_wcm) {
+ if ((s->c == p_wc && !s->gotesc && KeyTyped) || s->c == p_wcm
+ || s->c == Ctrl_Z) {
int options = WILD_NO_BEEP;
if (wim_flags[s->wim_index] & WIM_BUFLASTUSED) {
options |= WILD_BUFLASTUSED;
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 0a3c30134b..344a2387d6 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -927,7 +927,7 @@ void nlua_typval_eval(const String str, typval_T *const arg,
memcpy(lcmd + sizeof(EVALHEADER) - 1, str.data, str.size);
lcmd[lcmd_len - 1] = ')';
#undef EVALHEADER
- typval_exec_lua(lcmd, lcmd_len, "luaeval()", arg, 1, true, ret_tv);
+ nlua_typval_exec(lcmd, lcmd_len, "luaeval()", arg, 1, true, ret_tv);
if (lcmd != (char *)IObuff) {
xfree(lcmd);
@@ -954,16 +954,16 @@ void nlua_typval_call(const char *str, size_t len, typval_T *const args,
#undef CALLHEADER
#undef CALLSUFFIX
- typval_exec_lua(lcmd, lcmd_len, "v:lua", args, argcount, false, ret_tv);
+ nlua_typval_exec(lcmd, lcmd_len, "v:lua", args, argcount, false, ret_tv);
if (lcmd != (char *)IObuff) {
xfree(lcmd);
}
}
-static void typval_exec_lua(const char *lcmd, size_t lcmd_len, const char *name,
- typval_T *const args, int argcount, bool special,
- typval_T *ret_tv)
+static void nlua_typval_exec(const char *lcmd, size_t lcmd_len,
+ const char *name, typval_T *const args,
+ int argcount, bool special, typval_T *ret_tv)
{
if (check_secure()) {
if (ret_tv) {
@@ -1140,7 +1140,7 @@ void ex_lua(exarg_T *const eap)
xfree(code);
return;
}
- typval_exec_lua(code, len, ":lua", NULL, 0, false, NULL);
+ nlua_typval_exec(code, len, ":lua", NULL, 0, false, NULL);
xfree(code);
}
@@ -1231,17 +1231,30 @@ void ex_luado(exarg_T *const eap)
void ex_luafile(exarg_T *const eap)
FUNC_ATTR_NONNULL_ALL
{
+ nlua_exec_file((const char *)eap->arg);
+}
+
+/// execute lua code from a file.
+///
+/// @param path path of the file
+///
+/// @return true if everything ok, false if there was an error (echoed)
+bool nlua_exec_file(const char *path)
+ FUNC_ATTR_NONNULL_ALL
+{
lua_State *const lstate = nlua_enter();
- if (luaL_loadfile(lstate, (const char *)eap->arg)) {
+ if (luaL_loadfile(lstate, path)) {
nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s"));
- return;
+ return false;
}
if (lua_pcall(lstate, 0, 0, 0)) {
nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
- return;
+ return false;
}
+
+ return true;
}
static void nlua_add_treesitter(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 63249416b1..79c165419e 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -1069,9 +1069,14 @@ static void command_line_scan(mparm_T *parmp)
} else {
a = argv[0];
}
- size_t s_size = STRLEN(a) + 4;
+
+ size_t s_size = STRLEN(a) + 9;
char *s = xmalloc(s_size);
- snprintf(s, s_size, "so %s", a);
+ if (path_with_extension(a, "lua")) {
+ snprintf(s, s_size, "luafile %s", a);
+ } else {
+ snprintf(s, s_size, "so %s", a);
+ }
parmp->cmds_tofree[parmp->n_commands] = true;
parmp->commands[parmp->n_commands++] = s;
} else {
@@ -1770,6 +1775,23 @@ static bool do_user_initialization(void)
do_exrc = p_exrc;
return do_exrc;
}
+
+ char_u *init_lua_path = (char_u *)stdpaths_user_conf_subpath("init.lua");
+ if (os_path_exists(init_lua_path)
+ && nlua_exec_file((const char *)init_lua_path)) {
+ os_setenv("MYVIMRC", (const char *)init_lua_path, 1);
+ char_u *vimrc_path = (char_u *)stdpaths_user_conf_subpath("init.vim");
+
+ if (os_path_exists(vimrc_path)) {
+ EMSG3(_("Conflicting configs: \"%s\" \"%s\""), init_lua_path, vimrc_path);
+ }
+
+ xfree(vimrc_path);
+ xfree(init_lua_path);
+ return false;
+ }
+ xfree(init_lua_path);
+
char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim");
if (do_source(user_vimrc, true, DOSO_VIMRC) != FAIL) {
do_exrc = p_exrc;
@@ -1829,8 +1851,12 @@ static void source_startup_scripts(const mparm_T *const parmp)
|| strequal(parmp->use_vimrc, "NORC")) {
// Do nothing.
} else {
- if (do_source((char_u *)parmp->use_vimrc, false, DOSO_NONE) != OK) {
- EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
+ if (path_with_extension(parmp->use_vimrc, "lua")) {
+ nlua_exec_file(parmp->use_vimrc);
+ } else {
+ if (do_source((char_u *)parmp->use_vimrc, false, DOSO_NONE) != OK) {
+ EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
+ }
}
}
} else if (!silent_mode) {
diff --git a/src/nvim/message.c b/src/nvim/message.c
index f76a408481..ad38e6d060 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -1711,8 +1711,11 @@ void msg_prt_line(char_u *s, int list)
} else if ((l = utfc_ptr2len(s)) > 1) {
col += utf_ptr2cells(s);
char buf[MB_MAXBYTES + 1];
- if (curwin->w_p_lcs_chars.nbsp != NUL && list
- && (utf_ptr2char(s) == 160 || utf_ptr2char(s) == 0x202f)) {
+ if (l >= MB_MAXBYTES) {
+ xstrlcpy(buf, "¿", sizeof(buf));
+ } else if (curwin->w_p_lcs_chars.nbsp != NUL && list
+ && (utf_ptr2char(s) == 160
+ || utf_ptr2char(s) == 0x202f)) {
utf_char2bytes(curwin->w_p_lcs_chars.nbsp, (char_u *)buf);
buf[utfc_ptr2len((char_u *)buf)] = NUL;
} else {
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 0034117ddc..acca6fe681 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -352,9 +352,6 @@ void set_init_1(bool clean_arg)
langmap_init();
- // Be nocompatible
- p_cp = false;
-
/*
* Find default value for 'shell' option.
* Don't use it if it is empty.
@@ -683,7 +680,7 @@ set_options_default(
{
for (int i = 0; options[i].fullname; i++) {
if (!(options[i].flags & P_NODEFAULT)) {
- set_option_default(i, opt_flags, p_cp);
+ set_option_default(i, opt_flags, false);
}
}
@@ -763,7 +760,7 @@ void set_init_2(bool headless)
// which results in the actual value computed from the window height.
idx = findoption("scroll");
if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) {
- set_option_default(idx, OPT_LOCAL, p_cp);
+ set_option_default(idx, OPT_LOCAL, false);
}
comp_col();
@@ -1113,7 +1110,7 @@ int do_set(
if (vim_strchr((char_u *)"?=:!&<", nextchar) != NULL) {
arg += len;
- cp_val = p_cp;
+ cp_val = false;
if (nextchar == '&' && arg[1] == 'v' && arg[2] == 'i') {
if (arg[3] == 'm') { // "opt&vim": set to Vim default
cp_val = false;
@@ -3617,10 +3614,14 @@ static void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
{
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
int indir = (int)options[opt_idx].indir;
- const LastSet last_set = { .script_ctx =
- { script_ctx.sc_sid, script_ctx.sc_seq,
- script_ctx.sc_lnum + sourcing_lnum },
- current_channel_id };
+ const LastSet last_set = {
+ .script_ctx = {
+ script_ctx.sc_sid,
+ script_ctx.sc_seq,
+ script_ctx.sc_lnum + sourcing_lnum
+ },
+ current_channel_id
+ };
// Remember where the option was set. For local options need to do that
// in the buffer or window structure.
@@ -4950,7 +4951,7 @@ static int optval_default(vimoption_T *p, char_u *varp)
if (varp == NULL) {
return true; // hidden option is always at default
}
- dvi = ((p->flags & P_VI_DEF) || p_cp) ? VI_DEFAULT : VIM_DEFAULT;
+ dvi = (p->flags & P_VI_DEF) ? VI_DEFAULT : VIM_DEFAULT;
if (p->flags & P_NUM) {
return *(long *)varp == (long)(intptr_t)p->def_val[dvi];
}
@@ -7174,3 +7175,75 @@ long get_sidescrolloff_value(void)
{
return curwin->w_p_siso < 0 ? p_siso : curwin->w_p_siso;
}
+
+Dictionary get_vimoption(String name, Error *err)
+{
+ int opt_idx = findoption_len((const char *)name.data, name.size);
+ if (opt_idx < 0) {
+ api_set_error(err, kErrorTypeValidation, "no such option: '%s'", name.data);
+ return (Dictionary)ARRAY_DICT_INIT;
+ }
+ return vimoption2dict(&options[opt_idx]);
+}
+
+Dictionary get_all_vimoptions(void)
+{
+ Dictionary retval = ARRAY_DICT_INIT;
+ for (size_t i = 0; i < PARAM_COUNT; i++) {
+ Dictionary opt_dict = vimoption2dict(&options[i]);
+ PUT(retval, options[i].fullname, DICTIONARY_OBJ(opt_dict));
+ }
+ return retval;
+}
+
+static Dictionary vimoption2dict(vimoption_T *opt)
+{
+ Dictionary dict = ARRAY_DICT_INIT;
+
+ PUT(dict, "name", CSTR_TO_OBJ(opt->fullname));
+ PUT(dict, "shortname", CSTR_TO_OBJ(opt->shortname));
+
+ const char *scope;
+ if (opt->indir & PV_BUF) {
+ scope = "buf";
+ } else if (opt->indir & PV_WIN) {
+ scope = "win";
+ } else {
+ scope = "global";
+ }
+
+ PUT(dict, "scope", CSTR_TO_OBJ(scope));
+
+ // welcome to the jungle
+ PUT(dict, "global_local", BOOL(opt->indir & PV_BOTH));
+ PUT(dict, "commalist", BOOL(opt->flags & P_COMMA));
+ PUT(dict, "flaglist", BOOL(opt->flags & P_FLAGLIST));
+
+ PUT(dict, "was_set", BOOL(opt->flags & P_WAS_SET));
+
+ PUT(dict, "last_set_sid", INTEGER_OBJ(opt->last_set.script_ctx.sc_sid));
+ PUT(dict, "last_set_linenr", INTEGER_OBJ(opt->last_set.script_ctx.sc_lnum));
+ PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)opt->last_set.channel_id));
+
+ const char *type;
+ Object def;
+ // TODO(bfredl): do you even nocp?
+ char_u *def_val = opt->def_val[(opt->flags & P_VI_DEF)
+ ? VI_DEFAULT : VIM_DEFAULT];
+ if (opt->flags & P_STRING) {
+ type = "string";
+ def = CSTR_TO_OBJ(def_val ? (char *)def_val : "");
+ } else if (opt->flags & P_NUM) {
+ type = "number";
+ def = INTEGER_OBJ((Integer)(intptr_t)def_val);
+ } else if (opt->flags & P_BOOL) {
+ type = "boolean";
+ def = BOOL((intptr_t)def_val);
+ } else {
+ type = ""; def = NIL;
+ }
+ PUT(dict, "type", CSTR_TO_OBJ(type));
+ PUT(dict, "default", def);
+
+ return dict;
+}
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index af0ea7f4a2..ec2160d365 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -372,7 +372,6 @@ EXTERN long p_cwh; // 'cmdwinheight'
EXTERN long p_ch; // 'cmdheight'
EXTERN long p_columns; // 'columns'
EXTERN int p_confirm; // 'confirm'
-EXTERN int p_cp; // 'compatible'
EXTERN char_u *p_cot; // 'completeopt'
# ifdef BACKSLASH_IN_FILENAME
EXTERN char_u *p_csl; // 'completeslash'
diff --git a/src/nvim/path.c b/src/nvim/path.c
index f52fbbd5c8..2de7e00ddb 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -1704,6 +1704,13 @@ int path_with_url(const char *fname)
return path_is_url(p);
}
+bool path_with_extension(const char *path, const char *extension)
+{
+ const char *last_dot = strrchr(path, '.');
+ if (!last_dot) { return false; }
+ return strcmp(last_dot + 1, extension) == 0;
+}
+
/*
* Return TRUE if "name" is a full (absolute) path name or URL.
*/
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 3d7d587ed2..7fdc998e20 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -6155,7 +6155,7 @@ static int qf_setprop_items_from_lines(
qf_free_items(&qi->qf_lists[qf_idx]);
}
if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, errorformat,
- false, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) {
+ false, (linenr_T)0, (linenr_T)0, NULL, NULL) >= 0) {
retval = OK;
}
@@ -6256,9 +6256,12 @@ static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action,
retval = qf_setprop_curidx(qi, qfl, di);
}
- if (retval == OK) {
+ if (newlist || retval == OK) {
qf_list_changed(qfl);
}
+ if (newlist) {
+ qf_update_buffer(qi, NULL);
+ }
return retval;
}
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 90e1e25de2..787a464070 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -89,7 +89,7 @@ static struct spat spats[2] =
static int last_idx = 0; /* index in spats[] for RE_LAST */
static char_u lastc[2] = { NUL, NUL }; // last character searched for
-static int lastcdir = FORWARD; // last direction of character search
+static Direction lastcdir = FORWARD; // last direction of character search
static int last_t_cmd = true; // last search t_cmd
static char_u lastc_bytes[MB_MAXBYTES + 1];
static int lastc_bytelen = 1; // >1 for multi-byte char
@@ -437,7 +437,7 @@ void set_last_csearch(int c, char_u *s, int len)
memset(lastc_bytes, 0, sizeof(lastc_bytes));
}
-void set_csearch_direction(int cdir)
+void set_csearch_direction(Direction cdir)
{
lastcdir = cdir;
}
@@ -1430,7 +1430,7 @@ end_do_search:
* ADDING is set. If p_ic is set then the pattern must be in lowercase.
* Return OK for success, or FAIL if no line found.
*/
-int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat)
+int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat)
{
linenr_T start = 0;
char_u *ptr;
@@ -1496,10 +1496,11 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat)
* Return FAIL or OK.
*/
int searchc(cmdarg_T *cap, int t_cmd)
+ FUNC_ATTR_NONNULL_ALL
{
- int c = cap->nchar; /* char to search for */
- int dir = cap->arg; /* TRUE for searching forward */
- long count = cap->count1; /* repeat count */
+ int c = cap->nchar; // char to search for
+ Direction dir = cap->arg; // TRUE for searching forward
+ long count = cap->count1; // repeat count
int col;
char_u *p;
int len;
@@ -4462,7 +4463,7 @@ static void search_stat(int dirc, pos_T *pos,
void
find_pattern_in_path(
char_u *ptr, // pointer to search pattern
- int dir, // direction of expansion
+ Direction dir, // direction of expansion
size_t len, // length of search pattern
bool whole, // match whole words only
bool skip_comments, // don't match inside comments
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 797fe41320..5714f5e425 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -79,7 +79,6 @@
/* for offsetof() */
#include <stddef.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/spell.h"
#include "nvim/buffer.h"
@@ -6653,7 +6652,7 @@ void
spell_dump_compl (
char_u *pat, // leading part of the word
int ic, // ignore case
- int *dir, // direction for adding matches
+ Direction *dir, // direction for adding matches
int dumpflags_arg // DUMPFLAG_*
)
{
@@ -6820,7 +6819,9 @@ spell_dump_compl (
// Dumps one word: apply case modifications and append a line to the buffer.
// When "lnum" is zero add insert mode completion.
-static void dump_word(slang_T *slang, char_u *word, char_u *pat, int *dir, int dumpflags, int wordflags, linenr_T lnum)
+static void dump_word(slang_T *slang, char_u *word, char_u *pat,
+ Direction *dir, int dumpflags, int wordflags,
+ linenr_T lnum)
{
bool keepcap = false;
char_u *p;
@@ -6906,7 +6907,7 @@ dump_prefixes (
slang_T *slang,
char_u *word, // case-folded word
char_u *pat,
- int *dir,
+ Direction *dir,
int dumpflags,
int flags, // flags with prefix ID
linenr_T startlnum
diff --git a/src/nvim/spell.h b/src/nvim/spell.h
index ad66df4c5d..e93c82b91d 100644
--- a/src/nvim/spell.h
+++ b/src/nvim/spell.h
@@ -6,6 +6,7 @@
#include "nvim/spell_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/globals.h"
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "spell.h.generated.h"
diff --git a/src/nvim/testdir/test49.vim b/src/nvim/testdir/test49.vim
index c86fdf25ab..5468f7c4aa 100644
--- a/src/nvim/testdir/test49.vim
+++ b/src/nvim/testdir/test49.vim
@@ -318,7 +318,7 @@ let ExtraVimCount = 0
let ExtraVimBase = expand("<sfile>")
let ExtraVimTestEnv = ""
"
-function! ExtraVim(...)
+function ExtraVim(...)
" Count how often this function is called.
let g:ExtraVimCount = g:ExtraVimCount + 1
@@ -500,7 +500,7 @@ endfunction
" an ExtraVim script as passed by ExtraVim() in ExtraVimBegin.
"
" EXTRA_VIM_START - do not change or remove this line.
-function! ExtraVimThrowpoint()
+function ExtraVimThrowpoint()
if !exists("g:ExtraVimBegin")
Xout "ExtraVimThrowpoint() used outside ExtraVim() script."
return v:throwpoint
@@ -530,7 +530,7 @@ endfunction
" as a script file, use ExecAsScript below.
"
" EXTRA_VIM_START - do not change or remove this line.
-function! MakeScript(funcname, ...)
+function MakeScript(funcname, ...)
let script = tempname()
execute "redir! >" . script
execute "function" a:funcname
@@ -568,7 +568,7 @@ endfunction
" location specified in the function.
"
" EXTRA_VIM_START - do not change or remove this line.
-function! ExecAsScript(funcname)
+function ExecAsScript(funcname)
" Make a script from the function passed as argument.
let script = MakeScript(a:funcname)
@@ -3694,7 +3694,7 @@ endif
if ExtraVim(msgfile)
try
Xpath 4194304 " X: 4194304
- let x = novar " error E121/E15; exception: E121
+ let x = novar " error E121; exception: E121
catch /E15:/ " should not catch
Xpath 8388608 " X: 0
endtry
@@ -3702,7 +3702,7 @@ if ExtraVim(msgfile)
endif
Xpath 33554432 " X: 33554432
-if !MESSAGES('E121', "Undefined variable", 'E15', "Invalid expression")
+if !MESSAGES('E121', "Undefined variable")
Xpath 67108864 " X: 0
endif
@@ -8548,7 +8548,7 @@ endfunction
" Remove the autocommands for the events specified as arguments in all used
" autogroups.
-function! Delete_autocommands(...)
+function Delete_autocommands(...)
let augfile = tempname()
while 1
try
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index 7647475427..4f056abdc0 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -1,7 +1,6 @@
" A series of tests that can run in one Vim invocation.
" This makes testing go faster, since Vim doesn't need to restart.
-source test_assign.vim
source test_backup.vim
source test_behave.vim
source test_cd.vim
diff --git a/src/nvim/testdir/test_assign.vim b/src/nvim/testdir/test_assign.vim
deleted file mode 100644
index 50415ad6fd..0000000000
--- a/src/nvim/testdir/test_assign.vim
+++ /dev/null
@@ -1,47 +0,0 @@
-" Test for assignment
-
-func Test_no_type_checking()
- let v = 1
- let v = [1,2,3]
- let v = {'a': 1, 'b': 2}
- let v = 3.4
- let v = 'hello'
-endfunc
-
-func Test_let_termcap()
- " Nvim does not support `:set termcap`.
- return
- " Terminal code
- let old_t_te = &t_te
- let &t_te = "\<Esc>[yes;"
- call assert_match('t_te.*^[[yes;', execute("set termcap"))
- let &t_te = old_t_te
-
- if exists("+t_k1")
- " Key code
- let old_t_k1 = &t_k1
- let &t_k1 = "that"
- call assert_match('t_k1.*that', execute("set termcap"))
- let &t_k1 = old_t_k1
- endif
-
- call assert_fails('let x = &t_xx', 'E15')
- let &t_xx = "yes"
- call assert_equal("yes", &t_xx)
- let &t_xx = ""
- call assert_fails('let x = &t_xx', 'E15')
-endfunc
-
-func Test_let_option_error()
- let _w = &tw
- let &tw = 80
- call assert_fails('let &tw .= 1', 'E734')
- call assert_equal(80, &tw)
- let &tw = _w
-
- let _w = &fillchars
- let &fillchars = "vert:|"
- call assert_fails('let &fillchars += "diff:-"', 'E734')
- call assert_equal("vert:|", &fillchars)
- let &fillchars = _w
-endfunc
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index 1fa7eeaea0..641e98ab30 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -1359,7 +1359,7 @@ func Test_ChangedP()
endfunc
let g:setline_handled = v:false
-func! SetLineOne()
+func SetLineOne()
if !g:setline_handled
call setline(1, "(x)")
let g:setline_handled = v:true
diff --git a/src/nvim/testdir/test_charsearch.vim b/src/nvim/testdir/test_charsearch.vim
index 8b313b5a35..17a49e02be 100644
--- a/src/nvim/testdir/test_charsearch.vim
+++ b/src/nvim/testdir/test_charsearch.vim
@@ -1,5 +1,5 @@
-function! Test_charsearch()
+func Test_charsearch()
enew!
call append(0, ['Xabcdefghijkemnopqretuvwxyz',
\ 'Yabcdefghijkemnopqretuvwxyz',
@@ -29,10 +29,10 @@ function! Test_charsearch()
normal! ;;p
call assert_equal('ZabcdeZfghijkZZemnokqretkZvwxyz', getline(3))
enew!
-endfunction
+endfunc
" Test for t,f,F,T movement commands and 'cpo-;' setting
-function! Test_search_cmds()
+func Test_search_cmds()
enew!
call append(0, ["aaa two three four", " zzz", "yyy ",
\ "bbb yee yoo four", "ccc two three four",
@@ -59,4 +59,4 @@ function! Test_search_cmds()
call assert_equal('ccc', getline(5))
call assert_equal('ddd yee y', getline(6))
enew!
-endfunction
+endfunc
diff --git a/src/nvim/testdir/test_charsearch_utf8.vim b/src/nvim/testdir/test_charsearch_utf8.vim
index eac5d46ad8..09341a90b0 100644
--- a/src/nvim/testdir/test_charsearch_utf8.vim
+++ b/src/nvim/testdir/test_charsearch_utf8.vim
@@ -14,6 +14,6 @@ function! Test_search_cmds()
normal! ,
call assert_equal([0, 1, 28, 0], getpos('.'))
bw!
-endfunction
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim
index abad6983dc..e1393e875b 100644
--- a/src/nvim/testdir/test_edit.vim
+++ b/src/nvim/testdir/test_edit.vim
@@ -11,7 +11,7 @@ source view_util.vim
" Needs to come first until the bug in getchar() is
" fixed: https://groups.google.com/d/msg/vim_dev/fXL9yme4H4c/bOR-U6_bAQAJ
-func! Test_edit_00b()
+func Test_edit_00b()
new
call setline(1, ['abc '])
inoreabbr <buffer> h here some more
@@ -23,7 +23,7 @@ func! Test_edit_00b()
bw!
endfunc
-func! Test_edit_01()
+func Test_edit_01()
" set for Travis CI?
" set nocp noesckeys
new
@@ -61,7 +61,7 @@ func! Test_edit_01()
bw!
endfunc
-func! Test_edit_02()
+func Test_edit_02()
" Change cursor position in InsertCharPre command
new
call setline(1, 'abc')
@@ -101,7 +101,7 @@ func! Test_edit_02()
bw!
endfunc
-func! Test_edit_03()
+func Test_edit_03()
" Change cursor after <c-o> command to end of line
new
call setline(1, 'abc')
@@ -120,7 +120,7 @@ func! Test_edit_03()
bw!
endfunc
-func! Test_edit_04()
+func Test_edit_04()
" test for :stopinsert
new
call setline(1, 'abc')
@@ -132,7 +132,7 @@ func! Test_edit_04()
bw!
endfunc
-func! Test_edit_05()
+func Test_edit_05()
" test for folds being opened
new
call setline(1, ['abcX', 'abcX', 'zzzZ'])
@@ -154,7 +154,7 @@ func! Test_edit_05()
bw!
endfunc
-func! Test_edit_06()
+func Test_edit_06()
" Test in diff mode
if !has("diff") || !executable("diff")
return
@@ -176,7 +176,7 @@ func! Test_edit_06()
bw!
endfunc
-func! Test_edit_07()
+func Test_edit_07()
" 1) Test with completion <c-l> when popupmenu is visible
new
call setline(1, 'J')
@@ -228,7 +228,7 @@ func! Test_edit_08()
unlet g:bufnr
endfunc
-func! Test_edit_09()
+func Test_edit_09()
" test i_CTRL-\ combinations
new
call setline(1, ['abc', 'def', 'ghi'])
@@ -258,7 +258,7 @@ func! Test_edit_09()
bw!
endfunc
-func! Test_edit_10()
+func Test_edit_10()
" Test for starting selectmode
new
set selectmode=key keymodel=startsel
@@ -270,7 +270,7 @@ func! Test_edit_10()
bw!
endfunc
-func! Test_edit_11()
+func Test_edit_11()
" Test that indenting kicks in
new
set cindent
@@ -314,7 +314,7 @@ func! Test_edit_11()
bw!
endfunc
-func! Test_edit_11_indentexpr()
+func Test_edit_11_indentexpr()
" Test that indenting kicks in
new
" Use indentexpr instead of cindenting
@@ -341,7 +341,7 @@ func! Test_edit_11_indentexpr()
bw!
endfunc
-func! Test_edit_12()
+func Test_edit_12()
" Test changing indent in replace mode
new
call setline(1, ["\tabc", "\tdef"])
@@ -393,7 +393,7 @@ func! Test_edit_12()
bw!
endfunc
-func! Test_edit_13()
+func Test_edit_13()
" Test smartindenting
if exists("+smartindent")
new
@@ -481,7 +481,7 @@ func! Test_edit_CTRL_()
endfunc
" needs to come first, to have the @. register empty
-func! Test_edit_00a_CTRL_A()
+func Test_edit_00a_CTRL_A()
" Test pressing CTRL-A
new
call setline(1, repeat([''], 5))
@@ -501,7 +501,7 @@ func! Test_edit_00a_CTRL_A()
bw!
endfunc
-func! Test_edit_CTRL_EY()
+func Test_edit_CTRL_EY()
" Ctrl-E/ Ctrl-Y in insert mode completion to scroll
10new
call setline(1, range(1, 100))
@@ -517,7 +517,7 @@ func! Test_edit_CTRL_EY()
bw!
endfunc
-func! Test_edit_CTRL_G()
+func Test_edit_CTRL_G()
new
call setline(1, ['foobar', 'foobar', 'foobar'])
call cursor(2, 4)
@@ -535,7 +535,7 @@ func! Test_edit_CTRL_G()
bw!
endfunc
-func! Test_edit_CTRL_I()
+func Test_edit_CTRL_I()
" Tab in completion mode
let path=expand("%:p:h")
new
@@ -559,7 +559,7 @@ func! Test_edit_CTRL_I()
bw!
endfunc
-func! Test_edit_CTRL_K()
+func Test_edit_CTRL_K()
" Test pressing CTRL-K (basically only dictionary completion and digraphs
" the rest is already covered
call writefile(['A', 'AA', 'AAA', 'AAAA'], 'Xdictionary.txt')
@@ -632,7 +632,7 @@ func! Test_edit_CTRL_K()
bw!
endfunc
-func! Test_edit_CTRL_L()
+func Test_edit_CTRL_L()
" Test Ctrl-X Ctrl-L (line completion)
new
set complete=.
@@ -688,7 +688,7 @@ func! Test_edit_CTRL_L()
bw!
endfunc
-func! Test_edit_CTRL_N()
+func Test_edit_CTRL_N()
" Check keyword completion
new
set complete=.
@@ -709,7 +709,7 @@ func! Test_edit_CTRL_N()
bw!
endfunc
-func! Test_edit_CTRL_O()
+func Test_edit_CTRL_O()
" Check for CTRL-O in insert mode
new
inoreabbr <buffer> h here some more
@@ -749,7 +749,7 @@ func! Test_edit_CTRL_R()
bw!
endfunc
-func! Test_edit_CTRL_S()
+func Test_edit_CTRL_S()
" Test pressing CTRL-S (basically only spellfile completion)
" the rest is already covered
new
@@ -793,7 +793,7 @@ func! Test_edit_CTRL_S()
bw!
endfunc
-func! Test_edit_CTRL_T()
+func Test_edit_CTRL_T()
" Check for CTRL-T and CTRL-X CTRL-T in insert mode
" 1) increase indent
new
@@ -870,7 +870,7 @@ func! Test_edit_CTRL_T()
bw!
endfunc
-func! Test_edit_CTRL_U()
+func Test_edit_CTRL_U()
" Test 'completefunc'
new
" -1, -2 and -3 are special return values
@@ -929,7 +929,7 @@ func! Test_edit_CTRL_U()
bw!
endfunc
-func! Test_edit_CTRL_Z()
+func Test_edit_CTRL_Z()
" Ctrl-Z when insertmode is not set inserts it literally
new
call setline(1, 'abc')
@@ -939,7 +939,7 @@ func! Test_edit_CTRL_Z()
" TODO: How to Test Ctrl-Z in insert mode, e.g. suspend?
endfunc
-func! Test_edit_DROP()
+func Test_edit_DROP()
if !has("dnd")
return
endif
@@ -955,7 +955,7 @@ func! Test_edit_DROP()
bw!
endfunc
-func! Test_edit_CTRL_V()
+func Test_edit_CTRL_V()
if has("ebcdic")
return
endif
@@ -983,7 +983,7 @@ func! Test_edit_CTRL_V()
bw!
endfunc
-func! Test_edit_F1()
+func Test_edit_F1()
" Pressing <f1>
new
call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix')
@@ -993,7 +993,7 @@ func! Test_edit_F1()
bw
endfunc
-func! Test_edit_F21()
+func Test_edit_F21()
" Pressing <f21>
" sends a netbeans command
if has("netbeans_intg")
@@ -1004,7 +1004,7 @@ func! Test_edit_F21()
endif
endfunc
-func! Test_edit_HOME_END()
+func Test_edit_HOME_END()
" Test Home/End Keys
new
set foldopen+=hor
@@ -1019,7 +1019,7 @@ func! Test_edit_HOME_END()
bw!
endfunc
-func! Test_edit_INS()
+func Test_edit_INS()
" Test for Pressing <Insert>
new
call setline(1, ['abc', 'def'])
@@ -1033,7 +1033,7 @@ func! Test_edit_INS()
bw!
endfunc
-func! Test_edit_LEFT_RIGHT()
+func Test_edit_LEFT_RIGHT()
" Left, Shift-Left, Right, Shift-Right
new
call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX'])
@@ -1080,7 +1080,7 @@ func! Test_edit_LEFT_RIGHT()
bw!
endfunc
-func! Test_edit_MOUSE()
+func Test_edit_MOUSE()
" This is a simple test, since we not really using the mouse here
if !has("mouse")
return
@@ -1135,7 +1135,7 @@ func! Test_edit_MOUSE()
bw!
endfunc
-func! Test_edit_PAGEUP_PAGEDOWN()
+func Test_edit_PAGEUP_PAGEDOWN()
10new
call setline(1, repeat(['abc def ghi'], 30))
call cursor(1, 1)
@@ -1234,7 +1234,7 @@ func! Test_edit_PAGEUP_PAGEDOWN()
bw!
endfunc
-func! Test_edit_forbidden()
+func Test_edit_forbidden()
new
" 1) edit in the sandbox is not allowed
call setline(1, 'a')
@@ -1294,7 +1294,7 @@ func! Test_edit_forbidden()
bw!
endfunc
-func! Test_edit_rightleft()
+func Test_edit_rightleft()
" Cursor in rightleft mode moves differently
if !exists("+rightleft")
return
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 52b5884c8b..f3c3e085f6 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -471,7 +471,6 @@ let s:filename_checks = {
\ 'tssgm': ['file.tssgm'],
\ 'tssop': ['file.tssop'],
\ 'twig': ['file.twig'],
- \ 'typescript': ['file.ts'],
\ 'typescriptreact': ['file.tsx'],
\ 'uc': ['file.uc'],
\ 'udevconf': ['/etc/udev/udev.conf'],
@@ -668,5 +667,22 @@ func Test_hook_file()
filetype off
endfunc
+func Test_ts_file()
+ filetype on
+
+ call writefile(['<?xml version="1.0" encoding="utf-8"?>'], 'Xfile.ts')
+ split Xfile.ts
+ call assert_equal('xml', &filetype)
+ bwipe!
+
+ call writefile(['// looks like Typescript'], 'Xfile.ts')
+ split Xfile.ts
+ call assert_equal('typescript', &filetype)
+ bwipe!
+
+ call delete('Xfile.hook')
+ filetype off
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_fnameescape.vim b/src/nvim/testdir/test_fnameescape.vim
index cdff0dfbd9..5382b89aa6 100644
--- a/src/nvim/testdir/test_fnameescape.vim
+++ b/src/nvim/testdir/test_fnameescape.vim
@@ -1,6 +1,6 @@
" Test if fnameescape is correct for special chars like !
-function! Test_fnameescape()
+func Test_fnameescape()
let fname = 'Xspa ce'
let status = v:false
try
@@ -18,4 +18,4 @@ function! Test_fnameescape()
endtry
call assert_true(status, "ExclamationMark")
call delete(fname)
-endfunction
+endfunc
diff --git a/src/nvim/testdir/test_getcwd.vim b/src/nvim/testdir/test_getcwd.vim
index 5d97295e9a..ca098781e4 100644
--- a/src/nvim/testdir/test_getcwd.vim
+++ b/src/nvim/testdir/test_getcwd.vim
@@ -1,112 +1,112 @@
-function! GetCwdInfo(win, tab)
- let tab_changed = 0
- let mod = ":t"
- if a:tab > 0 && a:tab != tabpagenr()
- let tab_changed = 1
- exec "tabnext " . a:tab
- endif
- let bufname = fnamemodify(bufname(winbufnr(a:win)), mod)
- if tab_changed
- tabprevious
- endif
- if a:win == 0 && a:tab == 0
- let dirname = fnamemodify(getcwd(), mod)
- let lflag = haslocaldir()
- elseif a:tab == 0
- let dirname = fnamemodify(getcwd(a:win), mod)
- let lflag = haslocaldir(a:win)
- else
- let dirname = fnamemodify(getcwd(a:win, a:tab), mod)
- let lflag = haslocaldir(a:win, a:tab)
- endif
- return bufname . ' ' . dirname . ' ' . lflag
-endfunction
+func GetCwdInfo(win, tab)
+ let tab_changed = 0
+ let mod = ":t"
+ if a:tab > 0 && a:tab != tabpagenr()
+ let tab_changed = 1
+ exec "tabnext " . a:tab
+ endif
+ let bufname = fnamemodify(bufname(winbufnr(a:win)), mod)
+ if tab_changed
+ tabprevious
+ endif
+ if a:win == 0 && a:tab == 0
+ let dirname = fnamemodify(getcwd(), mod)
+ let lflag = haslocaldir()
+ elseif a:tab == 0
+ let dirname = fnamemodify(getcwd(a:win), mod)
+ let lflag = haslocaldir(a:win)
+ else
+ let dirname = fnamemodify(getcwd(a:win, a:tab), mod)
+ let lflag = haslocaldir(a:win, a:tab)
+ endif
+ return bufname . ' ' . dirname . ' ' . lflag
+endfunc
" Do all test in a separate window to avoid E211 when we recursively
" delete the Xtopdir directory during cleanup
function SetUp()
- set visualbell
- set nocp viminfo+=nviminfo
+ set visualbell
+ set nocp viminfo+=nviminfo
- " On windows a swapfile in Xtopdir prevents it from being cleaned up.
- set noswapfile
+ " On windows a swapfile in Xtopdir prevents it from being cleaned up.
+ set noswapfile
- " On windows a stale "Xtopdir" directory may exist, remove it so that
- " we start from a clean state.
- call delete("Xtopdir", "rf")
- new
- call mkdir('Xtopdir')
- cd Xtopdir
- let g:topdir = getcwd()
- call mkdir('Xdir1')
- call mkdir('Xdir2')
- call mkdir('Xdir3')
+ " On windows a stale "Xtopdir" directory may exist, remove it so that
+ " we start from a clean state.
+ call delete("Xtopdir", "rf")
+ new
+ call mkdir('Xtopdir')
+ cd Xtopdir
+ let g:topdir = getcwd()
+ call mkdir('Xdir1')
+ call mkdir('Xdir2')
+ call mkdir('Xdir3')
endfunction
let g:cwd=getcwd()
function TearDown()
- q
- exec "cd " . g:cwd
- call delete("Xtopdir", "rf")
+ q
+ exec "cd " . g:cwd
+ call delete("Xtopdir", "rf")
endfunction
function Test_GetCwd()
- new a
- new b
- new c
- 3wincmd w
- lcd Xdir1
- call assert_equal("a Xdir1 1", GetCwdInfo(0, 0))
- call assert_equal(g:topdir, getcwd(-1))
- wincmd W
- call assert_equal("b Xtopdir 0", GetCwdInfo(0, 0))
- call assert_equal(g:topdir, getcwd(-1))
- wincmd W
- lcd Xdir3
- call assert_equal("c Xdir3 1", GetCwdInfo(0, 0))
- call assert_equal("a Xdir1 1", GetCwdInfo(bufwinnr("a"), 0))
- call assert_equal("b Xtopdir 0", GetCwdInfo(bufwinnr("b"), 0))
- call assert_equal("c Xdir3 1", GetCwdInfo(bufwinnr("c"), 0))
- call assert_equal(g:topdir, getcwd(-1))
- wincmd W
- call assert_equal("a Xdir1 1", GetCwdInfo(bufwinnr("a"), tabpagenr()))
- call assert_equal("b Xtopdir 0", GetCwdInfo(bufwinnr("b"), tabpagenr()))
- call assert_equal("c Xdir3 1", GetCwdInfo(bufwinnr("c"), tabpagenr()))
- call assert_equal(g:topdir, getcwd(-1))
+ new a
+ new b
+ new c
+ 3wincmd w
+ lcd Xdir1
+ call assert_equal("a Xdir1 1", GetCwdInfo(0, 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ wincmd W
+ call assert_equal("b Xtopdir 0", GetCwdInfo(0, 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ wincmd W
+ lcd Xdir3
+ call assert_equal("c Xdir3 1", GetCwdInfo(0, 0))
+ call assert_equal("a Xdir1 1", GetCwdInfo(bufwinnr("a"), 0))
+ call assert_equal("b Xtopdir 0", GetCwdInfo(bufwinnr("b"), 0))
+ call assert_equal("c Xdir3 1", GetCwdInfo(bufwinnr("c"), 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ wincmd W
+ call assert_equal("a Xdir1 1", GetCwdInfo(bufwinnr("a"), tabpagenr()))
+ call assert_equal("b Xtopdir 0", GetCwdInfo(bufwinnr("b"), tabpagenr()))
+ call assert_equal("c Xdir3 1", GetCwdInfo(bufwinnr("c"), tabpagenr()))
+ call assert_equal(g:topdir, getcwd(-1))
- tabnew x
- new y
- new z
- 3wincmd w
- call assert_equal("x Xtopdir 0", GetCwdInfo(0, 0))
- call assert_equal(g:topdir, getcwd(-1))
- wincmd W
- lcd Xdir2
- call assert_equal("y Xdir2 1", GetCwdInfo(0, 0))
- call assert_equal(g:topdir, getcwd(-1))
- wincmd W
- lcd Xdir3
- call assert_equal("z Xdir3 1", GetCwdInfo(0, 0))
- call assert_equal("x Xtopdir 0", GetCwdInfo(bufwinnr("x"), 0))
- call assert_equal("y Xdir2 1", GetCwdInfo(bufwinnr("y"), 0))
- call assert_equal("z Xdir3 1", GetCwdInfo(bufwinnr("z"), 0))
- call assert_equal(g:topdir, getcwd(-1))
- let tp_nr = tabpagenr()
- tabrewind
- call assert_equal("x Xtopdir 0", GetCwdInfo(3, tp_nr))
- call assert_equal("y Xdir2 1", GetCwdInfo(2, tp_nr))
- call assert_equal("z Xdir3 1", GetCwdInfo(1, tp_nr))
- call assert_equal(g:topdir, getcwd(-1))
+ tabnew x
+ new y
+ new z
+ 3wincmd w
+ call assert_equal("x Xtopdir 0", GetCwdInfo(0, 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ wincmd W
+ lcd Xdir2
+ call assert_equal("y Xdir2 1", GetCwdInfo(0, 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ wincmd W
+ lcd Xdir3
+ call assert_equal("z Xdir3 1", GetCwdInfo(0, 0))
+ call assert_equal("x Xtopdir 0", GetCwdInfo(bufwinnr("x"), 0))
+ call assert_equal("y Xdir2 1", GetCwdInfo(bufwinnr("y"), 0))
+ call assert_equal("z Xdir3 1", GetCwdInfo(bufwinnr("z"), 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ let tp_nr = tabpagenr()
+ tabrewind
+ call assert_equal("x Xtopdir 0", GetCwdInfo(3, tp_nr))
+ call assert_equal("y Xdir2 1", GetCwdInfo(2, tp_nr))
+ call assert_equal("z Xdir3 1", GetCwdInfo(1, tp_nr))
+ call assert_equal(g:topdir, getcwd(-1))
endfunc
function Test_GetCwd_lcd_shellslash()
- new
- let root = fnamemodify('/', ':p')
- exe 'lcd '.root
- let cwd = getcwd()
- if !exists('+shellslash') || &shellslash
- call assert_equal(cwd[-1:], '/')
- else
- call assert_equal(cwd[-1:], '\')
- endif
+ new
+ let root = fnamemodify('/', ':p')
+ exe 'lcd '.root
+ let cwd = getcwd()
+ if !exists('+shellslash') || &shellslash
+ call assert_equal(cwd[-1:], '/')
+ else
+ call assert_equal(cwd[-1:], '\')
+ endif
endfunc
diff --git a/src/nvim/testdir/test_highlight.vim b/src/nvim/testdir/test_highlight.vim
index a80a73161f..8f6834c2ab 100644
--- a/src/nvim/testdir/test_highlight.vim
+++ b/src/nvim/testdir/test_highlight.vim
@@ -39,15 +39,15 @@ func Test_highlight()
call assert_fails("hi Crash term='asdf", "E475:")
endfunc
-function! HighlightArgs(name)
+func HighlightArgs(name)
return 'hi ' . substitute(split(execute('hi ' . a:name), '\n')[0], '\<xxx\>', '', '')
-endfunction
+endfunc
-function! IsColorable()
+func IsColorable()
return has('gui_running') || str2nr(&t_Co) >= 8
-endfunction
+endfunc
-function! HiCursorLine()
+func HiCursorLine()
let hiCursorLine = HighlightArgs('CursorLine')
if has('gui_running')
let guibg = matchstr(hiCursorLine, 'guibg=\w\+')
@@ -58,9 +58,9 @@ function! HiCursorLine()
let hi_bg = 'hi CursorLine cterm=NONE ctermbg=Gray'
endif
return [hiCursorLine, hi_ul, hi_bg]
-endfunction
+endfunc
-function! Check_lcs_eol_attrs(attrs, row, col)
+func Check_lcs_eol_attrs(attrs, row, col)
let save_lcs = &lcs
set list
@@ -68,7 +68,7 @@ function! Check_lcs_eol_attrs(attrs, row, col)
set nolist
let &lcs = save_lcs
-endfunction
+endfunc
func Test_highlight_eol_with_cursorline()
let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
diff --git a/src/nvim/testdir/test_hlsearch.vim b/src/nvim/testdir/test_hlsearch.vim
index 97f6ae7b51..cf2791113a 100644
--- a/src/nvim/testdir/test_hlsearch.vim
+++ b/src/nvim/testdir/test_hlsearch.vim
@@ -1,6 +1,6 @@
" Test for v:hlsearch
-function! Test_hlsearch()
+func Test_hlsearch()
new
call setline(1, repeat(['aaa'], 10))
set hlsearch nolazyredraw
@@ -30,7 +30,7 @@ function! Test_hlsearch()
call garbagecollect(1)
call getchar(1)
enew!
-endfunction
+endfunc
func Test_hlsearch_hangs()
if !has('reltime') || !has('float')
diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim
index 57a0a7aaf4..6fe1d29434 100644
--- a/src/nvim/testdir/test_ins_complete.vim
+++ b/src/nvim/testdir/test_ins_complete.vim
@@ -312,6 +312,24 @@ func Test_completefunc_args()
delfunc CompleteFunc
endfunc
+func CompleteTest(findstart, query)
+ if a:findstart
+ return col('.')
+ endif
+ return ['matched']
+endfunc
+
+func Test_completefunc_info()
+ new
+ set completeopt=menuone
+ set completefunc=CompleteTest
+ call feedkeys("i\<C-X>\<C-U>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
+ call assert_equal("matched{'pum_visible': 1, 'mode': 'function', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
+ bwipe!
+ set completeopt&
+ set completefunc&
+endfunc
+
" Check that when using feedkeys() typeahead does not interrupt searching for
" completions.
func Test_compl_feedkeys()
diff --git a/src/nvim/testdir/test_let.vim b/src/nvim/testdir/test_let.vim
index 0b9331ee38..a5cbd8f6a6 100644
--- a/src/nvim/testdir/test_let.vim
+++ b/src/nvim/testdir/test_let.vim
@@ -150,6 +150,59 @@ func Test_let_utf8_environment()
call assert_equal('ĀĒĪŌŪあいうえお', $a)
endfunc
+func Test_let_no_type_checking()
+ let v = 1
+ let v = [1,2,3]
+ let v = {'a': 1, 'b': 2}
+ let v = 3.4
+ let v = 'hello'
+endfunc
+
+func Test_let_termcap()
+ throw 'skipped: Nvim does not support termcap option'
+ " Terminal code
+ let old_t_te = &t_te
+ let &t_te = "\<Esc>[yes;"
+ call assert_match('t_te.*^[[yes;', execute("set termcap"))
+ let &t_te = old_t_te
+
+ if exists("+t_k1")
+ " Key code
+ let old_t_k1 = &t_k1
+ let &t_k1 = "that"
+ call assert_match('t_k1.*that', execute("set termcap"))
+ let &t_k1 = old_t_k1
+ endif
+
+ call assert_fails('let x = &t_xx', 'E113')
+ let &t_xx = "yes"
+ call assert_equal("yes", &t_xx)
+ let &t_xx = ""
+ call assert_fails('let x = &t_xx', 'E113')
+endfunc
+
+func Test_let_option_error()
+ let _w = &tw
+ let &tw = 80
+ call assert_fails('let &tw .= 1', 'E734')
+ call assert_equal(80, &tw)
+ let &tw = _w
+
+ let _w = &fillchars
+ let &fillchars = "vert:|"
+ call assert_fails('let &fillchars += "diff:-"', 'E734')
+ call assert_equal("vert:|", &fillchars)
+ let &fillchars = _w
+endfunc
+
+func Test_let_errors()
+ let s = 'abcd'
+ call assert_fails('let s[1] = 5', 'E689:')
+
+ let l = [1, 2, 3]
+ call assert_fails('let l[:] = 5', 'E709:')
+endfunc
+
func Test_let_heredoc_fails()
call assert_fails('let v =<< marker', 'E991:')
diff --git a/src/nvim/testdir/test_listlbr.vim b/src/nvim/testdir/test_listlbr.vim
index cdc5e4cc7c..d619ac0eb5 100644
--- a/src/nvim/testdir/test_listlbr.vim
+++ b/src/nvim/testdir/test_listlbr.vim
@@ -16,9 +16,9 @@ function s:screen_lines(lnum, width) abort
return ScreenLines(a:lnum, a:width)
endfunction
-function! s:compare_lines(expect, actual)
+func s:compare_lines(expect, actual)
call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
-endfunction
+endfunc
function s:test_windows(...)
call NewWindow(10, 20)
diff --git a/src/nvim/testdir/test_listlbr_utf8.vim b/src/nvim/testdir/test_listlbr_utf8.vim
index b648a3361b..c38e0c5f3c 100644
--- a/src/nvim/testdir/test_listlbr_utf8.vim
+++ b/src/nvim/testdir/test_listlbr_utf8.vim
@@ -9,15 +9,15 @@ endif
source view_util.vim
-function s:screen_lines(lnum, width) abort
+func s:screen_lines(lnum, width) abort
return ScreenLines(a:lnum, a:width)
-endfunction
+endfunc
-function! s:compare_lines(expect, actual)
+func s:compare_lines(expect, actual)
call assert_equal(a:expect, a:actual)
-endfunction
+endfunc
-function s:screen_attr(lnum, chars, ...) abort
+func s:screen_attr(lnum, chars, ...) abort
let line = getline(a:lnum)
let attr = []
let prefix = get(a:000, 0, 0)
@@ -26,18 +26,18 @@ function s:screen_attr(lnum, chars, ...) abort
let attr += [screenattr(a:lnum, scol + prefix)]
endfor
return attr
-endfunction
+endfunc
-function s:test_windows(...)
+func s:test_windows(...)
call NewWindow(10, 20)
setl ts=4 sw=4 sts=4 linebreak sbr=+ wrap
exe get(a:000, 0, '')
-endfunction
+endfunc
-function s:close_windows(...)
+func s:close_windows(...)
call CloseWindow()
exe get(a:000, 0, '')
-endfunction
+endfunc
func Test_linebreak_with_fancy_listchars()
call s:test_windows("setl list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
diff --git a/src/nvim/testdir/test_matchadd_conceal.vim b/src/nvim/testdir/test_matchadd_conceal.vim
index 393e183ddb..f9e40a9b43 100644
--- a/src/nvim/testdir/test_matchadd_conceal.vim
+++ b/src/nvim/testdir/test_matchadd_conceal.vim
@@ -27,9 +27,9 @@ function! Test_simple_matchadd()
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
quit!
-endfunction
+endfunc
-function! Test_simple_matchadd_and_conceal()
+func Test_simple_matchadd_and_conceal()
new
setlocal concealcursor=n conceallevel=1
@@ -49,9 +49,9 @@ function! Test_simple_matchadd_and_conceal()
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
quit!
-endfunction
+endfunc
-function! Test_matchadd_and_conceallevel_3()
+func Test_matchadd_and_conceallevel_3()
new
setlocal conceallevel=3
@@ -90,9 +90,9 @@ function! Test_matchadd_and_conceallevel_3()
syntax off
quit!
-endfunction
+endfunc
-function! Test_default_conceal_char()
+func Test_default_conceal_char()
new
setlocal concealcursor=n conceallevel=1
@@ -126,9 +126,9 @@ function! Test_default_conceal_char()
let &listchars = listchars_save
quit!
-endfunction
+endfunc
-function! Test_syn_and_match_conceal()
+func Test_syn_and_match_conceal()
new
setlocal concealcursor=n conceallevel=1
@@ -162,9 +162,9 @@ function! Test_syn_and_match_conceal()
syntax off
quit!
-endfunction
+endfunc
-function! Test_clearmatches()
+func Test_clearmatches()
new
setlocal concealcursor=n conceallevel=1
@@ -201,9 +201,9 @@ function! Test_clearmatches()
call assert_equal({'group': 'Conceal', 'pattern': '\%2l ', 'priority': 10, 'id': a[0].id, 'conceal': 'Z'}, a[0])
quit!
-endfunction
+endfunc
-function! Test_using_matchaddpos()
+func Test_using_matchaddpos()
new
setlocal concealcursor=n conceallevel=1
" set filetype and :syntax on to change screenattr()
@@ -232,9 +232,9 @@ function! Test_using_matchaddpos()
syntax off
quit!
-endfunction
+endfunc
-function! Test_matchadd_repeat_conceal_with_syntax_off()
+func Test_matchadd_repeat_conceal_with_syntax_off()
new
" To test targets in the same line string is replaced with conceal char
@@ -251,9 +251,9 @@ function! Test_matchadd_repeat_conceal_with_syntax_off()
call assert_equal('t_tt', Screenline(2))
quit!
-endfunction
+endfunc
-function! Test_matchadd_and_syn_conceal()
+func Test_matchadd_and_syn_conceal()
new
let cnt='Inductive bool : Type := | true : bool | false : bool.'
let expect = 'Inductive - : Type := | true : - | false : -.'
diff --git a/src/nvim/testdir/test_matchadd_conceal_utf8.vim b/src/nvim/testdir/test_matchadd_conceal_utf8.vim
index 160d0598a1..34c8c49dd5 100644
--- a/src/nvim/testdir/test_matchadd_conceal_utf8.vim
+++ b/src/nvim/testdir/test_matchadd_conceal_utf8.vim
@@ -36,4 +36,4 @@ function! Test_match_using_multibyte_conceal_char()
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
quit!
-endfunction
+endfunc
diff --git a/src/nvim/testdir/test_number.vim b/src/nvim/testdir/test_number.vim
index 3c9afc41d5..81326bce14 100644
--- a/src/nvim/testdir/test_number.vim
+++ b/src/nvim/testdir/test_number.vim
@@ -2,23 +2,23 @@
source view_util.vim
-func! s:screen_lines(start, end) abort
+func s:screen_lines(start, end) abort
return ScreenLines([a:start, a:end], 8)
endfunc
-func! s:compare_lines(expect, actual)
+func s:compare_lines(expect, actual)
call assert_equal(a:expect, a:actual)
endfunc
-func! s:test_windows(h, w) abort
+func s:test_windows(h, w) abort
call NewWindow(a:h, a:w)
endfunc
-func! s:close_windows() abort
+func s:close_windows() abort
call CloseWindow()
endfunc
-func! s:validate_cursor() abort
+func s:validate_cursor() abort
" update skipcol.
" wincol():
" f_wincol
diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim
index 10e16f4198..15c1836c9a 100644
--- a/src/nvim/testdir/test_options.vim
+++ b/src/nvim/testdir/test_options.vim
@@ -1,6 +1,6 @@
" Test for options
-function! Test_whichwrap()
+func Test_whichwrap()
set whichwrap=b,s
call assert_equal('b,s', &whichwrap)
diff --git a/src/nvim/testdir/test_partial.vim b/src/nvim/testdir/test_partial.vim
index 590e18e024..52aac05ea1 100644
--- a/src/nvim/testdir/test_partial.vim
+++ b/src/nvim/testdir/test_partial.vim
@@ -113,9 +113,9 @@ func Test_function_in_dict()
call OuterCall()
endfunc
-function! s:cache_clear() dict
+func s:cache_clear() dict
return self.name
-endfunction
+endfunc
func Test_script_function_in_dict()
let s:obj = {'name': 'foo'}
@@ -135,10 +135,10 @@ func Test_script_function_in_dict()
call assert_equal('bar', B())
endfunc
-function! s:cache_arg(arg) dict
+func s:cache_arg(arg) dict
let s:result = self.name . '/' . a:arg
return s:result
-endfunction
+endfunc
func Test_script_function_in_dict_arg()
let s:obj = {'name': 'foo'}
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index 5c84e45a79..e06c4f59da 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -4485,4 +4485,62 @@ func Test_quickfix_window_fails_to_open()
call delete('XquickfixFails')
endfunc
+" Test for updating the quickfix buffer whenever the assocaited quickfix list
+" is changed.
+func Xqfbuf_update(cchar)
+ call s:setup_commands(a:cchar)
+
+ Xexpr "F1:1:line1"
+ Xopen
+ call assert_equal(['F1|1| line1'], getline(1, '$'))
+ call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
+
+ " Test setqflist() using the 'lines' key in 'what'
+ " add a new entry
+ call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
+ call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
+ call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
+ " replace all the entries with a single entry
+ call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
+ call assert_equal(['F3|3| line3'], getline(1, '$'))
+ call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
+ " remove all the entries
+ call g:Xsetlist([], 'r', {'lines' : []})
+ call assert_equal([''], getline(1, '$'))
+ call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
+ " add a new list
+ call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
+ call assert_equal(['F4|4| line4'], getline(1, '$'))
+ call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
+
+ " Test setqflist() using the 'items' key in 'what'
+ " add a new entry
+ call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
+ call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
+ call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
+ " replace all the entries with a single entry
+ call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
+ call assert_equal(['F6|6| line6'], getline(1, '$'))
+ call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
+ " remove all the entries
+ call g:Xsetlist([], 'r', {'items' : []})
+ call assert_equal([''], getline(1, '$'))
+ call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
+ " add a new list
+ call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
+ call assert_equal(['F7|7| line7'], getline(1, '$'))
+ call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
+
+ call g:Xsetlist([], ' ', {})
+ call assert_equal([''], getline(1, '$'))
+ call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
+
+ Xclose
+endfunc
+
+func Test_qfbuf_update()
+ call Xqfbuf_update('c')
+ call Xqfbuf_update('l')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_smartindent.vim b/src/nvim/testdir/test_smartindent.vim
index 9e93a55eb0..e89ad19d34 100644
--- a/src/nvim/testdir/test_smartindent.vim
+++ b/src/nvim/testdir/test_smartindent.vim
@@ -1,24 +1,24 @@
" Tests for smartindent
" Tests for not doing smart indenting when it isn't set.
-function! Test_nosmartindent()
+func Test_nosmartindent()
new
call append(0, [" some test text",
- \ " test text",
- \ "test text",
- \ " test text"])
+ \ " test text",
+ \ "test text",
+ \ " test text"])
set nocindent nosmartindent autoindent
exe "normal! gg/some\<CR>"
exe "normal! 2cc#test\<Esc>"
call assert_equal(" #test", getline(1))
enew! | close
-endfunction
+endfunc
-function MyIndent()
-endfunction
+func MyIndent()
+endfunc
" When 'indentexpr' is set, setting 'si' has no effect.
-function Test_smartindent_has_no_effect()
+func Test_smartindent_has_no_effect()
new
exe "normal! i\<Tab>one\<Esc>"
set noautoindent
@@ -36,6 +36,6 @@ function Test_smartindent_has_no_effect()
set smartindent&
set indentexpr&
bwipe!
-endfunction
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_substitute.vim b/src/nvim/testdir/test_substitute.vim
index ff07d8eceb..2a27f7a3a1 100644
--- a/src/nvim/testdir/test_substitute.vim
+++ b/src/nvim/testdir/test_substitute.vim
@@ -1,6 +1,6 @@
" Tests for multi-line regexps with ":s".
-function! Test_multiline_subst()
+func Test_multiline_subst()
enew!
call append(0, ["1 aa",
\ "bb",
@@ -38,9 +38,9 @@ function! Test_multiline_subst()
call assert_equal('7x7f', getline(12))
call assert_equal('xxxxx', getline(13))
enew!
-endfunction
+endfunc
-function! Test_substitute_variants()
+func Test_substitute_variants()
" Validate that all the 2-/3-letter variants which embed the flags into the
" command name actually work.
enew!
@@ -248,9 +248,9 @@ func Test_sub_cmd_4()
" List entry format: [input, cmd, output]
let tests = [ ['aAa', "s/A/\\=substitute(submatch(0), '.', '\\', '')/",
- \ ['a\a']],
+ \ ['a\a']],
\ ['bBb', "s/B/\\=substitute(submatch(0), '.', '\\', '')/",
- \ ['b\b']],
+ \ ['b\b']],
\ ['cCc', "s/C/\\=substitute(submatch(0), '.', '\<C-V>\<C-M>', '')/",
\ ["c\<C-V>", 'c']],
\ ['dDd', "s/D/\\=substitute(submatch(0), '.', '\\\<C-V>\<C-M>', '')/",
diff --git a/src/nvim/testdir/test_textobjects.vim b/src/nvim/testdir/test_textobjects.vim
index f70cc1f70a..9b800d0fa9 100644
--- a/src/nvim/testdir/test_textobjects.vim
+++ b/src/nvim/testdir/test_textobjects.vim
@@ -301,7 +301,7 @@ func Test_sentence_with_quotes()
%delete _
endfunc
-func! Test_sentence_with_cursor_on_delimiter()
+func Test_sentence_with_cursor_on_delimiter()
enew!
call setline(1, "A '([sentence.])' A sentence.")
diff --git a/src/nvim/testdir/test_utf8.vim b/src/nvim/testdir/test_utf8.vim
index 1b4ce4c4af..e8161f8fcb 100644
--- a/src/nvim/testdir/test_utf8.vim
+++ b/src/nvim/testdir/test_utf8.vim
@@ -22,17 +22,17 @@ func Test_strchars()
endfunc
" Test for customlist completion
-function! CustomComplete1(lead, line, pos)
+func CustomComplete1(lead, line, pos)
return ['あ', 'い']
-endfunction
+endfunc
-function! CustomComplete2(lead, line, pos)
+func CustomComplete2(lead, line, pos)
return ['あたし', 'あたま', 'あたりめ']
-endfunction
+endfunc
-function! CustomComplete3(lead, line, pos)
+func CustomComplete3(lead, line, pos)
return ['Nこ', 'Nん', 'Nぶ']
-endfunction
+endfunc
func Test_customlist_completion()
command -nargs=1 -complete=customlist,CustomComplete1 Test1 echo
@@ -103,3 +103,14 @@ func Test_list2str_str2list_latin1()
call assert_equal(l, lres)
call assert_equal(s, sres)
endfunc
+
+func Test_print_overlong()
+ " Text with more composing characters than MB_MAXBYTES.
+ new
+ call setline(1, 'axxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
+ s/x/\=nr2char(1629)/g
+ print
+ bwipe!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_utf8_comparisons.vim b/src/nvim/testdir/test_utf8_comparisons.vim
index 1fc670aafd..fdf9d80802 100644
--- a/src/nvim/testdir/test_utf8_comparisons.vim
+++ b/src/nvim/testdir/test_utf8_comparisons.vim
@@ -29,26 +29,26 @@ function! Chk(a, b, result)
call Ch(a:a, '<?', a:b, 1)
call Ch(a:a, '>?', a:b, 0)
endif
-endfunction
+endfunc
-function! Check(a, b, result)
+func Check(a, b, result)
call Chk(a:a, a:b, a:result)
call Chk(a:b, a:a, -a:result)
-endfunction
+endfunc
-function! LT(a, b)
+func LT(a, b)
call Check(a:a, a:b, -1)
-endfunction
+endfunc
-function! GT(a, b)
+func GT(a, b)
call Check(a:a, a:b, 1)
-endfunction
+endfunc
-function! EQ(a, b)
+func EQ(a, b)
call Check(a:a, a:b, 0)
-endfunction
+endfunc
-function Test_comparisons()
+func Test_comparisons()
call EQ('', '')
call LT('', 'a')
call EQ('abc', 'abc')
@@ -81,11 +81,11 @@ function Test_comparisons()
for n in range(0xC0, 0xFF)
call LT(printf('xYz\xc2\x%.2XUvW', n), printf('XyZ\xc2\x%.2XuVw', n))
endfor
-endfunction
+endfunc
" test that g~ap changes one paragraph only.
-function Test_gap()
+func Test_gap()
new
call feedkeys("iabcd\n\ndefggg0g~ap", "tx")
call assert_equal(["ABCD", "", "defg"], getline(1,3))
-endfunction
+endfunc
diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim
index 118a5dab2b..4edf8308e7 100644
--- a/src/nvim/testdir/test_vimscript.vim
+++ b/src/nvim/testdir/test_vimscript.vim
@@ -5,11 +5,11 @@
" Test environment {{{1
"-------------------------------------------------------------------------------
-com! XpathINIT let g:Xpath = ''
+com! XpathINIT let g:Xpath = ''
com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . <args>
" Append a message to the "messages" file
-func! Xout(text)
+func Xout(text)
split messages
$put =a:text
wq
@@ -50,7 +50,7 @@ function! MakeScript(funcname, ...)
write
bwipeout
return script
-endfunction
+endfunc
" ExecAsScript - Source a temporary script made from a function. {{{2
"
@@ -301,9 +301,9 @@ XpathINIT
"
let calls = ""
com! -nargs=1 CALL
- \ if !exists("calls") && !exists("outer") |
- \ let g:calls = g:calls . <args> |
- \ endif
+ \ if !exists("calls") && !exists("outer") |
+ \ let g:calls = g:calls . <args> |
+ \ endif
let i = 0
while i < 3
@@ -357,7 +357,7 @@ endif
if exists("*F1")
call F1("F1")
if exists("*G1")
- call G1("G1")
+ call G1("G1")
endif
endif
@@ -367,13 +367,13 @@ endif
if exists("*F2")
call F2(2, "F2")
if exists("*G21")
- call G21("G21")
+ call G21("G21")
endif
if exists("*G22")
- call G22("G22")
+ call G22("G22")
endif
if exists("*G23")
- call G23("G23")
+ call G23("G23")
endif
endif
@@ -383,13 +383,13 @@ endif
if exists("*F3")
call F3(3, "F3")
if exists("*G31")
- call G31("G31")
+ call G31("G31")
endif
if exists("*G32")
- call G32("G32")
+ call G32("G32")
endif
if exists("*G33")
- call G33("G33")
+ call G33("G33")
endif
endif
@@ -640,7 +640,7 @@ function! MSG(enr, emsg)
endif
endif
return match
-endfunction
+endfunc
if 1 || strlen("\"") | Xpath 'a'
Xpath 'b'
@@ -1099,70 +1099,70 @@ endfunction
func Test_script_lines()
" :append
try
- call DefineFunction('T_Append', [
- \ 'append',
- \ 'py <<EOS',
- \ '.',
- \ ])
+ call DefineFunction('T_Append', [
+ \ 'append',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
catch
- call assert_report("Can't define function")
+ call assert_report("Can't define function")
endtry
try
- call DefineFunction('T_Append', [
- \ 'append',
- \ 'abc',
- \ ])
- call assert_report("Shouldn't be able to define function")
+ call DefineFunction('T_Append', [
+ \ 'append',
+ \ 'abc',
+ \ ])
+ call assert_report("Shouldn't be able to define function")
catch
- call assert_exception('Vim(function):E126: Missing :endfunction')
+ call assert_exception('Vim(function):E126: Missing :endfunction')
endtry
" :change
try
- call DefineFunction('T_Change', [
- \ 'change',
- \ 'py <<EOS',
- \ '.',
- \ ])
+ call DefineFunction('T_Change', [
+ \ 'change',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
catch
- call assert_report("Can't define function")
+ call assert_report("Can't define function")
endtry
try
- call DefineFunction('T_Change', [
- \ 'change',
- \ 'abc',
- \ ])
- call assert_report("Shouldn't be able to define function")
+ call DefineFunction('T_Change', [
+ \ 'change',
+ \ 'abc',
+ \ ])
+ call assert_report("Shouldn't be able to define function")
catch
- call assert_exception('Vim(function):E126: Missing :endfunction')
+ call assert_exception('Vim(function):E126: Missing :endfunction')
endtry
" :insert
try
- call DefineFunction('T_Insert', [
- \ 'insert',
- \ 'py <<EOS',
- \ '.',
- \ ])
+ call DefineFunction('T_Insert', [
+ \ 'insert',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
catch
- call assert_report("Can't define function")
+ call assert_report("Can't define function")
endtry
try
- call DefineFunction('T_Insert', [
- \ 'insert',
- \ 'abc',
- \ ])
- call assert_report("Shouldn't be able to define function")
+ call DefineFunction('T_Insert', [
+ \ 'insert',
+ \ 'abc',
+ \ ])
+ call assert_report("Shouldn't be able to define function")
catch
- call assert_exception('Vim(function):E126: Missing :endfunction')
+ call assert_exception('Vim(function):E126: Missing :endfunction')
endtry
endfunc
"-------------------------------------------------------------------------------
" Test 96: line continuation {{{1
"
-" Undefined behavior was detected by ubsan with line continuation
-" after an empty line.
+" Undefined behavior was detected by ubsan with line continuation
+" after an empty line.
"-------------------------------------------------------------------------------
func Test_script_emty_line_continuation()
@@ -1393,6 +1393,20 @@ func Test_compound_assignment_operators()
let @/ = ''
endfunc
+func Test_unlet_env()
+ let $TESTVAR = 'yes'
+ call assert_equal('yes', $TESTVAR)
+ call assert_fails('lockvar $TESTVAR', 'E940')
+ call assert_fails('unlockvar $TESTVAR', 'E940')
+ call assert_equal('yes', $TESTVAR)
+ if 0
+ unlet $TESTVAR
+ endif
+ call assert_equal('yes', $TESTVAR)
+ unlet $TESTVAR
+ call assert_equal('', $TESTVAR)
+endfunc
+
func Test_funccall_garbage_collect()
func Func(x, ...)
call add(a:x, a:000)